[freefempp] 01/09: Imported Upstream version 3.25

Dimitrios Eftaxiopoulos eftaxiop-guest at alioth.debian.org
Fri Sep 6 22:13:40 UTC 2013


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

eftaxiop-guest pushed a commit to branch eftaxiop
in repository freefempp.

commit 70db1d722c675b7a2bce5676ea385ea87712a977
Author: Dimitrios Eftaxiopoulos <eftaxi12 at otenet.gr>
Date:   Fri Sep 6 17:54:03 2013 +0300

    Imported Upstream version 3.25
---
 ._README_MAC                                       |  Bin 0 -> 171 bytes
 0ldUserReadMe.txt                                  |   54 +-
 COPYRIGHT                                          |    2 +-
 CheckAllEdp                                        |   61 +-
 DOC/._freefem++doc.tex                             |  Bin 0 -> 82 bytes
 DOC/Makefile.in                                    |   39 +-
 DOC/freefem++doc.pdf                               |  Bin 9539068 -> 9542807 bytes
 DOC/freefem++doc.tex                               |   85 +-
 DOC/manual-full.tex                                |17682 ++++++++++----------
 DOC/plots/._VarIneqFill.jpg                        |  Bin 0 -> 225 bytes
 DOC/plots/._VarIneqIso.jpg                         |  Bin 0 -> 225 bytes
 DOC/plots/._minsurf3D.jpg                          |  Bin 0 -> 445 bytes
 DOC/plots/._nlopttab.pdf                           |  Bin 0 -> 412 bytes
 INNOVATION                                         |   32 +-
 Makefile.am                                        |    8 +-
 Makefile.in                                        |   46 +-
 README                                             |   15 +
 WindowsPackage.m4                                  |  306 +-
 acmpi.m4                                           |  310 +
 acoptim.m4                                         |   13 +-
 build/cleancrlf                                    |   54 +
 config-wrapper.h                                   |   36 +-
 config.h.in                                        |    6 +
 configure                                          |  928 +-
 configure.ac                                       |  615 +-
 download/Makefile.am                               |  300 +-
 download/Makefile.in                               |  106 +-
 download/arpack/Makefile.am                        |  139 +-
 download/arpack/Makefile.in                        |   42 +-
 download/blacs/BLACS.patch                         |   13 +
 .../blacs/BLACS_gridinit_.c-return-values.patch    |   12 +
 download/blacs/Bmake-blacs.inc                     |    6 +-
 download/blacs/Makefile                            |  174 +-
 download/blas/Makefile.am                          |  401 +-
 download/blas/Makefile.in                          |   43 +-
 download/fftw/Makefile.am                          |   64 +-
 download/gmm/cxxflags                              |    4 +-
 download/hips/Makefile                             |  418 +-
 download/hips/makefile-hips.inc                    |    5 +-
 download/ipopt/Makefile                            |  154 +-
 download/metis/Makefile                            |  177 +-
 download/metis/metis-4.0_main_return.patch         |  176 +
 download/mmg3d/Makefile                            |  229 +-
 download/mmg3d/patch-mmg3dv4.diff                  | 6211 +++----
 download/mshmet/Makefile                           |  198 +-
 download/mshmet/mshmet.2012.04.25_i586.patch       |   11 +
 download/mumps-seq/Makefile                        |  136 +-
 download/mumps/Makefile                            |  155 +-
 download/mumps/Makefile-mumps-4.10.0.inc           |    7 +-
 download/nlopt/Makefile                            |   20 +-
 download/parmetis/Makefile-parmetis.in             |    3 +-
 download/parmetis/makefile                         |   62 +-
 download/parms/Makefile                            |  130 +-
 download/parms/makefile-parms.in                   |   10 +-
 download/pastix/Makefile                           |  300 +-
 download/pastix/config-pastix-complex.in           |    2 +-
 download/pastix/config-pastix-real.in              |    2 +-
 download/scalapack/Makefile                        |  153 +-
 download/scalapack/SLmake-scalapack.inc            |    6 +-
 download/scotch/._Makefile.patch                   |  Bin 0 -> 225 bytes
 download/scotch/Makefile                           |  154 +-
 download/scotch/Makefile-scotch.inc                |   14 +-
 download/superlu/Makefile                          |  275 +-
 download/superludist/Makefile                      |   37 +-
 download/superludist/make-superlu.inc              |    9 +-
 .../superludist/superludist_3.0-cast_warning.patch |   25 +
 .../superludist_3.0-operation_undefined.patch      |   24 +
 download/superludist/superludist_3.0-printf.patch  |   10 +
 .../superludist_3.0-return_values.patch            |  158 +
 download/tetgen/Makefile                           |  150 +-
 download/tetgen/patches.win64                      |  104 +
 download/umfpack/Makefile.am                       |   15 +-
 download/umfpack/Makefile.in                       |   52 +-
 download/yams/._freeyams.2012.02.05.patch          |  Bin 0 -> 171 bytes
 download/yams/Makefile                             |  206 +-
 .../yams/freeyams.2012.02.05-return-values.patch   |   11 +
 examples++-3d/._beam-3d.edp                        |  Bin 0 -> 171 bytes
 examples++-3d/._periodic-3d.edp                    |  Bin 0 -> 171 bytes
 examples++-3d/Lac.edp                              |    2 +
 examples++-3d/Laplace-Adapt-3d.edp                 |    3 +-
 examples++-3d/LaplaceRT-3d.edp                     |   15 +-
 examples++-3d/Makefile.am                          |    6 +-
 examples++-3d/Makefile.in                          |   52 +-
 examples++-3d/Period-Poisson-cube-ballon.edp       |    2 +
 examples++-3d/Poisson-cube-ballon.edp              |   14 +-
 examples++-3d/Poisson3d.edp                        |    6 +
 examples++-3d/Stokes.edp                           |   10 +
 examples++-3d/TruncLac.edp                         |    4 +-
 examples++-3d/cone.edp                             |    5 +-
 examples++-3d/cube-period.edp                      |   10 +-
 examples++-3d/cylinder-3d.edp                      |    4 +-
 examples++-3d/cylinder.edp                         |    4 +-
 examples++-3d/pyramide.edp                         |    2 +
 examples++-3d/refinesphere.edp                     |  113 +-
 examples++-3d/sphere2.edp                          |    8 +
 examples++-3d/sphere6.edp                          |    2 +
 examples++-3d/tetgencube.edp                       |    2 +
 examples++-3d/tetgenholeregion.edp                 |    5 +
 examples++-bug/Makefile.in                         |   39 +-
 examples++-bug/bugifexp.edp                        |    4 +
 examples++-chapt3/._NSNewton.edp                   |  Bin 0 -> 171 bytes
 examples++-chapt3/._NSprojection.edp               |  Bin 0 -> 171 bytes
 examples++-chapt3/._convects.edp                   |  Bin 0 -> 171 bytes
 examples++-chapt3/BlackScholes2D.edp               |   58 +-
 examples++-chapt3/Makefile.am                      |    9 +-
 examples++-chapt3/Makefile.in                      |   47 +-
 examples++-chapt3/condensor.edp                    |   68 +-
 examples++-chapt3/heatex.edp                       |   48 +-
 examples++-chapt3/membrane.edp                     |   56 +-
 examples++-chapt3/membranerror.edp                 |   58 +-
 examples++-chapt3/muwave.edp                       |   68 +-
 examples++-chapt3/potential.edp                    |   64 +-
 examples++-chapt3/schwarz.edp                      |   52 +-
 examples++-chapt3/sound.edp                        |   90 +-
 examples++-chapt3/stokes.edp                       |   22 +-
 examples++-chapt3/test1.edp                        |   56 +-
 examples++-chapt3/testbed.edp                      |   36 +-
 examples++-chapt3/thermal.edp                      |   48 +-
 examples++-chapt3/thermic.edp                      |   88 +-
 examples++-eigen/Lap3dEigenValue.edp               |    5 +-
 examples++-eigen/LapComplexEigenValue.edp          |    3 +
 examples++-eigen/LapEigenValue.edp                 |    4 +-
 examples++-eigen/LapnosymEigenValue.edp            |    9 +-
 examples++-eigen/Makefile.am                       |    7 +-
 examples++-eigen/Makefile.in                       |   48 +-
 examples++-eigen/Stokes-eigen.edp                  |    4 +-
 examples++-eigen/VP-Steklov-Poincare.edp           |    2 +-
 examples++-eigen/neuman.edp                        |    8 +-
 examples++-load/._APk-AdaptEpsDeltaPk.edp          |  Bin 0 -> 170 bytes
 examples++-load/._APk-ExplicitPkTest.edp           |  Bin 0 -> 457 bytes
 examples++-load/._APk-MetricPk.edp                 |  Bin 0 -> 1420 bytes
 examples++-load/._Element_P3.cpp                   |  Bin 0 -> 171 bytes
 examples++-load/._IpOptMinSurf.edp                 |  Bin 0 -> 171 bytes
 examples++-load/._IpoptVI2.edp                     |  Bin 0 -> 391 bytes
 examples++-load/._PARDISO.cpp                      |  Bin 0 -> 171 bytes
 examples++-load/._TensorK.hpp                      |  Bin 0 -> 171 bytes
 examples++-load/._ch.pts                           |  Bin 0 -> 171 bytes
 examples++-load/._cmaes.cpp                        |  Bin 0 -> 276 bytes
 examples++-load/._cmaes.h                          |  Bin 0 -> 276 bytes
 examples++-load/._cmaes_interface.h                |  Bin 0 -> 225 bytes
 examples++-load/._ff-Ipopt.cpp                     |  Bin 0 -> 171 bytes
 examples++-load/._ff-NLopt.cpp                     |  Bin 0 -> 171 bytes
 examples++-load/._gsl.cpp                          |  Bin 0 -> 171 bytes
 examples++-load/._isoline.cpp                      |  Bin 0 -> 171 bytes
 examples++-load/._isoline.edp                      |  Bin 0 -> 171 bytes
 examples++-load/._mat_dervieux.cpp                 |  Bin 0 -> 171 bytes
 examples++-load/._pipe.edp                         |  Bin 0 -> 171 bytes
 examples++-load/._scotch.edp                       |  Bin 0 -> 365 bytes
 examples++-load/._shell.cpp                        |  Bin 0 -> 171 bytes
 examples++-load/._splitedges.cpp                   |  Bin 0 -> 171 bytes
 examples++-load/._symmetrizeCSR.cpp                |  Bin 0 -> 210 bytes
 examples++-load/._tetgen.cpp                       |  Bin 0 -> 167 bytes
 examples++-load/BinaryIO.cpp                       |    1 +
 examples++-load/DxWriter.cpp                       |  694 +-
 examples++-load/IpoptMinSurfVol.edp                |   17 +-
 examples++-load/MUMPS_seq.cpp                      |    1 -
 examples++-load/Makefile.am                        |  105 +-
 examples++-load/Makefile.in                        |  160 +-
 examples++-load/MetricKuate.edp                    |    3 +
 examples++-load/NewSolver.cpp                      |    2 +-
 examples++-load/PARDISO.edp                        |    2 +-
 examples++-load/SuperLU.edp                        |    3 +
 examples++-load/SuperLu.cpp                        |    4 +-
 examples++-load/UMFPACK64.cpp                      |   24 +-
 examples++-load/VTK_writer.cpp                     |  675 +-
 examples++-load/VTK_writer_3d.cpp                  |  731 +-
 examples++-load/VarIneq2.edp                       |    2 +-
 examples++-load/addNewType.cpp                     |    1 +
 examples++-load/buildlayermesh.edp                 |  114 +-
 examples++-load/cmaes-VarIneq.edp                  |    2 +-
 examples++-load/cmaes-oven.edp                     |    7 +-
 examples++-load/convect_dervieux.edp               |    2 +-
 examples++-load/ff-Ipopt.cpp                       |  128 +-
 examples++-load/ff-get-dep.in                      |   11 +-
 examples++-load/fflapack.cpp                       |    4 +-
 examples++-load/ffrandom.cpp                       |   16 +-
 examples++-load/gsl.cpp                            |   15 +-
 examples++-load/gsl.edp                            |   10 +-
 examples++-load/iovtk.cpp                          |    2 +
 examples++-load/lap-solvers.edp                    |    1 -
 examples++-load/lapack.cpp                         |    4 +-
 examples++-load/lapack.edp                         |    8 +-
 examples++-load/load.link.in                       |   38 +-
 examples++-load/mat_psi.cpp                        |    1 +
 examples++-load/medit.cpp                          |    2 +-
 examples++-load/msh3.cpp                           |   18 +-
 examples++-load/newuoa.f                           | 2910 ++--
 examples++-load/provadxw.edp                       |   24 +-
 examples++-load/schwarz-nm.edp                     |    4 +
 examples++-load/scotch.cpp                         |    3 +-
 examples++-load/test-ElementMixte.edp              |    6 +
 examples++-load/testFE-PkEdge.edp                  |    4 +-
 examples++-load/tetgenholeregion.edp               |   86 -
 examples++-load/ttestio.edp                        |    3 +-
 examples++-mpi/._DDM-Schwarz-Lame-2d.edp           |  Bin 0 -> 171 bytes
 examples++-mpi/._DDM-Schwarz-Lap-2dd.edp           |  Bin 0 -> 171 bytes
 examples++-mpi/._DDM-Schwarz-Stokes-2d.edp         |  Bin 0 -> 171 bytes
 examples++-mpi/._chaleur3D-mumps.edp               |  Bin 0 -> 171 bytes
 examples++-mpi/._dmatrix.hpp                       |  Bin 0 -> 210 bytes
 examples++-mpi/MUMPS.cpp                           |    7 +
 examples++-mpi/MUMPS_FreeFem.cpp                   |    9 +-
 examples++-mpi/Makefile.am                         |   44 +-
 examples++-mpi/Makefile.in                         |   85 +-
 examples++-mpi/NSI3d-carac.edp                     |    2 +-
 examples++-mpi/Stokes-v1-matrix-mumps.edp          |    3 +-
 examples++-mpi/Stokes-v1-matrix-pastix.edp         |    3 +-
 examples++-mpi/Stokes-v1-matrix-superludist.edp    |    3 +-
 examples++-mpi/Stokes-v2-matrix-mumps.edp          |    2 +-
 examples++-mpi/Stokes-v2-matrix-pastix.edp         |    2 +-
 examples++-mpi/Stokes-v2-matrix-superludist.edp    |    2 +-
 examples++-mpi/Stokes-v3-matrix-mumps.edp          |    4 +-
 examples++-mpi/Stokes-v3-matrix-pastix.edp         |    4 +-
 examples++-mpi/Stokes-v3-matrix-superludist.edp    |    2 +-
 examples++-mpi/chaleur3D-mumps.edp                 |    2 +-
 examples++-mpi/complex_SuperLU_DIST_FreeFem.cpp    |   17 +-
 examples++-mpi/complex_pastix_FreeFem.cpp          |    2 +
 examples++-mpi/dSuperLU_DIST.cpp                   |    6 +
 examples++-mpi/essai-com.edp                       |    2 +-
 examples++-mpi/hypre_FreeFem.cpp                   |    4 +
 examples++-mpi/interfacepastix.cpp                 |    2 +
 examples++-mpi/parms_FreeFem.cpp                   |   14 +-
 examples++-mpi/real_SuperLU_DIST_FreeFem.cpp       |    5 +
 examples++-mpi/real_pastix_FreeFem.cpp             |    2 +
 examples++-mpi/testsolver_MUMPS.edp                |    4 +
 examples++-mpi/testsolver_SuperLU_DIST.edp         |    5 +
 examples++-mpi/testsolver_dsuperlu_dist.edp        |    4 +
 examples++-other/Makefile.in                       |   39 +-
 examples++-other/lap3-cpu.edp                      |    4 +
 examples++-tutorial/._BEM-C.edp                    |  Bin 0 -> 171 bytes
 examples++-tutorial/._LapDG2.edp                   |  Bin 0 -> 171 bytes
 examples++-tutorial/._LaplaceRT.edp                |  Bin 0 -> 171 bytes
 examples++-tutorial/._fluidStruct.edp              |  Bin 0 -> 171 bytes
 examples++-tutorial/._fluidStructAdapt.edp         |  Bin 0 -> 171 bytes
 examples++-tutorial/._gnuplot.edp                  |  Bin 0 -> 171 bytes
 examples++-tutorial/._regtests.m4                  |  Bin 0 -> 230 bytes
 examples++-tutorial/._sphere.edp                   |  Bin 0 -> 171 bytes
 examples++-tutorial/Laplace-RHS-Dirac.edp          |    6 +
 examples++-tutorial/Laplace.cpp                    |   59 +
 examples++-tutorial/Makefile.am                    |    8 +-
 examples++-tutorial/Makefile.in                    |  194 +-
 examples++-tutorial/NS-BackwardStep.edp            |    7 +
 examples++-tutorial/Newton.edp                     |    8 +-
 examples++-tutorial/a_tutorial.edp                 |    2 +-
 examples++-tutorial/array.edp                      |    6 +-
 examples++-tutorial/calculus.edp                   |    2 +-
 examples++-tutorial/freeboundary-weak.edp          |    4 +-
 examples++-tutorial/glumesh.edp                    |    4 +
 examples++-tutorial/intlevelset.edp                |   30 +
 examples++-tutorial/{readmesh.edp => io.edp}       |    0
 examples++-tutorial/medit.edp                      |    3 +-
 examples++-tutorial/mesh.edp                       |    5 +-
 examples++-tutorial/mortar-DN-4.edp                |    4 +-
 examples++-tutorial/readmesh.edp                   |   27 +
 examples++-tutorial/saverestore.edp                |    2 +
 examples++-tutorial/schwarz-no-overlap.edp         |    4 +-
 examples++-tutorial/sparse-cmatrix.edp             |    2 +-
 examples++-tutorial/thermic-fast.edp               |   84 +-
 examples++/._FE-medit.edp                          |  Bin 0 -> 171 bytes
 examples++/._aaa-adp.edp                           |  Bin 0 -> 171 bytes
 examples++/._bilap.edp                             |  Bin 0 -> 171 bytes
 examples++/._testadp.edp                           |  Bin 0 -> 171 bytes
 examples++/Makefile.am                             |    5 +-
 examples++/Makefile.in                             |   44 +-
 examples++/ccc-adp.edp                             |    2 +-
 examples++/ref.edp                                 |   20 -
 examples++/testFE.edp                              |    3 +-
 freefem++.spec                                     |  196 +-
 src/Algo/Makefile.in                               |   39 +-
 src/Graphics/._ffglut.cpp                          |  Bin 0 -> 167 bytes
 src/Graphics/._ffglut.hpp                          |  Bin 0 -> 171 bytes
 src/Graphics/Makefile.am                           |    6 +
 src/Graphics/Makefile.in                           |   64 +-
 src/Graphics/ffglut.cpp                            |  138 +-
 src/Graphics/getprog-unix.hpp                      |   47 +-
 src/Graphics/sansrgraph.cpp                        |    2 +-
 src/Makefile.in                                    |   39 +-
 src/bamg/Makefile.in                               |   39 +-
 src/bamglib/._Mesh2.h                              |  Bin 0 -> 171 bytes
 src/bamglib/._MeshGeom.cpp                         |  Bin 0 -> 167 bytes
 src/bamglib/Makefile.in                            |   39 +-
 src/bamglib/Mesh2.h                                |    3 +-
 src/bin-win32/Makefile.am                          |   16 +-
 src/bin-win32/Makefile.in                          |   78 +-
 src/femlib/._CheckPtr.cpp                          |  Bin 0 -> 167 bytes
 src/femlib/._FESpace.cpp                           |  Bin 0 -> 167 bytes
 src/femlib/._FESpacen.cpp                          |  Bin 0 -> 170 bytes
 src/femlib/._GQuadTree.cpp                         |  Bin 0 -> 170 bytes
 src/femlib/._GenericMesh.hpp                       |  Bin 0 -> 167 bytes
 src/femlib/._MatriceCreuse.hpp                     |  Bin 0 -> 171 bytes
 src/femlib/._MatriceCreuse_tpl.hpp                 |  Bin 0 -> 171 bytes
 src/femlib/._MeshPoint.hpp                         |  Bin 0 -> 171 bytes
 src/femlib/._P012_2d.cpp                           |  Bin 0 -> 170 bytes
 src/femlib/._PkLagrange.hpp                        |  Bin 0 -> 170 bytes
 src/femlib/._RNM.hpp                               |  Bin 0 -> 170 bytes
 src/femlib/._RNM_op.hpp                            |  Bin 0 -> 171 bytes
 src/femlib/._RNM_opc.hpp                           |  Bin 0 -> 171 bytes
 src/femlib/FQuadTree.cpp                           |    2 +-
 src/femlib/Makefile.in                             |   39 +-
 src/femlib/MatriceCreuse_tpl.hpp                   |   47 +-
 src/fflib/._AFunction.cpp                          |  Bin 0 -> 171 bytes
 src/fflib/._Operator.hpp                           |  Bin 0 -> 171 bytes
 src/fflib/._array_long.cpp                         |  Bin 0 -> 170 bytes
 src/fflib/._array_real.cpp                         |  Bin 0 -> 170 bytes
 src/fflib/._array_resize.hpp                       |  Bin 0 -> 171 bytes
 src/fflib/._array_tlp.hpp                          |  Bin 0 -> 171 bytes
 src/fflib/._glumesh2D.cpp                          |  Bin 0 -> 170 bytes
 src/fflib/._lex.cpp                                |  Bin 0 -> 170 bytes
 src/fflib/._lgfem.hpp                              |  Bin 0 -> 171 bytes
 src/fflib/._lgmesh3.cpp                            |  Bin 0 -> 171 bytes
 src/fflib/._lgsolver.hpp                           |  Bin 0 -> 171 bytes
 src/fflib/._problem.hpp                            |  Bin 0 -> 167 bytes
 src/fflib/AFunction.cpp                            |  208 +-
 src/fflib/AFunction.hpp                            |   66 +-
 src/fflib/AFunction2.cpp                           |    2 +-
 src/fflib/Makefile.am                              |    6 +-
 src/fflib/Makefile.in                              |   48 +-
 src/fflib/PlotStream.hpp                           |   29 +-
 src/fflib/environment.cpp                          |    9 +
 src/fflib/ffapi.cpp                                |  205 +-
 src/fflib/ffapi.hpp                                |   48 +-
 src/fflib/ffstack.hpp                              |    8 +-
 src/fflib/global.cpp                               |    6 +-
 src/fflib/lex.hpp                                  |    2 +
 src/fflib/lgfem.cpp                                |   83 +-
 src/fflib/lgfem.hpp                                |   45 -
 src/fflib/lgmat.cpp                                |    2 +-
 src/fflib/lgmesh.cpp                               |    3 +-
 src/fflib/load.cpp                                 |   17 +
 src/fflib/problem.cpp                              |  275 +-
 src/fflib/problem.hpp                              |    7 +-
 src/fflib/strversionnumber.cpp                     |    4 +-
 src/lglib/Makefile.in                              |   39 +-
 src/lglib/lg.tab.cpp                               | 1658 +-
 src/lglib/lg.tab.hpp                               |  120 +-
 src/lglib/lg.ypp                                   |   56 +-
 src/lglib/mymain.cpp                               |    3 +
 src/libMesh/Makefile.in                            |   39 +-
 src/medit/Makefile.am                              |   48 +-
 src/medit/Makefile.in                              |  138 +-
 src/mpi/Makefile.am                                |   10 +-
 src/mpi/Makefile.in                                |   67 +-
 src/mpi/ff-mpirun.in                               |    8 +-
 src/mpi/parallelempi.cpp                           |   11 +-
 src/nw/Makefile.am                                 |    8 +-
 src/nw/Makefile.in                                 |   69 +-
 src/solver/hypre_FreeFem.cpp                       |    2 +-
 src/solver/parms_FreeFem.cpp                       |   27 +-
 test-driver-ff                                     |    6 +-
 348 files changed, 23912 insertions(+), 19606 deletions(-)

diff --git a/._README_MAC b/._README_MAC
new file mode 100644
index 0000000..f7a8f68
Binary files /dev/null and b/._README_MAC differ
diff --git a/0ldUserReadMe.txt b/0ldUserReadMe.txt
index f04ced1..c8c8995 100644
--- a/0ldUserReadMe.txt
+++ b/0ldUserReadMe.txt
@@ -1,34 +1,34 @@
-///////////////////////////////
-     New 3D features of freefem++ 
-///////////////////////////////
-
-Version 3.0 is the first version capable of 3D computations.  The price to pay is more difficult mesh generations and difficulties to display the results.  More details can be found in the documentation
-
-1. Mesh generation
-==============
+///////////////////////////////
+     New 3D features of freefem++ 
+///////////////////////////////
+
+Version 3.0 is the first version capable of 3D computations.  The price to pay is more difficult mesh generations and difficulties to display the results.  More details can be found in the documentation
+
+1. Mesh generation
+==============
 There is an interface with the mesh generator tetgen (http://tetgen.berlios.de/)
-   see: examples++-3d/Poisson3d.edp  ( mesh of a sphere)
+   see: examples++-3d/Poisson3d.edp  ( mesh of a sphere)
 There is a small 3D mesh generator for cylindrical meshes by extrusion of a 2D mesh
    see example: examples++-3d/Lac.edp  for a mesh of a lac
                 examples++-3d/Stokes.edp for a mesh a cube.
-
+
 There is a mesh reader from files in format .mesh of medit (http://www.ann.jussieu.fr/~frey/software.html)
   see example: examples++-3d/dodecaedre01.mesh 
- 
-
-2. Graphics
-========
-
-2D Graphics
--------------
-The standard graphic windows now use a client/server architecture based on openGL GLUT, so the commands have changed:
- - to go to the next graphic type "enter key"
- - to close the graphic window type escape
- - to find out about other commands type the ? key
- 
-Warning:  you must have "ffglut" in your path; this is done for you by the install program on windows system if you do not uncheck the click box.
-
-3D Graphics
--------------
-Real 3D graphics can be obtained with medit, built in freefem andit can be  launched independently of freefem by the command shell "ffmedit".
+ 
+
+2. Graphics
+========
+
+2D Graphics
+-------------
+The standard graphic windows now use a client/server architecture based on openGL GLUT, so the commands have changed:
+ - to go to the next graphic type "enter key"
+ - to close the graphic window type escape
+ - to find out about other commands type the ? key
+ 
+Warning:  you must have "ffglut" in your path; this is done for you by the install program on windows system if you do not uncheck the click box.
+
+3D Graphics
+-------------
+Real 3D graphics can be obtained with medit, built in freefem andit can be  launched independently of freefem by the command shell "ffmedit".
 Freefem can also launch medit by the keywork medit.  Two calls to medit will launch two instances of medit. To close these windows use escape.
\ No newline at end of file
diff --git a/COPYRIGHT b/COPYRIGHT
index 51891da..6207c52 100644
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -1,7 +1,7 @@
 This is The FreeFem++ software.
 
 Programs in it were maintained by
-Fr�d�ric hecht <Frederic.Hecht at upmc.fr>  and by
+Frederic hecht <Frederic.Hecht at upmc.fr>  and by
 Olivier Pironneau <Olivier.Pironneau at upmc.fr> and by
 Antoine Le Hyaric <lehyaric at ann.jussieu.fr>
 
diff --git a/CheckAllEdp b/CheckAllEdp
index a5b80a4..a21f29e 100755
--- a/CheckAllEdp
+++ b/CheckAllEdp
@@ -1,4 +1,19 @@
-#!/bin/sh
+#!/bin/bash
+  red='' # Red.
+  grn='' # Green.
+  lgn='' # Light green.
+  blu='' # Blue.
+  mgn='' # Magenta.
+  std=''     # No color.
+
+NL=0
+NA=0
+NX=0
+NN=0
+NO=0
+NC=0
+NF=0
+
 cmm=$1;shift;
 if [ $# -eq 0 ]; then
 list=*.edp
@@ -11,14 +26,44 @@ do
 	all.edp|regtests.edp) 
 	    echo  pass   $i;; 
 	*)
+	    ((NN++))
 	    ( $cmm "$i" )2>&1 1>$i-out;
-	    if [ $? -eq 0 ] 
-	    then 
-		echo  OK $cmm $i;
-	    else  
-		echo  FAIL $cmm $i "( see $i-out )";
-		echo  FAIL $cmm $i "(see $i-out ">>/tmp/list-ff-$$
+	    RES=$?
+	    ((SIG=$RES%128));
+
+	    ## error Compile error : Error load   # 1
+	    ## error Compile error :
+            ## Exec error : exec assert
+	    ## Exec error :
+	    errl=`grep 'error Compile error : Error load' $i-out`
+	    errC=`grep 'error Compile error :' $i-out`
+	    errX=`grep 'Exec error :' $i-out`
+	    errA=`grep 'Exec error : exec assert' $i-out`
+	  #  echo "$RES,$SIG,$errC,$errA."
+	    if [ -n "$errl" ] ; then
+		((NL++))
+		MSG="${mgn} FAIL(load)        ${std}"
+	    elif [ -n "$errC" ] ; then
+		((NC++))
+		MSG="${lgn} FAIL(Compile)     ${std}"
+	    elif [ -n "$errA" ] ; then
+		((NA++))
+		MSG="${blu} FAIL(Assert)      ${std}"
+	    elif [ -n "$errX" ] ; then
+		((NX++))
+		MSG="${mgn} FAIL(Exec)        ${std}"
+	    elif [ $SIG -eq 0 ] ; then
+		((NO++))
+		MSG="${grn} OK  (Exec)        ${std}"
+	    else
+		MSG="${red} FAIL(signal)=$SIG ${std}"
+		((NF++))
 	    fi
+	    echo $MSG  $cmm $i  >>$i-out
+	    echo  $MSG  $cmm $i "( see $i-out )";
+#	    echo  $MSG  $cmm $i "(see $i-out )" >>/tmp/list-ff-$$
 	    ;;
     esac
-done
\ No newline at end of file
+done
+
+echo "Nb Case $NN / ${grn}OK $NO / ${red} FAIL $NF / ${blu} Assert Error $NA/ ${lgn} Compile Error $NC  / ${mgn} load Error $NL / Exec Error $NX${std}"
diff --git a/DOC/._freefem++doc.tex b/DOC/._freefem++doc.tex
new file mode 100644
index 0000000..3465e1d
Binary files /dev/null and b/DOC/._freefem++doc.tex differ
diff --git a/DOC/Makefile.in b/DOC/Makefile.in
index 4c56f8f..a170ef8 100644
--- a/DOC/Makefile.in
+++ b/DOC/Makefile.in
@@ -55,7 +55,8 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(top_srcdir)/mkinstalldirs $(dist_pkgdata_DATA)
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/acmacros.m4 \
-	$(top_srcdir)/acoptim.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/acoptim.m4 $(top_srcdir)/acmpi.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -154,11 +155,47 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EIGENOBJ = @EIGENOBJ@
+ENABLE_FFCS = @ENABLE_FFCS@
 EPSTOPDF = @EPSTOPDF@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+FFCS_COMPILE_fflapack = @FFCS_COMPILE_fflapack@
+FFCS_COMPILE_gsl = @FFCS_COMPILE_gsl@
+FFCS_COMPILE_hips = @FFCS_COMPILE_hips@
+FFCS_COMPILE_hypre = @FFCS_COMPILE_hypre@
+FFCS_COMPILE_ipopt = @FFCS_COMPILE_ipopt@
+FFCS_COMPILE_lapack = @FFCS_COMPILE_lapack@
+FFCS_COMPILE_mmg3d = @FFCS_COMPILE_mmg3d@
+FFCS_COMPILE_mshmet = @FFCS_COMPILE_mshmet@
+FFCS_COMPILE_mumps = @FFCS_COMPILE_mumps@
+FFCS_COMPILE_mumps_seq = @FFCS_COMPILE_mumps_seq@
+FFCS_COMPILE_pardiso = @FFCS_COMPILE_pardiso@
+FFCS_COMPILE_parms = @FFCS_COMPILE_parms@
+FFCS_COMPILE_pastix = @FFCS_COMPILE_pastix@
+FFCS_COMPILE_pipe = @FFCS_COMPILE_pipe@
+FFCS_COMPILE_scotch = @FFCS_COMPILE_scotch@
+FFCS_COMPILE_superludist = @FFCS_COMPILE_superludist@
+FFCS_COMPILE_yams = @FFCS_COMPILE_yams@
+FFCS_DYLIB_fflapack = @FFCS_DYLIB_fflapack@
+FFCS_DYLIB_gsl = @FFCS_DYLIB_gsl@
+FFCS_DYLIB_hips = @FFCS_DYLIB_hips@
+FFCS_DYLIB_hypre = @FFCS_DYLIB_hypre@
+FFCS_DYLIB_ipopt = @FFCS_DYLIB_ipopt@
+FFCS_DYLIB_lapack = @FFCS_DYLIB_lapack@
+FFCS_DYLIB_mmg3d = @FFCS_DYLIB_mmg3d@
+FFCS_DYLIB_mshmet = @FFCS_DYLIB_mshmet@
+FFCS_DYLIB_mumps = @FFCS_DYLIB_mumps@
+FFCS_DYLIB_mumps_seq = @FFCS_DYLIB_mumps_seq@
+FFCS_DYLIB_pardiso = @FFCS_DYLIB_pardiso@
+FFCS_DYLIB_parms = @FFCS_DYLIB_parms@
+FFCS_DYLIB_pastix = @FFCS_DYLIB_pastix@
+FFCS_DYLIB_pipe = @FFCS_DYLIB_pipe@
+FFCS_DYLIB_scotch = @FFCS_DYLIB_scotch@
+FFCS_DYLIB_superludist = @FFCS_DYLIB_superludist@
+FFCS_DYLIB_yams = @FFCS_DYLIB_yams@
+FFCS_MAKEFLAGS = @FFCS_MAKEFLAGS@
 FFGLUTNAME = @FFGLUTNAME@
 FFGLUTPROG = @FFGLUTPROG@
 FFLAGS = @FFLAGS@
diff --git a/DOC/freefem++doc.pdf b/DOC/freefem++doc.pdf
index 464132f..de05a1a 100644
Binary files a/DOC/freefem++doc.pdf and b/DOC/freefem++doc.pdf differ
diff --git a/DOC/freefem++doc.tex b/DOC/freefem++doc.tex
index 18398d5..1d22fa9 100644
--- a/DOC/freefem++doc.tex
+++ b/DOC/freefem++doc.tex
@@ -10,7 +10,7 @@
 
 \newtheorem{remark}{Remark}
 
-\def\VERSION{3.22}
+\def\VERSION{3.25}
 \def\key#1{\emph{#1}\index{#1}}
 \def\vec#1{\mbox{\boldmath $#1$}}
 \def\C{\mathbb{C}}
@@ -3912,7 +3912,7 @@ Hence FE-functions are not defined only by their formula but also by the mesh an
 
 \bFF
 func f=x^2*(1+y)^3+y^2;
-mesh Th = square(20,20,[-2+2*x,-2+2*y]); // square $]-2,2[^2$
+mesh Th = square(20,20,[-2+4*x,-2+4*y]); // square $]-2,2[^2$
 fespace Vh(Th,P1);
 Vh fh=f;  // fh is the  projection of f to Vh (real value)
 func zf=(x^2*(1+y)^3+y^2)*exp(x+1i*y);
@@ -3974,7 +3974,7 @@ d = ( a ? b : c ); // for i = 0, n-1  : d[i] = a[i] ? b[i] : c[i] ,
 @cout << " d = ( a ? b : c )  is " << d << endl;
 d = ( a ? 1 : c );// for i = 0, n-1: d[i] = a[i] ? 1 : c[i] ,  \hfill (v2.23-1)
 d = ( a ? b : 0 );// for i = 0, n-1: d[i] = a[i] ? b[i] : 0 ,  \hfill (v2.23-1)
-d = ( a ? 1 : 0 );// for i = 0, n-1: d[i] = a[i] ? 0 : 1 ,     \hfill�(v2.23-1)
+d = ( a ? 1 : 0 );// for i = 0, n-1: d[i] = a[i] ? 0 : 1 ,     \hfill(v2.23-1)
 tab.sort ; //  sort the array tab  (version 2.18)
 cout << " tab (after sort) "  << tab << endl;
 int[int] ii(0:d.n-1); // set array ii to 0,1, ..., d.n-1 \hfill (v3.2)
@@ -5082,6 +5082,7 @@ Let us begin with the two important keywords \texttt{\bf border} and \texttt{\bf
 All examples in this section come from the files \texttt{mesh.edp}
 and \texttt{tablefunction.edp}.
 
+% <<square>>
 \index{square}
 \subsubsection{\setS{Square}}
 
@@ -10467,55 +10468,59 @@ for this are the following :
 \end{description}
 
 
-
-
-
+%%  version S. Auliac du 26/08/2013 ...
 \subsection{IPOPT}
 The {\tt ff-Ipopt} package is an interface for the IPOPT \cite{ipopt} optimizer. IPOPT is a software library for large scale, non-linear, constrained optimization. Detailed informations about it are in \cite{ipopt} and \url{https://projects.coin-or.org/Ipopt}. It implements a primal-dual interior point method along with filter method based line searchs. 
 IPOPT need a direct sparse symmetric linear solver. If your version of FreeFem has been compiled with the {\tt --enable-downlad} tag, it will automatically be linked with a sequential version of MUMPS. An alternative to MUMPS would be to download the HSL subroutines (see \url{http://www.coin-or.org/Ipopt/documentation/node16.html}) and place them in the {\tt /ipopt/Ipopt-3.10.2/ThirdParty/HSL} directory of the FreeFem++ downloads folder before compiling.
 
 \subsubsection{Short description of the algorithm}
- In this section, we give a very brief glimpse at the underlying mathematics of IPOPT. For a deeper introduction on interior methods for nonlinear smooth optimization, one can consult \cite{ipintro}, or \cite{ipopt} for more IPOPT specific elements. For convenience, let us assume that the minimization problem is the following, given a function $f:\mathbb{R}^{n}\mapsto\mathbb{R}$, find :
+ In this section, we give a very brief glimpse at the underlying mathematics of IPOPT. For a deeper introduction on interior methods for nonlinear smooth optimization, one may consults \cite{ipintro}, or \cite{ipopt} for more IPOPT specific elements. IPOPT is designed to perform optimization for both equality and inequality constrained problems. Though, nonlinear inequalities are rearranged before the beginning of the optimization process in order to restrict the panel of nonlinear const [...]
+ Thus, for convenience, we will assume that the minimization problem does not contain any nonlinear inequality constraint. It means that, given a function $f:\mathbb{R}^{n}\mapsto\mathbb{R}$, we want to find :
  \begin{equation}\label{minimproblem}
  \begin{array} {c}
  x_{0} = \underset{x\in V}{\operatorname{argmin}} f(x) \\
- \mathrm{with}\ V = \left\lbrace x\in\R^{n} \vert \forall i, 1\leq i \leq m, c_{i}(x) \geq 0 \right\rbrace 
+ \mathrm{with}\ V = \left\lbrace x\in\R^{n}\ \vert\ c(x)= 0 \ \text{and}\ x_{l}\leq x\leq x_{u}\right\rbrace 
  \end{array}
  \end{equation}
-Generalization to mixed equality/inequality constraints can be found in \cite{ipintro} or \cite{ipopt}. The $f$ function as well as the constraints $c$ should be twice-continuously differentiable.
-
-
-%For this optimization problem, the first order Karush-Kuhn-Tucker (KKT) conditions, hold at the point $x^{*}$ if $\exists \lambda^{*}\in\R^{m}$ such that :
-%\begin{equation}\label{KKT}
-%\begin{array}{r c l}
-%	\forall i,\  c_{i}(x^{*})& \geq &0 \\
-%	\nabla f(x^{*}) & = & J_{c}(x^{*})^{T}\lambda^{*}\\
-%	\forall i,\ \lambda_{i}^{*} & \geq & 0 \\
-%	c(x^{*})\cdot\lambda^{*} &=&0
-%\end{array}
-%\end{equation}
-%When certain assumptions upon the constraints are met (see \cite{ipintro}), these are necessary conditions for a point to be a solution of \ref{minimproblem}.
-As a barrier method, interior point algorithms try to find a Karush-Kuhn-Tucker point for \ref{minimproblem} by solving a sequence of unconstrained problems of the form :
+Where $c:\R^{n}\rightarrow\R^{m}$ and $x_{l},x_{u}\in\R^{n}$ and inequalities hold componentwise.
+The $f$ function as well as the constraints $c$ should be twice-continuously differentiable.
+
+As a barrier method, interior points algorithms try to find a Karush-Kuhn-Tucker point for (\ref{minimproblem}) by solving a sequence of problems, unconstrained with respect to the inequality constraints, of the form :
 \begin{equation}\label{barrier}
-\mathrm{for\ a\ given\ }\mu > 0,\ \mathrm{find}\ x_{\mu} = \underset{x\in\R^{n}}{\operatorname{argmin}}\  f(x) - \displaystyle{\mu\sum_{i=1}^{m} \ln c_{i}(x)}
+\mathrm{for\ a\ given\ }\mu > 0,\ \mathrm{find}\ x_{\mu} = \underset{x\in\R^{n}\ \vert\ c(x)=0}{\operatorname{argmin}}\  B(x,\mu) 
 \end{equation}
-If the sequence of barrier parameters $\mu$ converge to 0, intuition suggests that the sequence of minimizers of \ref{barrier} converge to a local constrained minimizer of \ref{minimproblem}. For a given $\mu$, \ref{barrier} is solved by finding $x_{\mu}\in\R^{n}$ such that :
+Where $\mu$ is a positive real number and $B(x,\mu) = f(x) - \displaystyle{\mu\sum_{i=1}^{n} \ln (x_{u,i}-x_{i})} - \displaystyle{\mu\sum_{i=1}^{m} \ln(x_{i}-x_{l,i})}$.
+The remaining equality constraints are handled with the usual Lagrange multipliers method.
+If the sequence of barrier parameters $\mu$ converge to 0, intuition suggests that the sequence of minimizers of (\ref{barrier}) converge to a local constrained minimizer of (\ref{minimproblem}). For a given $\mu$, (\ref{barrier}) is solved by finding $(x_{\mu},\lambda_{\mu})\in\R^{n}\times\R^{m}$ such that :
 \begin{equation}\label{muproblem}
- \nabla f(x_{\mu}) - \displaystyle{\sum_{i=1}^{m}\frac{\mu}{c_{i}(x_{\mu})}\nabla c_{i}(x_{\mu})}
- = \nabla f(x_{\mu}) - J_{c}(x_{\mu})^{T}
- \left(\begin{array}{c} \mu / c_{1}(x_{\mu}) \\ \vdots \\ \mu / c_{m}(x_{\mu}) \end{array}\right) = 0
+ \nabla B(x_{\mu},\mu) + \displaystyle{\sum_{i=1}^{m}\lambda_{\mu,i}\nabla c_{i}(x_{\mu})}
+ = \nabla B(x_{\mu},\mu) + J_{c}(x_{\mu})^{T}\lambda_{\mu} = 0\quad \text{and}\quad c(x_{\mu}) = 0
 \end{equation}
-If we call $\lambda_{\mu}\in\R^{m}$ the vector of components $\lambda_{\mu,i} = \mu / c_{i}(x_{\mu})$, the upper condition can then be written as :
+The derivations for $\nabla B$ only holds for the $x$ variables, so that :
+\[
+\nabla B(x,\mu) = \nabla f(x) + \left(\begin{matrix}\mu/(x_{u,1}-x_{1}) \\ \vdots \\ \mu/(x_{u,n}-x_{n})\end{matrix}\right) - \left(\begin{matrix}\mu/(x_{1}-x_{l,1}) \\ \vdots \\ \mu/(x_{n}-x_{l,n})\end{matrix}\right)
+\]
+If we respectively call $z_{u}(x,\mu) = \left(\mu/(x_{u,1}-x_{1}),\dots, \mu/(x_{u,n}-x_{n})\right)$ and $z_{l}(x,\mu)$ the other vector appearing in the above equation, then the optimum $(x_{\mu},\lambda_{\mu})$ 
+satisfies :
 \begin{equation}\label{muproblemlambda}
- \nabla f(x_{\mu}) - J_{c}(x_{\mu})^{T}\lambda_{\mu}= 0
+\nabla f(x_{\mu}) + J_{c}(x_{\mu})^{T}\lambda_{\mu}+ z_{u}(x_{\mu},\mu) - z_{l}(x_{\mu},\mu) = 0 \quad \text{and} \quad c(x_{\mu}) = 0
 \end{equation}
-It should remind something of the Lagrange multipliers, and indeed, when certain assumptions are met, when $\mu\rightarrow 0$, the $\lambda_{\mu, i}$ converge toward some suitable Lagrange multipliers for the KKT conditions. 
-
-
-Equation \ref{muproblemlambda} is solved by performing a Newton method  in order to find a solution of \ref{muproblem} for each of the decreasing values of $\mu$. Some order 2 conditions are also taken into account to avoid convergence to local maximizer, see \cite{ipintro} for precision about them. In a classical IP algorithm, the Newton method is directly applied to \ref{muproblem}. This is in most case inefficient due to frequent computation of infeasible points. These difficulties ar [...]
-
+In this equation, the $z_l$ and $z_u$ vectors seems to play the role of Lagrange multipliers for the simple bounds inequalities, and indeed, when $\mu\rightarrow 0$, they converge toward some suitable Lagrange multipliers for the KKT conditions, provided some technical assumptions are fulfilled (see \cite{ipintro}). 
+
+Equation \ref{muproblemlambda} is solved by performing a Newton method  in order to find a solution of (\ref{muproblem}) for each of the decreasing values of $\mu$. Some order 2 conditions are also taken into account to avoid convergence to local maximizer, see \cite{ipintro} for precision about them. In the most classical IP algorithms, the Newton method is directly applied to (\ref{muproblem}). This is in most case inefficient due to frequent computation of infeasible points. These dif [...]
+\begin{equation}\label{PrimalDualIPBarrierProblem}
+\left\lbrace\begin{array}{rcl}
+\nabla f(x) + J_{c}(x)^{T}\lambda+ z_{u} - z_{l} & = & 0 \\
+c(x) & = & 0 \\
+(X_u - X) z_u - \mu e & = & 0 \\
+(X - X_l) z_l - \mu e & = & 0 
+\end{array}\right.
+\end{equation}
+Where if $a$ is a vector of $\R^n$, $A$ denotes the diagonal matrix $A=(a_i \delta_{ij})_{1\leq i,j\leq n}$ and $e\in\R^{n} = (1,1,\dots,1)$. Solving this nonlinear system by the Newton methods is known as being
+the \textit{primal-dual} interior points method. Here again, more details are available in \cite{ipintro}. Most actual implementations introduce features in order to globalize the convergence capability of the method, essentially by 
+adding some line-search steps to the Newton algorithm, or by using trust regions. For the purpose of IPOPT, this is achieved by a \textit{filter line search} methods, the details of which can be found in \cite{iplinesearch}.
 
-More IPOPT specific features or implementation details can be found in \cite{ipopt}. We will just retain that IPOPT is a smart Newton method for solving constrained optimization problem. Thus, the optimization process requires expressions of all derivatives up to the order 2 of the fitness function as well as those of the constraints. For problems whose hessian are difficult to compute or leads to high dimension dense matrices, it is possible to use a BFGS approximation of these objects  [...]
+More IPOPT specific features or implementation details can be found in \cite{ipopt}. We will just retain that IPOPT is a smart Newton method for solving constrained optimization problem, with global convergence capabilities due to a robust line search method (in the sense that the algorithm will convergence no matter the initializer). Due to the underlying Newton method, the optimization process requires expressions of all derivatives up to the order 2 of the fitness function as well as  [...]
 
 
 \subsubsection{IPOPT in FreeFem++}
@@ -10679,8 +10684,10 @@ Here are some other valid definitions of the problem (cases when $f$ is a pure q
   \item[\texttt{pivtol} :] {\tt real} value to set the pivot tolerance for the linear solver. A smaller number pivots for sparsity, a larger number pivots for stability. The value has to be in the $[0,1]$ interval and is set to $10^{-6}$  by default.
   \item[\texttt{brf} :] Bounds relax factor : before starting the optimization, the bounds given by the user are relaxed. This option sets the factor for this relaxation. If it is set to zero, then the bounds relaxation is disabled. This {\tt real} has to be positive and its default value is $10^{-8}$.
   \item[\texttt{objvalue} :] An identifier to a {\tt real} type variable to get the last value of the objective function (best value in case of succes).
-  
+  \item[\texttt{mumin} :] Minimal value for the barrier parameter $\mu$, a {\tt real} with $10^{-11}$ as default value.
+  \item[\texttt{linesearch} :] A boolean which disables the line search when set to {\tt false}. The line search is activated by default. When disabled, the method becomes a standard Newton algorithm other the primal-dual system. The global convergence is then no longer assured, meaning that many initializers could lead to diverging iterates. But on the other hand, it can be useful when trying to catch a precise local minimum without having some out of control process making the iterate  [...]
 \end{description}
+%% fin de   version S. Auliac du 26/08/2013 ...
 
 \subsection{Some short examples using IPOPT}
 \begin{example}[IpoptVI.edp]
@@ -10817,7 +10824,7 @@ This metric is used to express the area of the surface. Let $g=\det(G)$, then we
 The volume of the space enclosed within the shape is easier to express :
 \begin{equation}\label{msvolume}
 	\mathcal{V}(\rho)
-	= \MyInt{\Omega}{\int_{0}^{\rhotp} r^{2}\sin(\phi) �dr d\theta d\phi}
+	= \MyInt{\Omega}{\int_{0}^{\rhotp} r^{2}\sin(\phi) dr d\theta d\phi}
 	= \frac{1}{3}\MyInt{\Omega}{\rho^{3} \sin(\phi) d\theta d\phi}
 \end{equation}
 
@@ -11105,7 +11112,7 @@ All the nlOpt features are called that way :
 
 The possible optional named parameters are the following, note that they are not used by all algorithm s (some does not supports constraints, or a type of constraints, some are gradient-based and other are derivative free, etc...). One can refer to the table after the parameters description to check which are the named parameters supported by a specific algorithm. Using an unsupported parameter will not stop 
 the compiler work and seldom breaks runtime, it will just be ignored. That said, when it is obvious you are missusing a routine, you will get a warning message at runtime (for exemple if you pass a gradient 
-to a derivative free algorithm, or set the population of a non-genetic one, etc...). In the following description, $n$ stands for the dimension of the search space.\\�\\
+to a derivative free algorithm, or set the population of a non-genetic one, etc...). In the following description, $n$ stands for the dimension of the search space.\\ \\
 
 
 
@@ -11688,7 +11695,7 @@ communicators in \texttt{FreeFem++}.
 %%%
 %%%The possible optional named parameters are the following, note that they are not used by all algorithm s (some does not supports constraints, or a type of constraints, some are gradient-based and other are derivative free, etc...). One can refer to the table after the parameters description to check which are the named parameters supported by a specific algorithm. Using an unsupported parameter will not stop 
 %%%the compiler work and seldom breaks runtime, it will just be ignored. That said, when it is obvious you are missusing a routine, you will get a warning message at runtime (for exemple if you pass a gradient 
-%%%to a derivative free algorithm, or set the population of a non-genetic one, etc...). In the following description, $n$ stands for the dimension of the search space.\\�\\
+%%%to a derivative free algorithm, or set the population of a non-genetic one, etc...). In the following description, $n$ stands for the dimension of the search space.\\ \\
 %%%
 %%%
 %%%\index{ffNLOpt}
diff --git a/DOC/manual-full.tex b/DOC/manual-full.tex
index ce99a0d..454b7d3 100644
--- a/DOC/manual-full.tex
+++ b/DOC/manual-full.tex
@@ -1,8841 +1,8841 @@
-%&LaTeX
-\documentclass[a4paper,twoside,12pt]{book}
-\usepackage{styles}
-\def\key#1{\emph{#1}\index{#1}}
-\def\vec#1{\mbox{\boldmath $#1$}}
-\def\C{\mathbb{C}}
-\def\Z{\mathbb{Z}}
-\def\N{\mathbb{N}}
-
-\def\setS#1{#1\label{sec:#1}}
-\def\refSec#1{Section \ref{sec:#1}}
-\def\refChap#1{Chapter \ref{sec:#1}}
-\def\borderarray#1#2#3#4#5#6{%
-\setbox0\hbox{$\begin{array}{#5}#6\end{array}$}
-\setlength{\dimen1}{\wd0}\addtolength{\dimen1}{-#3}\addtolength{\dimen1}{-\arraycolsep}
-\setlength{\dimen2}{\ht0}\addtolength{\dimen2}{-#4}
-\setbox1\hbox{$\left#1\rule{\dimen1}{0pt}\rule{0pt}{\dimen2}\right#2$}
-\setbox0\hbox{\raisebox{\dp0}{\box0}\kern-\dimen1\kern-5pt\raisebox{\dp1}{\box1}}
-\vcenter{\box0}
-}
-
-\title{
-%\DeclareFixedFont{\TitreFont}{\encodingdefault}{pnc}{r}{\shapedefault}{70pt}
- {\Blue{ \TitreFont FreeFem++ \\ \vglue 1cm  Manual}} \\ \vglue 3cm  ~ \\
-      \normalsize  { version 1.46-1  \Red{(Under construction)} }
- \\ \vglue 0.7cm
- \large \url{http://www.freefem.org} \\
-\url{http://www.freefem.org/ff++/index.htm}
-}
-\author{F. Hecht \thanks{\url{mailto:hecht at ann.jussieu.fr}},
- O. Pironneau \thanks{\url{mailto:pironneau at ann.jussieu.fr}},
-\\ Universit\'{e} Pierre et Marie Curie,
-\\  Laboratoire Jacques-Louis Lions,
-\\175 rue du Chevaleret ,PARIS XIII
-\\ ~ \\  K. Ohtsuka  \thanks{\url{mailto:ohtsuka at barnard.cs.hkg.ac.jp}}, \\
-Hiroshima Kokusai Gakuin University, Hiroshima, Japan
-}
-\makeindex
-\begin{document}
-\graphicspath{{./}{plots/}{figures/}}
-\ifpdf
-\DeclareGraphicsExtensions{.pdf ,.jpg , .tif}
-\else
-\DeclareGraphicsExtensions{.eps ,.ps ,.jpg}
-\fi
-
-\maketitle
-
-\tableofcontents
-\let\subsubsection\subsection
-\let\subsection\section
-\let\section\chapter
-\section{Introduction}
-A partial differential equation is a relation between a function
-of several variables and its (partial) derivatives.
- Many problems in physics, engineering, mathematics and even banking
-are modeled by one or several partial differential equations.
-\\\\
-
-\texttt{Freefem} is a software to solve these equations numerically.
-As its name says, it is a free software (see copyright for full detail)
-based  on the Finite
-Element Method. This software runs on all unix OS (with g++ 2.95.2 or
-better and X11R6) , on Window95, 98, 2000, NT, XP,  on MacOS 9 and
-X.  \\\\
-Many phenomena involve several different fields.  Fluid-structure
-interactions, Lorenz forces in liquid aluminium and ocean-atmosphere
-problems are three such systems. These require approximations of
-different degrees, possibly on different meshes.  Some algorithms such
-as Schwarz' domain decomposition method also require data
-interpolation on different meshes within one
-program. \texttt{freefem++} can handle these difficulties, i.e. {\it
-arbitrary finite element spaces on arbitrary unstructured and adapted
-meshes}.  \\\\
-
-The characteristics of \freefempp are:
-\begin{itemize}
-\item A large variety of finite elements : linear and quadratic
- Lagrangian elements, discontinuous P1 and Raviart-Thomas elements,
- elements of a non-scalar type, mini-element, ...
-\item  Automatic interpolation of data on different meshes to an over mesh, store the interpolation matrix.
-%
-\item Linear problems description (real or complex) thanks to a formal variational form,
-with access to the vectors and the matrix if needed.
-%
-\item Includes tools to define discontinuous Galerkin formulations
-(please refer to the following keywords: ``jump'', ``average'',
-``intalledges'').
-%
-\item Analytic description of boundaries. When two boundaries
-intersect, the user must specify the intersection points.
-%
-\item Automatic mesh generator, based on the Delaunay-Vorono\"{i}
-algorithm. Inner points density is proportional to the density of
-points on the boundary \cite{George}.
-%
-\item Metric-based anisotropic mesh adaptation. The metric can be
-computed automatically from the Hessien of a solution \cite{bamg}.
-%
-%\item Every variable is typed. For instance \texttt{f} is a function, specified
-%by the keyword \texttt{func}.
-%
-\item Solvers : LU, Cholesky, Crout, CG, GMRES, UMFPACK linear solver,
-eigenvalue and eigenvector computation.
-%
-\item Online graphics, C++-like syntax.
-%
-\item Many examples: Navier-Stokes, elasticity, Fluid structure,
-Schwarz's domain decomposition method, Eigen value problem, residual
-error indicator, ...
-%
-\item Parallel version using \texttt{mpi}
-\end{itemize}
-
-
-\subsection{History}
-
-The project has evolved from \texttt{MacFem, PCfem}, written in
-Pascal. The first C version was \texttt{freefem 3.4}; it offered mesh
-adaptation on a single mesh.  A thorough rewriting in C++ led to
-\texttt{freefem+ 1.2.10}, which also included interpolation over
-multiple meshes (functions defined on one mesh can be used on any
-other mesh).  Implementing the interpolation from one unstructured
-mesh to another was not easy because it had to be fast and
-non-diffusive; for each point, one had to find the containing
-triangle. This is one of the basic problems of computational geometry
-(see Preparata \& Shamos\cite{Preparata} for example). Doing it in a
-minimum number of operations was a challenge.  Our implementation was
-$O(n\log n)$ and based on a quadtree.  \\\\
-
-We are now introducing \freefempp, an entirely new program written
-in C++ and based on \texttt{bison} for a more adaptable
-freefem language.
-\\\\
-
-The freefem language allows for a quick specification of any partial
-differential system of equations.  The language syntax of \freefempp
-is the result of a new design which makes use of the STL \cite{cpp},
-templates and \texttt{bison} for its implementation,
- for more detail see \cite{FHcpp}.
-  The outcome is a
-versatile software in which any new finite element can be included in
-a few hours; but a recompilation is then necessary.  The library of
-finite elements available in \freefempp will therefore grow with the
-version number.  So far we have linear and quadratic Lagrangian
-elements, discontinuous P1 and Raviart-Thomas elements.
-
-\subsection{Getting Started}
-\label{sec:example}
-
-We explain how \freefempp solve the problem \textbf{Poisson};
-For a given function $f(x,y)$, find a function $u(x,y)$ satisfying
-\begin{eqnarray}
-\label{eqn:Poisson}
--\Delta u(x,y) &=& f(x,y)\quad \mbox{if $(x,y)$ is in }\Omega,
-\qquad \Delta u = \partial^2 u/\partial x^2 + \partial^2 u/\partial y^2,\\
-\label{eqn:Dirichlet}
-u(x,y) &=& 0\quad \mbox{if $(x,y)$ is on }\partial\Omega
-\end{eqnarray}
-The following example shows \freefempp program solving $u$ when
-$f(x,y)=xy$ (see 5th line) and $\Omega$ is the unit disk. The boundary $C=\partial\Omega$ is
-$$
-C=\{(x,y)|\; x=\cos(t),\, y=\sin(t),\, 0\le t\le 2\pi\}
-\quad \textrm{(see 1st line)}
-$$
-The domain will
-be on the left side of the oriented boundary by the parameter $t$.
-As illustrated in Fig. \ref{firstU}, we can see the isovalue of $u$ by using \ttCC{@plot} (see 13th line).
-\twoplot[height=5cm]{firstTh}{firstU}{mesh \ttCC{Th} by \ttCC{build(C(50))}}{isovalue by \ttCC{plot(u)}}
-
-\begin{example}\label{exm:first}~
-\bFF
- 1: @border C(t=0,2*@pi){@x=cos(t); @y=sin(t);label=1;}
- 2: @mesh Th = @buildmesh (C(50));
- 3; @fespace Vh(Th, at P2);
- 4: Vh u,v;
- 5: @func f= x*y;
- 6: @problem Poisson(u,v, at solver=LU) =
- 7:    @int2d(Th)(@dx(u)*@dx(v) + @dy(u)*@dy(v))   //  bilinear part
- 8:    - @int2d(Th)( f*v)          // right hand side
- 9:    + @on(1,u=0)  ;  // Dirichlet boundary condition
-10:
-11: @real cpu=clock();
-12: Poisson; // SOLVE THE PDE
-13: @plot(u);
-14: @cout << " CPU time = " << clock()-cpu << @endl;
-\eFF
-\end{example}
-
-\subsubsection{FEM by \freefempp}
-The example shows \freefempp covers  easily all standard step in FEM (finite element method).
-We explain how they are done by \freefempp in a step-by-step manner.\\
-
-\textbf{Step1: Mesh Generation}\\
-
-\textbf{1st line:} the boundary $\Gamma$ are described analytically (by opposition to CSG)
-as stated before.
-In the case $\Gamma=\sum_{j=0}^J \Gamma_j$ with curves $\Gamma_j$, then
-the user must specify the
-intersection points in case two boundaries intersect.
-By the use of the keyword ``label'' such as
-\bT
- at border Gamma1(t=a1,b1) { x=$\cdots$; y=$\cdots$ ;label=1; }
- $\vdots$        $\vdots$           $\vdots$      $\vdots$
- at border GammaJ(t=aJ,bJ) { x=$\cdots$; y=$\cdots$;label=1; }
-\eT
-the user can refer to $\Gamma$  by the number ``1''.
-(examples are in \refSec{Meshing Examples}).
-
-\textbf{2nd line:} the triangulation $\mathcal{T}_h$ of $\Omega$ is
-automatically generated  by
-``\ttCC{@buildmesh}(C(50))'' giving 50 points on $C$ as in Fig. \ref{firstTh}.
-Automatic mesh generation is based on the Delaunay-Voronoi algorithm.
-Refinement of the mesh are done by increasing the points on $\Gamma$,
-for example, ``\ttCC{@buildmesh}(C(100))'', because inner vertices are
-determined by the density of points on the boundary.
-
-The symbol $\mathcal{T}_h$ (\texttt{Th} in \freefempp) shows
-a family $\{T_k\}_{k=1,\cdots,n_t}$ of triangles in Fig. \ref{firstTh}
-with the size $h$ of the mesh.
-Here $n_t$ stands for the number of
-triangules in $\mathcal{T}_h$.
-If $\Omega$ is not polygonal domain, a ``skin'' remains between
-the exact domain $\Omega$ and its approximation
-$\Omega_h=\cup_{k=1}^{n_t}T_k$.
-However, we notice that all corners of $\Gamma_h = \partial\Omega_h$ are
-on $\Gamma$.\\
-
-\textbf{Step2: Making finite element space}\\
-
-\textbf{3rd line:} ``\ttCC{@fespace} Vh(Th,P2)'' makes the continuous Finite Element SPACE
-\begin{equation}
-V_h(\mathcal{T}_h,P_2)=\left\{w(x,y)\left|\;
-w(x,y)=\sum_{k=0}^{M-1}w_k\phi_k(x,y),\, w_k\textrm{ are real numbers}\right.\right\}
-\end{equation}
-where $P_2$ indicate $\phi_k$ is a polynomial of degree $\le 2$, that is,
-in each $T_k$,
-$$
-\phi_k(x,y)=\alpha_1+\alpha_2x+\alpha_3y+\alpha_4x^2+\alpha_5xy+\alpha_6y^2
-$$
-and the constants $\alpha_1,\,\cdots,\, \alpha_6$ are defined by its values
-at the vertices of $T_k$ and their middle points that continuous in $\Omega$.
-Here $w_k$ are called the degree of freedom of $w$ and $M$ the number of
-the degree of freedom.
-Already \freefempp implemented
-P0, P1, P2, RT0, P1nc, P1dc, P2dc, P1b, P2b elements, .
-The user can easily add a part of arbitrary degree elements to \freefempp,
-so the available finite elements will differ with the version.\\
-
-\textbf{Step3: Setting the problem}\\
-
-\textbf{4th line:} ``\texttt{Vh u}'' declare that $u$ is approximated
-through the use of the basis functions $\phi_k$ in $V_h$, that is,
-\begin{equation*}
-u(x,y)\simeq u_h(x,y)=\sum_{k=0}^{M-1} u_k\phi_k(x,y)
-\end{equation*}
-\textbf{5th line:} the given function $f$ is defined analytically using the keyword
-\ttCC{@func}.
-
-\textbf{6th--9th lines:} the formulation of (\ref{eqn:Poisson}) and
-(\ref{eqn:Dirichlet}) are done.
-
-Multiplying (\ref{eqn:Poisson}) by $v(x,y)$ and integrating
-the result over $\Omega$, we have
-$$
--\int_{\Omega}v\Delta u \,dxdy = \int_{\Omega} vf\, dxdy
-$$
-Then, by Green's formula, the problem Poisson is translated into finding $u$
-such that
-\begin{eqnarray}
-\label{eqn:weakform}
-&&a(u,v) - \ell(f,v) = 0
-\qquad \textrm{for all }v\\
-&&a(u,v)=\int_{\Omega}\nabla u\cdot \nabla v \,dxdy
-\quad \ell(f,v)=\int_{\Omega}fv\, dxdy
-\label{eqn:bilinear}
-\end{eqnarray}
-satisfying $v=0$ on $\partial\Omega$. In \freefempp
-the problem \textbf{Poisson} is declared by
-\begin{center}
-\ttCC{Vh u,v; @problem Poisson(u,v) =}
-\end{center}
-and (\ref{eqn:weakform}) is expressed by symbols \ttCC{@dx}(u) $=\partial u/\partial x$, \ttCC{@dy}(u) $=\partial u/\partial y$ and
-\begin{eqnarray*}
-&&\int_{\Omega}\nabla u\cdot \nabla v\, dxdy \longrightarrow
-\ttCC{@int at 2d(Th)( @dx(u)*@dx(v) + @dy(u)*@dy(v) )}\\
-&&\int_{\Omega}fv\, dxdy \longrightarrow
-\ttCC{@int at 2d(Th)( f*v )}\qquad
-\textrm{(notice here, $u$ is unused)}\\
-\end{eqnarray*}
-In \freefempp the first and second formulas just above must be distinguished each other.
-Because, the linear system to be solved are created from substituting $u_h$ for $u$ and $\phi_i$ for $v$ in (\ref{eqn:weakform}),
-\begin{eqnarray}
-\label{eqn:Equation}
-A_{ij}u_j - F_i=0\quad i,j=0,\cdots,M-1;\qquad
-F_i=\int_{\Omega}f\phi_i\, dxdy
-\end{eqnarray}
-and the solution $u_h=\sum_{j=0}^{M-1}u_j\phi_j$  must
-satisfy ``$u_h=0$ on $\Gamma_h\simeq C$''.
-The matrix $A=(A_{ij})$ is called \emph{stiffness matrix}
-\index{matrix!stiffness matrix} and is modified from
-\begin{eqnarray}
-\label{eqn:Stiffness0}
-A^0=\{A^0_{ij}\},\, A^0_{ij}=\int_{\Omega}\nabla \phi_j\cdot \nabla \phi_i \,dxdy\quad i.j=0,\cdots,M-1
-\end{eqnarray}
-to ensure $u=0$ on $C$ by ``+\ttCC{@on}\{1,u=0\}'' in 9th line.
-If you want use the symbol ``C'' such as ``+\ttCC{@on}\{C,u=0\}'' (9th line),
-then \emph{the user do not use the keyword ``label''}.
-
-we can create directly the stiffness matrix $A$ in
-(\ref{eqn:Equation}) by
-\bT
- at varf a(u,v) = @int2d(Th)( @dx(u)*@dx(v) + @dy(u)*@dy(v))
-               + @on(C,u=0) ;
- at matrix A=a(Vh,Vh);  // stiffness matrix, see (\ref{eqn:Stiffness0})
-\eT
-(see Example \ref{exm:second}).
-The vector $B$ in (\ref{eqn:Equation}) is called \emph{load matrix}
-\index{matrix!load matrix}, and also we get it:
-\bT
- at varf b([v],[f]) = @int2d(Th)(v*f);
- at matrix B=b(Vh,Vh);
-\eT
-
-The linear system (\ref{eqn:Equation}) is solved by a Gauss LU
-factorization. You can declare the solver of (\ref{eqn:Equation}),
-for example,
-\begin{center}
-\ttCC{Vh u,v; @problem Poisson(u,v, at solver=CG) =}
-\end{center}
-means that (\ref{eqn:Equation}) will be solved by Conjugate Gradient method.\\
-
-\textbf{Step4: Solving and visualization}\\
-
-\textbf{11th line:} the current time is stored into the real-valued variable \ttCC{cpu}.
-
-\textbf{12th line:} the problem is solved by calling its name.
-
-\textbf{13th line:} the visualization is done as illustrated in Fig. \ref{firstU}
-(see \refSec{Plot} for zoom, postscript and other commands).
-
-\textbf{14th line:} the time in calculation is outputed into your console
-(= default of standard output) using C++-like syntax.
-The user need not study C++ for using \freefempp, because
-C++-like syntax is used for input/output, loops, flow-controls etc.
-
-\subsubsection{Features of \freefempp}
-
-The language it
-defines is typed, polymorphic and reentrant with macro generation (see
-\ref{macro}).  Every variable must be typed and declared in a
-statement; each statement separated from the next by a semicolon
-`\texttt{;}'.
-
-For purposes of explanation, we used $\mathcal{T}_h$ (\texttt{Th}),\, $V_h$ (\texttt{Vh}), unknown function $u$ (\texttt{u}), test functions $v$ (\texttt{v}) and the problem \textbf{Poisson}, etc. (the term inside the parentheses are symbols in \freefempp programming), but
-you can use \emph{any name except reserved words and names already used}.
-Reserved words are shown in blue. \texttt{pi, x, y, label, solver} are
-reserved variables. It is allowed (although not advisable) to redefine
-these variables, so they will not be highlighted again in the
-following example programs.\\\\
-
-In each step, the independence in \freefempp programming is very high
-as stated below.
-\begin{itemize}
-  \item
-  For example, by changing 1st and 2nd lines as
-  following, we can solve (\ref{eqn:Poisson}) and (\ref{eqn:Dirichlet})
-  in L-shape domain with $\Gamma=\sum_{j=1}^6\Gamma_j$.
-\bT
- at border G1(t=0,1){x=t;y=0;@label=1;}  // $\Gamma_1$
- at border G2(t=0,0.5){x=1;y=t;@label=1;}  // $\Gamma_2$
- at border G3(t=0,0.5){x=1-t;y=0.5;@label=1;}  // $\Gamma_3$
- at border G4(t=0.5,1){x=0.5;y=t;@label=1;}  // $\Gamma_4$
- at border G5(t=0.5,1){x=1-t;y=1;@label=1;}  // $\Gamma_5$
- at border G6(t=0,1){x=0;y=1-t;@label=1;}  // $\Gamma_6$
- at mesh Th = @buildmesh ( G1(6)+G2(4)+G3(4)+G4(4)+G5(4)+G6(6));
-\eT
-  \item
-  In Step 3, you can control where the solution will be approximated.
-  If you write ``\texttt{Vh(Th,P1);}'' in 3rd line, you can get $P_1$-approximation. The machine time by $P_1$-element will be faster than $P_2$-element
-  and the storage is less.
-  \item
-  In Step 4, you can change the equation and boundary conditions easily.
-  For example, if you want solve
-  \begin{eqnarray*}
-  -\textrm{div}(k(x,y)\nabla u(x,y))&=&f(x,y)\quad\textrm{in }\Omega\\
-  u(x,y)&=&0\qquad \textrm{if $(x,y)$ on }\Gamma
-  \end{eqnarray*}
-  you only write as follows
-  \bT
-  @func f= $\cdots$;
-  @func k= 1+sin(2*pi*x)*cos(2*pi*y);
-  @problem Poisson(u,v) =
-     @int2d(Th)(k*(@dx(u)*@dx(v) + @dy(u)*@dy(v)))
-     - @int2d(Th)( f*v)
-     + @on(1,u=0)  ;
-  \eT
-  \emph{The user can use FE-function as the given function $f$ } (see \refSec{FE-function}), for example, obtained function \texttt{u} in Example \ref{exm:first}.
-  In \freefempp programming, the easy reuse of the obtained results
-  is important feature.
-  \item
-  The user can easily compare between mathematical modelling and \freefempp program.
-\end{itemize}
-
-\subsection{Projection or Interpolation}
-\index{P1-projection}
-For a finite element space $V_h$, $P_1$-projection $\Pi_h$ is defined by
-\[
-\Pi_h f=f(q^1)\phi_1+f(q^2)\phi_2+\cdots +f(q^{n_v})\phi_{n_v}
-\]
-for all continuous functions $f$. In \freefempp we can easily create the
-projection $f_h(=\texttt{fh})$ by
-\bT
-Vh fh = $f(x,y)$;
-\eT
-$\Pi_h$ is also called $P_1$-interpolate.
-
-\subsection{\setS{Matrix and Vector}}
-Here, we show how to get the stiffness matrix using \freefempp
-The first command \texttt{varf} is to define the \key{variational formula}.
-\begin{example}\label{exm:second}
-Here we solve the same problem (\ref{eqn:Poisson}) and (\ref{eqn:Dirichlet})
-using matrix.
-For purposes of explanation, we chage mesh size and use $P_1$-element:
-\bT
- 1: @border C(t=0,2*pi) { x = cos(t); y = sin(t); }
- 2: @mesh Th = @buildmesh(C(7));  // changed from Example \ref{exm:first}
- 3: @fespace Vh(Th,P1);
- 4: Vh u,v,f,F;
- 5: @varf a(u,v) = @int2d(Th)( @dx(u)*@dx(v) + @dy(u)*@dy(v))
- 6:             + @on(C,u=0) ; // see (\ref{eqn:Stiffness0})
- 7: @varf b([v],[f]) = @int2d(Th)(v*f);
- 8:
- 9: f = x*y;  // interpolate $(x,y) \longleftarrow x*y$ function
-10: @matrix A=a(Vh,Vh);  // stiffness matrix, see (\ref{eqn:Equation})
-11: @matrix B=b(Vh,Vh);
-12: F[]=B*f[];     // load vector, see (\ref{eqn:Equation})
-13: @cout << "F=" << F[] << @endl;
-14: @cout <<"A="<< A << @endl;
-15: u[]=A^-1*F[];  // solve $A\vec{U}_h = \vec{F}$, see (\ref{eqn:Equation})
-16: @plot(u);
-\eT
-
-We get the mesh $\mathcal{T}_h=\{T_1,\cdots,T_7\}$ (see Fig. \ref{fig:secondTh}).
-\begin{note}
-\label{note:mesh}
-In what follows, we denote the vertices by $q^i,\, i=1,\cdots,8$,
-the number of vertices by $n_v$, the number of triangles by $n_t$.
-For each triangle $T_k\in \mathcal{T}_h$, we index the vertices by
-$q^{k_1},\, q^{k_2},\, q^{k_3}$ and denote the edges by
-$[q^{k_1}, q^{k_2}]$, $[q^{k_2}, q^{k_3}]$, $[q^{k_3}, q^{k_i}]$, that is,
-$[q^i,q^j]$ is the segment connecting $q^i$ and $q^j$.
-We denote the number of edges $[q^i,q^j]$
-by $n_e$ for all $q^i,\, q^j\partial\Omega_h$,
-$\Omega_h=\sum_{k=1}^7T_k$.
-Here $n_v=8$, $n_t=7$, $n_e=7$.
-\end{note}
-\begin{figure}[htbp]
-\begin{minipage}{\textwidth}
-\begin{minipage}{0.3\textwidth}
-\includegraphics[width=\textwidth]{secondT}%
-\caption{mesh \texttt{Th}}
-\label{fig:secondTh}
-\end{minipage}
-\hspace{0.5mm}
-\begin{minipage}{0.7\textwidth}
-\includegraphics[width=\textwidth]{hat}%
-\caption{Graph of $\phi_1$ (left hand side) and $\phi_6$}
-\label{fig:hatFunction}
-\end{minipage}
-\end{minipage}
-\end{figure}
-
-
-The function $v$ in ``\texttt{Vh}'' is expressed
-\begin{equation*}
-v(x)=v_{1}\varphi _{1}(x) +\cdots +v_{n_{v}}\varphi _{n_{v}}(x)
-\end{equation*}%
-using the \key{hat functions} $\varphi _{j},\,j=1,\cdots ,n_{v}$ (see Fig.
-\ref{fig:hatFunction}).
-Here the $j$-th hat function $\varphi _{j}$ associated with $j$-th
-vertex $q^j$ is defined in the following way:
-\begin{enumerate}
-\item $\varphi _{j}$ is continuous function on $\Omega_h$.
-
-\item $\varphi _{j}$ is linear on each triangle $T_k,\, k=1,\cdots,n_{t}$
- of ``\texttt{Th}''.
-
-\item $\varphi _{j}\left( {q^{i}}\right) =\delta _{ji}$ where $q^{i}$
-denotes the $i$-th vertex, for all $i=1,\cdots ,n_{v}$.
-\end{enumerate}
-Here $\delta_{ij}$ is the Kronecker symbol.
-
-\begin{note}
-Other finite element spaces in \freefempp are explained in \refSec{Finite Elements}.
-\end{note}
-\begin{note}
-\label{note:FE2VEC}
-For an element $v=v_1\phi_1+\cdots+v_M\phi_M$ in
-a finite element space $V_h$, we get the \emph{column vector}
-$\{v\}$
-\[
-\{v\}=\left[
-\begin{array}{c}
-v_1\\
-\vdots\\
-v_M
-\end{array}
-\right]\qquad
-\{v\}=\texttt{v[]}\quad \textrm{in \freefempp}
-\]
-\end{note}
-Theoretically, it is natural to use the finite element space
-\[
-H^1_{0h}=
-\left\{v\in V_h(\mathcal{T}_h,P_1)\left|
-\phi_i(x)=0\quad \textrm{if }q^i\in \partial\Omega_h
-\right.\right\}
-\]
-Let $I_{\Omega}$ be the set of indices $i$ of all internal vertices of the mesh
-\texttt{Vh}. In this example, $I_{\Omega}=\{6\}$.
-The stiffness matrix $A$ in 10th line is:
-\begin{eqnarray}
-\label{eqn:StiffnessDirichlet}
-\borderarray{[}{]}{1em}{1.2ex}{rrrrrrrrr}{
-&1&2&3&4&5&6&7&8\\
-1&10^{30}& -0.31& 0& 0&-0.46& -0.51& 0&0\\
-2&-0.31& 10^{30}& -0.23& 0& 0&-0.71& 0&0\\
-3&0&-0.23&10^{30}&-0.31& 0&-0.71& 0&0\\
-4&0& 0&-0.31&10^{30}& 0& -0.51& -0.46&0 \\
-5&-0.46& 0& 0& 0&10^{30}& -0.35& 0&-0.54\\
-6&-0.51& -0.71& -0.71& -0.51& -0.35& 3.47& -0.35& -0.30\\
-7&0& 0& 0&-0.46& &-0.35& 10^{30}& -0.54\\
-8&0& 0& 0& 0&-0.54&-0.30&-0.54& 10^{30}
-}
-\end{eqnarray}
-that is
-\begin{eqnarray}
-A_{ij}&=&\int_{\Omega_h}\nabla u_j\cdot \nabla u_i\quad
-\textrm{if }i\neq j,\, i=j\in I_{\Omega}\\
-A_{ij}&=&E\qquad (E=10^{30})\quad \textrm{if }j\in I_{\Omega}.
-\end{eqnarray}
-The load matrix $F^T$ is:
-\begin{eqnarray*}
-\left(
-\begin{array}{cccccccc}
--0.020& -0.037& 0.037& 0.020&0.064& 0& -0.064&1.\times 10^{-17}
-\end{array}
-\right)
-\end{eqnarray*}
-For $i\not\in I_{\Omega}$,
-\[
-Eu_i+\sum_{i\neq j}A_{ij}u_j=b_i
-\]
-which means that
-\[
-u_i=(b_i-\sum_{i\neq j}A_{ij}u_j)\times E^{-1}\simeq 10^{-30}\simeq 0
-\]
-\end{example}
-
-Mathematical results indicate that the Poisson equation
-with Neaumann boundary condition has not unique solution,
-whose weak form is same to (\ref{eqn:Poisson}) except the boundary condition:
-\[
-\int_{\Omega}\nabla u\cdot \nabla v = \int_{\Omega}fvdx
-\]
-without pernarization $E$. Then the stiffness matrix is created by
-\bT
- at varf a(u,v) = @int2d(Th)( @dx(u)*@dx(v) + @dy(u)*@dy(v))
- at matrix A=a(Vh,Vh); // stiffness matrix
-\eT
-and the obtained stiffness matrix is the following
-\[
-\borderarray{[}{]}{1em}{1.2ex}{rrrrrrrrr}{
-&1&2&3&4&5&6&7&8\\
-1&1.29&-0.31&0&0&-0.46&-0.51&0&0\\
-2&-0.31&1.26&-0.23&0&0&-0.71&0&0\\
-3&0&-0.23&1.26&-0.31&0&-0.71&0&0\\
-4&0&0&-0.31&1.29&0&-0.51&-0.46&0\\
-5&-0.46&0&0&0&1.35&-0.35&0&-0.54\\
-6&-0.51&-0.71&-0.71&-0.51&-0.35&3.47&-0.35&-0.30\\
-7&0&0&0&-0.46&0&-0.35&1.35&-0.54\\
-8&0&0&0&0&-0.54&-0.30&-0.54&1.38
-}
-\]
-The determinant of this matrix is $-1.7082274230870981\times 10^{-9}\approx 0$
-(The matrix here differ from original one by omitting from third decimal decimal point).
-
-\subsubsection{Non-homogeneous Dirichlet Condition}
-If we want solve the problem
-\[
--\Delta u=f\quad \textrm{in }\Omega;\qquad
-u=g\quad \textrm{on }\partial\Omega
-\]
-We rewrite Example \ref{exm:first} as
-\bT
- 5: @func f= x*y; @func g = sin(pi*x)*cos(pi*y);
- 6: @problem Poisson(u,v, at solver=LU) =
- 7:    @int2d(Th)(@dx(u)*@dx(v) + @dy(u)*@dy(v))   //  bilinear part
- 8:    - @int2d(Th)( f*v)          // right hand side
- 9:    + @on(1,u=g)  ;  // Non-homogeneous Dirichlet
-\eT
-This make the following linear system, for $i\not\in I_{\Omega}$,
-\[
-Eu_i+\sum_{i\neq j}A_{ij}u_j=b_i+Eg(q^i)
-\]
-which means that
-\[
-u_i=g(q^i)+(b_i-\sum_{i\neq j}A_{ij}u_j)\times E^{-1}\simeq g(q^i)+O(1/E)
-\]
-\begin{note}
-To solve non-homogeneous Dirichlet, we rewrite Example \ref{exm:second} as
-\bT
- 4: Vh u,v,f,F,g,bc; g = sin(pi*x)*cos(pi*y);
- 5: @varf a(u,v) = @int2d(Th)( @dx(u)*@dx(v) + @dy(u)*@dy(v))
- 6:             + @on(C,u=1) ; // see (\ref{eqn:Stiffness0})
-10: @matrix A=a(Vh,Vh); bc[]=a(0,Vh);
-12: F[]=B*f[];  F[] += bc[] .* g[];
-\eT
-Here ``\texttt{bc[]=a(0,Vh)}'' create the vector
-$[bc_1,bc_2,\cdots,bc_M]$, $bc_i=0$ if $i\in I_{\Omega}$ and
-$bc_i=E (=10^{30})$ if $i\not\in I_{\Omega}$.
-If the finite approximation of $g$ is $g\approx g_1\phi_1+\cdots+g_M\phi_M$
-\begin{equation}
-\texttt{bc[] .* g[]}=\sum_{j=0}^{M-1} bc_jg_j
-\end{equation}
-\end{note}
-
-\subsubsection{\setS{Matrix Operations}}
-
-The multiplicative operators *, /, and \% group left to right.
-
-\begin{itemize}
-\item  \verb@'@  is unary right transposition of array, matrix \index{transpose}
- \item \verb at .*@ is the term to term multiply operator. \index{.*} \index{\string'} \index{divide!term to term}
- \item \verb at ./@ is the term to term divide operator. \index{./} \index{\string'} \index{product!term to term}
-\end{itemize}
-there are some compound operator:
-\begin{itemize}
- \item \verb@^-1@ is for  solving the linear system (example: \verb$ b = A^-1 x$) \index{solve!linear system}
- \item \verb@' *@ is the compound  of transposition and matrix product, so it is the dot product
-(example \verb$real DotProduct=a'*b$) \index{dot product}\index{product!dot}
-\end{itemize}
-\begin{example}~
-\bFF
- at mesh Th = @square(2,1);
- at fespace Vh(Th,P1);
-Vh f,g;
-f = x*y;
-g = sin(pi*x);
-Vh<complex> ff,gg; // a complex valued finite element function \index{FE function!complex}
-ff= x*(y+1i);
-gg = exp(pi*x*i);
- at varf mat(u,v) =
-  int2d(Th)(1*dx(u)*dx(v)+2*dx(u)*dy(v)+3*dy(u)*dx(v)+4*dy(u)*dy(v))
-  + on(1,2,3,4,u=1);
- at varf mati(u,v) =
-  int2d(Th)(1*dx(u)*dx(v)+2i*dx(u)*dy(v)+3*dy(u)*dx(v)+4*dy(u)*dy(v))
-  + on(1,2,3,4,u=1);
- at matrix A = mat(Vh,Vh); @matrix<complex> AA = mati(Vh,Vh); // a
-complex sparse matrix \index{matrix:complex}
-
-Vh m0; m0[] = A*f[];
-Vh m01; m01[] = A'*f[];
-Vh m1; m1[] = f[].*g[];
-Vh m2; m2[] = f[]./g[];
- at cout << "f = " << f[] << @endl;
- at cout << "g = " << g[] << @endl;
- at cout << "A = " << A << @endl;
- at cout << "m0 = " << m0[] << @endl;
- at cout << "m01 = " << m01[] << @endl;
- at cout << "m1 = "<< m1[] << @endl;
- at cout << "m2 = "<< m2[] << @endl;
- at cout << "dot Product = "<< f[]'*g[] << @endl;
- at cout << "hermitien Product = "<< ff[]'*gg[] << @endl;
-\eFF
-This produce the following:
-\begin{eqnarray*}
-A&=&\borderarray{[}{]}{1em}{1.2ex}{rrrrrrrr}{
-&1&2&3&4&5&6\\
-1&10^{30}& 1 0.5& 0&3 0.& 4 -2.5& 0\\
-2&0.&10^{30}&0.5& 0&0.5&-2.5\\
-3&0&0.&10^{30}& 0& 0&0.5\\
-4&0.5& 0& 0& 10^{30}& 0.& 0\\
-5&-2.5&0.5& 0&0.5&10^{30}&0.\\
-6&0&-2.5&0.& 0&0.5& 10^{30}
-}
-\\
-\{v\}=\texttt{f[]}&=&
-\left(
-\begin{array}{rrrrrr}
-0 & 0 & 0 & 0 & 0.5 & 1
-\end{array}
-\right)^T\\
-\{w\}=\texttt{g[]}&=&
-\left(
-\begin{array}{rrrrrr}
-0 &1  &1.2\times 10^{-16}& 0 & 1 & 1.2\times 10^{-16}
-\end{array}
-\right)^T\\
-\texttt{A*f[]}&=&
-\left(
-\begin{array}{rrrrrr}
--1.25 &  -2.25 &  0.5   & 0 & 5\times 10^{29} & 10^{30}
-\end{array}
-\right)^T\quad (=A\{v\})\\
-\texttt{A'*f[]}&=&
-\left(
-\begin{array}{rrrrrr}
--1.25 &  -2.25 &  0  & 0.25 & 5\times 10^{29} & 10^{30}
-\end{array}
-\right)^T\quad (=A^T\{v\})\\
-\texttt{f[].*g[]}&=&
-\left(
-\begin{array}{rrrrrr}
-0 & 0 & 0 & 0 & 0.5 & 1.2\times 10^{-16}
-\end{array}
-\right)^T\quad =(v_1w_1\quad\cdots\quad v_Mw_M)^T\\
-\texttt{f[]./g[]}&=&
-\left(
-\begin{array}{rrrrrr}
--nan & 0  & 0  & -nan  & 0.5 & 8.1\times 10^{15}
-\end{array}
-\right)^T\quad =(v_1/w_1\,\cdots\, v_M/w_M)^T\\
-\texttt{f[]'*g[]}&=&0.5\quad
-(=\{v\}\{w\}^T=\{v\}\cdot\{w\})
-\end{eqnarray*}
-\end{example}
-\begin{note}
-The operators \verb|^-1| cannot create the matrix by themselves.
-Indeed, the following occur errors
-\bT
- at matrix AAA = A^-1;
-\eT
-\end{note}
-
-%%%  modif FH july 2005----
-\subsection{Block matrix}
-\bFF
-  matrix A=[[A11,0,B1],[0,A11,0,B1],[B1',B2',0]];
-  set(A,solver=UMFPACK); //  by default no solver is defined
-  real[int] b=[b1[],b2[],b3[]];
-  [b1[],b2[],b3[]]= A^-1*b;
-\eFF
-%%%  fin modif FH july 2005
-
-\subsection{\setS{Modeling}--Edit--Run--Visualize--Revise}
-\bigskip
-\freefempp provide many examples and its documentation, so you can easily calculate
-mathematical models by FEM (finite element method) and study them.
-Explanations for these examples are given in this book. If you are a
-beginner of FEM, you start from Quick Tour of
-\freefempp. The numerical simulation of scientific problem will be done as follows.
-
-\begin{description}
-\item[Modeling:] Make a mathematical model describing scientific problems.
-Mathematical modeling is a deep and fruitful one, with many important
-implications for scientific problems
-(refer to Chapter \ref{sec:MathModels}).
-
-\item[Programming:] Translate the mathematical model to
-\freefempp source code, which is easy because \freefempp
-includes many clever techniques in FEM with mathematical writing.
-
-\item[Run:] Next step is to run it to see if it works. If we provisionally
-give the name of the source code to ``something.edp'', we can execute it by
-the typing\newline
-\newline
-\texttt{\% freefem++ something.edp}
-
-An important part in programming is to keep aware of collections of
-programs that are available, and this manual contains many examples you
-can use freely. So we hope you to run these examples and their
-representing mathematical models, which are contained in the package in
-\freefempp.
-
-\item[Visualization:] The numerical calculation by FEM make huge data, so
-the easy way to check the obtained result is their visualization. \freefempp
-can display the mesh and the contour lines of obtained functions. If
-you want to use these visualization after execution, you add the filename of
-PostScript to the commands ``plot'' (see \refSec{Plot}).
-
-\item[Debugging:] If the boolean value of ``wait'' is true (default is `false'), then
-\freefempp will stop at the information in visual form.
-Write the following, execute it and make a change the line
-``\ttCC{@wait=@true}'' to ``\ttCC{@wait=@false}''.
-\bT
- at bool wait = true;  // set "true" if you want see each plotting
-mesh Th = @square(10,10,[-1+2*x,-1+2*y]); // $]-1,1[^2$
- at plot(Th);  // plot the mesh
- at fespace Vh(Th,P2);
-Vh f = @sin(pi*x)*@cos(pi*y);
-plot(f,wait=wait);  // plot the function f
-Vh g = @sin(@pi*x + @cos(@pi*y));
- at plot(g,wait=wait);  // plot the function g
-\eT
-If there is a fatal error in your
-source code, \freefempp will end and cause an error message to appear. In MS-Windows, \freefempp will open the message file by notepad.
-For example, if you forget parenthesis as in
-\bT
- at mesh Th = @square(10,10;
- at plot(Th);
-\eT
-then you will get the following message from \texttt{freefem++},
-\bT
-mesh Th = square(10,10;
- Error line number 0, in file xxxxxx.edp, before  token ;
-parse error
-Compile error : parse error
-        line number :0, ;
- at exec line  0
-error Compile error : parse error
-        line number :0, ;
-\eT
-If you use the same symbol twice as in
-\bT
- at real aaa =1;
- at real aaa;
-\eT
-then you will get the message
-\bT
-real aaa =1;
-    1 : real aaa; The identifier aaa exist
-\eT
-Notice that the line number start from 0.
-If you find that the program isn't doing what you want it
-to do, then you check the line number and try to figure out
-what's wrong.
-We give two techniques; One is \emph{trace} by \ttCC{@plot}
-for \emph{meshes} and (FE-)functions with \ttCC{@wait=@true},
-and by \ttCC{@cout} for scalar, vectors and matrices.
-Another is to \emph{comment out} by ``\ttCC{//}''.
-If you find a doubtful line in your source code, you comment out
-as follows,
-\bT
- at real aaa =1;
-// real aaa;
-\eT
-\end{description}
-
-\bigskip
-
-\subsection{Installation}
-
-There are binary packages available for Microsoft Windows and Apple
-Mac OS. For all other platforms, \freefempp must be compiled and
-installed from the source archive. This archive is available from:
-
-\url{http://www.ann.jussieu.fr/~hecht/ftp/freefem/freefem++.tgz}.
-
- To
-extract files from the compressed archive \texttt{freefem++.tgz} into
-a directory called \texttt{freefem++-X.XX} (where X.XX is the version number)
-enter the following commands in a shell window~:
-
-\bFF
-tar zxvf freefem++.tgz
-cd freefem++-X.XX
-\eFF
-
-To compile and install \freefempp, just follow the \texttt{INSTALL}
-and \texttt{README} files. The following programs are produced,
-depending on the system you are running (Linux, Windows, MacOS)~:
-
-\begin{enumerate}
-\item \texttt{FreeFem++}, standard version, with a graphical interface
-based on X11, Win32 or MacOS
-\item \texttt{FreeFem++-nw}, postscript plot output only (batch version, no windows)
-\item \texttt{FreeFem++-mpi}, parallel version, postscript output only
-\item \texttt{FreeFem++-glx}, graphics using OpenGL and X11
-\item \texttt{FreeFem++-cs}, integrated development environment
-(please see chapter ``Graphical User Interface'' for more details).
-\item \texttt{/Applications/FreeFem++.app}, Drag and Drop CoCoa MacOs
-Application
-\item \texttt{FreeFem++-CoCoa}, MacOS Shell script for MacOS OpenGL
-version (MacOS 10.2 or better) (note: it uses
-/Applications/FreeFem++.app)
-\end{enumerate}
-
-As an installation test, go into the directory
-\texttt{examples++-tutorial} and run \freefempp on the example script
-\texttt{LaplaceP1.edp} with the command~:
-
-\bFF
-FreeFem++ LaplaceP1.edp
-\eFF
-
-\textBlack
-\section{Syntax}
-\subsection{Data Types}
-Basically \freefempp  is a \index{compiler} compiler,
-  the language is typed, polymorphic and reentrant.
-Every variable must be typed, declared in a  statement;
-each statement separated
-from the next by a semicolon `\texttt{;}'.
-The language allows the manipulation of basic types
-integers (\texttt{int}), reals (\texttt{real}), strings (\texttt{string}),
-arrays (example: \texttt{real[int]}),
- bidimensional (2D) finite element meshes (\texttt{mesh}),
-2D finite element spaces (\texttt{fespace}) , definition of functions
-(\texttt{func}), arrays of
-finite element functions (\texttt{func$[basic\_type]$}),
-linear and bilinear operators, sparse matrices, vectors , etc. For instance
-
-\bFF
-  @int i,n=20;               //  $ i,n$ are integer.
-  @real[@int] xx(n),yy(n);    //  two array of size n
-  @for (i=0;i<=20;i++)       // which can be used in statements such as
-   { xx[i]= cos(i*pi/10); yy[i]= sin(i*pi/10); }
-\eFF
-The life of a variable is the current block $\{\ldots \}$, except the \texttt{fespace} variable, and the in variables local to a block are destroyed at the end of the block as follows.
-\begin{example}~~
-\bT
- at real r= 0.01;
- at mesh Th=@square(10,10); // unit square mesh
- at fespace Vh(Th, at P1);     // P1 lagrange finite  element space
-Vh u = x+ exp(y);
- at func f = z * x + r * log(y);
- at plot(u,wait=true);
-{  // new block
-  @real r = 2; // not the same r
-  @fespace Vh(Th, at P1);//  error because Vh is a global name
-}  // end of block
-//  here r back to 0.01
-\eT
-\end{example}
-The type declarations are  compulsory in \freefempp  because it is easy
-to make bugs in a language with many types. \index{variable} The
-variable name is just an alphanumeric \index{alphanumeric} string, the
-underscore character  ``\texttt{\_}'' is not allowed, because
-it will be used as an operator in the future.\index{\_}
-
-\subsection{List of major types}
-\begin{description}
-\item[bool]   is used for logical expression and flow-control.
-\index{bool}\index{true}\index{false}
-\item[int]
-  declare an integer.
-\item[string] declare the varible to store
-a text enclosed within double quates, such as:
-\bT
-"This is a string in double quotes."
-\eT
-\index{string}
-\item[real] declare the variable to store a number such as ``12.345''. \index{real}
-\item[complex]  Complex numbers, such as
-$1+2i,\, i=\sqrt{-1}$.
-\bT
- at complex a =  1 at i, b = 2 + 3 at i;
- at cout << "a + b = " << a + b << @endl;
- at cout << "a - b = " << a + b << @endl;
- at cout << "a * b = " << a * b << @endl;
- at cout << "a / b = " << a / b << @endl;
-\eT
-Here's the output;
-\bT
-a + b = (2,4)
-a - b = (-2,-2)
-a * b = (-3,2)
-a / b = (0.230769,0.153846)
-\eT
-\item[ofstream]  make a output file and its functions.
-\item[ifstream]   make a input file and its functions.
-
-\item[real[int]]  declare a variable that store multiple
-real numbers with integer index.
-\index{array}
-\bT
- at real[@int] a(5);
-a[0] = 1; a[1] = 2; a[2] = 3.3333333; a[3] = 4; a[4] = 5;
- at cout << "a = " << a  << @endl;
-\eT
-This produces the output;
-\bT
-a = 5   :
-  1       2     3.33333   4       5
-\eT
-\item[real[string]]  declare a variable that store multiple
-real numbers with string index.
-\item[string[string]]  declare a variable that store multiple
-strings with string index.
-\index{array}
-\itemtt[func] define a function without argument,
-if independent variables are \ttCC{x, y}.
-For example
-\bT
- at func f=cos(x)+sin(y) ;
-\eT
-\index{func}
-Remark the function's type is given by the expression's type.
-The power of functions are given in \freefempp such as
-\ttCC{x\^{}1}, \ttCC{y\^{}0.23}.
-
-\itemtt[mesh]  \index{mesh}
-create the triangulation, see \refSec{Mesh Generation}.
-\itemtt[fespace]
-define a new type of finite element space, see Section \refSec{Finite Elements}.
-\itemtt[problem]  declare the weak form of a partial differential problem without solving. \index{problem}
-\itemtt[solve]  declare a problem and solve it.\index{solve}
-\itemtt[varf]   define a full variational form. \index{varf}
-\itemtt[matrix] define a sparse matrix. \index{matrix}
-\end{description}
-
-\subsection{Global Variables}\label{sec:Global}
- The names \ttCC{x,y,z,label,region,P,N,nu\_triangle} are used to link
-the language to the finite element tools:
-\begin{description}
-    \itemtt[x]  expresses $x$ coordinate of current point (real value) \index{x}
-    \itemtt[y]  expresses $y$ coordinate  of current point (real value) \index{y}
-    \itemtt[z]  expresses $z$ coordinate of current point (real value) \index{z}, but is reserved for future use.
-\itemtt[label] show the label number of boundary if the  current point is
-on a boundary, otherwise 0 (int value). \index{label}
-    \item[region]   returns the region number of  the current point (x,y) (int value). \index{region}
-\itemtt[P]  give the  current point  ($\R^{2}$ value. \index{P}).
-By \texttt{P.x}, \texttt{P.y}, we can get the $x,\, y$ components of \texttt{P} .
-Also \texttt{P.z} is reserved.
-    \itemtt[N]  give the outward unit normal vector at the  current point is on the curve define by \texttt{border} ($\R^{3}$ value).
-\texttt{N.x} and \texttt{N.y} are $x$ and $y$ components of the normal vector.
-\texttt{N.z} is reserved. \index{N}.
-    \itemtt[lenEdge] give the length of the current edge\index{lenEdge}\\
-    \[
-    \texttt{lenEdge} = |q^i-q^j|\quad \textrm{if the current edge is }[q^i,q^j]
-    \]
-
-    \itemtt[hTriangle] give the size of the current triangle \index{hTriangle}
-
-    \itemtt[nuTriangle] give the index of the current triangle (integer).
-    \index{nuTriangle}
-
-    \itemtt[nuEdge]  give the index of the current edge in the triangle (integer).
-    \index{nuEdge}
-
-    \itemtt[nTonEdge] give the number of adjacent triangle of the current
-    edge (integer ).\index{nTonEdge}
-
-    \itemtt[area] give the area of the current triangle (real). \index{area}
-
-\itemtt[cout]  is the standard output device (default is console).
-On MS-Windows, the standard output is only to console, in this time.
-  \Ostream
-\itemtt[cin]  is the standard input device (default is keyboard). (\Istream).
-On MS-Windows, this don't work.
-\itemtt[endl] give the end of line in the input/output devices.
-\itemtt[true]   means ``true'' in  \Bool\  value.
-\itemtt[false]  means ``false'' in  \Bool\ value.
-\itemtt[pi]   is the \Real ~approximation value of $\pi$.
-\end{description}
-
-\medskip
-
-Here is how to show all the types, and all the operator and functions.
-\bFF
- @dumptable(@cout);
-\eFF \index{dumptable}
-To execute a system command in the string (not implemented on Carbon
-MacOs)
-\bFF
-  @exec("shell command");
-\eFF
-On MS-Windows, we need the full path. For example, if there is the command
-``ls.exe'' in the subdirectory ``\verb|c:\cygwin\bin\|'', then we must write
-\bFF
-  @exec("c:\\cygwin\\bin\\ls.exe");
-\eFF
-\index{exec}
-
-
-\subsection{Arithmetic}
-In integers, $+,\, -,\, *$ express the usual arithmetic summation (plus),
-subtraction (minus) and multiplication (times), respectively.
-The operators $/$ and $\%$ yield the quotient and the remainder from the division of the first expression by the second.
-If the second number of $/$ or $\%$ is zero the behavior is undefined.
-The \key{maximum} or \key{minimum} of two integers $a,\, b$ are obtained
-by \texttt{max($a$,$b$)} of
-\texttt{min($a$,$b$)}.
-The power $a^b$ of two integers $a,\, b$ is calculated by writing \verb|a^b|.
-\begin{example} Calculations with the integers
-\label{exm:int}
-\bFF
- at int a = 12, b = 5;
- at cout <<"plus, minus of "<<a<<" and "<<b<<" are "<<a+b<<", "<<a-b<<@endl;
- at cout <<"multiplication, quotient of them are "<<a*b<<", "<<a/b<<@endl;
- at cout <<"remainder from division of "<<a<<" by "<<b<<" is "<<a%b<<@endl;
- at cout <<"the minus of "<<a<<" is "<< -a << @endl;
- at cout <<a<<" plus -"<<b<<" need bracket:"<<a<<"+(-"<<b<<")="<<a+(-b)<<@endl;
- at cout <<"max and min of "<<a<<" and "<<b<<" is "<<@max(a,b)<<","<<@min(a,b)<< @endl;
- at cout <<b<<"th power of "<<a<<" is "<<a^b<< @endl;
-b=0;
- at cout <<a<<"/0"<<" is "<< a/b << @endl;
- at cout <<a<<"\%0"<<" is "<< a\%b << @endl;
-\eFF
-produce the following result:
-\bFF
-plus, minus of 12 and 5 are 17, 7
-multiplication, quotient of them are 60, 2
-remainder from division of 12 by 5 is 2
-the minus of 12 is -12
-12 plus -5 need bracket :12+(-5)=7
-max and min of 12 and 5 is 12,5
-5th power of 12 is 248832
-12/0 : long long long
-Fatal error : ExecError  Div by 0 at exec line  9
-Exec error : exit
-\eFF
-\end{example}
-
-By the relation $integer\subset real$, the operators
-``$+,\, -,\, *,\, /,\, \%$'' and ``\ttCC{@max,\, @min,\, \^}''
-are also applicable in real-type. However,  $\%$
-calculates the remainder of the integral parts of two real numbers.
-
-The following example similar to Example \ref{exm:int}
-\bT
- at real a=sqrt(2.), b = pi;
- at cout <<"plus, minus of "<<a<<" and "<<pi<<" are "<< a+b <<", "<< a-b << @endl;
- at cout <<"multiplication, quotient of them are "<<a*b<<", "<<a/b<< @endl;
- at cout <<"remainder from division of "<<a<<" by "<<b<<" is "<< a%b << @endl;
- at cout <<"the minus of "<<a<<" is "<< -a << @endl;
- at cout <<a<<" plus -"<<b<<" need bracket :"<<a<<"+(-"<<b<<")="<<a + (-b) << @endl;
-\eT
-gives the following output:
-\bT
-plus, minus of 1.41421 and 3.14159 are 4.55581, -1.72738
-multiplication, quotient of them are 4.44288, 0.450158
-remainder from division of 1.41421 by 3.14159 is 1
-the minus of 1.41421 is -1.41421
-1.41421 plus -3.14159 need bracket :1.41421+(-3.14159)=-1.72738
-\eT
-
-By the relation
-$$
-bool\subset int \subset real\subset complex,
-$$
-the operators
-``$+,\, -,\, *,\, /$'' and ``\ttCC{\^}'' are also applicable in complex-type,
-but ``\%,\, max, min'' fall into disuse.
-Complex number such as \texttt{5+9i},\, i$=\sqrt{-1}$, can be a little tricky.
-For real variables \texttt{a=2.45, b=5.33}, we must write the complex numbers
-\texttt{a+b*i} and \ttCC{a+ at sqrt(2.0)*i} as
-\bT
- at complex z1 = a+b*1i, z2=a+ at sqrt(2.0)*1i;
-\eT
-The imaginary and real parts of complex number \texttt{z} is obtained by
-\ttCC{@imag} and \ttCC{@real}.
-The conjugate of $a+bi$ ($a,b$ are real) is defined by $a-bi$, which
-is denoted by \ttCC{@conj(a+b*1i)} in \freefempp.
-
-The complex number $z=a+ib$ is considered as
-the pair $(a,b)$ of real numbers $a,\, b$.
-Now we draw the point $(a,b)$ in the plane (Cartesian rectangular system
-of axes) and mark on the $x$-axis the real numbers in the usual way, on the
-$y$-axis the imaginary numbers with $i$ as unit.
-By changing Cartesian coordinate $(a,b)$ to the polar coordinate $(r,\phi)$,
-the complex number $z$ has another expression $z=r(\cos \phi+i\sin\phi )$,
-$r=\sqrt{a^2+b^2}$ and $\phi=\tan^{-1}(b/a)$;
-$r$ is called the \key{absolute value} and $\phi$ the \key{argument} of $z$.
-In the following example, we shall show them using \freefempp programming,
-and \key{de Moivre's formula} $z^n=r^n(\cos n\phi+i\sin n\phi)$.
-
-\begin{example}~
-\label{exm:complex}
-\bFF
- at real a=2.45, b=5.33;
- at complex  z1=a+b*1i, z2 = a+sqrt(2.)*1i;
- at func @string pc(@complex z) // printout complex to (real)+i(imaginary)
-{
-   @string r = "("+real(z);
-   if (@imag(z)>=0) r = r+"+";
-   @return r+ at imag(z)+"i)";
-}
-// printout complex to |z|*(cos(arg(z))+i*sin(arg(z)))
- at func @string toPolar(@complex z)
-{
-   @return @abs(z)+"*(cos("+ at arg(z)+")+i*sin("+ at arg(z)+"))";
-}
-cout <<"Standard output of the complex "<<pc(z1)<<" is the pair "
-     <<z1<<endl;
-cout <<"Plus, minus of "<<pc(z1)<<" and "<<pc(z2)<<" are "<< pc(z1+z2)
-     <<", "<< pc(z1-z2) << endl;
-cout <<"Multiplication, quotient of them are "<<pc(z1*z2)<<", "
-     <<pc(z1/z2)<< endl;
-cout <<"Real/imaginary part of "<<pc(z1)<<" is "<<@real(z1)<<", "
-     <<@imag(z1)<<endl;
-cout <<"Absolute of "<<pc(z1)<<" is "<<@abs(z1)<<endl;
-cout <<pc(z2)<<" = "<<toPolar(z2)<<endl;
-cout <<"  and polar("<<@abs(z2)<<","<<@arg(z2)<<") = "
-     << pc(@polar(abs(z2),arg(z2)))<<endl;
-cout <<"de Moivre's formula: "<<pc(z2)<<"^3 = "<<toPolar(z2^3)<<endl;
-cout <<"conjugate of "<<pc(z2)<<" is "<<pc(@conj(z2))<<endl;
-cout <<pc(z1)<<"^"<<pc(z2)<<" is "<< pc(z1^z2) << endl;
-\eFF
-Here's the output from Example \ref{exm:complex}
-\bT
-Standard output of the complex (2.45+5.33i) is the pair (2.45,5.33)
-Plus, minus of (2.45+5.33i) and (2.45+1.41421i) are (4.9+6.74421i), (0+3.91579i)
-Multiplication, quotient of them are (-1.53526+16.5233i), (1.692+1.19883i)
-Real/imaginary part of (2.45+5.33i) is 2.45, 5.33
-Absolute of (2.45+5.33i) is 5.86612
-(2.45+1.41421i) = 2.82887*(cos(0.523509)+i*sin(0.523509))
-  and polar(2.82887,0.523509) = (2.45+1.41421i)
-de Moivre's formula: (2.45+1.41421i)^3
-                         = 22.638*(cos(1.57053)+i*sin(1.57053))
-conjugate of (2.45+1.41421i) is (2.45-1.41421i)
-(2.45+5.33i)^(2.45+1.41421i) is (8.37072-12.7078i)
-\eT
-\end{example}
-
-\subsection{\setS{One Variable Functions}}
-\index{functions}
-\begin{description}
-  \item[Fundamental functions] are built into \freefempp.
-The \emph{power function} \ttCC{x\^}$\alpha (=x^\alpha)$;
-the \emph{exponent function} \ttCC{@exp(x)} ($=e^x$);
-the \emph{logarithmic function} \ttCC{@log(x)}($=\ln x$) or
-\ttCC{@log10(x)} ($=\log_{10}x$);
-the \emph{trigonometric functions} \ttCC{@sin(x), @cos(x), @tan(x)}
-depending on angles measured by \emph{radian};
-the inverse of $\sin x,\, \cos x,\, \tan x$ called \emph{circular function} or \emph{inverse trigonometric function} \ttCC{@asin(x)}(=$\arcsin x$), \ttCC{@acos(x)}(=$\arccos x$), \ttCC{@atan(x)}(=$\arctan x$);
-the \emph{hyperbolic function},
-\[
-\sinh x=\left( e^x-e^{-x}\right)/2,\qquad
-\cosh x=\left( e^x+e^{-x}\right)/2.
-\]
-and $\tanh x=\sinh x/\cosh x$ written
-by \ttCC{@sinh(x)}, \ttCC{@cosh(x)}, \ttCC{@asinh(x)} and \ttCC{@acosh(x)}.
-\[
-\sinh^{-1}x=\ln \left[x+\sqrt{x^2+1}\right],\qquad
-\cosh^{-1}x=\ln \left[x+\sqrt{x^2-1}\right].
-\]
-\itemtt[Elementary Functions]
-is the class of functions consisting of the functions in this section
-(polynomials, exponential, logarithmic, trigonometric, circular) and
-the functions obtained from those listed by the four arithmetic operations
-\[
-f(x)+g(x),\, f(x)-g(x),\, f(x)g(x),\, f(x)/g(x)
-\]
-and by superposition $f(g(x))$, in which four arithmetic operarions and superpositions are permitted finitely many times.
-In \freefempp, we can create all elementary functions.
-The derivative of an elementary function is also elementary.
-However, the indefinite integral of an elementary function cannot always be expressed in terms of elementary functions.
-\begin{example}
-The following give the example
-to make the boundary using elementary functions.
-\emph{Cardioid}
-\bT
- at real b = 1.;
- at real a = b;
- at func @real phix(@real t)
-{
-   @return (a+b)*cos(t)-b*cos(t*(a+b)/b);
-}
- at func @real phiy(@real t)
-{
-   @return (a+b)*sin(t)-b*sin(t*(a+b)/b);
-}
- at border C(t=0,2*pi) { x=phix(t); y=phiy(t); }
- at mesh Th = @buildmesh(C(50));
-\eT
-\end{example}
-Taking the principal value, we can define $\log z$ for $z\neq 0$ by
-\[
-\ln z = \ln |z|+\arg z.
-\]
-Using \freefempp, we calculated
-\ttCC{@exp(1+4i)}, \ttCC{@sin(pi+1i)}, \ttCC{@cos(pi/2-1i)} and \ttCC{@log(1+2i)}, we then have
-\begin{eqnarray*}
--1.77679-2.0572i,& 1.88967 10^{-16}-1.1752i,\\
-9.44833 10^{-17}+1.1752i, & 0.804719+1.10715i.
-\end{eqnarray*}
-\end{description}
-
-\subsection{Two Variable Functions}
-\label{sec:TwoVarFunctions}
-\subsubsection{\setS{Formula}}
-The general form of real functions with two independent variables $x,\, y$ is
-usually written as $z=f(x,y)$. In \freefempp, \ttCC{x} and \ttCC{y} are
-reserved word in Section \ref{sec:Global}.
-When two independent variables are \ttCC{x} and \ttCC{y},
-we can define a function without argument, for example
-\bT
- at func f=@cos(x)+ at sin(y) ;
-\eT
-Remark the function's type is given by the expression's type.
-The power of functions are given in \freefempp such as
-\ttCC{x\^{}1}, \ttCC{y\^{}0.23}.
-In \ttCC{func}, we can write an elementary function as follows
-\bT
- at func f = @sin(x)*@cos(y);
- at func g = (x^2+3*y^2)*@exp(1-x^2-y^2);
- at func h = @max(-0.5,0.1*@log(f^2+g^2));
-\eT
-
-Complex valued function create functions with 2 variables \ttCC{x, y} as follows,
-\bT
- at mesh Th=square(20,20,[-pi+2*pi*x,-pi+2*pi*y]); // $]-\pi,\pi[^2$
- at fespace Vh(Th,P2);
- at func z=x+y*1i;  // $z=x+iy$
- at func f=@imag(sqrt(z));  // $f=\Im\sqrt{z}$
- at func g=@abs( sin(z/10)*exp(z^2/10) ); // $g=|\sin z/10\exp z^2/10|$
-Vh fh = f; plot(fh);  // contour lines of $f$
-Vh gh = g; plot(gh);  // contour lines of $g$
-\eT
-We call also by \emph{two variable elementary function} functions
-obtained from elementary functions $f(x)$ or $g(y)$
-by the four arithmetic operations
-and by superposition in finite times.
-
-\subsubsection{\setS{FE-function}}\index{FE-function}
-Arithmetic built-in functions are able to construct a new function by
-the four arithmetic operations and superposition of them
-(see \emph{elementary functions}), which are called
-\key{formulas} to distinguish from
-FE-functions.
-We can add \emph{new formulas} easily, if we want.
-Here, FE-function is an element of
-finite element space (real or complex) (see Section \refSec{Finite Elements}).
-Or to put it another way: \emph{formulas} are the
-mathematical expressions combining its numerical analogs, but
-it is independent of meshes (triangulations).
-
-Also, in \texttt{freefem++}, we can give an arbitrary symbol to FE-function
-combining numerical calculation by FEM.
-The projection of a formula $f$ to FE-space is done as in
-\bT
-func f=x^2*(1+y)^3+y^2;
-mesh Th = square(20,20,[-2+2*x,-2+2*y]); // square $]-2,2[^2$
-fespace Vh(Th,P1);
-Vh fh=f;  // fh is the  projection of f to Vh (real value)
-func zf=(x^2*(1+y)^3+y^2)*exp(x+1i*y);
-Vh<complex> zh = zf; // zh is the projection of zf
-// to complex value Vh space   \index{FE function!complex}
-\eT
-The construction of \ttCC{fh} (=$f_h$) is explained in
-\refSec{Finite Elements}.
-
-\begin{note}
-The command \ttCC{@plot} is valid only for real  FE-functions.
-\end{note}
-Complex valued function create functions with 2 variables \ttCC{x, y} as follows,
-\bT
- at mesh Th=square(20,20,[-pi+2*pi*x,-pi+2*pi*y]); // $]-\pi,\pi[^2$
- at fespace Vh(Th,P2);
- at func z=x+y*1i;  // $z=x+iy$
- at func f=@imag(sqrt(z));  // $f=\Im\sqrt{z}$
- at func g=@abs( sin(z/10)*exp(z^2/10) ); // $g=|\sin z/10\exp z^2/10|$
-Vh fh = f; plot(fh);  // Fig. \ref{cfunc1} isovalue of $f$
-Vh gh = g; plot(gh);  // Fig. \ref{cfunc2} isovalue of $g$
-\eT
-\twoplot[height=5cm]{cfunc1}{cfunc2}{$\Im\sqrt{z}$ has branch}
-{$|\sin (z/10)\exp (z^2/10)|$}
-
-\subsection{Array}
-\index{array}
-An \emph{array} stores multiple objects, and
-there are 2 kinds of arrays:
-The first is the \emph{vector} that is arrays with \emph{integer indices}
-and
-arrays with \emph{string indices}.
-
-In the first case, the size of this array
-must be know at the execution time, and the implementation is done
-with the \ttCC{KN<>} class so all the vector operator of
- \ttCC{KN<>} are implemented. The sample
-\bT
- at real [int] tab(10), tab1(10); // 2 array of 10 real
- at real [int] tab2;    //  bug array with no size
-tab = 1.03;                //  set all the array to 1.03
-tab[1]=2.15;
- at cout << tab[1] << " " << tab[9] << " size of tab = "
-     << tab.n << " min: " << tab.min << "  max:" << tab.max
-     << " sum : "   << tab.sum <<   endl; //
-tab.resize(12); //  change the size of array tab
-  // to 12 with preserving first value
-tab(10:11)=3.14; //  set unset value
-cout <<" resize tab: " <<  tab << endl;
-\eT
-\index{array!resize}\index{resize}\index{max}\index{array!max} \index{min}\index{array!min}\index{sum}\index{array!sum}
-produce the output
-\bT
-2.15 1.03 size of tab = 10 min: 1.03  max:2.15 sum : 11.42
- resize tab: 12
-        1.03    2.15    1.03    1.03    1.03
-        1.03    1.03    1.03    1.03    1.03
-        3.14    3.14
-\eT
-
-It is also possible to make an array of FE function, with the same syntax,
-and we can treat them as \emph{vector valued function} if we need them.
-\index{array}\index{array!FE function}
-\begin{example}
-In the following example, Poisson's equation is solved under 3 different given
-functions $f=1,\, \sin(\pi x)\cos(\pi y),\, |x-1||y-1|$, whose solutions are
-stored in an array of FE function.
-\bT
- at mesh Th=@square(20,20,[2*x,2*y]);
- at fespace Vh(Th,P1);
-Vh u, v, f;
- at problem @Poisson(u,v) =
-    @int2d(Th)( @dx(u)*@dx(v) + @dy(u)*@dy(v))
-     + @int2d(Th)( -f*v ) + @on(1,2,3,4,u=0) ;
-Vh[int] uu(3); // an array of FE function
-f=1;   // problem1
-Poisson; uu[0] = u;
-f=sin(pi*x)*cos(pi*y);  // problem2
-Poisson; uu[1] = u;
-f=abs(x-1)*abs(y-1);    // problem3
-Poisson; uu[2] = u;
- at for (int i=0; i<3; i++)  // plots all solutions
-  @plot(uu[i], @wait=true);
-\eT
-\end{example}
-
- For the second case, it is just
- a map of the STL\footnote{Standard template Library, now part of standard \Cpp}\cite{cpp}
- so no vector operation except the
- selection of an item is allowed . \index{dot product}\index{transpose}
-
-The transpose operator is \texttt{\string'} like  MathLab or SciLab, so the way
-to compute the dot product of two array \ttCC{a,b} is  \ttCC{@real\ ab=\ a'*b}\index{product!dot}.
-\index{min}\index{array!min}
-\bFF
- at int i;
- at real [int] tab(10), tab1(10); // 2 array of 10 real
-  \it  real [int] tab2;    //  bug array with no size
-tab = 1;                //  set all the array to 1
-tab[1]=2;
- at cout << tab[1] << " " << tab[9] << " size of tab = "
-     << tab.n << " " << tab.min << " " << tab.max << " " <<  @endl;
-tab1=tab; tab=tab+tab1; tab=2*tab+tab1*5; tab1=2*tab-tab1*5;
-tab+=tab; @cout << " dot product " << tab'*tab << @endl; //
-${}^{t}{tab}\,{tab} $ @cout << tab << @endl; @cout << tab[1] << " "
-<< tab[9] <<  @endl; @real[string] map;        //  a dynamic array
- at for (i=0;i<10;i=i+1)
-  {
-    tab[i] = i*i;
-    @cout << i << " " << tab[i] << "\n";
-  };
-
-map["1"]=2.0;
-map[2]=3.0;             //  2 is automatically cast to the string "2"
-
- at cout << " map[\"1\"] = " << map["1"] << "; "<< @endl;
- at cout << " map[2] = " << map[2] << "; "<< @endl;
-\eFF
-
-
-\subsection{\setS{Loops}}
-
-The \texttt{for} and \texttt{while}  loops are implemented
-with \texttt{break} and \texttt{continue} keywords.
-\index{for}\index{while}
-\index{break}\index{continue}
-
-In for-loop, there are three parameters;
-the INITIALIZATION of a control variable,
-the CONDITION to continue,
-the CHANGE of the control variable.
-While \texttt{CONDITION} is true, for-loop continue.
-\bT
- at for (INITIALIZATION; CONDITION; CHANGE)
-     { BLOCK of calculations }
-\eT
-The sum from 1 to 10 is calculated by (the result is in \ttCC{sum}),
-\bT
- at int sum=0;
- at for (@int i=1; i<=10; i++)
-   sum += i;
-\eT
-The while-loop
-\bT
- at while (CONDITION) {
-   BLOCK of calculations or change of control variables
-}
-\eT
-is executed repeatedly until CONDITION become false.
-The sum from 1 to 10 is also written by \ttCC{@while} as follows,
-\bT
- at int i=1, sum=0;
- at while (i<=10) {
-  sum += i; i++;
-}
-\eT
-
-We can exit from a loop in midstream by \ttCC{@break}.
-The \ttCC{@continue} statement will pass the part from
-\emph{continue} to the end of the loop.
-
-\begin{example}~
-\bFF
- at for (@int i=0;i<10;i=i+1)
-    @cout << i << "\n";
- at real eps=1;
- at while (eps>1e-5)
- { eps = eps/2;
-   @if( i++ <100) @break;
-   @cout << eps << @endl;}
-
- at for (int j=0; j<20; j++) {
-   @if (j<10) @continue;
-   @cout << "j = " << j << @endl;
-}
-\eFF
-\end{example}
-
-\subsection{\setS{Input/Output}}
-\index{cout}\index{cint}\index{ifstream}\index{ofstream}\index{endl}
-
-The syntax of input/output statements is similar  to \Cpp syntax. It
-uses \ttCC{@cout}, \ttCC{@cin}, \ttCC{@endl}, \ttCC{<<,>>}.
-
-To write  to (resp. read from)  a file, \index{$<<$} \index{$>>$}\index{append}\index{ofstream!append}
-declare a new variable \texttt{ofstream ofile("filename");} or \texttt{ofstream ofile("filename",append);} (resp.
-\texttt{ifstream ifile("filename");} ) and use \texttt{ofile}  (resp. \texttt{ifile})
-as \texttt{cout} (resp. \texttt{cin}). The word \texttt{append} in  \texttt{ofstream ofile("filename",append);}
- means openning a file in append mode.
-
-\begin{note} The file is closed
-at the exit of the enclosing block,
-\end{note}
-\begin{example}~
-\label{exm:io}
-\bFF
- at int i;
- at cout << " std-out" << @endl;
- at cout << " enter i= ? ";
- at cin >> i ;
-{
-  @ofstream f("toto.txt");
-  f << i << "coucou'\n";
-}; //  close the file f because the variable f is delete
-
-{
-  @ifstream f("toto.txt");
-   f >> i;
-}
-{
-  @ofstream f("toto.txt",append);
-     // to append to the existing file "toto.txt"
-  f << i << "coucou'\n";
-}; //  close the file f because the variable f is delete
-
-  @cout << i << @endl;
-\eFF
-\end{example}
-
-\section{\setS{Mesh Generation}}
-\subsection{Commands for Mesh Generation}\label{sec:InitialMesh}
-In Step1 in Section \ref{sec:example}, the keywords
-\texttt{\bf border, buildmesh}
-are explained.
-%square,
-%,  movemesh ,
-% adaptmesh, readmesh, trunc, triangulate, splitmesh, emptymesh}
-%
-%The following keywords are discussed in this section:
-%
-%\texttt{\bf square, border, buildmesh,  movemesh ,
-% adaptmesh, readmesh, trunc, triangulate, splitmesh, emptymesh}
-%
-% \index{square}\index{border}\index{buildmesh}\index{movemesh}\index{adaptmesh}
-% \index{readmesh}\index{triangulate}\index{splitmesh}\index{emptymesh}
-
-All the examples in this section come from the files \texttt{mesh.edp}
-and \texttt{tablefunction.edp}.
-
-\subsubsection{\setS{Square}}
-
-For easy and simple testing, there is the command
-``\texttt{\bf square}''.
-The following
-\bT
- at mesh Th = @square(4,5);
-\eT
-generate a $4\times 5$ grid in the unit squre $[0,1]^2$ whose labels
-are shown in Fig. \ref{fig:square}.
-\begin{figure}[htbp]
-\begin{center}
-  \includegraphics[height=5cm]{figures/square}
-\end{center}
-  \caption{Boundary labels of the mesh by \texttt{square(10,10)}}
-  \label{fig:square} \index{label}
-\end{figure}
-If you want constructs a
-$n\times m$ grid in the rectangle $[x_0,x_1]\times [y_0,y_1]$, you can
-write
-\bFF
-  @real x0=1.2,x1=1.8;
-  @real y0=0,y1=1;
-  @int n=5,m=20;
-  @mesh Th=@square(n,m,[x0+(x1-x0)*x,y0+(y1-y0)*y]);
-\eFF
- \begin{note}
-You must notice that if you adding the name parameter \texttt{flags=1}, you  get a
-Union Jack fags mesh pattern. \index{square!flags=}
-\bFF
-  @mesh Th=@square(n,m,[x0+(x1-x0)*x,y0+(y1-y0)*y],flags=1);
-\eFF
-\end{note}
-
-
-
-\subsubsection{\setS{Border}}\index{border}\index{label}
-
-A domain is defined as being on the left (resp right) of its
-parameterized boundary
-$$
-\Gamma_j=\{(x,y)\left|\; x=\varphi_x(t),\, y=\varphi_y(t),\, a_j\le t\le b_j\right.\}
-$$
-We can easily check the orientation by drawing the curve
-$t\mapsto (\varphi_x(t),\varphi_y(t)),\, t_0\le t\le t_1$.
-If the figure become like to Fig. \ref{fig:border}, then
-the domain lie on the shaded area, otherwise it lie on opposite side
-(see also the examples enclosed with the box).
-The boundaries $\Gamma_j$ can only intersect at their end points.
-
-\begin{figure}[htbp]
-\begin{center}
-  \includegraphics[height=4cm]{figures/border}
-\end{center}
-  \caption{Orientation of the boundary defined by $(\phi_x(t),\phi_y(t))$}
-  \label{fig:border} \index{border}
-\end{figure}
-The general expression of the triangulation is
-\[
-\ttCC{@mesh  ~~Mesh\_Name = @buildmesh$\left(\Gamma_1(m_1)+\cdots+\Gamma_J(m_j)\right)$;}
-\]
-where $m_j$ are numbers of marked points on $\Gamma_j,\,
-\Gamma=\cup_{j=1}^J \Gamma_J$.
-We can change the orientation of boundaries by changing the sign of $m_j$.
-The following example shows how to change the orientation.
-The example generates the unit disk
-with a small circular hole, and assign ``1'' to the unit disk
-(``2'' to the circle inside).
-The boundary label must be non-zero, however we can omit the label
-if we want use only the symbol.
-
-\bFF
-1: @border a(t=0,2*pi){ x=cos(t); y=sin(t);label=1;}
-2: @border b(t=0,2*pi){ x=0.3+0.3*cos(t); y=0.3*sin(t);label=2;}
-3: @plot(a(50)+b(+30)) ; // to see a plot of the border mesh \index{plot!border}
-4: @mesh Thwithouthole= @buildmesh(a(50)+b(+30));
-5: @mesh Thwithhole   = @buildmesh(a(50)+b(-30));
-6: @plot(Thwithouthole,wait=1,ps="Thwithouthole.eps"); //figure \ref{Thwithouthole}\index{plot!mesh}
-7: @plot(Thwithhole,wait=1,ps="Thwithhole.eps"); // figure \ref{Thwithhole}
-\eFF
-\begin{note}
-You must notice that the orientation is changed by ``\texttt{b(-30)}'' in 5th line. In 7th line, \texttt{ps="fileName"} is used to generate a postscript file
-identification that is shown on screen.
-\end{note}
-
-\twoplot[height=6cm]{Thwithouthole}{Thwithhole}{mesh without hole}{mesh with hole}
-
-\subsubsection{Data Structure of Mesh and Reading/Writing a Mesh}
-
-\index{readmesh}\index{savemesh}
-Some user asked us that they want use the triangulation made from other tools
-or hand-made mesh.
-The example
-\bT
- at border C(t=0,2*pi) { x=cos(t); y=sin(t); }
- at mesh Th = @buildmesh(C(10));
- at savemesh("mesh_sample.msh");
-\eT
-make the mesh as in Fig. \ref{fig:meshSample}.
-The informations about \texttt{Th} are save in the file ``mesh\_sample.msh''.
-
-We can read from Fig. \ref{fig:meshSample} and ``mesh\_sample.msh''
-as in Table \ref{tab:meshSample} where $n_v$ is
-the number of vertices, $n_t$ number of triangles
-and $n_s$ the number of edges on boundary.
-For each vertex $q^i,\, i=1,\cdots,n_v$, we denote by $(q^i_x,q^i_y)$
-the $x$-coordinate and $y$-coordinate.
-
-Each triangle $T_k, k=1,\cdots,10$ have three vertices $q^{k_1},\, q^{k_2},\,q^{k_3}$ that are oriented in counterclockwise.
-The boundary consists of 10 lines $L_i,\, i=1,\cdots,10$ whose tips are
-$q^{i_1},\, q^{i_2}$.
-
-\begin{figure}[htbp]
-\begin{minipage}{\textwidth}
-\begin{minipage}{0.5\textwidth}
-\includegraphics[width=\textwidth]{figures/mesh_sample}%
-\caption{mesh by \texttt{buildmesh(C(10))}}
-\label{fig:meshSample}
-\end{minipage}
-\hspace{0.5mm}
-\begin{minipage}{0.5\textwidth}
-In the left figure, we have the following.\\\\
-$n_v=14,\, n_t=16,\, n_s=10$\\\\
-$q^1=(-0.309016994375,\, 0.951056516295)$\\
-$\vdots\qquad \vdots\qquad \vdots$\\
-$q^{14}=(-0.309016994375,\, -0.951056516295)$\\\\
-The vertices of $T_1$ are $q^9,\, q^{12},\, q^{10}$.\\
-$\vdots\qquad \vdots\qquad \vdots$\\
-The vertices of $T_{16}$ are $q^9,\, q^{10},\, q^{6}$.\\\\
-The edge of 1st side $L_1$ are $q^6,\, q^5$.\\
-$\vdots\qquad \vdots\qquad \vdots$\\
-The edge of 10th side $L_{10}$ are $q^{10},\, q^6$.\\
-\end{minipage}
-\end{minipage}
-\end{figure}
-
-\begin{table}[htbp]
-\begin{tabular}{|l|l|}
-\hline
-Contents of file&Explanation\\
-\hline
-14 16 10& $n_v$\qquad  $n_t$\qquad $n_e$\\
--0.309016994375 0.951056516295 1& $q^1_x$\qquad $q^1_y$\qquad boundary label=1\\
-0.309016994375 0.951056516295 1& $q^2_x$\qquad $q^2_y$\qquad boundary label=1\\
-$\cdots$  $\cdots$ $\vdots$& \\
--0.309016994375 -0.951056516295 1& $q^{14}_x$\qquad $q^{14}_y$\qquad boundary label=1\\
-\hline
-9 12 10 0&$1_1$\quad $1_2$\quad $1_3$\quad region label=0 \\
-5 9 6 0&$2_1$\quad $2_2$\quad $2_3$\quad region label=0  \\
-$\cdots$& \\
-9 10 6 0&$16_1$\quad $16_2$\quad $16_3$\quad region label=0 \\
-\hline
-6 5 1&$1_1\quad 1_2$\quad boundary label=1\\
-5 2 1&$2_1\quad 2_2$\quad boundary label=1\\
-$\cdots$& \\
-10 6 1&$10_1\quad 10_2$\quad boundary label=1\\
-\hline
-\end{tabular}
-  \caption{The structure of ``mesh\_sample.msh''}
-  \label{tab:meshSample}
-\end{table}
-
-There are many mesh file formats available for communication with
-other tools such as emc2, modulef.. (see \refSec{Mesh Files}),
-The extension of a file gives the chosen
-type.\index{bamg} More details can be found in the article by F. Hecht
-"bamg : a bidimentional anisotropic mesh generator" available from the
-FreeFem web site.  \\
-
-The following give the example write and read files of generated mesh,
-Freefem can read and write files. A
-mesh file can be read back into \freefempp but the names of the
-borders are lost. So these borders have to be referenced by the number
-which corresponds to their order of appearance in the program, unless
-this number is forced by the keyword "label".
-
-\bFF
- at border floor(t=0,1){ x=t; y=0; label=1;}; // the unit square
- at border right(t=0,1){ x=1; y=t; label=5;};
- at border ceiling(t=1,0){ x=t; y=1; label=5;};
- at border left(t=1,0){ x=0; y=t; label=5;};
- at int n=10;
- at mesh th= buildmesh(floor(n)+right(n)+ceiling(n)+left(n));
- at savemesh(th,"toto.am_fmt");  // "formatted Marrocco" format \index{file!am\_fmt}
- at savemesh(th,"toto.Th");      // "bamg"-type mesh   \index{file!bamg}
- at savemesh(th,"toto.msh");     // freefem format \index{file!mesh}
- at savemesh(th,"toto.nopo");     // modulef format \index{file!nopo} see \cite{modulef}
- at mesh th2 = readmesh("toto.msh"); // read the mesh
-
-\eFF
-
-The following example explains methods to obtain mesh information.
-\index{triangle![]}\index{triangle!label}\index{triangle!label}
-\index{vertex!x}\index{vertex!y}\index{vertex!label}
-\bFF
-{  // get mesh information (version 1.37)
-  @mesh Th=square(2,2);
-  // get data of the mesh
-  @int nbtriangles=Th.nt;
-  @for (@int i=0;i<nbtriangles;i++)
-    @for (@int j=0; j <3; j++)
-      @cout << i << " " << j << " Th[i][j] = "
-           << Th[i][j] << "  x = "<< Th[i][j].x  << " , y= "<< Th[i][j].y
-           << ",  label=" << Th[i][j].label << endl;
-
-  // To Day:   this Hack works: to get x,y of vertex i \hfilll
-  // remark: i can be set with i= Th[it][j] \hfilll
-  // the idea is to build de interpolation of x and y function \hfilll
-  // with 2 array now given i -> x and i-> y. \hfilll
-
-  fespace femp1(Th,P1);
-  femp1 Thx=x,Thy=y;
-  cout << " nb of vertices = " << nbvertices << endl;
-  for (int i=0;i<nbvertices;i++)
-        cout << i  << " : " << Thx[][i] << " " << Thy[][i] << endl;
-
-  //Hack  to get a triangle number of mesh contening point x,y \hfilll
-  //     or  region number \hfilll
-  // ----------------------------------------- \hfilll
-  fespace femp0(Th,P0);
-  femp0 nuT; // a P0 function  to get triangle numbering
-    for (int i=0;i<Th.nt;i++)
-     nuT[][i]=i;
-  femp0 nuReg=region; // a P0 function to get the region number
-  //  inquire
-  int it0=nuT(0.55,0.6); //  number of triangle contening point (0.55,0,6);
-  int nr0=nuReg(0.55,0.6); //  number of region of mesh contening point (0.55,0,6);
-  // new method if   version > 1.450007
-  int it00 = Th(0.55,0.6).nuTriangle; // get the number of Th's triangle contening (0.55,0.6)
-  int nr00 = Th(0.55,0.6).region;; // get the region  number of Th's triangle
-    // dump
-  cout << "  point (0.55,0,6) :triangle number " << it0 << " " << it00
-       << ", region = " << nr0 << " == " << nr00 << endl;
-}
-
-\eFF
-the output is:
-\bFF
-0 0 Th[i][j] = 0  x = 0 , y= 0,  label=4
-0 1 Th[i][j] = 1  x = 0.5 , y= 0,  label=1
-0 2 Th[i][j] = 4  x = 0.5 , y= 0.5,  label=0
-1 0 Th[i][j] = 0  x = 0 , y= 0,  label=4
-1 1 Th[i][j] = 4  x = 0.5 , y= 0.5,  label=0
-1 2 Th[i][j] = 3  x = 0 , y= 0.5,  label=4
-.......
-5 2 Th[i][j] = 6  x = 0 , y= 1,  label=4
-6 0 Th[i][j] = 4  x = 0.5 , y= 0.5,  label=0
-6 1 Th[i][j] = 5  x = 1 , y= 0.5,  label=2
-6 2 Th[i][j] = 8  x = 1 , y= 1,  label=3
-7 0 Th[i][j] = 4  x = 0.5 , y= 0.5,  label=0
-7 1 Th[i][j] = 8  x = 1 , y= 1,  label=3
-7 2 Th[i][j] = 7  x = 0.5 , y= 1,  label=3
- Nb Of Nodes = 9
- Nb of DF = 9
- -- vector function's bound  -0 1
- -- vector function's bound  -0 1
- nb of vertices = 9
-0 : -0 -0
-1 : 0.5 -0
-2 : 1 -0
-3 : -0 0.5
-4 : 0.5 0.5
-5 : 1 0.5
-6 : -0 1
-7 : 0.5 1
-8 : 1 1
- Nb Of Nodes = 8
- Nb of DF = 8
- -- vector function's bound  -0 -0
-  point (0.55,0,6) :triangle number 7 7, region = 0 == 0
-\eFF
-\begin{example}[Readmesh.edp]
-\index{tutorial!readmesh.edp}
-\index{read files}
-\index{write files}
-\bFF
- at border floor(t=0,1){ x=t; y=0; label=1;}; // the unit square
- at border right(t=0,1){ x=1; y=t; label=5;};
- at border ceiling(t=1,0){ x=t; y=1; label=5;};
- at border left(t=1,0){ x=0; y=t; label=5;};
- at int n=10;
- at mesh th= buildmesh(floor(n)+right(n)+ceiling(n)+left(n));
- at savemesh(th,"toto.am_fmt");  // format "formated Marrocco" \index{file!am\_fmt}
- at savemesh(th,"toto.Th");      // format database  db mesh "bamg"   \index{file!bamg}
- at savemesh(th,"toto.msh");     // format freefem \index{file!mesh}
- at savemesh(th,"toto.nopo");     // modulef format \index{file!nopo} see \cite{modulef}
- at mesh th2 = readmesh("toto.msh");
- at fespace femp1(th, at P1);
-femp1 f = sin(x)*cos(y),g;
-{ // save solution
- at ofstream file("f.txt");
-file << f[] << endl;
-}  // close the file (end block)
-{  // read
- at ifstream file("f.txt");
-file >> g[] ;
-} // close reading file (end block)
- at fespace Vh2(th2,P1);
-Vh2 u,v;
- at plot(g);
-//  find $u$ such that \hfilll
-// $ u - \Delta u = g $ in $\Omega $ , \hfilll
-// $ u=0$ on $\Gamma_1$ and $\frac{\partial u }{\partial n} = g$ on $\Gamma_2$  \hfilll
- at solve pb(u,v) =
-    @int2d(th)( u*v - dx(u)*dx(v)-dy(u)*dy(v) )
-  + @int2d(th)(-g*v)
-  + @int1d(th,5)( g*v) //  $\frac{\partial u }{\partial n} = g$ on $\Gamma_2$
-  + @on(1,u=0) ;
- at plot (th2,u);
-\eFF
-\end{example}
-
-\subsubsection{Triangulate}\index{triangulate}
-
-\freefempp is able to build a triangulation from a set of points. This
-triangulation is a Delaunay mesh of the convex hull of the set of points.
-It can be useful to build a mesh form a table function.
-
-The coordinates of the points and the value of the table function
-are defined separately with rows of the form: \texttt{x y f(x,y)}
-in a file such as:
-
-\bFF
-0.51387 0.175741 0.636237
-0.308652 0.534534 0.746765
-0.947628 0.171736 0.899823
-0.702231 0.226431 0.800819
-0.494773 0.12472 0.580623
-0.0838988 0.389647 0.456045
-...............
-\eFF
-%%% Thxy.eps not found
-\twoplot[height=4cm]{Thxy}{xyf}{Delaunay mesh of the convex hull of point set in file xyf}{Isovalue of table function}
-
-The third column of each line is left untouched by the
-\texttt{triangulate} command. But you can use this third value to
-define a table function with rows of the form: \texttt{x y f(x,y)}.
-
-
-The following example shows how to make mesh from the file ``xyf''
-with the format stated just above.
-The command
-\texttt{triangulate} command use only use 1st and 2nd rows.
-
-\index{function!tables}
-
-\bFF
- at mesh Thxy=triangulate("xyf"); // build the Delaunay mesh of the convex hull
-// points are defined by the first 2 columns of file \texttt{xyf}
- at plot(Thxy,ps="Thxyf.ps"); // (see figure  \ref{Thxy})
-
- at fespace Vhxy(Thxy,P1); // create a P1 interpolation
-Vhxy fxy; // the function
-
-// reading the 3rd row to define the function
-{ @ifstream file("xyf");
-   @real xx,yy;
-   @for(@int i=0;i<fxy.n;i++)
-   file >> xx >>yy >> fxy[][i];  // to read third row only.
-   // xx and yy are just skipped
-}
- at plot(fxu,ps="xyf.eps"); // plot the function (see figure  \ref{xyf})
-\eFF
-
-\subsection{build empty mesh}\index{emptymesh}
-When you want to define Finite Element space on boundary,
-we come up with the idea of a mesh with no internal points (call empty mesh).
-It can be useful when you have a Lagrange multiplier definied on the border.
-
-So the function emptymesh remove all the internal point of a mesh expect if the
-point is on internal boundary.
-
-\bFF
-{  //  new stuff 2004 emptymesh (version 1.40)
- // -- useful to build Multiplicator space
- //  build a mesh without internal point
- // with the same boundary
- //  -----
-  assert(version>=1.40);
-  @border a(t=0,2*pi){ x=cos(t); y=sin(t);label=1;}
-  @mesh Th=buildmesh(a(20));
-   Th=@emptymesh(Th);
-  @plot(Th,wait=1,ps="emptymesh-1.eps");//see figure \ref{fig emptymesh-1}
-}
-\eFF
-
-or it is also possible to build a empty mesh of peusdo subregion
-with \texttt{emptymesh(Th,ssd)} with the set of edges of the mesh \texttt{Th}
-a edge $e$ is in  this set  if the two adjacent triangles $e =t1\cap t2$
-and  $ ssd[T1] \neq ssd[T2]$ where \texttt{ssd}  defined the peusdo region numbering of triangle, when they are stored in \texttt{int[int]} array of size the number of triangles.
-\bFF
-{  //  new stuff 2004 emptymesh (version 1.40) \hfilll
- // -- useful to build Multiplicator space \hfilll
- //  build a mesh without internal point \hfilll
- // of peusdo sub domain  \hfilll
- //  ----- \hfilll
-  assert(version>=1.40);
-  mesh Th=square(10,10);
-  int[int] ssd(Th.nt);
-  for(int i=0;i<ssd.n;i++) // build the  peusdo region numbering
-   {  int iq=i/2;   // because 2 traingle per quad
-      int ix=iq%10; //
-      int iy=iq/10; //
-    ssd[i]= 1 + (ix>=5) +  (iy>=5)*2;
-   }
-  Th=emptymesh(Th,ssd); // build emtpy  with
-  //  all edge $e = T1 \cap T2$ and $ ssd[T1] \neq ssd[T2]$
-  plot(Th,wait=1,ps="emptymesh-2.eps");//see figure \ref{fig emptymesh-2}
-  savemesh(Th,"emptymesh-2.msh");
-}
-\eFF
-
-\twoplot[height=6cm]{emptymesh-1}{emptymesh-2}{ The empty mesh with boundary
-\label{fig emptymesh-1}}{An empty mesh
-defined from a peusdo region numbering of triangle\label{fig emptymesh-2}}
-
-\subsection{Remeshing}
-\subsubsection{\setS{Movemesh}}\index{movemesh}\index{checkmovemesh}
-After solving the elasticity, we want watch the deformation
-$\Omega\mapsto\Phi(\Omega)$,
-$\vec\Phi(x,y)=(\Phi_1(x,y),\Phi_2(x,y))$ of shape.
-In free boundary value problems, the shape of domain will vary.
-
-If $\Omega$ is triangulated already -- dubbed $T_h(\Omega)$,
-then we want $\Phi(\Omega)$ is also triangulated automatically.
-This want is satisfied by
-\bT
- at mesh  Th=@movemesh(Th,[$\Phi$1,$\Phi$2]);
-\eT
-where $\Phi=(\Phi_1,\Phi_2)$ and $\Phi_i,\, i=1,2$ are functions.
-Sometimes the moved mesh is invalid because some triangle
-becomes reversed (with a negative area). This is why we check the
-minimum triangle area in the transformed mesh with
-\texttt{checkmovemesh} before any real transformation.
-
-\begin{example} $\Phi_1(x,y)=x+k*\sin(y*\pi)/10)$,
-$\Phi_2(x,y)=y+k*\cos(y\pi)/10)$ for a big number $k>1$.
-\bFF
-verbosity=4;
- at border a(t=0,1){x=t;y=0;label=1;};
- at border b(t=0,0.5){x=1;y=t;label=1;};
- at border c(t=0,0.5){x=1-t;y=0.5;label=1;};
- at border d(t=0.5,1){x=0.5;y=t;label=1;};
- at border e(t=0.5,1){x=1-t;y=1;label=1;};
- at border f(t=0,1){x=0;y=1-t;label=1;};
- at func uu= sin(y*pi)/10;
- at func vv= cos(x*pi)/10;
-
- at mesh Th = buildmesh ( a(6) + b(4) + c(4) +d(4) + e(4) + f(6));
- at plot(Th,wait=1,fill=1,ps="Lshape.eps");// see figure \ref{lshape}
- at real coef=1;
- at real minT0= checkmovemesh(Th,[x,y]); // the min triangle area
- at while(1) // find a correct move mesh
-{
-  @real minT=@checkmovemesh(Th,[x+coef*uu,y+coef*vv]);//the min triangle area
-  if (minT > minT0/5) break ; // if big enough
-  coef=/1.5;
-}
-
-Th=@movemesh(Th,[x+coef*uu,y+coef*vv]);
- at plot(Th,wait=1,fill=1,ps="movemesh.eps");// see figure \ref{movemesh}
-\eFF
-
-\twoplot[height=6cm]{lshape}{movemesh}{L-shape}{  moved L-shape }
-\end{example}
-\begin{note}
-Consider a function $u$ defined on a mesh \texttt{Th}. A statement like
-\texttt{Th=movemesh(Th...)} does not change $u$ and so the old mesh
-still exists. It will be destroyed when no function use it. A
-statement like $u=u$ redefines $u$ on the new mesh \texttt{Th} with
-interpolation and therefore destroys the old \texttt{Th} if $u$ was the only
-function using it.
-\end{note}
-
-\begin{example}[movemesh.edp]
-\index{tutorial!movemesh.edp}
-Now, we given an example of moving mesh with lagrangian\index{lagrangian}
-function $u$ defined on the moving mesh.
-
-\bFF
-// simple movemesh example
- at mesh Th=square(10,10);
- at fespace Vh(Th,P1);
- at real t=0;
-// ---
-//  the problem is how to build data without interpolation
-//  so the data u is moving with the mesh as you can see in the plot
-// ---
-Vh u=y;
- at for (int i=0;i<4;i++)
-{
- t=i*0.1;
- Vh f= x*t;
- @real minarea=checkmovemesh(Th,[x,y+f]);
- if (minarea >0 ) // movemesh will be ok
-   Th=movemesh(Th,[x,y+f]);
-
- cout << " Min area  " << minarea << endl;
-
- real[int] tmp(u[].n);
- tmp=u[];  // save the value
- u=0;        // to change the FEspace and mesh associated with u
- u[]=tmp;  // set the value of u without any mesh update
- @plot(Th,u,wait=1);
-};
-// In this program, since u is only defined on the last mesh, all the \hfilll
-// previous meshes are deleted from memory.  \hfilll
-//   --------  \hfilll
-\eFF
-\end{example}
-
-\subsection{\setS{Regular Triangulation}}
-For a set $S$, we define the diameter of $S$ by
-\[
-\textrm{diam}(S)=\sup\{|\vec{x}-\vec{y}|; \; \vec{x},\, \vec{y}\in S\}
-\]
-The sequence $\{\mathcal{T}_h\}_{h\downarrow 0}$ of $\Omega$ is called
-\emph{regular}\index{mesh!regular} if they satisfy the following:
-\begin{enumerate}
-  \item
-\[
-\lim_{h\downarrow 0}\max\{\textrm{diam}(T_k)|\; T_k\in \mathcal{T}_h\}
-\]
-  \item
-There is a number $\sigma>0$ independent of $h$ such that
-\[
-\frac{\rho(T_k)}{\textrm{diam}(T_k)}\ge \sigma
-\qquad \textrm{for all }T_k\in \mathcal{T}_h
-\]
-where $\rho(T_k)$ are the diameter of the inscribed circle of $T_k$.
-\end{enumerate}
-We put $h(\mathcal{T}_h)=\max\{\textrm{diam}(T_k)|\; T_k\in \mathcal{T}_h\}$,
-which is obtained by
-\bT
- at mesh Th = ......;
- at fespace Ph(Th,P0);
-Ph h = hTriangle;
- at cout << "size of mesh = " << h[].max << @endl;
-\eT
-
-\subsection{Adaptmesh}\index{adaptmesh}
-\label{sec:Adaptmesh}
-The function
-\[
-f(x,y) = 10.0x^3+y^3+\tan^{-1}[\epsilon/(\sin(5.0y)-2.0x)]
-\qquad \epsilon =  0.0001
-\]
-sharply vary its value.
-However, the initial mesh given by the command in Section \ref{sec:InitialMesh}
-cannot reflect its sharp variation.
-\begin{example}~
-\bFF
- at real eps =  0.0001;
- at real h=1;
- at real hmin=0.05;
- at func f = 10.0*x^3+y^3+h*atan2(eps,sin(5.0*y)-2.0*x);
-
- at mesh Th=square(5,5,[-1+2*x,-1+2*y]);
- at fespace Vh(Th,P1);
-Vh fh=f;
- at plot(fh);
-for (@int i=0;i<2;i++)
- {
-   Th=@adaptmesh(Th,fh);
-   fh=f;  // old mesh is deleted
-   @plot(Th,fh,wait=1);
- }
-\eFF
-\end{example}
-\plot[height=6cm]{adaptmesh}{3D graph under the initial mesh and after of 1st and 2nd adaptation}
-
-\freefempp uses a variable metric/Delaunay automatic meshing
-algorithm.
-The command
-\bT
- at mesh ATh = @adaptmesh(Th, f);
-\eT
-create the new mesh \texttt{ATh} by the Hessian
-$$
-D^2f=(\partial^2 f/\partial x^2,\, \partial^2 f/\partial x\partial y,
-\partial^2 f/\partial y^2)
-$$
-of a function (formula or FE-function).
-Mesh adaptation is a very powerful tool when the solution of a problem
-vary locally and sharply.
-
-Here we solve the problem (\ref{eqn:Poisson})-(\ref{eqn:Dirichlet}),
-when $f=1$ and $\Omega$ is L-shape domain.
-
-\twoplot[height=5cm]{L-shape2}{lshapeSol}{ L-shape domain and its boundary name}{Final solution after 4-times adaptation}
-
-
-\begin{example}[Adapt.edp]
-\index{tutorial!adapt.edp}
-The solution has the
-\index{singularity}singularity $r^{3/2},\, r=|x-\gamma|$
-at the point $\gamma$ of the intersection of two lines
-$bc$ and $bd$ (see Fig. \ref{L-shape2}).
-\bFF
- at border ba(t=0,1.0){x=t;   y=0;  label=1;};
- at border bb(t=0,0.5){x=1;   y=t;  label=1;};
- at border bc(t=0,0.5){x=1-t; y=0.5;label=1;};
- at border bd(t=0.5,1){x=0.5; y=t;  label=1;};
- at border be(t=0.5,1){x=1-t; y=1;  label=1;};
- at border bf(t=0.0,1){x=0;   y=1-t;label=1;};
- at mesh Th = @buildmesh ( ba(6)+bb(4)+bc(4)+bd(4)+be(4)+bf(6) );
- at fespace Vh(Th, at P1);  // set FE space
-Vh u,v;             // set unknown and test function
-func f = 1;
- at real error=0.1;        // level of error
- at problem Poisson(u,v,solver=CG,eps=1.0e-6) =
-    @int2d(Th)(  dx(u)*dx(v) + dy(u)*dy(v))
-  - @int2d(Th) ( f*v )
-  + @on(1,u=0)  ;
- at for (@int i=0;i< 4;i++)
-{
-  Poisson;
-  Th=@adaptmesh(Th,u,err=error);
-  error = error/2;
-} ;
- at plot(u);
-\eFF
-\end{example}
-To speed up the adaptation
-we change by hand a default parameter \texttt{err} of
-\texttt{adaptmesh}\index{concatenation}, which
-specifies the required precision, so as to make the new mesh finer.
-The problem is coercive and symmetric,
-so the linear system can be solved with the conjugate gradient
-method \index{solver=!CG} (parameter \texttt{solver=CG}
-with the stopping criteria on the residual, here
-\texttt{eps=1.0e-6}).
-By \texttt{adaptmesh}, we get good slope of the final solution near
-the point of intersection of $bc$ and $bd$ as in Fig. \ref{lshapeSol}.
-
-This method is described in detail in \cite{bamg}. It has a number of
-default parameters which can be modified~:
-
-\index{adaptmesh}
-\begin{description}
-
-    \item[\texttt{hmin=}] Minimum edge size.  \index{adaptmesh!hmin=}
-    ({\tt val} is a real. Its default is related to
-    the size of the domain to be meshed and the precision of the mesh
-    generator).
-
-    \item[\texttt{hmax=}] Maximum edge size.  ({\tt val} is a real.
-    It defaults to the diameter of the domain to be
-    meshed) \index{adaptmesh!hmax=}
-
-    \item[\texttt{err=}] $P^1$ interpolation error level (0.01 is the
-    default).  \index{adaptmesh!err=}
-
-    \item[\texttt{errg=}] Relative geometrical error. By default this
-    error is 0.01, and in any case it must be lower than $1/\sqrt{2}$.
-    Meshes created with this option may have some edges smaller than
-    the {\tt -hmin } due to geometrical constraints.
-    \index{adaptmesh!errg=}
-
-    \item[\texttt{nbvx=}] Maximum number of vertices generated by the
-    mesh generator (9000 is the default).
-    \index{adaptmesh!nbvx=}
-
-    \item[\texttt{nbsmooth=}] number of iterations of the smoothing
-    procedure (5 is the default).  \index{adaptmesh!nbsmooth=}
-
-    \item[\texttt{nbjacoby=}] number of iterations in a smoothing
-    procedure during the metric construction, 0 means no smoothing (6
-    is the default).  \index{adaptmesh!nbjacoby=}
-
-    \item[\texttt{ratio=}] ratio for a prescribed smoothing on the
-    metric.  If the value is 0 or less than 1.1 no smoothing is done
-    on the metric (1.8 is the default).
-
-    If \texttt{ratio} $> 1.1$, the speed of mesh size variations is
-    bounded by $log(\mathtt{ratio})$.  Note: As {\tt ratio} gets
-    closer to {\tt 1}, the number of generated vertices increases.
-    This may be useful to control the thickness of refined regions
-    near shocks or boundary layers .  \index{adaptmesh!ratio=}
-
-   \item[\texttt{omega=}] relaxation parameter for the smoothing
-   procedure (1.0 is the default).  \index{adaptmesh!omega=}
-
-    \item[\texttt{iso=}] If true, forces the metric to be isotropic
-    (false is the default).  \index{adaptmesh!iso=}
-
-    \item[\texttt{abserror=}] If false, the metric is evaluated using
-    the criterium of equi-repartion of relative error (false is the
-    default).  In this case the metric is defined by
-
-\begin{equation}
-  \mathcal{M} = \left({1\over\mathtt{err}\,\, \mathtt{coef}^2} \quad {
-  |\mathcal{H}| \over max(\mathtt{CutOff},|\eta|)}\right)^p
-  \label{eq err rel}
-\end{equation}
-    \index{adaptmesh!abserror=}
-
-    otherwise, the metric is evaluated using the criterium of
-    equi-distribution of errors.  In this case the metric is defined
-    by
-
-\begin{equation}
-  \mathcal{M} = \left({1\over \mathtt{err}\,\,\mathtt{coef}^2} \quad
-  {|{\mathcal{H}|} \over
-  {\mathit{sup}(\eta)-\mathit{inf}(\eta)}}\right)^p.\label{eq err abs}
-\end{equation}
-
-    \item[\texttt{cutoff=}] lower limit for the relative error
-    evaluation (1.0e-6 is the default).
-    \index{adaptmesh!cutoff=}
-
-    \item[\texttt{verbosity=}] informational messages level (can be
-    chosen between 0 and $\infty$). Also changes the value of the
-    global variable verbosity (obsolete).  \index{adaptmesh!verbosity=
-    }
-
-    \item[\texttt{inquire=}] To inquire graphically about the mesh (false is the
-    default).  \index{adaptmesh!inquire=}
-
-    \item[\texttt{splitpbedge=}] If true, splits all internal edges in
-    half with two boundary vertices (true is the default).
-    \index{adaptmesh!splitpbedge=}
-
-    \item[\texttt{maxsubdiv=}] Changes the metric such that the
-    maximum subdivision of a background edge is bound by {\tt val}
-    (always limited by 10, and 10 is also the default).
-    \index{adaptmesh!maxsubdiv=}
-
-    \item[\texttt{rescaling=}] if true, the function with respect to
-    which the mesh is adapted is rescaled to be between 0 and 1 (true
-    is the default).  \index{adaptmesh!rescaling=}
-
-    \item[\texttt{keepbackvertices=}] if true, tries to keep as many
-    vertices from the original mesh as possible (true is the default).
-    \index{adaptmesh!keepbackvertices=}
-
-    \item[\texttt{isMetric=}] if true, the metric is defined
-    explicitly (false is the default).  If the 3 functions $m_{11},
-    m_{12}, m_{22}$ are given, they directly define a symmetric matrix
-    field whose Hessian is computed to define a metric. If only one
-    function is given, then it represents the isotropic mesh size at
-    every point.  \index{adaptmesh!isMetric=}
-
-    For example, if the partial derivatives
-    \texttt{fxx} ($=\partial^2 f/\partial x^2$),
-    \texttt{fxx} ($=\partial^2 f/\partial x\partial y$),
-    \texttt{fyy} ($=\partial^2 f/\partial y^2$) are given, we can set
-    $$
-    \ttCC{Th=@adaptmesh(Th,fxx,fxy,fyy,IsMetric=1,nbvx=10000,hmin=hmin);}
-    $$
-
-    \item[\texttt{power=}] exponent power of the Hessian used to
-    compute the metric (1 is the default).  \index{adaptmesh!powerin=}
-
-    \item[\texttt{thetamax=}] minimum corner angle in degrees (default
-    is 0).
-
-    \item[\texttt{splitin2=}] boolean value. If true, splits all
-    triangles of the final mesh into 4
-    sub-triangles. \index{adaptmesh!splitin2}
-
-    \item[\texttt{metric=}] \index{adaptmesh!metric=} an array of 3
-    real arrays to set or get metric data information. The size of
-    these three arrays must be the number of vertices. So if
-    \texttt{m11,m12,m22} are three P1 finite elements related to the
-    mesh to adapt, you can write: \texttt{metric=[m11[],m12[],m22[]]}
-    (see file convect-apt.edp for a full example)
-
-    \itemtt[nomeshgeneration=] \index{adaptmesh!nomeshgeneration=} If
-    true, no adapted mesh is generated (useful to compute only a
-    metric).
-
-    \itemtt[periodic=] \index{adaptmesh!periodic=} %%% modif FH
-    As writing \texttt{periodic=[[4,y],[2,y],[1,x],[3,x]];}
-    it builds an adapted periodic mesh. The sample
-    build a biperiodic mesh of a square.
-    (see periodic finite element   spaces \ref{periodic BC}, and see \texttt{sphere.edp} for a  full example)
-
-\end{description}
-
-%%%alh proofreading ok up to here
-
-\subsection{Trunc}\index{trunc}
-
-  A small operator to create a truncated mesh from a mesh with respect to a
-boolean function.
-
-The two named parameter
-\begin{description} \index{split=} \index{label=}\index{trunc!split=} \index{trunc!label=}
-  \itemtt[label=] sets the label number of new boundary item (one by default)
-  \itemtt[split=] sets the level $n$ of triangle splitting. each triangle is splitted in  $n\times n$ ( one by default).
-\end{description}
-
-To create the mesh \texttt{Th3}
-where alls  triangles of a mesh \texttt{Th}  are splitted in $3{\times}3$ , just write:
-\bFF
-  mesh Th3 = trunc(Th,1,split=3);
-\eFF
-
-The  \texttt{truncmesh.edp} example construct
-all "trunc" mesh  to the support of the basic function  of the space \texttt{Vh} (cf. \texttt{abs(u)>0}),
-split all the  triangles in $5{\times} 5$, and put a label number to $2$ on new boundary.
-\bFF
- at mesh Th=square(3,3);
- at fespace Vh(Th,P1);
-Vh u;
- at int i,n=u.n;
-u=0;
- at for (i=0;i<n;i++)  // all degree of freedom
- {
-  u[][i]=1;        //  the basic function i
-  @plot(u,wait=1);
-  @mesh Sh1=trunc(Th,abs(u)>1.e-10,split=5,label=2);
-  plot(Th,Sh1,wait=1,ps="trunc"+i+".eps");// plot the mesh of
-  // the function's support
-  u[][i]=0;      // reset
- }
-\eFF
-\twoplot[height=6cm]{trunc0}{trunc6}{ mesh of support the function P1  number 0, splitted in $5{\times}5$ }{
-mesh of support the function P1  number 6, splitted in $5{\times}5$ }
-\subsection{splitmesh}
-A other way to split mesh triangle:
-\bFF
-{  //  new stuff 2004 splitmesh (version 1.37)
-  assert(version>=1.37);
-  @border a(t=0,2*pi){ x=cos(t); y=sin(t);label=1;}
-  @plot(Th,wait=1,ps="nosplitmesh.eps"); // see figure \ref{fig nosplitmesh}
-  @mesh Th=@buildmesh(a(20));
-  @plot(Th,wait=1);
-  @Th=@splitmesh(Th,1+5*(square(x-0.5)+y*y));
-  @plot(Th,wait=1,ps="splitmesh.eps"); // see figure \ref{fig splitmesh}
-}
-\eFF
-
-\twoplot[height=6cm]{nosplitmesh}{splitmesh}{\label{fig nosplitmesh}initial mesh}{\label{fig splitmesh}all left mesh triangle is split  conformaly in \texttt{int(1+5*(square(x-0.5)+y*y)\^2} triangles.}
-
-
-\subsection{\setS{Meshing Examples}}
-
-\begin{example}[Two rectangles touching by a side]~
-\index{mesh!beam}
-\bFF
- at border a(t=0,1){x=t;y=0;};
- at border b(t=0,1){x=1;y=t;};
- at border c(t=1,0){x=t ;y=1;};
- at border d(t=1,0){x = 0; y=t;};
- at border c1(t=0,1){x=t ;y=1;};
- at border e(t=0,0.2){x=1;y=1+t;};
- at border f(t=1,0){x=t ;y=1.2;};
- at border g(t=0.2,0){x=0;y=1+t;};
- at int n=1;
- at mesh th = @buildmesh(a(10*n)+b(10*n)+c(10*n)+d(10*n));
- at mesh TH = @buildmesh ( c1(10*n) + e(5*n) + f(10*n) + g(5*n) );
- at plot(th,TH,ps="TouchSide.esp"); // Fig. \ref{TouchSide}
-\eFF
-\end{example}
-
-\begin{example}[NACA0012 Airfoil]~
-\index{mesh!NACA0012}
-\bFF
- at border upper(t=0,1) { x = t;
-     y = 0.17735*sqrt(t)-0.075597*t
-  - 0.212836*(t^2)+0.17363*(t^3)-0.06254*(t^4); }
- at border lower(t=1,0) { x = t;
-     y= -(0.17735*sqrt(t)-0.075597*t
-  -0.212836*(t^2)+0.17363*(t^3)-0.06254*(t^4)); }
- at border c(t=0,2*pi) { x=0.8*cos(t)+0.5;  y=0.8*sin(t); }
- at mesh Th = @buildmesh(c(30)+upper(35)+lower(35));
- at plot(Th, at ps="NACA0012.eps", at bw=1);  // Fig. \ref{NACA0012}
-\eFF
-\end{example}
-
-\twoplot[height=5cm]{TouchSide}{NACA0012}{Two rectangles touching by a side}
-{NACA0012 Airfoil}
-
-\begin{example}[Cardioid]~
-\index{mesh!Cardioid}
-\bFF
- at real b = 1, a = b;
- at border C(t=0,2*pi) { x=(a+b)*cos(t)-b*cos((a+b)*t/b);
-                        y=(a+b)*sin(t)-b*sin((a+b)*t/b); }
- at mesh Th = @buildmesh(C(50));
- at plot(Th, at ps="Cardioid.eps",bw=1); // Fig. \ref{Cardioid}
-\eFF
-\end{example}
-\begin{example}[Cassini Egg]~
-\index{mesh!Cassini Egg}
-\bFF
- at border C(t=0,2*pi) { x=(2*cos(2*t)+3)*cos(t);
-                      y=(2*cos(2*t)+3)*sin(t); }
- at mesh Th = @buildmesh(C(50));
- at plot(Th, at ps="Cassini.eps",bw=1); // Fig. \ref{Cassini}
-\eFF
-\end{example}
-\twoplot[height=5cm]{Cardioid}{Cassini}{Domain with Cardioid curve boundary}
-{Domain with Cassini Egg curve boundary}
-
-\begin{example}[By cubic Bezier curve]~
-\index{mesh!Bezier curve}
-\bFF
-// A cubic Bezier curve connecting two points with two control points
- at func @real @bzi(@real p0, at real p1, at real q1, at real q2, at real t)
-{
-  @return p0*(1-t)^3+q1*3*(1-t)^2*t+q2*3*(1-t)*t^2+p1*t^3;
-}
-
-real[int] p00=[0,1], p01=[0,-1], q00=[-2,0.1], q01=[-2,-0.5];
-real[int] p11=[1,-0.9], q10=[0.1,-0.95], q11=[0.5,-1];
-real[int] p21=[2,0.7], q20=[3,-0.4], q21=[4,0.5];
-real[int] q30=[0.5,1.1], q31=[1.5,1.2];
- at border G1(t=0,1) { x=bzi(p00[0],p01[0],q00[0],q01[0],t);
-                   y=bzi(p00[1],p01[1],q00[1],q01[1],t); }
- at border G2(t=0,1) { x=bzi(p01[0],p11[0],q10[0],q11[0],t);
-                   y=bzi(p01[1],p11[1],q10[1],q11[1],t); }
- at border G3(t=0,1) { x=bzi(p11[0],p21[0],q20[0],q21[0],t);
-                   y=bzi(p11[1],p21[1],q20[1],q21[1],t); }
- at border G4(t=0,1) { x=bzi(p21[0],p00[0],q30[0],q31[0],t);
-                   y=bzi(p21[1],p00[1],q30[1],q31[1],t); }
- at int m=5;
- at mesh Th = @buildmesh(G1(2*m)+G2(m)+G3(3*m)+G4(m));
- at plot(Th,ps="Bezier.eps",bw=1);  // Fig \ref{Bezier}
-\eFF
-\end{example}
-
-\begin{example}[Section of Engine]~
-\index{mesh!Section of Engine}
-\bFF
-real a= 6., b= 1., c=0.5;
-border L1(t=0,1) { x= -a; y= 1+b - 2*(1+b)*t; }
-border L2(t=0,1) { x= -a+2*a*t; y= -1-b*(x/a)*(x/a)*(3-2*abs(x)/a );}
-border L3(t=0,1) { x= a; y=-1-b + (1+ b )*t; }
-border L4(t=0,1) { x= a - a*t;   y=0; }
-border L5(t=0,pi) { x= -c*sin(t)/2; y=c/2-c*cos(t)/2; }
-border L6(t=0,1) { x= a*t;  y=c; }
-border L7(t=0,1) { x= a;  y=c + (1+ b-c )*t; }
-border L8(t=0,1) { x= a-2*a*t; y= 1+b*(x/a)*(x/a)*(3-2*abs(x)/a); }
-mesh Th = buildmesh(L1(8)+L2(26)+L3(8)+L4(20)+L5(8)+L6(30)+L7(8)+L8(30));
-plot(Th,ps="Engine.eps",bw=1); // Fig. \ref{Engine}
-\eFF
-\end{example}
-
-\begin{figure}[hbt]
-\begin{multicols}{2}
-\begin{center}
-\includegraphics*[height=5cm]{Bezier}
-\caption{\label{Bezier} Boundary drawed by Bezier curves}
-\end{center}
-\begin{center}
-\vspace{3cm}~~\par
-\includegraphics*[height=2.8cm]{Engine}
-\caption{\label{Engine} Section of Engine}
-\end{center}
-\end{multicols}
-\end{figure}
-
-\begin{example}[Domain with U-shape channel]~
-\index{mesh!U-shape channel}
-\bFF
- at real d = 0.1; // width of U-shape
- at border L1(t=0,1-d) { x=-1; y=-d-t; }
- at border L2(t=0,1-d) { x=-1; y=1-t; }
- at border B(t=0,2) { x=-1+t; y=-1; }
- at border C1(t=0,1) { x=t-1; y=d; }
- at border C2(t=0,2*d) { x=0; y=d-t; }
- at border C3(t=0,1) { x=-t; y=-d; }
- at border R(t=0,2) { x=1; y=-1+t; }
- at border T(t=0,2) { x=1-t; y=1; }
- at int n = 5;
- at mesh Th = buildmesh (L1(n/2)+L2(n/2)+B(n)+C1(n)+C2(3)+C3(n)+R(n)+T(n));
- at plot(Th,ps="U-shape.eps",bw=1); // Fig \ref{U-shape}
-\eFF
-\end{example}
-\begin{example}[Domain with V-shape cut]~
-\index{mesh!V-shape cut}
-\bFF
- at real dAg = 0.01; // angle of V-shape
- at border C(t=dAg,2*pi-dAg) { x=cos(t); y=sin(t); };
- at real[int] pa(2), pb(2), pc(2);
-pa[0] = cos(dAg); pa[1] = sin(dAg);
-pb[0] = cos(2*pi-dAg); pb[1] = sin(2*pi-dAg);
-pc[0] = 0; pc[1] = 0;
- at border seg1(t=0,1) { x=(1-t)*pb[0]+t*pc[0]; y=(1-t)*pb[1]+t*pc[1]; };
- at border seg2(t=0,1) { x=(1-t)*pc[0]+t*pa[0]; y=(1-t)*pc[1]+t*pa[1]; };
- at mesh Th = @buildmesh(seg1(20)+C(40)+seg2(20));
- at plot(Th, at ps="V-shape.eps", at bw=1);  // Fig. \ref{V-shape}
-\eFF
-\end{example}
-\twoplot[height=5cm]{U-shape}{V-shape}{Domain with U-shape channel changed by \ttCC{d}}
-{Domain with V-shape cut changed by \ttCC{dAg}}
-
-\begin{example}[Smiling face]~
-\index{mesh!Smiling face}
-\bFF
- at real d=0.1;
- at int m=5;
- at real a=1.5, b=2, c=0.7, e=0.01;
- at border F(t=0,2*pi) { x=a*cos(t); y=b*sin(t); }
- at border E1(t=0,2*pi) { x=0.2*cos(t)-0.5; y=0.2*sin(t)+0.5; }
- at border E2(t=0,2*pi) { x=0.2*cos(t)+0.5; y=0.2*sin(t)+0.5; }
- at func @real @st(real t) {
-   @return sin(pi*t)-pi/2;
-}
- at border C1(t=-0.5,0.5) { x=(1-d)*c*cos(st(t)); y=(1-d)*c*sin(st(t)); }
- at border C2(t=0,1){x=((1-d)+d*t)*c*cos(st(0.5));y=((1-d)+d*t)*c*sin(st(0.5));}
- at border C3(t=0.5,-0.5) { x=c*cos(st(t)); y=c*sin(st(t)); }
- at border C4(t=0,1) { x=(1-d*t)*c*cos(st(-0.5)); y=(1-d*t)*c*sin(st(-0.5));}
-
- at border C0(t=0,2*pi) { x=0.1*cos(t); y=0.1*sin(t); }
- at mesh Th=@buildmesh(F(10*m)+C1(2*m)+C2(3)+C3(2*m)+C4(3)
-                  +C0(m)+E1(-2*m)+E2(-2*m));
- at plot(Th, at ps="SmileFace.eps", at bw=1);  // see Fig. \ref{SmileFace}
-}\eFF
-\end{example}
-
-\begin{example}[3point bending]~
-\index{mesh!3point bending}
-\bFF
-// Square for Three-Point Bend Specimens fixed on \ttCC{Fix1, Fix2}
-// It will be loaded on \ttCC{Load}.
- at real a=1, b=5, c=0.1;
- at int n=5, m=b*n;
- at border Left(t=0,2*a) { x=-b; y=a-t; }
- at border Bot1(t=0,b/2-c) { x=-b+t; y=-a; }
- at border Fix1(t=0,2*c) { x=-b/2-c+t; y=-a; }
- at border Bot2(t=0,b-2*c) { x=-b/2+c+t; y=-a; }
- at border Fix2(t=0,2*c) { x=b/2-c+t; y=-a; }
- at border Bot3(t=0,b/2-c) { x=b/2+c+t; y=-a; }
- at border Right(t=0,2*a) { x=b; y=-a+t; }
- at border Top1(t=0,b-c) { x=b-t; y=a; }
- at border Load(t=0,2*c) { x=c-t; y=a; }
- at border Top2(t=0,b-c) { x=-c-t; y=a; }
-mesh Th = buildmesh(Left(n)+Bot1(m/4)+Fix1(5)+Bot2(m/2)+Fix2(5)+Bot3(m/4)
-                    +Right(n)+Top1(m/2)+Load(10)+Top2(m/2));
-plot(Th,ps="ThreePoint.eps",bw=1); // Fig. \ref{ThreePoint}
-\eFF
-\end{example}
-
-\begin{figure}[hbt]
-\begin{multicols}{2}
-\begin{center}
-\includegraphics*[height=5cm]{SmileFace}
-\caption{\label{SmileFace} Smiling face (Mouth is changeable)}
-\end{center}
-\begin{center}
-\vspace{2cm}~~\par
-\includegraphics*[height=2.8cm]{ThreePoint}
-\caption{\label{ThreePoint} Domain for three-point bending test}
-\end{center}
-\end{multicols}
-\end{figure}
-
-
-\section{\setS{Finite Elements}} \index{finite element space}
-As stated in Step2 in Section \ref{sec:example}.
-FEM make approximations all functions $w$ to
-\[
-w(x,y)\simeq w_0\phi_0(x,y)+w_1\phi_1(x,y)+\cdots+w_{M-1}\phi_{M-1}(x,y)
-\]
-with finite basis functions $\phi_k(x,y)$ and numbers $w_k$ ($k=0,\cdots,M-1$).
-The functions $\phi_k(x,y)$ is constructed from the triangle $T_{i_k}$, so
-$\phi_k(x,y)$ is called \emph{shape function}.
-The finite element space
-$$
-V_h=\left\{w\left|\; w_0\phi_0+w_1\phi_1+\cdots+w_{M-1}\phi_{M-1},\,
-w_i\in \R\right.\right\}
-$$ is easily created by
-\bT
-     @fespace IDspace(IDmesh,<IDFE>) ;
-\eT
-or with $\ell$ pair of periodic boundary condition
-\bT
-     @fespace IDspace(IDmesh,<IDFE>,
-                      periodic=[[la$_1$,sa$_1$],[lb$_1$,sb$_1$],
-                                ...
-                                [la$_k$,sa$_k$],[lb$_k$,sb$_\ell$]]);
-\eT
-where
-\index{fespace}\index{periodic}
-\ttCC{IDspace} is the name of the space (e.g. \ttCC{Vh}),
-\ttCC{IDmesh} is the name of the associated mesh and  \ttCC{<IDFE>}
-is a identifier of finite element type.
-In a pair of periodic boundary condition, \label{periodic BC}
-if \ttCC{[la$_i$,sa$_i$],[lb$_i$,sb$_i$]} is a pair of
-\texttt{int}, this expressions the 2 labels \ttCC{la$_i$} and \ttCC{lb$_i$}
-of the piece of the boundary to be equivalence;
-If \ttCC{[la$_i$,sa$_i$],[lb$_i$,sb$_i$]} is a pair of \texttt{real},
-this expressions \ttCC{sa$_i$} and \ttCC{sb$_i$}
-give two common abscissa on the two boundary curve, and two points are identify
-if the two abscissa are equal.
-
-
-\medskip
- As of today, the known
-types of finite element are: \index{type of finite element}
-\begin{description}
-     \item[P0]  piecewise constante discontinuous finite element
-     \index{P0|textbf}\index{fespace!P0}
-    \begin{eqnarray}
-    \label{eq:P0}
-     P0_{h} = \left\{ v \in L^2(\Omega) \left|\; \textrm{for all }K \in \mathcal{T}_{h}\;\;\textrm{there is }\alpha_{K}\in \R :
-        \;\; v_{|K} = \alpha_{K } \right.\right\}
-     \end{eqnarray}
-     \item[P1]  piecewise linear  continuous finite element
-     \index{P1|textbf}\index{fespace!P1}
-     \begin{eqnarray}
-     &&P1_{h} = \left\{ v \in H^{1}(\Omega) \left|\; \forall K \in \mathcal{T}_{h}
-        \quad v_{|K} \in P_{1} \right.\right\} \label{eq:P1}
-     \end{eqnarray}
-     \item[P1dc]  piecewise linear  discontinuous finite element
-     \index{P1dc|textbf}\index{fespace!P1dc}
-     \begin{equation}
-     P1dc_{h} = \left\{ v \in L^{2}(\Omega) \left|\; \forall K \in \mathcal{T}_{h}
-        \quad v_{|K} \in P_{1} \right.\right\} \label{eq:P1dc}
-     \end{equation}
-     \item[P1b]  piecewise linear  continuous finite element plus bubble
-     \index{P1b|textbf}\index{fespace!P1b}
-     \begin{equation}
-     P1b_{h} = \left\{ v \in H^{1}(\Omega) \left|\; \forall K \in \mathcal{T}_{h}
-        \quad v_{|K} \in P_{1} \oplus Span\{  \lambda^{K}_{0} \lambda^{K}_{1} \lambda^{K}_{2} \} \right.\right\} \label{eq:P1b}
-     \end{equation}
-     where $\lambda ^{K}_{i}, i=0,1,2$ are the 3 area coordinate functions of the triangle $K$
-
-     \item[P2] piecewise $P_{2}$  continuous finite element,
-     \index{P2|textbf}\index{fespace!P2}
-     \begin{equation}
-     P2_{h} = \left\{ v \in H^{1}(\Omega) \left|\; \forall K \in \mathcal{T}_{h}
-        \quad v_{|K} \in P_{2} \right.\right\}
-     \end{equation}
-     where
-     $P_{2}$ is the set of polynomials of $\R^{2}$ of  degrees $\le 2$.
-     \item[P2b] piecewise $P_{2} $ continuous finite element  plus bubble,
-     \index{P2|textbf}\index{fespace!P2}
-     \begin{equation}
-     P2_{h} = \left\{ v \in H^{1}(\Omega) \left|\; \forall K \in \mathcal{T}_{h}
-        \quad v_{|K} \in P_{2} \oplus Span\{  \lambda^{K}_{0} \lambda^{K}_{1} \lambda^{K}_{2} \} \right.\right\}
-     \end{equation}
-
-     \item[P2dc] piecewise $P_{2}$  discontinuous finite element,
-     \index{P2dc|textbf}\index{fespace!P2dc}
-     \begin{equation}
-     P2dc_{h} = \left\{ v \in L^{2}(\Omega) \left|\; \forall K \in \mathcal{T}_{h}
-        \quad v_{|K} \in P_{2} \right.\right\}
-     \end{equation}
-     \item[RT0]  Raviart-Thomas finite element
-     \index{RT0|textbf}\index{fespace!RT0}
-     \begin{equation}
-         RT0_{h} = \left\{ \mathbf{v} \in H(\textrm{div}) \left|\; \forall K \in
-         \mathcal{T}_{h} \quad  \mathbf{v}_{|K}(x,y) =
-         \vecttwo{\alpha_{K}}{\beta_{K}} + \gamma_{K}\vecttwo{x}{y}  \right.\right\}
-         \label{eq:RT0}
-     \end{equation}
-      where by writing
-      $\textrm{div }\mathbf{w}=\partial w_1/\partial x+\partial w_2/\partial y,
-      \, \mathbf{w}=(w_1,w_2)$,
-      $$
-      H(\textrm{div})=\left\{\mathbf{w}\in L^{2}(\Omega)^2\left|
-      \textrm{div } \mathbf{w}\in L^{2}(\Omega)
-      \right.\right\}
-      $$
-      and
-      $\alpha_{K},\beta_{K},\gamma_{K} $ are real numbers.
-     \item[P1nc] \index{P1nc|textbf}\index{fespace!P1nc} piecewise linear   element continuous at
-     the middle of edge only.
-
-\end{description}
-
-If we get the finite element spaces
-$$  X_{h} = \{ v \in H^{1}(]0,1[^2) |\; \forall K \in \mathcal{T}_{h}
-\quad v_{|K} \in
-P_{1} \}$$
-$$ X_{ph} = \{  v \in X_{h} |\; v(\vecttwo{0}{.} ) =  v(\vecttwo{1}{.}) , v(\vecttwo{.}{0} ) =  v(\vecttwo{.}{1} )  \}$$
-$$  M_{h} = \{ v \in H^{1}(]0,1[^2) |\; \forall K \in \mathcal{T}_{h}
-\quad v_{|K} \in
-P_{2} \}$$
-$$  R_{h} = \{ \mathbf{v} \in H^{1}(]0,1[^2)^{2} |\; \forall K \in \mathcal{T}_{h}
-\quad
- \mathbf{v}_{|K}(x,y) =
-         \vecttwo{\alpha_{K}}{\beta_{K}} + \gamma_{K}\vecttwo{x}{y} \}$$
-
-when $\mathcal{T}_h$ is a mesh $10\times 10$ of the unit square $]0,1[^2$,
-we only write in \freefempp as follows:
-\bT
- at mesh Th=@square(10,10);
- at fespace Xh(Th, at P1);      //  scalar FE
- at fespace Xph(Th,P1,
-         periodic=[[2,y],[4,y],[1,x],[3,x]]);//bi-periodic FE
- at fespace Mh(Th, at P2);      //  scalar FE
- at fespace Rh(Th, at RT0);     //  vectorial FE
-\eT
-where \texttt{Xh,Mh,Rh} expresses finite element spaces (called FE spaces
-\index{FE space}) $X_h,\, M_h,\, R_h$, respectively.
-If we want use FE-functions
-$ u_{h},v_{h} \in X_{h} $ and $ p_{h},q_{h} \in M_{h} $
-and $U_{h},V_{h} \in R_{h}$
-\index{FE-function}, we write in \freefempp
-\bT
-  Xh uh,vh;
-  Xph uph,vph;
-  Mh ph,qh;
-  Rh [Uxh,Uyh],[Vxh,Vyh];
-  Xh[@int] Uh(10); //  array of 10 function in Xh
-  Rh[@int] [Wxh,Wyh](10); //  array of 10 functions in Rh.\index{array!fespace}
-\eT
-
-The functions $U_{h},V_{h}$ have two components so we have
-$$U_{h}=\vecttwo{Uxh}{Uyh}  \quad \mbox{and}\quad V_{h}=\vecttwo{Vxh}{Vyh}$$
-
-\subsection{Lagrange finite element}
-\label{sec:P0P1P2}
-\subsubsection{P0-element}
-For each triangle $T_k$, the basis function $\phi_k$ in \texttt{Vh(Th,P0)}
-is given by
-$$
-\phi_k(x,y)=1\textrm{ if }(x,y)\in T_k,\qquad
-\phi_k(x,y)=0\textrm{ if }(x,y)\not\in T_k
-$$
-If we write
-\bT
-Vh(Th, at P0);  Vh fh=$f(x.y)$;
-\eT
-then for vertices $q^{k_i},\, i=1,2,3$ in Fig. \ref{P1P2}(a),
-$$
-\ttCC{fh}=f_h(x,y)=\sum_{k=1}^{n_t}\frac{f(q^{k_1})+f(q^{k_2})+f(q^{k_3})}{3}\phi_k
-$$
-See Fig. \ref{projP0} for the projection of $f(x,y)=\sin(\pi x)\cos(\pi y)$
-into \ttCC{Vh(Th, at P0)} when
-the mesh \ttCC{Th} with $4\times 4$-grid of $[-1,1]^2$ as in Fig. \ref{P0P1P2P1nc}.
-
-\subsubsection{P1-element}
-\plot[height=4cm]{P1P2}{$P_1$  and $P_2$ degrees of freedom on triangle $T_k$}
-
-For each vertex $q^i$, the basis function $\phi_i$ in \texttt{Vh(Th,P1)}
-is given by
-\begin{eqnarray*}
-&&\phi_i(x,y)=a^k_i+b^k_ix+c^k_iy~\textrm{for }(x,y)\in T_k,\\
-&&\phi_i(q^i)=1,\quad \phi_i(q^j)=0\textrm{ if }i\neq j
-\end{eqnarray*}
-The basis function $\phi_{k_1}(x,y)$ with the vertex $q^{k_1}$ in
-Fig. \ref{P1P2}(a) at point $p=(x,y)$ in triangle $T_k$ simply coincide with the
-\emph{barycentric coordinates $\lambda^k_1$ (area coordinates)} :
-$$
-\phi_{k_1}(x,y) = \lambda^k_{1}(x,y)=
-\frac{\textrm{area of triangle} (p, q^{k_2},q^{k_3})}
-{\textrm{area of triangle}(q^{k_1},q^{k_2},q^{k_3})}
-$$
-If we write
-\bT
-Vh(Th, at P1); Vh fh=$g(x.y)$;
-\eT
-then
-$$
-\ttCC{fh}=f_h(x,y)=\sum_{i=1}^{n_v}f(q^i)\phi_i(x,y)
-$$
-See Fig. \ref{projP1} for the projection of $f(x,y)=\sin(\pi x)\cos(\pi y)$
-into \ttCC{Vh(Th, at P1)}.
-
-\twoplot[height=5cm]{P0P1P2P1nc}{projP0}{Test mesh \texttt{Th} for projection}{projection to \texttt{Vh(Th,P0)}}
-
-\subsubsection{P2-element}
-For each vertex or midpoint $q^i$. the basis function $\phi_i$ in \texttt{Vh(Th,P2)}
-is given by
-\begin{eqnarray*}
-&&\phi_i(x,y)=a^k_i+b^k_ix+c^k_iy+d^k_ix^2+e^k_ixy+f^f_jy^2~\textrm{for }(x,y)\in T_k,\\
-&&\phi_i(q^i)=1,\quad \phi_i(q^j)=0\textrm{ if }i\neq j
-\end{eqnarray*}
-The basis function $\phi_{k_1}(x,y)$ with the vertex $q^{k_1}$ in
-Fig. \ref{P1P2}(b) is defined by the \emph{barycentric coordinates}:
-$$
-\phi_{k_1}(x,y) = \lambda^k_{1}(x,y)(2\lambda^k_1(x,y)-1)
-$$
-and for the midpoint $q^{k_2}$
-$$
-\phi_{k_2}(x,y) = 4\lambda^k_1(x,y)\lambda^k_4(x,y)
-$$
-If we write
-\bT
-Vh(Th, at P2); Vh fh=$f(x.y)$;
-\eT
-then
-$$
-\ttCC{fh}=f_h(x,y)=\sum_{i=1}^{M}f(q^i)\phi_i(x,y)\quad (\textrm{summation over all vetex or midpoint})
-$$
-See Fig. \ref{projP2} for the projection of $f(x,y)=\sin(\pi x)\cos(\pi y)$
-into \ttCC{Vh(Th, at P2)}.
-
-\twoplot[height=5cm]{projP1}{projP2}{projection to \texttt{Vh(Th,P1)}}{projection to \texttt{Vh(Th,P2)}}
-
-\subsection{P1 Nonconforming Element}
-Refer \cite{Thomasset} for detail.
-In \refSec{P0P1P2}, the approximation are a continuous function all
-over the domain, and
-$$
-w_h\in V_h\subset H^1(\Omega)
-$$
-However, we allow the continuity requirement to be relaxed.
-If we write
-\bT
-Vh(Th, at P1nc); Vh fh=$f(x.y)$;
-\eT
-then
-$$
-\ttCC{fh}=f_h(x,y)=\sum_{i=1}^{n_v}f(m^i)\phi_i(x,y)\quad (\textrm{summation over all midpoint})
-$$
-Here the basis function $\phi_i$ associated with the midpoint
-$m^i=(q^{k_i}+q^{k_{i+1}})/2$ where $q^{k_i}$ is the $i$-th point in $T_k$,
-and we assume that $j+1=0$ if $j=3$:
-\begin{eqnarray*}
-&&\phi_i(x,y)=a^k_i+b^k_ix+c^k_iy~\textrm{for }(x,y)\in T_k,\\
-&&\phi_i(m^i)=1,\quad \phi_i(m^j)=0\textrm{ if }i\neq j
-\end{eqnarray*}
-
-Strictly speaking $\partial \phi_i/\partial x,\, \partial \phi_i/\partial y$
-contain Dirac distribution $\rho \delta_{\partial T_k}$.
-The numerical calculations will automatically \emph{ignore} them.
-In \cite{Thomasset}, there is a proof of the estimation
-\[
-\left(\sum_{k=1}^{n_v}\int_{T_k}|\nabla w-\nabla w_h|^2dxdy\right)^{1/2}
-=O(h)
-\]
-The basis functions $\phi_k$ have the following properties.
-\begin{enumerate}
-  \item
-  For the bilinear form $a$ defined in (\ref{eqn:bilinear}) satisfy
-  \begin{eqnarray*}
-  &&a(\phi_i,\phi_i)>0,\qquad a(\phi_i,\phi_j)\le 0\quad\textrm{if }i\neq j\\
-  &&\sum_{k=1}^{n_v}a(\phi_i,\phi_k)\ge 0
-  \end{eqnarray*}
-  \item
-  $f\ge 0 \Rightarrow u_h\ge 0$
-  \item If $i\neq j$, the basis function $\phi_i$ and $\phi_j$ are $L^2$-orthogonal:
-  $$
-  \int_{\Omega}\phi_i\phi_j\, dxdy=0\qquad \textrm{if }i\neq j
-  $$
-  which is false for $P_1$-element.
-\end{enumerate}
-See Fig. \ref{projP1nc} for the projection of $f(x,y)=\sin(\pi x)\cos(\pi y)$
-into \ttCC{Vh(Th, at P1nc)}.
-See Fig. \ref{projP1nc} for the projection of $f(x,y)=\sin(\pi x)\cos(\pi y)$
-into \ttCC{Vh(Th, at P1nc)}.
-
-\twoplot[height=5cm]{projP1nc}{projP1b}{projection to \texttt{Vh(Th,P1nc)}}{projection to \texttt{Vh(Th,P1b)}}
-
-\subsection{Other FE-space}
-For each triangle $T_k\in \mathcal{T}_h$,
-let $\lambda_{k_1}(x,y),\, \lambda_{k_2}(x,y),\, \lambda_{k_3}(x,y)$ be
-the area cordinate
-of the triangle (see Fig. \ref{P1P2}), and put
-\begin{equation}
-\beta_k(x,y)=27\lambda_{k_1}(x,y)\lambda_{k_2}(x,y)\lambda_{k_3}(x,y)
-\end{equation}
-called \emph{bubble}\index{bubble} function on $T_k$.
-The bubble function has the feature:
-\begin{enumerate}
-  \item
-  $\beta_k(x,y)=0\quad \textrm{if }(x,y)\in \partial T_k$.
-  \item
-  $\beta_k(q^{k_b})=1$ where $q^{k_b}$ is the barycenter
-  $\frac{q^{k_1}+q^{k_2}+q^{k_3}}{3}$.
-\end{enumerate}
-If we write
-\bT
-Vh(Th, at P1b); Vh fh=$f(x.y)$;
-\eT
-then
-$$
-\texttt{fh}=f_h(x,y)=\sum_{i=1}^{n_v}f(q^i)\phi_i(x,y)+\sum_{k=1}^{n_t}f(q^{k_b})\beta_k(x,y)
-$$
-See Fig. \ref{projP1b} for the projection of $f(x,y)=\sin(\pi x)\cos(\pi y)$
-into \ttCC{Vh(Th, at P1b)}.
-
-
-\subsection{Vector valued FE-function}
-Functions from  $\R^{2}$ to $\R^{N}$ with $N=1$ is called scalar function and
-called \emph{vector valued} when $N>1$.
-When $N=2$
-\bT
-     @fespace Vh(Th,[@P0, at P1]) ;
-\eT
-make the space
-\[
-V_h=\{\mathbf{w}=(w_1,w_2)|\; w_1\in V_h(\mathcal{T}_h,P_0),\,
-w_2\in V_h(\mathcal{T}_h,P_1)\}
-\]
-
-\subsubsection{Raviart-Thomas element}
-In the Raviart-Thomas finite element $RT0_{h}$,
-the degree of freedom are the flux  throw an edge $e$ of the mesh, where the flux of the function $\mathbf{f} : \R^2 \longrightarrow \R^2 $ is $\int_{e} \mathbf{f}.n_{e}$,
- $n_{e}$ is the unit normal of edge $e$.
-
- This implies a orientation of all the edges of the mesh,
- for example we can use the global numbering of the edge vertices and we just go to small to large number.
-
-To compute the flux, we use an quadrature formulation with one point, the middle point of the edge. Consider a triangle $T_k$ with three vertices $(\mathbf{a},\mathbf{b},\mathbf{c})$.
-Let denote the  vertices numbers by $i_{a},i_{b},i_{c}$, and define the three edge vectors $\mathbf{e}^{1},\mathbf{e}^{2},\mathbf{e}^{3}$
-by $ sgn(i_{b}-i_{c})(\mathbf{b}-\mathbf{c})$, $sgn(i_{c}-i_{a})(\mathbf{c}-\mathbf{a})$, $sgn(i_{a}-i_{b})(\mathbf{a}-\mathbf{b})$,
-
-We get three basis functions,
-\begin{equation}
-\boldsymbol{\phi}^{k}_{1}= \frac{sgn(i_{b}-i_{c})}{2|T_k|}(\mathbf{x}-\mathbf{a}),\quad
-\boldsymbol{\phi}^{k}_{2}= \frac{sgn(i_{c}-i_{a})}{2|T_k|}(\mathbf{x}-\mathbf{b}),\quad
-\boldsymbol{\phi}^{k}_{3}= \frac{sgn(i_{a}-i_{b})}{2|T_k|}(\mathbf{x}-\mathbf{c}),
-\end{equation}
-where $|T_k|$ is the area of the triangle $T_k$.
-If we write
-\bT
-Vh(Th, at RT0); Vh [f1h,f2h]=[$f1(x.y),f2(x,y)$];
-\eT
-then
-$$
-\ttCC{fh}=\vec{f}_h(x,y)=\sum_{k=1}^{n_t}\sum_{l=1}^6
-n_{i_lj_l}|\mathbf{e^{i_l}}|f_{j_l}(m^{i_l})
-\phi_{i_lj_l}
-$$
-where $n_{i_lj_l}$ is the $j_l$-th component of the normal vector
-$\vec{n}_{i_l}$,
-$$
-\{m_1,m_2,m_3\} = \left\{\frac{\mathbf{b}+\mathbf{c}}{2},
-\frac{\mathbf{a}+\mathbf{c}}{2},
-\frac{\mathbf{b}+\mathbf{a}}{2} \right\}
-$$
-and
-$i_l=\{1,1,2,2,3,3\},\, j_l=\{1,2,1,2,1,2\}$ with the order
-of $l$.
-\plot[height=4cm]{RT0}{normal vectors of each edge}
-
-\begin{example}
-\bFF
- at mesh Th=@square(2,2);
- at fespace Xh(Th, at P1);
- at fespace Vh(Th, at RT0);
-Xh uh,vh;
-Vh [Uxh,Uyh];
-[Uxh,Uyh] = [sin(x),cos(y)];   // ok vectorial FE function
-vh= x^2+y^2;  // vh
-Th = @square(5,5); // change the mesh
-//  Xh is unchange
-uh = x^2+y^2; // compute on the new Xh
-Uxh = x;    // error: impossible to set only 1 component
-         // of  a vector FE function.
-vh = Uxh;  // ok
-// and now uh use the 5x5 mesh
-// but the fespace of vh is alway the 2x2 mesh
- at plot(uh,ps="onoldmesh.eps");  // figure \ref{onoldmesh}
-uh = uh; // do a interpolation of vh (old) of 5x5 mesh
-            // to get the new vh on 10x10 mesh.
- at plot(uh,ps="onnewmesh.eps"); // figure \ref{onnewmesh}
-vh([x-1/2,y])= x^2 + y^2;  // interpolate vh = $((x-1/2)^2 + y^2)  $
-\eFF
-\twoplot[height=6cm]{onoldmesh}{onnewmesh}{ vh Iso on mesh $2\times 2$}{
-vh Iso on mesh $5\times 5$}
-\end{example}
-
-
- To get the value at a point $x=1,y=2$ of the FE function \texttt{uh},
- or \texttt{[Uxh,Uyh]},one writes
-
-\bFF
-   @real value;
-   value = uh(2,4);       //  get value= uh(2,4)
-   value = Uxh(2,4);      // get value= Uxh(2,4)
-   //  ------  or ------
-   x=1;y=2;
-   value = uh;       // get value= uh(1,2)
-   value = Uxh;      // get value= Uxh(1,2)
-   value = Uyh;      // get value= Uyh(1,2).
-\eFF
-
-  To get the value of the array associated to the FE function
-  \texttt{uh}, one writes
-
-  \index{FE function!value}\index{FE function![]|textbf}
-  \index{FE function!n|textbf}\index{[]@\verb=[]=}\index{n}
-
-\bFF
-   @real value = uh[][0] ; // get the value of degree of freedom 0
-   @real maxdf = uh[].max; //  maximum value of degree of freedom
-   @int size = uh.n; // the number of degree of freedom
-   @real[int] array(uh.n)= uh[]; //  copy the array of the function uh
-\eFF
-Warning for no scalar finite element function   \texttt{[Uxh,Uyh]}
- the two array \texttt{Uxh[]} and  \texttt{Uyh[]} are the same array, because
- the degre of freedom can touch more than one componant.
-
-
-
-The other way to set a FE function  is to solve a `problem' (see
-below).
-
-%%Changed the place (OT 04/02/2005)
-\subsection{A \setS{Fast Finite Element Interpolator}}
-\medskip
-In practice one may discretize the variational equations by the Finite Element method. Then
-there will be one mesh for $\Omega_1$ and another one for $\Omega_2$.  The computation
-of integrals of products of functions defined on different meshes is difficult.
-Quadrature formulae and interpolations from one mesh to another at quadrature points are needed.
-We present below the interpolation operator which we have used and which is new,
-to the best of our knowledge.
-\bigskip
-Let ${\cal T}_{h}^0=\cup_k T^0_k,{\cal T}_{h}^1=\cup_k T^1_k$ be two triangulations of a domain $\Omega$.
-Let
-$$
-V({\hbox{${\cal T}$}_{h}^i}) =\{ C^0(\Omega_h^i)~:~f|_{T^i_k}\in P^1\},~~~i=0,1
-$$
-be the spaces of continuous piecewise affine functions on each triangulation.
-
-Let $f\in V({\cal T}_{h}^0)$. The problem is to find $g\in V({\cal T}_{h}^1)$ such that
-$$
-g(q) = f(q) \quad \forall q\hbox{~vertex of ~} {\cal T}_{h}^1
-$$
-Although this is a seemingly simple problem, it is difficult to find an
-efficient algorithm in practice.
-We propose an algorithm which is of complexity  $N^1\log N^0$, where $N^i$ is
-the number of vertices of ${\hbox{${\cal T}$}_{h}^i}$, and which
-is very fast for most practical 2D applications.
-\bigskip
-
-{\bf Algorithm }\par
- The method has 5 steps.
-  First a quadtree is built containing all the vertices of mesh ${\cal T}_{h}^0$ such that in
- each terminal cell there are at least one, and at most 4, vertices of ${\cal T}_{h}^0$ .\par
-For each $q^1$, vertex of ${\cal T}_{h}^1$ do:
-\\\\
-\begin{description}
-\item[Step 1]
-Find the terminal cell of the quadtree containing $q^1$.
- \item[Step 2] Find the the nearest vertex $q^0_j$ to $q^1$ in that cell.
- \item[Step 3] Choose one triangle $T_k^0\in{\cal T}_{h}^0$ which has $q^0_j$ for vertex.
- \item[Step 4] Compute the barycentric coordinates $\{\lambda_j\}_{j=1,2,3}
- $ of $q^1$ in $T^0_k$.
-\begin{itemize}
- \item{$-$} if all barycentric coordinates are positive, go to Step 5
- \item{$-$} else if one barycentric coordinate $\lambda_i$ is negative replace $T^0_k$ by the
- adjacent triangle opposite $q^0_i$ and go to Step 4.
- \item{$-$} else two barycentric coordinates are negative so take one of the two randomly
- and replace $T^0_k$ by the adjacent triangle as above.
-\end{itemize}
-  \item[Step 5] Calculate $g(q^1)$ on $T^0_k$ by linear interpolation of $f$:
- $$
- g(q^1) = \sum_{j=1,2,3} \lambda_j f(q^0_j)
- $$
- \item[End]~
-\end{description}
-\plot[height=5cm]{fastInterpolat}{
- To interpolate a function at $q^0$ the knowledge of the triangle
-which contains $q^0$ is needed.  The algorithm may start at $q^1\in T_k^0$ and stall
-on the boundary (thick line) because the line $q^0q^1$ is not inside $\Omega$. But if the holes
-are triangulated too (doted line) then the problem does not arise.}
-
-Two problems needs to solved:
-\begin{itemize}
-  \item {\it  What if $q^1$ is not in $\Omega^0_h$ ?}  Then Step 5 will stop with a
- boundary triangle. So we add a step which test the distance of $q^1$ with the
- two adjacent boundary edges and select the nearest, and so on till the distance
- grows.
- \medskip
- \item {\it What if $\Omega^0_h$ is not convex and the marching process of Step 4
- locks on a boundary?}
- By construction  Delaunay-Vorono\"{i} mesh generators always triangulate the convex
- hull of the vertices of the domain.  So we make sure that this information is not
- lost when ${\cal T}_{h}^0,{\cal T}_{h}^1$ are constructed and we keep the triangles which are
- outside the domain in a special list. Hence in step 5 we can use that list
- to step over holes if needed.
-\end{itemize}
-
-\begin{note}
- Step 3 requires an array of pointers
- such that each vertex points to one triangle
- of the triangulation.
-\end{note}
-
-\subsection{Problem and solve}
-
- For \freefempp  a problem must be given in variational form, %\cite{blop},
- so we need a bilinear form $a(u,v)$ , a linear form $\ell(f,v)$,
-and possibly a boundary condition form must be added.
- \index{problem}
-\bT
- at problem P(u,v) =
-     a(u,v) - $\ell$(f,v)
-     + (boundary condition);
-\eT
-
-
-\begin{note} When you want to formulate the problem and to solve it
-in the same time, you can use the keywork \texttt{solve}.
-\index{solve}
-\end{note}
-
-\subsubsection{Weak form and Boundary Condition}
-
-To Present the Principe  of Variational Formulation or of weak Formulation,
-let us take a model problem : a Poisson equation with  Dirichlet and Robin Boundary condition
-\index{Dirichlet}\index{Robin}.
-\medskip
-
-The problem is: Find $u$ a real function defined on  domain $\Omega$ of $\R^2$ such that
-
-\begin{equation} -  \nabla.(\nu \nabla u) = f  , \quad \mbox{in}\quad \Omega, \quad
- a u + \nu \frac{\partial u}{\partial n} = b \quad\mbox{on}\quad \Gamma_r, \quad
- u = g  \quad\mbox{on}\quad \Gamma_d
- \end{equation}
-
-where
-\begin{itemize}
-\item $ \nabla.(\nu \nabla u) = \partial_x(\nu \partial_x u ) + \partial_y(\nu \partial_y u ) $
-with $ \partial_x u = \frac{\partial u}{\partial x}$
-and $\partial_y u = \frac{\partial u}{\partial y}$
-\item the border $\Gamma=\partial \Omega$ is split in $\Gamma_d$ and $\Gamma_n$
-such that $\Gamma_d \cup \Gamma_n = \emptyset$ and $ \Gamma_d \cap \Gamma_n = \partial \Omega$,
-\item $\nu$ is a given positive function, such that $\exists \nu_0 \in \R ,\quad 0 < \nu_0  \leq \nu $.
-\item  $a$ a given non negative function,
-\item  $ b$ a given function.
-\end{itemize}
-
-\begin{note}{} This problem,  we can be a classical
-Neumann boundary condition  if  $a$ is  $0$, and if $\Gamma_d$ is empty.
-In this case
-the function is defined just by derivative, so this defined too a constant
- (if $u$ is a solution then  $ u+ 1$ is also a solution).
-\end{note}
-
-Let  ${ v} $  a regular test function  null  on  $\Gamma_d$ , by integration par part we get
- \begin{equation}-\int_{\Omega}  \nabla.(\nu \nabla  u) \, { v} \,d\omega = \int_{\Omega}  \nu \nabla{ v} . \nabla u  \,d\omega= \int_{\Omega} f {v}  \,d\omega - \int_{\Gamma} {v}
- \nu \frac{  \partial u}{\partial n}  \,d\gamma,
-  \end{equation}
-
-where $ \nabla{ v} . \nabla u = \frac{\partial u}{\partial x}\frac{\partial { v}}{\partial x}
-+\frac{\partial u}{\partial y}\frac{\partial { v}}{\partial y}$ , and where $n$ is the unitary ouside normal of
- $\partial\Omega$.
-
-Now we note that $ \nu \frac{  \partial u}{\partial n} = - a u + g $  on $\Gamma_r$
-and $  v = 0 $ on $ \Gamma_d $ and $ \partial \Omega = \Gamma_d \cup \Gamma_n $
-thus
-$$
-  - \int_{\partial \Omega} {v}
- \nu \frac{  \partial u}{\partial n} = \int_{\Gamma_r} a u v - \int_{\Gamma_r} b v
-$$
-
-The problem become:
-
-Find   $u \in V_g = \{v \in H^1(\Omega) / v = g \mbox{ on } \Gamma_d \} $  such that
-\begin{equation} {\int_{\Omega} \nu \nabla{ v} . \nabla u  \,d\omega
- + \int_{\Gamma_r} a u v  \,d\gamma = \int_{\Omega} f {v}}  \,d\omega  + \int_{\Gamma_r} b v  \,d\gamma , \quad \forall v \in V_0 \label{eq:v-poisson}
-\end{equation}
-
-where  $  V_0 = \{v \in H^1(\Omega) / v = 0 \mbox{ on } \Gamma_d \} $
-
-The problem (\ref{eq:v-poisson}) is generally weal posed if we do not have only  Neumann
-boundary condition ( ie. $\Gamma_d = \emptyset$ and $a = 0$).
-
-\begin{note}
-\label{note:fu} If we have only Neumann boundary condition, then the problem is defined
-to a constant, and $ 1 \in V_0$ so the following compatibility condition may occur: \index{compatibility condition}
-$
- \int_{\Omega} f   \,d\omega  + \int_{\Gamma} b \,d\gamma
-$
-and a way to fixe the constant is to solve the following problem.
-
- Find $u \in H^1(\Omega)$ such that:
-\begin{equation}
- {\int_{\Omega} \varepsilon u v \,\,d\omega\; + \; \nu \nabla{ v} . \nabla u  \,d\omega
-  = \int_{\Omega} f {v}}  \,d\omega  + \int_{\Gamma_r} b v  \,d\gamma , \quad \forall v \in H^1(\Omega) \label{eq:v-poisson-N}
-\end{equation}
-where $\varepsilon$ is a small parameter ( $ \sim 10^{-10}$ ).
-
-Remark, if the solution
-is of order $ \frac{1}{\varepsilon}$ then the compatibility condition is unsatisfied, otherwise
-we get the solution such that $\int_\Omega u = 0 $.
-
-\end{note}
-
-In \texttt{FreeFem++},  the problem (\ref{eq:v-poisson}) become
-\bFF
-  problem Pw(u,v) =
-       @int2d(Th)( nu* ( dx(u)*dx(u) +  dy(u)*dy(u)))  // $\int_{\Omega} \nu \nabla{v} . \nabla u  \,d\omega$ \hfilll
-     + @int1d(Th,gn)( a * u*v )                        // $\int_{\Gamma_r} a u v  \,d\gamma$  \hfilll
-     - @int2d(Th)(f*v)                                 // $\int_{\Omega} f v  \,d\omega $ \hfilll
-     - @int1d(Th,gn)( b * v )                          // $ \int_{\Gamma_r} b v  \,d\gamma$ \hfilll
-     + @on(gd)(u= g) ;                                 // $ u =g $ on $\Gamma_d$  \hfilll
-\eFF
-where \texttt{Th} is a mesh of the domain $\Omega$, and \texttt{gd} and \texttt{gn} are respectively the
-boundary label of boundary $\Gamma_d$ and $\Gamma_n$.
-
-\subsection{Parameter Description for \texttt{solve} and \texttt{problem}}
-
-The parameters are FE function real or complex, the number $n$ of parameters is even
-($n=2*k$), the $k$ first function parameters are unknown, and the $k$
-last are test functions.
-
-\begin{note} If the functions are a part of
-vectoriel FE then you must give  all the functions of the vectorial
-FE in the same order (see laplaceMixte problem for example).
-\end{note}
-\begin{note} Don't mixte  complex and real parameters  FE function. %add  FH
-\end{note}
-\begin{bug}
-The mixing of \texttt{fespace} with different periodic boundary condition is not
-implemented. So all the finite element space use for test or unknown functions
-in a problem, must  have the same  type of periodic boundary condition or
-no periodic boundary condition.
-No clean message is given and the result is
-impredictible, Sorry.\index{periodic}\index{fespace!periodic=}
-\end{bug}
-
-\index{solver=!LU}\index{solver=!CG}\index{solver=!Crout}\index{solver=!GMRES}\index{solver=!Cholesky}\index{solver=!UMFPACK}
-\index{LU}\index{CG}\index{Crout}\index{GMRES}\index{Cholesky}\index{UMFPACK}
-
-The named parameters are:
-\begin{description}
-    \item[solver=]   \texttt{LU}, \texttt{CG},\index{solve!solver=}\index{problem!solver=}
-    \texttt{Crout},\texttt{Cholesky},\texttt{GMRES},\texttt{UMFPACK} ...
-
-    The default solver is \texttt{LU}.
-    The storage mode of the matrix of the underlying linear system
-    depends on
-    the type of solver chosen; for \texttt{LU}  the matrix is sky-line non
-    symmetric, for \texttt{Crout} the matrix is sky-line symmetric, for
-    \texttt{Cholesky} the matrix is sky-line symmetric positive
-    definite,  for \texttt{CG}   the matrix is sparse symmetric positive,
-    and for \texttt{GMRES} or \texttt{UMFPACK} the matrix is just  sparse.
-
-    \item[eps=]  \index{problem!eps=}  \index{solve!eps=} a real expression. $\varepsilon$  sets the stopping test for
-    the iterative methods like \texttt{CG}. Note that if $\varepsilon$
-    is negative  then the stopping test is:
-    $$  || A x - b || < |\varepsilon| $$
-    if it is positive then the stopping test is \index{stop test}
-        $$  || A x - b || < \frac{|\varepsilon|}{|| A x_{0} - b ||} $$
-
-    \item[init=]   \index{problem!init=}  \index{solve!init=}boolean expression, if it is false or 0 \index{init=}
-    the matrix is reconstructed. Note that if the mesh changes the matrix is
-    reconstructed too.
-    \item[precon=]  \index{problem!precon=}  \index{solve!precon=}name of a function (for example \texttt{P}) to set the precondioner. \index{precon=}
-    The prototype for the function \texttt{P} must be
-\bFF
-    @func @real[@int]  P(@real[@int] & xx) ;
-\eFF
-      \item[tgv=]  \index{problem!tgv=}  \index{solve!tgv=}  Huge value ($10^{30}$) used to lock boundary conditions (see (\ref{eqn:StiffnessDirichlet}))
-\end{description}
-
-\subsection{Problem definition}
-
-Below  \texttt{v} is the unknown function and \texttt{w} is the test function.
-
-  After the "=" sign, one may find sums of:
-  \index{int1d}\index{int2d}\index{intalledges}
-
-\begin{itemize}
-    \item a name; this is the name given to the
-     variational form (type \texttt{varf} \index{varf}) for possible reuse.
-    \item  the bilinear form term: for given functions $K$ and
-    unknown function $v$, test tunctions $w$,
-    \begin{itemize}
-       \item[-)]   \texttt{ int2d(Th)( K*v*w) } $ \displaystyle =       \sum_{T\in\mathtt{Th}}\int_{T } K\,v\,w  $
-       \item[-)]   \texttt{ int2d(Th,1)( K*v*w) } $ \displaystyle = \sum_{T\in\mathtt{Th},T\subset \Omega_{1}}\int_{T} K\,v\,w  $
-
-       \item[-)] \texttt{ int1d(Th,2,5)( K*v*w) }  $ \displaystyle = \sum_{T\in\mathtt{Th}}\int_{(\partial T\cup\Gamma) \cap ( \Gamma_2 \cup \Gamma_{5})
-          } K\,v\,w  $
-
-       \item[-)] \texttt{ intalledges(Th)( K*v*w) } $ \displaystyle = \sum_{T\in\mathtt{Th}}\int_{\partial T } K\,v\,w  $
-       \item[-)] \texttt{ intalledges(Th,1)( K*v*w) } $ \displaystyle = \sum_{{T\in\mathtt{Th},T\subset \Omega_{1}}}\int_{\partial T } K\,v\,w  $
-
-       \item[-)]  they become a sparse matrix of type \texttt{matrix}
-       \end{itemize}
-    \item  the linear form term: for given functions $K,\, f$ and test functions $w$,
-         \begin{itemize}
-       \item[-)]
-         \texttt{ int1d(Th)( K*w) } $ \displaystyle = \sum_{T\in\mathtt{Th}}\int_{T
-          } K\,w  $
-
-      \item[-)] \texttt{ int1d(Th,2,5)( K*w) }   $ \displaystyle = \sum_{T\in\mathtt{Th}}\int_{(\partial T\cup\Gamma) \cap ( \Gamma_2 \cup \Gamma_{5})
-          } K \,w  $
-
-       \item[-)] \texttt{ intalledges(Th)( f*w) } $ \displaystyle = \sum_{T\in\mathtt{Th}}\int_{\partial T } f\,w  $
-
-       \item[-)] a vector of type  \texttt{real[int]}
-      \end{itemize}
-
-    \item  The boundary condition form term :
-    \begin{itemize}
-        \item  An "on" form (for Dirichlet ) :\index{on}
-     \texttt{ on(1, u = g )}\index{on}
-        \item  a linear form on $\Gamma$  (for Neumann ) \index{Neumman}
-         \texttt{ -int1d(Th))( f*w) } or \texttt{ -int1d(Th,3))( f*w) }
-        \item   a bilinear form on $\Gamma$  or $\Gamma_{2}$ (for  Robin )\index{Robin}
-         \texttt{ int1d(Th))( K*v*w) } or
-         \texttt{ int1d(Th,2))( K*v*w)}.
-
-    \end{itemize}
-
-\end{itemize}
-
-If needed, the different kind of terms in the sum can appear more than once.
-
-Remark: the integral mesh and the mesh associated to test function or unknown
-function can be different in the case of linear form.
-
-\begin{note}
- \texttt{N.x} and \texttt{N.y} are the normal's components. \index{normal}\index{N}
- \end{note}
-
-{\bf Important}: it is not possible to write in the same integral the
-linear part and the bilinear part such as in
-\texttt{ int1d(Th)( K*v*w - f*w) }.
-
-\subsection{\setS{Numerical Integration}}
-Let $D$ be a $N$-dimensional bounded domain.
-For an arbitrary polynomials $f$ of degree $r$,
-if we can find particular points $\vec{\xi}_j,\, j=1,\cdots,J$ in $D$ and
-constants $\omega_j$ such that
-\begin{eqnarray}
-\label{eqn:GaussInt}
-\int_{D}f(\vec{x}) = \sum_{\ell =1}^L c_\ell f(\vec{\xi}_\ell)
-\end{eqnarray}
-then we have the error estimation (see Crouzeix-Mignot (1984)),
-then there exists a constant $C>$ such that,
-\begin{eqnarray}
-\label{eqn:GaussIntError}
-\left|\int_{D}f(\vec{x}) - \sum_{\ell =1}^L \omega_\ell
-f(\vec{\xi}_\ell )\right|
-\le C|D|h^{r+1}
-\end{eqnarray}
-for any function $r + 1$ times continuously differentiable $f$ in $D$,
-where $h$ is the diameter of $D$ and $|D|$ its measure.
-
-a point in the segment $[q^iq^j]$ is given as
-\[
-\{(x,y)|\; x=(1-t)q^i_x+tq^j_x,\, y=(1-t)q^i_y+tq^j_y,\, 0\le t\le 1\}
-\]
-For a domain $\Omega_h=\sum_{k=1}^{n_t}T_k,\, \mathcal{T}_h=\{T_k\}$,
-we can calculate the integral over $\Gamma_h=\partial\Omega_h$ by
-\begin{eqnarray*}
-\int_{\Gamma_h}f(\vec{x})ds&=&\texttt{int1d(Th)(f)}\\
-&=&\texttt{int1d(Th,qfe=*)(f)}\\
-&=&\texttt{int1d(Th,qforder=*)(f)}
-\end{eqnarray*}
-where * stands for the name of quadrature formulas or the order of the Gauss formula.
-\begin{figure}[hbt]
-\begin{tabular}{|c|c|c|c|c|c|}
-    \hline
-    $L$ & name (\texttt{qfe=}) & order \texttt{qforder=} &
-    point in $[q^iq^j](=t)$ & $\omega_\ell$~~~  & degree of exact \\
-    \hline
-    \hline
-    1 & qf1pE&2&$0$ & $|q^iq^j|$ & 1 \\
-    \hline
-    2 & qf2pE&3& $(1-\sqrt{1/3})/2$ & $|q^iq^j|/2$ & 3 \\
-    & &&$(1+\sqrt{1/3})/2$ & $|q^iq^j|/2$ &  \\
-    \hline
-    3 & \textbf{qf3pE} &6&$(1-\sqrt{3/5})/2$ & $(5/18)|q^iq^j|$ & 5  \\
-    & & & $1/2$ & $(8/18)|q^iq^j|$ & \\
-    & & & $(1+\sqrt{3/5})/2$ & $(5/18)|q^iq^j|$ &\\
-    \hline
-    2 &qf1pElump E&2& $-1$ & $|q^iq^j|/2$ & 1 \\
-    & &&$+1$ & $|q^iq^j|/2$ &  \\
-    \hline
-
-\end{tabular}
-\index{quadrature:qf1pE}\index{quadrature:qf2pE}%
-\index{quadrature:qf3pE}%
-\index{quadrature:qf1pElump}%
-\end{figure}
-where $|q^iq^j|$ is the length of segment $\overline{q^iq^j}$.
-For a part $\Gamma_1$ of $\Gamma_h$ with the label ``1'', we can
-calculate the integral over $\Gamma_1$ by
-\begin{eqnarray*}
-\int_{\Gamma_1}f(x,y)ds&=&\texttt{int1d(Th,1)(f)}\\
-&=&\texttt{int1d(Th,1,qfe=qf2pE)(f)}
-\end{eqnarray*}
-The integral over $\Gamma_1,\, \Gamma_3$ are given by
-\begin{eqnarray*}
-\int_{\Gamma_1\cup \Gamma_3}f(x,y)ds=\texttt{int1d(Th,1,3)(f)}
-\end{eqnarray*}
-
-For each triangule $T_k=[q^{k_1}q^{k_2}q^{k_3}]$ , the point
-$P(x,y)$ in $T_k$ is expressed by the \emph{area coordinate}\index{area coordinate} as $P(\xi,\eta)$:
-\begin{eqnarray*}
-&&|T_k|=\left|
-\begin{array}{ccc}
-1&q^{k_1}_x&q^{k_1}_y\\
-1&q^{k_2}_x&q^{k_2}_y\\
-1&q^{k_3}_x&q^{k_3}_y
-\end{array}
-\right|\quad
-D_1=\left|
-\begin{array}{ccc}
-1&x&y\\
-1&q^{k_2}_x&q^{k_2}_y\\
-1&q^{k_3}_x&q^{k_3}_y
-\end{array}
-\right|
-\quad
-D_2=\left|
-\begin{array}{ccc}
-1&q^{k_1}_x&q^{k_1}_y\\
-1&x&y\\
-1&q^{k_3}_x&q^{k_3}_y
-\end{array}
-\right|
-\quad
-D_3=\left|
-\begin{array}{ccc}
-1&q^{k_1}_x&q^{k_1}_y\\
-1&q^{k_2}_x&q^{k_2}_y\\
-1&x&y
-\end{array}
-\right|\\
-&&\xi=D_1/|T_k|\qquad
-\eta=D_2/|T_k|\qquad \textrm{then }
-1-\xi-\eta=D_3/|T_k|
-\end{eqnarray*}
-For a domain $\Omega_h=\sum_{k=1}^{n_t}T_k,\, \mathcal{T}_h=\{T_k\}$,
-we can calculate the integral over $\Omega_h$ by
-\begin{eqnarray*}
-\int_{\Omega_h}f(x,y)&=&\texttt{int2d(Th)(f)}\\
-&=&\texttt{int2d(Th,qft=*)(f)}\\
-&=&\texttt{int2d(Th,qforder=*)(f)}
-\end{eqnarray*}
-where * stands for the name of quadrature formulas or the order of the Gauss formula.
-\begin{figure}[hbt]
-\begin{tabular}{|c|c|c|c|c|c|}
-    \hline
-    $L$ & \texttt{qfe=} & \texttt{qforder=} &
-    point in $T_k$ & $\omega_\ell$~~~  & degree of exact \\
-    \hline
-    \hline
-    1 & qf1pT&2&$\left(\frac{1}{3},\frac{1}{3}\right)$ & $|T_k|$ & 1 \\
-    \hline
-    3 & qf2pT&3& $\left(\frac{1}{2},\frac{1}{2}\right)$ & $|T_k|/3$ & 2 \\
-    & &&$\left(\frac{1}{2},0\right)$ & $|T_k|/3$ &  \\
-    & &&$\left(0,\frac{1}{2}\right)$ & $|T_k|/3$ &  \\
-    \hline
-    7 & \textbf{qf5pT}&6&$\left(\frac{1}{3},\frac{1}{3}\right)$ & $0.225|T_k|$ & 5 \\
-    & & & $\left(\frac{6-\sqrt{15}}{21},\frac{6-\sqrt{15}}{21}\right)$ & $
-    \frac{(155-\sqrt{15})|T_k|}{1200}$ & \\
-    & & & $\left(\frac{6-\sqrt{15}}{21},\frac{9+2\sqrt{15}}{21}\right)$ & $\frac{(155-\sqrt{15})|T_k|}{1200}$ &\\
-    & & & $\left(\frac{9+2\sqrt{15}}{21},\frac{6-\sqrt{15}}{21}\right)$ & $\frac{(155-\sqrt{15})|T_k|}{1200}$ &\\
-    & & & $\left(\frac{6+\sqrt{15}}{21},\frac{6+\sqrt{15}}{21}\right)$ & $\frac{(155+\sqrt{15})|T_k|}{1200}$ &\\
-    & & & $\left(\frac{6+\sqrt{15}}{21},\frac{9-2\sqrt{15}}{21}\right)$ & $\frac{(155+\sqrt{15})|T_k|}{1200}$ &\\
-    & & & $\left(\frac{9-2\sqrt{15}}{21},\frac{6+\sqrt{15}}{21}\right)$ & $\frac{(155+\sqrt{15})|T_k|}{1200}$ &\\
-    \hline
-    3 & qf1pTlump& & $\left(0,0\right)$ & $|T_k|/3$ & 1 \\
-    & &&$\left(1,0\right)$ & $|T_k|/3$ &  \\
-    & &&$\left(0,1\right)$ & $|T_k|/3$ &  \\
-    \hline
-    9 & qf2pT4P1& &$\left(\frac{1}{4},\frac{3}{4}\right)$ & $|T_k|/12$ & 1  \\
-      &         & &$\left(\frac{3}{4},\frac{1}{4}\right)$ & $|T_k|/12$ &   \\
-      &         & &$\left(0,\frac{1}{4}\right)$ & $|T_k|/12$ &   \\
-      &         & &$\left(0,\frac{3}{4}\right)$ & $|T_k|/12$ &   \\
-      &         & &$\left(\frac{1}{4},0\right)$ & $|T_k|/12$ &   \\
-      &         & &$\left(\frac{3}{4},0\right)$ & $|T_k|/12$ &   \\
-      &         & &$\left(\frac{1}{4},\frac{1}{4}\right)$ & $|T_k|/6$ &   \\
-      &         & &$\left(\frac{1}{4},\frac{1}{2}\right)$ & $|T_k|/6$ &   \\
-      &         & &$\left(\frac{1}{2},\frac{1}{4}\right)$ & $|T_k|/6$ &   \\
-    \hline
-    15 & qf7pT& 8 & see  \cite{0501496} for detail  & &7 \\
-       \hline
-    21 & qf9pT& 10 & see \cite{0501496} for detail  & &9 \\
-    \hline
-
-\end{tabular}
-\index{quadrature:qf1pT} \index{quadrature:qf2pT}\index{quadrature: qf5pT}
-\index{quadrature:qf1pTlump}\index{quadrature:qf2pT4P1}
-\index{quadrature:qf7pT}\index{quadrature:qf7pT}
-
-\index{quadrature:qfe=} \index{quadrature:qft=}\index{quadrature:qforder=}
-\end{figure}
-
-\begin{note}
- By default,  we use the formula which is exact for polynomes of degrees $5$ on triangles or edges (in bold in two tables)\index{quadrature:default}.
-\end{note}
-
-
-
-
-\subsection{Variational Form, Sparse Matrix, Right Hand Side Vector}
-  \index{varf}\index{array}
-  It is possible to define variational forms:
-\bFF
- at mesh Th=@square(10,10);
- at fespace Xh(Th, at P2),Mh(Th, at P1);
-
- at varf bx(u1,q) = @int2d(Th)( (dx(u1)*q));
-\eFF
-$$ bx(u_{1},q)= \int_{\Omega_{h}} \frac{\partial u_{1}}{\partial x} q $$
-
-\bFF
- at varf by(u1,q) = @int2d(Th)( (dy(u1)*q));
-\eFF
-$$ by(u_{1},q)= \int_{\Omega_{h}} \frac{\partial u_{1}}{\partial y} q $$
-\bFF
- at varf a(u1,u2)= @int2d(Th)(  dx(u1)*dx(u2) + dy(u1)*dy(u2) )
-                    +  @on(1,2,4,u1=0)  +  @on(3,u1=1) ;
-\eFF
-\begin{note}
- the parameters of the variational form are completely formal,  but is not the case
- in \texttt{problem} and \texttt{solve} functionality. %FH add
-\end{note}
-
-$$ a(u_{1},v_{2}) = \int_{\Omega_{h}}  \nabla u_{1}.\nabla u_{2}; \quad
-             \quad u_{1} = 1*g \mbox{ on } \Gamma_{3}, u_{1} =0 \mbox{ on } \Gamma_{1}\cup \Gamma_{2}\cup \Gamma_{4} $$
- where $f$ is defined later.
- \\
- Later variational forms can be used to construct right hand side vectors,
-matrices associated to them, or to define a new problem;\index{matrix}
-\bFF
-Xh u1,u2,v1,v2;
-Mh p,q,ppp;
-
-Xh bc1; bc1[] = a(0,Xh);  //  right hand side for boundary condition
-Xh b;
-
- at matrix A= a(Xh,Xh,solver=CG);   // the Laplace matrix \index{matrix!solver} \index{GC}
- at matrix<complex> CA= a(Xh,Xh,solver=CG);   // the complex Laplace matrix \index{matrix!complex} \index{GC}
-
- at matrix Bx= bx(Xh,Mh);    // $ Bx = (Bx_{ij})$ and $ Bx_{ij}= bx(b^x_j,b^m_j)$
-//  where $b^x_j$ is a basis of Xh, and $b^m_j$ is a basis of Mh.
- at matrix By= by(Xh,Mh);    // $ By= (By_{ij})$ and $ By_{ij}= by(b^x_j,b^m_j)$
-\eFF
-\begin{note}
-The line of the matrix corresponding to test function on the bilinear form.
-\end{note}
-
-\begin{note}
-The vector $bc1[]$ contains the contribution of the boundary condition $u_{1}=1$.
-\end{note}
-Here we have three matrices $A,Bx,By$, and we can solve the problem:\\
-find $ u_{1} \in X_{h}$ such that
-$$ a(v_{1},u_{1})= by(v_{1},f), \forall v_{1}\in X_{0h}, $$
-$$ u_{1} = g , \quad \mbox{on~} \Gamma_{1}, \mbox{and}\quad u_{1}=0 \quad \mbox{on~}  \Gamma_{1}\cup \Gamma_{2}\cup \Gamma_{4}$$
-with the following line (where $f=x$, and $ g=\sin(x)$)\index{[]@\verb=[]=}
-\bFF
-Mh f=x;
-Xh g=sin(x);
-b[]  = Bx'*f[]; //
-b[] += bc1[] .*bcx[]; // u1= g on $\Gamma_{3}$ boundary see following remark
-u1[] = A^-1*b[]; // solve the linear system \index{solve!linear system}\index{\string^-1}
-\eFF
-\begin{note} The boundary condition \index{boundary condition} is implemented
- by penalization and the vector \texttt{bc1[]} contains
- the contribution of the boundary condition $u_{1}=1$ ,
-so to change the boundary condition,
-we have just to multiply the vector $bc1[]$ by the value $f$
- of the new boundary condition term by term
-with the operator \texttt{.*}.\index{.*@\verb=.*=}
-The \refSec{Uzawa} \texttt{StokesUzawa.edp}  gives
- a real example of using all this features.
-\end{note}
-
-We add automatic expression optimization by default, if this optimization trap
-you can remove the use of this optimization by writing for example : \index{optimize=}
-\bFF
- at varf a(u1,u2)= @int2d(Th,optimize=false)(  dx(u1)*dx(u2) + dy(u1)*dy(u2) )
-                    +  @on(1,2,4,u1=0)  +  @on(3,u1=1) ;
-\eFF
-
-Remark, it is all possible to build interpolation matrix, like in
-\index{interpolate}\index{matrix!interpolate}
-the following example:
-\bFF
- at mesh  TH = square(3,4);
- at mesh  th = square(2,3);
- at mesh  Th = square(4,4);
-
-
- at fespace VH(TH,P1);
- at fespace Vh(th,P1);
- at fespace Wh(Th,P1);
-
- at matrix B= interpolate(VH,Vh);  // build interpolation matrix
-Vh->VH @matrix BB= interpolate(Wh,Vh);  // build interpolation
-matrix  Vh->Wh \eFF and after some operations on sparse matrices are
-available for example \bFF
-  @int N=10;
-  @real [int,int] A(N,N);  // a full matrix
-  @real [int] a(N),b(N);
-  A =0;
-  @for (@int i=0;i<N;i++)
-    {
-      @A(i,i)=1+i;
-      @if(i+1 < N)    A(i,i+1)=-i;
-      a[i]=i;
-    }
-  b=A*b;
-  @cout << "xxxx\n";
-  @matrix sparseA=A;
-  cout << sparseA << endl;
-  @sparseA = 2*sparseA+sparseA';
-  @sparseA = 4*sparseA+sparseA*5; //
-  matrix sparseB=sparseA+sparseA+sparseA; ;
-  @cout << "sparseB = " << sparseB(0,0) << endl;
-\eFF
-\subsection{Interpolation matrix}
-
- This becomes possible to store the matrix of a linear interpolation operator from
- a finite element space $V_h$ to  $W_h$ with \texttt{interpolate} function.
-Note that the continuous finite functions are extended by continuity
-to the outside of the domain.
-
-
-The named parameter of function \texttt{interpolate} are:
-\begin{description}
-\item[\texttt{inside=}] set true to create zero-extension.
-\item[\texttt{t=}] set true to get the transposed matrix
-\item[\texttt{op=}] set an integer written below
-
-\begin{description}
-\item[0] the default value and interpolate of the function
-\item[1] interpolate the $\partial_x$
-\item[2] interpolate the $\partial_y$
-\end{description}
-
-
- \index{inside=}\index{interpolate!inside=}
- \index{interpolate!t=}\index{interpolate!t=}.
- \index{interpolate!op=}\index{interpolate!op=}.
-\end{description}
-
-\begin{example}[mat\_interpol.edp]~
-\bFF
- at mesh Th=square(4,4);
- at mesh Th4=square(2,2,[x*0.5,y*0.5]);
- at plot(Th,Th4,ps="ThTh4.eps",wait=1);
- at fespace Vh(Th,P1);     @fespace Vh4(Th4,P1);
- at fespace Wh(Th,P0);     @fespace Wh4(Th4,P0);
-
- at matrix IV= interpolate(Vh,Vh4); //  here the function is
-// exended by continuity
-cout << " IV Vh<-Vh4 " << IV << endl;
-
- at matrix IV0= interpolate(Vh,Vh4,inside=1); // here the fonction is
-// exended by zero
-cout << " IV Vh<-Vh4 (inside=1)  " << IV0 << endl;
-
- at matrix IVt0= interpolate(Vh,Vh4,inside=1,t=1);
-cout << " IV Vh<-Vh4^t (inside=1)  " << IVt0 << endl;
-
- at matrix IV4t0= interpolate(Vh4,Vh);
-cout << " IV Vh4<-Vh^t  " << IV4t0 << endl;
-
- at matrix IW4= interpolate(Wh4,Wh);
-cout << " IV Wh4<-Wh  " << IW4  << endl;
-
- at matrix IW4V= interpolate(Wh4,Vh);
-cout << " IV Wh4<-Vh  " << IW4  << endl;
-\eFF
-\end{example}
-
-\subsection{Finite elements connectivity}
-Here, we show how get the informations of a
-finite element space $W_h({\cal T}_n,*)$,
-where ``*'' denotes P1, P2, P1nc, etc.
-\index{nt} \index{ndof} \index{ndofK} \index{connectivity}
-\index{FEspace!nt}\index{FEspace!ndof} \index{FEspace!(int ,int )}
-\begin{itemize}
-\item   \ttCC{Wh.nt}  gives the number of element of $W_h$
-\item   \ttCC{   Wh.ndof}  gives the number of degree of freedom or unknown
-\item   \ttCC{   Wh.ndofK }  gives the number of degree of freedom on one element
-\item   \ttCC{   Wh(k,i) }   gives the number of $i$th  degree of freedom of element $k$.
-
-\end{itemize}
-See the following for an example:
-\begin{example}[FE.edp]
-\bFF
- at mesh Th=@square(5,5);
- at fespace Wh(Th,P2);
- at cout << " nb of degree of freedom           : " << Wh.ndof << endl;
- at cout << " nb of degree of freedom / ELEMENT : " << Wh.ndofK << endl;
- @int k= 2;  // element 2
- @int kdf= Wh.ndofK ;
- @cout << " df of element " << k << ":" ;
- @for (@int i=0;i<kdf;i++)
-    @cout << Wh(k,i) << " ";
- @cout << @endl;
-\eFF
-\end{example}
-and the output is:
-\bFF
- Nb Of Nodes = 121
- Nb of DF = 121
- FESpace:Gibbs: old skyline = 5841  new skyline = 1377
- nb of degree of freedom           : 121
- nb of degree of freedom / ELEMENT : 6
- df of element 2:78 95 83 87 79 92
-\eFF
-
-
-\section{Visualization}
-Numerical results in FEM create huge data, so it is very important to
-make obtained results visible.
-There are two ways of visualization in \freefempp:
-One is default view supporting the draw of meshes, isovalue of real  FE-functions
-and vector fields by the command \ttCC{@plot} (see \refSec{Plot}).
-For documentation, \freefempp make the plotting stored as postscript files.
-
-Another method is to use the external tools, for example, gnuplot
-(see Section \ref{sec:gnuplot}), medit (see Section \ref{sec:medit})
- using the command \ttCC{@system}.
-
-\subsection{Plot} \index{sec:Plot}\label{sec:Plot}
-   With the command plot,
-   meshes, isovalues and vector fields can be displayed.
-
-The parameters of the plot command can be , meshes,real FE functions ,
-arrays of 2  real FE functions, arrays of two arrays of double, to plot
-respectively mesh,
-isovalue, vector field, or curve defined by the two arrays of double.
-
-The named parameter are
-\begin{description}
-    \item[wait=] boolean expression to wait or not (by default no wait). If true we wait for
-    a keyboard up event or mouse event,
-    they respond to an event by the following characters
-    \begin{description}
-        \item[\texttt{+}]  to zoom in around the mouse cursor,
-        \item[\texttt{-}]  to zoom out around the mouse cursor,
-        \item[\texttt{=}]  to restore de initial graphics state,
-        \item[\texttt{c}]  to decrease the vector arrow coef,
-        \item[\texttt{C}]  to increase the vector arrow coef,
-        \item[\texttt{r}]  to refresh the graphic window,
-        \item[\texttt{f}]  to toggle the filling between isovalues,
-        \item[\texttt{b}]  to toggle the black and white,
-        \item[\texttt{g}]  to toggle to  grey or color ,
-        \item[\texttt{v}]  to toggle  the plotting of value,
-        \item[\texttt{p}]  to save to a postscript file,
-  \item[\texttt{?}]  to show all actives keyboard char,
-    \end{description}
-    to redraw, otherwise we continue.
-
-    \itemtt[ps=]  \index{plot!ps=}  string expression to save the plot on postscript file
-    \itemtt[coef=]  \index{plot!coef=} the vector arrow coef between arrow unit and domain unit.
-    \itemtt[fill=]  \index{plot!coef=} to fill between isovalues.
-     \itemtt[cmm=]  \index{plot!cmm=}string expression to write in the graphic window
-     \itemtt[value=]  \index{plot!value=}to plot the value of isoline and the value of vector arrow.
-    \itemtt[aspectratio=] \index{plot! aspectratio =}boolean to be sure that the aspect ratio of plot
- is preserved or not.
-    \itemtt[bb=] \index{plot!bb=}array of 2 array ( like \texttt{ [[0.1,0.2],[0.5,0.6]]}),
-       to set the bounding box and specify a partial view where the  box defined by the two corner points [0.1,0.2] and [0.5,0.6].
-
-    \itemtt[nbiso=]  \index{plot! nbiso =}(int) sets the number of isovalues (20 by default)
-    \itemtt[nbarrow=] \index{plot!nbarraw=} (int) sets the number of colors of arrow values (20 by default)
-    \itemtt[viso=]  \index{plot!viso=}sets the array  value of isovalues (an array real[int])
-    \itemtt[varrow=] \index{plot!varrow=}  sets the array value of color arrows (an array real[int])
-    \itemtt[bw=] \index{plot!bw=} (bool)  sets or not the plot in black and white color.
-    \itemtt[grey=] \index{plot!grey=} (bool)  sets or not the plot in grey color.
-\end{description}
-For example: \index{plot!cut}
-\bFF
- at real[@int] xx(10),yy(10);
- at mesh Th=@square(5,5);
- at fespace Vh(Th, at P1);
-Vh uh=x*x+y*y,vh=-y^2+x^2;
- at int i;
-//  compute a cut
- at for (i=0;i<10;i++)
- {
-   x=i/10.; y=i/10.;
-   xx[i]=i;
-   yy[i]=uh; // value of uh at point (i/10. , i/10.)
- }
- @plot(Th,uh,[uh,vh],value=true,ps="three.eps",wait=true); // figure \ref{three}
- //  zoom on box defined by the two corner points [0.1,0.2] and [0.5,0.6]
- @plot(uh,[uh,vh],bb=[[0.1,0.2],[0.5,0.6]],
-        wait=true,grey=1,fill=1,value=1,ps="threeg.eps"); // figure \ref{threeg}
- @plot([xx,yy],ps="likegnu.eps",wait=true); // figure \ref{likegnu}
-\eFF
-\twoplot[height=6cm]{three}{threeg}{ mesh, isovalue, and
-vector}{enlargement in grey of isovalue, and
-vector}
-
-\plot[height=6cm]{likegnu}{Plots a cut of uh. Note that a refinement of the same can be obtained
-in combination with gnuplot}
-
-\subsection{link with gnuplot}\label{sec:gnuplot}
-\index{gnuplot}\index{exec}
-First this work only if gnuplot\footnote{\url{http://www.gnuplot.info/}} is installed , and
-only on unix computer.
-
-You just and to the previous example:
-{\def\bks{$\backslash$}
-\bFF
-// file for gnuplot
-{
-  @ofstream gnu("plot.gp");
-  @for (int i=0;i<=n;i++)
-   {
-     gnu <<  xx[i] << " " << yy[i] << endl;
-    }
-} //  the file plot.gp is close because the variable gnu is delete
-
-//  to call gnuplot command and wait 5 second (tanks to unix command)
-//  and make postscipt plot
- at exec("echo 'plot \bks"plot.gp\bks" w l \bks
-pause 5 \bks
-set term postscript \bks
-set output \bks"gnuplot.eps\bks" \bks
-replot \bks
-quit' | gnuplot");
-\eFF}
-\plot[height=7cm,angle=270]{gnuplot}{Plots a cut of uh with gnuplot}
-
-\subsection{link with medit}\label{sec:medit}
-First this work only if medit \footnote{\url{http://www-rocq.inria.fr/gamma/medit/medit.html}}
-software is installed.
-
-\index{medit}\index{exec}
-
-\bFF
-// build square $]-1,1[^2$
-mesh Th=square(10,10,[2*x-1,2*y-1]);
-fespace Vh(Th,P1);
-Vh u=2-x*x-y*y;
-
-   savemesh(Th,"mm",[x,y,u*.5]); //save mm.points and mm.faces file
-// for medit
-   // build a mm.bb file
-  { ofstream file("mm.bb");
-  file << "2 1 1 "<< u[].n << " 2 \n";
-  int j;
-  for (j=0;j<u[].n ; j++)
-    file << u[][j] << endl;
-    }
-    // call medit command
-    exec("medit mm");
-    // clean files on unix OS
-    exec("rm mm.bb      mm.faces   mm.points");
-
-\eFF
-\plot[height=10cm]{medit}{medit plot}
-
-
-
-\section{Algorithms}
-
- The associated example is fully defined in \texttt{algo.edp} file.
-
- \subsection{conjugate Gradient/GMRES}
-
-If we want to solve  the Euler problem: find $ x\in \R^n $  such that
-\begin{equation}
-\label{eqn:dJ=0}
-\nabla J(x) = \left(\frac{\partial J}{\partial x_i} (\vec{x})\right) = 0
-\end{equation}
-where $ J$ is a functional (to minimize  for example) from  $ \R^n$ to $ \R$.
-
-If the function is convex we can use the conjugate gradient to solve the problem, and we just need the function (named \texttt{dJ} for example)
-which compute $\nabla J$, so the two parameters
-are the name of the function with prototype \ttCC{@func\ @real[@int]\  dJ(@real[@int] \& xx)}
- which compute $\nabla J$,
-a vector \ttCC{x} of type \ttCC{@real[@int]} to initialize the process and get the result.
-
-
-Given a staring value $\vec{x}^{(0)}$, a maximum number $i_{\max}$
-of iterations, and an error tolerance $0<\epsilon<1$:
-Put $\vec{x}=\vec{x}^{(0)}$ and write
-\begin{quote}\texttt{
-NLCG($\nabla J$, $\vec{x}$, precon$=M$, nbiter$=i_{\max}$, eps$=\epsilon$);
-}
-\end{quote}
-Then we get the solution $\vec{x}$ of $\nabla J(\vec{x})=0$.
-We can omit parameters \texttt{precon, nbiter, eps}.
-Here $M$ is the preconditioner whose default is the identity matrix.
-The stopping test is
-\[
-\| \nabla J(\vec{x})\|_P\le \epsilon\| \nabla J(\vec{x}^{(0)})\|_P
-\]
-Writing the minus value in \texttt{eps=}, i.e.,
-\begin{quote}\texttt{
-NLCG($\nabla J$, $\vec{x}$, precon$=M$, nbiter$=i_{\max}$, eps$=-\epsilon$);
-}
-\end{quote}
-we can use the stopping test
-\[
-\| \nabla J(\vec{x})\|_P^2\le \epsilon
-\]
-The named parameter of these three functions are:
-\begin{description}  \index{linearCG!nbiter=} \index{linearCG!precon=} \index{linearCG!eps=}\index{linearCG!veps=}
-\index{NLCG!nbiter=}  \index{NLCG!eps=}\index{NLCG!veps=}
-\index{LinearGMRES!nbiter=} \index{LinearGMRES!precon=} \index{LinearCMRES!eps=}\index{LinearGMRES!veps=}
-
-\itemtt[nbiter=] set the number of iteration (by default $100$)
-\itemtt[precon=] set the preconditioner function (\texttt{P} for example)   by default it is the identity, remark the prototype
-is \ttCC{@func\ @real[\@int]\ P(@real[@int] \&x)}.
-\itemtt[eps=] set the value of the stop test $\varepsilon$ ($=10^{-6}$ by default) if positive then relative test
-$||\nabla J(x)||_P\leq \varepsilon||\nabla J(x_0)||_P$, otherwise the  absolute test is  $||\nabla J(x)||_P^2\leq |\varepsilon|$.
-\itemtt[veps=] set and return the value of the stop test,  if positive then relative test
-$||\nabla J(x)||_P\leq \varepsilon||\nabla J(x_0)||_P$, otherwise the  absolute test is  $||\nabla J(x)||_P^2\leq |\varepsilon|$.
-The return value is  minus  the real stop test (remark: it is useful in loop).
-
-\end{description}
-\begin{example}[from algo.edp]
-For a given function $b$, let us find the minimizer $u$ of the functional
-\begin{eqnarray*}
- J(u) &=& \int_{\Omega} f(|\nabla u|^2) - \int_{\Omega}  u b \\
- f(x) &=& ax + x-\ln(1+x), \quad f'(x) = a+\frac{x}{1+x}, \quad f''(x) =  \frac{1}{(1+x)^2}
-\end{eqnarray*}
-under the boundary condition $u=0$ on $\partial\Omega$.
-\bFF
- at mesh Th=@square(10,10);  // mesh definition of $\Omega$
- at fespace Vh(Th,P1);      // finite element space
- at fespace Ph(Th,P0);      // make optimization
-\eFF
-/*
-A small hack to construct a function
-\[
-Cl= \left\{
-\begin{array}{cl} 1 & \textrm{\rm on interior degree of freedom} \\
- 0 & \textrm{\rm on boundary degree of freedom}
- \end{array}\right.
-\]
-*/\\
-// Hack to construct an array :\\
-//  1 on interior nodes and 0 on boundary nodes
-\bFF
- at varf vCl(u,v) = @on(1,2,3,4,u=1);
-Vh Cl;
-Cl[]= vCl(0,Vh,tgv=1);  //  0 and tgv
- at real tgv=Cl[].max;     //
-Cl[] = -Cl[];  Cl[] += tgv; Cl[] /=tgv;
-\eFF
-// the definition of $f$, $f'$, $f''$ and $b$
-\bFF
- at real a=0.001;
-
- at func @real f(@real u) { @return u*a+u-log(1+u); }
- at func @real df(@real u) { @return a+u/(1+u);}
- at func @real ddf(@real u) { @return 1/((1+u)*(1+u));}
-Vh b=1;  // to defined b
-// the routine to compute the functional $J$
- at func @real J(@real[int] & x)
-  {
-    Vh u;u[]=x;
-    @real r=@int2d(Th)(f( dx(u)*dx(u) + dy(u)*dy(u) ) - b*u) ;
-    @cout << "J(x) =" << r << " " << x.min <<  " " << x.max << @endl;
-    @return r;
-  }
-// The function  \index{function}to compute $D J$, where $u$ is the current solution.
-Vh u=0; //  the current value of the solution
-Vh alpha; // of store  $f'(|\nabla u|^2)$
- at int iter=0;
-alpha=df( dx(u)*dx(u) + dy(u)*dy(u) ); // optimization
-
- at func @real[@int] dJ(@real[int] & x)
-  {
-    @int verb=verbosity; verbosity=0;
-    Vh u;u[]=x;
-    alpha=df( dx(u)*dx(u) + dy(u)*dy(u) ); // optimization
-    @varf au(uh,vh) = @int2d(Th)( alpha*( dx(u)*dx(vh) + dy(u)*dy(vh) ) - b*vh);
-    x= au(0,Vh);
-    x = x.* Cl[]; //  the grad in 0 on boundary
-    verbosity=verb;
-    @return x; // warning no return of local array
-  }
-\eFF
-/*
-We want to construct also a preconditioner $C$
-with solving the problem:  find $u_h \in V_{0h}$ such that
-\[
-\forall v_h \in V_{0h}, \quad  \int_\Omega \alpha \nabla u_h . \nabla v_h = \int_\Omega b v_h
-\]
-where $ \alpha=f'(|\nabla u|^2)$.
-*/
-\bFF
- at varf alap(uh,vh,solver=Cholesky,init=iter)=
-   @int2d(Th)( alpha *( dx(uh)*dx(vh) + dy(uh)*dy(vh) )) + @on(1,2,3,4,uh=0);
-
- at varf amass(uh,vh,solver=Cholesky,init=iter)=
-   @int2d(Th)( uh*vh)  + @on(1,2,3,4,uh=0);
-
- at matrix Amass = alap(Vh,Vh,solver=CG); // \index{matrix}
-
- at matrix Alap=  alap(Vh,Vh,solver=Cholesky,factorize=1);   // \index{Cholesky}\index{factorize=}\index{solver=}
-
-// the preconditionner function
- at func @real[@int] C(@real[@int] & x)
-{
-   @real[@int] u(x.n);
-   u=Amass*x;
-   x = Alap^-1*u;
-   x = x .* Cl[];
-   @return x; // no return of local array  variable
-}
-\eFF
-/*
-To solve the problem, we make 10 iteration of the conjugate gradient,
-recompute the preconditioner and restart the conjugate gradient:
-*/
-\bFF
-   verbosity=5;
-   @int conv=0;
-   @real eps=1e-6;
-   @for(@int i=0;i<20;i++)
-   {
-     conv=NLCG(dJ,u[],nbiter=10,precon=C,veps=eps); // \index{veps=}\index{NLCG}
-     @if (conv) break;  // if converge break loop
-
-     alpha=df( dx(u)*dx(u) + dy(u)*dy(u) ); // recompute alpha optimization
-     Alap = alap(Vh,Vh,solver=Cholesky,factorize=1);
-     @cout << " restart with new preconditionner " << conv << " eps =" << eps << endl;
-    }
-
-   @plot (u,wait=1,cmm="solution with NLCG");
-\eFF
-\end{example}
-For a given symmetric positive matrix $A$, consider the quadratic form
-\[
-J(\vec{x})=\frac{1}{2}\vec{x}^TA\vec{x}-\vec{b}^T\vec{x}
-\]
-then $J(\vec{x})$ is minimized by the solution $\vec{x}$ of $A\vec{x}=\vec{b}$.
-In this case, we can use the function \texttt{LinearCG}
-\begin{quote}\texttt{
-LinearCG($A$, $\vec{x}$, precon$=M$, nbiter$=i_{\max}$, eps$=\pm\epsilon$);
-}
-\end{quote}
-If $A$ is not symmetric, we can use GMRES(Generalized Minimum Residual) algorithm by
-\begin{quote}\texttt{
-LinearGMRES($A$, $\vec{x}$, precon$=M$, nbiter$=i_{\max}$, eps$=\pm\epsilon$);
-}
-\end{quote}
-Also, we can use the non-linear version of GMRES algorithm
-(the functional $J$ is just convex)
-\begin{quote}\texttt{
-LinearGMRES($\nabla J$, $\vec{x}$, precon$=M$, nbiter$=i_{\max}$, eps$=\pm\epsilon$);
-}
-\end{quote}
-For detail of these algorithms, refer to \cite{Lucquin}[Chapter IV, 1.3].
-
-\subsection{Optimization}
-Two algorithms of
-COOOL  a package \cite{coool} are interfaced with
-the Newton Raphson method  (call \texttt{Newton}) and
-the  \texttt{BFGS} method. \index{Newton}\index{BFGS}
-Be careful these algorithms, because the
-implementation use full matrix.
-
-Example of utilization of \texttt{algo.edp}
-\bFF
-  @func real J(real[int] & x)
-    {
-      @real s=0;
-      for (int i=0;i<x.n;i++)
-         s +=(i+1)*x[i]*x[i]*0.5 - b[i]*x[i];
-         cout << "J ="<< s << " x =" <<  x[0] << " " << x[1] << "...\n" ;
-      return s;
-    }
-  b=1; x=2; // set  right hand side and initial gest
-  @BFGS(J,dJ,x,eps=1.e-6,nbiter=20,nbiterline=20);
-  @cout << "BFGS: J(x) = " << J(x) << " err=" << error(x,b) << endl;
-
-\eFF
-
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\section{Mathematical Models}
-\label{sec:MathModels}
-
-\subsection{Static Problems}
-
-\subsubsection{\setS{Soap Film}}
-Our starting point here will be the mathematical model to find the shape of
-\textbf{soap film} which is glued to the ring on the $xy-$plane
-\begin{equation*}
-C=\{(x,y);\;x=\cos t,\,y=\sin t,\,0\leq t\leq 2\pi \}.
-\end{equation*}
-We assume the shape of the film is described as the graph $(x,y,u(x,y))$ of the vertical
-displacement $u(x,y)\, (x^2+y^2<1)$ under a vertical pressure $p$
-in terms of force per unit area and an initial tension $\mu$ in terms of force
-per unit length.
-Consider ``small plane'' ABCD, A:$(x,y,u(x,y))$, B:$(x,y,u(x+\delta x,y))$, C:$(x,y,u(x+\delta x,y+\delta y))$ and D:$(x,y,u(x,y+\delta y))$.
-Let us denote by $\vec{n}(x,y)=(n_x(x,y),n_y(x,y),n_z(x,y))$ the normal vector of the surface $z=u(x,y)$.
-We see that the vertical force due to the tension $\mu$ acting along the edge
-AD is $-\mu n_x(x,y)\delta y$ and the the vertical force acting along the edge
-AD is
-\[
-\mu n_x(x+\delta x,y)\delta y\simeq \mu\left(n_x(x,y)
-+\frac{\partial n_x}{\partial x}\delta x\right)(x,y)\delta y.
-\]
-\begin{figure}[htbp]
-\label{fig:soupfilm}
-\begin{center}
-\includegraphics[height=3cm]{soapfilm}
-\end{center}
-%\caption{``small plane'' ABCD}
-\label{fig:soapfilm}
-\end{figure}
-Similarly, for the edges AB and DC we have
-\[
--\mu n_y(x,y)\delta x,\qquad
-\mu\left(n_y(x,y)+\partial n_y/\partial y\right)(x,y)\delta x.
-\]
-The force in the vertical direction on the surface ABCD due to the tension $\mu$ is given by
-\[
-\mu\left(\partial n_x/\partial x\right)\delta x\delta y+T\left(\partial n_y/\partial y\right)\delta y\delta x.
-\]
-Assuming small displacements, we have
-\begin{eqnarray*}
-\nu_x&=&(\partial u/\partial x)/\sqrt{1+(\partial u/\partial x)^2+(\partial u/\partial y)^2}\simeq \partial u/\partial x,\\
-\nu_y&=&(\partial u/\partial y)/\sqrt{1+(\partial u/\partial x)^2+(\partial u/\partial y)^2}\simeq \partial u/\partial y.
-\end{eqnarray*}
-Letting $\delta x\to dx,\, \delta y\to dy$, we have the equilibrium of the vertical displacement of soap film on ABCD by $p$
-\[
-\mu dx dy\partial^2 u/\partial x^2 +  \mu dx dy\partial^2 u/\partial y^2
-+ p dx dy = 0.
-\]
-Using the Laplace operator $\Delta = \partial^2 /\partial x^2 + \partial^2 /\partial y^2$, we can find the virtual displacement write the following
-\begin{equation}
--\Delta u = f\quad \mbox{in }\Omega
-\end{equation}%
-where $f=p/\mu$, $\Omega =\{(x,y);\;x^{2}+y^{2}<1\}$.
- Poisson's equation (\ref{eqn:Poisson}) appear
-also in \textbf{electrostatics} taking the form of $f=\rho /\epsilon $ where
-$\rho $ is the charge density, $\epsilon $ the dielectric constant and $u$
-is named as electrostatic potential. The soap film is glued to the ring $%
-\partial \Omega =C$, then we have the boundary condition
-\begin{equation}
-u=0\quad \mbox{on }\partial \Omega
-\end{equation}%
-If the force is gravity, for simplify, we assume that $f=-1$.
-
-
-\begin{example}[a\_tutorial.edp]~
-\index{tutorial!aTutorial.edp}
-\bFF
- 1 : @border a(t=0,2*pi){ x = cos(t); y = sin(t);label=1;};
- 2 :
- 3 : @mesh disk = @buildmesh(a(50));
- 4 : @plot(disk);
- 5 : @fespace femp1(disk,P1);
- 6 : femp1 u,v;
- 7 : @func f = -1;
- 8 : @problem laplace(u,v) =
- 9 :     @int2d(disk)( @dx(u)*@dx(v) + @dy(u)*@dy(v) )     //  bilinear form
-10 :   - @int2d(disk)( f*v )                          //  linear form
-11 :   + @on(1,u=0) ;                                // boundary condition
-12 : @func ue = (x^2+y^2-1)/4;   // ue: exact solution
-13 : laplace;
-14 : femp1 err = u - ue;
-15 :
-16 : @plot (u,ps="aTutorial.eps",value=true,wait=true);
-17 : @plot(err,value=true,wait=true);
-18 :
-19 : @cout << "error L2=" << @sqrt(@int2d(disk)( err^2) )<< @endl;
-20 : @cout << "error H10=" << @sqrt( @int2d(disk)((dx(u)-x/2)^2)
-21 :                               + @int2d(disk)((dy(u)-y/2)^2))<< @endl;
-22 :
-23 : disk = @adaptmesh(disk,u,err=0.01);
-24 : @plot(disk,wait=1);
-25 :
-26 : laplace;
-27 :
-28 : @plot (u,value=true,wait=true);
-29 : err = u - ue;  // become FE-function on adapted mesh
-30 : @plot(err,value=true,wait=true);
-31 : cout << "error L2=" << @sqrt(@int2d(disk)( err^2) )<< endl;
-32 : cout << "error H10=" << @sqrt(@int2d(disk)((@dx(u)-x/2)^2)
-33 :                              + @int2d(disk)((@dy(u)-y/2)^2))<< endl;
-\eFF
-\begin{figure}[htbp]
-\begin{minipage}{\textwidth}
-\begin{minipage}{0.4\textwidth}
-\includegraphics[width=\textwidth]{aTutorial}%
-\caption{isovalue of $u$}
-\label{aTutorial}
-\end{minipage}
-\hspace{0.5mm}
-\begin{minipage}{0.6\textwidth}
-\includegraphics[width=\textwidth]{soapfilm3d}%
-\caption{a side view of $u$}
-\end{minipage}
-\end{minipage}
-\end{figure}
-
-In 19th line, the $L^2$-error estimation between the exact solution $u_e$,
-$$
-\|u_h - u_e\|_{0,\Omega}=\left(\int_{\Omega}|u_h-u_e|^2\, dxdy\right)^{1/2}
-$$
-and from 20th line to 21th line, the $H^1$-error seminorm estimation
-$$
-|u_h - u_e|_{1,\Omega}=\left(\int_{\Omega}|\nabla u_h-\nabla u_e|^2\, dxdy\right)^{1/2}
-$$
-are done on the initial mesh. The results are
-$\|u_h - u_e\|_{0,\Omega}=0.000384045,\, |u_h - u_e|_{1,\Omega}=0.0375506$.
-
-After the adaptation, we hava
-$\|u_h - u_e\|_{0,\Omega}=0.000109043,\, |u_h - u_e|_{1,\Omega}=0.0188411$.
-So the numerical solution is improved by adaptation of mesh.
-\end{example}
-
-\subsubsection{Electrostatics}
-We assume that there is no current and a time independent charge distribution.
-Then the electric field $\vec E$ satisfy
-\begin{eqnarray}
-\label{eqn:Maxwell0}
-\mathrm{div}\vec E=\rho/\epsilon,\quad \mathrm{curl}\vec E=0
-\end{eqnarray}
-where $\rho$ is the charge density and $\epsilon$ is called the permittivity of free space. From the second equation in (\ref{eqn:Maxwell0}), we can introduce
-the electrostatic potential such that $\vec E=-\nabla \phi$.
-Then we have Poisson equation $-\Delta \phi=f$, $f=-\rho/\epsilon$.
-We now obtain the equipotential line which is the level curve of $\phi$,
-when there are no charges except conductors $\{C_i\}_{1,\cdots,K}$.
-Let us assume $K$ conductors $C_1,\cdots,C_K$ within an enclosure $C_0$.
-Each one is held
-at an electrostatic potential $\varphi_i$. We assume that the enclosure $C0$ is
-held at
-potential 0.
-In order to know $\varphi(x)$ at any point $x$ of the domain $\Omega$, we must
-solve
-\begin{equation}
--\Delta \varphi =0\quad \textrm{in  }\Omega ,
-\end{equation}
-where $\Omega$ is the interior of $C_0$ minus the conductors $C_i$, and
-$\Gamma$ is the boundary of $\Omega$, that is $\sum_{i=0}^N C_i$.
-Here $g$ is any function of $x$ equal to $\varphi_i$ on $C_i$ and to
-0 on $C_0$. The second equation is a reduced form for:
-\begin{equation}
-\varphi =\varphi _{i}\;\text{on }C_{i},\;i=1...N,\varphi =0\;\text{on\ }%
-C_{0}.
-\end{equation}
-\begin{example}~
-First we give the geometrical informations; $C_0=\{(x,y);\; x^2+y^2=5^2\}$,
-$C_1=\{(x,y):\; \frac{1}{0.3^2}(x-2)^2+\frac{1}{3^2}y^2=1\}$,
-$C_2=\{(x,y):\; \frac{1}{0.3^2}(x+2)^2+\frac{1}{3^2}y^2=1\}$.
-Let $\Omega$ be the disk enclosed by $C_0$ with the elliptical holes enclosed
-by $C_1$ and $C_2$. Note that $C_0$ is described counterclockwise, whereas the
-elliptical holes are described clockwise, because the boundary must be oriented so that the computational domain is to its left.
-\bFF
-// a circle with center at (0 ,0) and radius 5
-border C0(t=0,2*pi) { x = 5 * cos(t); y = 5 * sin(t); }
-border C1(t=0,2*pi) { x = 2+0.3 * cos(t); y = 3*sin(t); }
-border C2(t=0,2*pi) { x = -2+0.3 * cos(t); y = 3*sin(t); }
-
-mesh Th = buildmesh(C0(60)+C1(-50)+C2(-50));
-plot(Th,ps="electroMesh"); // figure \ref{electroMesh}
-fespace Vh(Th,P1);     // P1 FE-space
-Vh uh,vh;              // unknown and test function.
-problem Electro(uh,vh) =  //  definition of  the problem
-    int2d(Th)( dx(uh)*dx(vh) + dy(uh)*dy(vh) ) //  bilinear
-    + on(C0,uh=0)       //  boundary condition on $C_0$
-    + on(C1,uh=1)       //  +1 volt on $C_1$
-    + on(C2,uh=-1) ;    //  -1 volt on $C_2$
-
-Electro; // solve the problem, see figure \ref{electro} for the solution
-plot(uh,ps="electro.eps",wait=true); // figure \ref{electro}
-\eFF
-\end{example}
-
-\twoplot[height=5cm]{electroMesh}{electro}{Disk with two elliptical holes}
-{Equipotential lines, where $C_1$ is located in right hand side}
-
-\subsubsection{Aerodynamics}
-Let us consider a wing profile $S$ in a uniform flow.
-Infinity will be represented
-by a large circle $\Gamma_{\infty}$.
-As previously, we must solve
-\begin{equation}
-\label{eqn:NACA-5-5}
-\Delta \varphi=0\quad\textrm{in }\Omega,
-\quad \varphi|_S=c,\quad
-\varphi|_{\Gamma_{\infty}}=u_{\infty 1x}-u_{\infty2x}
-\end{equation}
-where $\Omega$ is the area occupied by the
-fluid, $u_{\infty}$ is the air speed at infinity, $c$
-is a constant to be determined so that
-$\partial_n\varphi$ is continuous at the trailing edge
-$P$ of $S$ (so-called Kutta-Joukowski condition).
-Lift is proportional to $c$.
-To find $c$ we use a superposition method. As all equations in
-(\ref{eqn:NACA-5-5}) are
-linear, the solution $\varphi_c$ is a linear function of $c$
-\begin{equation}
-\label{eqn:NACA-5-6}
-\varphi_c = \varphi_0 + c\varphi_1,
-\end{equation}
-where $\varphi_0$ is a solution of (\ref{eqn:NACA-5-5}) with $c = 0$ and
-$\varphi_1$ is a solution with $c = 1$ and
-zero speed at infinity.
-With these two fields computed, we shall determine $c$
-by requiring the continuity of $\partial \varphi /\partial n$ at the trailing edge.
-An equation for the upper surface of a NACA0012 (this is a classical wing
-profile in aerodynamics; the rear of the wing is called the trailing edge) is:
-\begin{equation}
-\label{eqn:NACA-5-7}
-y := 0.17735\sqrt{x} - 0.075597x - 0.212836x^2 + 0.17363x^3 - 0.06254x^4.
-\end{equation}
-Taking an incidence angle $\alpha$ such that $\tan \alpha = 0.1$, we must solve
-\begin{equation}
-\label{eqn:NACA-5-8}
--\Delta\varphi  = 0\qquad \textrm{in }\Omega, \qquad
-\varphi|_{\Gamma_1} = y - 0.1x,\quad \varphi |_{\Gamma_2} = c,
-\end{equation}
-where $\Gamma_2$ is the wing profile and $\Gamma_1$ is an approximation of
-infinity. One finds $c$ by solving:
-\begin{eqnarray}
-\label{eqn:NACA-5-9}
--\Delta\varphi_0 = 0 ~~\textrm{in }\Omega,\qquad
-\varphi_0|_{\Gamma_1} = y - 0.1x, \quad \varphi_0|_{\Gamma_2} = 0,\\
-\label{eqn:NACA-5-10}
--\Delta\varphi_1 = 0 ~~\textrm{in }\Omega, \qquad
-\varphi_1|_{\Gamma_1} = 0, \quad \varphi_1|_{\Gamma_2} = 1.
-\end{eqnarray}
-The solution $\varphi  = \varphi_0+c\varphi_1$ allows us to find $c$
-by writing that $\partial_n\varphi$  has no jump
-at the trailing edge $P = (1, 0)$.
-We have $\partial n\varphi  -(\varphi (P^+)-\varphi (P))/\delta$ where $P^+$
-is the point just above $P$ in the direction normal to the profile at a distance
-$\delta$. Thus the jump of $\partial_n\varphi$  is
-$(\varphi_0|_{P^+} +c(\varphi_1|_{P^+} -1))+(\varphi_0|_{P^-} +c(\varphi_1|_{P^-} -1))$
-divided by $\delta$ because the normal changes sign between the lower and upper
-surfaces. Thus
-\begin{equation}
-\label{eqn:NACA-5-11}
-c = -\frac{\varphi_0|_{P^+} + \varphi_0|_{P^-}}
-{(\varphi_1|_{P^+} + \varphi_1|_{P^-} - 2)} ,
-\end{equation}
-which can be programmed as:
-\begin{equation}
-\label{eqn:NACA-5-12}
-c = -\frac{\varphi_0(0.99, 0.01) + \varphi_0(0.99,-0.01)}
-{(\varphi_1(0.99, 0.01) + \varphi_1(0.99,-0.01) - 2)} .
-\end{equation}
-
-\begin{example}
-\bFF
-
-// Computation of the potential flow around a NACA0012 airfoil.
-// The method of decomposition is used to apply the Joukowski condition
-// The solution is seeked in the form psi0 + beta psi1 and beta is
-// adjusted so that the pressure is continuous at the trailing edge
-
- at border a(t=0,2*pi) { x=5*cos(t);  y=5*sin(t); };// approximates infinity
-
- at border upper(t=0,1) { x = t;
-     y = 0.17735*sqrt(t)-0.075597*t
-  - 0.212836*(t^2)+0.17363*(t^3)-0.06254*(t^4); }
- at border lower(t=1,0) { x = t;
-     y= -(0.17735*sqrt(t)-0.075597*t
-  -0.212836*(t^2)+0.17363*(t^3)-0.06254*(t^4)); }
- at border c(t=0,2*pi) { x=0.8*cos(t)+0.5;  y=0.8*sin(t); }
-
- at wait = @true;
- at mesh  Zoom = @buildmesh(c(30)+upper(35)+lower(35));
- at mesh Th = @buildmesh(a(30)+upper(35)+lower(35));
- at fespace Vh(Th,P2);     // P1 FE space
-Vh psi0,psi1,vh;              // unknown and test function.
- at fespace ZVh(Zoom,P2);
-
- at solve Joukowski0(psi0,vh) =     //  definition of  the problem
-    @int2d(Th)( dx(psi0)*dx(vh) + dy(psi0)*dy(vh) ) //  bilinear form
-  + @on(a,psi0=y-0.1*x)                      //  boundary condition form
-  + @on(upper,lower,psi0=0);
- at plot(psi0);
-
- at solve Joukowski1(psi1,vh) =     //  definition of  the problem
-    @int2d(Th)( dx(psi1)*dx(vh) + dy(psi1)*dy(vh) ) //  bilinear form
-  + @on(a,psi1=0)                      //  boundary condition form
-  + @on(upper,lower,psi1=1);
-
- at plot(psi1);
-
-    // continuity of pressure at trailing edge
- at real beta = psi0(0.99,0.01)+psi0(0.99,-0.01);
- at beta = -beta / (psi1(0.99,0.01)+ psi1(0.99,-0.01)-2);
-
-
-Vh psi = beta*psi1+psi0;
- at plot(psi);
-ZVh Zpsi=psi;
- at plot(Zpsi,bw=true);
-Vh cp = -dx(psi)^2 - dy(psi)^2;
- at plot(cp);
-ZVh Zcp=cp;
- at plot(Zcp,nbiso=40);
-\eFF
-\end{example}
-\twoplot[height=5cm]{naca1}{naca2}
-{isovalue of $cp = -(\partial_x\psi)^2 - (\partial_y\psi)^2$}
-{Zooming of $cp$}
-
-
-\subsubsection{Error estimation}
-There are famous estimation between the numerical result $u_h$ and the
-exact solution $u$ of the problem \ref{eqn:Poisson} and \ref{eqn:Dirichlet}:
-If triangulations $\{\mathcal{T}_h\}_{h\downarrow 0}$ is regular
-(see \refSec{Regular Triangulation}), then we have the estimates
-\begin{eqnarray}
-\label{eqn:H1err}
-|\nabla u - \nabla u_h|_{0,\Omega}&\le& C_1h\\
-\label{eqn:L2err}
-\|u - u_h\|_{0,\Omega}&\le& C_2h^2
-\end{eqnarray}
-with constants $C_1,\, C_2$ independent of $h$,
-if $u$ is in $H^2(\Omega)$. It is known that $u\in H^2(\Omega)$
-if $\Omega$ is convex.
-
-In this section we check (\ref{eqn:H1err}) and (\ref{eqn:L2err}).
-We will pick up numericall error if we use the numerical derivative,
-so we will use the following for (\ref{eqn:H1err}).
-\begin{eqnarray*}
-\int_{\Omega}|\nabla u - \nabla u_h|^2\, dxdy
-&=&\int_{\Omega}\nabla u\cdot \nabla(u - 2u_h)\, dxdy+
-\int_{\Omega}\nabla u_h\cdot \nabla u_h\, dxdy\\
-&=&\int_{\Omega}f(u-2u_h)\, dxdy+\int_{\Omega}fu_h\, dxdy
-\end{eqnarray*}
-The constants $C_1,\, C_2$ are depend on $\mathcal{T}_h$ and $f$,
-so we will find them by \freefempp.
-In general, we cannot get the solution $u$ as a elementary functions
-(see Section \ref{sec:TwoVarFunctions}) even if spetical functions are added.
-Instead of the exact solution, here we use the approximate solution $u_0$  in
-$V_h(\mathcal{T}_h,P_2),\, h\sim 0$.
-
-\begin{example}~
-\bFF
- 1 : @mesh Th0 = @square(100,100);
- 2 : @fespace V0h(Th0,P2);
- 3 : V0h u0,v0;
- 4 : @func f = x*y; // sin(pi*x)*cos(pi*y);
- 5 :
- 6 : @solve Poisson0(u0,v0) =
- 7 :     @int2d(Th0)( @dx(u0)*@dx(v0) + @dy(u0)*@dy(v0) )     //  bilinear form
- 8 :   - @int2d(Th0)( f*v0 )                          //  linear form
- 9 :   + @on(1,2,3,4,u0=0) ;                // boundary condition
-10 :
-11 : @plot(u0);
-12 :
-13 : @real[int] errL2(10), errH1(10);
-14 :
-15 : @for (@int i=1; i<=10; i++) {
-16 :    @mesh Th = @square(5+i*3,5+i*3);
-17 :    @fespace Vh(Th,P1);
-18 :    @fespace Ph(Th,P0);
-19 :    Ph h = hTriangle;  // get the size of all triangles
-20 :    Vh u,v;
-21 :    @solve Poisson(u,v) =
-22 :         @int2d(Th)( dx(u)*dx(v) + dy(u)*dy(v) )     //  bilinear form
-23 :         - @int2d(Th)( f*v )                          //  linear form
-24 :         + @on(1,2,3,4,u=0) ;                // boundary condition
-25 :    V0h uu = u;
-26 :    errL2[i-1] = @sqrt( @int2d(Th0)((uu - u0)^2) )/h[].max^2;
-27 :    errH1[i-1] = @sqrt( @int2d(Th0)( f*(u0-2*uu+uu) ) )/h[].max;
-28 : }
-29 : @cout << "C1 = " << errL2.max <<"("<<errL2.min<<")"<< endl;
-30 : @cout << "C2 = " << errH1.max <<"("<<errH1.min<<")"<< endl;
-\eFF
-\end{example}
-We can guess that $C_1=0.0179253(0.0173266)$ and
-$C_2=0.0729566(0.0707543)$, where the numbers inside the parentheses
-are minimum in calculation.
-
-\subsubsection{Periodic }\index{periodic}\index{fespace!periodic=}
-We now solve the Poisson equation
-$$ -\Delta u= sin(x+\pi/4.)*cos(y+\pi/4.)$$ on
-the square $]0,2\pi[^2$
-under bi-periodic boundary condition
-$u(0,y)=u(2\pi,y)$ for all $y$ and
-$u(x,0)=u(x,2\pi)$ for all $x$.
-These boundary conditions are achieved from the definition
-of the periodic finite element space.
-
-\begin{example}[periodic.edp]~
-\label{exm:periodic}
-\index{tutorial!periodic.edp}
-\bFF
- at mesh Th=square(10,10,[2*x*pi,2*y*pi]);
-// defined the \bgroup\tt fespace\egroup  with periodic condition
-//    label :  2 and 4  are left and right   side with y the curve abscissa
-//             1 and 2  are bottom and upper side with x the curve abscissa
- at fespace Vh(Th,P2,periodic=[[2,y],[4,y],[1,x],[3,x]]);
- Vh uh,vh;              // unknown and test function.
- @func f=sin(x+pi/4.)*cos(y+pi/4.);      //  right hand side function
-
-@ problem laplace(uh,vh) =                      //  definion of  the problem
-    @int2d(Th)( dx(uh)*dx(vh) + dy(uh)*dy(vh) ) //  bilinear form
-  + @int2d(Th)( -f*vh )                         //  linear form
-;
-
-  @laplace; // solve the problem plot(uh); // to see the result
-  @plot(uh,ps="period.eps",value=true);
-\eFF
-\plot[height=6cm]{period}{The isovalue of solution $u$ with periodic boundary condition}
-\end{example}
-
-The periodic condition does not necessarily require
-parallel to the axis. Example \ref{exm:periodic4}
- give such example.
-
-\begin{example}[periodic4.edp]~
-\label{exm:periodic4}
-\index{tutorial!periodic4.edp}
-\bFF
- at real r=0.25;
-// a diamond with a hole
- at border a(t=0,1){x=-t+1; y=t;label=1;};
- at border b(t=0,1){ x=-t; y=1-t;label=2;};
- at border c(t=0,1){ x=t-1; y=-t;label=3;};
- at border d(t=0,1){ x=t; y=-1+t;label=4;};
- at border e(t=0,2*pi){ x=r*cos(t); y=-r*sin(t);label=0;};
- at int n = 10;
- at mesh Th= buildmesh(a(n)+b(n)+c(n)+d(n)+e(n));
- at plot(Th,wait=1);
- at real r2=1.732;
- at func abs=sqrt(x^2+y^2);
-//  warning for periodic condition: \hfilll
-//  side a and c \hfilll
-//  @on side a (label 1) $ x \in [0,1] $ or $ x-y\in [-1,1] $ \hfilll
-//  @on side c (label 3) $ x \in [-1,0]$ or $ x-y\in[-1,1] $\hfilll
-// so the common abscissa can be respectively $x$ and $x+1$
-// or you can can try curviline abscissa $x-y$ and $x-y$
-//  1 first way \hfilll
-// @fespace Vh(Th,P2,periodic=[[2,1+x],[4,x],[1,x],[3,1+x]]);  \hfilll
-// 2 second way \hfilll
- @fespace Vh(Th,P2,periodic=[[2,x+y],[4,x+y],[1,x-y],[3,x-y]]);
-
- Vh uh,vh;
-
- @func f=(y+x+1)*(y+x-1)*(y-x+1)*(y-x-1);
- @real intf = @int2d(Th)(f);
- @real mTh = @int2d(Th)(1);
- @real k =  intf/mTh;
- @cout << k << @endl;
- @problem laplace(uh,vh) =
-    @int2d(Th)( dx(uh)*dx(vh) + dy(uh)*dy(vh) ) + @int2d(Th)( (k-f)*vh ) ;
- laplace;
- @plot(uh,wait=1,ps="perio4.eps");
-\eFF
-\end{example}
-\plot[height=6cm]{perio4}{The isovalue of solution $u$ for
-$ \Delta u = ((y+x)^{2}+1)((y-x)^{2}+1) - k$, in $\Omega$ and $\partial_{n} u =0 $ on hole,and with two periodic boundary condition on external border}
-
-
-\subsubsection{Poisson with mixed boundary condition}
-Here we consider the Poisson equation with mixed boundary value
-problems: For given functions $f$ and $g$, find $u$ such that
-\begin{eqnarray}
-\label{eqn:mixBoundary}
--\Delta u &=& f\qquad \textrm{in }\Omega\nonumber\\
-u&=&g\quad \textrm{on }\Gamma_D,\quad
-\partial u/\partial n=0\quad \textrm{on }\Gamma_N
-\end{eqnarray}
-where $\Gamma_D$ is a part of the boundary $\Gamma$ and
-$\Gamma_N=\Gamma\setminus \overline{\Gamma_D}$.
-The solution $u$ has the singularity at the points
-$\{\gamma_1,\gamma_2\}=\overline{\Gamma_D}\cap\overline{\Gamma_N}$.
-When $\Omega=\{(x,y);\; -1<x<1,\, 0<y<1\}$,
-$\Gamma_N=\{(x,y);\; -1\le x<0,\, y=0\}$,\,
-$\Gamma_D=\partial \Omega\setminus \Gamma_N$,
-the singularity will appear at $\gamma_1=(0,0),\, \gamma_2(-1,0)$,
-and $u$ has the expression
-$$
-u=K_iu_S + u_R,\, u_R\in H^2(\textrm{near }\gamma_i),\, i=1,2
-$$
-with a constants $K_i$.
-Here $u_S = r_j^{1/2}\sin(\theta_j/2)$ by the local polar coordinate
-$(r_j,\theta_j$ at $\gamma_j$ such that
-$(r_1,\theta_1)=(r,\theta)$.
-Instead of poler coordinate system $(r,\theta)$, we use that
-$r=\ttCC{sqrt( x\^2+y\^2 )}$ and $\theta = \ttCC{atan2(y,x)}$
-in \freefempp.
-
-\begin{example} Assume that $f=-2\times 30(x^2+y^2)$ and
-$g=u_e=10(x^2+y^2)^{1/4}\sin\left ([\tan^{-1}(y/x)]/2\right)
-+30(x^2y^2)$, where $u_e$S is the exact solution.
-\bFF
- 1 : @border N(t=0,1) { x=-1+t; y=0; label=1; };
- 2 : @border D1(t=0,1){ x=t;  y=0; label=2;};
- 3 : @border D2(t=0,1){ x=1; y=t; label=2; };
- 4 : @border D3(t=0,2){ x=1-t; y=1; label=2;};
- 5 : @border D4(t=0,1) { x=-1; y=1-t; label=2; };
- 6 :
- 7 : @mesh T0h = @buildmesh(N(10)+D1(10)+D2(10)+D3(20)+D4(10));
- 8 : @plot(T0h,wait=true);
- 9 : @fespace V0h(T0h,P1);
-10 : V0h u0, v0;
-11 :
-12 : @func f=-2*30*(x^2+y^2); // given function
-13 : // the singular term of the solution is K*us (K: constant)
-14 : @func us = sin(atan2(y,x)/2)*sqrt( sqrt(x^2+y^2) );
-15 : @real K=10.;
-16 : @func ue = K*us + 30*(x^2*y^2);
-17 :
-18 : @solve Poisson0(u0,v0) =
-19 :     @int2d(T0h)( dx(u0)*dx(v0) + dy(u0)*dy(v0) )     //  bilinear form
-20 :   - @int2d(T0h)( f*v0 )                          //  linear form
-21 :   + @on(2,u0=ue) ;                                // boundary condition
-22 :
-23 : // adaptation by the singular term
-24 : @mesh Th = @adaptmesh(T0h,us);
-25 : @for (@int i=0;i< 5;i++)
-26 : {
-27 :   @mesh Th=@adaptmesh(Th,us);
-28 : } ;
-29 :
-30 : @fespace Vh(Th, P1);
-31 : Vh u, v;
-32 : @solve Poisson(u,v) =
-33 :     @int2d(Th)( dx(u)*dx(v) + dy(u)*dy(v) )     //  bilinear form
-34 :   - @int2d(Th)( f*v )                          //  linear form
-35 :   + @on(2,u=ue) ;                                // boundary condition
-36 :
-37 : /* plot the solution */
-38 : @plot(Th,ps="adaptDNmix.ps");
-39 : @plot(u,wait=true);
-40 :
-41 : Vh uue = ue;
-42 : @real  H1e = @sqrt( @int2d(Th)( dx(uue)^2 + dy(uue)^2 + uue^2 ) );
-43 :
-44 : /* calculate the H1 Sobolev norm */
-45 : Vh err0 = u0 - ue;
-46 : Vh  err = u - ue;
-47 : Vh  H1err0 = @int2d(Th)( dx(err0)^2+dy(err0)^2+err0^2 );
-48 : Vh  H1err = @int2d(Th)( dx(err)^2+dy(err)^2+err^2 );
-49 : @cout <<"Relative error in first mesh "<< @int2d(Th)(H1err0)/H1e<<@endl;
-50 : @cout <<"Relative error in adaptive mesh "<< @int2d(Th)(H1err)/H1e<@<endl;
-\eFF
-From 24th line to 28th, adaptation of meshes are done using the
-base of singular term.
-In 42th line, \ttCC{H1e}=$\|u_e\|_{1,\Omega}$ is calculated.
-In last 2 lines, the relative errors are calculated, that is,
-\begin{eqnarray*}
-\|u^0_h-u_e\|_{1,\Omega}/\ttCC{H1e}&=&0.120421\\
-\|u^a_h-u_e\|_{1,\Omega}/\ttCC{H1e}&=&0.0150581
-\end{eqnarray*}
-where $u^0_h$ is the numerical solution in \ttCC{T0h} and
-$u^a_h$ is \ttCC{u} in this program.
-\end{example}
-
-\subsubsection{Adaptation with residual error indicator}
-
-We do metric mesh adaption and compute the classical
-residual error indicator $\eta_{T}$ on the element $T$ for the Poisson problem.
-
-\begin{example}[adaptindicatorP2.edp]~
-\index{tutorial!adaptindicatorP2.edp}
-First, we solve the same problem as in a previous example.
-\bFF
- 1 : @border ba(t=0,1.0){x=t;   y=0;  label=1;}; // see Fig,\ref{L-shape2}
- 2 : @border bb(t=0,0.5){x=1;   y=t;  label=2;};
- 3 : @border bc(t=0,0.5){x=1-t; y=0.5;label=3;};
- 4 : @border bd(t=0.5,1){x=0.5; y=t;  label=4;};
- 5 : @border be(t=0.5,1){x=1-t; y=1;  label=5;};
- 6 : @border bf(t=0.0,1){x=0;   y=1-t;label=6;};
- 7 : @mesh Th = buildmesh (ba(6) + bb(4) + bc(4) +bd(4) + be(4) + bf(6));
- 8 : @savemesh(Th,"th.msh");
- 9 : @fespace Vh(Th,P2);
-10 : @fespace Nh(Th,P0);
-11 : Vh u,v;
-12 : Nh rho;
-13 : real[int] viso(21);
-14 : @for (@int i=0;i<viso.n;i++)
-15 :   viso[i]=10.^(+(i-16.)/2.);
-16 : @real error=0.01;
-17 : @func f=(x-y);
-18 : @problem Probem1(u,v,solver=CG,eps=1.0e-6) =
-19 :     @int2d(Th,qforder=5)( u*v*1.0e-10+  dx(u)*dx(v) + dy(u)*dy(v))
-20 :   + @int2d(Th,qforder=5)( -f*v);
-21 : /*************
-\eFF
-\index{jump}\index{intalledges}\index{square}\index{lenEdge}\index{hTriangle}%\index{area}
-Now, the local  error indicator $\eta_{T}$ is:
-\def\Th{\mathcal{T}_{h}}
-\def\AK{\mathcal{E}_{K}}
-
-$$\eta_{T} =\left(  h_{T}^{2} || f + \Delta u_{{h}} ||_{L^{2}(T)}^{2} +\sum_{e\in \AK} h_{e} \,||\, [ \frac{\partial u_{h}}{\partial n_{k}}] \,||^{2}_{L^{2}(e)} \right)^{\frac{1}{2}}
-   $$
-where $h_{T}$ is the longest's edge of  $T$, ${\cal E}_T$ is the set of $T$ edge not on
-$\Gamma=\partial \Omega$, $n_{T}$ is the  outside unit normal to $K$, $h_{e}$ is the length of edge $e$,
-$[ g ]$ is the jump of the function $g$ across edge (left value minus right value).
-
-Of coarse, we can use a variational form to compute $\eta_{T}^{2}$,
-with test function constant function in each triangle.
-\bFF
-29 : *************/
-30 :
-31 : @varf indicator2(uu,chiK) =
-32 :      @intalledges(Th)(chiK*lenEdge*square(jump(N.x*dx(u)+N.y*dy(u))))
-33 :     + at int2d(Th)(chiK*square(hTriangle*(f+dxx(u)+dyy(u))) );
-34 : for (int i=0;i< 4;i++)
-35 : {
-36 :   Probem1;
-37 :    @cout << u[].min << " " << u[].max << endl;
-38 :    @plot(u,wait=1);
-39 :    @cout << " indicator2 " << endl;
-40 :
-41 :    rho[] = indicator2(0,Nh);
-42 :    rho=sqrt(rho);
-43 :    @cout << "rho =   min " << rho[].min << " max=" << rho[].max << @endl;
-44 :    @plot(rho,fill=1,wait=1,cmm="indicator density ",ps="rhoP2.eps",
-                                       value=1,viso=viso,nbiso=viso.n);
-45 :    @plot(Th,wait=1,cmm="Mesh ",ps="ThrhoP2.eps");
-46 :    Th=@adaptmesh(Th,[dx(u),dy(u)],err=error,anisomax=1);
-47 :    @plot(Th,wait=1);
-48 :    u=u;
-49 :    rho=rho;
-50 :   error = error/2;
-51 : } ;
-\eFF
-If the method is correct, we expect to look the graphics by an almost constant function $\eta$ on your computer as in Fig. \ref{fig:rhoP2}.
-\begin{figure}[hbt]
-\begin{center}
-\label{fig:rhoP2}
-\includegraphics[height=8cm]{rhoP2} \includegraphics[height=8cm]{ThrhoP2}
-\end{center}
-\caption{Density of the error indicator  with isotropic $P^{2}$ metric }
-\end{figure}
-\end{example}
-
-
-\subsection{Elasticity}
-
-Consider an elastic plate with undeformed shape $\Omega\times ]-h,h[$
-in $\R^3$, $\Omega\subset\R^2$.
-By the deformation of the plate,
-we assume that a point $P(x_1,x_2,x_3)$ moves to
-${\cal P}(\xi_1,\xi_2,\xi_3)$.
-The vector $\vec u=(u_1,u_2,u_3)=(\xi_1-x_1,\xi_2-x_2,\xi_3-x_3)$ is called
-\key{displacement vector}.
-By the deformation,
-the line segment
-$\overline{\mathbf{x},\mathbf{x}+\tau\Delta\mathbf{x}}$ moves approximately to
-$\overline{\mathbf{x}+u(\mathbf{x}),\mathbf{x}+\tau\Delta\mathbf{x}
-+u(\mathbf{x}+\tau\Delta\mathbf{x})}$ for small $\tau$,
-where
-$\mathbf{x}=(x_1,x_2,x_3),\, \Delta\mathbf{x}
-=(\Delta x_1,\Delta x_2,\Delta x_3)$.
-We now calculate the ratio between two segments
-\[
-\eta(\tau)=\tau^{-1}|\Delta\mathbf{x}|^{-1}
-\left(|u(\mathbf{x}+\tau\Delta\mathbf{x})
--u(\mathbf{x})+\tau\Delta\mathbf{x}|-\tau|\Delta\mathbf{x}|\right)
-\]
-then we have (see e.g. \cite[p.32]{Necas})
-\begin{eqnarray*}
-\lim_{\tau\to 0}\eta(\tau)=(1+2e_{ij}\nu_i\nu_j)^{1/2}-1,
-\quad 2e_{ij}=\frac{\partial u_k}{\partial x_i}\frac{\partial u_k}{\partial x_j}+\left(\frac{\partial u_i}{\partial x_j}+
-\frac{\partial u_j}{\partial x_i}\right)
-\end{eqnarray*}
-where $\nu_i=\Delta x_i|\Delta\mathbf{x}|^{-1}$. If the deformation is
-\emph{small}, then we may consider that
-\[
-(\partial u_k/\partial x_i)(\partial u_k/\partial x_i)\approx 0
-\]
-and the following is called \emph{small \key{strain tensor}}
-\[
-\varepsilon_{ij}(u)=\frac{1}{2}\left(\frac{\partial u_i}{\partial x_j}+
-\frac{\partial u_j}{\partial x_i}\right)
-\]
-The tensor $e_{ij}$ is called \emph{finite strain tensor}.
-
-Consider the small plane $\Delta \Pi(\mathbf{x})$
-centered at $\mathbf{x}$ with the
-unit normal direction $\vec n=(n_1,n_2,n_3)$, then the surface
-on $\Delta \Pi(\mathbf{x})$ at $\mathbf{x}$ is
-\[
-(\sigma_{1j}(\mathbf{x})n_j, \sigma_{2j}(\mathbf{x})n_j, \sigma_{3j}(\mathbf{x})n_j)
-\]
-where $\sigma_{ij}(\mathbf{x})$ is called \key{stress tensor} at $\mathbf{x}$.
-Hooke's law is the assumption of a linear relation between $\sigma_{ij}$
-and $\varepsilon_{ij}$ such as
-\[
-\sigma_{ij}(\mathbf{x})=c_{ijkl}(\mathbf{x})\varepsilon_{ij}(\mathbf{x})
-\]
-with the symmetry $c_{ijkl}=c_{jikl}, c_{ijkl}=c_{ijlk}, c_{ijkl}=c_{klij}$.
-
-If Hooke's tensor $c_{ijkl}(\mathbf{x})$ do not depend on the choice of
-coordinate system, the material is called \key{isotropic} at $\mathbf{x}$.
-If $c_{ijkl}$ is constant, the material is called \emph{homogeneous}.
-In homogeneous isotropic case, there is \emph{Lam\'{e} constants}
-$\lambda, \mu$ (see e.g. \cite[p.43]{Necas}) satisfying
-\begin{eqnarray}
-\label{eqn:isotropic}
-\sigma_{ij}=\lambda\delta_{ij}\textrm{div}u+2\mu \varepsilon_{ij}
-\end{eqnarray}
-where $\delta_{ij}$ is Kronecker's delta.
-We assume that
-the elastic plate is fixed
-on $\Gamma_D\times ]-h,h[,\, \Gamma_D\subset \partial\Omega$.
-If the body force $f=(f_1,f_2,f_3)$ is given in $\Omega\times]-h,h[$
-and surface force $g$ is given in $\Gamma_N\times]-h,h[,
-\Gamma_N=\partial\Omega\setminus\overline{\Gamma_D}$,
-then the equation of equilibrium is given as follows:
-\begin{eqnarray}
-\label{eqn:elasticity}
--\partial_j \sigma_{ij}&=&f_i~~\textrm{in }\Omega\times ]-h,h[,\quad
-i=1,2,3\\
-\sigma_{ij}n_j&=&g_i~~\textrm{on }\Gamma_N\times ]-h,h[,\quad
-u_i=0~~\textrm{on }\Gamma_D\times ]-h,h[,\quad i=1,2,3
-\end{eqnarray}
-
-We now explain the plain elasticity.
-\begin{description}
-\item[Plain strain:]
-On the end of plate, the contact condition $u_3=0,\, g_3=$ is satisfied.
-In this case, we can suppose that $f_3=g_3=u_3=0$ and
-$\vec u(x_1,x_2,x_3)=\overline{u}(x_1,x_2)$ for all $-h<x_3<h$.
-\item[Plain stress:]
-The cylinder is assumed to be very thin and subjected to no load on the
-ends $x_3=\pm h$, that is,
-\[
-\sigma_{3i}=0,\quad x_3=\pm h,\quad i~1,2,3
-\]
-The assumption leads that $\sigma_{3i}=0$ in $\Omega\times ]-h,h[$
-and $\vec u(x_1,x_2,x_3)=\overline{u}(x_1,x_2)$ for all $-h<x_3<h$.
-\item[Generalized plain stress:]
-The cylinder is subjected to no load on the ends $x_3=\pm h$.
-Introducing the mean values with respect to thickness,
-\[
-\overline{u}_i(x_1,x_2)=\frac{1}{2h}
-\int_{-h}^h u(x_1,x_2,x_3)dx_3
-\]
-and we derive $\overline{u}_3\equiv 0$. Similarly we define the mean
-values $\overline{f},\overline{g}$ of the body force and surface force
-as well as the mean values $\overline{\varepsilon}_{ij}$ and
-$\overline{\sigma}_{ij}$ of the components of stress and strain, respectively.
-\end{description}
-In what follows we omit the overlines of
-$\overline{u}, \overline{f},\overline{g}, \overline{\varepsilon}_{ij}$ and
-$\overline{\varepsilon}_{ij}$.
-Then we obtain similar equation of equilibrium given in (\ref{eqn:elasticity})
-replacing $\Omega\times ]-h,h[$ with $\Omega$ and changing $i=1,2$.
-In the case of plane stress,
-$\sigma_{ij}=\lambda^* \delta_{ij}\textrm{div}u+2\mu\varepsilon_{ij},
-\lambda^*=(2\lambda \mu)/(\lambda+\mu)$.
-
-The equations of elasticity are naturally written in variational form
-for the displacement vector $u(x)\in V$ as
-\Blue{$$
-\int_\Omega [2\mu\epsilon_{ij}(\vec u)\epsilon_{ij}(\vec v)
-+\lambda \epsilon_{ii}(\vec{u})\epsilon_{jj}(\vec v)]
-=\int_\Omega \vec f\cdot \vec v +\int_\Gamma \vec g\cdot \vec v,%\`{u}
-\forall \vec v\in V
-$$}
-where $V$ is the linear closed subspace of $H^1(\Omega)^2$.
-
-\begin{example}[Beam.edp]
-\index{tutorial!beam.edp}
-Consider  elastic plate with the undeformed rectangle shape
-$[0,10]\times [0,2]$.
-The body force is the gravity force $\vec f$ and the
-boundary force $\vec g$ is zero on lower and upper side.
-On the two vertical sides of the beam are fixed.
-\bFF
-//   a weighting beam sitting on a
-
-int bottombeam = 2;
- at border a(t=2,0)  { x=0; y=t ;label=1;};        //  left beam
- at border b(t=0,10) { x=t; y=0 ;label=bottombeam;};        //  bottom of beam
- at border c(t=0,2)  { x=10; y=t ;label=1;};       //  rigth beam
- at border d(t=0,10) { x=10-t; y=2; label=3;};     //  top beam
- at real E = 21.5;
- at real sigma = 0.29;
- at real mu = E/(2*(1+sigma));
- at real lambda = E*sigma/((1+sigma)*(1-2*sigma));
- at real gravity = -0.05;
- at mesh th = buildmesh( b(20)+c(5)+d(20)+a(5));
- at fespace Vh(th,[P1,P1]);
-Vh [uu,vv], [w,s];
- at cout << "lambda,mu,gravity ="<<lambda<< " " << mu << " " << gravity << endl;
-// deformation of a beam under its own weight
- at solve  bb([uu,vv],[w,s])  =
-    @int2d(th)(
-          2*mu*(dx(uu)*dx(w)+dy(vv)*dy(s)+ ((dx(vv)+dy(uu))*(dx(s)+dy(w)))/2 )
-          + lambda*(dx(uu)+dy(vv))*(dx(w)+dy(s))
-    )
-  + @int2d(th) (-gravity*s)
-  + @on(1,uu=0,vv=0)
- ;
-
- at plot([uu,vv],wait=1);
- at plot([uu,vv],wait=1,bb=[[-0.5,2.5],[2.5,-0.5]]);
- at mesh th1 = movemesh(th, [x+uu, y+vv]);
- at plot(th1,wait=1);
-\eFF
-\end{example}
-
-\subsubsection{Fracture Mechanics}
-Consider the plate with the crack whose undeformed shape is
-a curve $\Sigma$ with the two edges $\gamma_1,\, \gamma_2$.
-We assume the stress tensor $\sigma_{ij}$ is the state of
-plate stress regarding $(x,y)\in \Omega_{\Sigma}=\Omega\setminus \Sigma$.
-Here $\Omega$ stands for the undeformed shape of elastic plate
-without crack.
-If the part $\Gamma_N$ of the boundary $\partial\Omega$ is fixed
-and a load ${\cal L}=(\vec f,\vec g)\in
-L^2(\Omega)^2\times L^2(\Gamma_N)^2$  is given,
-then the displacement $\vec u$ is the minimizer of the potential energy
-functional
-\[
-{\cal E}(\vec v;{\cal L},\Omega_{\Sigma})
-=\int_{\Omega_{\Sigma}}
-\{w(x,\vec v)-\vec f\cdot \vec v\}
--\int_{\Gamma_N}\vec g\cdot \vec v\
-\]
-over the functional space $V(\Omega_{\Sigma})$,
-\[
-V(\Omega_{\Sigma})
-=\left\{ \vec v\in H^1(\Omega_{\Sigma})^2;\;
-\vec v=0\quad \hbox{\rm on }
-\Gamma_D=\partial\Omega\setminus\overline{\Gamma_N}\right\},
-\]
-where $w(x,\vec v)=\sigma_{ij}(\vec v)\varepsilon_{ij}(\vec v)/2$,
-\[
-\sigma_{ij}(\vec v)=C_{ijkl}(x)\varepsilon_{kl}(\vec v),\quad
-\varepsilon_{ij}(\vec v)=(\partial v_i/\partial x_j+
-\partial v_j/\partial x_i)/2,
-\qquad (C_{ijkl}:\quad \hbox{\rm Hooke's tensor}).
-\]
-If the elasticity is homogeneous isotropic, then the
-displacement $\vec u(x)$ is decomposed in an open neighborhood $U_k$
-of $\gamma_k$ as in (see e.g. \cite{Ohtsuka})
-\begin{equation}
-\label{eqn:SIF}
-\vec u(x) =
-\sum_{l=1}^2 K_l(\gamma_k) r_k^{1/2} S^C_{kl}(\theta_k)
-+ \vec u_{k,R}(x)
-\quad \mbox{for }x\in \Omega_{\Sigma}\cap U_k,\, k=1,2
-\end{equation}
-with $\vec u_{k,R} \in H^2(\Omega_\Sigma\cap U_k)^2$, where
-$U_k,\, k=1,2$ are open neighborhoods of $\gamma_k$ such that
-$\partial L_1\cap U_1=\gamma_1,\, \partial L_m\cap U_2=\gamma_2$,
-and
-\begin{eqnarray}
-\label{eqn:SIF2}
- S^C_{k1}(\theta_k) & = & \frac 1 {4\mu} \frac 1 {(2\pi)^{1/2}}
-    \left[ \begin{array}{c}
-    [2\kappa-1]\cos(\theta_k/2)-\cos(3\theta_k/2)\\
-    -[2\kappa+1]\sin(\theta_k/2)+\sin(3\theta_k/2)
-    \end{array}\right],\\
- S^C_{k2}(\theta_k) & = & \frac 1 {4\mu} \frac 1 {(2\pi)^{1/2}}
-    \left[ \begin{array}{c}
-    -[2\kappa-1]\sin(\theta_k/2)+3\sin(3\theta_k/2)\\
-    -[2\kappa+1]\cos(\theta_k/2)+\cos(3\theta_k/2)
-    \end{array}\right]. \nonumber
-\end{eqnarray}
-where $\mu$ is the shear modulus of elasticity,
-$\kappa=3-4\nu$ ($\nu$ is the Poisson's ratio) for
-plane strain and $\kappa=\frac {3-\nu} {1+\nu}$ for plane stress.
-
-The coefficients $K_1(\gamma_i)$ and $K_2(\gamma_i),$ which are important parameters in fracture mechanics,
-are called stress intensity factors of the opening mode (mode I)
-and the sliding mode (mode II), respectively.
-
-For simplicity, we consider the following simple crack
-\[
-\Omega=\{(x,y):\; -1<x<1, -1<y<1\},\qquad
-\Sigma=\{(x,y):\; -1\le x\le 0, y=0\}
-\]
-with only one crack tip $\gamma=(0,0)$.
-Unfortunately, \freefempp cannot treat crack, so we use the modification
-of the domain with U-shape channel (see Fig. \ref{U-shape})
-with $d=0.0001$. The undeformed crack $\Sigma$ is approximated by
-\begin{eqnarray*}
-\Sigma_d&=&\{(x,y):\; -1\le x\le -10*d, -d\le y\le d\}\\
-&&\cup\{(x,y):\; -10*d\le x\le 0, -d+0.1*x\le y\le d-0.1*x\}
-\end{eqnarray*}
-and $\Gamma_D=\ttCC{R}$ in Fig. \ref{U-shape}.
-In this example, we use three technique:
-\begin{itemize}
-\item
-Fast Finite Element Interpolator from the mesh \ttCC{Th}
-to \ttCC{Zoom} for the scale-up of
-near $\gamma$.
-\item
-After obtaining the displacement vector $\vec u=(u,v)$, we shall watch
-the deformation of the crack near $\gamma$ as follows,
-\bT
-mesh Plate = movemesh(Zoom,[x+u,y+v]);
-plot(Plate);
-\eT
-\item
-Important technique is adaptive mesh, because the large singularity occur at
-$\gamma$
-as shown in (\ref{eqn:SIF}).
-\end{itemize}
-First example create mode I deformation by the opposed surface force
-on \ttCC{B} and \ttCC{T}
-in the vertical direction of $\Sigma$, and
-the displacement is fixed on \ttCC{R}.
-
-In a laboratory, fracture engineer use
-photoelasticity to make stress field visible, which
-shows the principal stress difference
-\begin{eqnarray}
-\sigma_1-\sigma_2=\sqrt{(\sigma_{11}-\sigma_{22})^2+4\sigma_{12}^2}
-\end{eqnarray}
-where $\sigma_1$ and $\sigma_2$ are the principal stresses.
-In opening mode, the photoelasticity make symmetric pattern concentrated at
-$\gamma$.
-\begin{example}[Crack Opening, $K_2(\gamma)=0$]
-\bFF{CrackOpen.edp}
- at real d = 0.0001;
- at int n = 5;
- at real cb=1, ca=1, tip=0.0;
- at border L1(t=0,ca-d) { x=-cb; y=-d-t; }
- at border L2(t=0,ca-d) { x=-cb; y=ca-t; }
- at border B(t=0,2) { x=cb*(t-1); y=-ca; }
- at border C1(t=0,1) { x=-ca*(1-t)+(tip-10*d)*t; y=d; }
- at border C21(t=0,1) { x=(tip-10*d)*(1-t)+tip*t; y=d*(1-t); }
- at border C22(t=0,1) { x=(tip-10*d)*t+tip*(1-t); y=-d*t; }
- at border C3(t=0,1) { x=(tip-10*d)*(1-t)-ca*t; y=-d; }
- at border C4(t=0,2*d) { x=-ca; y=-d+t; }
- at border R(t=0,2) { x=cb; y=cb*(t-1); }
- at border T(t=0,2) { x=cb*(1-t); y=ca; }
- at mesh Th = @buildmesh (L1(n/2)+L2(n/2)+B(n)
-                       +C1(n)+C21(3)+C22(3)+C3(n)+R(n)+T(n));
-cb=0.1; ca=0.1;
- at plot(Th, at wait=1);
- at mesh Zoom = @buildmesh (L1(n/2)+L2(n/2)+B(n)+C1(n)
-                         +C21(3)+C22(3)+C3(n)+R(n)+T(n));
- at plot(Zoom, at wait=1);
- at real E = 21.5;
- at real sigma = 0.29;
- at real mu = E/(2*(1+sigma));
- at real lambda = E*sigma/((1+sigma)*(1-2*sigma));
- at fespace Vh(Th,[P2,P2]);
- at fespace zVh(Zoom,P2);
-Vh [u,v], [w,s];
- at solve  Problem([u,v],[w,s])  =
-    @int2d(Th)(
-             2*mu*(dx(u)*dx(w)+ ((dx(v)+dy(u))*(dx(s)+dy(w)))/4 )
-             + lambda*(dx(u)+dy(v))*(dx(w)+dy(s))/2
-             )
-    - at int1d(Th,T)(0.1*(4-x)*s)+ at int1d(Th,B)(0.1*(4-x)*s)
-    + at on(R,u=0)+on(R,v=0);                // fixed
-;
-
-zVh Sx, Sy, Sxy, N;
- at for (@int i=1; i<=5; i++)
-{
-  @mesh Plate = @movemesh(Zoom,[x+u,y+v]); // deformation near $\gamma$
-  Sx = lambda*(dx(u)+dy(v)) + 2*mu*dx(u);
-  Sy = lambda*(dx(u)+dy(v)) + 2*mu*dy(v);
-  Sxy = mu*(dy(u) + dx(v));
-  N = 0.1*1*sqrt((Sx-Sy)^2+4*Sxy^2); //principal stress difference
-  @if (i==1) {
-     @plot(Plate,ps="1stCOD.eps",bw=1); // Fig. \ref{1stMode1}
-     @plot(N,ps="1stPhoto.eps",bw=1);   // Fig. \ref{1stMode1}
-  } @else @if (i==5) {
-     @plot(Plate,ps="LastCOD.eps",bw=1); // Fig. \ref{LastMode1}
-     @plot(N,ps="LastPhoto.eps",bw=1);   // Fig. \ref{LastMode1}
-     @break;
-  }
-  Th=@adaptmesh(Th,[u,v]);
-  Problem;
-}
-\eFF
-\end{example}
-
-\begin{figure}[hbt]
-\begin{multicols}{2}
-\begin{center}
-\includegraphics*[height=3cm]{1stCOD}\includegraphics*[height=3cm]{1stPhoto}
-    \caption{\label{1stMode1} Crack open displacement (COD) and Principal stress difference in the first mesh}
-\end{center}
-\begin{center}
-\includegraphics*[height=3cm]{LastCOD}\includegraphics*[height=3cm]{LastPhoto}
-    \caption{\label{LastMode1} COD and Principal stress difference in the last adaptive mesh}
-\end{center}
-\end{multicols}
-\end{figure}
-It is difficult to create mode II deformation by the opposed shear force
-on \ttCC{B} and \ttCC{T} that is observed in a laboratory.
-So we use the body shear force along $\Sigma$, that is, the $x$-component $f_1$
-of the body force $\vec f$ is given by
-\[
-f_1(x,y)=H(y-0.001)*H(0.1-y)-H(-y-0.001)*H(y+0.1)
-\]
-where $H(t)=1$ if $t>0$; $= 0$ if $t<0$.
-
-\begin{example}[Crack Sliding, $K_2(\gamma)=0$]
-\bFF
-(use the same mesh Th)
-cb=0.01; ca=0.01;
- at mesh Zoom = @buildmesh (L1(n/2)+L2(n/2)+B(n)+C1(n)
-                         +C21(3)+C22(3)+C3(n)+R(n)+T(n));
-(use same FE-space Vh and elastic modulus)
- at fespace Vh1(Th,P1);
-Vh1 fx = ((y>0.001)*(y<0.1))-((y<-0.001)*(y>-0.1)) ;
-
- at solve  Problem([u,v],[w,s])  =
-    @int2d(Th)(
-             2*mu*(dx(u)*dx(w)+ ((dx(v)+dy(u))*(dx(s)+dy(w)))/4 )
-             + lambda*(dx(u)+dy(v))*(dx(w)+dy(s))/2
-             )
-    - at int2d(Th)(fx*w)
-    + at on(R,u=0)+ at on(R,v=0);        // fixed
-;
-
- at for (@int i=1; i<=3; i++)
-{
-  @mesh Plate = @movemesh(Zoom,[x+u,y+v]); // deformation near $\gamma$
-  Sx = lambda*(dx(u)+dy(v)) + 2*mu*dx(u);
-  Sy = lambda*(dx(u)+dy(v)) + 2*mu*dy(v);
-  Sxy = mu*(dy(u) + dx(v));
-  N = 0.1*1*sqrt((Sx-Sy)^2+4*Sxy^2); //principal stress difference
-  @if (i==1) {
-     @plot(Plate,ps="1stCOD2.eps",bw=1); // Fig. \ref{LastMode2}
-     @plot(N,ps="1stPhoto2.eps",bw=1);   // Fig. \ref{1stMode2}
-  } else if (i==3) {
-     @plot(Plate,ps="LastCOD2.eps",bw=1); // Fig. \ref{LastMode2}
-     @plot(N,ps="LastPhoto2.eps",bw=1);   // Fig. \ref{LastMode2}
-     break;
-  }
-  Th=@adaptmesh(Th,[u,v]);
-  Problem;
-}
-\eFF
-\end{example}
-\begin{figure}[hbt]
-\begin{multicols}{2}
-\begin{center}
-\includegraphics*[height=3cm]{1stCOD2}\includegraphics*[height=3cm]{1stPhoto2}
-    \caption{\label{1stMode2} (COD) and Principal stress difference in the first mesh}
-\end{center}
-\begin{center}
-\includegraphics*[height=3cm]{LastCOD2}\includegraphics*[height=3cm]{LastPhoto2}
-    \caption{\label{LastMode2} COD and Principal stress difference in the last adaptive mesh}
-\end{center}
-\end{multicols}
-\end{figure}
-
-
-\subsection{Nonlinear Static Problems}
-We propose how to solve the following non-linear academic  problem of minimization
-of a functional $$J(u) = \int_\Omega f(|\nabla u|^2) - u*b $$
-where $u$ is function of $H^1_0(\Omega)$
-and $f$ defined by
-$$
-f(x) = a*x + x-ln(1+x), \quad f'(x) = a+\frac{x}{1+x}, \quad f''(x) =  \frac{1}{(1+x)^2}
-$$
-
-\subsubsection{Newton Ralphson algorithm}
-
-
-Now, we solve the Euler problem $ \nabla J (u) = 0$
-with Newton Ralphson algorithm, that is,
-$$
-u^{n+1} = u^n - ( \nabla^2 J (u^{n}))^{-1}*dJ(u^n)
-$$
-
-\index{Newton}
-First we introduice the two variational form \texttt{vdJ} and \texttt{vhJ} to
-compute respectively $ \nabla J$ and $ \nabla^2 J$
-\bFF
-//   method of  Newton Ralphson to solve dJ(u)=0; \hfilll
-//    $$ u^{n+1} = u^n - (\frac{\partial dJ}{\partial u_i})^{-1}*dJ(u^n) $$ \hfilll
-//   --------------------------------------------- \hfilll
-  Ph dalpha ; //to store = $f''( |\nabla u|^2) $  optimisation
-
-
-  // the variational form of evaluate  dJ = $ \nabla J$ \hfilll
-  // -------------------------------------- \hfilll
-  //  dJ =  f'()*( dx(u)*dx(vh) + dy(u)*dy(vh) \hfilll
-  @varf vdJ(uh,vh) =  int2d(Th)( alpha*( dx(u)*dx(vh) + dy(u)*dy(vh) ) - b*vh)
-  + on(1,2,3,4, uh=0);
-
-
-  // the variational form of evaluate  ddJ   $= \nabla^2 J$ \hfilll
-  // hJ(uh,vh) =  f'()*( dx(uh)*dx(vh) + dy(uh)*dy(vh) \hfilll
-  //            + f''()( dx(u)*dx(uh) + dy(u)*dy(uh) ) * (dx(u)*dx(vh) + dy(u)*dy(vh)) \hfilll
-  @varf vhJ(uh,vh) = int2d(Th)( alpha*( dx(uh)*dx(vh) + dy(uh)*dy(vh) )
-   +  dalpha*( dx(u)*dx(vh) + dy(u)*dy(vh)  )*( dx(u)*dx(uh) + dy(u)*dy(uh) ) )
-   + on(1,2,3,4, uh=0);
-
- // the Newton algorithm \hfilll
-  Vh v,w;
-  u=0;
-  @for (int i=0;i<100;i++)
-   {
-    alpha = df( dx(u)*dx(u) + dy(u)*dy(u) ) ; // optimization
-    dalpha = ddf( dx(u)*dx(u) + dy(u)*dy(u) ) ; // optimization
-    v[]= vdJ(0,Vh);  // $ v = \nabla J(u) $
-    real res= v[]'*v[]; // the dot product
-    cout << i <<  " residu^2 = " <<  res  << endl;
-    @if( res< 1e-12) @break;
-    @matrix H= vhJ(Vh,Vh,factorize=1,solver=LU); //\index{matrix!factorize=}
-    w[]=H^-1*v[];
-    u[] -= w[];
-   }
-   plot (u,wait=1,cmm="solution with Newton Ralphson");
-\eFF
-
-\subsection{Eigenvalue Problems}
-
-This section depend on your FreeFem++ compilation process (see \texttt{README\_arpack}),
-of this tools.
-This tools is available in \texttt{FreeFem++}  if the word ``eigenvalue'' appear in line ``Load:'', like:
-\bFF
--- FreeFem++ v1.28 (date Thu Dec 26 10:56:34 CET 2002)
- file : LapEigenValue.edp
- Load: lg_fem lg_mesh @eigenvalue
-\eFF
-This tools is based on the \texttt{arpack++} \footnote{\url{http://www.caam.rice.edu/software/ARPACK/}}
-the object-oriented version of ARPACK eigenvalue package \cite{arpack}.
-
-The function EigenValue compute the generalized eigenvalue
-of  $ A u = \lambda B u $ where sigma =$\sigma$ is the shift of the method.
-The matrix  $ OP$ is defined with $ A - \sigma B $.
-The return value is the number of converged eigenvalue (can be greater than the number of eigen value nev=)
-
-\bFF
- at int k=@EigenValue(OP,B,nev= , sigma= );
-\eFF
-where the matrix $OP=  A - \sigma B $ with a solver and boundary condition,
-and the matrix $B$.
-
-\begin{description}
-          \item[\texttt{sym=}]    the problem is symmetric (all the eigen value are real)
-          \item[\texttt{nev=}]    the number desired eigenvalues (nev)  close to the shift.
-        \item[\texttt{value=}]    the array to store the real part of the eigenvalues
-         \item[\texttt{ivalue=}]     the array to store the imag. part of the eigenvalues
-         \item[\texttt{vector=}]    the array to store the eigenvectors.
- For real nonsymmetric problems, complex eigenvectors are given as two consecutive vectors, so if eigenvalue $k$ and $k+1$ are complex conjugate eigenvalues, the $k$th vector will contain the real part and the $k+1$th vector the imaginary part of the corresponding complex conjugate eigenvectors.
-
-         \item[\texttt{tol=}]        the relative accuracy to which eigenvalues are to be determined;
-         \item[\texttt{sigma=}]    the shift value;
-         \item[\texttt{maxit=}]    the maximum number of iterations allowed;
-          \item[\texttt{ncv=}]     the number of Arnoldi vectors generated at each iteration of ARPACK.
- \end{description}
-
-
-\begin{example}[lapEignenValue.edp]
-\label{exm:lapEigenValue}
-In the first example, we compute   the eigenvalue and the eigenvector of the
- Dirichlet problem  on square $\Omega=]0,\pi[^2$.
-
-The problem is find:   $\lambda$, and $\nabla u_{\lambda}$  in $\mathbb{R}{\times} H^1_0(\Omega)$
-$$ \int_\Omega \nabla u_{\lambda} \nabla v = \lambda \int_\Omega u  v \quad  \forall v \in H^1_0(\Omega)$$
-
-The exact
-eigenvalues are $\lambda_{n,m} =(n^2+m^2), (n,m)\in {\mathbb{N}_*}^2$ with
-the associated eigenvectors are  $  u_{{m,n}}=sin(nx)*sin(my)$.
-
-
-
-We use the generalized inverse shift mode of the \texttt{arpack++} library, to find
-20 eigenvalue and eigenvector close to the shift value $\sigma=20$.
-
-\bFF
-//  Computation of the eigen value and eigen vector of the \hfilll
-//  Dirichlet problem  on square $]0,\pi[^2$ \hfilll
-// ----------------------------------------\hfilll
-// we use the inverse shift mode \hfilll
-// the shift is given with the real sigma\hfilll
-// -------------------------------------\hfilll
-//  find $\lambda$ and $u_\lambda\in H^1_0(\Omega)$ such that: \hfilll
-// \hfilll$\displaystyle  \int_{\Omega}  \nabla u_{\lambda} \nabla v = \lambda \int_{\Omega} u_{\lambda}   v , \forall v \in H^1_0(\Omega) $\hfilll
-verbosity=10;
- at mesh Th=square(20,20,[pi*x,pi*y]);
- at fespace Vh(Th, at P2);
-Vh u1,u2;
-
-
- at real sigma = 20;  // value of the shift
-
-// OP = A - sigma B ;  //  the shifted matrix
- at varf  op(u1,u2)= int2d(Th)(  dx(u1)*dx(u2) + dy(u1)*dy(u2) - sigma* u1*u2 )
-                    +  on(1,2,3,4,u1=0) ;  // Boundary condition
-
- at varf b([u1],[u2]) = int2d(Th)(  u1*u2 ) ; // no  Boundary condition
-
- at matrix OP= op(Vh,Vh,solver=Crout,factorize=1);  // crout solver because the matrix in not positive
- at matrix B= b(Vh,Vh,solver=CG,eps=1e-20);
-
-// important remark:
-// the boundary condition is make with exact penalization:
-//     we put 1e30=tgv  on the diagonal term of the lock degree of freedom.
-//  So take Dirichlet boundary condition just on $a$ variational form
-// and not on  $b$ variational form.
-// because we solve $ w=OP^-1*B*v $
-
-int nev=20;  // number of computed eigen value close to sigma
-
-real[int] ev(nev); // to store the  nev eigenvalue
-Vh[int] eV(nev);   // to store the nev eigenvector \index{EigenValue}
-
-
- at int k=@EigenValue(OP,B,sym=true,sigma=sigma,value=ev,vector=eV,
-                   tol=1e-10,maxit=0,ncv=0);
-
-//   tol= the tolerance \hfilll
-//   maxit= the maximum iteration see arpack doc.\hfilll
-//   ncv   see arpack doc. \url{http://www.caam.rice.edu/software/ARPACK/}\hfilll
-//  the return value is number of converged eigen value.\hfilll
-
- at for (@int i=0;i<k;i++)
-{
-  u1=eV[i];
-  @real gg = int2d(Th)(dx(u1)*dx(u1) + dy(u1)*dy(u1));
-  @real mm= int2d(Th)(u1*u1) ;
-  @cout << " ---- " <<  i<< " " << ev[i]<< " err= "
-       <<int2d(Th)(dx(u1)*dx(u1) + dy(u1)*dy(u1) - (ev[i])*u1*u1) << " --- "<<endl;
-  @plot(eV[i],cmm="Eigen  Vector "+i+" valeur =" + ev[i]  ,wait=1,value=1);
-}
-
-\eFF
-
-The output of this example is:
-
-\bFF
-
-   Nb of edges on Mortars  = 0
-   Nb of edges on Boundary = 80, neb = 80
- Nb Of Nodes = 1681
- Nb of DF = 1681
-Real symmetric eigenvalue problem: A*x - B*x*lambda
-
-
-Thanks to ARPACK++ class ARrcSymGenEig
-Real symmetric eigenvalue problem: A*x - B*x*lambda
-Shift and invert mode  sigma=20
-
-Dimension of the system            : 1681
-Number of 'requested' eigenvalues  : 20
-Number of 'converged' eigenvalues  : 20
-Number of Arnoldi vectors generated: 41
-Number of iterations taken         : 2
-
-Eigenvalues:
-  lambda[1]: 5.0002
-  lambda[2]: 8.00074
-  lambda[3]: 10.0011
-  lambda[4]: 10.0011
-  lambda[5]: 13.002
-  lambda[6]: 13.0039
-  lambda[7]: 17.0046
-  lambda[8]: 17.0048
-  lambda[9]: 18.0083
-  lambda[10]: 20.0096
-  lambda[11]: 20.0096
-  lambda[12]: 25.014
-  lambda[13]: 25.0283
-  lambda[14]: 26.0159
-  lambda[15]: 26.0159
-  lambda[16]: 29.0258
-  lambda[17]: 29.0273
-  lambda[18]: 32.0449
-  lambda[19]: 34.049
-  lambda[20]: 34.0492
-
- ---- 0 5.0002 err= -0.000225891 ---
- ---- 1 8.00074 err= -0.000787446 ---
- ---- 2 10.0011 err= -0.00134596 ---
- ---- 3 10.0011 err= -0.00134619 ---
- ---- 4 13.002 err= -0.00227747 ---
- ---- 5 13.0039 err= -0.004179 ---
- ---- 6 17.0046 err= -0.00623649 ---
- ---- 7 17.0048 err= -0.00639952 ---
- ---- 8 18.0083 err= -0.00862954 ---
- ---- 9 20.0096 err= -0.0110483 ---
- ---- 10 20.0096 err= -0.0110696 ---
- ---- 11 25.014 err= -0.0154412 ---
- ---- 12 25.0283 err= -0.0291014 ---
- ---- 13 26.0159 err= -0.0218532 ---
- ---- 14 26.0159 err= -0.0218544 ---
- ---- 15 29.0258 err= -0.0311961 ---
- ---- 16 29.0273 err= -0.0326472 ---
- ---- 17 32.0449 err= -0.0457328 ---
- ---- 18 34.049 err= -0.0530978 ---
- ---- 19 34.0492 err= -0.0536275 ---
-\eFF
-
-\twoplot[height=8cm]{eigen11}{eigen12}{Isovalue of 11th eigenvector $u_{4,3}-u_{3,4}$}{Isovalue of 12th eigenvector $u_{4,3}+u_{3,4}$}
-\end{example}
-
-\subsection{\setS{Evolution Problems}}
-\freefempp also solve evolution problems such as the heat problem
-\begin{eqnarray}
-\label{prb:heat}
-&&\frac{\partial u}{\partial t}-\mu\Delta u=f\quad \textrm{in }\Omega\times ]0,T[,\\
-&&u(\vec x,0)=u_0(\vec x)\quad \textrm{in }\Omega; \qquad
-\left(\partial u/\partial n\right)(\vec x,t)=0\quad\textrm{on }\partial\Omega\times ]0,T[.\nonumber
-\end{eqnarray}
-with a positive viscosity coefficient $\mu$ and homogeneous Neumann boundary conditions.
-We solve (\ref{prb:heat}) by FEM in space and finite differences in time.
-We use the definition of the partial derivative of the solution in the time
-derivative,
-\[
-\frac{\partial u}{\partial t}(x,y,t) = \lim_{\tau \to 0}
-\frac{u(x,y,t)-u(x,y,t-\tau )}{\tau }
-\]
-which indicate that $u^m(x,y)=u(x,y,m\tau )$ imply
-\[
-\frac{\partial u}{\partial t}(x,y,m\tau )\simeq \frac{u^m(x,y)-u^{m-1}(x,y)}{\tau }
-\]
-The time discretization of heat equation (\ref{eqn:heat}) is as follows:
-\begin{eqnarray}
-\label{eqn:heat}
-&&\frac{u^{m+1}-u^{m}}{\tau }-\mu\Delta u^{m+1}=f^{m+1}
-\quad \textrm{in }\Omega\\
-&&u^0(\vec x)=u_0(\vec x)\quad \textrm{in }\Omega; \qquad
-\partial u^{m+1}/\partial n(\vec x)=0\quad\textrm{on }\partial\Omega,\quad
-\textrm{for all }m=0,\cdots,[T/\tau ],\nonumber
-\end{eqnarray}
-which is so-called \key{backward Euler method} for (\ref{eqn:heat}).
-Multiplying the test function $v$ both sides of the formula
-just above, we have
-\begin{equation*}
-\int_{\Omega }\{u^{m+1}v-\tau \Delta u^{m+1}v\}
-=\int_{\Omega }\{u^m+\tau  f^{m+1}\}v\, .
-\end{equation*}%
-By the divergence theorem, we have
-\begin{equation*}
-\int_{\Omega} \{u^{m+1}v+\tau \nabla u^{m+1}\cdot \nabla v\}
--\int_{\partial\Omega} \tau \left( \partial u^{m+1}/\partial n\right) v=\int_{\Omega }\{u^mv+\tau f^{m+1}v\}.
-\end{equation*}%
-By the boundary condition $\partial u^{m+1}/\partial n=0$, it follows that
-\begin{equation}
-\label{eqn:BackEuler}
-\int_{\Omega} \{u^{m+1}v+\tau \nabla u^{m+1}\cdot \nabla v\}-
-\int_{\Omega }\{u^mv+\tau f^{m+1}v\}=0.
-\end{equation}%
-Using the identity just above, we can calculate the finite element
-approximation $u_h^m$ of $u^m$ in a step-by-step manner with respect to $t$.
-
-\begin{example}
-We now solve the following example with the exact solution $u(x,y,t)=tx^4$.
-\begin{eqnarray*}
-&&\frac{{\partial u}}{{\partial t}} - \mu \Delta u = x^4 - \mu 12tx^2 ~
-\textrm{in  } \Omega  \times ]0,3[,\, \Omega = ]0,1[^2 \\
-&&u(x,y,0) = 0\quad\textrm{on }\Omega,\qquad \left. u \right|_{\partial\Omega}  = t*x^4
-\end{eqnarray*}
-\bFF
-// heat equation  $\partial_t u = -\mu \Delta u = x^4 - \mu 12tx^2$
- at mesh Th=@square(16,16);
- at fespace Vh(Th,P1);
-
-Vh u,v,uu,f,g;
- at real dt = 0.1, mu = 0.01;
- at problem dHeat(u,v) =
-    @int2d(Th)( u*v + dt*mu*(@dx(u)*@dx(v) + @dy(u)*@dy(v)))
-    + @int2d(Th) (- uu*v - dt*f*v )
-    + @on(1,2,3,4,u=g);
-
- at real t = 0; // start from t=0
-uu = 0;     // u(x,y,0)=0
- at for (@int m=0;m<=3/dt;m++)
-{
-   t=t+dt;
-   f = x^4-mu*t*12*x^2;
-   g = t*x^4;
-   dHeat;
-   @plot(u,wait=true);
-   uu = u;
-   @cout <<"t="<<t<<"L^2-Error="<<@sqrt( @int2d(Th)((u-t*x^4)^2) ) << @endl;
-}
-\eFF
-In the last statement, the $L^2$-error
-$\left(\int_{\Omega}\left| u-tx^4\right|^2\right)^{1/2}$ is calculated at
-$t=m\tau , \tau =0.1$. At $t=0.1$, the error is 0.000213269.
-The errors increase with $m$ and 0.00628589 at $t=3$.
-
-The iteration of the backward Euler (\ref{eqn:BackEuler}) is made by
-\textbf{for loop} (see \refSec{Loops}).
-\end{example}
-
-\begin{note}
-The stiffness matrix in loop is used over and over again.
-\freefempp support reuses of stiffness matrix.
-\end{note}
-
-\subsubsection{Mathematical Theory on time difference}
-In this section, we show the advantage of the backward Euler.
-Let $V, H$ be separable Hilbert space and $V$ is dense in $H$.
-Let $a$ be a continuous bilinear form over $V \times V$ with coercivity and
-symmetry.
-Then $\sqrt{a(v,v)}$ become equivalent to the norm $\| v\|$ of $V$.
-
-\textbf{problem} Ev$(f,\Omega)$: For a given $f\in L^2(0,T;V'),\, u^0\in H$
-\begin{eqnarray}
-\label{eqn:Abstract}
-\frac{d}{dt}(u(t),v)+a(u(t),v)&=&( f(t),v)\qquad \forall v\in V,,\quad a.e. \, t\in [0,T]\\
-u(0)&=&u^0\nonumber
-\end{eqnarray}
-where $V'$ is the dual space of $V$.
-Then, there is an unique solution
-$u\in L^{\infty}(0,T;H)\cap L^2(0,T;V)$.
-
-Let us denote the time step by $\tau>0$, $N_T=[T/\tau]$.
-For the discretization, we put $u^n = u(n\tau)$
-and consider the time difference for each $\theta\in [0,1]$
-\begin{eqnarray}
-\label{eqn:t-method}
-\frac{1}{\tau}\left( u_h^{n+1}-u_h^n,\phi_i\right)
-+a\left( u_h^{n+\theta},\phi_i\right)=\langle f^{n+\theta},\phi_i\rangle\\
-i=1,\cdots, m,\quad n=0,\cdots, N_T\nonumber\\
-u_h^{n+\theta}=\theta u_h^{n+1}+(1-\theta)u_h^n,\quad
-f^{n+\theta}=\theta f^{n+1}+(1-\theta)f^n\nonumber
-\end{eqnarray}
-Formula (\ref{eqn:t-method}) is the \emph{forward Euler scheme} if
-$\theta=0$, \emph{Crank-Nicolson scheme} if $\theta=1/2$,
-the \emph{backward Euler scheme} if $\theta=1$.
-
-Unknown vectors $u^n=(u_h^1,\cdots,u_h^M)^T$ in
-\[
-u_h^n(x)=u^n_1\phi_1(x)+\cdots+u^n_m\phi_m(x),\quad u^n_1,\cdots,u^n_m\in \R
-\]
-are obtained from solving the matrix
-\begin{eqnarray}
-\label{eqn:Evolution-1}
-(M+\theta\tau A)u^{n+1}=\{M-(1-\theta)\tau A\}u^n
-+\tau\left\{\theta f^{n+1}+(1-\theta)f^n\right\}\\
-M=(m_{ij}),\quad m_{ij}=(\phi_j,\phi_i),\qquad
-A=(a_{ij}),\quad a_{ij}=a(\phi_j,\phi_i)\nonumber
-\end{eqnarray}
-Refer \cite[pp.70--75]{TA94} for solvability of (\ref{eqn:Evolution-1}).
-The stability of (\ref{eqn:Evolution-1}) is in \cite[Theorem 2.13]{TA94}:
-\begin{quotation}
-Let $\{\mathcal{T}_h\}_{h\downarrow 0}$ be regular triangulations
-(see \refSec{Regular Triangulation}).
-Then there is a number $c_0>0$ independent of $h$ such that,
-\begin{eqnarray}
-|u_h^n|^2\le
-\left\{
-\begin{array}{lr}
-\frac{1}{\delta}\left\{
-|u^0_h|^2+\tau \sum_{k=0}^{n-1}\|f^{k+\theta}\|^2_{V_h'}
-\right\}&\theta\in [0,1/2)\\
-|u^0_h|^2+\tau \sum_{k=0}^{n-1}\|f^{k+\theta}\|^2_{V_h'}&\theta\in [1/2,1]
-\end{array}
-\right.
-\end{eqnarray}
-if the following are satisfied:
-\begin{enumerate}
-  \item When $\theta\in [0,1/2)$, then we can take a time step $\tau$ in
-such a way that
-\begin{eqnarray}
-\tau <\frac{2(1-\delta)}{(1-2\theta)c_0^2}h^2
-\end{eqnarray}
-for arbitrary $\delta\in (0,1)$.
-  \item When $1/2\le \theta\le 1$, we can take $\tau$ arbitrary.
-\end{enumerate}
-\end{quotation}
-
-\begin{example}~
-\bFF
- at mesh Th=square(12,12);
- at fespace Vh(Th,P1);
- at fespace Ph(Th,P0);
-
-Ph h = hTriangle; // mesh sizes for each triangle
- at real tau = 0.1, theta=0.;
- at func @real f(@real t) {
-   @return x^2*(x-1)^2 + t*(-2 + 12*x - 11*x^2 - 2*x^3 + x^4);
-}
- at ofstream out("err02.csv"); // file to store calculations
-out << "mesh size = "<<h[].max<<", time step = "<<tau<<@endl;
- at for (@int n=0;n<5/tau;n++) \\
-   out<<n*tau<<",";
-out << @endl;
-Vh u,v,oldU;
-Vh f1, f0;
- at problem aTau(u,v) =
-  @int2d(Th)( u*v + theta*tau*(dx(u)*dx(v) + dy(u)*dy(v) + u*v))
-  - @int2d(Th)(oldU*v - (1-theta)*tau*(dx(oldU)*dx(v)+dy(oldU)*dy(v)+oldU*v))
-  - @int2d(Th)(tau*( theta*f1+(1-theta)*f0 )*v );
-
- at while (theta <= 1.0) {
-  @real t = 0, T=3; // from t=0 to T
-  oldU = 0;     // u(x,y,0)=0
-  out <<theta<<",";
-  @for (@int n=0;n<T/tau;n++) {
-      t = t+tau;
-      f0 = f(n*tau); f1 = f((n+1)*tau);
-      aTau;
-      oldU = u;
-      @plot(u);
-      Vh uex = t*x^2*(1-x)^2; // exact sol.$=tx^2(1-x)^2$
-      Vh err = u - uex; // $err=$FE-sol - exact
-      out<< abs(err[].max)/abs(uex[].max) <<","; // $\|err \|_{L^\infty(\Omega )}/\|u_{ex} \|_{L^\infty(\Omega )}$
-  }
-  out << endl;
-  theta = theta + 0.1;
-}
-\eFF
-\begin{figure}[htbp]
-\begin{center}
-\includegraphics[height=6cm]{err02}
-\end{center}
-\caption{$\max_{x\in \Omega}|u_h^n(\theta)-u_{ex}(n\tau)|/\max_{x\in \Omega}|u_{ex}(n\tau)|$ at $n=0,1,\cdots,29$}
-\label{fig:err02}
-\end{figure}
-We can see in Fig. \ref{fig:err02} that $u_h^n(\theta)$ become unstable at $\theta=0.4$, and figures are omitted in the case $\theta<0.4$.
-\end{example}
-
-\subsubsection{Convection}
-The hyperbolic equation
-\begin{eqnarray}
-\label{eqn:conv}
-\partial_t u-\vec{\alpha} \cdot \nabla u=f;~~
-\textrm{for a vector-valued function }\vec{\alpha},~
-\partial_t=\frac{\partial}{\partial t},
-\end{eqnarray}
-appear frequently in scientific problems, for example,
-Navier-Stokes equation, Convection-Diffusion equation, etc.
-
-In the case of 1-dimensional space, we can easily find the general solution
-$(x,t)\mapsto u(x,t)=u^0(x-\alpha t)$ of the following equation, if $\alpha$ is constant,
-\begin{eqnarray}
-\label{eqn:conv0}
-\partial_t u +\alpha\partial_x u=0,\qquad u(x,0)=u^0(x),
-\end{eqnarray}
-because $\partial_t u +\alpha\partial_x u=-\alpha\dot{u}^0+a\dot{u}^0=0$,
-where $\dot{u}^0=du^0(x)/dx$.
-Even if $\alpha$ is not constant construction, the principle is similar.
-One begins the ordinary differential equation
-(with convention which $\alpha$
-is prolonged by zero apart from $(0,L)\times (0,T)$):
-\[
-\dot{X}(\tau )=-\alpha(X(\tau ),\tau ),~~~\tau \in (0,t)\quad X(t)=x
-\]%
-In this equation $\tau$ is the variable and $x,t$ is parameters,
-and we denote the solution by $X_{x,t}(\tau )$.
-Then it is noticed that $(x,t)\rightarrow v(X(\tau ),\tau )$ in
-$\tau=t$ satisfy the equation
-\[
-\partial _{t}v+\alpha\partial _{x}v=\partial _{t}X\dot{v}+a\partial _{x}X\dot{v}%
-=0
-\]%
-and by the definition $\partial _{t}X=\dot{X}=-\alpha$ and
-$\partial_{x}X=\partial _{x}x$ in $\tau=t$, because
-if $\tau =t$ we have $X(\tau )=x$.
-The general solution of (\ref{eqn:conv0}) is thus the value of the boundary condition in $X_{x, t}(0)$,
-it is has to say $u(x,t)=u^{0}(X_{x,t}(0))$ if $X_{x,t}(0)$ is on the
-$x$ axis, $u(x,t)=u^{0}(X_{x,t}(0))$ if $X_{x,t}(0)$ is on the axis of
-$t$.
-
-In higher dimension $\Omega \subset R^{d},~d=2,3$, the equation of the
-convection is written
-\[
-\partial _{t}u+\vec{\alpha}\cdot \nabla u=0\hbox{ in }\Omega \times (0,T)
-\]%
-where  $\vec{a}(x,t)\in R^{d}$.
-\freefempp implements the Characteristic-Galerkin method for convection operators. Recall that the equation (\ref{eqn:conv})
-can be discretized as
-\[
-\frac{Du}{Dt} = f\;\;\textrm{i.e. }\frac{du}{dt}\left( {X(t),t} \right) = f\left(X( t ),t \right)\textrm{  where  }\frac{dX}{dt}( t ) = \vec \alpha( {X(t),t})
-\]
-where $D$  is  the total derivative operator.
-So a good scheme is one step of backward
-convection by the method of Characteristics-Galerkin
-\begin{eqnarray}
-\label{eqn:Charac}
-\frac{1}{{\tau }}\left(u^{m + 1}(x) - u^m(X^m(x))\right) = f^m (x)
-\end{eqnarray}
-where $X^m (x)$ is an approximation of the solution at $t = m\tau $
-of the ordinary differential equation
-\[
-\frac{d\vec{X}}{dt}(t) = \vec{\alpha}^m(\vec{X}(t)),\, \vec{X}((m + 1)\tau ) = x.
-\]
-where $\vec{\alpha}^m(x)=(\alpha_1(x,m\tau ),\alpha_2(x,m\tau ))$.
-Because, by Taylor's expansion, we have
-\begin{eqnarray}
-\label{eqn:conv1}
-u^m(\vec {X}(m\tau ))&=&
-u^m(\vec{X}((m+1)\tau )) -
-\tau \sum_{i=1}^d \frac{\partial u^m}{\partial x_i}(\vec{X}((m+1)\tau ))
-\frac{\partial X_i}{\partial t}((m+1)\tau )
-+o(\tau )\nonumber\\
-&=&u^m(x)-\tau \vec{\alpha}^m(x)\cdot \nabla u^m(x)+o(\tau )
-\end{eqnarray}
-where $X_i(t)$ are the i-th component of $\vec{X}(t)$,
-$u^m(x)=u(x,m\tau )$
-and we used the chain rule and $x=\vec{X}((m+1)\tau )$.
-From (\ref{eqn:conv1}), it follows that
-\begin{eqnarray}
-u^m(X^m(x))=u^m(x)-\tau \vec{\alpha}^m(x)\cdot \nabla u^m(x)+o(\tau ).
-\end{eqnarray}
-Also we apply Taylor's expansion for
-$t\mapsto u^m(x-\vec{\alpha}^m(x)t),\, 0\le t\le \tau $, then
-\[
-u^m(x-\vec{\alpha}\tau )=u^m(x)-\tau \vec{\alpha}^m(x)\cdot \nabla u^m(x)+o(\tau ).
-\]
-Putting
-\[
-\ttCC{@convect}\left( {\vec{\alpha},\tau ,u^m } \right)
-= u^m \left(x - \vec{\alpha}^m\tau  \right),
-\]
-we can get the approximation
-\[
-u^m \left( {X^m( x )} \right) \approx
-{\ttCC{@convect}}\left( {[a_1^m ,a_2^m],\tau ,u^m } \right)\;\;
-\textrm{by }x = X((m + 1)\tau ).
-\]
-
-A classical convection problem is that of the ``rotating bell''
-(quoted from \cite{Lucquin}[p.16]).
-Let $\Omega$ be the unit disk centered at 0,
-with its center rotating with speed
-$\alpha_1 = y,\, \alpha_2 = -x$
-We consider the problem (\ref{eqn:conv}) with $f=0$ and the initial condition
-$u(x,0)=u^0(x)$, that is, from (\ref{eqn:Charac})
-\begin{eqnarray*}
-u^{m + 1}(x) = u^m(X^m(x))\approx \texttt{convect}(\vec{\alpha},\tau ,u^m).
-\end{eqnarray*}
-The exact solution is $u(x, t) = u(\vec{X}(t))$
-where $\vec{X}$ equals $x$
-rotated around the origin by an angle $\theta = -t$ (rotate in clockwise).
-So, if $u^0$ in a 3D perspective
-looks like a bell, then $u$ will have exactly the same shape, but rotated by the
-same amount.
-The program consists in solving the equation until $T = 2\pi$, that is for a full
-revolution and to compare the final solution with the initial one; they should
-be equal.
-\begin{example}[convect.edp]
-\index{tutotial!convect.edp}
-\bFF
- at border C(t=0, 2*pi) { x=cos(t);  y=sin(t); }; // the unit circle
- at mesh Th = @buildmesh(C(70));   // triangulates the disk
- at fespace Vh(Th,P1);
-Vh u0 = @exp(-10*((x-0.3)^2 +(y-0.3)^2));    // give $u^0$
-
- at real dt = 0.17,t=0;       // time step
-Vh a1 = -y, a2 = x;                   // rotation velocity
-Vh u; // $u^{m+1}$
- at for (@int m=0; m<2*pi/dt ; m++) {
-    t += dt;
-    u=@convect([a1,a2],dt,u0);  // $u^{m+1}=u^m(X^m(x))$
-    u0=u;                      // m++
-    @plot(u,cmm="convection: t="+t + ", min=" + u[].min + ", max=" +  u[].max,wait=0);
-};
-\eFF
-\end{example}
-\begin{note}
-The scheme \texttt{convect} is unconditionally stable, then
-the bell become lower and lower (the maximum of $u^{37}$ is $0.406$ as shown in Fig. \ref{BellLast}).
-\twoplot[height=5cm]{BellInit}{BellLast}{$u^0=e^{-10((x-0.3)^2 +(y-0.3)^2)}$}{The bell at $t=6.29$}
-\end{note}
-
-
-\subsubsection{Two-dimensional Black-Scholes equation}
-In mathematical finance, an option on two assets is modeled by a Black-Scholes equations in two space variables, (see for example Wilmott's book : a student introduction to mathematical finance, Cambridge University Press).
-\begin{eqnarray}
-\label{eqn:BS-1-1}
- &&\partial _t u + \frac{{\left( {\sigma _1 x } \right)^2 }}{2}\frac{{\partial ^2 u}}{{\partial x^2 }} + \frac{{\left( {\sigma _2 y } \right)^2 }}{2}\frac{{\partial ^2 u}}{{\partial y^2 }} \\
- &&{\rm{      }} + \rho x y \frac{{\partial ^2 u}}{{\partial x \partial y }} + rS_1 \frac{{\partial u}}{{\partial x }} + rS_2 \frac{{\partial u}}{{\partial y }} - rP = 0 \nonumber
-\end{eqnarray}
-which is to be integrated in $\left( {0,T} \right) \times \R^ +   \times \R^ +$
-subject to, in the case of a put
-\begin{eqnarray}
-\label{eqn:BS-1-2}
-u\left( {x , y ,T} \right) = \left( {K - \max \left( {x ,y } \right)} \right)^ +  .
-\end{eqnarray}
-Boundary conditions for this problem may not be so easy to device.
-As in the one dimensional case the PDE contains boundary conditions on the axis $x_1 = 0$ and on the axis $x_2 = 0$, namely two one dimensional Black-Scholes equations driven respectively by the data $u\left( {0, + \infty ,T} \right)$
-and $u\left( { + \infty ,0,T} \right)$.
-These will be automatically accounted for because they are embedded in the PDE. So if we do nothing in the variational form (i.e. if we take a Neuman boundary condition at these two axis in the strong form) there will be no disturbance to these.
-At infinity in one of the variable, as in 1D, it makes sense to match the final condition:
-\begin{eqnarray}
-\label{eqn:BS-1-3}
-u\left( {x ,y ,t} \right) \approx \left( {K - \max \left( {x ,y } \right)} \right)^ +  e^{r\left( {T - t} \right)} {\rm{    when  }}\left| {\rm{x}} \right| \to \infty
-\end{eqnarray}
-For an American put we will also have the constraint
-\begin{eqnarray}
-\label{eqn:BS-1-4}
-u\left( {x ,y ,t} \right) \ge \left( {K - \max \left( {x ,y } \right)} \right)^ +  e^{r\left( {T - t} \right)} .
-\end{eqnarray}
-We take
-\begin{eqnarray}
-\label{eqn:BS-1-5}
-\sigma _1  = 0.3,\;\;\sigma _2  = 0.3,\;\;\rho  = 0.3,\;\;r = 0.05,\;\;K = 40,\;\;T = 0.5
-\end{eqnarray}
-An implicit Euler scheme with projection is used and a mesh adaptation is done every 10 time steps. The first order terms are treated by the Characteristic Galerkin method, which, roughly, approximates
-\begin{eqnarray}
-\label{eqn:BS-1-6}
-\frac{{\partial u}}{{\partial t}} + a_1 \frac{{\partial u}}{{\partial x}} + a_2 \frac{{\partial u}}{{\partial y}} \approx \frac{1}{{\tau }}\left( {u^{n + 1} \left( x \right) - u^n \left( {x - \vec \alpha\tau } \right)} \right)
-\end{eqnarray}
-\begin{example}~
-[BlackSchol.edp]\index{tutorial!BlackSchol.edp}
-\bFF
-// verbosity=1;
-int s=10; // y-scale
-int m=30;
-int L=80;
-int LL=80;
- at border aa(t=0,L){x=t;y=0;};
- at border bb(t=0,LL){x=L;y=t;};
- at border cc(t=L,0){x=t ;y=LL;};
- at border dd(t=LL,0){x = 0; y = t;};
-
- at mesh th = buildmesh(aa(m)+bb(m)+cc(m)+dd(m));
- at fespace Vh(th,P1);
-
- at real sigmax=0.3;
- at real sigmay=0.3;
- at real rho=0.3;
- at real r=0.05;
- at real K=40;
- at real dt=0.01;
-
- at real eps=0.3;
-
- at func f = max(K-max(x,y),0.);
-
-Vh u=f,v,w;
-
- at func beta = 1;//(w<=f-eps)*eps + (w>=f) + (w<f)*(w>f-eps)*(eps+(w-f+eps)/eps)*(1-eps);
-
- at plot(u,wait=1);
-
- th = adaptmesh(th,u,abserror=1,nbjacoby=2,
-        err=0.004, nbvx=5000, omega=1.8,ratio=1.8, nbsmooth=3,
-            splitpbedge=1, maxsubdiv=5,rescaling=1 );
- u=u;
-
-Vh xveloc = -x*r+x*sigmax^2+x*rho*sigmax*sigmay/2;
-Vh yveloc = -y*r+y*sigmay^2+y*rho*sigmax*sigmay/2;
-
- at int j=0;
- at int n;
- at problem eq1(u,v,init=j, at solver=LU) = @int2d(th)(
-                          u*v*(r+1/dt/beta)
-                        + @dx(u)*@dx(v)*(x*sigmax)^2/2.
-                        + @dy(u)*@dy(v)*(y*sigmay)^2/2.
-      + @dy(u)*@dx(v)*rho*sigmax*sigmay*x*y/2.
-                  + @dx(u)*@dy(v)*rho*sigmax*sigmay*x*y/2.   )
-            + @int2d(th)( -v*convect([xveloc,yveloc],dt,w)/dt/beta)
-                  + @on(bb,cc,u=f)//*exp(-r*t);
-;
-int ww=1;
- at for ( n=0; n*dt <= 1.0; n++)
-{
-  @cout <<" iteration " << n   <<  " j=" << j << @endl;
-  w=u;
-  eq1;
-  v = @max(u-f,0.);
-  plot(v,wait=ww);
-  u = @max(u,f);
-  ww=0;
-
-  @if(j>10)  { cout << " adaptmesh " << endl;
-    th = adaptmesh(th,u,verbosity=1,abserror=1,nbjacoby=2,
-      err=0.001, nbvx=5000, omega=1.8, ratio=1.8, nbsmooth=3,
-            splitpbedge=1, maxsubdiv=5,rescaling=1) ;
-        j=-1;
-     xveloc = -x*r+x*sigmax^2+x*rho*sigmax*sigmay/2;
-     yveloc = -y*r+y*sigmay^2+y*rho*sigmax*sigmay/2;
-     u=u;
-     ww=1;
-    };
-  j=j+1;
-  @cout << " j = " <<  j << endl;
-};
-v = @max(u-f,0.);
- at plot(v,wait=1,value=1);
- at plot(u,wait=1,value=1);
-\eFF
-\end{example}
-
-\subsection{Navier-Stokes Equation}
-
-\subsubsection{Stokes and Navier-Stokes}
-
-The Stokes equations are: for a given $\vec{f}\in L^2(\Omega)^2$,
-\index{stokes}
-\Blue{
-\begin{equation} \label{eqn:Stokes}
-    \left.\begin{array}{cl}
- -\Delta \vec{u}+\nabla p & =\vec{f} \\
- \nabla\cdot \vec{u} &=0
- \end{array}\right\}\quad \hbox{ in }\Omega
-\end{equation}}
-where $\vec{u}=(u_1,u_2)$ is the velocity vector and $p$ the pressure.
-For simplicity, let us choose Dirichlet boundary conditions
-on the velocity,  $\vec{u}=\vec{u}_{\Gamma}$ on $\Gamma$.
-
-In Temam [Theorem 2.2], there ia a weak form of (\ref{eqn:Stokes}):
-Find $\vec{v}=(v_1,v_2)\in \vec{V}(\Omega)$
-\[
-\vec{V}(\Omega)=\{\vec{w}\in H^1_0(\Omega)^2|\; \textrm{div}\vec{w}=0\}
-\]
-which satisfy
-\[
-\sum_{i=1}^2\int_{\Omega}\nabla u_i\cdot \nabla v_i=\int_{\Omega}\vec{f}\cdot \vec{w}
-\quad \textrm{for all }v\in V
-\]
-Here it is used the existence
-$p\in H^1(\Omega)$ such that $\vec{u}=\nabla p$, if
-\[
-\int_{\Omega}\vec{u}\cdot \vec{v}=0\quad \textrm{for all }\vec{v}\in
-V
-\]
-\medskip
-
-Another weak form is derived as follows: We put
-\begin{eqnarray*}
-\vec{V}=H^1_0(\Omega)^2;\quad
-W=\left\{q\in L^2(\Omega)\left|\; \int_{\Omega}q=0\right.\right\}
-\end{eqnarray*}
-By multiplying the first equation in (\ref{eqn:Stokes}) with $v\in V$ and the
-second with $q\in W$, subsequent integration over $\Omega$, and an
-application of Green's formula, we have
-\begin{eqnarray*}
-\int_{\Omega}\nabla\vec{u}\cdot \nabla\vec{v}-\int_{\Omega}\textrm{div}\vec{v}\, p
-&=&\int_{\Omega}\vec{f}\cdot\vec{v}\\
-\int_{\Omega}\textrm{div}\vec{u}\, q&=&0
-\end{eqnarray*}
-This yields the weak form of (\ref{eqn:Stokes}):
-Find $(\vec{u},p)\in \vec{V}\times W$ such that
-\begin{eqnarray}
-\label{eqn:wStokes-1}
-a(\vec{u},\vec{v})+b(\vec{v},p)&=&(\vec{f},\vec{v})\\
-\label{eqn:wStokes-2}
-b(\vec{u},q)&=&0
-\end{eqnarray}
-for all $(\vec{v},q)\in V\times W$, where
-\begin{eqnarray}
-\label{eqn:Stokes-a}
-a(\vec{u},\vec{v})&=&\int_{\Omega}\nabla \vec{u}\cdot \nabla\vec{v}
-=\sum_{i=1}^2\int_{\Omega}\nabla u_i\cdot \nabla v_i\\
-\label{eqn:Stokes-b}
-b(\vec{u},q)&=&-\int_{\Omega}\textrm{div}\vec{u}\, q
-\end{eqnarray}
-
-Now, we consider finite element spaces $\vec{V}_h\subset \vec{V}$ and $W_h\subset W$,
-and we assume the following basis functions
-\begin{eqnarray*}
-&&\vec{V}_h=V_h\times V_h,\quad
-V_h=\{v_h|\; v_h=v_1\phi_1+\cdots +v_{M_V}\phi_{M_V}\},\\
-&&W_h=\{q_h|\; q_h=q_1\varphi_1+\cdots +q_{M_W}\varphi_{M_W}\}
-\end{eqnarray*}
-The discrete weak form is:
-Find $(\vec{u}_{h},p_{h}) \in \vec{V}_{h} \times W_{h}$ such that
-\Blue{
-\begin{equation} \label{eqn:vfStokes}
-    \begin{array}{cll}
-   a(\vec{u}_h,\vec{v}_h)+b(\vec{v}_h,p)  &= (\vec{f},\vec{v}_h) ,
-      &\forall \vec{v}_{h} \in \vec{V}_{h} \\
-    b(\vec{u}_h,q_h)&= 0,
-     &\forall q_{h} \in W_{h}
-    \end{array}
-\end{equation}}
-\begin{note}
-Assume that:
-\begin{enumerate}
-  \item There is a constant $\alpha_h>0$ such that
-  \[
-  a(\vec{v}_h,\vec{v}_h)\ge \alpha\| \vec{v}_h\|_{1,\Omega}^2\quad \textrm{for all }\vec{v}_h\in Z_h
-  \]
-  where
-  \[
-  Z_h=\{\vec{v}_h\in \vec{V}_h|\; b(\vec{w}_h,q_h)=0\quad \textrm{for all }q_h\in W_h\}
-  \]
-  \item There is a constant $\beta_h>0$ such that
-  \[
-  \sup_{\vec{v}_h\in \vec{V}_h}\frac{b(\vec{v}_h,q_h)}{\| \vec{v}_h\|_{1,\Omega}}
-  \ge \beta_h\| q_h\|_{0,\Omega}\quad \textrm{for all }q_h\in W_h
-  \]
-\end{enumerate}
-  Then we have an unique solution $(\vec{u}_h,p_h)$ of (\ref{eqn:vfStokes})
-  satisfying
-  \[
-  \| \vec{u}-\vec{u}_h\|_{1,\Omega}+\| p-p_h\|_{0,\Omega}
-  \le C\left(
-  \inf_{\vec{v}_h\in \vec{V}_h}\| u-v_h\|_{1,\Omega}
-  +\inf_{q_h\in W_h}\| p-q_h\|_{0,\Omega}\right)
-  \]
-  with a constant $C>0$ (see e.g. \cite[Theorem 10.4]{RT93}).
-\end{note}
-Let us denote that
-\begin{eqnarray}
-A&=&(A_{ij}),\, A_{ij}=\int_{\Omega}\nabla \phi_j\cdot \nabla \phi_i\qquad
-i,j=1,\cdots,M_{\vec{V}}\\
-\vec{B}&=&(Bx_{ij},By_{ij}),\,
-Bx_{ij}=-\int_{\Omega}\partial \phi_j/\partial x\, \varphi_i\qquad
-By_{ij}=-\int_{\Omega}\partial \phi_j/\partial y\, \varphi_i\nonumber\\
-&&\qquad i=1,\cdots,M_W;j=1,\cdots,M_V\nonumber
-\end{eqnarray}
-then (\ref{eqn:vfStokes}) is written by
-\begin{eqnarray}
-\left(
-\begin{array}{cc}
-\vec{A}&\vec{\vec{B}}^*\\
-\vec{B}&0
-\end{array}
-\right)
-\left(
-\begin{array}{cc}
-\vec{U}_h\\
-\{p_h\}
-\end{array}
-\right)
-=
-\left(
-\begin{array}{cc}
-\vec{F}_h\\
-0
-\end{array}
-\right)
-\end{eqnarray}
-where
-\begin{eqnarray*}
-&&\vec{A}=\left(
-\begin{array}{cc}
-A&0\\
-0&A
-\end{array}
-\right)
-\qquad
-\vec{B}^*=\left\{
-\begin{array}{c}
-Bx^T\\
-By^T
-\end{array}
-\right\}
-\qquad
-\vec{U}_h=\left\{
-\begin{array}{c}
-\{u_{1,h}\}\\
-\{u_{2,h}\}
-\end{array}
-\right\}
-\qquad
-\vec{F}_h=\left\{
-\begin{array}{c}
-\{\textstyle{\int_{\Omega}f_1\phi_i}\}\\
-\{\textstyle{\int_{\Omega}f_2\phi_i}\}
-\end{array}
-\right\}
-\end{eqnarray*}
-
-\textbf{Penalty method:} This method consists of replacing (\ref{eqn:vfStokes}) by a more regular problem: Find
-$(\vec{v}_h^{\epsilon},p_h^{\epsilon})\in \vec{V}_h\times \tilde{W}_{h}$ satisfying
-\Blue{
-\begin{equation} \label{eqn:PvfStokes}
-    \begin{array}{cll}
-   a(\vec{u}_h^\epsilon,\vec{v}_h)+b(\vec{v}_h,p_h^{\epsilon})  &= (\vec{f},\vec{v}_h) ,
-      &\forall \vec{v}_{h} \in \vec{V}_{h} \\
-    b(\vec{u}_h^{\epsilon},q_h)-\epsilon(p_h^{\epsilon},q_h)&= 0,
-     &\forall q_{h} \in \tilde{W}_{h}
-    \end{array}
-\end{equation}}
-where $\tilde{W}_h\subset L^2(\Omega)$. Formally, we have
-\[
-\textrm{div}\vec{u}_h^{\epsilon}=\epsilon p_h^{\epsilon}
-\]
-and the corresponding algebraic problem
-\begin{eqnarray*}
-\left(
-\begin{array}{cc}
-\vec{A}&B^*\\
-B&-\epsilon I
-\end{array}
-\right)
-\left(
-\begin{array}{cc}
-\vec{U}_h^{\epsilon}\\
-\{p_h^{\epsilon}\}
-\end{array}
-\right)
-=
-\left(
-\begin{array}{cc}
-\vec{F}_h\\
-0
-\end{array}
-\right)
-\end{eqnarray*}
-\begin{note}
-We can eliminate $p_h^\epsilon=(1/\epsilon)BU_h^{\epsilon}$ to obtain
-\begin{eqnarray}
-\label{eqn:StiffPvfStokes}
-(A+(1/\epsilon)B^*B)\vec{U}_h^{\epsilon}=\vec{F}_h^{\epsilon}
-\end{eqnarray}
-Since the matrix $A+(1/\epsilon)B^*B$ is symmetric, positive-definite, and sparse, (\ref{eqn:StiffPvfStokes}) can be solved by known technique.
-There is a constant $C>0$ independent of $\epsilon$ such that
-\[
-\|\vec{u}_h-\vec{u}_h^\epsilon\|_{1,\Omega}+
-\|p_h-p_h^{\epsilon}\|_{0,\Omega}\le C\epsilon
-\]
-(see e.g. \cite[17.2]{RT93})
-\end{note}
-
-\begin{example}[Cavity.edp]
-
-The driven cavity flow problem is solved first at zero Reynolds number
-(Stokes flow) and then at Reynolds 100.  \index{fluid}The
-velocity pressure formulation is used first and then the calculation
-is repeated with the stream function vorticity formulation.
-
-We solve the driven cavity problem by the penalty method (\ref{eqn:PvfStokes}) \index{Stokes} where
- $\vec{u}_{\Gamma}\cdot \vec{n}=0$ and $\vec{u}_{\Gamma}\cdot \vec{s}
-=1$ on the top boundary and zero elsewhere ( $\vec{n}$ is the unit normal to $\Gamma$, and $\vec{s}$ the unit tangent to $\Gamma$).
-\\
-The mesh is constructed by
-\bFF
- at mesh Th=@square(8,8);
-\eFF
-
-We use a classical Taylor-Hood element technic to solve the problem:
-\\\\
-The velocity is approximated with the $P_{2}$ FE ( $X_{h}$ space), and the
-the pressure is approximated with the $P_{1}$ FE ( $M_{h}$ space),
-\\\\
-where
-\Blue{
-$$  X_{h} = \left\{ \vec{v} \in H^{1}(]0,1[^2) \left|\; \forall K \in \mathcal{T}_{h}
-\quad v_{|K} \in
-P_{2} \right.\right\}$$} and
-\Blue{$$  M_{h} = \left\{ v \in H^{1}(]0,1[^2) \left|\; \forall K \in \mathcal{T}_{h}
-\quad v_{|K} \in
-P_{1} \right.\right\}$$}
-
-The FE spaces and functions  are constructed by
-
-\bFF
- at fespace Xh(Th, at P2); //  definition of the velocity component space
- at fespace Mh(Th, at P1);  //  definition of the pressure space
-Xh u2,v2;
-Xh u1,v1;
-Xh p,q;
-\eFF
-
-The Stokes operator is implemented as a system-solve for the velocity
-$(u1,u2)$ and the pressure $p$.  The test function  for the velocity is $(v1,v2)$
-and $q$ for the pressure, so the variational form (\ref{eqn:vfStokes}) in freefem
-language is:
-\bFF
- at solve Stokes (u1,u2,p,v1,v2,q,solver=Crout) =
-    @int2d(Th)( ( dx(u1)*dx(v1) + dy(u1)*dy(v1)
-            +  dx(u2)*dx(v2) + dy(u2)*dy(v2) )
-            - p*q*(0.000001)
-            - p*dx(v1) - p*dy(v2)
-            - dx(u1)*q - dy(u2)*q
-           )
-  + @on(3,u1=1,u2=0)
-  + @on(1,2,4,u1=0,u2=0); // see \refSec{Square} for labels 1,2,3,4
-\eFF
-Each unknown has its own boundary conditions.
-\\\\
-
-If the \index{streamlines}streamlines are required, they can be
-computed by finding $\psi$ such that rot$\psi=u$ or better,
-\Blue{$$-\Delta\psi=\nabla\times u$$}
-\bFF
-Xh psi,phi;
-
- at solve streamlines(psi,phi) =
-      @int2d(Th)( dx(psi)*dx(phi) + dy(psi)*dy(phi))
-   +  @int2d(Th)( -phi*(dy(u1)-dx(u2)))
-   +  @on(1,2,3,4,psi=0);
-\eFF
-
-\bigskip
-
-Now the Navier-Stokes equations are solved
-\eq{
-    {\partial {u}\over\partial t} +u\cdot\nabla u-\nu \Delta u+\nabla p=0,~~~ \nabla\cdot u=0
-}
-with the same boundary conditions and with initial conditions $u=0$.
-
-This is implemented by using the convection operator \texttt{convect} for the term
-${\partial u\over\partial t} +u\cdot\nabla u$, giving a discretization in time
-\Blue{\index{Navier-Stokes}
-\begin{equation}
-    \label{eq Navier Stokes carac}
-\begin{array}{cl}
-\frac{1}{\tau } (u^{n+1}-u^n\circ X^n) -\nu\Delta u^{n+1} + \nabla p^{n+1} &=0,\\
- \nabla\cdot u^{n+1} &= 0
- \end{array}
-\end{equation}
-}
-The term $u^n\circ X^n(x)\approx u^n(x-u^n(x)\tau )$ will be
-computed by the operator ``convect" \index{convect} , so we obtain
-\bFF
-int i=0;
- at real  nu=1./100.;
- at real dt=0.1;
- at real alpha=1/dt;
-
-Xh up1,up2;
-
- at problem  NS (u1,u2,p,v1,v2,q,solver=Crout,init=i) =
-    @int2d(Th)(
-             alpha*( u1*v1 + u2*v2)
-            + nu * ( dx(u1)*dx(v1) + dy(u1)*dy(v1)
-            +  dx(u2)*dx(v2) + dy(u2)*dy(v2) )
-            - p*q*(0.000001)
-            - p*dx(v1) - p*dy(v2)
-            - dx(u1)*q - dy(u2)*q
-           )
-  + @int2d(Th) ( -alpha*
-       convect([up1,up2],-dt,up1)*v1 -alpha*convect([up1,up2],-dt,up2)*v2 )
-  + @on(3,u1=1,u2=0)
-  + @on(1,2,4,u1=0,u2=0)
-;
-
- at for (i=0;i<=10;i++)
- {
-   up1=u1;
-   up2=u2;
-   NS;
-   @if ( !(i % 10))  // plot every 10 iteration
-    @plot(coef=0.2,cmm=" [u1,u2] and p  ",p,[u1,u2]);
- } ;
-\eFF
-Notice that the stiffness matrices are \index{Reusable matrices}
-reused (keyword
-\texttt{init=i})
-\end{example}
-
-\subsubsection{\setS{Uzawa} Conjugate Gradient}
-We solve Stokes problem without penalty.
-The classical iterative method of Uzawa is described by the algorithm
-(see e.g.\cite[17.3]{RT93}):
-\begin{description}
-  \item[Initialize:] Let $p_h^0$ be an arbitrary chosen element of
-  $L^2(\Omega)$.
-  \item[Calculate $\vec{u}_h$:] Once $p_h^n$ is known, $\vec{v}_h^n$ is the solution of
-  \[
-  \vec{u}_h^n = A^{-1}(\vec{f}_h-\vec{B}^*p_h^n)
-  \]
-  \item[Advance $p_h$:] Let $p_h^{n+1}$ be defined by
-  \[
-  p_h^{n+1}=p_h^n+\rho_n\vec{B}\vec{u}_h^n
-  \]
-\end{description}
-There is a constant $\alpha>0$ such that $\alpha\le \rho_n\le 2$ for each $n$,
-then $\vec{u}_h^n$ converges to the solution $\vec{u}_h$, and then
-$B\vec{v}_h^n\to 0$ as $n\to \infty$ from the \emph{Advance $p_h$}.
-This method in general converges quite slowly.
-
-First we define mesh, and the Taylor-Hood \index{Taylor-Hood}  approximation.
-So $X_{h}$  is the velocity space, and $M_{h}$ is the pressure space.
-\begin{example}[StokesUzawa.edp]~
-\index{tutorial!StokesUzawa.edp}
-\bFF
- at mesh Th=@square(10,10);
- at fespace Xh(Th, at P2),Mh(Th, at P1);
-Xh u1,u2,v1,v2;
-Mh p,q,ppp;  //  ppp is a working pressure
-\eFF
-
-\bFF
- at varf bx(u1,q) = @int2d(Th)( -(dx(u1)*q));
- at varf by(u1,q) = @int2d(Th)( -(dy(u1)*q));
- at varf a(u1,u2)= @int2d(Th)(  dx(u1)*dx(u2) + dy(u1)*dy(u2) )
-                    +  on(3,u1=1)  +  @on(1,2,4,u1=0) ;
-//  remark:  put the \ttCC{@on(3,u1=1)} before  \ttCC{@on(1,2,4,u1=0)}
-//  because we want zero on intersection %\index{on!intersection}
-
- at matrix A= a(Xh,Xh,solver=CG);
- at matrix Bx= bx(Xh,Mh);  // $\vec{B}=(Bx\quad By)$
- at matrix By= by(Xh,Mh);
-
-Xh bc1; bc1[] = a(0,Xh);  //  boundary condition contribution  on u1
-Xh bc2; bc2   = O ;       //  no boundary condition contribution on u2
-Xh b;
-\eFF
-
-$p_h^n\to \vec{B}A^{-1}(-\vec{B}^*p_h^n)=-\textrm{div}\vec{u}_h$
-is realized as
-the function \emph{\texttt{divup}}.
-\bFF
- at func @real[@int] divup(@real[@int] @& pp)
-{
-   //  compute u1(pp)
-   b[]  = Bx'*pp; b[] *=-1; b[] += bc1[] ;    u1[] = A^-1*b[];
-   //  compute u2(pp)
-   b[]  = By'*pp; b[] *=-1; b[] += bc2[] ;    u2[] = A^-1*b[];
-   //  $\vec{u}^n=A^{-1}(Bx^Tp^n\quad By^Tp^n)^T$ \hfilll
-   ppp[] =   Bx*u1[];   // $  ppp= Bx u_{1} $
-   ppp[] +=  By*u2[];   // $   \quad   +  By u_{2} $
-   @return ppp[] ;
-};
-\eFF
-
- Call now the conjugate gradient algorithm:
-
-\bFF
-p=0;q=0; // $p_h^0 = 0$
- at LinearCG(divup,p[],eps=1.e-6,nbiter=50); // $p_h^{n+1}=p_h^n+\vec{B}\vec{u}_h^n$
-// if $n> 50$ or $|p_h^{n+1}-p_h^n|\le 10^{-6}$, then the loop end. \hfilll
-divup(p[]); // compute the final solution
-
- at plot([u1,u2],p,wait=1,value=true,coef=0.1);
-\eFF
-\end{example}
-
-\subsubsection{NSUzawaCahouetChabart.edp}
-
- In this example we solve the Navier-Stokes \index{Navier-Stokes} equation,
- in the driven-cavity,
- with the Uzawa  algorithm preconditioned by the Cahouet-Chabart method.
-
- The idea of the preconditioner is that in a periodic domain, all
- differential operators commute and  the  Uzawa algorithm comes to solving the
- linear operator  $ \nabla. ( (\alpha Id + \nu \Delta)^{-1} \nabla$,
- where $ Id $ is the identity operator.
- So  the preconditioer suggested is $ \alpha \Delta^{-1} + \nu Id$.
-\\\\
-To implement this, we reuse the previous example, by including \index{include} a file.
-Then we define the time step $ \Delta t$, viscosity, and new variational form and matrix.
-
-\begin{example}[NSUzawaCahouetChabart.edp]~
-\index{tutorial!NSUzawaCahouetChabart.edp}
-\bFF
- at include "StokesUzawa.edp" // include the Stokes part
- at real dt=0.05, alpha=1/dt;  // $ \Delta t$
-
- at cout << " alpha = " << alpha;
- at real xnu=1./400; // viscosity $ \nu = {\hbox{Reynolds number}}^{-1} $
-
-//  the new variational form with mass term \index{varf}
- at varf at(u1,u2)= @int2d(Th)( xnu*dx(u1)*dx(u2)
-                        + xnu*dy(u1)*dy(u2) + u1*u2*alpha  )
-                        +  @on(1,2,4,u1=0)  + @on(3,u1=1) ;
-
-A = at(Xh,Xh,solver=CG);  //  change the matrix \index{matrix!=}\index{matrix!solver=}
-
-//  set the 2 convect variational form \index{qforder=} \index{convect}
- at varf  vfconv1(uu,vv)  = @int2d(Th,qforder=5) (@convect([u1,u2],-dt,u1)*vv*alpha);
- at varf  vfconv2(v2,v1)  = @int2d(Th,qforder=5) (@convect([u1,u2],-dt,u2)*v1*alpha);
-
- at int idt;       // index of of time set
- at real temps=0;  // current time
-
-Mh pprec,prhs;
- at varf vfMass(p,q) = int2d(Th)(p*q);
- at matrix MassMh=vfMass(Mh,Mh,solver=CG);
-
- at varf vfLap(p,q)  = int2d(Th)(dx(pprec)*dx(q)+dy(pprec)*dy(q) + pprec*q*1e-10);
- at matrix LapMh= vfLap(Mh,Mh,solver=Cholesky);
-\eFF
-
- The function to define the preconditioner
-
-\bFF
- at func real[int]  CahouetChabart(real[int] & xx)
-{  //  xx = $ \int (div u) w_i$
-   //   $ \alpha LapMh ^{-1}  + \nu MassMh^{-1} $
-   pprec[]= LapMh^-1* xx;
-   prhs[] =  MassMh^-1*xx;
-   pprec[] = alpha*pprec[]+xnu* prhs[];
-   @return pprec[];
-};
-\eFF
-
-The loop in time.
-Warning with the stop test of the conjugate gradient, because
-we start from the previous solution and the end the previous solution
-is close to the final solution, don't take a relative  stop test to
-the first residual, take an absolute stop test ( negative here)
-\index{stop test!absolue}
-\bFF
-for (idt = 1; idt < 50; idt++)
- {
-   temps += dt;
-   cout << " --------- temps " << temps << " \n ";
-   b1[] =  vfconv1(0,Xh);
-   b2[] =  vfconv2(0,Xh);
-   cout << "  min b1 b2  " << b1[].min << " " << b2[].min << endl;
-   cout << "  max b1 b2  " << b1[].max << " " << b2[].max << endl;
-   // call Conjugate Gradient with preconditioner '
-   //  warning eps < 0 => absolue stop test \index{precon=}
-   LinearCG(divup,p[],eps=-1.e-6,nbiter=50,precon=CahouetChabart);
-   divup(p[]);   //  computed the velocity
-
-   plot([u1,u2],p,wait=!(idt%10),value= 1,coef=0.1);
- }
-\eFF
-\end{example}
-\subsection{Variational  inequality}
-We present, a classical examples of variational inequality.
-
-Let us denote  $\mathcal{C} = \{ u\in H^1_0(\Omega), u \le g \}$
-
-The problem is :
-
-$$
- u = arg \min_{u\in \mathcal{C}}  J(u) = \frac{1}{2} \int_\Omega \nabla u . \nabla u - \int_\Omega f u
-$$
-where $f$ and $g$ are given function.
-
-The solution is a projection on the convex $\mathcal{C}$ of $f^\star$
-for the scalar product $((v,w)) = \int_\Omega \nabla v . \nabla w$ of
-$  H^1_0(\Omega)$
-where $ {f^\star} $ is solution of $ ((f^\star, v )) = \int_\Omega f v, \forall v \in  H^1_0(\Omega)$.
-The projection on a convex satisfy clearly
-$\forall v \in \mathcal{C}, \quad   (( u -v ,  u - \tilde{f}  )) \leq 0   $,
-and after expanding, we get the classical inequality
-$$\forall v \in \mathcal{C}, \quad   \int_\Omega \nabla(u -v) \nabla  u  \leq  \int_\Omega   (u-v) f .   $$
-
-We can also rewrite the problem as a saddle point problem
-
-Find $\lambda, u$ such that:
-$$
-  \max_{\lambda\in L^2(\Omega), \lambda\geq 0}  \min_{u\in H^1_0(\Omega)}  \mathcal{L}(u,\lambda) = \frac{1}{2} \int_\Omega \nabla u . \nabla u - \int_\Omega f u  + \int_{\Omega} \lambda (u-g)^+
-$$
-where $((u-g)^+ = max(0,u-g) $
-
-This saddle point problem is equivalent to find $ u, \lambda $ such that:
-\begin{equation}
- \left\{
-\begin{array}{cc}
-\displaystyle \int_\Omega \nabla u . \nabla v + \lambda v^+ \,d\omega= \int_\Omega f u  , &\forall v \in H^1_0(\Omega) \cr
-\displaystyle \int_\Omega   \mu (u-g)^+ = 0  , & \forall \mu \in L^2(\Omega) , \mu \geq 0, \lambda \geq 0,
- \end{array}\right.\label{eq:iq1}
-\end{equation}
-
-
-A algorithm to solve the previous problem is:
-
-\begin{enumerate}
-\item k=0, and choose, $\lambda_0$ belong $ H^{-1}(\Omega)$
-\item loop on $ k = 0, .....$
- \begin{enumerate}
-\item  set $ \mathcal{I}_{k} = \{ x \in \Omega / \lambda_{k} + c * ( u_{k+1} - g)  \leq 0 \} $
-\item  $ V_{g,k+1} = \{ v\in H^1_0(\Omega) / v = g $   on ${I}_{k} \}$,
-\item  $ V_{0,k+1} = \{ v\in  H^1_0(\Omega) / v = 0$ on ${I}_{k} \}$,
- \item Find  $ u_{k+1} \in V_{g,k+1} $ and  $\lambda_{k+1} \in H^{-1}(\Omega)$ such that
- $$
- \left\{\begin{array}{cc}
- \displaystyle  \int_\Omega \nabla u_{k+1}. \nabla v_{k+1}   \,d\omega = \int_\Omega f v_{k+1}  , &\forall v_{k+1} \in  V_{0,k+1} \cr
- \displaystyle  <\lambda_{k+1},v>  =  \int_\Omega \nabla u_{k+1}. \nabla v  -  f v \,d\omega &
-  \end{array}\right.
- $$
- where $<,>$ is the duality bracket between $ H^{1}_0(\Omega)$ and  $ H^{-1}(\Omega)$, and $c$
-is  a penalty constant (large enough).
-\end{enumerate}
-
-\end{enumerate}
-You can find all the mathematic  about this algorithm in \cite{ItoKunisch}.
-
-Now how to do that in \texttt{FreeFem++}
-
-The full example is:
-\begin{example}[VI.edp]
-\index{tutotial!VI.edp}
-\bFF
-
- at mesh Th=square(20,20);
- at real eps=1e-5;
- at fespace Vh(Th,P1);     // P1 FE space
- at int n = Vh.ndof; // number of Degree of freedom
- at Vh uh,uhp;              // solution and previous one
- at Vh Ik; //  to def the set where the containt is reached.
- at real[int] rhs(n); // to store the right and side of the equation
- at real c=1000;  // the penalty  parameter of the algoritm
- at func f=1;         //  right hand side function
- at func fd=0;         // Dirichlet   boundary condition function
-Vh g=0.05;  // the discret function g
-
- at real[int] Aii(n),Aiin(n); // to store the diagonal of the matrix 2 version
-
- at real tgv = 1e30; // a huge value for exact penalization
-// of boundary condition
-//  the variatonal form of the problem: \hfilll
- at varf a(uh,vh) =                    //  definition of  the problem
-    int2d(Th)( dx(uh)*dx(vh) + dy(uh)*dy(vh) ) //  bilinear form
-  - int2d(Th)( f*vh )                          //  linear form
-  + on(1,2,3,4,uh=fd) ;                      //  boundary condition form
-
-
-// two version of the matrix of the problem  \hfilll
- at matrix A=a(Vh,Vh,tgv=tgv,solver=CG); // one changing
- at matrix AA=a(Vh,Vh,solver:GC); // one for computing residual
-
- //  the mass Matrix construction: \hfilll
- at varf vM(uh,vh) = int2d(Th)(uh*vh);
- at matrix M=vM(Vh,Vh); // to do a fast computing of $L^2$ norm : sqrt( u'*(w=M*u))
-
-Aii=A.diag; // get the diagonal of the matrix (appear in version 1.46-1)
-
-rhs = a(0,Vh,tgv=tgv);
-Ik =0;
-uhp=-tgv; // previous value is
-Vh lambda=0;
- at for(int iter=0;iter<100;++iter)
-{
-  @real[int] b(n) ; b=rhs;  //  get a copy of the Right hand side
-  @real[int] Ak(n); //  the complementary of Ik ( !Ik = (Ik-1))
-  // Today  the operator Ik- 1. is not implement so we do:
-  Ak= 1.; Ak  -= Ik[];  // build Ak  = ! Ik
-  //  adding new locking  condition on b and on the diagonal if (Ik ==1 )
-  b = Ik[] .* g[];      b *= tgv;     b  -=  Ak .* rhs;
-  Aiin = Ik[] *  tgv;      Aiin  +=  Ak  .* Aii;  //set  Aii= tgv  $ i \in Ik $
-  A.diag = Aiin; //  set the matrix diagonal  (appear in version 1.46-1)
-  @set(A,solver=CG); // important to change preconditioning  for solving
-  uh[] = A^-1* b;   //  solve the problem with more locking condition
-  lambda[] = AA * uh[]; //  compute the residual ( fast with matrix)
-  lambda[] += rhs; // remark rhs = $-\int f v $
-
-  Ik = ( lambda + c*( g- uh)) < 0.;  // the new of locking value
-
-   @plot(Ik, wait=1,cmm=" lock set ",value=1,ps="VI-lock.eps",fill=1 );
-   @plot(uh,wait=1,cmm="uh",ps="VI-uh.eps");
-   // trick to compute  $L^2$ norm of the variation (fast method)
-      real[int] diff(n),Mdiff(n);
-      diff= uh[]-uhp[];
-      Mdiff = M*diff;
-      real err = sqrt(Mdiff'*diff);
-  @cout << "  || u_{k=1} - u_{k} ||_2 " << err << endl;
-  @if(err< eps) @break; // stop test
-  uhp[]=uh[] ; // set the previous solution
-}
-savemesh(Th,"mm",[x,y,uh*10]); // for medit plotting
-\eFF
-\end{example}
-
-Remark, as you can see on this example, some vector , or matrix operator are not implemented
-so a way is to skip the expression and we  use operator \texttt{+=},  \texttt{-=} to merge
-the result.
-
-
-\subsection{Domain decomposition}
-We present, three classic examples, of domain decomposition
-technique:
-first, Schwarz algorithm with overlapping, second
-Schwarz algorithm without  overlapping (also call Shur complement), and
-last we show to use the conjugate gradient
-to solve the boundary problem of the Shur complement.
-
-\subsubsection{Schwarz Overlap Scheme}
-\label{schwarz-overlap}
-To solve
-\eq{ -\Delta u =f,\; \hin\Omega=\Omega_1\cup\Omega_2\quad u|_\Gamma=0}
-the Schwarz algorithm  runs like this
-\Blue{
-\begin{eqnarray*}
-   -\Delta u^{n+1}_1&=&f\hin\Omega_1\quad
-    u^{n+1}_1|_{\Gamma_1}=u^n_2\\
-    -\Delta u^{n+1}_2&=&f\hin\Omega_2\quad
-    u^{n+1}_2|_{\Gamma_2}=u^n_1
-\end{eqnarray*}}
-where $\Gamma_i$ is the boundary of $\Omega_i$ and on the
-condition that $\Omega_1\cap\Omega_2\neq\emptyset$ and that $u_i$
-are zero at iteration 1.
-\\\\
-Here we take $\Omega_1$ to be a quadrangle, $\Omega_2$ a disk and
-we apply the algorithm starting from zero.
-\begin{figure}[hbt]
-\HLINE{\hss
-\includegraphics[width=6cm]{schwarz-th} \hss}
-\caption{ The 2 overlapping mesh \texttt{TH} and \texttt{th}  }
-\end{figure}
-
-\begin{example}[Schwarz-overlap.edp]~
-\index{tutorial!Schwarz-overlap.edp}
- \bFF
- at int inside = 2;  //  inside boundary
- at int outside = 1; //  outside boundary
- at border a(t=1,2){x=t;y=0;label=outside;};
- at border b(t=0,1){x=2;y=t;label=outside;};
- at border c(t=2,0){x=t ;y=1;label=outside;};
- at border d(t=1,0){x = 1-t; y = t;label=inside;};
- at border e(t=0, pi/2){ x= cos(t); y = sin(t);label=inside;};
- at border e1(t=pi/2, 2*pi){ x= cos(t); y = sin(t);label=outside;};
- at int n=4;
- at mesh th = @buildmesh( a(5*n) + b(5*n) + c(10*n) + d(5*n));
- at mesh TH = @buildmesh( e(5*n) + e1(25*n) );
- at plot(th,TH,wait=1);  //  to see the 2 meshes
-\eFF
-
-The space  and problem definition is :
-\bFF
- at fespace vh(th, at P1);
- at fespace VH(TH, at P1);
-vh u=0,v; VH U,V;
- at int i=0;
-
- at problem PB(U,V,init=i,solver=Cholesky) =
-    @int2d(TH)( dx(U)*dx(V)+dy(U)*dy(V) )
-  + @int2d(TH)( -V) + on(inside,U = u)  + @on(outside,U= 0 ) ;
- at problem pb(u,v,init=i,solver=Cholesky) =
-    @int2d(th)( dx(u)*dx(v)+dy(u)*dy(v) )
-  + @int2d(th)( -v) + on(inside ,u = U) + @on(outside,u = 0 ) ;
-\eFF
- The  calculation loop:
-\bFF
- at for ( i=0 ;i< 10; i++)
-{
-   PB;
-   pb;
-   @plot(U,u,wait=true);
-};
-\eFF
-\end{example}
-
-\begin{figure}[hbt]
-\HLINE{\hss
-\includegraphics[width=6cm]{schwarz-u0}
-\hss
-\includegraphics[width=6cm]{schwarz-u} }
-\caption{  Isovalues of the solution at  iteration 0  and iteration 9}
-\end{figure}
-
-
-
-\subsubsection{Schwarz non Overlap Scheme}
-
-To solve\index{domain decomposition}\index{shurr}
-\eq{ -\Delta u =f \hin\Omega=\Omega_1\cup\Omega_2\quad u|_\Gamma=0,}
-the Schwarz algorithm for domain decomposition without overlapping  runs like this
-
-\begin{figure}[hbt]
-\HLINE{\hss
-\includegraphics[width=6cm]{schwarz-no-th} \hss}
-\caption{ The two none overlapping mesh \texttt{TH} and \texttt{th}  }
-\end{figure}
-
-Let introduce  $\Gamma_i$ is  common the boundary of $\Omega_1$ and
-$\Omega_2$ and    $\Gamma_e^i= \partial \Omega_i \setminus \Gamma_i$.
-
-The problem  find  $\lambda$ such that $ (u_1|_{\Gamma_i}=u_2|_{\Gamma_i}) $
-where  $u_i$ is solution of the following Laplace problem:
-\eq{
-    -\Delta u_i=f\hin\Omega_i\quad
-    u_i|_{\Gamma_i}=\lambda \quad
-    u_i|_{\Gamma_e^i} = 0
- }
-
-To solve this problem we just make a loop
-with upgrading$\lambda$ with
-$$\lambda = \lambda {\pm} \frac{(u_1-u_2)}{2}$$
-where the sign $+$ or $-$ of ${\pm}$ is choose to have convergence.
-
-\begin{example}[Schwarz-no-overlap.edp]~
-\index{tutorial!Schwarz-no-overlap.edp}
-\bFF
-// schwarz1 without overlapping
- at int inside = 2;
- at int outside = 1;
- at border a(t=1,2){x=t;y=0;label=outside;};
- at border b(t=0,1){x=2;y=t;label=outside;};
- at border c(t=2,0){x=t ;y=1;label=outside;};
- at border d(t=1,0){x = 1-t; y = t;label=inside;};
- at border e(t=0, 1){ x= 1-t; y = t;label=inside;};
- at border e1(t=pi/2, 2*pi){ x= cos(t); y = sin(t);label=outside;};
- at int n=4;
- at mesh th = buildmesh( a(5*n) + b(5*n) + c(10*n) + d(5*n));
- at mesh TH = buildmesh ( e(5*n) + e1(25*n) );
- at plot(th,TH,wait=1,ps="schwarz-no-u.eps");
- at fespace vh(th,P1);
- at fespace VH(TH,P1);
-vh u=0,v; VH U,V;
-vh lambda=0;
- at int i=0;
-
- at problem PB(U,V,init=i,solver=Cholesky) =
-    @int2d(TH)( dx(U)*dx(V)+dy(U)*dy(V) )
-  + @int2d(TH)( -V)
-  + @int1d(TH,inside)(-lambda*V) +    on(outside,U= 0 ) ;
- at problem pb(u,v,init=i,solver=Cholesky) =
-    @int2d(th)( dx(u)*dx(v)+dy(u)*dy(v) )
-  + @int2d(th)( -v)
-  + @int1d(th,inside)(+lambda*v) +    on(outside,u = 0 ) ;
-
-
- at for ( i=0 ;i< 10; i++)
-{
-   PB;
-   pb;
-   lambda = lambda - (u-U)/2;
-   @plot(U,u,wait=true);
-};
-
- at plot(U,u,ps="schwarz-no-u.eps");
-
-\eFF
-\end{example}
-
-\begin{figure}[hbt]
-\HLINE{\hss
-\includegraphics[width=6cm]{schwarz-no-u0}
-\hss
-\includegraphics[width=6cm]{schwarz-no-u} }
-\caption{  Isovalues of the solution at  iteration 0  and iteration 9 without overlapping }
-\end{figure}
-
-\subsubsection{Schwarz-gc.edp}
-To solve\index{domain decomposition}\index{shurr}
-\eq{ -\Delta u =f \hin\Omega=\Omega_1\cup\Omega_2\quad u|_\Gamma=0,}
-the Schwarz algorithm for domain decomposition without overlapping  runs like this
-
-Let introduce  $\Gamma_i$ is  common the boundary of $\Omega_1$ and
-$\Omega_2$ and    $\Gamma_e^i= \partial \Omega_i \setminus  \Gamma_i$.
-
-The problem  find  $\lambda$ such that $ (u_1|_{\Gamma_i}=u_2|_{\Gamma_i}) $
-where  $u_i$ is solution of the following Laplace problem:
-\eq{
-    -\Delta u_i=f\hin\Omega_i\quad
-    u_i|_{\Gamma_i}=\lambda \quad
-    u_i|_{\Gamma_e^i} = 0
- }
-
-The version of this example for  Shur componant. The border problem
-is solve with conjugate gradient.
-
-First, we construct the two domain
-\begin{example}[Schwarz-gc.edp]~
-\index{tutorial!Schwarz-gc.edp}
-\bFF
-// Schwarz without overlapping (Shur complenement Neumann -> Dirichet)
- at real cpu=clock();
- at int inside = 2;
- at int outside = 1;
-
- at border Gamma1(t=1,2){x=t;y=0;label=outside;};
- at border Gamma2(t=0,1){x=2;y=t;label=outside;};
- at border Gamma3(t=2,0){x=t ;y=1;label=outside;};
-
- at border GammaInside(t=1,0){x = 1-t; y = t;label=inside;};
-
- at border GammaArc(t=pi/2, 2*pi){ x= cos(t); y = sin(t);label=outside;};
-int n=4;
-//  build the mesh of $\Omega_1$ and $\Omega_2$
- at mesh Th1 = buildmesh( Gamma1(5*n) + Gamma2(5*n) + GammaInside(5*n) + Gamma3(5*n));
- at mesh Th2 = buildmesh ( GammaInside(-5*n) + GammaArc(25*n) );
- at plot(Th1,Th2);
-
-// defined the 2 FE space
- at fespace Vh1(Th1,P1),      Vh2(Th2,P1);
-\eFF
-\begin{note}
-It is impossible to
-define a function just on a part of boundary, so the $\ lambda $
-function must be defined on the all domain $\Omega_1$
-such as
-\bFF
- at Vh1 lambda=0;  // take $\lambda \in V_{h1}$
-\eFF
-\end{note}
-
-The two Poisson problem:
-\bFF
- at Vh1 u1,v1;              Vh2 u2,v2;
- at int i=0;  // for factorization optimization
- at problem Pb2(u2,v2,init=i,solver=Cholesky) =
-    int2d(Th2)( dx(u2)*dx(v2)+dy(u2)*dy(v2) )
-  + int2d(Th2)( -v2)
-  + int1d(Th2,inside)(-lambda*v2) +    on(outside,u2= 0 ) ;
- at problem Pb1(u1,v1,init=i,solver=Cholesky) =
-    int2d(Th1)( dx(u1)*dx(v1)+dy(u1)*dy(v1) )
-  + int2d(Th1)( -v1)
-  + int1d(Th1,inside)(+lambda*v1) +    on(outside,u1 = 0 ) ;
-\eFF
-or, we define a border matrix , because the
- $\ lambda $ function is none zero inside the domain $\Omega_1$:
-\bFF
- at varf b(u2,v2,solver=CG) =int1d(Th1,inside)(u2*v2);
- at matrix B= b(Vh1,Vh1,solver=CG);
-\eFF
-
-The boundary problem function,
-  $$
-  \lambda \longrightarrow  \int_{\Gamma_i }(u_1-u_2) v_{1}
-$$
-\bFF
- at func @real[@int] BoundaryProblem(real[int] &l)
-{
-   lambda[]=l; // make FE function form l
-   Pb1;     Pb2;
-   i++;  //  no  refactorization i !=0
-   v1=-(u1-u2);
-   lambda[]=B*v1[];
-   @return lambda[] ;
-};
-\eFF
-\begin{note}
-The  difference between the two notations \ttCC{v1} and \ttCC{v1[]}  is:
- \ttCC{v1} is the finite element  function and \ttCC{v1[]}
-is the vector in the canonical basis of the   finite element  function  \ttCC{v1} .
-\index{[]@\verb=[]=}
-\end{note}
-\bFF
-Vh1 p=0,q=0;
-//  solve the problem with Conjugate Gradient
-LinearCG(BoundaryProblem,p[],eps=1.e-6,nbiter=100);
-//  compute the final solution, because CG works with increment
-BoundaryProblem(p[]); // solve again  to have right u1,u2
-
-cout << " -- CPU time  schwarz-gc:" <<  clock()-cpu << endl;
-plot(u1,u2); // plot
-\eFF
-\end{example}
-
-\subsection{Fluid/Structures Coupled Problem}
-
-This problem involves the Lam\'{e} system of elasticity
-and the Stokes system for viscous fluids with velocity $\vec u$ and pressure $p$:
-\begin{eqnarray*}\Blue
--\Delta \vec u +\vec\nabla p = 0, \,
-%\`{u}
-\nabla\cdot \vec u = 0,\hbox{~~in ~}\Omega,\,
-\vec u=\vec u_\Gamma \hbox{~~on~~}\Gamma=\partial\Omega
-\end{eqnarray*}\Black
-where $u_\Gamma$ is the velocity of the boundaries. The
-force  that the fluid applies to the boundaries is the normal stress
-\Blue{$$
-\vec h =(\nabla\vec u +\nabla\vec u^T)\vec n -p\vec n
-$$}
-
-Elastic solids subject to forces deform: a point in the solid,
-at (x,y)
-goes to (X,Y) after.  When the displacement vector
-$\vec v=(v_1,v_2) = (X-x, Y-y)$  is small, Hooke's
-law relates the stress tensor $\sigma$ inside the solid to the
-deformation tensor $\epsilon$:
-\Blue{
- $$ \sigma_{ij} = \lambda \delta_{ij} \nabla.\vec v + 2\mu\epsilon_{ij},
-\,
-\epsilon_{ij} = {1\over 2}({\partial v_i\over\partial x_j} +
-{\partial v_j\over\partial x_i} )$$
-}
-where $\delta$ is the Kronecker symbol
-and where $\lambda, \mu$ are two constants describing the material mechanical
-properties in terms of the modulus of
-elasticity, and Young's modulus.
-
-The equations of elasticity are naturally written in variational form
-for the displacement vector $v(x)\in V$ as
-\Blue{$$
-\int_\Omega [2\mu\epsilon_{ij}(\vec v)\epsilon_{ij}(\vec w)
-+\lambda \epsilon_{ii}(v)\epsilon_{jj}(\vec w)]
-=\int_\Omega \vec g\cdot \vec w +\int_\Gamma \vec h\cdot \vec w,%\`{u}
-\forall \vec w\in V
-$$}
-The data are the gravity force $\vec g$ and the
-boundary stress $\vec h$.
-
-\begin{example}[Fluidstruct.edp]
-\index{tutorial!Fluidstruct.edp}
-In our example the Lam\'{e} system and the Stokes system are coupled by a
-common boundary on which
-the fluid  stress creates a displacement of the boundary and hence
-changes the shape of the domain where the Stokes problem is integrated.
-The geometry is that of a vertical driven cavity with an elastic lid.
-The lid is a beam with weight so it will
-be deformed by its own weight and by the normal stress due to the fluid reaction.
-The cavity is the $10 \times 10$ square and the lid is a rectangle of height $l=2$.
-\\\\
-A beam sits on a box full of fluid rotating because the left vertical side has velocity one.
-The beam is bent by its own weight, but the pressure of the fluid modifies the bending.
-\\
-The bending displacement of the beam is given by (uu,vv) whose solution is
-given as follows.
-\bFF
-//  Fluid-structure interaction for a weighting beam sitting on a
-// square cavity filled with a fluid.
-
- at int bottombeam = 2; // label of bottombeam
- at border a(t=2,0)  { x=0; y=t ;label=1;};        //  left beam
- at border b(t=0,10) { x=t; y=0 ;label=bottombeam;};        //  bottom of beam
- at border c(t=0,2)  { x=10; y=t ;label=1;};       //  rigth beam
- at border d(t=0,10) { x=10-t; y=2; label=3;};     //  top beam
- at real E = 21.5;
- at real sigma = 0.29;
- at real mu = E/(2*(1+sigma));
- at real lambda = E*sigma/((1+sigma)*(1-2*sigma));
- at real gravity = -0.05;
- at mesh th = @buildmesh( b(20)+c(5)+d(20)+a(5));
- at fespace Vh(th, at P1);
-Vh uu,w,vv,s,fluidforce=0;
- at cout << "lambda,mu,gravity ="<<lambda<< " " << mu << " " << gravity << @endl;
-// deformation of a beam under its own weight
- at solve  bb([uu,vv],[w,s])  =
-    @int2d(th)(
-                 2*mu*(dx(uu)*dx(w)+ ((dx(vv)+dy(uu))*(dx(s)+dy(w)))/4 )
-               + lambda*(dx(uu)+dy(vv))*(dx(w)+dy(s))/2
-             )
-  + @int2d(th) (-gravity*s)
-  + @on(1,uu=0,vv=0)
-  + fluidforce[];
- ;
-
- @plot([uu,vv],wait=1);
- @mesh th1 = movemesh(th, [x+uu, y+vv]);
- @plot(th1,wait=1);
-\eFF
-Then Stokes equation for fluids ast low speed are solved in the box below the beam,
-but the beam has deformed the box (see border h):
-\bFF
-//Stokes on square  b,e,f,g  driven cavite on left side g
- at border e(t=0,10) { x=t; y=-10; label= 1; };      //  bottom
- at border f(t=0,10) { x=10; y=-10+t ; label= 1; };   //  right
- at border g(t=0,10) { x=0; y=-t ;label= 2;};       //  left
- at border h(t=0,10) { x=t; y=vv(t,0)*( t>=0.001 )*(t <= 9.999);
-                    label=3;};   //  top of cavity deformed
-
- at mesh sh = @buildmesh(h(-20)+f(10)+e(10)+g(10));
- at plot(sh,wait=1);
-\eFF
- We use the Uzawa conjugate gradient to solve the Stokes problem like in example \refSec{Uzawa}
-
-\bFF
- at fespace Xh(sh,P2),Mh(sh,P1);
-Xh u1,u2,v1,v2;
-Mh p,q,ppp;
-
-
- at varf bx(u1,q) = @int2d(sh)( -(dx(u1)*q));
-
- at varf by(u1,q) = @int2d(sh)( -(dy(u1)*q));
-
- at varf Lap(u1,u2)= @int2d(sh)(  dx(u1)*dx(u2) + dy(u1)*dy(u2) )
-                    +  @on(2,u1=1) +  @on(1,3,u1=0)  ;
-
-Xh bc1; bc1[] = Lap(0,Xh);
-Xh brhs;
-
- at matrix A= Lap(Xh,Xh,solver=CG);
- at matrix Bx= bx(Xh,Mh);
- at matrix By= by(Xh,Mh);
-Xh bcx=0,bcy=1;
-
- at func @real[@int] divup(@real[@int] & pp)
-{
-  @int verb=verbosity;
-   verbosity=0;
-   brhs[]  = Bx'*pp; brhs[] += bc1[] .*bcx[];
-   u1[] = A^-1*brhs[];
-   brhs[]  = By'*pp; brhs[] += bc1[] .*bcy[];
-   u2[] = A^-1*brhs[];
-   ppp[] =   Bx*u1[];
-   ppp[] +=  By*u2[];
-   verbosity=verb;
-   @return ppp[] ;
-};
-
- p=0;q=0;u1=0;v1=0;
-
- @LinearCG(divup,p[],eps=1.e-3,nbiter=50);
- divup(p[]);
-\eFF
-Now the beam will feel the stress constraint from the fluid:
-\bFF
-  Vh sigma11,sigma22,sigma12;
-  Vh uu1=uu,vv1=vv;
-
-  sigma11([x+uu,y+vv]) = (2*dx(u1)-p);
-  sigma22([x+uu,y+vv]) = (2*dy(u2)-p);
-  sigma12([x+uu,y+vv]) = (dx(u1)+dy(u2));
-\eFF
-which comes as a boundary condition to the PDE of the beam:
-\bFF
- at varf fluidf([uu,vv],[w,s]) fluidforce =
- at solve  bbst([uu,vv],[w,s],init=i)  =
-    @int2d(th)(
-                 2*mu*(dx(uu)*dx(w)+ ((dx(vv)+dy(uu))*(dx(s)+dy(w)))/4 )
-               + lambda*(dx(uu)+dy(vv))*(dx(w)+dy(s))/2
-             )
-  + @int2d(th) (-gravity*s)
-  + @int1d(th,bottombeam)( -coef*(   sigma11*N.x*w + sigma22*N.y*s
-                                   + sigma12*(N.y*w+N.x*s) )  )
-  + @on(1,uu=0,vv=0);
- @plot([uu,vv],wait=1);
- @real  err = sqrt(@int2d(th)( (uu-uu1)^2 + (vv-vv1)^2 ));
- @cout <<  " Erreur L2 = " << err << "----------\n";
-\eFF
-
-Notice that the matrix generated by bbst is reused (see \ttCC{init=i}).
-Finally we deform the beam
-\bFF
- th1 = @movemesh(th, [x+0.2*uu, y+0.2*vv]);
- @plot(th1,wait=1);
-\eFF
-\end{example}
-
-\subsection{\setS{Transmission Problem}}
-Consider an elastic plate whose displacement change vertically,
-which is made up of three plates of different materials,
-welded on each other.
-Let $\Omega_i,\, i=1,2,3$ be the domain occupied by $i$-th material
-with tension $\mu_i$ (see \refSec{Soap Film}).
-The computational domain $\Omega$ is the interior of
-$\overline{\Omega_1}\cup \overline{\Omega_2}\cup \overline{\Omega_3}$.
-The vertical displacement $u(x,y)$ is obtained from
-\begin{eqnarray}
-\label{eqn:transm-1}
--\mu_i\Delta u&=&f~\textrm{in }\Omega_i\\
-\label{eqn:transm-2}
-\mu_i\partial_n u|_{\Gamma_{i}}&=&-\mu_j\partial_n u|_{\Gamma_{j}}
-\quad \textrm{on }\overline{\Omega_{i}}\cap\overline{\Omega_{j}}
-\qquad \textrm{if }1\le i< j\le 3
-\end{eqnarray}
-where $\partial_n u|_{\Gamma_{i}}$ denotes the value of
-the normal derivative $\partial_n u$ on the boundary $\Gamma_i$ of
-the domain $\Omega_i$.
-
-By introducing the characteristic function $\chi_i$ of $\Omega_i$, that is,
-\begin{equation}
-\chi_i(x)=1\quad\textrm{if }x\in \Omega_i;\qquad
-\chi_i(x)=0\quad\textrm{if }x\not\in \Omega_i
-\end{equation}
-we can easily rewrite (\ref{eqn:transm-1}) and (\ref{eqn:transm-2})
-to the weak form. Here we assume that $u=0$ on $\Gamma=\partial\Omega$.
-
-problem Transmission: For a given function $f$, find $u$ such that
-\begin{eqnarray}
-\label{eqn:transmission}
-a(u,v)&=&\ell(f,v)\quad \textrm{for all }v\in H^1_0(\Omega)\\
-a(u,v)=\int_{\Omega}\mu \nabla u\cdot \nabla v,\quad
-\ell(f,v)=\int_{\Omega}fv\nonumber
-\end{eqnarray}
-where $\mu=\mu_1\chi_1+\mu_2\chi_2+\mu_3\chi_3$.
-Here we notice that $\mu$ become the discontinuous function.
-
-With dissipation, and at the thermal equilibrium, the temperature equation
-is:
-
-This example explains the definition and manipulation of \emph{region}, i.e.
-\index{subdomains} subdomains of the whole domain.
-
-Consider this L-shaped domain with 3 diagonals as internal boundaries, defining
-4 subdomains:
-
-\bFF
-//   example using region keyword
-// construct a mesh with 4 regions (sub-domains)
-border a(t=0,1){x=t;y=0;};
-border b(t=0,0.5){x=1;y=t;};
-border c(t=0,0.5){x=1-t;y=0.5;};
-border d(t=0.5,1){x=0.5;y=t;};
-border e(t=0.5,1){x=1-t;y=1;};
-border f(t=0,1){x=0;y=1-t;};
-//  internal boundary
-border i1(t=0,0.5){x=t;y=1-t;};
-border i2(t=0,0.5){x=t;y=t;};
-border i3(t=0,0.5){x=1-t;y=t;};
-
-mesh th = buildmesh (a(6) + b(4) + c(4) +d(4) + e(4) +
-    f(6)+i1(6)+i2(6)+i3(6));
-fespace Ph(th,P0);  // constant discontinuous functions / element
-fespace Vh(th,P1);  // $P_1$ continuous functions / element
-
-Ph reg=region; //  defined the $P_0$ function  associated to region number
-plot(reg,fill=1,wait=1,value=1);
-\eFF
-\twoplot[height=8cm]{region}{region_nu}{the function \texttt{reg}}{the function \texttt{nu} }
-
-\index{region} \texttt{region}  is a keyword of freefem++ which is in fact a variable depending of
-the current position (is not a function today, use \texttt{Ph reg=region;} to  set  a function).  This variable value returned is the number of the
-subdomain of the current position.  This number is defined by "buildmesh" which scans while building the mesh all
-its connected component.  So to get the number of a region containing a particular point
-one does:
-\bFF
-
-int nupper=reg(0.4,0.9); // get the region number of point (0.4,0.9)
-int nlower=reg(0.9,0.1);  // get the region number of point (0.4,0.1)
-cout << " nlower " <<  nlower << ", nupper = " << nupper<< endl;
-//  defined the characteristics functions of upper and lower region
-Ph nu=1+5*(region==nlower) + 10*(region==nupper);
-plot(nu,fill=1,wait=1);
-\eFF
-This is particularly useful to define \index{discontinuous functions}discontinuous functions such as might occur
-when one part of the domain is copper and the other one is iron, for example.
-\\
-We this in mind we proceed to solve a Laplace equation with discontinuous coefficients
-($\nu$ is 1, 6 and 11 below).
-\bFF
-Ph nu=1+5*(region==nlower) + 10*(region==nupper);
-plot(nu,fill=1,wait=1);
-problem lap(u,v) =   int2d(th)( nu*( dx(u)*dx(v)*dy(u)*dy(v) )) + int2d(-1*v) + on(a,b,c,d,e,f,u=0);
-plot(u);
-\eFF
-\plot[height=8cm]{region_u}{the isovalue of the solution $u$}
-\newpage
-
-\subsection{Free Boundary Problem}
-
-The domain $\Omega$ is defined with:
-
-\bFF
- at real L=10;        //longueur du domaine
- at real h=2.1;      // hauteur du bord gauche
- at real h1=0.35;    // hauteur du bord droite
-
-//  maillage d'un tapeze
- at border a(t=0,L){x=t;y=0;};       // bottom:  $\Gamma_a$ \hfill
- at border b(t=0,h1){x=L;y=t;};      // right:  $\Gamma_b$ \hfill
- at border f(t=L,0){x=t;y=t*(h1-h)/L+h;}; //  free surface:  $\Gamma_f$ \hfill
- at border d(t=h,0){x=0;y=t;};      // left:  $\Gamma_d$ \hfill
-
- at int n=4;
- at mesh Th=@buildmesh (a(10*n)+b(6*n)+f(8*n)+d(3*n));
- at plot(Th,ps="dTh.eps");
-\eFF
-
-
-\begin{figure}[hbt]
-\includegraphics[width=15cm]{dTh}
-\caption{The mesh of the domain $\Omega$}
-\end{figure}
-
-The free boundary problem is:
-
-Find $u$ and $\Omega$ such that:
-
- $$ \left\{\begin{array}{cl}
- \displaystyle - \Delta u = 0  & \mbox{in } \Omega\\
- \displaystyle      u = y         &\mbox{on } \Gamma_b \\
- \displaystyle      {\partial u  \over \partial n} = 0   &\mbox{on } \Gamma_d \cup \Gamma_a \\
- \displaystyle    {\partial u  \over \partial n} = { q\over K} n_x
-          \mbox{\ and \ } {u = y}  &\mbox{on\ } \Gamma_ f
-\end{array}\right. $$
-
-
-We use a fixed point method;
-$\Omega^0 = \Omega$
-
-in two step, fist we solve the classical following problem:
-$$ \left\{\begin{array}{rll}
- \displaystyle - \Delta u &= 0  & \mbox{in } \Omega^n\\
- \displaystyle      u &= y         &\mbox{on } \Gamma^n_b \\
- \displaystyle      {\partial u  \over \partial n} &= 0   &\mbox{on } \Gamma^n_d \cup \Gamma^n_a\\
- \displaystyle    u &= y        &\mbox{on\ } \Gamma^n_ f
-\end{array}\right. $$
-
-The variational formulation is:
-
-find $u$ on $V=H^1(\Omega^n)$, such than  $u=y$ on $\Gamma^n_b$ and $\Gamma^n_f$
-$$
- \int_{\Omega^n}  \nabla u \nabla u' = 0,  \quad \forall u' \in V  \mbox{ with }  u' =0 \mbox{ on }
-\Gamma^n_b \cup \Gamma^n_f
-$$
-
-
-and secondly to construct a domain deformation $\mathcal{F}(x,y)=[x,y-v(x,y)]$
-
-where $v$ is  solution of  the following problem:
-
- $$ \left\{\begin{array}{rll}
- \displaystyle - \Delta v &= 0  & \mbox{in } \Omega^n\\
- \displaystyle      v  &= 0         &\mbox{on } \Gamma^n_a \\
- \displaystyle      {\partial v \over \partial n} &= 0   &\mbox{on } \Gamma^n_b \cup \Gamma^n_d \\
- \displaystyle    {\partial v  \over \partial n}  &=  \displaystyle {\partial u  \over \partial n} - { q\over K} n_x
-            &\mbox{on\ } \Gamma^n_ f
-\end{array}\right. $$
-
-The variational formulation is:
-
-find $v$ on $V$, such than  $v=0$ on $\Gamma^n_a$
-$$
- \int_{\Omega^n}  \nabla v \nabla v' = \int_{\Gamma_f^n}  ({\partial u  \over \partial n} - { q\over K} n_x )v',  \quad \forall v' \in V  \mbox{ with }  v' =0 \mbox{ on }
-\Gamma^n_a
-$$
-
-Finally the new domain
-$\Omega^{n+1} = \mathcal{F}(\Omega^n)$
-
-
-
-\begin{example}[freeboundary.edp]
-\index{tutorial!freeboundary.edp}
-The  \texttt{FreeFem++} :implementation is:
-
-\bFF
- at real q=0.02;      //flux entrant
- at real K=0.5;           //permeabilit\'{e}
-
- at fespace Vh(Th,P1);
- at int j=0;
-
-Vh u,v,uu,vv;
-
- at problem Pu(u,uu,solver=CG) = @int2d(Th)( dx(u)*dx(uu)+dy(u)*dy(uu))
-  + @on(b,f,u=y) ;
-
- at problem Pv(v,vv,solver=CG) = @int2d(Th)( dx(v)*dx(vv)+dy(v)*dy(vv))
-  +  @on (a, v=0) + @int1d(Th,f)(vv*((q/K)*N.y- (dx(u)*N.x+dy(u)*N.y)));
-
-
- at real errv=1;
- at real erradap=0.001;
-verbosity=1;
- at while(errv>1e-6)
-{
-  j++;
-  Pu;
-  Pv;
-  @plot(Th,u,v ,wait=0);
-  errv=int1d(Th,f)(v*v);
-   real coef=1;
-
-//
-  real mintcc = @checkmovemesh(Th,[x,y])/5.;
-  real mint = @checkmovemesh(Th,[x,y-v*coef]);
-
-  if (mint<mintcc ||  j%10==0) {  // mesh to bad => remeshing
-    Th=@adaptmesh(Th,u,err=erradap ) ;
-    mintcc = @checkmovemesh(Th,[x,y])/5.;
-  }
-
-  @while (1)
-  {
-    real mint = @checkmovemesh(Th,[x,y-v*coef]);
-
-    if (mint>mintcc) break;
-
-    cout << " min |T]  " << mint << endl;
-    coef /= 1.5;
-  }
-
-  Th=@movemesh(Th,[x,y-coef*v]); // calcul de la deformation
-  cout << "\n\n"<<j <<"------------ errv = " << errv << "\n\n";
-
-}
- at plot(Th,ps="d_Thf.eps");
- at plot(u,wait=1,ps="d_u.eps");
-\eFF
-\end{example}
-
-\begin{figure}[hbt]
-\includegraphics[width=15cm]{d_u}
-\caption{The final solution on  the new  domain $\Omega^{72}$}
-\end{figure}
-\begin{figure}[hbt]
-\includegraphics[width=15cm]{d_Thf}
-\caption{The adapted mesh of the domain $\Omega^{72}$}
-\end{figure}
-
-\textBlack\subsection{nolinear-elas.edp}
-\textBlack
-The nonlinear elasticity  problem is find  the displacement $(u_{1},u_{2})$  minimizing  $J$
-$$ \min J(u_{1},u_{2}) = \int_{\Omega} f(F2) -  \int_{\Gamma_{p}} P_{a} \,  u_{2} $$
-where  $F2(u_{1},u_{2}) =  A(E[u_{1},u_{2}],E[u_{1},u_{2}])$ and $A(X,Y)$ is bilinear sym. positive form with respect two matrix $X,Y$.
-where $f$ is a given $\mathcal{C}^2$  function, and $E[u_{1},u_{2}] = (E_{ij})_{i=1,2,\,j=1,2}$ is the Green-Saint Venant deformation tensor defined  with:
-$$  E_{ij} = 0.5 ( \partial_i u_j + \partial_j u_i ) + \sum_k \partial_i u_k {\times} \partial_j u_k  $$
-
-
-
-The differential of $J$ is
-  $$ DJ(u_{1},u_{2})(v_{1},v_{2}) = \int 2 A(E[u_{1},u_{2}],DE[u_{1},u_{2}](v_{1},v_{2})) f'(F2(u_{1},u_{2}))) -  \int_{\Gamma_{p}} P_{a}  u_{2}  $$
-
-denote $\mathbf{u}=u_{1},u_{2}$, $\mathbf{v}=v_{1},v_{2}$, $\mathbf{w}=(w_{1},w_{2})$ and
-the second order differential is
- {\begin{eqnarray*}
- D^2 J(\mathbf{u})((\mathbf{v}),(\mathbf{w}))  &= & A(E[\mathbf{u}],DE[\mathbf{u}](\mathbf{v})) A(E[\mathbf{u}],DE[\mathbf{u}](\mathbf{w})) f''(F2(\mathbf{u}))) \\
- & + &  A(DE[\mathbf{u}](\mathbf{v}),DE[\mathbf{u}](\mathbf{w})) f'(F2(\mathbf{u}))) \\
- &+&  A(DE[\mathbf{u}],D^{2}E[\mathbf{u}]((\mathbf{v}),(\mathbf{w}))) f'(F2(\mathbf{u})))
-\end{eqnarray*}}
- where $DE$ and $D^{2}E$ are the first and second differential of $E$.
-
- \medskip
-
-
-The Newton Method is
-
-choose $ n=0$,and $u_O,v_O$ the initial displacement
-\begin{itemize}
-\item loop: \par
-\item  \hspace{1cm}    find $(du,dv)$ :  solution of
-$$ D^2J(u_n,v_n)((w,s),(du,dv)) =  DJ(u_n,v_n)(w,s) , \quad \forall w,s $$
-\item  \hspace{1cm}      $un =un - du,\quad vn =vn - dv$
-\item  \hspace{1cm}      until $(du,dv)$ small is enough
-\end{itemize}
-
-\color{black}The way to implement this algorithm in \freefempp is
-use a macro tool to implement  $A$ and $F2$, $f$, $f'$,$f''$.
-
-A macro\label{macro}\index{macro} is like is \texttt{ccp} preprocessor of \Cpp, but this begin by
-\texttt{macro} and the end of the macro definition is the begin of the comment $//$.
-In this case the macro is very useful because the type of parameter can be change.
-And  it is easy to make automatic differentiation.
-
-\bFF
-//  non linear elasticity model \hfilll
-//   \hfilll
-//  -------------------------------\hfilll
-//  with huge utilization of  macro\hfilll
-// ---------------------------\hfilll
-//   optimize version \hfilll
-// ------------\hfilll
-//  @problem is  find $(uu,vn)$  minimizing  $J$\hfilll
-//  $ min J(un,vn) = @int f(F2) -  @int Pa * un $\hfilll
-//   $ dJ(u,u,uu,vv) = @int dF2(u,v,uu,vv) df(F2(u,v))$ \hfilll
-//   where $F2 =  (^t {E}  A {E} )$ , \hfilll
-//   $E(U) =  1/2 (\nabla U + \nabla U^t + \nabla U^t  \nabla U) $ \hfilll
-//         ($u_1$) \hfilll
-//  with U=(   )\hfilll
-//         ($u_2$)\hfilll
-// so: \hfilll
-// \hfilll$$ E_{ij} = 0.5 ( d_i u_j + d_j u_i ) + \sum_k d_i u_k * d_j*u_k  \leqno(1)$$
-//  the 3 components of the Green Saint-Venant deformation tensor: \hfilll
-//  $E1(u1,u2) =    E_{11} $\hfilll
-//  $E2(u1,u2) =    E_{12} = E_21 $\hfilll
-//  $E3(u1,u2) =    E_{22}  $\textBlack\hfilll
-\eFF
-~
-\bFF
-// remark : we can parametrize E1,E2,E3 with:\hfilll
-//  EE(da,db,a,b,u1,u2) \hfilll
-//   where $da,db$ correspond to $d_i, d_j$ in (1)\hfilll
-//   where  $a,b$  correspond to $u_i, u_j$ in (1)\hfilll
-//   where $u1,u2$  correspond to $u_1, u_2$ in (1)\hfilll
-//  ----------------------------------------------
-
-//  first the linear part of EE linear elasticite\hfilll
-// remark a macro end with a // comment \hfilll
- at macro EEL(di,dj,ui,uj) ( (di(uj)+dj(ui))*0.5 )    // 11
-
-// non linear par of EE (bilinear)  simple to differential \hfilll
- at macro bEENL(di,dj,u1,u2,v1,v2) (di(u1)*dj(v1)*.5+di(u2)*dj(v2)*0.5)
-//
- at macro EENL(di,dj,u1,u2) bEENL(di,dj,u1,u2,u1,u2) //
- at macro dEENL(di,dj,u1,u2,du1,du2) ( bEENL(di,dj,du1,du2,u1,u2)
-                                  + bEENL(di,dj,u1,u2,du1,du2) )
-//   ------------ \hfilll
- at macro EE(di,dj,ui,uj,u1,u2) (EEL(di,dj,u1,uj) + EENL(di,dj,u1,u2)) //
- at macro dEE(di,dj,dui,duj,u1,u2,du1,du2) (EEL(di,dj,du1,duj)
-                                         + dEENL(di,dj,u1,u2,du1,du2)) //
- at macro ddEE(di,dj,du1,du2,ddu1,ddu2) ( dEENL(di,dj,du1,du2,ddu1,ddu2))
-//
-// remark  : \hfilll
-// $ dEE(di,dj,dui,duj,u1,u2,du1,du2)$  is "the formal differential of EE" \hfilll
-// where $du1=\delta u1$ ,$du2=\delta u2$ \hfilll
-// $ ddEE(di,dj,dui,duj,u1,u2,du1,du2)$  is "the formal differential of dEE" \hfilll
-// where $ddu1=\delta^2 u1$ ,$ddu2=\delta^2 u2$ \hfilll
-// --- \hfilll
-
-//  the macro corresponding to the 3 componante of E \hfilll
- at macro E1(u,v)  /*E11*/EE(dx,dx,u,u,u,v)  //
- at macro E2(u,v)  /*E12*/EE(dx,dy,u,v,u,v)  //
- at macro E3(u,v)  /*E22*/EE(dy,dy,v,v,u,v)  //
-
- at macro dE1(u,v,uu,vv) /*dE11*/dEE(dx,dx,uu,uu,u,v,uu,vv) //
- at macro dE2(u,v,uu,vv) /*dE12*/dEE(dx,dy,uu,vv,u,v,uu,vv) //
- at macro dE3(u,v,uu,vv) /*dE22*/dEE(dy,dy,vv,vv,u,v,uu,vv) //
- at macro ddE1(u,v,uu,vv,uuu,vvv) /*ddE11*/ddEE(dx,dx,uu,vv,uuu,vvv) //
- at macro ddE2(u,v,uu,vv,uuu,vvv) /*ddE12*/ddEE(dx,dy,uu,vv,uuu,vvv) //
- at macro ddE3(u,v,uu,vv,uuu,vvv) /*ddE22*/ddEE(dy,dy,uu,vv,uuu,vvv)
-//
-//  a formal bilinear term \hfilll
- at macro PP(A,B,u,v) (A(u,v)*B(u,v))
-//
-// a formal diff  bilinear term \hfilll
- at macro dPP(A,B,dA,dB,u,v,uu,vv) (dA(u,v,uu,vv)*B(u,v) + A(u,v)*dB(u,v,uu,vv))
-//
-// a formal $diff^2$ bilinear term \hfilll
- at macro ddPP(A,B,dA,dB,ddA,ddB,u,v,uu,vv,uuu,vvv) (
-  dA(u,v,uu,vv)*dB(u,v,uuu,vvv) + dA(u,v,uuu,vvv)*dB(u,v,uu,vv)
-  +  ddA(u,v,uu,vv,uuu,vvv)*B(u,v) + A(u,v)*ddB(u,v,uu,vv,uuu,vvv)
-  ) //
-// so the @matrix A is 6 coef \hfilll
-//
-//     a11 a12 a13 \hfilll
-//     a12 a22 a23 \hfilll
-//     a13 a23 a33 \hfilll
- at macro F2(u,v)  /* F2 */  (
-     a11*PP(E1,E1,u,v)
-  +  a22*PP(E2,E2,u,v)
-  +  a33*PP(E3,E3,u,v)
-  +  a13*PP(E1,E3,u,v)
-  +  a13*PP(E3,E1,u,v)
-  +  a12*PP(E1,E2,u,v)
-  +  a12*PP(E2,E1,u,v)
-  +  a23*PP(E2,E3,u,v)
-  +  a23*PP(E3,E2,u,v)
-)  // end macro F2
-
- at macro dF2(u,v,uu,vv)  /* dF2 */  (
-       a11*dPP(E1,E1,dE1,dE1,u,v,uu,vv)
-     + a12*dPP(E1,E2,dE1,dE2,u,v,uu,vv)
-     + a13*dPP(E1,E3,dE1,dE3,u,v,uu,vv)
-     + a21*dPP(E2,E1,dE2,dE1,u,v,uu,vv)
-     + a22*dPP(E2,E2,dE2,dE2,u,v,uu,vv)
-     + a23*dPP(E2,E3,dE2,dE3,u,v,uu,vv)
-     + a31*dPP(E3,E1,dE3,dE1,u,v,uu,vv)
-     + a32*dPP(E3,E2,dE3,dE2,u,v,uu,vv)
-     + a33*dPP(E3,E3,dE3,dE3,u,v,uu,vv)
-) // end macro dF2 ($D F2$)
-
- at macro ddF2(u,v,uu,vv,uuu,vvv)  /* ddF2 */  (
-       a11*ddPP(E1,E1,dE1,dE1,ddE1,ddE1,u,v,uu,vv,uuu,vvv)
-     + a12*ddPP(E1,E2,dE1,dE2,ddE1,ddE2,u,v,uu,vv,uuu,vvv)
-     + a13*ddPP(E1,E3,dE1,dE3,ddE1,ddE3,u,v,uu,vv,uuu,vvv)
-     + a21*ddPP(E2,E1,dE2,dE1,ddE2,ddE1,u,v,uu,vv,uuu,vvv)
-     + a22*ddPP(E2,E2,dE2,dE2,ddE2,ddE2,u,v,uu,vv,uuu,vvv)
-     + a23*ddPP(E2,E3,dE2,dE3,ddE2,ddE3,u,v,uu,vv,uuu,vvv)
-     + a31*ddPP(E3,E1,dE3,dE1,ddE3,ddE1,u,v,uu,vv,uuu,vvv)
-     + a32*ddPP(E3,E2,dE3,dE2,ddE3,ddE2,u,v,uu,vv,uuu,vvv)
-     + a33*ddPP(E3,E3,dE3,dE3,ddE3,ddE3,u,v,uu,vv,uuu,vvv)
-) // end macro ddF2  ($D^{2}  F2$)
-
-//  differential of J: \hfilll
-
-//  @for hyper elasticity @problem  \hfilll
-//  ------------------------------ \hfilll
-
- at macro f(u) (u) // end of macro
- at macro df(u) (1) // end of macro  $df=f'$
- at macro ddf(u) (0) // end of macro $ddf=f''$
-
-//  -- du caoutchouc --- CF cours de Herve Le Dret. \hfilll
-// ------------------------------- \hfilll
- at real mu = 0.012e5; //  $kg/cm^2$
- at real lambda =  0.4e5; //  $kg/cm^2$
-//  \hfilll
-//   $  \sigma = 2 \mu E + \lambda tr(E) Id $  \hfilll
-//    \hfilll
-//   ( a b )  \hfilll
-//   ( b c )  \hfilll
-//  \hfilll
-//  tr*Id : (a,b,c) -> (a+c,0,a+c)  \hfilll
-// so the associed @matrix is:  \hfilll
-//   ( 1 0 1 )  \hfilll
-//   ( 0 0 0 )  \hfilll
-//   ( 1 0 1 )  \hfilll
-// ------------------ the coef \hfilll
- at real a11= 2*mu +  lambda  ;
- at real a22= 2*mu ;
- at real a33= 2*mu +   lambda ;
- at real a12= 0 ;
- at real a13= lambda ;
- at real a23= 0 ;
-//  symetric part
- at real a21= a12 ;
- at real a31= a13 ;
- at real a32= a23 ;
- at real Pa=1e2; //  a pressure of 100 Pa
-// ----------------
-
- at int n=30,m=10;
- at mesh Th= square(n,m,[x,.3*y]); // label: 1 bottom, 2 right, 3 up, 4 left;
- at int bottom=1, right=2,upper=3,left=4;
-
- at plot(Th);
-
- at fespace Wh(Th,P1dc);
- at fespace Vh(Th,[P1,P1]);
- at fespace Sh(Th,P1);
-
-Wh e2,fe2,dfe2,ddfe2; // optimisation
-Wh ett,ezz,err,erz; // optimisation
-
-Vh [uu,vv], [w,s],[un,vn];
-[un,vn]=[0,0];//  intialisation
-[uu,vv]=[0,0];
-
- at varf vmass([uu,vv],[w,s],solver=CG) =  @int2d(Th)( uu*w + vv*s );
- at matrix M=vmass(Vh,Vh);
-
- at problem NonLin([uu,vv],[w,s],solver=LU)=
- @int2d(Th,qforder=1)( // $(D^2 J(un))$ part
-               ddF2(un,vn,uu,vv,w,s)* dfe2
-       + dF2(un,vn,uu,vv)*dF2(un,vn,w,s)*ddfe2
-        )
-   - at int2d(Th,<1)( // $(D J(un))$ part
-           dF2(un,vn,w,s) * dfe2  )
-   - @int1d(Th,3)(Pa*s)
-   + @on(right,left,uu=0,vv=0);
-;
-// Newton's method
-// ---------------
-Sh u1,v1;
- at for (@int i=0;i<10;i++)
-{
-  @cout << "Loop " << i << @endl;
-  e2 = F2(un,vn);
-  dfe2 = df(e2) ;
-  ddfe2 = ddf(e2);
-  @cout << "  e2 max " <<e2[].max << " , min" << e2[].min << @endl;
-  @cout << " de2 max "<< dfe2[].max << " , min" << dfe2[].min << @endl;
-  @cout << "dde2 max "<< ddfe2[].max << " , min" << ddfe2[].min << @endl;
-  NonLin; //  compute $[uu,vv] = (D^2 J(un))^{-1}(D J(un))$
-
-  w[]   = M*uu[];
-  @real res = sqrt(w[]' * uu[]); //  norme $ L^2 of [uu,vv]$
-  u1 = uu;
-  v1 = vv;
-  @cout << " L^2 residual = " << res << @endl;
-  @cout << " u1 min =" <<u1[].min << ", u1 max= " << u1[].max << @endl;
-  @cout << " v1 min =" <<v1[].min << ", v2 max= " << v1[].max << @endl;
-  @plot([uu,vv],wait=1,cmm=" uu, vv " );
-  un[] -= uu[];
-  @plot([un,vn],wait=1,cmm=" deplacement " );
-  @if (res<1e-5) @break;
-}
-
- at plot([un,vn],wait=1);
- at mesh th1 = @movemesh(Th, [x+un, y+vn]);
- at plot(th1,wait=1); //  see figure \ref{fig nl-elas}
-\eFF
-
-\begin{figure}[hbt]
-\begin{center}\includegraphics[width=16cm]{nl-elas}\end{center}
-\caption{\label{fig nl-elas} The deformated domain}
-\end{figure}
-
-
-
-\section{Parallel version experimental}
-A first test of parallelization of \texttt{FreeFem++} is make under mpi.
-We add three word in the language:
-\begin{description}
-\itemtt[mpisize] The total number of  processes\index{mpisize}
-\itemtt[mpirank]  the number of my current process in $\{0,..., mpisize-1\}$.\index{mpirank}
-\itemtt [processor] a function to set the possessor to send or receive data
-\itemtt [broadcast] a function to broadcast from a processor to all other a data \index{broadcast}\index{processor}
-\bFF
-    processor(10) << a ; // send to the process 10 the data a;
-    processor(10) >> a ; // receive from the process 10 the data a;
-
-\eFF
-\end{description}
-\subsection{Schwarz in parallel}
-If example is just the rewritting of example \texttt{schwarz-overlap}
-in section \ref{schwarz-overlap}.\index{schwarz}\index{broadcast}\index{processor}
-\index{array!mesh}
-
-How to use
-\bFF
-[examples++-mpi] Hecht%lamboot
-
-LAM 6.5.9/MPI 2 C++/ROMIO - Indiana University
-
-
-[examples++-mpi] hecht% mpirun -np 2 FreeFem++-mpi schwarz-c.edp
-\eFF
-
-\bFF
-//  a new coding version c,   methode de schwarz in parallele \hfilll
-// with 2 proc. \hfilll
-//  ------------------------------- \hfilll
-// F.Hecht december 2003 \hfilll
-// ---------------------------------- \hfilll
-//  to test the broadcast instruction \hfilll
-//  and array of mesh  \hfilll
-//  add add the stop test \hfilll
-//  --------------------------------- \hfilll
-
- at if ( mpisize != 2 ) {
-  @cout << " sorry number of processeur !=2 " << endl;
-  exit(1);}
- at verbosity=3;
- at real pi=4*atan(1);
- at int inside = 2;
- at int outside = 1;
- at border a(t=1,2){x=t;y=0;label=outside;};
- at border b(t=0,1){x=2;y=t;label=outside;};
- at border c(t=2,0){x=t ;y=1;label=outside;};
- at border d(t=1,0){x = 1-t; y = t;label=inside;};
- at border e(t=0, pi/2){ x= cos(t); y = sin(t);label=inside;};
- at border e1(t=pi/2, 2*pi){ x= cos(t); y = sin(t);label=outside;};
- at int n=4;
- at mesh[int]  Th(mpisize);
- at if (mpirank == 0)
- Th[0] = buildmesh( a(5*n) + b(5*n) + c(10*n) + d(5*n));
- at else
- Th[1] = buildmesh ( e(5*n) + e1(25*n) );
-
- at broadcast(@processor(0),Th[0]);
- at broadcast(@processor(1),Th[1]);
-
- at fespace Vh(Th[mpirank],P1);
- at fespace Vhother(Th[1-mpirank],P1);
-
-Vh u=0,v;
-Vhother U=0;
- at int i=0;
-
- at problem pb(u,v,init=i,solver=Cholesky) =
-    @int2d(Th[mpirank])( dx(u)*dx(v)+dy(u)*dy(v) )
-  - @int2d(Th[mpirank])( v)
-  + @on(inside,u = U)  +  @on(outside,u= U ) ;
-
- at for ( i=0 ;i< 20; i++)
-{
-  @cout << mpirank << " looP " << i << endl;
-   pb;
-   //  send u  to the other proc, receive in U
-   @processor(1-mpirank) << u[];   @processor(1-mpirank) >> U[];
-   @real err0,err1;
-   err0 = int1d(Th[mpirank],inside)(square(U-u)) ;
-   // send err0  to the other proc, receive in err1
-   @processor(1-mpirank)<<err0;   @processor(1-mpirank)>>err1;
-   @real err= sqrt(err0+err1);
-   @cout <<" err = " << err << " err0 = " << err0 << ", err1 = " << err1 << endl;
-   @if(err<1e-3) @break;
-};
- at if (mpirank==0)
-    @plot(u,U,ps="uU.eps");
-
-\eFF
-
-\include{docFFGUI}
-
-\section{\setS{Mesh Files}}
- \def\Chars#1{{\tt (C*)}  #1}
- \def\Char#1{{\tt (C)}  #1}
- \def\Int#1{ {\tt(I)} #1}
- \def\Real#1{{\tt(R)} #1}
- \def\Bool#1{{\tt(B)} #1}
- \def\Vertex#1{{{\tt @@Vertex}#1}}
- \def\Edge#1{{{\tt @@Edge}#1}}
- \def\Triangle#1{{{\tt @@Tria}#1}}
- \def\Quadrangle#1{{{\tt @@Quad}#1}}
- \def\Tetrahedron#1{{{\tt @@Tetra}#1}}
- \def\Hexahedron#1{{{\tt @@Hexa}#1}}
- \def\Pentahedron#1{{{\tt @@Penta}#1}}
- \def\Loop#1#2{{\bf\Large(}\,#1\,{\bf\Large{,\,\,}}\,#2\,{\bf\Large)}}
- \def\requis{\hfill {\it  requis}}
- \def\facultatif{\quad\quad facultatif}
- \def\need#1{\hfill{\it  requiert le champ\,:\,#1}}
-
-\subsection{File mesh data structure}
-\index{file!data base}\index{file!bamg}
-The mesh data structure, output of a mesh generation algorithm,
-refers to the geometric data structure and in some case to another
-mesh data structure.
-
-In this case, the fields are
-
-\small
-\begin{itemize}
-\item {\tt MeshVersionFormatted 0}
-\end{itemize}
-\normalsize
-
-\small
-\begin{itemize}
-\item {\tt Dimension}
-  \Int{dim}
-
-\item {\tt Vertices}
-  \Int{NbOfVertices}\\
-  \Loop{\,\,\Loop{\Real{x$_i^j$}}{j=1,dim}\,\,,\,\Int{$Ref \phi_i^v$}}{i=1\,,\,NbOfVertices}
-
-\item {\tt Edges}
-  \Int{NbOfEdges} \\
-  \Loop{\Vertex{$^1_i$}\,,\,\Vertex{$^2_i$}\,,\,\Int{$Ref \phi_i^e$}}{i=1\,,\,NbOfEdges}
-
-\item {\tt Triangles}
-  \Int{NbOfTriangles} \\
-    \Loop{\Loop{\Vertex{$_i^j$}}{j=1,3}\,,\,\Int{$Ref \phi_i^t$} }{ i=1\,,\,NbOfTriangles}
-
-\item {\tt Quadrilaterals}
-  \Int{NbOfQuadrilaterals} \\
-    \Loop{\Loop{\Vertex{$_i^j$}}{j=1,4}\,,\,\Int{$Ref \phi_i^t$} }{ i=1\,,\,NbOfQuadrilaterals}
-
-\item {\tt Geometry} \\
-\Chars{FileNameOfGeometricSupport} \\
-
-\begin{itemize}
-\item {\tt VertexOnGeometricVertex} \\
-   \Int{NbOfVertexOnGeometricVertex}\\
-\Loop{\Vertex{$_i$}\,,\,\Vertex{$_i^{geo}$}}{i=1,NbOfVertexOnGeometricVertex}
-
-\item {\tt EdgeOnGeometricEdge} \\
-   \Int{NbOfEdgeOnGeometricEdge}\\
-\Loop{\Edge{$_i$}\,,\,\Edge{$_i^{geo}$}}{i=1,NbOfEdgeOnGeometricEdge}
-\end{itemize}
-
-\item {\tt CrackedEdges}
-  \Int{NbOfCrackedEdges}\\
-  \Loop{\Edge{$_i^1$}\,,\,\Edge{$_i^2$}}{i=1\,,\,{NbOfCrackedEdges}}
-
-\end{itemize}
-\normalsize
-
-When the current mesh refers to a previous mesh, we have in addition
-
-\small
-\begin{itemize}
-\item {\tt MeshSupportOfVertices} \\
-\Chars{FileNameOfMeshSupport} \\
-\begin{itemize}
-
-\item {\tt VertexOnSupportVertex} \\
-   \Int{NbOfVertexOnSupportVertex}\\
-\Loop{\Vertex{$_i$}\,,\,\Vertex{$_i^{supp}$}}{i=1,NbOfVertexOnSupportVertex}
-
-\item {\tt VertexOnSupportEdge} \\
-   \Int{NbOfVertexOnSupportEdge}\\
-\Loop{\Vertex{$_i$}\,,\,\Edge{$_i^{supp}$}\,,\,  \mbox{\Real{$u_i^{supp}$}}  }{i=1,NbOfVertexOnSupportEdge}
-
-\item {\tt VertexOnSupportTriangle} \\
-   \Int{NbOfVertexOnSupportTriangle}\\
-\Loop{\Vertex{$_i$}\,,\,\Triangle{$_i^{supp}$}\,,\,
-  \mbox{\Real{$u_i^{supp}$}}\,,\,  \mbox{\Real{$v_i^{supp}$}}  }
-{\\ \hbox to 3cm {} i=1\,,\,{NbOfVertexOnSupportTriangle}}
-
-
-\item {\tt VertexOnSupportQuadrilaterals} \\
-   \Int{NbOfVertexOnSupportQuadrilaterals}\\
-\Loop{\Vertex{$_i$}\,,\,\Quadrangle{$_i^{supp}$}\,,\,
-  \mbox{\Real{$u_i^{supp}$}}\,,\,  \mbox{\Real{$v_i^{supp}$}}  }
-{\\ \hbox to 3cm {} i=1\,,\,{NbOfVertexOnSupportQuadrilaterals}}
-
-
-\end{itemize}
-
-\end{itemize}
-\normalsize
-
-
-
-\subsection {bb File type for Store Solutions}
-The file is formatted such that:
-{\tt \obeylines
-   2 nbsol nbv 2
-  $\left(\left(\mathtt{U}_{ij}, \quad \forall i \in \{1,...,\mathtt{nbsol}\}\right), \quad \forall j \in \{1,...,\mathtt{nbv}\}\right)$
- }
-
-where
-\begin{itemize}
-\item {\tt  nbsol} is a integer equal to  the number of solutions.
-\item  {\tt nbv} is  a integer equal to the number of vertex .
-\item  {\tt U$_{ij}$} is a real equal the value of the $i$ solution at vertex $j$
-on the associated mesh background if read file, generated if write file.
-\end{itemize}
-
-\subsection {BB File Type for Store Solutions}
-The file is formatted such that:
-{\tt \obeylines
-  $ \mathtt{ \quad 2 \quad n \quad typesol^1 \quad ... \quad typesol^n \quad  nbv \quad 2}  $
-  $\left(\left(\left( \mathtt{U}_{ij}^k, \quad \forall i \in \{1,...,\mathtt{typesol}^k\}\right), %
-\quad \forall k \in \{1,...\mathtt{n}\}\right) %
- \quad \forall j \in \{1,...,\mathtt{nbv}\}\right)$
- }
-
-where
-\begin{itemize}
-\item {\tt  n} is a integer equal to  the number of solutions
-\item $\mathtt{  typesol^k}$, type of the solution  number $ k$, is
-  \begin{itemize}
-   \item $\mathtt{typesol^k = 1}$ the solution {\tt k} is scalare  (1  value per vertex)
-   \item $\mathtt{typesol^k = 2}$ the solution {\tt k} is vectorial  (2 values per unknown)
-   \item $\mathtt{typesol^k = 3}$ the solution {\tt k} is a  $2{\times} 2$ symmetric matrix  (3 values per vertex)
-   \item $\mathtt{typesol^k = 4}$ the solution  {\tt k} is a  $2{\times} 2$ matrix  (4 values per vertex)
-   \end{itemize}
-
-\item  {\tt nbv} is  a integer equal to the number of vertices
-\item  {\tt U$_{ij}^k$} is a real equal the value of the component  $i$ of the solution  $k$ at vertex $j$
-on the associated mesh background if read file, generated if write file.
-\end{itemize}
-
-
-\subsection{Metric File}
- A metric file can be of two types, isotropic or anisotropic.
-\label{Metric file}
-
-the isotropic file is such that
-{\tt \obeylines
-   nbv  1
-   h$_i \quad \forall i \in \{1,...,\mathtt{nbv}\}$
-}
-
-
-where
-\begin{itemize}
-\item {\tt  nbv} is  a integer equal to the number of vertices.
-\item   {\tt h$_i$} is the wanted mesh size near the vertex $i$ on background mesh,
-the metric is $\mathcal{M}_i=h_i^{-2} Id$, where $ Id $ is the identity matrix.
-\end{itemize}
-
-The metric anisotrope
-{\tt \obeylines
-   nbv  3
-   a11$_i$,a21$_i$,a22$_i \quad \forall i \in \{1,...,\mathtt{nbv}\}$
-}
-
-
-where
-\begin{itemize}
-\item   {\tt nbv} is  a integer equal to the number of vertices,
-\item  a11$_i$, a12$_i$, a22$_i$ is metric
-$\mathcal{M}_i = \left(\begin{smallmatrix} a11_i & a12_i \\ a12_i & a22_i \end{smallmatrix}\right)$ which define the wanted mesh size
-in a vicinity of  the vertex $i$
-such that $h$ in direction $u \in \R^2$ is equal to $ |u|/\sqrt{u\cdot\mathcal{M}_i\, u}$ , where $\cdot$ is the dot product
-in $\R^2$, and $|\cdot|$ is the classical norm.
-
-\end{itemize}
-
-\subsection{List of  AM\_FMT, AMDBA Meshes}
- \index{file!am}\index{file!am\_fmt}\index{file!amdba}
- The mesh is only composed of triangles and can be defined with the help of
-the following two integers and four arrays:
-
-  \begin{ttlist}
-  \item [nbt] is the number of triangles.
-  \item [nbv] is the number of vertices.
-
-  \item [nu(1:3,1:nbt)] is an integer array giving the three vertex numbers
-
-counterclockwise for each triangle.
-
-  \item [c(1:2,nbv)]    is a real array giving the two coordinates of each vertex.
-  \item [refs(nbv)]     is an integer array giving the reference numbers of the
-vertices.
-  \item [reft(nbv)]     is an integer array giving the reference numbers of the
-triangles.
-  \end{ttlist}
-
-\paragraph{AM\_FMT Files}\label{AMFMT}
-\index{file!am\_fmt}
-In fortran the  {\tt am\_fmt}  files are read as follows:
-
-\begin{verbatim}
-     open(1,file='xxx.am_fmt',form='formatted',status='old')
-       read (1,*) nbv,nbt
-       read (1,*)  ((nu(i,j),i=1,3),j=1,nbt)
-       read (1,*)  ((c(i,j),i=1,2),j=1,nbv)
-       read (1,*)  ( reft(i),i=1,nbt)
-       read (1,*)  ( refs(i),i=1,nbv)
-     close(1)
-\end{verbatim}
-
-\paragraph{AM Files}\label{AM}
-\index{file!am}
-In fortran the  {\tt am}  files are read as follows:
-
-\begin{verbatim}
-     open(1,file='xxx.am',form='unformatted',status='old')
-       read (1,*) nbv,nbt
-       read (1)  ((nu(i,j),i=1,3),j=1,nbt),
-     &   ((c(i,j),i=1,2),j=1,nbv),
-     &   ( reft(i),i=1,nbt),
-     &   ( refs(i),i=1,nbv)
-     close(1)
-\end{verbatim}
-\paragraph{AMDBA Files}\label{AMDBA}
-\index{file!amdba}
-In fortran the  {\tt amdba}  files are read as follows:
-\begin{verbatim}
-     open(1,file='xxx.amdba',form='formatted',status='old')
-       read (1,*) nbv,nbt
-       read (1,*) (k,(c(i,k),i=1,2),refs(k),j=1,nbv)
-       read (1,*) (k,(nu(i,k),i=1,3),reft(k),j=1,nbt)
-     close(1)
-\end{verbatim}
-\paragraph{msh Files}\label{MSH}
-\index{file!msh}
-First, we add the notions of boundary edges
-  \begin{ttlist}
-  \item [nbbe] is the number of boundary edge.
-  \item [nube(1:2,1:nbbe)] is an integer array giving the two vertex numbers
-  \item [refbe(1:nbbe)] is an integer array giving the two vertex numbers
-  \end{ttlist}
-In fortran the  {\tt msh}  files are read as follows:
-\begin{verbatim}
-     open(1,file='xxx.msh',form='formatted',status='old')
-       read (1,*) nbv,nbt,nbbe
-       read (1,*) ((c(i,k),i=1,2),refs(k),j=1,nbv)
-       read (1,*) ((nu(i,k),i=1,3),reft(k),j=1,nbt)
-       read (1,*) ((ne(i,k),i=1,2), refbe(k),j=1,nbbe)
-     close(1)
-\end{verbatim}
-\paragraph{ftq Files}\label{FTQ}
-\index{file!ftq}
-In fortran the  {\tt ftq}  files are read as follows:
-\begin{verbatim}
-     open(1,file='xxx.ftq',form='formatted',status='old')
-      read (1,*) nbv,nbe,nbt,nbq
-      read (1,*) (k(j),(nu(i,j),i=1,k(j)),reft(j),j=1,nbe)
-      read (1,*) ((c(i,k),i=1,2),refs(k),j=1,nbv)
-     close(1)
-\end{verbatim}
-where   if {\tt  k(j) = 3} then the element $j$  is  a triangle and if {\tt k = 4}
-the the element $j$   is a quadrilateral.
-
-\include{addfe}
-
-\appendix
-\section{Table of Notations}
-Here mathematical expressions and corresponding \freefempp commands are noted.
-\subsection{Generalities}
-\begin{description}
-  \item[$\delta_{ij}$] Kronecker delta ($0$ if $i\neq j$, 1 if $i=j$ for integers $i,j$)
-  \item[$\forall$] for all
-  \item[$\exists$] there exist
-  \item[i.e.] that is
-  \item[PDE] partial differential equation (with boundary conditions)
-  \item[$\emptyset$] the empty set
-  \item[$\N$] the set of integers ($a\in \N\Leftrightarrow \texttt{int a}$);
-  ``\texttt{int}'' means \emph{long integer} inside \freefempp
-  \item[$\R$] the set of real numbers ($a\in \R\Leftrightarrow \texttt{real a}$)  ;\emph{double} inside \freefempp
-  \item[$\C$] the set of complex numbers ($a\in \C\Leftrightarrow \texttt{complex a}$);
-  \emph{complex<double>}
-  \item[$\R^d$] $d$-dimensional Euclidean space
-\end{description}
-\subsection{Sets, Mappings, Matrices, Vectors}
-Let $E,\, F,\, G$ be three sets and $A$ subset of $E$.
-\begin{description}
-  \item[$\{x\in E|\; P\}$] the subset of $E$ consisting of the elements possessing the property $P$
-  \item[$E\cup F$] the set of elements belonging to $E$ or $F$
-  \item[$E\cap F$] the set of elements belonging to $E$ and $F$
-  \item[$E\setminus A$] the set $\{x\in E|\; x\not\in A\}$
-  \item[$E+F$] $E\cup F$ with $E\cap F=\emptyset$
-  \item[$E\times F$] the cartesian product of $E$ and $F$
-  \item[$E^n$] the $n$-th power of $E$ ($E^2=E\times E$, $E^n=E\times E^{n-1}$)
-  \item[$f:\; E\to F$] the mapping form $E$ into $F$, i.e.,
-  $E\ni x\mapsto f(x)\in F$
-  \item[$I_E$ or $I$] the identity mapping in $E$,i.e., $I(x)=x\quad \forall x\in E$
-  \item[$f\circ g$] for $f:\; F\to G$ and $g:\; E\to F$,
-  $E\ni x\mapsto (f\circ g)(x)=f(g(x))\in G$ (see \refSec{One Variable Functions})
-  \item[$f|_A$] the restriction of $f:\; E\to F$ to the subset $A$ of $E$
-  \item[$\{a_k\}$] column vector with components $a_k$
-  \item[$(a_k)$] row vector with components $a_k$
-  \item[$(a_{k})^T$] denotes the transpose of a matrix $(a_{k})$, and
-  is $\{a_{k}\}$
-  \item[$\{a_{ij}\}$] matrix with components $a_{ij}$, and $(a_{ij})^T=(a_{ji})$
-\end{description}
-
-\subsection{Numbers}
-For two real numbers $a,b$
-\begin{description}
-  \item[\quad]$[a,b]$ is the interval $\{x\in \R|\; a\le x\le b\}$
-  \item[\quad]$]a,b]$ is the interval $\{x\in \R|\; a< x\le b\}$
-  \item[\quad]$[a,b[$ is the interval $\{x\in \R|\; a\le x< b\}$
-  \item[\quad]$]a,b[$ is the interval $\{x\in \R|\; a< x< b\}$
-\end{description}
-
-\subsection{Differential Calculus}
-\begin{description}
-  \item[$\partial f/\partial x$] the partial derivative of $f:\R^d\to \R$ with respect to $x$ (\ttCC{@dx(f)})
-  \item[$\nabla f$] the gradient of $f:\Omega\to \R$,i.e., $\nabla f=(\partial f/\partial x,\, \partial f/\partial y)$
-  \item[div$\vec{f}$ or $\nabla.\vec{f}$] the divergence of $\vec{f}:\Omega\to \R^d$, i.e., div$\vec{f}=\partial f_1/\partial x+\partial f_2/\partial y$
-  \item[$\Delta f$] the Laplacian of $f:\; \Omega\to \R$, i.e.,
-  $\Delta f=\partial^2f/\partial x^2+\partial^2 f/\partial y^2$
-\end{description}
-
-\subsection{Meshes}
-\begin{description}
-  \item[$\Omega$] usually denotes a domain on which PDE is defined
-  \item[$\Gamma$] denotes the boundary of $\Omega$,i.e., $\Gamma=\partial\Omega
-$ (keyword \ttCC{@border}, see \refSec{Border})
-  \item[$\mathcal{T}_h$] the triangulation of $\Omega$, i.e., the set of triangles $T_k$, where $h$ stands for mesh size (keyword \ttCC{@mesh}, \ttCC{@buildmesh}, see \refSec{Mesh Generation})
-  \item[$n_t$] the number of triangles in $\mathcal{T}_h$ (get by \texttt{Th.nt}, see ``mesh.edp'')
-  \item[$\Omega_h$] denotes the approximated domain $\Omega_h=\cup_{k=1}^{n_t}T_k$ of $\Omega$. If $\Omega$ is polygonal domain, then it will be $\Omega=\Omega_h$
-  \item[$\Gamma_h$] the boundary of $\Omega_h$
-  \item[$n_v$] the number of vertices in $\mathcal{T}_h$ (get by \texttt{Th.nv})
-  \item[[$q^iq^j$]] the segment connecting $q^i$ and $q^j$
-  \item[$q^{k_1},q^{k_2},q^{k_3}$] the vertices of a triangle $T_k$ with anti-clock direction (get the coordinate of $q^{k_j}$ by
-  (\texttt{Th[k-1][j-1].x, Th[k-1][j-1].y}))
-  \item[$I_{\Omega}$] the set $\{i\in \N|\; q^i\not\in \Gamma_h\}$
-\end{description}
-
-\subsection{Finite Element Spaces}
-\begin{description}
-\item[$L^2(\Omega)$] the set
-$\displaystyle{
-\left\{w(x,y)\left|\; \int_{\Omega}|w(x,y)|^2dxdy<\infty\right.\right\}
-}$
-\begin{eqnarray*}
-&&\textrm{norm:}\; \| w\|_{0,\Omega}=\left(\int_{\Omega}|w(x,y)|^2dxdy\right)^{1/2}\\
-&&\textrm{scalar product:}\; (v,w)=\int_{\Omega}vw
-\end{eqnarray*}
-\item[$H^1(\Omega)$] the set
-$\displaystyle{
-\left\{w\in L^2(\Omega)\left|\; \int_{\Omega}
-\left(|\partial w/\partial x|^2+|\partial w/\partial y|^2\right)dxdy<\infty\right.\right\}
-}$
-\begin{eqnarray*}
-&&\textrm{norm:}\; \| w\|_{1,\Omega}=\left(\| w\|_{0,\Omega}^2+\|\nabla u\|_{0.\Omega}^2\right)^{1/2}
-\end{eqnarray*}
-\item[$H^m(\Omega)$] the set
-$\displaystyle{
-\left\{w\in L^2(\Omega)\left|\; \int_{\Omega}
-\frac{\partial^{|\alpha|} w}{\partial x^{\alpha_1}\partial y^{\alpha_2}}\in L^2(\Omega)\quad
-\forall \alpha=(\alpha_1,\alpha_2)\in \N^2,\, |\alpha|=\alpha_1+\alpha_2\right.
-\right\}
-}$
-\begin{eqnarray*}
-&&\textrm{scalar product:}\; (v,w)_{1,\Omega}=
-\sum_{|\alpha|\le m}\int_{\Omega} D^{\alpha}v D^{\alpha}w
-\end{eqnarray*}
-\item[$H^1_0(\Omega)$]
-the set $\left\{w\in H^1(\Omega)\left|\; u=0\quad \textrm{on }\Gamma\right.\right\}$
-\item[$L^2(\Omega)^2$] denotes $L^2(\Omega)\times L^2(\Omega)$, and also
-$H^1(\Omega)^2=H^1(\Omega)\times H^1(\Omega)$
-  \item[$V_h$] denotes the finite element space created by
-  ``\ttCC{@fespace} Vh(Th,*)'' in \freefempp (see \refSec{Finite Elements} for ``*'')
-  \item[$\Pi_h f$] the projection of the function $f$ into $V_h$
-  (``\ttCC{@func f=x\^{}2*y\^{}3; Vh v = f;}'' means \ttCC{v} = $\Pi_h$\ttCC{f})  \item[$\{v\}$]
-  for FE-function $v$ in $V_h$ means the column vector $(v_1,\cdots,v_M)^T$ if
-  $v=v_1\phi_1+\cdots+v_M\phi_M$, which is shown by
-  ``\ttCC{@fespace Vh(Th,P2); Vh v; cout << v[] << endl;}''
-\end{description}
-
-\section{Grammar}
-\subsection{Keywords}
-\bFF
-      Cmatrix
-      R3
-      bool
-      border
-      break
-      complex
-      continue
-      element
-      else
-      end
-      fespace
-      for
-      func
-      if
-      ifstream
-      include
-      int
-      load
-      macro
-      matrix
-      mesh
-      ofstream
-      problem
-      real
-      return
-      solve
-      string
-      vertex
-      varf
-      while
-
-\eFF
-\subsection{The bison grammar}
-\bFF
-
-start:   input @ENDOFFILE;
-
-input:   instructions ;
-
-instructions:  instruction
-        | instructions  instruction   ;
-
-list_of_id_args:
-            | id
-            | id '=' no_comma_expr
-            | @FESPACE id
-            | type_of_dcl id
-            | type_of_dcl '&' id
-            | '[' list_of_id_args ']'
-            | list_of_id_args ',' id
-            | list_of_id_args ',' '[' list_of_id_args ']'
-            | list_of_id_args ',' id '=' no_comma_expr
-            | list_of_id_args ',' FESPACE id
-            | list_of_id_args ',' type_of_dcl id
-            | list_of_id_args ',' type_of_dcl '&' id ;
-
-list_of_id1:  id
-            | list_of_id1 ',' id   ;
-
-id: @ID | @FESPACE ;
-
-list_of_dcls:    @ID
-              |  @ID '='   no_comma_expr
-              |  @ID  '(' parameters_list ')'
-              |  list_of_dcls ',' list_of_dcls  ;
-
-
-parameters_list:
-           no_set_expr
-        |  @FESPACE  @ID
-        |  @ID '=' no_set_expr
-        | parameters_list ',' no_set_expr
-        | parameters_list ',' id '=' no_set_expr ;
-
-type_of_dcl:   @TYPE
-             | @TYPE '[' @TYPE ']' ;
-
-ID_space:
-    @ID
- |  @ID '[' no_set_expr ']'
- |  @ID '=' no_set_expr
- |  '[' list_of_id1 ']'
- |  '[' list_of_id1 ']' '[' no_set_expr ']'
- |  '[' list_of_id1 ']' '=' no_set_expr ;
-
-ID_array_space:
-    @ID '(' no_set_expr ')'
- |  '[' list_of_id1 ']' '(' no_set_expr ')' ;
-
-fespace: @FESPACE ;
-
-spaceIDa  :      ID_array_space
-            |    spaceIDa ',' ID_array_space  ;
-
-spaceIDb  :      ID_space
-            |    spaceIDb ',' ID_space ;
-
-spaceIDs :    fespace               spaceIDb
-           |  fespace '[' @TYPE ']'  spaceIDa    ;
-
-fespace_def: @ID '(' parameters_list ')' ;
-
-fespace_def_list:  fespace_def
-                 | fespace_def_list ',' fespace_def ;
-
-
-declaration:   type_of_dcl list_of_dcls ';'
-             | 'fespace' fespace_def_list    ';'
-             | spaceIDs ';'
-             | @FUNCTION @ID '=' Expr ';'
-             | @FUNCTION type_of_dcl @ID  '(' list_of_id_args ')'  '{' instructions'}'
-             | @FUNCTION @ID '(' list_of_id_args ')'   '='   no_comma_expr  ';'     ;
-
-begin: '{'  ;
-end:   '}'  ;
-
-for_loop:    'for'   ;
-while_loop:  'while' ;
-
-instruction:   ';'
-         | 'include'  @STRING
-         | 'load'  @STRING
-         |  Expr  ';'
-         |  declaration
-         |  for_loop  '(' Expr ';' Expr ';' Expr ')' instruction
-         |  while_loop '(' Expr ')' instruction
-         |  'if' '(' Expr ')'   instruction
-         |  'if' '(' Expr ')'   instruction  ELSE instruction
-         |  begin  instructions end
-         |  'border'  @ID   border_expr
-         |  'border'   @ID   '['  array ']' ';'
-         |  'break'  ';'
-         |  'continue'  ';'
-         |  'return'  Expr ';'  ;
-
-
-bornes: '(' @ID '=' Expr ',' Expr ')' ;
-
-border_expr:   bornes instruction  ;
-
-Expr:    no_comma_expr
-       | Expr ',' Expr ;
-
-
-unop:     '-'
-        | '+'
-        | '!'
-        | '++'
-        | '--'  ;
-
-no_comma_expr:
-          no_set_expr
-        | no_set_expr '=' no_comma_expr
-        | no_set_expr '+=' no_comma_expr
-        | no_set_expr '-=' no_comma_expr
-        | no_set_expr '*=' no_comma_expr
-        | no_set_expr '/=' no_comma_expr ;
-
-no_set_expr:
-          unary_expr
-        | no_set_expr '*' no_set_expr
-        | no_set_expr '.*' no_set_expr
-        | no_set_expr './' no_set_expr
-        | no_set_expr '/' no_set_expr
-        | no_set_expr '%' no_set_expr
-        | no_set_expr '+' no_set_expr
-        | no_set_expr '-' no_set_expr
-        | no_set_expr '<<' no_set_expr
-        | no_set_expr '>>' no_set_expr
-        | no_set_expr '&' no_set_expr
-        | no_set_expr '&&' no_set_expr
-        | no_set_expr '|' no_set_expr
-        | no_set_expr '||' no_set_expr
-        | no_set_expr '<' no_set_expr
-        | no_set_expr '<=' no_set_expr
-        | no_set_expr '>' no_set_expr
-        | no_set_expr '>=' no_set_expr
-        | no_set_expr '==' no_set_expr
-        | no_set_expr '!=' no_set_expr ;
-
-
-parameters:
-        |   no_set_expr
-        |   @FESPACE
-        |   id '=' no_set_expr
-        |   parameters ',' @FESPACE
-        |   parameters ',' no_set_expr
-        |   parameters ',' id '=' no_set_expr ;
-
-array:   no_comma_expr
-       | array ',' no_comma_expr ;
-
-
-unary_expr:
-    pow_expr
-  | unop  pow_expr %prec UNARY ;
-
-pow_expr: primary
-  |      primary  '^' unary_expr
-  |      primary  '_' unary_expr
-  |      primary '\''  ;    //  transpose \index{transpose}
-
-primary:
-           @ID
-  |        @LNUM
-  |        @DNUM
-  |        @CNUM
-  |        @STRING
-  |        primary '('  parameters ')'
-  |        primary '[' Expr ']'
-  |        primary '['  ']'
-  |        primary '.'  ID
-  |        primary '++'
-  |        primary '--'
-  |        TYPE '('  Expr ')' ;
-  |        '(' Expr ')'
-  |        '[' array  ']' ;
-
-\eFF
-\subsection{The Types of the languages, and cast}
-%\begin{verbatim}
-% the types
-% --lgElement =  <lgElement>
-%    [,  type :<Polymorphic>
-%   operator :
-%   (    <lgVertex> :   <lgElement>, <long> )
-
-%
-% --lgVertex =  <lgVertex>
-%    label,  type :<Polymorphic>
-%   operator. :
-%   (    <long> :   <lgVertex> )
-
-%    x,  type :<Polymorphic>
-%   operator. :
-%   (    <double> :   <lgVertex> )
-
-%    y,  type :<Polymorphic>
-%   operator. :
-%   (    <double> :   <lgVertex> )
-
-% --Add_KN_<double> =  <Add_KN_<double>>
-
-% --Add_Mulc_KN_<double> * =  <Add_Mulc_KN_<double>>
-
-% --AnyTypeWithOutCheck =  <AnyTypeWithOutCheck>
-
-% --C_F0 =  <C_F0>
-
-% --DotStar_KN_<double> =  <DotStar_KN_<double>>
-
-% --E_Array =  <E_Array>
-
-% --FEbase<double> * =  <FEbase<double>>
-%    <FEbase<double>> :   <FEbase<double>>
-% --FEbase<double> ** =  <FEbase<double> **>
-
-% --FEbaseArray<double> * =  <FEbaseArray<double>>
-
-% --FEbaseArray<double> ** =  <FEbaseArray<double> **>
-%    []  type :<Polymorphic>   operator :
-%   (    <FEbase<double> **> :   <FEbaseArray<double> **>, <long> )
-
-%
-% --Fem2D::Mesh * =  <Fem2D::Mesh>
-%    <Fem2D::Mesh> :   <Fem2D::Mesh **>
-% --Fem2D::Mesh ** =  <Fem2D::Mesh **>
-%    <-,  type :<Polymorphic>
-%   (    <Fem2D::Mesh> :   <string> )
-%   (    <long> :   <Fem2D::Mesh **>, <double>, <double> )
-
-%    area,  type :<Polymorphic>   operator. :
-%   (    <double> :   <Fem2D::Mesh **> )
-
-%    nt,  type :<Polymorphic>
-%   operator. :
-%   (    <long> :   <Fem2D::Mesh **> )
-
-%    nv,  type :<Polymorphic>   operator. :
-%   (    <long> :   <Fem2D::Mesh **> )
-
-%
-% --Fem2D::MeshPoint * =  <Fem2D::MeshPoint>
-%    N,  type :<Polymorphic>   operator. :
-%   (    <Fem2D::R3> :   <Fem2D::MeshPoint> )
-
-%    P,  type :<Polymorphic>   operator. :
-%   (    <Fem2D::R3> :   <Fem2D::MeshPoint> )
-
-%
-% --Fem2D::R2 * =  <Fem2D::R2>
-
-% --Fem2D::R3 * =  <Fem2D::R3>
-%    x,  type :<Polymorphic>   operator. :
-%   (    <double *> :   <Fem2D::R3> )
-
-%    y,  type :<Polymorphic>   operator. :
-%   (    <double *> :   <Fem2D::R3> )
-
-%    z,  type :<Polymorphic>   operator. :
-%   (    <double *> :   <Fem2D::R3> )
-
-%
-% --Fem2D::TypeOfFE * =  <Fem2D::TypeOfFE>
-
-% --KN<double> =  <KN<double>>
-%    []  type :<Polymorphic>   operator :
-%   (    <double *> :   <KN<double>>, <long> )
-
-%
-% --KN<double> * =  <KN<double> *>
-%    <-,  type :<Polymorphic>
-%   (    <KN<double> *> :   <KN<double> *>, <long> )
-
-%    []  type :<Polymorphic>   operator :
-%   (    <double *> :   <KN<double> *>, <long> )
-
-%    max,  type :<Polymorphic>   operator. :
-%   (    <double> :   <KN<double> *> )
-
-%    min,  type :<Polymorphic>   operator. :
-%   (    <double> :   <KN<double> *> )
-
-%    n,  type :<Polymorphic>
-%   operator. :
-%   (    <long> :   <KN<double> *> )
-
-%    sum,  type :<Polymorphic>   operator. :
-%   (    <double> :   <KN<double> *> )
-
-%
-% --KN_<double> =  <KN_<double>>
-
-% --KN_<double> * =  <KN_<double> *>
-
-% --Matrice_Creuse<double> * =  <Matrice_Creuse<double>>
-%    <Matrice_Creuse<double>> :   <Problem>
-% --Matrice_Creuse_Transpose<double> =  <Matrice_Creuse_Transpose<double>>
-
-% --Matrice_Creuse_inv<double> =  <Matrice_Creuse_inv<double>>
-
-% --Mulc_KN_<double> =  <Mulc_KN_<double>>
-
-% --MyMap<String, double> * =  <MyMap<String, double>>
-%    []  type :<Polymorphic>   operator :
-%   (    <double *> :   <MyMap<String, double>>, <string> )
-
-%
-% --Polymorphic * =  <Polymorphic>
-
-% --Sub_KN_<double> =  <Sub_KN_<double>>
-
-% --Transpose<KN<double>> =  <Transpose<KN<double>>>
-
-% --TypeSolveMat * =  <TypeSolveMat>
-
-% --VirtualMatrice<double>::plusAtx =  <VirtualMatrice<double>::plusAtx>
-
-% --VirtualMatrice<double>::plusAx =  <VirtualMatrice<double>::plusAx>
-
-% --VirtualMatrice<double>::solveAxeqb =  <VirtualMatrice<double>::solveAxeqb>
-
-% --bool =  <bool>
-%    <bool> :   <bool *>
-% --bool * =  <bool *>
-
-% --char * =  <char>
-
-% --const BC_set<double> * =  <BC_set<double>>
-
-% --const CDomainOfIntegration * =  <CDomainOfIntegration>
-%    ()  type :<Polymorphic>   operator :
-%   (    <FormBilinear> :   <CDomainOfIntegration>, <LinearComb<std::pair<MGauche, MDroit>, C_F0>> )
-%   (    <double> :   <CDomainOfIntegration>, <double> )
-%   (    <FormLinear> :   <CDomainOfIntegration>, <LinearComb<MDroit, C_F0>> )
-
-%
-% --const C_args * =  <C_args>
-%    <C_args> :   <FormBilinear>     ()  type :<Polymorphic>   operator :
-%   (    <Call_FormLinear> :   <C_args>, <long>, <v_fes **> )
-%   (    <Call_FormBilinear> :   <C_args>, <v_fes **>, <v_fes **> )
-
-%
-% --const Call_FormBilinear * =  <Call_FormBilinear>
-
-% --const Call_FormLinear * =  <Call_FormLinear>
-
-% --const E_Border * =  <E_Border>
-
-% --const E_BorderN * =  <E_BorderN>
-
-% --const Fem2D::QuadratureFormular * =  <Fem2D::QuadratureFormular>
-
-% --const Fem2D::QuadratureFormular1d * =  <Fem2D::QuadratureFormular1d>
-
-% --const FormBilinear * =  <FormBilinear>
-%    ()  type :<Polymorphic>   operator :
-%   (    <Call_FormBilinear> :   <FormBilinear>, <v_fes **>, <v_fes **> )
-%   (    <Call_FormLinear> :   <FormBilinear>, <long>, <v_fes **> )
-
-%
-% --const FormLinear * =  <FormLinear>
-%    ()  type :<Polymorphic>   operator :
-%   (    <Call_FormLinear> :   <FormLinear>, <v_fes **> )
-
-%
-% --const IntFunction * =  <IntFunction>
-
-% --const LinearComb<MDroit, C_F0> * =  <LinearComb<MDroit, C_F0>>
-
-% --const LinearComb<MGauche, C_F0> * =  <LinearComb<MGauche, C_F0>>
-
-% --const LinearComb<std::pair<MGauche, MDroit>, C_F0> * =  <LinearComb<std::pair<MGauche, MDroit>, C_F0>>
-
-% --const Problem * =  <Problem>
-
-% --const Solve * =  <Solve>
-
-% --const char * =  <char>
-
-% --double =  <double>
-%    <double> :   <double *>     ()  type :<Polymorphic>   operator :
-%   (    <double> :   <double>, <double>, <double> )
-
-%
-% --double * =  <double *>
-
-% --interpolate_f_X_1<double>::type =  <interpolate_f_X_1<double>::type>
-
-% --long =  <long>
-%    <long> :   <long *>
-% --long * =  <long *>
-
-% --istream * =  <istream>
-%    <istream> :   <istream **>
-% --istream ** =  <istream **>
-
-% --ostream * =  <ostream>
-%    <ostream> :   <ostream **>
-% --ostream ** =  <ostream **>
-%    <-,  type :<Polymorphic>   operator( ):
-%   (    <ostream> :   <string> )
-
-%
-% --string * =  <string>
-%    <string> :   <string **>
-% --string ** =  <string **>
-
-% --std::complex<double> =  <complex>
-%    <complex> :   <complex *>
-% --std::complex<double> * =  <complex *>
-
-% --std::ios_base::openmode =  <std::ios_base::openmode>
-
-% --std::pair<FEbase<double> *, int> =  <std::pair<FEbase<double> *, int>>
-%    (),  type :<Polymorphic>   operator :
-%   (    <double> :   <std::pair<FEbase<double> *, int>>, <double>, <double> )
-%   (    <interpolate_f_X_1<double>::type> :   <std::pair<FEbase<double> *, int>>, <E_Array> )
-
-%    [],  type :<Polymorphic>  operator. :
-%   (    <KN<double> *> :   <std::pair<FEbase<double> *, int>> )
-
-%    n,  type :<Polymorphic>   operator. :
-%   (    <long> :   <std::pair<FEbase<double> *, int>> )
-% --std::pair<FEbaseArray<double> *, int> =  <std::pair<FEbaseArray<double> *, int>>
-%    []  type :<Polymorphic>
-%   operator :
-%   (    <std::pair<FEbase<double> *, int>> :   <std::pair<FEbaseArray<double> *, int>>, <long> )
-% --std::pair<Fem2D::Mesh **, int> * =  <std::pair<Fem2D::Mesh **, int>>
-% --v_fes * =  <v_fes>
-%    <v_fes> :   <v_fes **>
-% --v_fes ** =  <v_fes **>
-
-% --void =  <void>
-%\end{verbatim}
-
-\subsection{All the operators}
-\begin{verbatim}
-  - CG,  type :<TypeSolveMat>
-  - Cholesky,  type :<TypeSolveMat>
-  - Crout,  type :<TypeSolveMat>
-  - GMRES,  type :<TypeSolveMat>
-  - LU,  type :<TypeSolveMat>
-  - LinearCG,  type :<Polymorphic>   operator() :
-   (    <long> :   <Polymorphic>, <KN<double> *>, <KN<double> *> )
-
-  - N,  type :<Fem2D::R3>
-  - NoUseOfWait,  type :<bool *>
-  - P,  type :<Fem2D::R3>
-  - P0,  type :<Fem2D::TypeOfFE>
-  - P1,  type :<Fem2D::TypeOfFE>
-  - P1nc,  type :<Fem2D::TypeOfFE>
-  - P2,  type :<Fem2D::TypeOfFE>
-  - RT0,  type :<Fem2D::TypeOfFE>
-  - RTmodif,  type :<Fem2D::TypeOfFE>
-  - abs,  type :<Polymorphic>  operator() :
-   (    <double> :   <double> )
-
-  - acos,  type :<Polymorphic>   operator() :
-   (    <double> :   <double> )
-
-  - acosh,  type :<Polymorphic>   operator() :
-   (    <double> :   <double> )
-
-  - adaptmesh,  type :<Polymorphic>   operator() :
-   (    <Fem2D::Mesh> :   <Fem2D::Mesh>... )
-
-  - append,  type :<std::ios_base::openmode>
-  - asin,  type :<Polymorphic>   operator() :
-   (    <double> :   <double> )
-
-  - asinh,  type :<Polymorphic>  operator() :
-   (    <double> :   <double> )
-
-  - atan,  type :<Polymorphic>   operator() :
-   (    <double> :   <double> )
-   (    <double> :   <double>, <double> )
-
-  - atan2,  type :<Polymorphic>   operator() :
-   (    <double> :   <double>, <double> )
-
-  - atanh,  type :<Polymorphic>   operator() :
-   (    <double> :   <double> )
-
-  - buildmesh,  type :<Polymorphic>   operator() :
-   (    <Fem2D::Mesh> :   <E_BorderN> )
-
-  - buildmeshborder,  type :<Polymorphic>   operator() :
-   (    <Fem2D::Mesh> :   <E_BorderN> )
-
-  - cin,  type :<istream>
-  - clock,  type :<Polymorphic>
-   (    <double> :   )
-
-  - conj,  type :<Polymorphic>   operator() :
-   (    <complex> :   <complex> )
-
-  - convect,  type :<Polymorphic>   operator() :
-   (    <double> :   <E_Array>, <double>, <double> )
-
-  - cos,  type :<Polymorphic>  operator() :
-   (    <double> :   <double> )
-   (    <complex> :   <complex> )
-
-  - cosh,  type :<Polymorphic>   operator() :
-   (    <double> :   <double> )
-   (    <complex> :   <complex> )
-
-  - cout,  type :<ostream>
-  - dumptable,  type :<Polymorphic>   operator() :
-   (    <ostream> :   <ostream> )
-
-  - dx,  type :<Polymorphic>   operator() :
-   (    <LinearComb<MDroit, C_F0>> :   <LinearComb<MDroit, C_F0>> )
-   (    <double> :   <std::pair<FEbase<double> *, int>> )
-   (    <LinearComb<MGauche, C_F0>> :   <LinearComb<MGauche, C_F0>> )
-
-  - dy,  type :<Polymorphic>   operator() :
-   (    <LinearComb<MDroit, C_F0>> :   <LinearComb<MDroit, C_F0>> )
-   (    <double> :   <std::pair<FEbase<double> *, int>> )
-   (    <LinearComb<MGauche, C_F0>> :   <LinearComb<MGauche, C_F0>> )
-
-  - endl,  type :<char>
-  - exec,  type :<Polymorphic>   operator() :
-   (    <long> :   <string> )
-
-  - exit,  type :<Polymorphic>  operator() :
-   (    <long> :   <long> )
-
-  - exp,  type :<Polymorphic>  operator() :
-   (    <double> :   <double> )
-   (    <complex> :   <complex> )
-
-  - false,  type :<bool>
-  - imag,  type :<Polymorphic>   operator() :
-   (    <double> :   <complex> )
-
-  - int1d,  type :<Polymorphic>   operator() :
-   (    <CDomainOfIntegration> :   <Fem2D::Mesh>... )
-
-  - int2d,  type :<Polymorphic>   operator() :
-   (    <CDomainOfIntegration> :   <Fem2D::Mesh>... )
-
-  - intalledges,  type :<Polymorphic>
-   operator( :
-   (    <CDomainOfIntegration> :   <Fem2D::Mesh>... )
-
-  - jump,  type :<Polymorphic>
-   operator( :
-   (    <LinearComb<MDroit, C_F0>> :   <LinearComb<MDroit, C_F0>> )
-   (    <double> :   <double> )
-   (    <complex > :   <complex > )
-   (    <LinearComb<MGauche, C_F0>> :   <LinearComb<MGauche, C_F0>> )
-
-  - label,  type :<long *>
-  - log,  type :<Polymorphic>   operator() :
-   (    <double> :   <double> )
-   (    <complex> :   <complex> )
-
-  - log10,  type :<Polymorphic>   operator() :
-   (    <double> :   <double> )
-
-  - max,  type :<Polymorphic>   operator() :
-   (    <double> :   <double>, <double> )
-   (    <long> :   <long>, <long> )
-
-  - mean,  type :<Polymorphic>
-   operator( :
-   (    <double> :   <double> )
-   (    <complex> :   <complex> )
-
-  - min,  type :<Polymorphic>  operator() :
-   (    <double> :   <double>, <double> )
-   (    <long> :   <long>, <long> )
-
-  - movemesh,  type :<Polymorphic>   operator() :
-   (    <Fem2D::Mesh> :   <Fem2D::Mesh>, <E_Array>... )
-
-  - norm,  type :<Polymorphic>
-   operator( :
-   (    <double> :   <std::complex<double>> )
-
-  - nuTriangle,  type :<long>
-  - nuEdge,  type :<long>
-  - on,  type :<Polymorphic>   operator() :
-   (    <BC_set<double>> :   <long>... )
-
-  - otherside,  type :<Polymorphic>
-   operator( :
-   (    <LinearComb<MDroit, C_F0>> :   <LinearComb<MDroit, C_F0>> )
-   (    <LinearComb<MGauche, C_F0>> :   <LinearComb<MGauche, C_F0>> )
-
-  - pi,  type :<double>
-  - plot,  type :<Polymorphic>   operator() :
-   (    <long> :  ... )
-
-  - pow,  type :<Polymorphic>   operator() :
-   (    <double> :   <double>, <double> )
-   (    <complex> :   <complex>, <complex> )
-
-  - qf1pE,  type :<Fem2D::QuadratureFormular1d>
-  - qf1pT,  type :<Fem2D::QuadratureFormular>
-  - qf1pTlump,  type :<Fem2D::QuadratureFormular>
-  - qf2pE,  type :<Fem2D::QuadratureFormular1d>
-  - qf2pT,  type :<Fem2D::QuadratureFormular>
-  - qf2pT4P1,  type :<Fem2D::QuadratureFormular>
-  - qf3pE,  type :<Fem2D::QuadratureFormular1d>
-  - qf5pT,  type :<Fem2D::QuadratureFormular>
-
-  - readmesh,  type :<Polymorphic>   operator() :
-   (    <Fem2D::Mesh> :   <string> )
-
-  - real,  type :<Polymorphic>   operator() :
-   (    <double> :   <complex> )
-
-  - region,  type :<long *>
-  - savemesh,  type :<Polymorphic>  operator() :
-   (    <Fem2D::Mesh> :   <Fem2D::Mesh>, <string>... )
-
-  - sin,  type :<Polymorphic>   operator() :
-   (    <double> :   <double> )
-   (    <complex> :   <complex> )
-
-  - sinh,  type :<Polymorphic>   operator() :
-   (    <double> :   <double> )
-   (    <complex> :   <complex> )
-
-  - sqrt,  type :<Polymorphic>   operator() :
-   (    <double> :   <double> )
-   (    <complex> :   <complex> )
-
-  - square,  type :<Polymorphic>    operator() :
-   (    <Fem2D::Mesh> :   <long>, <long> )
-   (    <Fem2D::Mesh> :   <long>, <long>, <E_Array> )
-
-  - tan,  type :<Polymorphic>   operator() :
-   (    <double> :   <double> )
-
-  - true,  type :<bool>
-  - trunc,  type :<Polymorphic>   operator() :
-   (    <Fem2D::Mesh> :   <Fem2D::Mesh>, <bool> )
-
-  - verbosity,  type :<long *>
-  - wait,  type :<bool *>
-  - x,  type :<double *>
-  - y,  type :<double *>
-  - z,  type :<double *>
-\end{verbatim}
-
-%%%\subsection{History of the software}
-%%%{\scriptsize
-%%%\inputFF{../HISTORY}
-%%%}
-
-
-
-\begin{thebibliography}{xx}
-
-\bibitem{arpack} R. B. Lehoucq, D. C. Sorensen, and C. Yang
-{\it ARPACK Users' Guide: Solution of Large-Scale Eigenvalue Problems with Implicitly Restarted Arnoldi Methods}
-SIAM,  ISBN 0-89871-407-9 //
- \url{http://www.caam.rice.edu/software/ARPACK/}
-
-\bibitem{Babuska71}
-Babbu\v{s}ka, I: Error bounds for finite element method, Numer. Math. 16, 322-333.
-
-\bibitem{freefemp} D. Bernardi, F.Hecht, K. Ohtsuka, O. Pironneau: {\it
-freefem+ documentation}, on the web at  ftp://www.freefem.org/freefemplus.
-
-\bibitem{freefem} D. Bernardi, F.Hecht, O. Pironneau, C. Prud'homme: {\it
-freefem documentation}, on the web at  http://www. freefem.fr/freefem
-
-
-\bibitem{umfpack}
-Davis, T. A:  {Algorithm 8xx: UMFPACK V4.1, an unsymmetric-pattern multifrontal method}
-TOMS,
-2003 (under submission)
- \url{ http://www.cise.ufl.edu/research/sparse/umfpack}
-
-\bibitem{George}
-George, P.L: {\it Automatic triangulation}, Wiley 1996.
-
-\bibitem{bamg}
-Hecht, F: The mesh adapting software: bamg. INRIA report 1998.
-
-\bibitem{modulef}
-Library Modulef , INRIA,
-\url{http://www.inria-rocq/modulef}
-
-\bibitem{FHcpp}
-{\sc F. Hecht.}
-\newblock { C++ Tools to construct our user-level language.}
-\newblock   Vol 36, N�, 2002 pp 809-836,  Mod\'{e}l. math et Anal Num\'{e}r.
-
-\bibitem{Lions}
-J.L. Lions, O. Pironneau:
-Parallel Algorithms for boundary value problems, Note CRAS. Dec 1998.
-Also : Superpositions for composite domains (to appear)
-
-\bibitem{Lucquin} B. Lucquin, O. Pironneau: {\it Introduction to Scientific Computing}
-Wiley 1998.
-
-\bibitem{dan-hec-2003}
-I.~Danaila, F.~Hecht, and O.~Pironneau.
-\newblock {\em Simulation num\'erique en C++}.
-\newblock Dunod, Paris, 2003.
-
-\bibitem{Necas} J. Ne\v{c}as and L/ Hlav\'{a}\v{c}ek,
-Mathematical theory of elastic and elasto-plastic bodies:
-An introduction, Elsevier, 1981.
-
-\bibitem{Ohtsuka} K. Ohtsuka, O. Pironneau and F. Hecht: Theoretical and Numerical analysis of energy release rate in 2D fracture, INFORMATION \textbf{3} (2000), 303--315.
-
-\bibitem{Preparata} F. Preparata, M. Shamos; {\it Computational Geometry}
-Springer series in Computer sciences, 1984.
-
-\bibitem{Franca}R. Rannacher: On Chorin's projection method for the incompressible
-Navier-Stokes equations, in "Navier-Stokes Equations: Theory and Numerical Methods" (R.
-Rautmann, et al., eds.), Proc. Oberwolfach Conf., August 19-23, 1991, Springer, 1992
-
-\bibitem{RT93}
-Roberts, J.E. and Thomas J.-M: Mixed and Hybrid Methods, Handbook of Numerical Anaysis, Vol.II, North-Holland, 1993
-
-\bibitem{Steger} J.L. Steger: The Chimera method of flow simulation,
-Workshop on applied CFD, Univ of Tennessee Space Institute, August 1991.
-
-\bibitem{TA94}
-Tabata, M: Numerical solutions of partial differential equations II
-(in Japanese),
-Iwanami Applied Math., 1994
-
-\bibitem{Thomasset}
-Thomasset, F: Implementation of finite element methods
-of Navier-Stokes Equations, Springer-Verlag, 1981
-
-\bibitem{wirth} {\sc N. Wirth:} {\it Algorthims + Data Structures = Programs}, Prentice Hall,  1976
-
-
-\bibitem{Bison}  Bison documentation
-
-\bibitem{cpp}
-Bjarne Stroustrup:
-The \Cpp, programming language, Third edition,
-  Addison-Wesley 1997.
-
-\bibitem{coool} COOOL: a package of tools for writing optimization code and solving optimization problems,
-
-\bibitem{DGgirault}  B. Riviere, M.   Wheeler, V. Girault,
-A priori error estimates for finite element
- methods based on discontinuous approximation spaces
- for elliptic problems.
-  SIAM J. Numer. Anal. 39 (2001), no. 3, 902--931 (electronic).
-
-\bibitem{ItoKunisch}{\sc Kazufumi Ito,  and Karl Kunisch},
-Semi smooth newton methods for variational inequalities of the first kind ,
-M2AN, vol 37, N${}^{\circ}$, 2003, pp 41-62.
-
-\bibitem{COOLL} COOL package , \url{http://coool.mines.edu}
-
-\bibitem{0501496} {\sc M. A. Taylor,  B. A.
-Wingate  , L. P. Bos},  Several new quadrature formulas for polynomial integration in the triangle , Report-no: SAND2005-0034J,
- \url{http://xyz.lanl.gov/format/math.NA/0501496}
-\end{thebibliography}
-\printindex
-\end{document}
+%&LaTeX
+\documentclass[a4paper,twoside,12pt]{book}
+\usepackage{styles}
+\def\key#1{\emph{#1}\index{#1}}
+\def\vec#1{\mbox{\boldmath $#1$}}
+\def\C{\mathbb{C}}
+\def\Z{\mathbb{Z}}
+\def\N{\mathbb{N}}
+
+\def\setS#1{#1\label{sec:#1}}
+\def\refSec#1{Section \ref{sec:#1}}
+\def\refChap#1{Chapter \ref{sec:#1}}
+\def\borderarray#1#2#3#4#5#6{%
+\setbox0\hbox{$\begin{array}{#5}#6\end{array}$}
+\setlength{\dimen1}{\wd0}\addtolength{\dimen1}{-#3}\addtolength{\dimen1}{-\arraycolsep}
+\setlength{\dimen2}{\ht0}\addtolength{\dimen2}{-#4}
+\setbox1\hbox{$\left#1\rule{\dimen1}{0pt}\rule{0pt}{\dimen2}\right#2$}
+\setbox0\hbox{\raisebox{\dp0}{\box0}\kern-\dimen1\kern-5pt\raisebox{\dp1}{\box1}}
+\vcenter{\box0}
+}
+
+\title{
+%\DeclareFixedFont{\TitreFont}{\encodingdefault}{pnc}{r}{\shapedefault}{70pt}
+ {\Blue{ \TitreFont FreeFem++ \\ \vglue 1cm  Manual}} \\ \vglue 3cm  ~ \\
+      \normalsize  { version 1.46-1  \Red{(Under construction)} }
+ \\ \vglue 0.7cm
+ \large \url{http://www.freefem.org} \\
+\url{http://www.freefem.org/ff++/index.htm}
+}
+\author{F. Hecht \thanks{\url{mailto:hecht at ann.jussieu.fr}},
+ O. Pironneau \thanks{\url{mailto:pironneau at ann.jussieu.fr}},
+\\ Universit\'{e} Pierre et Marie Curie,
+\\  Laboratoire Jacques-Louis Lions,
+\\175 rue du Chevaleret ,PARIS XIII
+\\ ~ \\  K. Ohtsuka  \thanks{\url{mailto:ohtsuka at barnard.cs.hkg.ac.jp}}, \\
+Hiroshima Kokusai Gakuin University, Hiroshima, Japan
+}
+\makeindex
+\begin{document}
+\graphicspath{{./}{plots/}{figures/}}
+\ifpdf
+\DeclareGraphicsExtensions{.pdf ,.jpg , .tif}
+\else
+\DeclareGraphicsExtensions{.eps ,.ps ,.jpg}
+\fi
+
+\maketitle
+
+\tableofcontents
+\let\subsubsection\subsection
+\let\subsection\section
+\let\section\chapter
+\section{Introduction}
+A partial differential equation is a relation between a function
+of several variables and its (partial) derivatives.
+ Many problems in physics, engineering, mathematics and even banking
+are modeled by one or several partial differential equations.
+\\\\
+
+\texttt{Freefem} is a software to solve these equations numerically.
+As its name says, it is a free software (see copyright for full detail)
+based  on the Finite
+Element Method. This software runs on all unix OS (with g++ 2.95.2 or
+better and X11R6) , on Window95, 98, 2000, NT, XP,  on MacOS 9 and
+X.  \\\\
+Many phenomena involve several different fields.  Fluid-structure
+interactions, Lorenz forces in liquid aluminium and ocean-atmosphere
+problems are three such systems. These require approximations of
+different degrees, possibly on different meshes.  Some algorithms such
+as Schwarz' domain decomposition method also require data
+interpolation on different meshes within one
+program. \texttt{freefem++} can handle these difficulties, i.e. {\it
+arbitrary finite element spaces on arbitrary unstructured and adapted
+meshes}.  \\\\
+
+The characteristics of \freefempp are:
+\begin{itemize}
+\item A large variety of finite elements : linear and quadratic
+ Lagrangian elements, discontinuous P1 and Raviart-Thomas elements,
+ elements of a non-scalar type, mini-element, ...
+\item  Automatic interpolation of data on different meshes to an over mesh, store the interpolation matrix.
+%
+\item Linear problems description (real or complex) thanks to a formal variational form,
+with access to the vectors and the matrix if needed.
+%
+\item Includes tools to define discontinuous Galerkin formulations
+(please refer to the following keywords: ``jump'', ``average'',
+``intalledges'').
+%
+\item Analytic description of boundaries. When two boundaries
+intersect, the user must specify the intersection points.
+%
+\item Automatic mesh generator, based on the Delaunay-Vorono\"{i}
+algorithm. Inner points density is proportional to the density of
+points on the boundary \cite{George}.
+%
+\item Metric-based anisotropic mesh adaptation. The metric can be
+computed automatically from the Hessien of a solution \cite{bamg}.
+%
+%\item Every variable is typed. For instance \texttt{f} is a function, specified
+%by the keyword \texttt{func}.
+%
+\item Solvers : LU, Cholesky, Crout, CG, GMRES, UMFPACK linear solver,
+eigenvalue and eigenvector computation.
+%
+\item Online graphics, C++-like syntax.
+%
+\item Many examples: Navier-Stokes, elasticity, Fluid structure,
+Schwarz's domain decomposition method, Eigen value problem, residual
+error indicator, ...
+%
+\item Parallel version using \texttt{mpi}
+\end{itemize}
+
+
+\subsection{History}
+
+The project has evolved from \texttt{MacFem, PCfem}, written in
+Pascal. The first C version was \texttt{freefem 3.4}; it offered mesh
+adaptation on a single mesh.  A thorough rewriting in C++ led to
+\texttt{freefem+ 1.2.10}, which also included interpolation over
+multiple meshes (functions defined on one mesh can be used on any
+other mesh).  Implementing the interpolation from one unstructured
+mesh to another was not easy because it had to be fast and
+non-diffusive; for each point, one had to find the containing
+triangle. This is one of the basic problems of computational geometry
+(see Preparata \& Shamos\cite{Preparata} for example). Doing it in a
+minimum number of operations was a challenge.  Our implementation was
+$O(n\log n)$ and based on a quadtree.  \\\\
+
+We are now introducing \freefempp, an entirely new program written
+in C++ and based on \texttt{bison} for a more adaptable
+freefem language.
+\\\\
+
+The freefem language allows for a quick specification of any partial
+differential system of equations.  The language syntax of \freefempp
+is the result of a new design which makes use of the STL \cite{cpp},
+templates and \texttt{bison} for its implementation,
+ for more detail see \cite{FHcpp}.
+  The outcome is a
+versatile software in which any new finite element can be included in
+a few hours; but a recompilation is then necessary.  The library of
+finite elements available in \freefempp will therefore grow with the
+version number.  So far we have linear and quadratic Lagrangian
+elements, discontinuous P1 and Raviart-Thomas elements.
+
+\subsection{Getting Started}
+\label{sec:example}
+
+We explain how \freefempp solve the problem \textbf{Poisson};
+For a given function $f(x,y)$, find a function $u(x,y)$ satisfying
+\begin{eqnarray}
+\label{eqn:Poisson}
+-\Delta u(x,y) &=& f(x,y)\quad \mbox{if $(x,y)$ is in }\Omega,
+\qquad \Delta u = \partial^2 u/\partial x^2 + \partial^2 u/\partial y^2,\\
+\label{eqn:Dirichlet}
+u(x,y) &=& 0\quad \mbox{if $(x,y)$ is on }\partial\Omega
+\end{eqnarray}
+The following example shows \freefempp program solving $u$ when
+$f(x,y)=xy$ (see 5th line) and $\Omega$ is the unit disk. The boundary $C=\partial\Omega$ is
+$$
+C=\{(x,y)|\; x=\cos(t),\, y=\sin(t),\, 0\le t\le 2\pi\}
+\quad \textrm{(see 1st line)}
+$$
+The domain will
+be on the left side of the oriented boundary by the parameter $t$.
+As illustrated in Fig. \ref{firstU}, we can see the isovalue of $u$ by using \ttCC{@plot} (see 13th line).
+\twoplot[height=5cm]{firstTh}{firstU}{mesh \ttCC{Th} by \ttCC{build(C(50))}}{isovalue by \ttCC{plot(u)}}
+
+\begin{example}\label{exm:first}~
+\bFF
+ 1: @border C(t=0,2*@pi){@x=cos(t); @y=sin(t);label=1;}
+ 2: @mesh Th = @buildmesh (C(50));
+ 3; @fespace Vh(Th, at P2);
+ 4: Vh u,v;
+ 5: @func f= x*y;
+ 6: @problem Poisson(u,v, at solver=LU) =
+ 7:    @int2d(Th)(@dx(u)*@dx(v) + @dy(u)*@dy(v))   //  bilinear part
+ 8:    - @int2d(Th)( f*v)          // right hand side
+ 9:    + @on(1,u=0)  ;  // Dirichlet boundary condition
+10:
+11: @real cpu=clock();
+12: Poisson; // SOLVE THE PDE
+13: @plot(u);
+14: @cout << " CPU time = " << clock()-cpu << @endl;
+\eFF
+\end{example}
+
+\subsubsection{FEM by \freefempp}
+The example shows \freefempp covers  easily all standard step in FEM (finite element method).
+We explain how they are done by \freefempp in a step-by-step manner.\\
+
+\textbf{Step1: Mesh Generation}\\
+
+\textbf{1st line:} the boundary $\Gamma$ are described analytically (by opposition to CSG)
+as stated before.
+In the case $\Gamma=\sum_{j=0}^J \Gamma_j$ with curves $\Gamma_j$, then
+the user must specify the
+intersection points in case two boundaries intersect.
+By the use of the keyword ``label'' such as
+\bT
+ at border Gamma1(t=a1,b1) { x=$\cdots$; y=$\cdots$ ;label=1; }
+ $\vdots$        $\vdots$           $\vdots$      $\vdots$
+ at border GammaJ(t=aJ,bJ) { x=$\cdots$; y=$\cdots$;label=1; }
+\eT
+the user can refer to $\Gamma$  by the number ``1''.
+(examples are in \refSec{Meshing Examples}).
+
+\textbf{2nd line:} the triangulation $\mathcal{T}_h$ of $\Omega$ is
+automatically generated  by
+``\ttCC{@buildmesh}(C(50))'' giving 50 points on $C$ as in Fig. \ref{firstTh}.
+Automatic mesh generation is based on the Delaunay-Voronoi algorithm.
+Refinement of the mesh are done by increasing the points on $\Gamma$,
+for example, ``\ttCC{@buildmesh}(C(100))'', because inner vertices are
+determined by the density of points on the boundary.
+
+The symbol $\mathcal{T}_h$ (\texttt{Th} in \freefempp) shows
+a family $\{T_k\}_{k=1,\cdots,n_t}$ of triangles in Fig. \ref{firstTh}
+with the size $h$ of the mesh.
+Here $n_t$ stands for the number of
+triangules in $\mathcal{T}_h$.
+If $\Omega$ is not polygonal domain, a ``skin'' remains between
+the exact domain $\Omega$ and its approximation
+$\Omega_h=\cup_{k=1}^{n_t}T_k$.
+However, we notice that all corners of $\Gamma_h = \partial\Omega_h$ are
+on $\Gamma$.\\
+
+\textbf{Step2: Making finite element space}\\
+
+\textbf{3rd line:} ``\ttCC{@fespace} Vh(Th,P2)'' makes the continuous Finite Element SPACE
+\begin{equation}
+V_h(\mathcal{T}_h,P_2)=\left\{w(x,y)\left|\;
+w(x,y)=\sum_{k=0}^{M-1}w_k\phi_k(x,y),\, w_k\textrm{ are real numbers}\right.\right\}
+\end{equation}
+where $P_2$ indicate $\phi_k$ is a polynomial of degree $\le 2$, that is,
+in each $T_k$,
+$$
+\phi_k(x,y)=\alpha_1+\alpha_2x+\alpha_3y+\alpha_4x^2+\alpha_5xy+\alpha_6y^2
+$$
+and the constants $\alpha_1,\,\cdots,\, \alpha_6$ are defined by its values
+at the vertices of $T_k$ and their middle points that continuous in $\Omega$.
+Here $w_k$ are called the degree of freedom of $w$ and $M$ the number of
+the degree of freedom.
+Already \freefempp implemented
+P0, P1, P2, RT0, P1nc, P1dc, P2dc, P1b, P2b elements, .
+The user can easily add a part of arbitrary degree elements to \freefempp,
+so the available finite elements will differ with the version.\\
+
+\textbf{Step3: Setting the problem}\\
+
+\textbf{4th line:} ``\texttt{Vh u}'' declare that $u$ is approximated
+through the use of the basis functions $\phi_k$ in $V_h$, that is,
+\begin{equation*}
+u(x,y)\simeq u_h(x,y)=\sum_{k=0}^{M-1} u_k\phi_k(x,y)
+\end{equation*}
+\textbf{5th line:} the given function $f$ is defined analytically using the keyword
+\ttCC{@func}.
+
+\textbf{6th--9th lines:} the formulation of (\ref{eqn:Poisson}) and
+(\ref{eqn:Dirichlet}) are done.
+
+Multiplying (\ref{eqn:Poisson}) by $v(x,y)$ and integrating
+the result over $\Omega$, we have
+$$
+-\int_{\Omega}v\Delta u \,dxdy = \int_{\Omega} vf\, dxdy
+$$
+Then, by Green's formula, the problem Poisson is translated into finding $u$
+such that
+\begin{eqnarray}
+\label{eqn:weakform}
+&&a(u,v) - \ell(f,v) = 0
+\qquad \textrm{for all }v\\
+&&a(u,v)=\int_{\Omega}\nabla u\cdot \nabla v \,dxdy
+\quad \ell(f,v)=\int_{\Omega}fv\, dxdy
+\label{eqn:bilinear}
+\end{eqnarray}
+satisfying $v=0$ on $\partial\Omega$. In \freefempp
+the problem \textbf{Poisson} is declared by
+\begin{center}
+\ttCC{Vh u,v; @problem Poisson(u,v) =}
+\end{center}
+and (\ref{eqn:weakform}) is expressed by symbols \ttCC{@dx}(u) $=\partial u/\partial x$, \ttCC{@dy}(u) $=\partial u/\partial y$ and
+\begin{eqnarray*}
+&&\int_{\Omega}\nabla u\cdot \nabla v\, dxdy \longrightarrow
+\ttCC{@int at 2d(Th)( @dx(u)*@dx(v) + @dy(u)*@dy(v) )}\\
+&&\int_{\Omega}fv\, dxdy \longrightarrow
+\ttCC{@int at 2d(Th)( f*v )}\qquad
+\textrm{(notice here, $u$ is unused)}\\
+\end{eqnarray*}
+In \freefempp the first and second formulas just above must be distinguished each other.
+Because, the linear system to be solved are created from substituting $u_h$ for $u$ and $\phi_i$ for $v$ in (\ref{eqn:weakform}),
+\begin{eqnarray}
+\label{eqn:Equation}
+A_{ij}u_j - F_i=0\quad i,j=0,\cdots,M-1;\qquad
+F_i=\int_{\Omega}f\phi_i\, dxdy
+\end{eqnarray}
+and the solution $u_h=\sum_{j=0}^{M-1}u_j\phi_j$  must
+satisfy ``$u_h=0$ on $\Gamma_h\simeq C$''.
+The matrix $A=(A_{ij})$ is called \emph{stiffness matrix}
+\index{matrix!stiffness matrix} and is modified from
+\begin{eqnarray}
+\label{eqn:Stiffness0}
+A^0=\{A^0_{ij}\},\, A^0_{ij}=\int_{\Omega}\nabla \phi_j\cdot \nabla \phi_i \,dxdy\quad i.j=0,\cdots,M-1
+\end{eqnarray}
+to ensure $u=0$ on $C$ by ``+\ttCC{@on}\{1,u=0\}'' in 9th line.
+If you want use the symbol ``C'' such as ``+\ttCC{@on}\{C,u=0\}'' (9th line),
+then \emph{the user do not use the keyword ``label''}.
+
+we can create directly the stiffness matrix $A$ in
+(\ref{eqn:Equation}) by
+\bT
+ at varf a(u,v) = @int2d(Th)( @dx(u)*@dx(v) + @dy(u)*@dy(v))
+               + @on(C,u=0) ;
+ at matrix A=a(Vh,Vh);  // stiffness matrix, see (\ref{eqn:Stiffness0})
+\eT
+(see Example \ref{exm:second}).
+The vector $B$ in (\ref{eqn:Equation}) is called \emph{load matrix}
+\index{matrix!load matrix}, and also we get it:
+\bT
+ at varf b([v],[f]) = @int2d(Th)(v*f);
+ at matrix B=b(Vh,Vh);
+\eT
+
+The linear system (\ref{eqn:Equation}) is solved by a Gauss LU
+factorization. You can declare the solver of (\ref{eqn:Equation}),
+for example,
+\begin{center}
+\ttCC{Vh u,v; @problem Poisson(u,v, at solver=CG) =}
+\end{center}
+means that (\ref{eqn:Equation}) will be solved by Conjugate Gradient method.\\
+
+\textbf{Step4: Solving and visualization}\\
+
+\textbf{11th line:} the current time is stored into the real-valued variable \ttCC{cpu}.
+
+\textbf{12th line:} the problem is solved by calling its name.
+
+\textbf{13th line:} the visualization is done as illustrated in Fig. \ref{firstU}
+(see \refSec{Plot} for zoom, postscript and other commands).
+
+\textbf{14th line:} the time in calculation is outputed into your console
+(= default of standard output) using C++-like syntax.
+The user need not study C++ for using \freefempp, because
+C++-like syntax is used for input/output, loops, flow-controls etc.
+
+\subsubsection{Features of \freefempp}
+
+The language it
+defines is typed, polymorphic and reentrant with macro generation (see
+\ref{macro}).  Every variable must be typed and declared in a
+statement; each statement separated from the next by a semicolon
+`\texttt{;}'.
+
+For purposes of explanation, we used $\mathcal{T}_h$ (\texttt{Th}),\, $V_h$ (\texttt{Vh}), unknown function $u$ (\texttt{u}), test functions $v$ (\texttt{v}) and the problem \textbf{Poisson}, etc. (the term inside the parentheses are symbols in \freefempp programming), but
+you can use \emph{any name except reserved words and names already used}.
+Reserved words are shown in blue. \texttt{pi, x, y, label, solver} are
+reserved variables. It is allowed (although not advisable) to redefine
+these variables, so they will not be highlighted again in the
+following example programs.\\\\
+
+In each step, the independence in \freefempp programming is very high
+as stated below.
+\begin{itemize}
+  \item
+  For example, by changing 1st and 2nd lines as
+  following, we can solve (\ref{eqn:Poisson}) and (\ref{eqn:Dirichlet})
+  in L-shape domain with $\Gamma=\sum_{j=1}^6\Gamma_j$.
+\bT
+ at border G1(t=0,1){x=t;y=0;@label=1;}  // $\Gamma_1$
+ at border G2(t=0,0.5){x=1;y=t;@label=1;}  // $\Gamma_2$
+ at border G3(t=0,0.5){x=1-t;y=0.5;@label=1;}  // $\Gamma_3$
+ at border G4(t=0.5,1){x=0.5;y=t;@label=1;}  // $\Gamma_4$
+ at border G5(t=0.5,1){x=1-t;y=1;@label=1;}  // $\Gamma_5$
+ at border G6(t=0,1){x=0;y=1-t;@label=1;}  // $\Gamma_6$
+ at mesh Th = @buildmesh ( G1(6)+G2(4)+G3(4)+G4(4)+G5(4)+G6(6));
+\eT
+  \item
+  In Step 3, you can control where the solution will be approximated.
+  If you write ``\texttt{Vh(Th,P1);}'' in 3rd line, you can get $P_1$-approximation. The machine time by $P_1$-element will be faster than $P_2$-element
+  and the storage is less.
+  \item
+  In Step 4, you can change the equation and boundary conditions easily.
+  For example, if you want solve
+  \begin{eqnarray*}
+  -\textrm{div}(k(x,y)\nabla u(x,y))&=&f(x,y)\quad\textrm{in }\Omega\\
+  u(x,y)&=&0\qquad \textrm{if $(x,y)$ on }\Gamma
+  \end{eqnarray*}
+  you only write as follows
+  \bT
+  @func f= $\cdots$;
+  @func k= 1+sin(2*pi*x)*cos(2*pi*y);
+  @problem Poisson(u,v) =
+     @int2d(Th)(k*(@dx(u)*@dx(v) + @dy(u)*@dy(v)))
+     - @int2d(Th)( f*v)
+     + @on(1,u=0)  ;
+  \eT
+  \emph{The user can use FE-function as the given function $f$ } (see \refSec{FE-function}), for example, obtained function \texttt{u} in Example \ref{exm:first}.
+  In \freefempp programming, the easy reuse of the obtained results
+  is important feature.
+  \item
+  The user can easily compare between mathematical modelling and \freefempp program.
+\end{itemize}
+
+\subsection{Projection or Interpolation}
+\index{P1-projection}
+For a finite element space $V_h$, $P_1$-projection $\Pi_h$ is defined by
+\[
+\Pi_h f=f(q^1)\phi_1+f(q^2)\phi_2+\cdots +f(q^{n_v})\phi_{n_v}
+\]
+for all continuous functions $f$. In \freefempp we can easily create the
+projection $f_h(=\texttt{fh})$ by
+\bT
+Vh fh = $f(x,y)$;
+\eT
+$\Pi_h$ is also called $P_1$-interpolate.
+
+\subsection{\setS{Matrix and Vector}}
+Here, we show how to get the stiffness matrix using \freefempp
+The first command \texttt{varf} is to define the \key{variational formula}.
+\begin{example}\label{exm:second}
+Here we solve the same problem (\ref{eqn:Poisson}) and (\ref{eqn:Dirichlet})
+using matrix.
+For purposes of explanation, we chage mesh size and use $P_1$-element:
+\bT
+ 1: @border C(t=0,2*pi) { x = cos(t); y = sin(t); }
+ 2: @mesh Th = @buildmesh(C(7));  // changed from Example \ref{exm:first}
+ 3: @fespace Vh(Th,P1);
+ 4: Vh u,v,f,F;
+ 5: @varf a(u,v) = @int2d(Th)( @dx(u)*@dx(v) + @dy(u)*@dy(v))
+ 6:             + @on(C,u=0) ; // see (\ref{eqn:Stiffness0})
+ 7: @varf b([v],[f]) = @int2d(Th)(v*f);
+ 8:
+ 9: f = x*y;  // interpolate $(x,y) \longleftarrow x*y$ function
+10: @matrix A=a(Vh,Vh);  // stiffness matrix, see (\ref{eqn:Equation})
+11: @matrix B=b(Vh,Vh);
+12: F[]=B*f[];     // load vector, see (\ref{eqn:Equation})
+13: @cout << "F=" << F[] << @endl;
+14: @cout <<"A="<< A << @endl;
+15: u[]=A^-1*F[];  // solve $A\vec{U}_h = \vec{F}$, see (\ref{eqn:Equation})
+16: @plot(u);
+\eT
+
+We get the mesh $\mathcal{T}_h=\{T_1,\cdots,T_7\}$ (see Fig. \ref{fig:secondTh}).
+\begin{note}
+\label{note:mesh}
+In what follows, we denote the vertices by $q^i,\, i=1,\cdots,8$,
+the number of vertices by $n_v$, the number of triangles by $n_t$.
+For each triangle $T_k\in \mathcal{T}_h$, we index the vertices by
+$q^{k_1},\, q^{k_2},\, q^{k_3}$ and denote the edges by
+$[q^{k_1}, q^{k_2}]$, $[q^{k_2}, q^{k_3}]$, $[q^{k_3}, q^{k_i}]$, that is,
+$[q^i,q^j]$ is the segment connecting $q^i$ and $q^j$.
+We denote the number of edges $[q^i,q^j]$
+by $n_e$ for all $q^i,\, q^j\partial\Omega_h$,
+$\Omega_h=\sum_{k=1}^7T_k$.
+Here $n_v=8$, $n_t=7$, $n_e=7$.
+\end{note}
+\begin{figure}[htbp]
+\begin{minipage}{\textwidth}
+\begin{minipage}{0.3\textwidth}
+\includegraphics[width=\textwidth]{secondT}%
+\caption{mesh \texttt{Th}}
+\label{fig:secondTh}
+\end{minipage}
+\hspace{0.5mm}
+\begin{minipage}{0.7\textwidth}
+\includegraphics[width=\textwidth]{hat}%
+\caption{Graph of $\phi_1$ (left hand side) and $\phi_6$}
+\label{fig:hatFunction}
+\end{minipage}
+\end{minipage}
+\end{figure}
+
+
+The function $v$ in ``\texttt{Vh}'' is expressed
+\begin{equation*}
+v(x)=v_{1}\varphi _{1}(x) +\cdots +v_{n_{v}}\varphi _{n_{v}}(x)
+\end{equation*}%
+using the \key{hat functions} $\varphi _{j},\,j=1,\cdots ,n_{v}$ (see Fig.
+\ref{fig:hatFunction}).
+Here the $j$-th hat function $\varphi _{j}$ associated with $j$-th
+vertex $q^j$ is defined in the following way:
+\begin{enumerate}
+\item $\varphi _{j}$ is continuous function on $\Omega_h$.
+
+\item $\varphi _{j}$ is linear on each triangle $T_k,\, k=1,\cdots,n_{t}$
+ of ``\texttt{Th}''.
+
+\item $\varphi _{j}\left( {q^{i}}\right) =\delta _{ji}$ where $q^{i}$
+denotes the $i$-th vertex, for all $i=1,\cdots ,n_{v}$.
+\end{enumerate}
+Here $\delta_{ij}$ is the Kronecker symbol.
+
+\begin{note}
+Other finite element spaces in \freefempp are explained in \refSec{Finite Elements}.
+\end{note}
+\begin{note}
+\label{note:FE2VEC}
+For an element $v=v_1\phi_1+\cdots+v_M\phi_M$ in
+a finite element space $V_h$, we get the \emph{column vector}
+$\{v\}$
+\[
+\{v\}=\left[
+\begin{array}{c}
+v_1\\
+\vdots\\
+v_M
+\end{array}
+\right]\qquad
+\{v\}=\texttt{v[]}\quad \textrm{in \freefempp}
+\]
+\end{note}
+Theoretically, it is natural to use the finite element space
+\[
+H^1_{0h}=
+\left\{v\in V_h(\mathcal{T}_h,P_1)\left|
+\phi_i(x)=0\quad \textrm{if }q^i\in \partial\Omega_h
+\right.\right\}
+\]
+Let $I_{\Omega}$ be the set of indices $i$ of all internal vertices of the mesh
+\texttt{Vh}. In this example, $I_{\Omega}=\{6\}$.
+The stiffness matrix $A$ in 10th line is:
+\begin{eqnarray}
+\label{eqn:StiffnessDirichlet}
+\borderarray{[}{]}{1em}{1.2ex}{rrrrrrrrr}{
+&1&2&3&4&5&6&7&8\\
+1&10^{30}& -0.31& 0& 0&-0.46& -0.51& 0&0\\
+2&-0.31& 10^{30}& -0.23& 0& 0&-0.71& 0&0\\
+3&0&-0.23&10^{30}&-0.31& 0&-0.71& 0&0\\
+4&0& 0&-0.31&10^{30}& 0& -0.51& -0.46&0 \\
+5&-0.46& 0& 0& 0&10^{30}& -0.35& 0&-0.54\\
+6&-0.51& -0.71& -0.71& -0.51& -0.35& 3.47& -0.35& -0.30\\
+7&0& 0& 0&-0.46& &-0.35& 10^{30}& -0.54\\
+8&0& 0& 0& 0&-0.54&-0.30&-0.54& 10^{30}
+}
+\end{eqnarray}
+that is
+\begin{eqnarray}
+A_{ij}&=&\int_{\Omega_h}\nabla u_j\cdot \nabla u_i\quad
+\textrm{if }i\neq j,\, i=j\in I_{\Omega}\\
+A_{ij}&=&E\qquad (E=10^{30})\quad \textrm{if }j\in I_{\Omega}.
+\end{eqnarray}
+The load matrix $F^T$ is:
+\begin{eqnarray*}
+\left(
+\begin{array}{cccccccc}
+-0.020& -0.037& 0.037& 0.020&0.064& 0& -0.064&1.\times 10^{-17}
+\end{array}
+\right)
+\end{eqnarray*}
+For $i\not\in I_{\Omega}$,
+\[
+Eu_i+\sum_{i\neq j}A_{ij}u_j=b_i
+\]
+which means that
+\[
+u_i=(b_i-\sum_{i\neq j}A_{ij}u_j)\times E^{-1}\simeq 10^{-30}\simeq 0
+\]
+\end{example}
+
+Mathematical results indicate that the Poisson equation
+with Neaumann boundary condition has not unique solution,
+whose weak form is same to (\ref{eqn:Poisson}) except the boundary condition:
+\[
+\int_{\Omega}\nabla u\cdot \nabla v = \int_{\Omega}fvdx
+\]
+without pernarization $E$. Then the stiffness matrix is created by
+\bT
+ at varf a(u,v) = @int2d(Th)( @dx(u)*@dx(v) + @dy(u)*@dy(v))
+ at matrix A=a(Vh,Vh); // stiffness matrix
+\eT
+and the obtained stiffness matrix is the following
+\[
+\borderarray{[}{]}{1em}{1.2ex}{rrrrrrrrr}{
+&1&2&3&4&5&6&7&8\\
+1&1.29&-0.31&0&0&-0.46&-0.51&0&0\\
+2&-0.31&1.26&-0.23&0&0&-0.71&0&0\\
+3&0&-0.23&1.26&-0.31&0&-0.71&0&0\\
+4&0&0&-0.31&1.29&0&-0.51&-0.46&0\\
+5&-0.46&0&0&0&1.35&-0.35&0&-0.54\\
+6&-0.51&-0.71&-0.71&-0.51&-0.35&3.47&-0.35&-0.30\\
+7&0&0&0&-0.46&0&-0.35&1.35&-0.54\\
+8&0&0&0&0&-0.54&-0.30&-0.54&1.38
+}
+\]
+The determinant of this matrix is $-1.7082274230870981\times 10^{-9}\approx 0$
+(The matrix here differ from original one by omitting from third decimal decimal point).
+
+\subsubsection{Non-homogeneous Dirichlet Condition}
+If we want solve the problem
+\[
+-\Delta u=f\quad \textrm{in }\Omega;\qquad
+u=g\quad \textrm{on }\partial\Omega
+\]
+We rewrite Example \ref{exm:first} as
+\bT
+ 5: @func f= x*y; @func g = sin(pi*x)*cos(pi*y);
+ 6: @problem Poisson(u,v, at solver=LU) =
+ 7:    @int2d(Th)(@dx(u)*@dx(v) + @dy(u)*@dy(v))   //  bilinear part
+ 8:    - @int2d(Th)( f*v)          // right hand side
+ 9:    + @on(1,u=g)  ;  // Non-homogeneous Dirichlet
+\eT
+This make the following linear system, for $i\not\in I_{\Omega}$,
+\[
+Eu_i+\sum_{i\neq j}A_{ij}u_j=b_i+Eg(q^i)
+\]
+which means that
+\[
+u_i=g(q^i)+(b_i-\sum_{i\neq j}A_{ij}u_j)\times E^{-1}\simeq g(q^i)+O(1/E)
+\]
+\begin{note}
+To solve non-homogeneous Dirichlet, we rewrite Example \ref{exm:second} as
+\bT
+ 4: Vh u,v,f,F,g,bc; g = sin(pi*x)*cos(pi*y);
+ 5: @varf a(u,v) = @int2d(Th)( @dx(u)*@dx(v) + @dy(u)*@dy(v))
+ 6:             + @on(C,u=1) ; // see (\ref{eqn:Stiffness0})
+10: @matrix A=a(Vh,Vh); bc[]=a(0,Vh);
+12: F[]=B*f[];  F[] += bc[] .* g[];
+\eT
+Here ``\texttt{bc[]=a(0,Vh)}'' create the vector
+$[bc_1,bc_2,\cdots,bc_M]$, $bc_i=0$ if $i\in I_{\Omega}$ and
+$bc_i=E (=10^{30})$ if $i\not\in I_{\Omega}$.
+If the finite approximation of $g$ is $g\approx g_1\phi_1+\cdots+g_M\phi_M$
+\begin{equation}
+\texttt{bc[] .* g[]}=\sum_{j=0}^{M-1} bc_jg_j
+\end{equation}
+\end{note}
+
+\subsubsection{\setS{Matrix Operations}}
+
+The multiplicative operators *, /, and \% group left to right.
+
+\begin{itemize}
+\item  \verb@'@  is unary right transposition of array, matrix \index{transpose}
+ \item \verb at .*@ is the term to term multiply operator. \index{.*} \index{\string'} \index{divide!term to term}
+ \item \verb at ./@ is the term to term divide operator. \index{./} \index{\string'} \index{product!term to term}
+\end{itemize}
+there are some compound operator:
+\begin{itemize}
+ \item \verb@^-1@ is for  solving the linear system (example: \verb$ b = A^-1 x$) \index{solve!linear system}
+ \item \verb@' *@ is the compound  of transposition and matrix product, so it is the dot product
+(example \verb$real DotProduct=a'*b$) \index{dot product}\index{product!dot}
+\end{itemize}
+\begin{example}~
+\bFF
+ at mesh Th = @square(2,1);
+ at fespace Vh(Th,P1);
+Vh f,g;
+f = x*y;
+g = sin(pi*x);
+Vh<complex> ff,gg; // a complex valued finite element function \index{FE function!complex}
+ff= x*(y+1i);
+gg = exp(pi*x*i);
+ at varf mat(u,v) =
+  int2d(Th)(1*dx(u)*dx(v)+2*dx(u)*dy(v)+3*dy(u)*dx(v)+4*dy(u)*dy(v))
+  + on(1,2,3,4,u=1);
+ at varf mati(u,v) =
+  int2d(Th)(1*dx(u)*dx(v)+2i*dx(u)*dy(v)+3*dy(u)*dx(v)+4*dy(u)*dy(v))
+  + on(1,2,3,4,u=1);
+ at matrix A = mat(Vh,Vh); @matrix<complex> AA = mati(Vh,Vh); // a
+complex sparse matrix \index{matrix:complex}
+
+Vh m0; m0[] = A*f[];
+Vh m01; m01[] = A'*f[];
+Vh m1; m1[] = f[].*g[];
+Vh m2; m2[] = f[]./g[];
+ at cout << "f = " << f[] << @endl;
+ at cout << "g = " << g[] << @endl;
+ at cout << "A = " << A << @endl;
+ at cout << "m0 = " << m0[] << @endl;
+ at cout << "m01 = " << m01[] << @endl;
+ at cout << "m1 = "<< m1[] << @endl;
+ at cout << "m2 = "<< m2[] << @endl;
+ at cout << "dot Product = "<< f[]'*g[] << @endl;
+ at cout << "hermitien Product = "<< ff[]'*gg[] << @endl;
+\eFF
+This produce the following:
+\begin{eqnarray*}
+A&=&\borderarray{[}{]}{1em}{1.2ex}{rrrrrrrr}{
+&1&2&3&4&5&6\\
+1&10^{30}& 1 0.5& 0&3 0.& 4 -2.5& 0\\
+2&0.&10^{30}&0.5& 0&0.5&-2.5\\
+3&0&0.&10^{30}& 0& 0&0.5\\
+4&0.5& 0& 0& 10^{30}& 0.& 0\\
+5&-2.5&0.5& 0&0.5&10^{30}&0.\\
+6&0&-2.5&0.& 0&0.5& 10^{30}
+}
+\\
+\{v\}=\texttt{f[]}&=&
+\left(
+\begin{array}{rrrrrr}
+0 & 0 & 0 & 0 & 0.5 & 1
+\end{array}
+\right)^T\\
+\{w\}=\texttt{g[]}&=&
+\left(
+\begin{array}{rrrrrr}
+0 &1  &1.2\times 10^{-16}& 0 & 1 & 1.2\times 10^{-16}
+\end{array}
+\right)^T\\
+\texttt{A*f[]}&=&
+\left(
+\begin{array}{rrrrrr}
+-1.25 &  -2.25 &  0.5   & 0 & 5\times 10^{29} & 10^{30}
+\end{array}
+\right)^T\quad (=A\{v\})\\
+\texttt{A'*f[]}&=&
+\left(
+\begin{array}{rrrrrr}
+-1.25 &  -2.25 &  0  & 0.25 & 5\times 10^{29} & 10^{30}
+\end{array}
+\right)^T\quad (=A^T\{v\})\\
+\texttt{f[].*g[]}&=&
+\left(
+\begin{array}{rrrrrr}
+0 & 0 & 0 & 0 & 0.5 & 1.2\times 10^{-16}
+\end{array}
+\right)^T\quad =(v_1w_1\quad\cdots\quad v_Mw_M)^T\\
+\texttt{f[]./g[]}&=&
+\left(
+\begin{array}{rrrrrr}
+-nan & 0  & 0  & -nan  & 0.5 & 8.1\times 10^{15}
+\end{array}
+\right)^T\quad =(v_1/w_1\,\cdots\, v_M/w_M)^T\\
+\texttt{f[]'*g[]}&=&0.5\quad
+(=\{v\}\{w\}^T=\{v\}\cdot\{w\})
+\end{eqnarray*}
+\end{example}
+\begin{note}
+The operators \verb|^-1| cannot create the matrix by themselves.
+Indeed, the following occur errors
+\bT
+ at matrix AAA = A^-1;
+\eT
+\end{note}
+
+%%%  modif FH july 2005----
+\subsection{Block matrix}
+\bFF
+  matrix A=[[A11,0,B1],[0,A11,0,B1],[B1',B2',0]];
+  set(A,solver=UMFPACK); //  by default no solver is defined
+  real[int] b=[b1[],b2[],b3[]];
+  [b1[],b2[],b3[]]= A^-1*b;
+\eFF
+%%%  fin modif FH july 2005
+
+\subsection{\setS{Modeling}--Edit--Run--Visualize--Revise}
+\bigskip
+\freefempp provide many examples and its documentation, so you can easily calculate
+mathematical models by FEM (finite element method) and study them.
+Explanations for these examples are given in this book. If you are a
+beginner of FEM, you start from Quick Tour of
+\freefempp. The numerical simulation of scientific problem will be done as follows.
+
+\begin{description}
+\item[Modeling:] Make a mathematical model describing scientific problems.
+Mathematical modeling is a deep and fruitful one, with many important
+implications for scientific problems
+(refer to Chapter \ref{sec:MathModels}).
+
+\item[Programming:] Translate the mathematical model to
+\freefempp source code, which is easy because \freefempp
+includes many clever techniques in FEM with mathematical writing.
+
+\item[Run:] Next step is to run it to see if it works. If we provisionally
+give the name of the source code to ``something.edp'', we can execute it by
+the typing\newline
+\newline
+\texttt{\% freefem++ something.edp}
+
+An important part in programming is to keep aware of collections of
+programs that are available, and this manual contains many examples you
+can use freely. So we hope you to run these examples and their
+representing mathematical models, which are contained in the package in
+\freefempp.
+
+\item[Visualization:] The numerical calculation by FEM make huge data, so
+the easy way to check the obtained result is their visualization. \freefempp
+can display the mesh and the contour lines of obtained functions. If
+you want to use these visualization after execution, you add the filename of
+PostScript to the commands ``plot'' (see \refSec{Plot}).
+
+\item[Debugging:] If the boolean value of ``wait'' is true (default is `false'), then
+\freefempp will stop at the information in visual form.
+Write the following, execute it and make a change the line
+``\ttCC{@wait=@true}'' to ``\ttCC{@wait=@false}''.
+\bT
+ at bool wait = true;  // set "true" if you want see each plotting
+mesh Th = @square(10,10,[-1+2*x,-1+2*y]); // $]-1,1[^2$
+ at plot(Th);  // plot the mesh
+ at fespace Vh(Th,P2);
+Vh f = @sin(pi*x)*@cos(pi*y);
+plot(f,wait=wait);  // plot the function f
+Vh g = @sin(@pi*x + @cos(@pi*y));
+ at plot(g,wait=wait);  // plot the function g
+\eT
+If there is a fatal error in your
+source code, \freefempp will end and cause an error message to appear. In MS-Windows, \freefempp will open the message file by notepad.
+For example, if you forget parenthesis as in
+\bT
+ at mesh Th = @square(10,10;
+ at plot(Th);
+\eT
+then you will get the following message from \texttt{freefem++},
+\bT
+mesh Th = square(10,10;
+ Error line number 0, in file xxxxxx.edp, before  token ;
+parse error
+Compile error : parse error
+        line number :0, ;
+ at exec line  0
+error Compile error : parse error
+        line number :0, ;
+\eT
+If you use the same symbol twice as in
+\bT
+ at real aaa =1;
+ at real aaa;
+\eT
+then you will get the message
+\bT
+real aaa =1;
+    1 : real aaa; The identifier aaa exist
+\eT
+Notice that the line number start from 0.
+If you find that the program isn't doing what you want it
+to do, then you check the line number and try to figure out
+what's wrong.
+We give two techniques; One is \emph{trace} by \ttCC{@plot}
+for \emph{meshes} and (FE-)functions with \ttCC{@wait=@true},
+and by \ttCC{@cout} for scalar, vectors and matrices.
+Another is to \emph{comment out} by ``\ttCC{//}''.
+If you find a doubtful line in your source code, you comment out
+as follows,
+\bT
+ at real aaa =1;
+// real aaa;
+\eT
+\end{description}
+
+\bigskip
+
+\subsection{Installation}
+
+There are binary packages available for Microsoft Windows and Apple
+Mac OS. For all other platforms, \freefempp must be compiled and
+installed from the source archive. This archive is available from:
+
+\url{http://www.ann.jussieu.fr/~hecht/ftp/freefem/freefem++.tgz}.
+
+ To
+extract files from the compressed archive \texttt{freefem++.tgz} into
+a directory called \texttt{freefem++-X.XX} (where X.XX is the version number)
+enter the following commands in a shell window~:
+
+\bFF
+tar zxvf freefem++.tgz
+cd freefem++-X.XX
+\eFF
+
+To compile and install \freefempp, just follow the \texttt{INSTALL}
+and \texttt{README} files. The following programs are produced,
+depending on the system you are running (Linux, Windows, MacOS)~:
+
+\begin{enumerate}
+\item \texttt{FreeFem++}, standard version, with a graphical interface
+based on X11, Win32 or MacOS
+\item \texttt{FreeFem++-nw}, postscript plot output only (batch version, no windows)
+\item \texttt{FreeFem++-mpi}, parallel version, postscript output only
+\item \texttt{FreeFem++-glx}, graphics using OpenGL and X11
+\item \texttt{FreeFem++-cs}, integrated development environment
+(please see chapter ``Graphical User Interface'' for more details).
+\item \texttt{/Applications/FreeFem++.app}, Drag and Drop CoCoa MacOs
+Application
+\item \texttt{FreeFem++-CoCoa}, MacOS Shell script for MacOS OpenGL
+version (MacOS 10.2 or better) (note: it uses
+/Applications/FreeFem++.app)
+\end{enumerate}
+
+As an installation test, go into the directory
+\texttt{examples++-tutorial} and run \freefempp on the example script
+\texttt{LaplaceP1.edp} with the command~:
+
+\bFF
+FreeFem++ LaplaceP1.edp
+\eFF
+
+\textBlack
+\section{Syntax}
+\subsection{Data Types}
+Basically \freefempp  is a \index{compiler} compiler,
+  the language is typed, polymorphic and reentrant.
+Every variable must be typed, declared in a  statement;
+each statement separated
+from the next by a semicolon `\texttt{;}'.
+The language allows the manipulation of basic types
+integers (\texttt{int}), reals (\texttt{real}), strings (\texttt{string}),
+arrays (example: \texttt{real[int]}),
+ bidimensional (2D) finite element meshes (\texttt{mesh}),
+2D finite element spaces (\texttt{fespace}) , definition of functions
+(\texttt{func}), arrays of
+finite element functions (\texttt{func$[basic\_type]$}),
+linear and bilinear operators, sparse matrices, vectors , etc. For instance
+
+\bFF
+  @int i,n=20;               //  $ i,n$ are integer.
+  @real[@int] xx(n),yy(n);    //  two array of size n
+  @for (i=0;i<=20;i++)       // which can be used in statements such as
+   { xx[i]= cos(i*pi/10); yy[i]= sin(i*pi/10); }
+\eFF
+The life of a variable is the current block $\{\ldots \}$, except the \texttt{fespace} variable, and the in variables local to a block are destroyed at the end of the block as follows.
+\begin{example}~~
+\bT
+ at real r= 0.01;
+ at mesh Th=@square(10,10); // unit square mesh
+ at fespace Vh(Th, at P1);     // P1 lagrange finite  element space
+Vh u = x+ exp(y);
+ at func f = z * x + r * log(y);
+ at plot(u,wait=true);
+{  // new block
+  @real r = 2; // not the same r
+  @fespace Vh(Th, at P1);//  error because Vh is a global name
+}  // end of block
+//  here r back to 0.01
+\eT
+\end{example}
+The type declarations are  compulsory in \freefempp  because it is easy
+to make bugs in a language with many types. \index{variable} The
+variable name is just an alphanumeric \index{alphanumeric} string, the
+underscore character  ``\texttt{\_}'' is not allowed, because
+it will be used as an operator in the future.\index{\_}
+
+\subsection{List of major types}
+\begin{description}
+\item[bool]   is used for logical expression and flow-control.
+\index{bool}\index{true}\index{false}
+\item[int]
+  declare an integer.
+\item[string] declare the varible to store
+a text enclosed within double quates, such as:
+\bT
+"This is a string in double quotes."
+\eT
+\index{string}
+\item[real] declare the variable to store a number such as ``12.345''. \index{real}
+\item[complex]  Complex numbers, such as
+$1+2i,\, i=\sqrt{-1}$.
+\bT
+ at complex a =  1 at i, b = 2 + 3 at i;
+ at cout << "a + b = " << a + b << @endl;
+ at cout << "a - b = " << a + b << @endl;
+ at cout << "a * b = " << a * b << @endl;
+ at cout << "a / b = " << a / b << @endl;
+\eT
+Here's the output;
+\bT
+a + b = (2,4)
+a - b = (-2,-2)
+a * b = (-3,2)
+a / b = (0.230769,0.153846)
+\eT
+\item[ofstream]  make a output file and its functions.
+\item[ifstream]   make a input file and its functions.
+
+\item[real[int]]  declare a variable that store multiple
+real numbers with integer index.
+\index{array}
+\bT
+ at real[@int] a(5);
+a[0] = 1; a[1] = 2; a[2] = 3.3333333; a[3] = 4; a[4] = 5;
+ at cout << "a = " << a  << @endl;
+\eT
+This produces the output;
+\bT
+a = 5   :
+  1       2     3.33333   4       5
+\eT
+\item[real[string]]  declare a variable that store multiple
+real numbers with string index.
+\item[string[string]]  declare a variable that store multiple
+strings with string index.
+\index{array}
+\itemtt[func] define a function without argument,
+if independent variables are \ttCC{x, y}.
+For example
+\bT
+ at func f=cos(x)+sin(y) ;
+\eT
+\index{func}
+Remark the function's type is given by the expression's type.
+The power of functions are given in \freefempp such as
+\ttCC{x\^{}1}, \ttCC{y\^{}0.23}.
+
+\itemtt[mesh]  \index{mesh}
+create the triangulation, see \refSec{Mesh Generation}.
+\itemtt[fespace]
+define a new type of finite element space, see Section \refSec{Finite Elements}.
+\itemtt[problem]  declare the weak form of a partial differential problem without solving. \index{problem}
+\itemtt[solve]  declare a problem and solve it.\index{solve}
+\itemtt[varf]   define a full variational form. \index{varf}
+\itemtt[matrix] define a sparse matrix. \index{matrix}
+\end{description}
+
+\subsection{Global Variables}\label{sec:Global}
+ The names \ttCC{x,y,z,label,region,P,N,nu\_triangle} are used to link
+the language to the finite element tools:
+\begin{description}
+    \itemtt[x]  expresses $x$ coordinate of current point (real value) \index{x}
+    \itemtt[y]  expresses $y$ coordinate  of current point (real value) \index{y}
+    \itemtt[z]  expresses $z$ coordinate of current point (real value) \index{z}, but is reserved for future use.
+\itemtt[label] show the label number of boundary if the  current point is
+on a boundary, otherwise 0 (int value). \index{label}
+    \item[region]   returns the region number of  the current point (x,y) (int value). \index{region}
+\itemtt[P]  give the  current point  ($\R^{2}$ value. \index{P}).
+By \texttt{P.x}, \texttt{P.y}, we can get the $x,\, y$ components of \texttt{P} .
+Also \texttt{P.z} is reserved.
+    \itemtt[N]  give the outward unit normal vector at the  current point is on the curve define by \texttt{border} ($\R^{3}$ value).
+\texttt{N.x} and \texttt{N.y} are $x$ and $y$ components of the normal vector.
+\texttt{N.z} is reserved. \index{N}.
+    \itemtt[lenEdge] give the length of the current edge\index{lenEdge}\\
+    \[
+    \texttt{lenEdge} = |q^i-q^j|\quad \textrm{if the current edge is }[q^i,q^j]
+    \]
+
+    \itemtt[hTriangle] give the size of the current triangle \index{hTriangle}
+
+    \itemtt[nuTriangle] give the index of the current triangle (integer).
+    \index{nuTriangle}
+
+    \itemtt[nuEdge]  give the index of the current edge in the triangle (integer).
+    \index{nuEdge}
+
+    \itemtt[nTonEdge] give the number of adjacent triangle of the current
+    edge (integer ).\index{nTonEdge}
+
+    \itemtt[area] give the area of the current triangle (real). \index{area}
+
+\itemtt[cout]  is the standard output device (default is console).
+On MS-Windows, the standard output is only to console, in this time.
+  \Ostream
+\itemtt[cin]  is the standard input device (default is keyboard). (\Istream).
+On MS-Windows, this don't work.
+\itemtt[endl] give the end of line in the input/output devices.
+\itemtt[true]   means ``true'' in  \Bool\  value.
+\itemtt[false]  means ``false'' in  \Bool\ value.
+\itemtt[pi]   is the \Real ~approximation value of $\pi$.
+\end{description}
+
+\medskip
+
+Here is how to show all the types, and all the operator and functions.
+\bFF
+ @dumptable(@cout);
+\eFF \index{dumptable}
+To execute a system command in the string (not implemented on Carbon
+MacOs)
+\bFF
+  @exec("shell command");
+\eFF
+On MS-Windows, we need the full path. For example, if there is the command
+``ls.exe'' in the subdirectory ``\verb|c:\cygwin\bin\|'', then we must write
+\bFF
+  @exec("c:\\cygwin\\bin\\ls.exe");
+\eFF
+\index{exec}
+
+
+\subsection{Arithmetic}
+In integers, $+,\, -,\, *$ express the usual arithmetic summation (plus),
+subtraction (minus) and multiplication (times), respectively.
+The operators $/$ and $\%$ yield the quotient and the remainder from the division of the first expression by the second.
+If the second number of $/$ or $\%$ is zero the behavior is undefined.
+The \key{maximum} or \key{minimum} of two integers $a,\, b$ are obtained
+by \texttt{max($a$,$b$)} of
+\texttt{min($a$,$b$)}.
+The power $a^b$ of two integers $a,\, b$ is calculated by writing \verb|a^b|.
+\begin{example} Calculations with the integers
+\label{exm:int}
+\bFF
+ at int a = 12, b = 5;
+ at cout <<"plus, minus of "<<a<<" and "<<b<<" are "<<a+b<<", "<<a-b<<@endl;
+ at cout <<"multiplication, quotient of them are "<<a*b<<", "<<a/b<<@endl;
+ at cout <<"remainder from division of "<<a<<" by "<<b<<" is "<<a%b<<@endl;
+ at cout <<"the minus of "<<a<<" is "<< -a << @endl;
+ at cout <<a<<" plus -"<<b<<" need bracket:"<<a<<"+(-"<<b<<")="<<a+(-b)<<@endl;
+ at cout <<"max and min of "<<a<<" and "<<b<<" is "<<@max(a,b)<<","<<@min(a,b)<< @endl;
+ at cout <<b<<"th power of "<<a<<" is "<<a^b<< @endl;
+b=0;
+ at cout <<a<<"/0"<<" is "<< a/b << @endl;
+ at cout <<a<<"\%0"<<" is "<< a\%b << @endl;
+\eFF
+produce the following result:
+\bFF
+plus, minus of 12 and 5 are 17, 7
+multiplication, quotient of them are 60, 2
+remainder from division of 12 by 5 is 2
+the minus of 12 is -12
+12 plus -5 need bracket :12+(-5)=7
+max and min of 12 and 5 is 12,5
+5th power of 12 is 248832
+12/0 : long long long
+Fatal error : ExecError  Div by 0 at exec line  9
+Exec error : exit
+\eFF
+\end{example}
+
+By the relation $integer\subset real$, the operators
+``$+,\, -,\, *,\, /,\, \%$'' and ``\ttCC{@max,\, @min,\, \^}''
+are also applicable in real-type. However,  $\%$
+calculates the remainder of the integral parts of two real numbers.
+
+The following example similar to Example \ref{exm:int}
+\bT
+ at real a=sqrt(2.), b = pi;
+ at cout <<"plus, minus of "<<a<<" and "<<pi<<" are "<< a+b <<", "<< a-b << @endl;
+ at cout <<"multiplication, quotient of them are "<<a*b<<", "<<a/b<< @endl;
+ at cout <<"remainder from division of "<<a<<" by "<<b<<" is "<< a%b << @endl;
+ at cout <<"the minus of "<<a<<" is "<< -a << @endl;
+ at cout <<a<<" plus -"<<b<<" need bracket :"<<a<<"+(-"<<b<<")="<<a + (-b) << @endl;
+\eT
+gives the following output:
+\bT
+plus, minus of 1.41421 and 3.14159 are 4.55581, -1.72738
+multiplication, quotient of them are 4.44288, 0.450158
+remainder from division of 1.41421 by 3.14159 is 1
+the minus of 1.41421 is -1.41421
+1.41421 plus -3.14159 need bracket :1.41421+(-3.14159)=-1.72738
+\eT
+
+By the relation
+$$
+bool\subset int \subset real\subset complex,
+$$
+the operators
+``$+,\, -,\, *,\, /$'' and ``\ttCC{\^}'' are also applicable in complex-type,
+but ``\%,\, max, min'' fall into disuse.
+Complex number such as \texttt{5+9i},\, i$=\sqrt{-1}$, can be a little tricky.
+For real variables \texttt{a=2.45, b=5.33}, we must write the complex numbers
+\texttt{a+b*i} and \ttCC{a+ at sqrt(2.0)*i} as
+\bT
+ at complex z1 = a+b*1i, z2=a+ at sqrt(2.0)*1i;
+\eT
+The imaginary and real parts of complex number \texttt{z} is obtained by
+\ttCC{@imag} and \ttCC{@real}.
+The conjugate of $a+bi$ ($a,b$ are real) is defined by $a-bi$, which
+is denoted by \ttCC{@conj(a+b*1i)} in \freefempp.
+
+The complex number $z=a+ib$ is considered as
+the pair $(a,b)$ of real numbers $a,\, b$.
+Now we draw the point $(a,b)$ in the plane (Cartesian rectangular system
+of axes) and mark on the $x$-axis the real numbers in the usual way, on the
+$y$-axis the imaginary numbers with $i$ as unit.
+By changing Cartesian coordinate $(a,b)$ to the polar coordinate $(r,\phi)$,
+the complex number $z$ has another expression $z=r(\cos \phi+i\sin\phi )$,
+$r=\sqrt{a^2+b^2}$ and $\phi=\tan^{-1}(b/a)$;
+$r$ is called the \key{absolute value} and $\phi$ the \key{argument} of $z$.
+In the following example, we shall show them using \freefempp programming,
+and \key{de Moivre's formula} $z^n=r^n(\cos n\phi+i\sin n\phi)$.
+
+\begin{example}~
+\label{exm:complex}
+\bFF
+ at real a=2.45, b=5.33;
+ at complex  z1=a+b*1i, z2 = a+sqrt(2.)*1i;
+ at func @string pc(@complex z) // printout complex to (real)+i(imaginary)
+{
+   @string r = "("+real(z);
+   if (@imag(z)>=0) r = r+"+";
+   @return r+ at imag(z)+"i)";
+}
+// printout complex to |z|*(cos(arg(z))+i*sin(arg(z)))
+ at func @string toPolar(@complex z)
+{
+   @return @abs(z)+"*(cos("+ at arg(z)+")+i*sin("+ at arg(z)+"))";
+}
+cout <<"Standard output of the complex "<<pc(z1)<<" is the pair "
+     <<z1<<endl;
+cout <<"Plus, minus of "<<pc(z1)<<" and "<<pc(z2)<<" are "<< pc(z1+z2)
+     <<", "<< pc(z1-z2) << endl;
+cout <<"Multiplication, quotient of them are "<<pc(z1*z2)<<", "
+     <<pc(z1/z2)<< endl;
+cout <<"Real/imaginary part of "<<pc(z1)<<" is "<<@real(z1)<<", "
+     <<@imag(z1)<<endl;
+cout <<"Absolute of "<<pc(z1)<<" is "<<@abs(z1)<<endl;
+cout <<pc(z2)<<" = "<<toPolar(z2)<<endl;
+cout <<"  and polar("<<@abs(z2)<<","<<@arg(z2)<<") = "
+     << pc(@polar(abs(z2),arg(z2)))<<endl;
+cout <<"de Moivre's formula: "<<pc(z2)<<"^3 = "<<toPolar(z2^3)<<endl;
+cout <<"conjugate of "<<pc(z2)<<" is "<<pc(@conj(z2))<<endl;
+cout <<pc(z1)<<"^"<<pc(z2)<<" is "<< pc(z1^z2) << endl;
+\eFF
+Here's the output from Example \ref{exm:complex}
+\bT
+Standard output of the complex (2.45+5.33i) is the pair (2.45,5.33)
+Plus, minus of (2.45+5.33i) and (2.45+1.41421i) are (4.9+6.74421i), (0+3.91579i)
+Multiplication, quotient of them are (-1.53526+16.5233i), (1.692+1.19883i)
+Real/imaginary part of (2.45+5.33i) is 2.45, 5.33
+Absolute of (2.45+5.33i) is 5.86612
+(2.45+1.41421i) = 2.82887*(cos(0.523509)+i*sin(0.523509))
+  and polar(2.82887,0.523509) = (2.45+1.41421i)
+de Moivre's formula: (2.45+1.41421i)^3
+                         = 22.638*(cos(1.57053)+i*sin(1.57053))
+conjugate of (2.45+1.41421i) is (2.45-1.41421i)
+(2.45+5.33i)^(2.45+1.41421i) is (8.37072-12.7078i)
+\eT
+\end{example}
+
+\subsection{\setS{One Variable Functions}}
+\index{functions}
+\begin{description}
+  \item[Fundamental functions] are built into \freefempp.
+The \emph{power function} \ttCC{x\^}$\alpha (=x^\alpha)$;
+the \emph{exponent function} \ttCC{@exp(x)} ($=e^x$);
+the \emph{logarithmic function} \ttCC{@log(x)}($=\ln x$) or
+\ttCC{@log10(x)} ($=\log_{10}x$);
+the \emph{trigonometric functions} \ttCC{@sin(x), @cos(x), @tan(x)}
+depending on angles measured by \emph{radian};
+the inverse of $\sin x,\, \cos x,\, \tan x$ called \emph{circular function} or \emph{inverse trigonometric function} \ttCC{@asin(x)}(=$\arcsin x$), \ttCC{@acos(x)}(=$\arccos x$), \ttCC{@atan(x)}(=$\arctan x$);
+the \emph{hyperbolic function},
+\[
+\sinh x=\left( e^x-e^{-x}\right)/2,\qquad
+\cosh x=\left( e^x+e^{-x}\right)/2.
+\]
+and $\tanh x=\sinh x/\cosh x$ written
+by \ttCC{@sinh(x)}, \ttCC{@cosh(x)}, \ttCC{@asinh(x)} and \ttCC{@acosh(x)}.
+\[
+\sinh^{-1}x=\ln \left[x+\sqrt{x^2+1}\right],\qquad
+\cosh^{-1}x=\ln \left[x+\sqrt{x^2-1}\right].
+\]
+\itemtt[Elementary Functions]
+is the class of functions consisting of the functions in this section
+(polynomials, exponential, logarithmic, trigonometric, circular) and
+the functions obtained from those listed by the four arithmetic operations
+\[
+f(x)+g(x),\, f(x)-g(x),\, f(x)g(x),\, f(x)/g(x)
+\]
+and by superposition $f(g(x))$, in which four arithmetic operarions and superpositions are permitted finitely many times.
+In \freefempp, we can create all elementary functions.
+The derivative of an elementary function is also elementary.
+However, the indefinite integral of an elementary function cannot always be expressed in terms of elementary functions.
+\begin{example}
+The following give the example
+to make the boundary using elementary functions.
+\emph{Cardioid}
+\bT
+ at real b = 1.;
+ at real a = b;
+ at func @real phix(@real t)
+{
+   @return (a+b)*cos(t)-b*cos(t*(a+b)/b);
+}
+ at func @real phiy(@real t)
+{
+   @return (a+b)*sin(t)-b*sin(t*(a+b)/b);
+}
+ at border C(t=0,2*pi) { x=phix(t); y=phiy(t); }
+ at mesh Th = @buildmesh(C(50));
+\eT
+\end{example}
+Taking the principal value, we can define $\log z$ for $z\neq 0$ by
+\[
+\ln z = \ln |z|+\arg z.
+\]
+Using \freefempp, we calculated
+\ttCC{@exp(1+4i)}, \ttCC{@sin(pi+1i)}, \ttCC{@cos(pi/2-1i)} and \ttCC{@log(1+2i)}, we then have
+\begin{eqnarray*}
+-1.77679-2.0572i,& 1.88967 10^{-16}-1.1752i,\\
+9.44833 10^{-17}+1.1752i, & 0.804719+1.10715i.
+\end{eqnarray*}
+\end{description}
+
+\subsection{Two Variable Functions}
+\label{sec:TwoVarFunctions}
+\subsubsection{\setS{Formula}}
+The general form of real functions with two independent variables $x,\, y$ is
+usually written as $z=f(x,y)$. In \freefempp, \ttCC{x} and \ttCC{y} are
+reserved word in Section \ref{sec:Global}.
+When two independent variables are \ttCC{x} and \ttCC{y},
+we can define a function without argument, for example
+\bT
+ at func f=@cos(x)+ at sin(y) ;
+\eT
+Remark the function's type is given by the expression's type.
+The power of functions are given in \freefempp such as
+\ttCC{x\^{}1}, \ttCC{y\^{}0.23}.
+In \ttCC{func}, we can write an elementary function as follows
+\bT
+ at func f = @sin(x)*@cos(y);
+ at func g = (x^2+3*y^2)*@exp(1-x^2-y^2);
+ at func h = @max(-0.5,0.1*@log(f^2+g^2));
+\eT
+
+Complex valued function create functions with 2 variables \ttCC{x, y} as follows,
+\bT
+ at mesh Th=square(20,20,[-pi+2*pi*x,-pi+2*pi*y]); // $]-\pi,\pi[^2$
+ at fespace Vh(Th,P2);
+ at func z=x+y*1i;  // $z=x+iy$
+ at func f=@imag(sqrt(z));  // $f=\Im\sqrt{z}$
+ at func g=@abs( sin(z/10)*exp(z^2/10) ); // $g=|\sin z/10\exp z^2/10|$
+Vh fh = f; plot(fh);  // contour lines of $f$
+Vh gh = g; plot(gh);  // contour lines of $g$
+\eT
+We call also by \emph{two variable elementary function} functions
+obtained from elementary functions $f(x)$ or $g(y)$
+by the four arithmetic operations
+and by superposition in finite times.
+
+\subsubsection{\setS{FE-function}}\index{FE-function}
+Arithmetic built-in functions are able to construct a new function by
+the four arithmetic operations and superposition of them
+(see \emph{elementary functions}), which are called
+\key{formulas} to distinguish from
+FE-functions.
+We can add \emph{new formulas} easily, if we want.
+Here, FE-function is an element of
+finite element space (real or complex) (see Section \refSec{Finite Elements}).
+Or to put it another way: \emph{formulas} are the
+mathematical expressions combining its numerical analogs, but
+it is independent of meshes (triangulations).
+
+Also, in \texttt{freefem++}, we can give an arbitrary symbol to FE-function
+combining numerical calculation by FEM.
+The projection of a formula $f$ to FE-space is done as in
+\bT
+func f=x^2*(1+y)^3+y^2;
+mesh Th = square(20,20,[-2+2*x,-2+2*y]); // square $]-2,2[^2$
+fespace Vh(Th,P1);
+Vh fh=f;  // fh is the  projection of f to Vh (real value)
+func zf=(x^2*(1+y)^3+y^2)*exp(x+1i*y);
+Vh<complex> zh = zf; // zh is the projection of zf
+// to complex value Vh space   \index{FE function!complex}
+\eT
+The construction of \ttCC{fh} (=$f_h$) is explained in
+\refSec{Finite Elements}.
+
+\begin{note}
+The command \ttCC{@plot} is valid only for real  FE-functions.
+\end{note}
+Complex valued function create functions with 2 variables \ttCC{x, y} as follows,
+\bT
+ at mesh Th=square(20,20,[-pi+2*pi*x,-pi+2*pi*y]); // $]-\pi,\pi[^2$
+ at fespace Vh(Th,P2);
+ at func z=x+y*1i;  // $z=x+iy$
+ at func f=@imag(sqrt(z));  // $f=\Im\sqrt{z}$
+ at func g=@abs( sin(z/10)*exp(z^2/10) ); // $g=|\sin z/10\exp z^2/10|$
+Vh fh = f; plot(fh);  // Fig. \ref{cfunc1} isovalue of $f$
+Vh gh = g; plot(gh);  // Fig. \ref{cfunc2} isovalue of $g$
+\eT
+\twoplot[height=5cm]{cfunc1}{cfunc2}{$\Im\sqrt{z}$ has branch}
+{$|\sin (z/10)\exp (z^2/10)|$}
+
+\subsection{Array}
+\index{array}
+An \emph{array} stores multiple objects, and
+there are 2 kinds of arrays:
+The first is the \emph{vector} that is arrays with \emph{integer indices}
+and
+arrays with \emph{string indices}.
+
+In the first case, the size of this array
+must be know at the execution time, and the implementation is done
+with the \ttCC{KN<>} class so all the vector operator of
+ \ttCC{KN<>} are implemented. The sample
+\bT
+ at real [int] tab(10), tab1(10); // 2 array of 10 real
+ at real [int] tab2;    //  bug array with no size
+tab = 1.03;                //  set all the array to 1.03
+tab[1]=2.15;
+ at cout << tab[1] << " " << tab[9] << " size of tab = "
+     << tab.n << " min: " << tab.min << "  max:" << tab.max
+     << " sum : "   << tab.sum <<   endl; //
+tab.resize(12); //  change the size of array tab
+  // to 12 with preserving first value
+tab(10:11)=3.14; //  set unset value
+cout <<" resize tab: " <<  tab << endl;
+\eT
+\index{array!resize}\index{resize}\index{max}\index{array!max} \index{min}\index{array!min}\index{sum}\index{array!sum}
+produce the output
+\bT
+2.15 1.03 size of tab = 10 min: 1.03  max:2.15 sum : 11.42
+ resize tab: 12
+        1.03    2.15    1.03    1.03    1.03
+        1.03    1.03    1.03    1.03    1.03
+        3.14    3.14
+\eT
+
+It is also possible to make an array of FE function, with the same syntax,
+and we can treat them as \emph{vector valued function} if we need them.
+\index{array}\index{array!FE function}
+\begin{example}
+In the following example, Poisson's equation is solved under 3 different given
+functions $f=1,\, \sin(\pi x)\cos(\pi y),\, |x-1||y-1|$, whose solutions are
+stored in an array of FE function.
+\bT
+ at mesh Th=@square(20,20,[2*x,2*y]);
+ at fespace Vh(Th,P1);
+Vh u, v, f;
+ at problem @Poisson(u,v) =
+    @int2d(Th)( @dx(u)*@dx(v) + @dy(u)*@dy(v))
+     + @int2d(Th)( -f*v ) + @on(1,2,3,4,u=0) ;
+Vh[int] uu(3); // an array of FE function
+f=1;   // problem1
+Poisson; uu[0] = u;
+f=sin(pi*x)*cos(pi*y);  // problem2
+Poisson; uu[1] = u;
+f=abs(x-1)*abs(y-1);    // problem3
+Poisson; uu[2] = u;
+ at for (int i=0; i<3; i++)  // plots all solutions
+  @plot(uu[i], @wait=true);
+\eT
+\end{example}
+
+ For the second case, it is just
+ a map of the STL\footnote{Standard template Library, now part of standard \Cpp}\cite{cpp}
+ so no vector operation except the
+ selection of an item is allowed . \index{dot product}\index{transpose}
+
+The transpose operator is \texttt{\string'} like  MathLab or SciLab, so the way
+to compute the dot product of two array \ttCC{a,b} is  \ttCC{@real\ ab=\ a'*b}\index{product!dot}.
+\index{min}\index{array!min}
+\bFF
+ at int i;
+ at real [int] tab(10), tab1(10); // 2 array of 10 real
+  \it  real [int] tab2;    //  bug array with no size
+tab = 1;                //  set all the array to 1
+tab[1]=2;
+ at cout << tab[1] << " " << tab[9] << " size of tab = "
+     << tab.n << " " << tab.min << " " << tab.max << " " <<  @endl;
+tab1=tab; tab=tab+tab1; tab=2*tab+tab1*5; tab1=2*tab-tab1*5;
+tab+=tab; @cout << " dot product " << tab'*tab << @endl; //
+${}^{t}{tab}\,{tab} $ @cout << tab << @endl; @cout << tab[1] << " "
+<< tab[9] <<  @endl; @real[string] map;        //  a dynamic array
+ at for (i=0;i<10;i=i+1)
+  {
+    tab[i] = i*i;
+    @cout << i << " " << tab[i] << "\n";
+  };
+
+map["1"]=2.0;
+map[2]=3.0;             //  2 is automatically cast to the string "2"
+
+ at cout << " map[\"1\"] = " << map["1"] << "; "<< @endl;
+ at cout << " map[2] = " << map[2] << "; "<< @endl;
+\eFF
+
+
+\subsection{\setS{Loops}}
+
+The \texttt{for} and \texttt{while}  loops are implemented
+with \texttt{break} and \texttt{continue} keywords.
+\index{for}\index{while}
+\index{break}\index{continue}
+
+In for-loop, there are three parameters;
+the INITIALIZATION of a control variable,
+the CONDITION to continue,
+the CHANGE of the control variable.
+While \texttt{CONDITION} is true, for-loop continue.
+\bT
+ at for (INITIALIZATION; CONDITION; CHANGE)
+     { BLOCK of calculations }
+\eT
+The sum from 1 to 10 is calculated by (the result is in \ttCC{sum}),
+\bT
+ at int sum=0;
+ at for (@int i=1; i<=10; i++)
+   sum += i;
+\eT
+The while-loop
+\bT
+ at while (CONDITION) {
+   BLOCK of calculations or change of control variables
+}
+\eT
+is executed repeatedly until CONDITION become false.
+The sum from 1 to 10 is also written by \ttCC{@while} as follows,
+\bT
+ at int i=1, sum=0;
+ at while (i<=10) {
+  sum += i; i++;
+}
+\eT
+
+We can exit from a loop in midstream by \ttCC{@break}.
+The \ttCC{@continue} statement will pass the part from
+\emph{continue} to the end of the loop.
+
+\begin{example}~
+\bFF
+ at for (@int i=0;i<10;i=i+1)
+    @cout << i << "\n";
+ at real eps=1;
+ at while (eps>1e-5)
+ { eps = eps/2;
+   @if( i++ <100) @break;
+   @cout << eps << @endl;}
+
+ at for (int j=0; j<20; j++) {
+   @if (j<10) @continue;
+   @cout << "j = " << j << @endl;
+}
+\eFF
+\end{example}
+
+\subsection{\setS{Input/Output}}
+\index{cout}\index{cint}\index{ifstream}\index{ofstream}\index{endl}
+
+The syntax of input/output statements is similar  to \Cpp syntax. It
+uses \ttCC{@cout}, \ttCC{@cin}, \ttCC{@endl}, \ttCC{<<,>>}.
+
+To write  to (resp. read from)  a file, \index{$<<$} \index{$>>$}\index{append}\index{ofstream!append}
+declare a new variable \texttt{ofstream ofile("filename");} or \texttt{ofstream ofile("filename",append);} (resp.
+\texttt{ifstream ifile("filename");} ) and use \texttt{ofile}  (resp. \texttt{ifile})
+as \texttt{cout} (resp. \texttt{cin}). The word \texttt{append} in  \texttt{ofstream ofile("filename",append);}
+ means openning a file in append mode.
+
+\begin{note} The file is closed
+at the exit of the enclosing block,
+\end{note}
+\begin{example}~
+\label{exm:io}
+\bFF
+ at int i;
+ at cout << " std-out" << @endl;
+ at cout << " enter i= ? ";
+ at cin >> i ;
+{
+  @ofstream f("toto.txt");
+  f << i << "coucou'\n";
+}; //  close the file f because the variable f is delete
+
+{
+  @ifstream f("toto.txt");
+   f >> i;
+}
+{
+  @ofstream f("toto.txt",append);
+     // to append to the existing file "toto.txt"
+  f << i << "coucou'\n";
+}; //  close the file f because the variable f is delete
+
+  @cout << i << @endl;
+\eFF
+\end{example}
+
+\section{\setS{Mesh Generation}}
+\subsection{Commands for Mesh Generation}\label{sec:InitialMesh}
+In Step1 in Section \ref{sec:example}, the keywords
+\texttt{\bf border, buildmesh}
+are explained.
+%square,
+%,  movemesh ,
+% adaptmesh, readmesh, trunc, triangulate, splitmesh, emptymesh}
+%
+%The following keywords are discussed in this section:
+%
+%\texttt{\bf square, border, buildmesh,  movemesh ,
+% adaptmesh, readmesh, trunc, triangulate, splitmesh, emptymesh}
+%
+% \index{square}\index{border}\index{buildmesh}\index{movemesh}\index{adaptmesh}
+% \index{readmesh}\index{triangulate}\index{splitmesh}\index{emptymesh}
+
+All the examples in this section come from the files \texttt{mesh.edp}
+and \texttt{tablefunction.edp}.
+
+\subsubsection{\setS{Square}}
+
+For easy and simple testing, there is the command
+``\texttt{\bf square}''.
+The following
+\bT
+ at mesh Th = @square(4,5);
+\eT
+generate a $4\times 5$ grid in the unit squre $[0,1]^2$ whose labels
+are shown in Fig. \ref{fig:square}.
+\begin{figure}[htbp]
+\begin{center}
+  \includegraphics[height=5cm]{figures/square}
+\end{center}
+  \caption{Boundary labels of the mesh by \texttt{square(10,10)}}
+  \label{fig:square} \index{label}
+\end{figure}
+If you want constructs a
+$n\times m$ grid in the rectangle $[x_0,x_1]\times [y_0,y_1]$, you can
+write
+\bFF
+  @real x0=1.2,x1=1.8;
+  @real y0=0,y1=1;
+  @int n=5,m=20;
+  @mesh Th=@square(n,m,[x0+(x1-x0)*x,y0+(y1-y0)*y]);
+\eFF
+ \begin{note}
+You must notice that if you adding the name parameter \texttt{flags=1}, you  get a
+Union Jack fags mesh pattern. \index{square!flags=}
+\bFF
+  @mesh Th=@square(n,m,[x0+(x1-x0)*x,y0+(y1-y0)*y],flags=1);
+\eFF
+\end{note}
+
+
+
+\subsubsection{\setS{Border}}\index{border}\index{label}
+
+A domain is defined as being on the left (resp right) of its
+parameterized boundary
+$$
+\Gamma_j=\{(x,y)\left|\; x=\varphi_x(t),\, y=\varphi_y(t),\, a_j\le t\le b_j\right.\}
+$$
+We can easily check the orientation by drawing the curve
+$t\mapsto (\varphi_x(t),\varphi_y(t)),\, t_0\le t\le t_1$.
+If the figure become like to Fig. \ref{fig:border}, then
+the domain lie on the shaded area, otherwise it lie on opposite side
+(see also the examples enclosed with the box).
+The boundaries $\Gamma_j$ can only intersect at their end points.
+
+\begin{figure}[htbp]
+\begin{center}
+  \includegraphics[height=4cm]{figures/border}
+\end{center}
+  \caption{Orientation of the boundary defined by $(\phi_x(t),\phi_y(t))$}
+  \label{fig:border} \index{border}
+\end{figure}
+The general expression of the triangulation is
+\[
+\ttCC{@mesh  ~~Mesh\_Name = @buildmesh$\left(\Gamma_1(m_1)+\cdots+\Gamma_J(m_j)\right)$;}
+\]
+where $m_j$ are numbers of marked points on $\Gamma_j,\,
+\Gamma=\cup_{j=1}^J \Gamma_J$.
+We can change the orientation of boundaries by changing the sign of $m_j$.
+The following example shows how to change the orientation.
+The example generates the unit disk
+with a small circular hole, and assign ``1'' to the unit disk
+(``2'' to the circle inside).
+The boundary label must be non-zero, however we can omit the label
+if we want use only the symbol.
+
+\bFF
+1: @border a(t=0,2*pi){ x=cos(t); y=sin(t);label=1;}
+2: @border b(t=0,2*pi){ x=0.3+0.3*cos(t); y=0.3*sin(t);label=2;}
+3: @plot(a(50)+b(+30)) ; // to see a plot of the border mesh \index{plot!border}
+4: @mesh Thwithouthole= @buildmesh(a(50)+b(+30));
+5: @mesh Thwithhole   = @buildmesh(a(50)+b(-30));
+6: @plot(Thwithouthole,wait=1,ps="Thwithouthole.eps"); //figure \ref{Thwithouthole}\index{plot!mesh}
+7: @plot(Thwithhole,wait=1,ps="Thwithhole.eps"); // figure \ref{Thwithhole}
+\eFF
+\begin{note}
+You must notice that the orientation is changed by ``\texttt{b(-30)}'' in 5th line. In 7th line, \texttt{ps="fileName"} is used to generate a postscript file
+identification that is shown on screen.
+\end{note}
+
+\twoplot[height=6cm]{Thwithouthole}{Thwithhole}{mesh without hole}{mesh with hole}
+
+\subsubsection{Data Structure of Mesh and Reading/Writing a Mesh}
+
+\index{readmesh}\index{savemesh}
+Some user asked us that they want use the triangulation made from other tools
+or hand-made mesh.
+The example
+\bT
+ at border C(t=0,2*pi) { x=cos(t); y=sin(t); }
+ at mesh Th = @buildmesh(C(10));
+ at savemesh("mesh_sample.msh");
+\eT
+make the mesh as in Fig. \ref{fig:meshSample}.
+The informations about \texttt{Th} are save in the file ``mesh\_sample.msh''.
+
+We can read from Fig. \ref{fig:meshSample} and ``mesh\_sample.msh''
+as in Table \ref{tab:meshSample} where $n_v$ is
+the number of vertices, $n_t$ number of triangles
+and $n_s$ the number of edges on boundary.
+For each vertex $q^i,\, i=1,\cdots,n_v$, we denote by $(q^i_x,q^i_y)$
+the $x$-coordinate and $y$-coordinate.
+
+Each triangle $T_k, k=1,\cdots,10$ have three vertices $q^{k_1},\, q^{k_2},\,q^{k_3}$ that are oriented in counterclockwise.
+The boundary consists of 10 lines $L_i,\, i=1,\cdots,10$ whose tips are
+$q^{i_1},\, q^{i_2}$.
+
+\begin{figure}[htbp]
+\begin{minipage}{\textwidth}
+\begin{minipage}{0.5\textwidth}
+\includegraphics[width=\textwidth]{figures/mesh_sample}%
+\caption{mesh by \texttt{buildmesh(C(10))}}
+\label{fig:meshSample}
+\end{minipage}
+\hspace{0.5mm}
+\begin{minipage}{0.5\textwidth}
+In the left figure, we have the following.\\\\
+$n_v=14,\, n_t=16,\, n_s=10$\\\\
+$q^1=(-0.309016994375,\, 0.951056516295)$\\
+$\vdots\qquad \vdots\qquad \vdots$\\
+$q^{14}=(-0.309016994375,\, -0.951056516295)$\\\\
+The vertices of $T_1$ are $q^9,\, q^{12},\, q^{10}$.\\
+$\vdots\qquad \vdots\qquad \vdots$\\
+The vertices of $T_{16}$ are $q^9,\, q^{10},\, q^{6}$.\\\\
+The edge of 1st side $L_1$ are $q^6,\, q^5$.\\
+$\vdots\qquad \vdots\qquad \vdots$\\
+The edge of 10th side $L_{10}$ are $q^{10},\, q^6$.\\
+\end{minipage}
+\end{minipage}
+\end{figure}
+
+\begin{table}[htbp]
+\begin{tabular}{|l|l|}
+\hline
+Contents of file&Explanation\\
+\hline
+14 16 10& $n_v$\qquad  $n_t$\qquad $n_e$\\
+-0.309016994375 0.951056516295 1& $q^1_x$\qquad $q^1_y$\qquad boundary label=1\\
+0.309016994375 0.951056516295 1& $q^2_x$\qquad $q^2_y$\qquad boundary label=1\\
+$\cdots$  $\cdots$ $\vdots$& \\
+-0.309016994375 -0.951056516295 1& $q^{14}_x$\qquad $q^{14}_y$\qquad boundary label=1\\
+\hline
+9 12 10 0&$1_1$\quad $1_2$\quad $1_3$\quad region label=0 \\
+5 9 6 0&$2_1$\quad $2_2$\quad $2_3$\quad region label=0  \\
+$\cdots$& \\
+9 10 6 0&$16_1$\quad $16_2$\quad $16_3$\quad region label=0 \\
+\hline
+6 5 1&$1_1\quad 1_2$\quad boundary label=1\\
+5 2 1&$2_1\quad 2_2$\quad boundary label=1\\
+$\cdots$& \\
+10 6 1&$10_1\quad 10_2$\quad boundary label=1\\
+\hline
+\end{tabular}
+  \caption{The structure of ``mesh\_sample.msh''}
+  \label{tab:meshSample}
+\end{table}
+
+There are many mesh file formats available for communication with
+other tools such as emc2, modulef.. (see \refSec{Mesh Files}),
+The extension of a file gives the chosen
+type.\index{bamg} More details can be found in the article by F. Hecht
+"bamg : a bidimentional anisotropic mesh generator" available from the
+FreeFem web site.  \\
+
+The following give the example write and read files of generated mesh,
+Freefem can read and write files. A
+mesh file can be read back into \freefempp but the names of the
+borders are lost. So these borders have to be referenced by the number
+which corresponds to their order of appearance in the program, unless
+this number is forced by the keyword "label".
+
+\bFF
+ at border floor(t=0,1){ x=t; y=0; label=1;}; // the unit square
+ at border right(t=0,1){ x=1; y=t; label=5;};
+ at border ceiling(t=1,0){ x=t; y=1; label=5;};
+ at border left(t=1,0){ x=0; y=t; label=5;};
+ at int n=10;
+ at mesh th= buildmesh(floor(n)+right(n)+ceiling(n)+left(n));
+ at savemesh(th,"toto.am_fmt");  // "formatted Marrocco" format \index{file!am\_fmt}
+ at savemesh(th,"toto.Th");      // "bamg"-type mesh   \index{file!bamg}
+ at savemesh(th,"toto.msh");     // freefem format \index{file!mesh}
+ at savemesh(th,"toto.nopo");     // modulef format \index{file!nopo} see \cite{modulef}
+ at mesh th2 = readmesh("toto.msh"); // read the mesh
+
+\eFF
+
+The following example explains methods to obtain mesh information.
+\index{triangle![]}\index{triangle!label}\index{triangle!label}
+\index{vertex!x}\index{vertex!y}\index{vertex!label}
+\bFF
+{  // get mesh information (version 1.37)
+  @mesh Th=square(2,2);
+  // get data of the mesh
+  @int nbtriangles=Th.nt;
+  @for (@int i=0;i<nbtriangles;i++)
+    @for (@int j=0; j <3; j++)
+      @cout << i << " " << j << " Th[i][j] = "
+           << Th[i][j] << "  x = "<< Th[i][j].x  << " , y= "<< Th[i][j].y
+           << ",  label=" << Th[i][j].label << endl;
+
+  // To Day:   this Hack works: to get x,y of vertex i \hfilll
+  // remark: i can be set with i= Th[it][j] \hfilll
+  // the idea is to build de interpolation of x and y function \hfilll
+  // with 2 array now given i -> x and i-> y. \hfilll
+
+  fespace femp1(Th,P1);
+  femp1 Thx=x,Thy=y;
+  cout << " nb of vertices = " << nbvertices << endl;
+  for (int i=0;i<nbvertices;i++)
+        cout << i  << " : " << Thx[][i] << " " << Thy[][i] << endl;
+
+  //Hack  to get a triangle number of mesh contening point x,y \hfilll
+  //     or  region number \hfilll
+  // ----------------------------------------- \hfilll
+  fespace femp0(Th,P0);
+  femp0 nuT; // a P0 function  to get triangle numbering
+    for (int i=0;i<Th.nt;i++)
+     nuT[][i]=i;
+  femp0 nuReg=region; // a P0 function to get the region number
+  //  inquire
+  int it0=nuT(0.55,0.6); //  number of triangle contening point (0.55,0,6);
+  int nr0=nuReg(0.55,0.6); //  number of region of mesh contening point (0.55,0,6);
+  // new method if   version > 1.450007
+  int it00 = Th(0.55,0.6).nuTriangle; // get the number of Th's triangle contening (0.55,0.6)
+  int nr00 = Th(0.55,0.6).region;; // get the region  number of Th's triangle
+    // dump
+  cout << "  point (0.55,0,6) :triangle number " << it0 << " " << it00
+       << ", region = " << nr0 << " == " << nr00 << endl;
+}
+
+\eFF
+the output is:
+\bFF
+0 0 Th[i][j] = 0  x = 0 , y= 0,  label=4
+0 1 Th[i][j] = 1  x = 0.5 , y= 0,  label=1
+0 2 Th[i][j] = 4  x = 0.5 , y= 0.5,  label=0
+1 0 Th[i][j] = 0  x = 0 , y= 0,  label=4
+1 1 Th[i][j] = 4  x = 0.5 , y= 0.5,  label=0
+1 2 Th[i][j] = 3  x = 0 , y= 0.5,  label=4
+.......
+5 2 Th[i][j] = 6  x = 0 , y= 1,  label=4
+6 0 Th[i][j] = 4  x = 0.5 , y= 0.5,  label=0
+6 1 Th[i][j] = 5  x = 1 , y= 0.5,  label=2
+6 2 Th[i][j] = 8  x = 1 , y= 1,  label=3
+7 0 Th[i][j] = 4  x = 0.5 , y= 0.5,  label=0
+7 1 Th[i][j] = 8  x = 1 , y= 1,  label=3
+7 2 Th[i][j] = 7  x = 0.5 , y= 1,  label=3
+ Nb Of Nodes = 9
+ Nb of DF = 9
+ -- vector function's bound  -0 1
+ -- vector function's bound  -0 1
+ nb of vertices = 9
+0 : -0 -0
+1 : 0.5 -0
+2 : 1 -0
+3 : -0 0.5
+4 : 0.5 0.5
+5 : 1 0.5
+6 : -0 1
+7 : 0.5 1
+8 : 1 1
+ Nb Of Nodes = 8
+ Nb of DF = 8
+ -- vector function's bound  -0 -0
+  point (0.55,0,6) :triangle number 7 7, region = 0 == 0
+\eFF
+\begin{example}[Readmesh.edp]
+\index{tutorial!readmesh.edp}
+\index{read files}
+\index{write files}
+\bFF
+ at border floor(t=0,1){ x=t; y=0; label=1;}; // the unit square
+ at border right(t=0,1){ x=1; y=t; label=5;};
+ at border ceiling(t=1,0){ x=t; y=1; label=5;};
+ at border left(t=1,0){ x=0; y=t; label=5;};
+ at int n=10;
+ at mesh th= buildmesh(floor(n)+right(n)+ceiling(n)+left(n));
+ at savemesh(th,"toto.am_fmt");  // format "formated Marrocco" \index{file!am\_fmt}
+ at savemesh(th,"toto.Th");      // format database  db mesh "bamg"   \index{file!bamg}
+ at savemesh(th,"toto.msh");     // format freefem \index{file!mesh}
+ at savemesh(th,"toto.nopo");     // modulef format \index{file!nopo} see \cite{modulef}
+ at mesh th2 = readmesh("toto.msh");
+ at fespace femp1(th, at P1);
+femp1 f = sin(x)*cos(y),g;
+{ // save solution
+ at ofstream file("f.txt");
+file << f[] << endl;
+}  // close the file (end block)
+{  // read
+ at ifstream file("f.txt");
+file >> g[] ;
+} // close reading file (end block)
+ at fespace Vh2(th2,P1);
+Vh2 u,v;
+ at plot(g);
+//  find $u$ such that \hfilll
+// $ u - \Delta u = g $ in $\Omega $ , \hfilll
+// $ u=0$ on $\Gamma_1$ and $\frac{\partial u }{\partial n} = g$ on $\Gamma_2$  \hfilll
+ at solve pb(u,v) =
+    @int2d(th)( u*v - dx(u)*dx(v)-dy(u)*dy(v) )
+  + @int2d(th)(-g*v)
+  + @int1d(th,5)( g*v) //  $\frac{\partial u }{\partial n} = g$ on $\Gamma_2$
+  + @on(1,u=0) ;
+ at plot (th2,u);
+\eFF
+\end{example}
+
+\subsubsection{Triangulate}\index{triangulate}
+
+\freefempp is able to build a triangulation from a set of points. This
+triangulation is a Delaunay mesh of the convex hull of the set of points.
+It can be useful to build a mesh form a table function.
+
+The coordinates of the points and the value of the table function
+are defined separately with rows of the form: \texttt{x y f(x,y)}
+in a file such as:
+
+\bFF
+0.51387 0.175741 0.636237
+0.308652 0.534534 0.746765
+0.947628 0.171736 0.899823
+0.702231 0.226431 0.800819
+0.494773 0.12472 0.580623
+0.0838988 0.389647 0.456045
+...............
+\eFF
+%%% Thxy.eps not found
+\twoplot[height=4cm]{Thxy}{xyf}{Delaunay mesh of the convex hull of point set in file xyf}{Isovalue of table function}
+
+The third column of each line is left untouched by the
+\texttt{triangulate} command. But you can use this third value to
+define a table function with rows of the form: \texttt{x y f(x,y)}.
+
+
+The following example shows how to make mesh from the file ``xyf''
+with the format stated just above.
+The command
+\texttt{triangulate} command use only use 1st and 2nd rows.
+
+\index{function!tables}
+
+\bFF
+ at mesh Thxy=triangulate("xyf"); // build the Delaunay mesh of the convex hull
+// points are defined by the first 2 columns of file \texttt{xyf}
+ at plot(Thxy,ps="Thxyf.ps"); // (see figure  \ref{Thxy})
+
+ at fespace Vhxy(Thxy,P1); // create a P1 interpolation
+Vhxy fxy; // the function
+
+// reading the 3rd row to define the function
+{ @ifstream file("xyf");
+   @real xx,yy;
+   @for(@int i=0;i<fxy.n;i++)
+   file >> xx >>yy >> fxy[][i];  // to read third row only.
+   // xx and yy are just skipped
+}
+ at plot(fxu,ps="xyf.eps"); // plot the function (see figure  \ref{xyf})
+\eFF
+
+\subsection{build empty mesh}\index{emptymesh}
+When you want to define Finite Element space on boundary,
+we come up with the idea of a mesh with no internal points (call empty mesh).
+It can be useful when you have a Lagrange multiplier definied on the border.
+
+So the function emptymesh remove all the internal point of a mesh expect if the
+point is on internal boundary.
+
+\bFF
+{  //  new stuff 2004 emptymesh (version 1.40)
+ // -- useful to build Multiplicator space
+ //  build a mesh without internal point
+ // with the same boundary
+ //  -----
+  assert(version>=1.40);
+  @border a(t=0,2*pi){ x=cos(t); y=sin(t);label=1;}
+  @mesh Th=buildmesh(a(20));
+   Th=@emptymesh(Th);
+  @plot(Th,wait=1,ps="emptymesh-1.eps");//see figure \ref{fig emptymesh-1}
+}
+\eFF
+
+or it is also possible to build a empty mesh of peusdo subregion
+with \texttt{emptymesh(Th,ssd)} with the set of edges of the mesh \texttt{Th}
+a edge $e$ is in  this set  if the two adjacent triangles $e =t1\cap t2$
+and  $ ssd[T1] \neq ssd[T2]$ where \texttt{ssd}  defined the peusdo region numbering of triangle, when they are stored in \texttt{int[int]} array of size the number of triangles.
+\bFF
+{  //  new stuff 2004 emptymesh (version 1.40) \hfilll
+ // -- useful to build Multiplicator space \hfilll
+ //  build a mesh without internal point \hfilll
+ // of peusdo sub domain  \hfilll
+ //  ----- \hfilll
+  assert(version>=1.40);
+  mesh Th=square(10,10);
+  int[int] ssd(Th.nt);
+  for(int i=0;i<ssd.n;i++) // build the  peusdo region numbering
+   {  int iq=i/2;   // because 2 traingle per quad
+      int ix=iq%10; //
+      int iy=iq/10; //
+    ssd[i]= 1 + (ix>=5) +  (iy>=5)*2;
+   }
+  Th=emptymesh(Th,ssd); // build emtpy  with
+  //  all edge $e = T1 \cap T2$ and $ ssd[T1] \neq ssd[T2]$
+  plot(Th,wait=1,ps="emptymesh-2.eps");//see figure \ref{fig emptymesh-2}
+  savemesh(Th,"emptymesh-2.msh");
+}
+\eFF
+
+\twoplot[height=6cm]{emptymesh-1}{emptymesh-2}{ The empty mesh with boundary
+\label{fig emptymesh-1}}{An empty mesh
+defined from a peusdo region numbering of triangle\label{fig emptymesh-2}}
+
+\subsection{Remeshing}
+\subsubsection{\setS{Movemesh}}\index{movemesh}\index{checkmovemesh}
+After solving the elasticity, we want watch the deformation
+$\Omega\mapsto\Phi(\Omega)$,
+$\vec\Phi(x,y)=(\Phi_1(x,y),\Phi_2(x,y))$ of shape.
+In free boundary value problems, the shape of domain will vary.
+
+If $\Omega$ is triangulated already -- dubbed $T_h(\Omega)$,
+then we want $\Phi(\Omega)$ is also triangulated automatically.
+This want is satisfied by
+\bT
+ at mesh  Th=@movemesh(Th,[$\Phi$1,$\Phi$2]);
+\eT
+where $\Phi=(\Phi_1,\Phi_2)$ and $\Phi_i,\, i=1,2$ are functions.
+Sometimes the moved mesh is invalid because some triangle
+becomes reversed (with a negative area). This is why we check the
+minimum triangle area in the transformed mesh with
+\texttt{checkmovemesh} before any real transformation.
+
+\begin{example} $\Phi_1(x,y)=x+k*\sin(y*\pi)/10)$,
+$\Phi_2(x,y)=y+k*\cos(y\pi)/10)$ for a big number $k>1$.
+\bFF
+verbosity=4;
+ at border a(t=0,1){x=t;y=0;label=1;};
+ at border b(t=0,0.5){x=1;y=t;label=1;};
+ at border c(t=0,0.5){x=1-t;y=0.5;label=1;};
+ at border d(t=0.5,1){x=0.5;y=t;label=1;};
+ at border e(t=0.5,1){x=1-t;y=1;label=1;};
+ at border f(t=0,1){x=0;y=1-t;label=1;};
+ at func uu= sin(y*pi)/10;
+ at func vv= cos(x*pi)/10;
+
+ at mesh Th = buildmesh ( a(6) + b(4) + c(4) +d(4) + e(4) + f(6));
+ at plot(Th,wait=1,fill=1,ps="Lshape.eps");// see figure \ref{lshape}
+ at real coef=1;
+ at real minT0= checkmovemesh(Th,[x,y]); // the min triangle area
+ at while(1) // find a correct move mesh
+{
+  @real minT=@checkmovemesh(Th,[x+coef*uu,y+coef*vv]);//the min triangle area
+  if (minT > minT0/5) break ; // if big enough
+  coef=/1.5;
+}
+
+Th=@movemesh(Th,[x+coef*uu,y+coef*vv]);
+ at plot(Th,wait=1,fill=1,ps="movemesh.eps");// see figure \ref{movemesh}
+\eFF
+
+\twoplot[height=6cm]{lshape}{movemesh}{L-shape}{  moved L-shape }
+\end{example}
+\begin{note}
+Consider a function $u$ defined on a mesh \texttt{Th}. A statement like
+\texttt{Th=movemesh(Th...)} does not change $u$ and so the old mesh
+still exists. It will be destroyed when no function use it. A
+statement like $u=u$ redefines $u$ on the new mesh \texttt{Th} with
+interpolation and therefore destroys the old \texttt{Th} if $u$ was the only
+function using it.
+\end{note}
+
+\begin{example}[movemesh.edp]
+\index{tutorial!movemesh.edp}
+Now, we given an example of moving mesh with lagrangian\index{lagrangian}
+function $u$ defined on the moving mesh.
+
+\bFF
+// simple movemesh example
+ at mesh Th=square(10,10);
+ at fespace Vh(Th,P1);
+ at real t=0;
+// ---
+//  the problem is how to build data without interpolation
+//  so the data u is moving with the mesh as you can see in the plot
+// ---
+Vh u=y;
+ at for (int i=0;i<4;i++)
+{
+ t=i*0.1;
+ Vh f= x*t;
+ @real minarea=checkmovemesh(Th,[x,y+f]);
+ if (minarea >0 ) // movemesh will be ok
+   Th=movemesh(Th,[x,y+f]);
+
+ cout << " Min area  " << minarea << endl;
+
+ real[int] tmp(u[].n);
+ tmp=u[];  // save the value
+ u=0;        // to change the FEspace and mesh associated with u
+ u[]=tmp;  // set the value of u without any mesh update
+ @plot(Th,u,wait=1);
+};
+// In this program, since u is only defined on the last mesh, all the \hfilll
+// previous meshes are deleted from memory.  \hfilll
+//   --------  \hfilll
+\eFF
+\end{example}
+
+\subsection{\setS{Regular Triangulation}}
+For a set $S$, we define the diameter of $S$ by
+\[
+\textrm{diam}(S)=\sup\{|\vec{x}-\vec{y}|; \; \vec{x},\, \vec{y}\in S\}
+\]
+The sequence $\{\mathcal{T}_h\}_{h\downarrow 0}$ of $\Omega$ is called
+\emph{regular}\index{mesh!regular} if they satisfy the following:
+\begin{enumerate}
+  \item
+\[
+\lim_{h\downarrow 0}\max\{\textrm{diam}(T_k)|\; T_k\in \mathcal{T}_h\}
+\]
+  \item
+There is a number $\sigma>0$ independent of $h$ such that
+\[
+\frac{\rho(T_k)}{\textrm{diam}(T_k)}\ge \sigma
+\qquad \textrm{for all }T_k\in \mathcal{T}_h
+\]
+where $\rho(T_k)$ are the diameter of the inscribed circle of $T_k$.
+\end{enumerate}
+We put $h(\mathcal{T}_h)=\max\{\textrm{diam}(T_k)|\; T_k\in \mathcal{T}_h\}$,
+which is obtained by
+\bT
+ at mesh Th = ......;
+ at fespace Ph(Th,P0);
+Ph h = hTriangle;
+ at cout << "size of mesh = " << h[].max << @endl;
+\eT
+
+\subsection{Adaptmesh}\index{adaptmesh}
+\label{sec:Adaptmesh}
+The function
+\[
+f(x,y) = 10.0x^3+y^3+\tan^{-1}[\epsilon/(\sin(5.0y)-2.0x)]
+\qquad \epsilon =  0.0001
+\]
+sharply vary its value.
+However, the initial mesh given by the command in Section \ref{sec:InitialMesh}
+cannot reflect its sharp variation.
+\begin{example}~
+\bFF
+ at real eps =  0.0001;
+ at real h=1;
+ at real hmin=0.05;
+ at func f = 10.0*x^3+y^3+h*atan2(eps,sin(5.0*y)-2.0*x);
+
+ at mesh Th=square(5,5,[-1+2*x,-1+2*y]);
+ at fespace Vh(Th,P1);
+Vh fh=f;
+ at plot(fh);
+for (@int i=0;i<2;i++)
+ {
+   Th=@adaptmesh(Th,fh);
+   fh=f;  // old mesh is deleted
+   @plot(Th,fh,wait=1);
+ }
+\eFF
+\end{example}
+\plot[height=6cm]{adaptmesh}{3D graph under the initial mesh and after of 1st and 2nd adaptation}
+
+\freefempp uses a variable metric/Delaunay automatic meshing
+algorithm.
+The command
+\bT
+ at mesh ATh = @adaptmesh(Th, f);
+\eT
+create the new mesh \texttt{ATh} by the Hessian
+$$
+D^2f=(\partial^2 f/\partial x^2,\, \partial^2 f/\partial x\partial y,
+\partial^2 f/\partial y^2)
+$$
+of a function (formula or FE-function).
+Mesh adaptation is a very powerful tool when the solution of a problem
+vary locally and sharply.
+
+Here we solve the problem (\ref{eqn:Poisson})-(\ref{eqn:Dirichlet}),
+when $f=1$ and $\Omega$ is L-shape domain.
+
+\twoplot[height=5cm]{L-shape2}{lshapeSol}{ L-shape domain and its boundary name}{Final solution after 4-times adaptation}
+
+
+\begin{example}[Adapt.edp]
+\index{tutorial!adapt.edp}
+The solution has the
+\index{singularity}singularity $r^{3/2},\, r=|x-\gamma|$
+at the point $\gamma$ of the intersection of two lines
+$bc$ and $bd$ (see Fig. \ref{L-shape2}).
+\bFF
+ at border ba(t=0,1.0){x=t;   y=0;  label=1;};
+ at border bb(t=0,0.5){x=1;   y=t;  label=1;};
+ at border bc(t=0,0.5){x=1-t; y=0.5;label=1;};
+ at border bd(t=0.5,1){x=0.5; y=t;  label=1;};
+ at border be(t=0.5,1){x=1-t; y=1;  label=1;};
+ at border bf(t=0.0,1){x=0;   y=1-t;label=1;};
+ at mesh Th = @buildmesh ( ba(6)+bb(4)+bc(4)+bd(4)+be(4)+bf(6) );
+ at fespace Vh(Th, at P1);  // set FE space
+Vh u,v;             // set unknown and test function
+func f = 1;
+ at real error=0.1;        // level of error
+ at problem Poisson(u,v,solver=CG,eps=1.0e-6) =
+    @int2d(Th)(  dx(u)*dx(v) + dy(u)*dy(v))
+  - @int2d(Th) ( f*v )
+  + @on(1,u=0)  ;
+ at for (@int i=0;i< 4;i++)
+{
+  Poisson;
+  Th=@adaptmesh(Th,u,err=error);
+  error = error/2;
+} ;
+ at plot(u);
+\eFF
+\end{example}
+To speed up the adaptation
+we change by hand a default parameter \texttt{err} of
+\texttt{adaptmesh}\index{concatenation}, which
+specifies the required precision, so as to make the new mesh finer.
+The problem is coercive and symmetric,
+so the linear system can be solved with the conjugate gradient
+method \index{solver=!CG} (parameter \texttt{solver=CG}
+with the stopping criteria on the residual, here
+\texttt{eps=1.0e-6}).
+By \texttt{adaptmesh}, we get good slope of the final solution near
+the point of intersection of $bc$ and $bd$ as in Fig. \ref{lshapeSol}.
+
+This method is described in detail in \cite{bamg}. It has a number of
+default parameters which can be modified~:
+
+\index{adaptmesh}
+\begin{description}
+
+    \item[\texttt{hmin=}] Minimum edge size.  \index{adaptmesh!hmin=}
+    ({\tt val} is a real. Its default is related to
+    the size of the domain to be meshed and the precision of the mesh
+    generator).
+
+    \item[\texttt{hmax=}] Maximum edge size.  ({\tt val} is a real.
+    It defaults to the diameter of the domain to be
+    meshed) \index{adaptmesh!hmax=}
+
+    \item[\texttt{err=}] $P^1$ interpolation error level (0.01 is the
+    default).  \index{adaptmesh!err=}
+
+    \item[\texttt{errg=}] Relative geometrical error. By default this
+    error is 0.01, and in any case it must be lower than $1/\sqrt{2}$.
+    Meshes created with this option may have some edges smaller than
+    the {\tt -hmin } due to geometrical constraints.
+    \index{adaptmesh!errg=}
+
+    \item[\texttt{nbvx=}] Maximum number of vertices generated by the
+    mesh generator (9000 is the default).
+    \index{adaptmesh!nbvx=}
+
+    \item[\texttt{nbsmooth=}] number of iterations of the smoothing
+    procedure (5 is the default).  \index{adaptmesh!nbsmooth=}
+
+    \item[\texttt{nbjacoby=}] number of iterations in a smoothing
+    procedure during the metric construction, 0 means no smoothing (6
+    is the default).  \index{adaptmesh!nbjacoby=}
+
+    \item[\texttt{ratio=}] ratio for a prescribed smoothing on the
+    metric.  If the value is 0 or less than 1.1 no smoothing is done
+    on the metric (1.8 is the default).
+
+    If \texttt{ratio} $> 1.1$, the speed of mesh size variations is
+    bounded by $log(\mathtt{ratio})$.  Note: As {\tt ratio} gets
+    closer to {\tt 1}, the number of generated vertices increases.
+    This may be useful to control the thickness of refined regions
+    near shocks or boundary layers .  \index{adaptmesh!ratio=}
+
+   \item[\texttt{omega=}] relaxation parameter for the smoothing
+   procedure (1.0 is the default).  \index{adaptmesh!omega=}
+
+    \item[\texttt{iso=}] If true, forces the metric to be isotropic
+    (false is the default).  \index{adaptmesh!iso=}
+
+    \item[\texttt{abserror=}] If false, the metric is evaluated using
+    the criterium of equi-repartion of relative error (false is the
+    default).  In this case the metric is defined by
+
+\begin{equation}
+  \mathcal{M} = \left({1\over\mathtt{err}\,\, \mathtt{coef}^2} \quad {
+  |\mathcal{H}| \over max(\mathtt{CutOff},|\eta|)}\right)^p
+  \label{eq err rel}
+\end{equation}
+    \index{adaptmesh!abserror=}
+
+    otherwise, the metric is evaluated using the criterium of
+    equi-distribution of errors.  In this case the metric is defined
+    by
+
+\begin{equation}
+  \mathcal{M} = \left({1\over \mathtt{err}\,\,\mathtt{coef}^2} \quad
+  {|{\mathcal{H}|} \over
+  {\mathit{sup}(\eta)-\mathit{inf}(\eta)}}\right)^p.\label{eq err abs}
+\end{equation}
+
+    \item[\texttt{cutoff=}] lower limit for the relative error
+    evaluation (1.0e-6 is the default).
+    \index{adaptmesh!cutoff=}
+
+    \item[\texttt{verbosity=}] informational messages level (can be
+    chosen between 0 and $\infty$). Also changes the value of the
+    global variable verbosity (obsolete).  \index{adaptmesh!verbosity=
+    }
+
+    \item[\texttt{inquire=}] To inquire graphically about the mesh (false is the
+    default).  \index{adaptmesh!inquire=}
+
+    \item[\texttt{splitpbedge=}] If true, splits all internal edges in
+    half with two boundary vertices (true is the default).
+    \index{adaptmesh!splitpbedge=}
+
+    \item[\texttt{maxsubdiv=}] Changes the metric such that the
+    maximum subdivision of a background edge is bound by {\tt val}
+    (always limited by 10, and 10 is also the default).
+    \index{adaptmesh!maxsubdiv=}
+
+    \item[\texttt{rescaling=}] if true, the function with respect to
+    which the mesh is adapted is rescaled to be between 0 and 1 (true
+    is the default).  \index{adaptmesh!rescaling=}
+
+    \item[\texttt{keepbackvertices=}] if true, tries to keep as many
+    vertices from the original mesh as possible (true is the default).
+    \index{adaptmesh!keepbackvertices=}
+
+    \item[\texttt{isMetric=}] if true, the metric is defined
+    explicitly (false is the default).  If the 3 functions $m_{11},
+    m_{12}, m_{22}$ are given, they directly define a symmetric matrix
+    field whose Hessian is computed to define a metric. If only one
+    function is given, then it represents the isotropic mesh size at
+    every point.  \index{adaptmesh!isMetric=}
+
+    For example, if the partial derivatives
+    \texttt{fxx} ($=\partial^2 f/\partial x^2$),
+    \texttt{fxx} ($=\partial^2 f/\partial x\partial y$),
+    \texttt{fyy} ($=\partial^2 f/\partial y^2$) are given, we can set
+    $$
+    \ttCC{Th=@adaptmesh(Th,fxx,fxy,fyy,IsMetric=1,nbvx=10000,hmin=hmin);}
+    $$
+
+    \item[\texttt{power=}] exponent power of the Hessian used to
+    compute the metric (1 is the default).  \index{adaptmesh!powerin=}
+
+    \item[\texttt{thetamax=}] minimum corner angle in degrees (default
+    is 0).
+
+    \item[\texttt{splitin2=}] boolean value. If true, splits all
+    triangles of the final mesh into 4
+    sub-triangles. \index{adaptmesh!splitin2}
+
+    \item[\texttt{metric=}] \index{adaptmesh!metric=} an array of 3
+    real arrays to set or get metric data information. The size of
+    these three arrays must be the number of vertices. So if
+    \texttt{m11,m12,m22} are three P1 finite elements related to the
+    mesh to adapt, you can write: \texttt{metric=[m11[],m12[],m22[]]}
+    (see file convect-apt.edp for a full example)
+
+    \itemtt[nomeshgeneration=] \index{adaptmesh!nomeshgeneration=} If
+    true, no adapted mesh is generated (useful to compute only a
+    metric).
+
+    \itemtt[periodic=] \index{adaptmesh!periodic=} %%% modif FH
+    As writing \texttt{periodic=[[4,y],[2,y],[1,x],[3,x]];}
+    it builds an adapted periodic mesh. The sample
+    build a biperiodic mesh of a square.
+    (see periodic finite element   spaces \ref{periodic BC}, and see \texttt{sphere.edp} for a  full example)
+
+\end{description}
+
+%%%alh proofreading ok up to here
+
+\subsection{Trunc}\index{trunc}
+
+  A small operator to create a truncated mesh from a mesh with respect to a
+boolean function.
+
+The two named parameter
+\begin{description} \index{split=} \index{label=}\index{trunc!split=} \index{trunc!label=}
+  \itemtt[label=] sets the label number of new boundary item (one by default)
+  \itemtt[split=] sets the level $n$ of triangle splitting. each triangle is splitted in  $n\times n$ ( one by default).
+\end{description}
+
+To create the mesh \texttt{Th3}
+where alls  triangles of a mesh \texttt{Th}  are splitted in $3{\times}3$ , just write:
+\bFF
+  mesh Th3 = trunc(Th,1,split=3);
+\eFF
+
+The  \texttt{truncmesh.edp} example construct
+all "trunc" mesh  to the support of the basic function  of the space \texttt{Vh} (cf. \texttt{abs(u)>0}),
+split all the  triangles in $5{\times} 5$, and put a label number to $2$ on new boundary.
+\bFF
+ at mesh Th=square(3,3);
+ at fespace Vh(Th,P1);
+Vh u;
+ at int i,n=u.n;
+u=0;
+ at for (i=0;i<n;i++)  // all degree of freedom
+ {
+  u[][i]=1;        //  the basic function i
+  @plot(u,wait=1);
+  @mesh Sh1=trunc(Th,abs(u)>1.e-10,split=5,label=2);
+  plot(Th,Sh1,wait=1,ps="trunc"+i+".eps");// plot the mesh of
+  // the function's support
+  u[][i]=0;      // reset
+ }
+\eFF
+\twoplot[height=6cm]{trunc0}{trunc6}{ mesh of support the function P1  number 0, splitted in $5{\times}5$ }{
+mesh of support the function P1  number 6, splitted in $5{\times}5$ }
+\subsection{splitmesh}
+A other way to split mesh triangle:
+\bFF
+{  //  new stuff 2004 splitmesh (version 1.37)
+  assert(version>=1.37);
+  @border a(t=0,2*pi){ x=cos(t); y=sin(t);label=1;}
+  @plot(Th,wait=1,ps="nosplitmesh.eps"); // see figure \ref{fig nosplitmesh}
+  @mesh Th=@buildmesh(a(20));
+  @plot(Th,wait=1);
+  @Th=@splitmesh(Th,1+5*(square(x-0.5)+y*y));
+  @plot(Th,wait=1,ps="splitmesh.eps"); // see figure \ref{fig splitmesh}
+}
+\eFF
+
+\twoplot[height=6cm]{nosplitmesh}{splitmesh}{\label{fig nosplitmesh}initial mesh}{\label{fig splitmesh}all left mesh triangle is split  conformaly in \texttt{int(1+5*(square(x-0.5)+y*y)\^2} triangles.}
+
+
+\subsection{\setS{Meshing Examples}}
+
+\begin{example}[Two rectangles touching by a side]~
+\index{mesh!beam}
+\bFF
+ at border a(t=0,1){x=t;y=0;};
+ at border b(t=0,1){x=1;y=t;};
+ at border c(t=1,0){x=t ;y=1;};
+ at border d(t=1,0){x = 0; y=t;};
+ at border c1(t=0,1){x=t ;y=1;};
+ at border e(t=0,0.2){x=1;y=1+t;};
+ at border f(t=1,0){x=t ;y=1.2;};
+ at border g(t=0.2,0){x=0;y=1+t;};
+ at int n=1;
+ at mesh th = @buildmesh(a(10*n)+b(10*n)+c(10*n)+d(10*n));
+ at mesh TH = @buildmesh ( c1(10*n) + e(5*n) + f(10*n) + g(5*n) );
+ at plot(th,TH,ps="TouchSide.esp"); // Fig. \ref{TouchSide}
+\eFF
+\end{example}
+
+\begin{example}[NACA0012 Airfoil]~
+\index{mesh!NACA0012}
+\bFF
+ at border upper(t=0,1) { x = t;
+     y = 0.17735*sqrt(t)-0.075597*t
+  - 0.212836*(t^2)+0.17363*(t^3)-0.06254*(t^4); }
+ at border lower(t=1,0) { x = t;
+     y= -(0.17735*sqrt(t)-0.075597*t
+  -0.212836*(t^2)+0.17363*(t^3)-0.06254*(t^4)); }
+ at border c(t=0,2*pi) { x=0.8*cos(t)+0.5;  y=0.8*sin(t); }
+ at mesh Th = @buildmesh(c(30)+upper(35)+lower(35));
+ at plot(Th, at ps="NACA0012.eps", at bw=1);  // Fig. \ref{NACA0012}
+\eFF
+\end{example}
+
+\twoplot[height=5cm]{TouchSide}{NACA0012}{Two rectangles touching by a side}
+{NACA0012 Airfoil}
+
+\begin{example}[Cardioid]~
+\index{mesh!Cardioid}
+\bFF
+ at real b = 1, a = b;
+ at border C(t=0,2*pi) { x=(a+b)*cos(t)-b*cos((a+b)*t/b);
+                        y=(a+b)*sin(t)-b*sin((a+b)*t/b); }
+ at mesh Th = @buildmesh(C(50));
+ at plot(Th, at ps="Cardioid.eps",bw=1); // Fig. \ref{Cardioid}
+\eFF
+\end{example}
+\begin{example}[Cassini Egg]~
+\index{mesh!Cassini Egg}
+\bFF
+ at border C(t=0,2*pi) { x=(2*cos(2*t)+3)*cos(t);
+                      y=(2*cos(2*t)+3)*sin(t); }
+ at mesh Th = @buildmesh(C(50));
+ at plot(Th, at ps="Cassini.eps",bw=1); // Fig. \ref{Cassini}
+\eFF
+\end{example}
+\twoplot[height=5cm]{Cardioid}{Cassini}{Domain with Cardioid curve boundary}
+{Domain with Cassini Egg curve boundary}
+
+\begin{example}[By cubic Bezier curve]~
+\index{mesh!Bezier curve}
+\bFF
+// A cubic Bezier curve connecting two points with two control points
+ at func @real @bzi(@real p0, at real p1, at real q1, at real q2, at real t)
+{
+  @return p0*(1-t)^3+q1*3*(1-t)^2*t+q2*3*(1-t)*t^2+p1*t^3;
+}
+
+real[int] p00=[0,1], p01=[0,-1], q00=[-2,0.1], q01=[-2,-0.5];
+real[int] p11=[1,-0.9], q10=[0.1,-0.95], q11=[0.5,-1];
+real[int] p21=[2,0.7], q20=[3,-0.4], q21=[4,0.5];
+real[int] q30=[0.5,1.1], q31=[1.5,1.2];
+ at border G1(t=0,1) { x=bzi(p00[0],p01[0],q00[0],q01[0],t);
+                   y=bzi(p00[1],p01[1],q00[1],q01[1],t); }
+ at border G2(t=0,1) { x=bzi(p01[0],p11[0],q10[0],q11[0],t);
+                   y=bzi(p01[1],p11[1],q10[1],q11[1],t); }
+ at border G3(t=0,1) { x=bzi(p11[0],p21[0],q20[0],q21[0],t);
+                   y=bzi(p11[1],p21[1],q20[1],q21[1],t); }
+ at border G4(t=0,1) { x=bzi(p21[0],p00[0],q30[0],q31[0],t);
+                   y=bzi(p21[1],p00[1],q30[1],q31[1],t); }
+ at int m=5;
+ at mesh Th = @buildmesh(G1(2*m)+G2(m)+G3(3*m)+G4(m));
+ at plot(Th,ps="Bezier.eps",bw=1);  // Fig \ref{Bezier}
+\eFF
+\end{example}
+
+\begin{example}[Section of Engine]~
+\index{mesh!Section of Engine}
+\bFF
+real a= 6., b= 1., c=0.5;
+border L1(t=0,1) { x= -a; y= 1+b - 2*(1+b)*t; }
+border L2(t=0,1) { x= -a+2*a*t; y= -1-b*(x/a)*(x/a)*(3-2*abs(x)/a );}
+border L3(t=0,1) { x= a; y=-1-b + (1+ b )*t; }
+border L4(t=0,1) { x= a - a*t;   y=0; }
+border L5(t=0,pi) { x= -c*sin(t)/2; y=c/2-c*cos(t)/2; }
+border L6(t=0,1) { x= a*t;  y=c; }
+border L7(t=0,1) { x= a;  y=c + (1+ b-c )*t; }
+border L8(t=0,1) { x= a-2*a*t; y= 1+b*(x/a)*(x/a)*(3-2*abs(x)/a); }
+mesh Th = buildmesh(L1(8)+L2(26)+L3(8)+L4(20)+L5(8)+L6(30)+L7(8)+L8(30));
+plot(Th,ps="Engine.eps",bw=1); // Fig. \ref{Engine}
+\eFF
+\end{example}
+
+\begin{figure}[hbt]
+\begin{multicols}{2}
+\begin{center}
+\includegraphics*[height=5cm]{Bezier}
+\caption{\label{Bezier} Boundary drawed by Bezier curves}
+\end{center}
+\begin{center}
+\vspace{3cm}~~\par
+\includegraphics*[height=2.8cm]{Engine}
+\caption{\label{Engine} Section of Engine}
+\end{center}
+\end{multicols}
+\end{figure}
+
+\begin{example}[Domain with U-shape channel]~
+\index{mesh!U-shape channel}
+\bFF
+ at real d = 0.1; // width of U-shape
+ at border L1(t=0,1-d) { x=-1; y=-d-t; }
+ at border L2(t=0,1-d) { x=-1; y=1-t; }
+ at border B(t=0,2) { x=-1+t; y=-1; }
+ at border C1(t=0,1) { x=t-1; y=d; }
+ at border C2(t=0,2*d) { x=0; y=d-t; }
+ at border C3(t=0,1) { x=-t; y=-d; }
+ at border R(t=0,2) { x=1; y=-1+t; }
+ at border T(t=0,2) { x=1-t; y=1; }
+ at int n = 5;
+ at mesh Th = buildmesh (L1(n/2)+L2(n/2)+B(n)+C1(n)+C2(3)+C3(n)+R(n)+T(n));
+ at plot(Th,ps="U-shape.eps",bw=1); // Fig \ref{U-shape}
+\eFF
+\end{example}
+\begin{example}[Domain with V-shape cut]~
+\index{mesh!V-shape cut}
+\bFF
+ at real dAg = 0.01; // angle of V-shape
+ at border C(t=dAg,2*pi-dAg) { x=cos(t); y=sin(t); };
+ at real[int] pa(2), pb(2), pc(2);
+pa[0] = cos(dAg); pa[1] = sin(dAg);
+pb[0] = cos(2*pi-dAg); pb[1] = sin(2*pi-dAg);
+pc[0] = 0; pc[1] = 0;
+ at border seg1(t=0,1) { x=(1-t)*pb[0]+t*pc[0]; y=(1-t)*pb[1]+t*pc[1]; };
+ at border seg2(t=0,1) { x=(1-t)*pc[0]+t*pa[0]; y=(1-t)*pc[1]+t*pa[1]; };
+ at mesh Th = @buildmesh(seg1(20)+C(40)+seg2(20));
+ at plot(Th, at ps="V-shape.eps", at bw=1);  // Fig. \ref{V-shape}
+\eFF
+\end{example}
+\twoplot[height=5cm]{U-shape}{V-shape}{Domain with U-shape channel changed by \ttCC{d}}
+{Domain with V-shape cut changed by \ttCC{dAg}}
+
+\begin{example}[Smiling face]~
+\index{mesh!Smiling face}
+\bFF
+ at real d=0.1;
+ at int m=5;
+ at real a=1.5, b=2, c=0.7, e=0.01;
+ at border F(t=0,2*pi) { x=a*cos(t); y=b*sin(t); }
+ at border E1(t=0,2*pi) { x=0.2*cos(t)-0.5; y=0.2*sin(t)+0.5; }
+ at border E2(t=0,2*pi) { x=0.2*cos(t)+0.5; y=0.2*sin(t)+0.5; }
+ at func @real @st(real t) {
+   @return sin(pi*t)-pi/2;
+}
+ at border C1(t=-0.5,0.5) { x=(1-d)*c*cos(st(t)); y=(1-d)*c*sin(st(t)); }
+ at border C2(t=0,1){x=((1-d)+d*t)*c*cos(st(0.5));y=((1-d)+d*t)*c*sin(st(0.5));}
+ at border C3(t=0.5,-0.5) { x=c*cos(st(t)); y=c*sin(st(t)); }
+ at border C4(t=0,1) { x=(1-d*t)*c*cos(st(-0.5)); y=(1-d*t)*c*sin(st(-0.5));}
+
+ at border C0(t=0,2*pi) { x=0.1*cos(t); y=0.1*sin(t); }
+ at mesh Th=@buildmesh(F(10*m)+C1(2*m)+C2(3)+C3(2*m)+C4(3)
+                  +C0(m)+E1(-2*m)+E2(-2*m));
+ at plot(Th, at ps="SmileFace.eps", at bw=1);  // see Fig. \ref{SmileFace}
+}\eFF
+\end{example}
+
+\begin{example}[3point bending]~
+\index{mesh!3point bending}
+\bFF
+// Square for Three-Point Bend Specimens fixed on \ttCC{Fix1, Fix2}
+// It will be loaded on \ttCC{Load}.
+ at real a=1, b=5, c=0.1;
+ at int n=5, m=b*n;
+ at border Left(t=0,2*a) { x=-b; y=a-t; }
+ at border Bot1(t=0,b/2-c) { x=-b+t; y=-a; }
+ at border Fix1(t=0,2*c) { x=-b/2-c+t; y=-a; }
+ at border Bot2(t=0,b-2*c) { x=-b/2+c+t; y=-a; }
+ at border Fix2(t=0,2*c) { x=b/2-c+t; y=-a; }
+ at border Bot3(t=0,b/2-c) { x=b/2+c+t; y=-a; }
+ at border Right(t=0,2*a) { x=b; y=-a+t; }
+ at border Top1(t=0,b-c) { x=b-t; y=a; }
+ at border Load(t=0,2*c) { x=c-t; y=a; }
+ at border Top2(t=0,b-c) { x=-c-t; y=a; }
+mesh Th = buildmesh(Left(n)+Bot1(m/4)+Fix1(5)+Bot2(m/2)+Fix2(5)+Bot3(m/4)
+                    +Right(n)+Top1(m/2)+Load(10)+Top2(m/2));
+plot(Th,ps="ThreePoint.eps",bw=1); // Fig. \ref{ThreePoint}
+\eFF
+\end{example}
+
+\begin{figure}[hbt]
+\begin{multicols}{2}
+\begin{center}
+\includegraphics*[height=5cm]{SmileFace}
+\caption{\label{SmileFace} Smiling face (Mouth is changeable)}
+\end{center}
+\begin{center}
+\vspace{2cm}~~\par
+\includegraphics*[height=2.8cm]{ThreePoint}
+\caption{\label{ThreePoint} Domain for three-point bending test}
+\end{center}
+\end{multicols}
+\end{figure}
+
+
+\section{\setS{Finite Elements}} \index{finite element space}
+As stated in Step2 in Section \ref{sec:example}.
+FEM make approximations all functions $w$ to
+\[
+w(x,y)\simeq w_0\phi_0(x,y)+w_1\phi_1(x,y)+\cdots+w_{M-1}\phi_{M-1}(x,y)
+\]
+with finite basis functions $\phi_k(x,y)$ and numbers $w_k$ ($k=0,\cdots,M-1$).
+The functions $\phi_k(x,y)$ is constructed from the triangle $T_{i_k}$, so
+$\phi_k(x,y)$ is called \emph{shape function}.
+The finite element space
+$$
+V_h=\left\{w\left|\; w_0\phi_0+w_1\phi_1+\cdots+w_{M-1}\phi_{M-1},\,
+w_i\in \R\right.\right\}
+$$ is easily created by
+\bT
+     @fespace IDspace(IDmesh,<IDFE>) ;
+\eT
+or with $\ell$ pair of periodic boundary condition
+\bT
+     @fespace IDspace(IDmesh,<IDFE>,
+                      periodic=[[la$_1$,sa$_1$],[lb$_1$,sb$_1$],
+                                ...
+                                [la$_k$,sa$_k$],[lb$_k$,sb$_\ell$]]);
+\eT
+where
+\index{fespace}\index{periodic}
+\ttCC{IDspace} is the name of the space (e.g. \ttCC{Vh}),
+\ttCC{IDmesh} is the name of the associated mesh and  \ttCC{<IDFE>}
+is a identifier of finite element type.
+In a pair of periodic boundary condition, \label{periodic BC}
+if \ttCC{[la$_i$,sa$_i$],[lb$_i$,sb$_i$]} is a pair of
+\texttt{int}, this expressions the 2 labels \ttCC{la$_i$} and \ttCC{lb$_i$}
+of the piece of the boundary to be equivalence;
+If \ttCC{[la$_i$,sa$_i$],[lb$_i$,sb$_i$]} is a pair of \texttt{real},
+this expressions \ttCC{sa$_i$} and \ttCC{sb$_i$}
+give two common abscissa on the two boundary curve, and two points are identify
+if the two abscissa are equal.
+
+
+\medskip
+ As of today, the known
+types of finite element are: \index{type of finite element}
+\begin{description}
+     \item[P0]  piecewise constante discontinuous finite element
+     \index{P0|textbf}\index{fespace!P0}
+    \begin{eqnarray}
+    \label{eq:P0}
+     P0_{h} = \left\{ v \in L^2(\Omega) \left|\; \textrm{for all }K \in \mathcal{T}_{h}\;\;\textrm{there is }\alpha_{K}\in \R :
+        \;\; v_{|K} = \alpha_{K } \right.\right\}
+     \end{eqnarray}
+     \item[P1]  piecewise linear  continuous finite element
+     \index{P1|textbf}\index{fespace!P1}
+     \begin{eqnarray}
+     &&P1_{h} = \left\{ v \in H^{1}(\Omega) \left|\; \forall K \in \mathcal{T}_{h}
+        \quad v_{|K} \in P_{1} \right.\right\} \label{eq:P1}
+     \end{eqnarray}
+     \item[P1dc]  piecewise linear  discontinuous finite element
+     \index{P1dc|textbf}\index{fespace!P1dc}
+     \begin{equation}
+     P1dc_{h} = \left\{ v \in L^{2}(\Omega) \left|\; \forall K \in \mathcal{T}_{h}
+        \quad v_{|K} \in P_{1} \right.\right\} \label{eq:P1dc}
+     \end{equation}
+     \item[P1b]  piecewise linear  continuous finite element plus bubble
+     \index{P1b|textbf}\index{fespace!P1b}
+     \begin{equation}
+     P1b_{h} = \left\{ v \in H^{1}(\Omega) \left|\; \forall K \in \mathcal{T}_{h}
+        \quad v_{|K} \in P_{1} \oplus Span\{  \lambda^{K}_{0} \lambda^{K}_{1} \lambda^{K}_{2} \} \right.\right\} \label{eq:P1b}
+     \end{equation}
+     where $\lambda ^{K}_{i}, i=0,1,2$ are the 3 area coordinate functions of the triangle $K$
+
+     \item[P2] piecewise $P_{2}$  continuous finite element,
+     \index{P2|textbf}\index{fespace!P2}
+     \begin{equation}
+     P2_{h} = \left\{ v \in H^{1}(\Omega) \left|\; \forall K \in \mathcal{T}_{h}
+        \quad v_{|K} \in P_{2} \right.\right\}
+     \end{equation}
+     where
+     $P_{2}$ is the set of polynomials of $\R^{2}$ of  degrees $\le 2$.
+     \item[P2b] piecewise $P_{2} $ continuous finite element  plus bubble,
+     \index{P2|textbf}\index{fespace!P2}
+     \begin{equation}
+     P2_{h} = \left\{ v \in H^{1}(\Omega) \left|\; \forall K \in \mathcal{T}_{h}
+        \quad v_{|K} \in P_{2} \oplus Span\{  \lambda^{K}_{0} \lambda^{K}_{1} \lambda^{K}_{2} \} \right.\right\}
+     \end{equation}
+
+     \item[P2dc] piecewise $P_{2}$  discontinuous finite element,
+     \index{P2dc|textbf}\index{fespace!P2dc}
+     \begin{equation}
+     P2dc_{h} = \left\{ v \in L^{2}(\Omega) \left|\; \forall K \in \mathcal{T}_{h}
+        \quad v_{|K} \in P_{2} \right.\right\}
+     \end{equation}
+     \item[RT0]  Raviart-Thomas finite element
+     \index{RT0|textbf}\index{fespace!RT0}
+     \begin{equation}
+         RT0_{h} = \left\{ \mathbf{v} \in H(\textrm{div}) \left|\; \forall K \in
+         \mathcal{T}_{h} \quad  \mathbf{v}_{|K}(x,y) =
+         \vecttwo{\alpha_{K}}{\beta_{K}} + \gamma_{K}\vecttwo{x}{y}  \right.\right\}
+         \label{eq:RT0}
+     \end{equation}
+      where by writing
+      $\textrm{div }\mathbf{w}=\partial w_1/\partial x+\partial w_2/\partial y,
+      \, \mathbf{w}=(w_1,w_2)$,
+      $$
+      H(\textrm{div})=\left\{\mathbf{w}\in L^{2}(\Omega)^2\left|
+      \textrm{div } \mathbf{w}\in L^{2}(\Omega)
+      \right.\right\}
+      $$
+      and
+      $\alpha_{K},\beta_{K},\gamma_{K} $ are real numbers.
+     \item[P1nc] \index{P1nc|textbf}\index{fespace!P1nc} piecewise linear   element continuous at
+     the middle of edge only.
+
+\end{description}
+
+If we get the finite element spaces
+$$  X_{h} = \{ v \in H^{1}(]0,1[^2) |\; \forall K \in \mathcal{T}_{h}
+\quad v_{|K} \in
+P_{1} \}$$
+$$ X_{ph} = \{  v \in X_{h} |\; v(\vecttwo{0}{.} ) =  v(\vecttwo{1}{.}) , v(\vecttwo{.}{0} ) =  v(\vecttwo{.}{1} )  \}$$
+$$  M_{h} = \{ v \in H^{1}(]0,1[^2) |\; \forall K \in \mathcal{T}_{h}
+\quad v_{|K} \in
+P_{2} \}$$
+$$  R_{h} = \{ \mathbf{v} \in H^{1}(]0,1[^2)^{2} |\; \forall K \in \mathcal{T}_{h}
+\quad
+ \mathbf{v}_{|K}(x,y) =
+         \vecttwo{\alpha_{K}}{\beta_{K}} + \gamma_{K}\vecttwo{x}{y} \}$$
+
+when $\mathcal{T}_h$ is a mesh $10\times 10$ of the unit square $]0,1[^2$,
+we only write in \freefempp as follows:
+\bT
+ at mesh Th=@square(10,10);
+ at fespace Xh(Th, at P1);      //  scalar FE
+ at fespace Xph(Th,P1,
+         periodic=[[2,y],[4,y],[1,x],[3,x]]);//bi-periodic FE
+ at fespace Mh(Th, at P2);      //  scalar FE
+ at fespace Rh(Th, at RT0);     //  vectorial FE
+\eT
+where \texttt{Xh,Mh,Rh} expresses finite element spaces (called FE spaces
+\index{FE space}) $X_h,\, M_h,\, R_h$, respectively.
+If we want use FE-functions
+$ u_{h},v_{h} \in X_{h} $ and $ p_{h},q_{h} \in M_{h} $
+and $U_{h},V_{h} \in R_{h}$
+\index{FE-function}, we write in \freefempp
+\bT
+  Xh uh,vh;
+  Xph uph,vph;
+  Mh ph,qh;
+  Rh [Uxh,Uyh],[Vxh,Vyh];
+  Xh[@int] Uh(10); //  array of 10 function in Xh
+  Rh[@int] [Wxh,Wyh](10); //  array of 10 functions in Rh.\index{array!fespace}
+\eT
+
+The functions $U_{h},V_{h}$ have two components so we have
+$$U_{h}=\vecttwo{Uxh}{Uyh}  \quad \mbox{and}\quad V_{h}=\vecttwo{Vxh}{Vyh}$$
+
+\subsection{Lagrange finite element}
+\label{sec:P0P1P2}
+\subsubsection{P0-element}
+For each triangle $T_k$, the basis function $\phi_k$ in \texttt{Vh(Th,P0)}
+is given by
+$$
+\phi_k(x,y)=1\textrm{ if }(x,y)\in T_k,\qquad
+\phi_k(x,y)=0\textrm{ if }(x,y)\not\in T_k
+$$
+If we write
+\bT
+Vh(Th, at P0);  Vh fh=$f(x.y)$;
+\eT
+then for vertices $q^{k_i},\, i=1,2,3$ in Fig. \ref{P1P2}(a),
+$$
+\ttCC{fh}=f_h(x,y)=\sum_{k=1}^{n_t}\frac{f(q^{k_1})+f(q^{k_2})+f(q^{k_3})}{3}\phi_k
+$$
+See Fig. \ref{projP0} for the projection of $f(x,y)=\sin(\pi x)\cos(\pi y)$
+into \ttCC{Vh(Th, at P0)} when
+the mesh \ttCC{Th} with $4\times 4$-grid of $[-1,1]^2$ as in Fig. \ref{P0P1P2P1nc}.
+
+\subsubsection{P1-element}
+\plot[height=4cm]{P1P2}{$P_1$  and $P_2$ degrees of freedom on triangle $T_k$}
+
+For each vertex $q^i$, the basis function $\phi_i$ in \texttt{Vh(Th,P1)}
+is given by
+\begin{eqnarray*}
+&&\phi_i(x,y)=a^k_i+b^k_ix+c^k_iy~\textrm{for }(x,y)\in T_k,\\
+&&\phi_i(q^i)=1,\quad \phi_i(q^j)=0\textrm{ if }i\neq j
+\end{eqnarray*}
+The basis function $\phi_{k_1}(x,y)$ with the vertex $q^{k_1}$ in
+Fig. \ref{P1P2}(a) at point $p=(x,y)$ in triangle $T_k$ simply coincide with the
+\emph{barycentric coordinates $\lambda^k_1$ (area coordinates)} :
+$$
+\phi_{k_1}(x,y) = \lambda^k_{1}(x,y)=
+\frac{\textrm{area of triangle} (p, q^{k_2},q^{k_3})}
+{\textrm{area of triangle}(q^{k_1},q^{k_2},q^{k_3})}
+$$
+If we write
+\bT
+Vh(Th, at P1); Vh fh=$g(x.y)$;
+\eT
+then
+$$
+\ttCC{fh}=f_h(x,y)=\sum_{i=1}^{n_v}f(q^i)\phi_i(x,y)
+$$
+See Fig. \ref{projP1} for the projection of $f(x,y)=\sin(\pi x)\cos(\pi y)$
+into \ttCC{Vh(Th, at P1)}.
+
+\twoplot[height=5cm]{P0P1P2P1nc}{projP0}{Test mesh \texttt{Th} for projection}{projection to \texttt{Vh(Th,P0)}}
+
+\subsubsection{P2-element}
+For each vertex or midpoint $q^i$. the basis function $\phi_i$ in \texttt{Vh(Th,P2)}
+is given by
+\begin{eqnarray*}
+&&\phi_i(x,y)=a^k_i+b^k_ix+c^k_iy+d^k_ix^2+e^k_ixy+f^f_jy^2~\textrm{for }(x,y)\in T_k,\\
+&&\phi_i(q^i)=1,\quad \phi_i(q^j)=0\textrm{ if }i\neq j
+\end{eqnarray*}
+The basis function $\phi_{k_1}(x,y)$ with the vertex $q^{k_1}$ in
+Fig. \ref{P1P2}(b) is defined by the \emph{barycentric coordinates}:
+$$
+\phi_{k_1}(x,y) = \lambda^k_{1}(x,y)(2\lambda^k_1(x,y)-1)
+$$
+and for the midpoint $q^{k_2}$
+$$
+\phi_{k_2}(x,y) = 4\lambda^k_1(x,y)\lambda^k_4(x,y)
+$$
+If we write
+\bT
+Vh(Th, at P2); Vh fh=$f(x.y)$;
+\eT
+then
+$$
+\ttCC{fh}=f_h(x,y)=\sum_{i=1}^{M}f(q^i)\phi_i(x,y)\quad (\textrm{summation over all vetex or midpoint})
+$$
+See Fig. \ref{projP2} for the projection of $f(x,y)=\sin(\pi x)\cos(\pi y)$
+into \ttCC{Vh(Th, at P2)}.
+
+\twoplot[height=5cm]{projP1}{projP2}{projection to \texttt{Vh(Th,P1)}}{projection to \texttt{Vh(Th,P2)}}
+
+\subsection{P1 Nonconforming Element}
+Refer \cite{Thomasset} for detail.
+In \refSec{P0P1P2}, the approximation are a continuous function all
+over the domain, and
+$$
+w_h\in V_h\subset H^1(\Omega)
+$$
+However, we allow the continuity requirement to be relaxed.
+If we write
+\bT
+Vh(Th, at P1nc); Vh fh=$f(x.y)$;
+\eT
+then
+$$
+\ttCC{fh}=f_h(x,y)=\sum_{i=1}^{n_v}f(m^i)\phi_i(x,y)\quad (\textrm{summation over all midpoint})
+$$
+Here the basis function $\phi_i$ associated with the midpoint
+$m^i=(q^{k_i}+q^{k_{i+1}})/2$ where $q^{k_i}$ is the $i$-th point in $T_k$,
+and we assume that $j+1=0$ if $j=3$:
+\begin{eqnarray*}
+&&\phi_i(x,y)=a^k_i+b^k_ix+c^k_iy~\textrm{for }(x,y)\in T_k,\\
+&&\phi_i(m^i)=1,\quad \phi_i(m^j)=0\textrm{ if }i\neq j
+\end{eqnarray*}
+
+Strictly speaking $\partial \phi_i/\partial x,\, \partial \phi_i/\partial y$
+contain Dirac distribution $\rho \delta_{\partial T_k}$.
+The numerical calculations will automatically \emph{ignore} them.
+In \cite{Thomasset}, there is a proof of the estimation
+\[
+\left(\sum_{k=1}^{n_v}\int_{T_k}|\nabla w-\nabla w_h|^2dxdy\right)^{1/2}
+=O(h)
+\]
+The basis functions $\phi_k$ have the following properties.
+\begin{enumerate}
+  \item
+  For the bilinear form $a$ defined in (\ref{eqn:bilinear}) satisfy
+  \begin{eqnarray*}
+  &&a(\phi_i,\phi_i)>0,\qquad a(\phi_i,\phi_j)\le 0\quad\textrm{if }i\neq j\\
+  &&\sum_{k=1}^{n_v}a(\phi_i,\phi_k)\ge 0
+  \end{eqnarray*}
+  \item
+  $f\ge 0 \Rightarrow u_h\ge 0$
+  \item If $i\neq j$, the basis function $\phi_i$ and $\phi_j$ are $L^2$-orthogonal:
+  $$
+  \int_{\Omega}\phi_i\phi_j\, dxdy=0\qquad \textrm{if }i\neq j
+  $$
+  which is false for $P_1$-element.
+\end{enumerate}
+See Fig. \ref{projP1nc} for the projection of $f(x,y)=\sin(\pi x)\cos(\pi y)$
+into \ttCC{Vh(Th, at P1nc)}.
+See Fig. \ref{projP1nc} for the projection of $f(x,y)=\sin(\pi x)\cos(\pi y)$
+into \ttCC{Vh(Th, at P1nc)}.
+
+\twoplot[height=5cm]{projP1nc}{projP1b}{projection to \texttt{Vh(Th,P1nc)}}{projection to \texttt{Vh(Th,P1b)}}
+
+\subsection{Other FE-space}
+For each triangle $T_k\in \mathcal{T}_h$,
+let $\lambda_{k_1}(x,y),\, \lambda_{k_2}(x,y),\, \lambda_{k_3}(x,y)$ be
+the area cordinate
+of the triangle (see Fig. \ref{P1P2}), and put
+\begin{equation}
+\beta_k(x,y)=27\lambda_{k_1}(x,y)\lambda_{k_2}(x,y)\lambda_{k_3}(x,y)
+\end{equation}
+called \emph{bubble}\index{bubble} function on $T_k$.
+The bubble function has the feature:
+\begin{enumerate}
+  \item
+  $\beta_k(x,y)=0\quad \textrm{if }(x,y)\in \partial T_k$.
+  \item
+  $\beta_k(q^{k_b})=1$ where $q^{k_b}$ is the barycenter
+  $\frac{q^{k_1}+q^{k_2}+q^{k_3}}{3}$.
+\end{enumerate}
+If we write
+\bT
+Vh(Th, at P1b); Vh fh=$f(x.y)$;
+\eT
+then
+$$
+\texttt{fh}=f_h(x,y)=\sum_{i=1}^{n_v}f(q^i)\phi_i(x,y)+\sum_{k=1}^{n_t}f(q^{k_b})\beta_k(x,y)
+$$
+See Fig. \ref{projP1b} for the projection of $f(x,y)=\sin(\pi x)\cos(\pi y)$
+into \ttCC{Vh(Th, at P1b)}.
+
+
+\subsection{Vector valued FE-function}
+Functions from  $\R^{2}$ to $\R^{N}$ with $N=1$ is called scalar function and
+called \emph{vector valued} when $N>1$.
+When $N=2$
+\bT
+     @fespace Vh(Th,[@P0, at P1]) ;
+\eT
+make the space
+\[
+V_h=\{\mathbf{w}=(w_1,w_2)|\; w_1\in V_h(\mathcal{T}_h,P_0),\,
+w_2\in V_h(\mathcal{T}_h,P_1)\}
+\]
+
+\subsubsection{Raviart-Thomas element}
+In the Raviart-Thomas finite element $RT0_{h}$,
+the degree of freedom are the flux  throw an edge $e$ of the mesh, where the flux of the function $\mathbf{f} : \R^2 \longrightarrow \R^2 $ is $\int_{e} \mathbf{f}.n_{e}$,
+ $n_{e}$ is the unit normal of edge $e$.
+
+ This implies a orientation of all the edges of the mesh,
+ for example we can use the global numbering of the edge vertices and we just go to small to large number.
+
+To compute the flux, we use an quadrature formulation with one point, the middle point of the edge. Consider a triangle $T_k$ with three vertices $(\mathbf{a},\mathbf{b},\mathbf{c})$.
+Let denote the  vertices numbers by $i_{a},i_{b},i_{c}$, and define the three edge vectors $\mathbf{e}^{1},\mathbf{e}^{2},\mathbf{e}^{3}$
+by $ sgn(i_{b}-i_{c})(\mathbf{b}-\mathbf{c})$, $sgn(i_{c}-i_{a})(\mathbf{c}-\mathbf{a})$, $sgn(i_{a}-i_{b})(\mathbf{a}-\mathbf{b})$,
+
+We get three basis functions,
+\begin{equation}
+\boldsymbol{\phi}^{k}_{1}= \frac{sgn(i_{b}-i_{c})}{2|T_k|}(\mathbf{x}-\mathbf{a}),\quad
+\boldsymbol{\phi}^{k}_{2}= \frac{sgn(i_{c}-i_{a})}{2|T_k|}(\mathbf{x}-\mathbf{b}),\quad
+\boldsymbol{\phi}^{k}_{3}= \frac{sgn(i_{a}-i_{b})}{2|T_k|}(\mathbf{x}-\mathbf{c}),
+\end{equation}
+where $|T_k|$ is the area of the triangle $T_k$.
+If we write
+\bT
+Vh(Th, at RT0); Vh [f1h,f2h]=[$f1(x.y),f2(x,y)$];
+\eT
+then
+$$
+\ttCC{fh}=\vec{f}_h(x,y)=\sum_{k=1}^{n_t}\sum_{l=1}^6
+n_{i_lj_l}|\mathbf{e^{i_l}}|f_{j_l}(m^{i_l})
+\phi_{i_lj_l}
+$$
+where $n_{i_lj_l}$ is the $j_l$-th component of the normal vector
+$\vec{n}_{i_l}$,
+$$
+\{m_1,m_2,m_3\} = \left\{\frac{\mathbf{b}+\mathbf{c}}{2},
+\frac{\mathbf{a}+\mathbf{c}}{2},
+\frac{\mathbf{b}+\mathbf{a}}{2} \right\}
+$$
+and
+$i_l=\{1,1,2,2,3,3\},\, j_l=\{1,2,1,2,1,2\}$ with the order
+of $l$.
+\plot[height=4cm]{RT0}{normal vectors of each edge}
+
+\begin{example}
+\bFF
+ at mesh Th=@square(2,2);
+ at fespace Xh(Th, at P1);
+ at fespace Vh(Th, at RT0);
+Xh uh,vh;
+Vh [Uxh,Uyh];
+[Uxh,Uyh] = [sin(x),cos(y)];   // ok vectorial FE function
+vh= x^2+y^2;  // vh
+Th = @square(5,5); // change the mesh
+//  Xh is unchange
+uh = x^2+y^2; // compute on the new Xh
+Uxh = x;    // error: impossible to set only 1 component
+         // of  a vector FE function.
+vh = Uxh;  // ok
+// and now uh use the 5x5 mesh
+// but the fespace of vh is alway the 2x2 mesh
+ at plot(uh,ps="onoldmesh.eps");  // figure \ref{onoldmesh}
+uh = uh; // do a interpolation of vh (old) of 5x5 mesh
+            // to get the new vh on 10x10 mesh.
+ at plot(uh,ps="onnewmesh.eps"); // figure \ref{onnewmesh}
+vh([x-1/2,y])= x^2 + y^2;  // interpolate vh = $((x-1/2)^2 + y^2)  $
+\eFF
+\twoplot[height=6cm]{onoldmesh}{onnewmesh}{ vh Iso on mesh $2\times 2$}{
+vh Iso on mesh $5\times 5$}
+\end{example}
+
+
+ To get the value at a point $x=1,y=2$ of the FE function \texttt{uh},
+ or \texttt{[Uxh,Uyh]},one writes
+
+\bFF
+   @real value;
+   value = uh(2,4);       //  get value= uh(2,4)
+   value = Uxh(2,4);      // get value= Uxh(2,4)
+   //  ------  or ------
+   x=1;y=2;
+   value = uh;       // get value= uh(1,2)
+   value = Uxh;      // get value= Uxh(1,2)
+   value = Uyh;      // get value= Uyh(1,2).
+\eFF
+
+  To get the value of the array associated to the FE function
+  \texttt{uh}, one writes
+
+  \index{FE function!value}\index{FE function![]|textbf}
+  \index{FE function!n|textbf}\index{[]@\verb=[]=}\index{n}
+
+\bFF
+   @real value = uh[][0] ; // get the value of degree of freedom 0
+   @real maxdf = uh[].max; //  maximum value of degree of freedom
+   @int size = uh.n; // the number of degree of freedom
+   @real[int] array(uh.n)= uh[]; //  copy the array of the function uh
+\eFF
+Warning for no scalar finite element function   \texttt{[Uxh,Uyh]}
+ the two array \texttt{Uxh[]} and  \texttt{Uyh[]} are the same array, because
+ the degre of freedom can touch more than one componant.
+
+
+
+The other way to set a FE function  is to solve a `problem' (see
+below).
+
+%%Changed the place (OT 04/02/2005)
+\subsection{A \setS{Fast Finite Element Interpolator}}
+\medskip
+In practice one may discretize the variational equations by the Finite Element method. Then
+there will be one mesh for $\Omega_1$ and another one for $\Omega_2$.  The computation
+of integrals of products of functions defined on different meshes is difficult.
+Quadrature formulae and interpolations from one mesh to another at quadrature points are needed.
+We present below the interpolation operator which we have used and which is new,
+to the best of our knowledge.
+\bigskip
+Let ${\cal T}_{h}^0=\cup_k T^0_k,{\cal T}_{h}^1=\cup_k T^1_k$ be two triangulations of a domain $\Omega$.
+Let
+$$
+V({\hbox{${\cal T}$}_{h}^i}) =\{ C^0(\Omega_h^i)~:~f|_{T^i_k}\in P^1\},~~~i=0,1
+$$
+be the spaces of continuous piecewise affine functions on each triangulation.
+
+Let $f\in V({\cal T}_{h}^0)$. The problem is to find $g\in V({\cal T}_{h}^1)$ such that
+$$
+g(q) = f(q) \quad \forall q\hbox{~vertex of ~} {\cal T}_{h}^1
+$$
+Although this is a seemingly simple problem, it is difficult to find an
+efficient algorithm in practice.
+We propose an algorithm which is of complexity  $N^1\log N^0$, where $N^i$ is
+the number of vertices of ${\hbox{${\cal T}$}_{h}^i}$, and which
+is very fast for most practical 2D applications.
+\bigskip
+
+{\bf Algorithm }\par
+ The method has 5 steps.
+  First a quadtree is built containing all the vertices of mesh ${\cal T}_{h}^0$ such that in
+ each terminal cell there are at least one, and at most 4, vertices of ${\cal T}_{h}^0$ .\par
+For each $q^1$, vertex of ${\cal T}_{h}^1$ do:
+\\\\
+\begin{description}
+\item[Step 1]
+Find the terminal cell of the quadtree containing $q^1$.
+ \item[Step 2] Find the the nearest vertex $q^0_j$ to $q^1$ in that cell.
+ \item[Step 3] Choose one triangle $T_k^0\in{\cal T}_{h}^0$ which has $q^0_j$ for vertex.
+ \item[Step 4] Compute the barycentric coordinates $\{\lambda_j\}_{j=1,2,3}
+ $ of $q^1$ in $T^0_k$.
+\begin{itemize}
+ \item{$-$} if all barycentric coordinates are positive, go to Step 5
+ \item{$-$} else if one barycentric coordinate $\lambda_i$ is negative replace $T^0_k$ by the
+ adjacent triangle opposite $q^0_i$ and go to Step 4.
+ \item{$-$} else two barycentric coordinates are negative so take one of the two randomly
+ and replace $T^0_k$ by the adjacent triangle as above.
+\end{itemize}
+  \item[Step 5] Calculate $g(q^1)$ on $T^0_k$ by linear interpolation of $f$:
+ $$
+ g(q^1) = \sum_{j=1,2,3} \lambda_j f(q^0_j)
+ $$
+ \item[End]~
+\end{description}
+\plot[height=5cm]{fastInterpolat}{
+ To interpolate a function at $q^0$ the knowledge of the triangle
+which contains $q^0$ is needed.  The algorithm may start at $q^1\in T_k^0$ and stall
+on the boundary (thick line) because the line $q^0q^1$ is not inside $\Omega$. But if the holes
+are triangulated too (doted line) then the problem does not arise.}
+
+Two problems needs to solved:
+\begin{itemize}
+  \item {\it  What if $q^1$ is not in $\Omega^0_h$ ?}  Then Step 5 will stop with a
+ boundary triangle. So we add a step which test the distance of $q^1$ with the
+ two adjacent boundary edges and select the nearest, and so on till the distance
+ grows.
+ \medskip
+ \item {\it What if $\Omega^0_h$ is not convex and the marching process of Step 4
+ locks on a boundary?}
+ By construction  Delaunay-Vorono\"{i} mesh generators always triangulate the convex
+ hull of the vertices of the domain.  So we make sure that this information is not
+ lost when ${\cal T}_{h}^0,{\cal T}_{h}^1$ are constructed and we keep the triangles which are
+ outside the domain in a special list. Hence in step 5 we can use that list
+ to step over holes if needed.
+\end{itemize}
+
+\begin{note}
+ Step 3 requires an array of pointers
+ such that each vertex points to one triangle
+ of the triangulation.
+\end{note}
+
+\subsection{Problem and solve}
+
+ For \freefempp  a problem must be given in variational form, %\cite{blop},
+ so we need a bilinear form $a(u,v)$ , a linear form $\ell(f,v)$,
+and possibly a boundary condition form must be added.
+ \index{problem}
+\bT
+ at problem P(u,v) =
+     a(u,v) - $\ell$(f,v)
+     + (boundary condition);
+\eT
+
+
+\begin{note} When you want to formulate the problem and to solve it
+in the same time, you can use the keywork \texttt{solve}.
+\index{solve}
+\end{note}
+
+\subsubsection{Weak form and Boundary Condition}
+
+To Present the Principe  of Variational Formulation or of weak Formulation,
+let us take a model problem : a Poisson equation with  Dirichlet and Robin Boundary condition
+\index{Dirichlet}\index{Robin}.
+\medskip
+
+The problem is: Find $u$ a real function defined on  domain $\Omega$ of $\R^2$ such that
+
+\begin{equation} -  \nabla.(\nu \nabla u) = f  , \quad \mbox{in}\quad \Omega, \quad
+ a u + \nu \frac{\partial u}{\partial n} = b \quad\mbox{on}\quad \Gamma_r, \quad
+ u = g  \quad\mbox{on}\quad \Gamma_d
+ \end{equation}
+
+where
+\begin{itemize}
+\item $ \nabla.(\nu \nabla u) = \partial_x(\nu \partial_x u ) + \partial_y(\nu \partial_y u ) $
+with $ \partial_x u = \frac{\partial u}{\partial x}$
+and $\partial_y u = \frac{\partial u}{\partial y}$
+\item the border $\Gamma=\partial \Omega$ is split in $\Gamma_d$ and $\Gamma_n$
+such that $\Gamma_d \cup \Gamma_n = \emptyset$ and $ \Gamma_d \cap \Gamma_n = \partial \Omega$,
+\item $\nu$ is a given positive function, such that $\exists \nu_0 \in \R ,\quad 0 < \nu_0  \leq \nu $.
+\item  $a$ a given non negative function,
+\item  $ b$ a given function.
+\end{itemize}
+
+\begin{note}{} This problem,  we can be a classical
+Neumann boundary condition  if  $a$ is  $0$, and if $\Gamma_d$ is empty.
+In this case
+the function is defined just by derivative, so this defined too a constant
+ (if $u$ is a solution then  $ u+ 1$ is also a solution).
+\end{note}
+
+Let  ${ v} $  a regular test function  null  on  $\Gamma_d$ , by integration par part we get
+ \begin{equation}-\int_{\Omega}  \nabla.(\nu \nabla  u) \, { v} \,d\omega = \int_{\Omega}  \nu \nabla{ v} . \nabla u  \,d\omega= \int_{\Omega} f {v}  \,d\omega - \int_{\Gamma} {v}
+ \nu \frac{  \partial u}{\partial n}  \,d\gamma,
+  \end{equation}
+
+where $ \nabla{ v} . \nabla u = \frac{\partial u}{\partial x}\frac{\partial { v}}{\partial x}
++\frac{\partial u}{\partial y}\frac{\partial { v}}{\partial y}$ , and where $n$ is the unitary ouside normal of
+ $\partial\Omega$.
+
+Now we note that $ \nu \frac{  \partial u}{\partial n} = - a u + g $  on $\Gamma_r$
+and $  v = 0 $ on $ \Gamma_d $ and $ \partial \Omega = \Gamma_d \cup \Gamma_n $
+thus
+$$
+  - \int_{\partial \Omega} {v}
+ \nu \frac{  \partial u}{\partial n} = \int_{\Gamma_r} a u v - \int_{\Gamma_r} b v
+$$
+
+The problem become:
+
+Find   $u \in V_g = \{v \in H^1(\Omega) / v = g \mbox{ on } \Gamma_d \} $  such that
+\begin{equation} {\int_{\Omega} \nu \nabla{ v} . \nabla u  \,d\omega
+ + \int_{\Gamma_r} a u v  \,d\gamma = \int_{\Omega} f {v}}  \,d\omega  + \int_{\Gamma_r} b v  \,d\gamma , \quad \forall v \in V_0 \label{eq:v-poisson}
+\end{equation}
+
+where  $  V_0 = \{v \in H^1(\Omega) / v = 0 \mbox{ on } \Gamma_d \} $
+
+The problem (\ref{eq:v-poisson}) is generally weal posed if we do not have only  Neumann
+boundary condition ( ie. $\Gamma_d = \emptyset$ and $a = 0$).
+
+\begin{note}
+\label{note:fu} If we have only Neumann boundary condition, then the problem is defined
+to a constant, and $ 1 \in V_0$ so the following compatibility condition may occur: \index{compatibility condition}
+$
+ \int_{\Omega} f   \,d\omega  + \int_{\Gamma} b \,d\gamma
+$
+and a way to fixe the constant is to solve the following problem.
+
+ Find $u \in H^1(\Omega)$ such that:
+\begin{equation}
+ {\int_{\Omega} \varepsilon u v \,\,d\omega\; + \; \nu \nabla{ v} . \nabla u  \,d\omega
+  = \int_{\Omega} f {v}}  \,d\omega  + \int_{\Gamma_r} b v  \,d\gamma , \quad \forall v \in H^1(\Omega) \label{eq:v-poisson-N}
+\end{equation}
+where $\varepsilon$ is a small parameter ( $ \sim 10^{-10}$ ).
+
+Remark, if the solution
+is of order $ \frac{1}{\varepsilon}$ then the compatibility condition is unsatisfied, otherwise
+we get the solution such that $\int_\Omega u = 0 $.
+
+\end{note}
+
+In \texttt{FreeFem++},  the problem (\ref{eq:v-poisson}) become
+\bFF
+  problem Pw(u,v) =
+       @int2d(Th)( nu* ( dx(u)*dx(u) +  dy(u)*dy(u)))  // $\int_{\Omega} \nu \nabla{v} . \nabla u  \,d\omega$ \hfilll
+     + @int1d(Th,gn)( a * u*v )                        // $\int_{\Gamma_r} a u v  \,d\gamma$  \hfilll
+     - @int2d(Th)(f*v)                                 // $\int_{\Omega} f v  \,d\omega $ \hfilll
+     - @int1d(Th,gn)( b * v )                          // $ \int_{\Gamma_r} b v  \,d\gamma$ \hfilll
+     + @on(gd)(u= g) ;                                 // $ u =g $ on $\Gamma_d$  \hfilll
+\eFF
+where \texttt{Th} is a mesh of the domain $\Omega$, and \texttt{gd} and \texttt{gn} are respectively the
+boundary label of boundary $\Gamma_d$ and $\Gamma_n$.
+
+\subsection{Parameter Description for \texttt{solve} and \texttt{problem}}
+
+The parameters are FE function real or complex, the number $n$ of parameters is even
+($n=2*k$), the $k$ first function parameters are unknown, and the $k$
+last are test functions.
+
+\begin{note} If the functions are a part of
+vectoriel FE then you must give  all the functions of the vectorial
+FE in the same order (see laplaceMixte problem for example).
+\end{note}
+\begin{note} Don't mixte  complex and real parameters  FE function. %add  FH
+\end{note}
+\begin{bug}
+The mixing of \texttt{fespace} with different periodic boundary condition is not
+implemented. So all the finite element space use for test or unknown functions
+in a problem, must  have the same  type of periodic boundary condition or
+no periodic boundary condition.
+No clean message is given and the result is
+impredictible, Sorry.\index{periodic}\index{fespace!periodic=}
+\end{bug}
+
+\index{solver=!LU}\index{solver=!CG}\index{solver=!Crout}\index{solver=!GMRES}\index{solver=!Cholesky}\index{solver=!UMFPACK}
+\index{LU}\index{CG}\index{Crout}\index{GMRES}\index{Cholesky}\index{UMFPACK}
+
+The named parameters are:
+\begin{description}
+    \item[solver=]   \texttt{LU}, \texttt{CG},\index{solve!solver=}\index{problem!solver=}
+    \texttt{Crout},\texttt{Cholesky},\texttt{GMRES},\texttt{UMFPACK} ...
+
+    The default solver is \texttt{LU}.
+    The storage mode of the matrix of the underlying linear system
+    depends on
+    the type of solver chosen; for \texttt{LU}  the matrix is sky-line non
+    symmetric, for \texttt{Crout} the matrix is sky-line symmetric, for
+    \texttt{Cholesky} the matrix is sky-line symmetric positive
+    definite,  for \texttt{CG}   the matrix is sparse symmetric positive,
+    and for \texttt{GMRES} or \texttt{UMFPACK} the matrix is just  sparse.
+
+    \item[eps=]  \index{problem!eps=}  \index{solve!eps=} a real expression. $\varepsilon$  sets the stopping test for
+    the iterative methods like \texttt{CG}. Note that if $\varepsilon$
+    is negative  then the stopping test is:
+    $$  || A x - b || < |\varepsilon| $$
+    if it is positive then the stopping test is \index{stop test}
+        $$  || A x - b || < \frac{|\varepsilon|}{|| A x_{0} - b ||} $$
+
+    \item[init=]   \index{problem!init=}  \index{solve!init=}boolean expression, if it is false or 0 \index{init=}
+    the matrix is reconstructed. Note that if the mesh changes the matrix is
+    reconstructed too.
+    \item[precon=]  \index{problem!precon=}  \index{solve!precon=}name of a function (for example \texttt{P}) to set the precondioner. \index{precon=}
+    The prototype for the function \texttt{P} must be
+\bFF
+    @func @real[@int]  P(@real[@int] & xx) ;
+\eFF
+      \item[tgv=]  \index{problem!tgv=}  \index{solve!tgv=}  Huge value ($10^{30}$) used to lock boundary conditions (see (\ref{eqn:StiffnessDirichlet}))
+\end{description}
+
+\subsection{Problem definition}
+
+Below  \texttt{v} is the unknown function and \texttt{w} is the test function.
+
+  After the "=" sign, one may find sums of:
+  \index{int1d}\index{int2d}\index{intalledges}
+
+\begin{itemize}
+    \item a name; this is the name given to the
+     variational form (type \texttt{varf} \index{varf}) for possible reuse.
+    \item  the bilinear form term: for given functions $K$ and
+    unknown function $v$, test tunctions $w$,
+    \begin{itemize}
+       \item[-)]   \texttt{ int2d(Th)( K*v*w) } $ \displaystyle =       \sum_{T\in\mathtt{Th}}\int_{T } K\,v\,w  $
+       \item[-)]   \texttt{ int2d(Th,1)( K*v*w) } $ \displaystyle = \sum_{T\in\mathtt{Th},T\subset \Omega_{1}}\int_{T} K\,v\,w  $
+
+       \item[-)] \texttt{ int1d(Th,2,5)( K*v*w) }  $ \displaystyle = \sum_{T\in\mathtt{Th}}\int_{(\partial T\cup\Gamma) \cap ( \Gamma_2 \cup \Gamma_{5})
+          } K\,v\,w  $
+
+       \item[-)] \texttt{ intalledges(Th)( K*v*w) } $ \displaystyle = \sum_{T\in\mathtt{Th}}\int_{\partial T } K\,v\,w  $
+       \item[-)] \texttt{ intalledges(Th,1)( K*v*w) } $ \displaystyle = \sum_{{T\in\mathtt{Th},T\subset \Omega_{1}}}\int_{\partial T } K\,v\,w  $
+
+       \item[-)]  they become a sparse matrix of type \texttt{matrix}
+       \end{itemize}
+    \item  the linear form term: for given functions $K,\, f$ and test functions $w$,
+         \begin{itemize}
+       \item[-)]
+         \texttt{ int1d(Th)( K*w) } $ \displaystyle = \sum_{T\in\mathtt{Th}}\int_{T
+          } K\,w  $
+
+      \item[-)] \texttt{ int1d(Th,2,5)( K*w) }   $ \displaystyle = \sum_{T\in\mathtt{Th}}\int_{(\partial T\cup\Gamma) \cap ( \Gamma_2 \cup \Gamma_{5})
+          } K \,w  $
+
+       \item[-)] \texttt{ intalledges(Th)( f*w) } $ \displaystyle = \sum_{T\in\mathtt{Th}}\int_{\partial T } f\,w  $
+
+       \item[-)] a vector of type  \texttt{real[int]}
+      \end{itemize}
+
+    \item  The boundary condition form term :
+    \begin{itemize}
+        \item  An "on" form (for Dirichlet ) :\index{on}
+     \texttt{ on(1, u = g )}\index{on}
+        \item  a linear form on $\Gamma$  (for Neumann ) \index{Neumman}
+         \texttt{ -int1d(Th))( f*w) } or \texttt{ -int1d(Th,3))( f*w) }
+        \item   a bilinear form on $\Gamma$  or $\Gamma_{2}$ (for  Robin )\index{Robin}
+         \texttt{ int1d(Th))( K*v*w) } or
+         \texttt{ int1d(Th,2))( K*v*w)}.
+
+    \end{itemize}
+
+\end{itemize}
+
+If needed, the different kind of terms in the sum can appear more than once.
+
+Remark: the integral mesh and the mesh associated to test function or unknown
+function can be different in the case of linear form.
+
+\begin{note}
+ \texttt{N.x} and \texttt{N.y} are the normal's components. \index{normal}\index{N}
+ \end{note}
+
+{\bf Important}: it is not possible to write in the same integral the
+linear part and the bilinear part such as in
+\texttt{ int1d(Th)( K*v*w - f*w) }.
+
+\subsection{\setS{Numerical Integration}}
+Let $D$ be a $N$-dimensional bounded domain.
+For an arbitrary polynomials $f$ of degree $r$,
+if we can find particular points $\vec{\xi}_j,\, j=1,\cdots,J$ in $D$ and
+constants $\omega_j$ such that
+\begin{eqnarray}
+\label{eqn:GaussInt}
+\int_{D}f(\vec{x}) = \sum_{\ell =1}^L c_\ell f(\vec{\xi}_\ell)
+\end{eqnarray}
+then we have the error estimation (see Crouzeix-Mignot (1984)),
+then there exists a constant $C>$ such that,
+\begin{eqnarray}
+\label{eqn:GaussIntError}
+\left|\int_{D}f(\vec{x}) - \sum_{\ell =1}^L \omega_\ell
+f(\vec{\xi}_\ell )\right|
+\le C|D|h^{r+1}
+\end{eqnarray}
+for any function $r + 1$ times continuously differentiable $f$ in $D$,
+where $h$ is the diameter of $D$ and $|D|$ its measure.
+
+a point in the segment $[q^iq^j]$ is given as
+\[
+\{(x,y)|\; x=(1-t)q^i_x+tq^j_x,\, y=(1-t)q^i_y+tq^j_y,\, 0\le t\le 1\}
+\]
+For a domain $\Omega_h=\sum_{k=1}^{n_t}T_k,\, \mathcal{T}_h=\{T_k\}$,
+we can calculate the integral over $\Gamma_h=\partial\Omega_h$ by
+\begin{eqnarray*}
+\int_{\Gamma_h}f(\vec{x})ds&=&\texttt{int1d(Th)(f)}\\
+&=&\texttt{int1d(Th,qfe=*)(f)}\\
+&=&\texttt{int1d(Th,qforder=*)(f)}
+\end{eqnarray*}
+where * stands for the name of quadrature formulas or the order of the Gauss formula.
+\begin{figure}[hbt]
+\begin{tabular}{|c|c|c|c|c|c|}
+    \hline
+    $L$ & name (\texttt{qfe=}) & order \texttt{qforder=} &
+    point in $[q^iq^j](=t)$ & $\omega_\ell$~~~  & degree of exact \\
+    \hline
+    \hline
+    1 & qf1pE&2&$0$ & $|q^iq^j|$ & 1 \\
+    \hline
+    2 & qf2pE&3& $(1-\sqrt{1/3})/2$ & $|q^iq^j|/2$ & 3 \\
+    & &&$(1+\sqrt{1/3})/2$ & $|q^iq^j|/2$ &  \\
+    \hline
+    3 & \textbf{qf3pE} &6&$(1-\sqrt{3/5})/2$ & $(5/18)|q^iq^j|$ & 5  \\
+    & & & $1/2$ & $(8/18)|q^iq^j|$ & \\
+    & & & $(1+\sqrt{3/5})/2$ & $(5/18)|q^iq^j|$ &\\
+    \hline
+    2 &qf1pElump E&2& $-1$ & $|q^iq^j|/2$ & 1 \\
+    & &&$+1$ & $|q^iq^j|/2$ &  \\
+    \hline
+
+\end{tabular}
+\index{quadrature:qf1pE}\index{quadrature:qf2pE}%
+\index{quadrature:qf3pE}%
+\index{quadrature:qf1pElump}%
+\end{figure}
+where $|q^iq^j|$ is the length of segment $\overline{q^iq^j}$.
+For a part $\Gamma_1$ of $\Gamma_h$ with the label ``1'', we can
+calculate the integral over $\Gamma_1$ by
+\begin{eqnarray*}
+\int_{\Gamma_1}f(x,y)ds&=&\texttt{int1d(Th,1)(f)}\\
+&=&\texttt{int1d(Th,1,qfe=qf2pE)(f)}
+\end{eqnarray*}
+The integral over $\Gamma_1,\, \Gamma_3$ are given by
+\begin{eqnarray*}
+\int_{\Gamma_1\cup \Gamma_3}f(x,y)ds=\texttt{int1d(Th,1,3)(f)}
+\end{eqnarray*}
+
+For each triangule $T_k=[q^{k_1}q^{k_2}q^{k_3}]$ , the point
+$P(x,y)$ in $T_k$ is expressed by the \emph{area coordinate}\index{area coordinate} as $P(\xi,\eta)$:
+\begin{eqnarray*}
+&&|T_k|=\left|
+\begin{array}{ccc}
+1&q^{k_1}_x&q^{k_1}_y\\
+1&q^{k_2}_x&q^{k_2}_y\\
+1&q^{k_3}_x&q^{k_3}_y
+\end{array}
+\right|\quad
+D_1=\left|
+\begin{array}{ccc}
+1&x&y\\
+1&q^{k_2}_x&q^{k_2}_y\\
+1&q^{k_3}_x&q^{k_3}_y
+\end{array}
+\right|
+\quad
+D_2=\left|
+\begin{array}{ccc}
+1&q^{k_1}_x&q^{k_1}_y\\
+1&x&y\\
+1&q^{k_3}_x&q^{k_3}_y
+\end{array}
+\right|
+\quad
+D_3=\left|
+\begin{array}{ccc}
+1&q^{k_1}_x&q^{k_1}_y\\
+1&q^{k_2}_x&q^{k_2}_y\\
+1&x&y
+\end{array}
+\right|\\
+&&\xi=D_1/|T_k|\qquad
+\eta=D_2/|T_k|\qquad \textrm{then }
+1-\xi-\eta=D_3/|T_k|
+\end{eqnarray*}
+For a domain $\Omega_h=\sum_{k=1}^{n_t}T_k,\, \mathcal{T}_h=\{T_k\}$,
+we can calculate the integral over $\Omega_h$ by
+\begin{eqnarray*}
+\int_{\Omega_h}f(x,y)&=&\texttt{int2d(Th)(f)}\\
+&=&\texttt{int2d(Th,qft=*)(f)}\\
+&=&\texttt{int2d(Th,qforder=*)(f)}
+\end{eqnarray*}
+where * stands for the name of quadrature formulas or the order of the Gauss formula.
+\begin{figure}[hbt]
+\begin{tabular}{|c|c|c|c|c|c|}
+    \hline
+    $L$ & \texttt{qfe=} & \texttt{qforder=} &
+    point in $T_k$ & $\omega_\ell$~~~  & degree of exact \\
+    \hline
+    \hline
+    1 & qf1pT&2&$\left(\frac{1}{3},\frac{1}{3}\right)$ & $|T_k|$ & 1 \\
+    \hline
+    3 & qf2pT&3& $\left(\frac{1}{2},\frac{1}{2}\right)$ & $|T_k|/3$ & 2 \\
+    & &&$\left(\frac{1}{2},0\right)$ & $|T_k|/3$ &  \\
+    & &&$\left(0,\frac{1}{2}\right)$ & $|T_k|/3$ &  \\
+    \hline
+    7 & \textbf{qf5pT}&6&$\left(\frac{1}{3},\frac{1}{3}\right)$ & $0.225|T_k|$ & 5 \\
+    & & & $\left(\frac{6-\sqrt{15}}{21},\frac{6-\sqrt{15}}{21}\right)$ & $
+    \frac{(155-\sqrt{15})|T_k|}{1200}$ & \\
+    & & & $\left(\frac{6-\sqrt{15}}{21},\frac{9+2\sqrt{15}}{21}\right)$ & $\frac{(155-\sqrt{15})|T_k|}{1200}$ &\\
+    & & & $\left(\frac{9+2\sqrt{15}}{21},\frac{6-\sqrt{15}}{21}\right)$ & $\frac{(155-\sqrt{15})|T_k|}{1200}$ &\\
+    & & & $\left(\frac{6+\sqrt{15}}{21},\frac{6+\sqrt{15}}{21}\right)$ & $\frac{(155+\sqrt{15})|T_k|}{1200}$ &\\
+    & & & $\left(\frac{6+\sqrt{15}}{21},\frac{9-2\sqrt{15}}{21}\right)$ & $\frac{(155+\sqrt{15})|T_k|}{1200}$ &\\
+    & & & $\left(\frac{9-2\sqrt{15}}{21},\frac{6+\sqrt{15}}{21}\right)$ & $\frac{(155+\sqrt{15})|T_k|}{1200}$ &\\
+    \hline
+    3 & qf1pTlump& & $\left(0,0\right)$ & $|T_k|/3$ & 1 \\
+    & &&$\left(1,0\right)$ & $|T_k|/3$ &  \\
+    & &&$\left(0,1\right)$ & $|T_k|/3$ &  \\
+    \hline
+    9 & qf2pT4P1& &$\left(\frac{1}{4},\frac{3}{4}\right)$ & $|T_k|/12$ & 1  \\
+      &         & &$\left(\frac{3}{4},\frac{1}{4}\right)$ & $|T_k|/12$ &   \\
+      &         & &$\left(0,\frac{1}{4}\right)$ & $|T_k|/12$ &   \\
+      &         & &$\left(0,\frac{3}{4}\right)$ & $|T_k|/12$ &   \\
+      &         & &$\left(\frac{1}{4},0\right)$ & $|T_k|/12$ &   \\
+      &         & &$\left(\frac{3}{4},0\right)$ & $|T_k|/12$ &   \\
+      &         & &$\left(\frac{1}{4},\frac{1}{4}\right)$ & $|T_k|/6$ &   \\
+      &         & &$\left(\frac{1}{4},\frac{1}{2}\right)$ & $|T_k|/6$ &   \\
+      &         & &$\left(\frac{1}{2},\frac{1}{4}\right)$ & $|T_k|/6$ &   \\
+    \hline
+    15 & qf7pT& 8 & see  \cite{0501496} for detail  & &7 \\
+       \hline
+    21 & qf9pT& 10 & see \cite{0501496} for detail  & &9 \\
+    \hline
+
+\end{tabular}
+\index{quadrature:qf1pT} \index{quadrature:qf2pT}\index{quadrature: qf5pT}
+\index{quadrature:qf1pTlump}\index{quadrature:qf2pT4P1}
+\index{quadrature:qf7pT}\index{quadrature:qf7pT}
+
+\index{quadrature:qfe=} \index{quadrature:qft=}\index{quadrature:qforder=}
+\end{figure}
+
+\begin{note}
+ By default,  we use the formula which is exact for polynomes of degrees $5$ on triangles or edges (in bold in two tables)\index{quadrature:default}.
+\end{note}
+
+
+
+
+\subsection{Variational Form, Sparse Matrix, Right Hand Side Vector}
+  \index{varf}\index{array}
+  It is possible to define variational forms:
+\bFF
+ at mesh Th=@square(10,10);
+ at fespace Xh(Th, at P2),Mh(Th, at P1);
+
+ at varf bx(u1,q) = @int2d(Th)( (dx(u1)*q));
+\eFF
+$$ bx(u_{1},q)= \int_{\Omega_{h}} \frac{\partial u_{1}}{\partial x} q $$
+
+\bFF
+ at varf by(u1,q) = @int2d(Th)( (dy(u1)*q));
+\eFF
+$$ by(u_{1},q)= \int_{\Omega_{h}} \frac{\partial u_{1}}{\partial y} q $$
+\bFF
+ at varf a(u1,u2)= @int2d(Th)(  dx(u1)*dx(u2) + dy(u1)*dy(u2) )
+                    +  @on(1,2,4,u1=0)  +  @on(3,u1=1) ;
+\eFF
+\begin{note}
+ the parameters of the variational form are completely formal,  but is not the case
+ in \texttt{problem} and \texttt{solve} functionality. %FH add
+\end{note}
+
+$$ a(u_{1},v_{2}) = \int_{\Omega_{h}}  \nabla u_{1}.\nabla u_{2}; \quad
+             \quad u_{1} = 1*g \mbox{ on } \Gamma_{3}, u_{1} =0 \mbox{ on } \Gamma_{1}\cup \Gamma_{2}\cup \Gamma_{4} $$
+ where $f$ is defined later.
+ \\
+ Later variational forms can be used to construct right hand side vectors,
+matrices associated to them, or to define a new problem;\index{matrix}
+\bFF
+Xh u1,u2,v1,v2;
+Mh p,q,ppp;
+
+Xh bc1; bc1[] = a(0,Xh);  //  right hand side for boundary condition
+Xh b;
+
+ at matrix A= a(Xh,Xh,solver=CG);   // the Laplace matrix \index{matrix!solver} \index{GC}
+ at matrix<complex> CA= a(Xh,Xh,solver=CG);   // the complex Laplace matrix \index{matrix!complex} \index{GC}
+
+ at matrix Bx= bx(Xh,Mh);    // $ Bx = (Bx_{ij})$ and $ Bx_{ij}= bx(b^x_j,b^m_j)$
+//  where $b^x_j$ is a basis of Xh, and $b^m_j$ is a basis of Mh.
+ at matrix By= by(Xh,Mh);    // $ By= (By_{ij})$ and $ By_{ij}= by(b^x_j,b^m_j)$
+\eFF
+\begin{note}
+The line of the matrix corresponding to test function on the bilinear form.
+\end{note}
+
+\begin{note}
+The vector $bc1[]$ contains the contribution of the boundary condition $u_{1}=1$.
+\end{note}
+Here we have three matrices $A,Bx,By$, and we can solve the problem:\\
+find $ u_{1} \in X_{h}$ such that
+$$ a(v_{1},u_{1})= by(v_{1},f), \forall v_{1}\in X_{0h}, $$
+$$ u_{1} = g , \quad \mbox{on~} \Gamma_{1}, \mbox{and}\quad u_{1}=0 \quad \mbox{on~}  \Gamma_{1}\cup \Gamma_{2}\cup \Gamma_{4}$$
+with the following line (where $f=x$, and $ g=\sin(x)$)\index{[]@\verb=[]=}
+\bFF
+Mh f=x;
+Xh g=sin(x);
+b[]  = Bx'*f[]; //
+b[] += bc1[] .*bcx[]; // u1= g on $\Gamma_{3}$ boundary see following remark
+u1[] = A^-1*b[]; // solve the linear system \index{solve!linear system}\index{\string^-1}
+\eFF
+\begin{note} The boundary condition \index{boundary condition} is implemented
+ by penalization and the vector \texttt{bc1[]} contains
+ the contribution of the boundary condition $u_{1}=1$ ,
+so to change the boundary condition,
+we have just to multiply the vector $bc1[]$ by the value $f$
+ of the new boundary condition term by term
+with the operator \texttt{.*}.\index{.*@\verb=.*=}
+The \refSec{Uzawa} \texttt{StokesUzawa.edp}  gives
+ a real example of using all this features.
+\end{note}
+
+We add automatic expression optimization by default, if this optimization trap
+you can remove the use of this optimization by writing for example : \index{optimize=}
+\bFF
+ at varf a(u1,u2)= @int2d(Th,optimize=false)(  dx(u1)*dx(u2) + dy(u1)*dy(u2) )
+                    +  @on(1,2,4,u1=0)  +  @on(3,u1=1) ;
+\eFF
+
+Remark, it is all possible to build interpolation matrix, like in
+\index{interpolate}\index{matrix!interpolate}
+the following example:
+\bFF
+ at mesh  TH = square(3,4);
+ at mesh  th = square(2,3);
+ at mesh  Th = square(4,4);
+
+
+ at fespace VH(TH,P1);
+ at fespace Vh(th,P1);
+ at fespace Wh(Th,P1);
+
+ at matrix B= interpolate(VH,Vh);  // build interpolation matrix
+Vh->VH @matrix BB= interpolate(Wh,Vh);  // build interpolation
+matrix  Vh->Wh \eFF and after some operations on sparse matrices are
+available for example \bFF
+  @int N=10;
+  @real [int,int] A(N,N);  // a full matrix
+  @real [int] a(N),b(N);
+  A =0;
+  @for (@int i=0;i<N;i++)
+    {
+      @A(i,i)=1+i;
+      @if(i+1 < N)    A(i,i+1)=-i;
+      a[i]=i;
+    }
+  b=A*b;
+  @cout << "xxxx\n";
+  @matrix sparseA=A;
+  cout << sparseA << endl;
+  @sparseA = 2*sparseA+sparseA';
+  @sparseA = 4*sparseA+sparseA*5; //
+  matrix sparseB=sparseA+sparseA+sparseA; ;
+  @cout << "sparseB = " << sparseB(0,0) << endl;
+\eFF
+\subsection{Interpolation matrix}
+
+ This becomes possible to store the matrix of a linear interpolation operator from
+ a finite element space $V_h$ to  $W_h$ with \texttt{interpolate} function.
+Note that the continuous finite functions are extended by continuity
+to the outside of the domain.
+
+
+The named parameter of function \texttt{interpolate} are:
+\begin{description}
+\item[\texttt{inside=}] set true to create zero-extension.
+\item[\texttt{t=}] set true to get the transposed matrix
+\item[\texttt{op=}] set an integer written below
+
+\begin{description}
+\item[0] the default value and interpolate of the function
+\item[1] interpolate the $\partial_x$
+\item[2] interpolate the $\partial_y$
+\end{description}
+
+
+ \index{inside=}\index{interpolate!inside=}
+ \index{interpolate!t=}\index{interpolate!t=}.
+ \index{interpolate!op=}\index{interpolate!op=}.
+\end{description}
+
+\begin{example}[mat\_interpol.edp]~
+\bFF
+ at mesh Th=square(4,4);
+ at mesh Th4=square(2,2,[x*0.5,y*0.5]);
+ at plot(Th,Th4,ps="ThTh4.eps",wait=1);
+ at fespace Vh(Th,P1);     @fespace Vh4(Th4,P1);
+ at fespace Wh(Th,P0);     @fespace Wh4(Th4,P0);
+
+ at matrix IV= interpolate(Vh,Vh4); //  here the function is
+// exended by continuity
+cout << " IV Vh<-Vh4 " << IV << endl;
+
+ at matrix IV0= interpolate(Vh,Vh4,inside=1); // here the fonction is
+// exended by zero
+cout << " IV Vh<-Vh4 (inside=1)  " << IV0 << endl;
+
+ at matrix IVt0= interpolate(Vh,Vh4,inside=1,t=1);
+cout << " IV Vh<-Vh4^t (inside=1)  " << IVt0 << endl;
+
+ at matrix IV4t0= interpolate(Vh4,Vh);
+cout << " IV Vh4<-Vh^t  " << IV4t0 << endl;
+
+ at matrix IW4= interpolate(Wh4,Wh);
+cout << " IV Wh4<-Wh  " << IW4  << endl;
+
+ at matrix IW4V= interpolate(Wh4,Vh);
+cout << " IV Wh4<-Vh  " << IW4  << endl;
+\eFF
+\end{example}
+
+\subsection{Finite elements connectivity}
+Here, we show how get the informations of a
+finite element space $W_h({\cal T}_n,*)$,
+where ``*'' denotes P1, P2, P1nc, etc.
+\index{nt} \index{ndof} \index{ndofK} \index{connectivity}
+\index{FEspace!nt}\index{FEspace!ndof} \index{FEspace!(int ,int )}
+\begin{itemize}
+\item   \ttCC{Wh.nt}  gives the number of element of $W_h$
+\item   \ttCC{   Wh.ndof}  gives the number of degree of freedom or unknown
+\item   \ttCC{   Wh.ndofK }  gives the number of degree of freedom on one element
+\item   \ttCC{   Wh(k,i) }   gives the number of $i$th  degree of freedom of element $k$.
+
+\end{itemize}
+See the following for an example:
+\begin{example}[FE.edp]
+\bFF
+ at mesh Th=@square(5,5);
+ at fespace Wh(Th,P2);
+ at cout << " nb of degree of freedom           : " << Wh.ndof << endl;
+ at cout << " nb of degree of freedom / ELEMENT : " << Wh.ndofK << endl;
+ @int k= 2;  // element 2
+ @int kdf= Wh.ndofK ;
+ @cout << " df of element " << k << ":" ;
+ @for (@int i=0;i<kdf;i++)
+    @cout << Wh(k,i) << " ";
+ @cout << @endl;
+\eFF
+\end{example}
+and the output is:
+\bFF
+ Nb Of Nodes = 121
+ Nb of DF = 121
+ FESpace:Gibbs: old skyline = 5841  new skyline = 1377
+ nb of degree of freedom           : 121
+ nb of degree of freedom / ELEMENT : 6
+ df of element 2:78 95 83 87 79 92
+\eFF
+
+
+\section{Visualization}
+Numerical results in FEM create huge data, so it is very important to
+make obtained results visible.
+There are two ways of visualization in \freefempp:
+One is default view supporting the draw of meshes, isovalue of real  FE-functions
+and vector fields by the command \ttCC{@plot} (see \refSec{Plot}).
+For documentation, \freefempp make the plotting stored as postscript files.
+
+Another method is to use the external tools, for example, gnuplot
+(see Section \ref{sec:gnuplot}), medit (see Section \ref{sec:medit})
+ using the command \ttCC{@system}.
+
+\subsection{Plot} \index{sec:Plot}\label{sec:Plot}
+   With the command plot,
+   meshes, isovalues and vector fields can be displayed.
+
+The parameters of the plot command can be , meshes,real FE functions ,
+arrays of 2  real FE functions, arrays of two arrays of double, to plot
+respectively mesh,
+isovalue, vector field, or curve defined by the two arrays of double.
+
+The named parameter are
+\begin{description}
+    \item[wait=] boolean expression to wait or not (by default no wait). If true we wait for
+    a keyboard up event or mouse event,
+    they respond to an event by the following characters
+    \begin{description}
+        \item[\texttt{+}]  to zoom in around the mouse cursor,
+        \item[\texttt{-}]  to zoom out around the mouse cursor,
+        \item[\texttt{=}]  to restore de initial graphics state,
+        \item[\texttt{c}]  to decrease the vector arrow coef,
+        \item[\texttt{C}]  to increase the vector arrow coef,
+        \item[\texttt{r}]  to refresh the graphic window,
+        \item[\texttt{f}]  to toggle the filling between isovalues,
+        \item[\texttt{b}]  to toggle the black and white,
+        \item[\texttt{g}]  to toggle to  grey or color ,
+        \item[\texttt{v}]  to toggle  the plotting of value,
+        \item[\texttt{p}]  to save to a postscript file,
+  \item[\texttt{?}]  to show all actives keyboard char,
+    \end{description}
+    to redraw, otherwise we continue.
+
+    \itemtt[ps=]  \index{plot!ps=}  string expression to save the plot on postscript file
+    \itemtt[coef=]  \index{plot!coef=} the vector arrow coef between arrow unit and domain unit.
+    \itemtt[fill=]  \index{plot!coef=} to fill between isovalues.
+     \itemtt[cmm=]  \index{plot!cmm=}string expression to write in the graphic window
+     \itemtt[value=]  \index{plot!value=}to plot the value of isoline and the value of vector arrow.
+    \itemtt[aspectratio=] \index{plot! aspectratio =}boolean to be sure that the aspect ratio of plot
+ is preserved or not.
+    \itemtt[bb=] \index{plot!bb=}array of 2 array ( like \texttt{ [[0.1,0.2],[0.5,0.6]]}),
+       to set the bounding box and specify a partial view where the  box defined by the two corner points [0.1,0.2] and [0.5,0.6].
+
+    \itemtt[nbiso=]  \index{plot! nbiso =}(int) sets the number of isovalues (20 by default)
+    \itemtt[nbarrow=] \index{plot!nbarraw=} (int) sets the number of colors of arrow values (20 by default)
+    \itemtt[viso=]  \index{plot!viso=}sets the array  value of isovalues (an array real[int])
+    \itemtt[varrow=] \index{plot!varrow=}  sets the array value of color arrows (an array real[int])
+    \itemtt[bw=] \index{plot!bw=} (bool)  sets or not the plot in black and white color.
+    \itemtt[grey=] \index{plot!grey=} (bool)  sets or not the plot in grey color.
+\end{description}
+For example: \index{plot!cut}
+\bFF
+ at real[@int] xx(10),yy(10);
+ at mesh Th=@square(5,5);
+ at fespace Vh(Th, at P1);
+Vh uh=x*x+y*y,vh=-y^2+x^2;
+ at int i;
+//  compute a cut
+ at for (i=0;i<10;i++)
+ {
+   x=i/10.; y=i/10.;
+   xx[i]=i;
+   yy[i]=uh; // value of uh at point (i/10. , i/10.)
+ }
+ @plot(Th,uh,[uh,vh],value=true,ps="three.eps",wait=true); // figure \ref{three}
+ //  zoom on box defined by the two corner points [0.1,0.2] and [0.5,0.6]
+ @plot(uh,[uh,vh],bb=[[0.1,0.2],[0.5,0.6]],
+        wait=true,grey=1,fill=1,value=1,ps="threeg.eps"); // figure \ref{threeg}
+ @plot([xx,yy],ps="likegnu.eps",wait=true); // figure \ref{likegnu}
+\eFF
+\twoplot[height=6cm]{three}{threeg}{ mesh, isovalue, and
+vector}{enlargement in grey of isovalue, and
+vector}
+
+\plot[height=6cm]{likegnu}{Plots a cut of uh. Note that a refinement of the same can be obtained
+in combination with gnuplot}
+
+\subsection{link with gnuplot}\label{sec:gnuplot}
+\index{gnuplot}\index{exec}
+First this work only if gnuplot\footnote{\url{http://www.gnuplot.info/}} is installed , and
+only on unix computer.
+
+You just and to the previous example:
+{\def\bks{$\backslash$}
+\bFF
+// file for gnuplot
+{
+  @ofstream gnu("plot.gp");
+  @for (int i=0;i<=n;i++)
+   {
+     gnu <<  xx[i] << " " << yy[i] << endl;
+    }
+} //  the file plot.gp is close because the variable gnu is delete
+
+//  to call gnuplot command and wait 5 second (tanks to unix command)
+//  and make postscipt plot
+ at exec("echo 'plot \bks"plot.gp\bks" w l \bks
+pause 5 \bks
+set term postscript \bks
+set output \bks"gnuplot.eps\bks" \bks
+replot \bks
+quit' | gnuplot");
+\eFF}
+\plot[height=7cm,angle=270]{gnuplot}{Plots a cut of uh with gnuplot}
+
+\subsection{link with medit}\label{sec:medit}
+First this work only if medit \footnote{\url{http://www-rocq.inria.fr/gamma/medit/medit.html}}
+software is installed.
+
+\index{medit}\index{exec}
+
+\bFF
+// build square $]-1,1[^2$
+mesh Th=square(10,10,[2*x-1,2*y-1]);
+fespace Vh(Th,P1);
+Vh u=2-x*x-y*y;
+
+   savemesh(Th,"mm",[x,y,u*.5]); //save mm.points and mm.faces file
+// for medit
+   // build a mm.bb file
+  { ofstream file("mm.bb");
+  file << "2 1 1 "<< u[].n << " 2 \n";
+  int j;
+  for (j=0;j<u[].n ; j++)
+    file << u[][j] << endl;
+    }
+    // call medit command
+    exec("medit mm");
+    // clean files on unix OS
+    exec("rm mm.bb      mm.faces   mm.points");
+
+\eFF
+\plot[height=10cm]{medit}{medit plot}
+
+
+
+\section{Algorithms}
+
+ The associated example is fully defined in \texttt{algo.edp} file.
+
+ \subsection{conjugate Gradient/GMRES}
+
+If we want to solve  the Euler problem: find $ x\in \R^n $  such that
+\begin{equation}
+\label{eqn:dJ=0}
+\nabla J(x) = \left(\frac{\partial J}{\partial x_i} (\vec{x})\right) = 0
+\end{equation}
+where $ J$ is a functional (to minimize  for example) from  $ \R^n$ to $ \R$.
+
+If the function is convex we can use the conjugate gradient to solve the problem, and we just need the function (named \texttt{dJ} for example)
+which compute $\nabla J$, so the two parameters
+are the name of the function with prototype \ttCC{@func\ @real[@int]\  dJ(@real[@int] \& xx)}
+ which compute $\nabla J$,
+a vector \ttCC{x} of type \ttCC{@real[@int]} to initialize the process and get the result.
+
+
+Given a staring value $\vec{x}^{(0)}$, a maximum number $i_{\max}$
+of iterations, and an error tolerance $0<\epsilon<1$:
+Put $\vec{x}=\vec{x}^{(0)}$ and write
+\begin{quote}\texttt{
+NLCG($\nabla J$, $\vec{x}$, precon$=M$, nbiter$=i_{\max}$, eps$=\epsilon$);
+}
+\end{quote}
+Then we get the solution $\vec{x}$ of $\nabla J(\vec{x})=0$.
+We can omit parameters \texttt{precon, nbiter, eps}.
+Here $M$ is the preconditioner whose default is the identity matrix.
+The stopping test is
+\[
+\| \nabla J(\vec{x})\|_P\le \epsilon\| \nabla J(\vec{x}^{(0)})\|_P
+\]
+Writing the minus value in \texttt{eps=}, i.e.,
+\begin{quote}\texttt{
+NLCG($\nabla J$, $\vec{x}$, precon$=M$, nbiter$=i_{\max}$, eps$=-\epsilon$);
+}
+\end{quote}
+we can use the stopping test
+\[
+\| \nabla J(\vec{x})\|_P^2\le \epsilon
+\]
+The named parameter of these three functions are:
+\begin{description}  \index{linearCG!nbiter=} \index{linearCG!precon=} \index{linearCG!eps=}\index{linearCG!veps=}
+\index{NLCG!nbiter=}  \index{NLCG!eps=}\index{NLCG!veps=}
+\index{LinearGMRES!nbiter=} \index{LinearGMRES!precon=} \index{LinearCMRES!eps=}\index{LinearGMRES!veps=}
+
+\itemtt[nbiter=] set the number of iteration (by default $100$)
+\itemtt[precon=] set the preconditioner function (\texttt{P} for example)   by default it is the identity, remark the prototype
+is \ttCC{@func\ @real[\@int]\ P(@real[@int] \&x)}.
+\itemtt[eps=] set the value of the stop test $\varepsilon$ ($=10^{-6}$ by default) if positive then relative test
+$||\nabla J(x)||_P\leq \varepsilon||\nabla J(x_0)||_P$, otherwise the  absolute test is  $||\nabla J(x)||_P^2\leq |\varepsilon|$.
+\itemtt[veps=] set and return the value of the stop test,  if positive then relative test
+$||\nabla J(x)||_P\leq \varepsilon||\nabla J(x_0)||_P$, otherwise the  absolute test is  $||\nabla J(x)||_P^2\leq |\varepsilon|$.
+The return value is  minus  the real stop test (remark: it is useful in loop).
+
+\end{description}
+\begin{example}[from algo.edp]
+For a given function $b$, let us find the minimizer $u$ of the functional
+\begin{eqnarray*}
+ J(u) &=& \int_{\Omega} f(|\nabla u|^2) - \int_{\Omega}  u b \\
+ f(x) &=& ax + x-\ln(1+x), \quad f'(x) = a+\frac{x}{1+x}, \quad f''(x) =  \frac{1}{(1+x)^2}
+\end{eqnarray*}
+under the boundary condition $u=0$ on $\partial\Omega$.
+\bFF
+ at mesh Th=@square(10,10);  // mesh definition of $\Omega$
+ at fespace Vh(Th,P1);      // finite element space
+ at fespace Ph(Th,P0);      // make optimization
+\eFF
+/*
+A small hack to construct a function
+\[
+Cl= \left\{
+\begin{array}{cl} 1 & \textrm{\rm on interior degree of freedom} \\
+ 0 & \textrm{\rm on boundary degree of freedom}
+ \end{array}\right.
+\]
+*/\\
+// Hack to construct an array :\\
+//  1 on interior nodes and 0 on boundary nodes
+\bFF
+ at varf vCl(u,v) = @on(1,2,3,4,u=1);
+Vh Cl;
+Cl[]= vCl(0,Vh,tgv=1);  //  0 and tgv
+ at real tgv=Cl[].max;     //
+Cl[] = -Cl[];  Cl[] += tgv; Cl[] /=tgv;
+\eFF
+// the definition of $f$, $f'$, $f''$ and $b$
+\bFF
+ at real a=0.001;
+
+ at func @real f(@real u) { @return u*a+u-log(1+u); }
+ at func @real df(@real u) { @return a+u/(1+u);}
+ at func @real ddf(@real u) { @return 1/((1+u)*(1+u));}
+Vh b=1;  // to defined b
+// the routine to compute the functional $J$
+ at func @real J(@real[int] & x)
+  {
+    Vh u;u[]=x;
+    @real r=@int2d(Th)(f( dx(u)*dx(u) + dy(u)*dy(u) ) - b*u) ;
+    @cout << "J(x) =" << r << " " << x.min <<  " " << x.max << @endl;
+    @return r;
+  }
+// The function  \index{function}to compute $D J$, where $u$ is the current solution.
+Vh u=0; //  the current value of the solution
+Vh alpha; // of store  $f'(|\nabla u|^2)$
+ at int iter=0;
+alpha=df( dx(u)*dx(u) + dy(u)*dy(u) ); // optimization
+
+ at func @real[@int] dJ(@real[int] & x)
+  {
+    @int verb=verbosity; verbosity=0;
+    Vh u;u[]=x;
+    alpha=df( dx(u)*dx(u) + dy(u)*dy(u) ); // optimization
+    @varf au(uh,vh) = @int2d(Th)( alpha*( dx(u)*dx(vh) + dy(u)*dy(vh) ) - b*vh);
+    x= au(0,Vh);
+    x = x.* Cl[]; //  the grad in 0 on boundary
+    verbosity=verb;
+    @return x; // warning no return of local array
+  }
+\eFF
+/*
+We want to construct also a preconditioner $C$
+with solving the problem:  find $u_h \in V_{0h}$ such that
+\[
+\forall v_h \in V_{0h}, \quad  \int_\Omega \alpha \nabla u_h . \nabla v_h = \int_\Omega b v_h
+\]
+where $ \alpha=f'(|\nabla u|^2)$.
+*/
+\bFF
+ at varf alap(uh,vh,solver=Cholesky,init=iter)=
+   @int2d(Th)( alpha *( dx(uh)*dx(vh) + dy(uh)*dy(vh) )) + @on(1,2,3,4,uh=0);
+
+ at varf amass(uh,vh,solver=Cholesky,init=iter)=
+   @int2d(Th)( uh*vh)  + @on(1,2,3,4,uh=0);
+
+ at matrix Amass = alap(Vh,Vh,solver=CG); // \index{matrix}
+
+ at matrix Alap=  alap(Vh,Vh,solver=Cholesky,factorize=1);   // \index{Cholesky}\index{factorize=}\index{solver=}
+
+// the preconditionner function
+ at func @real[@int] C(@real[@int] & x)
+{
+   @real[@int] u(x.n);
+   u=Amass*x;
+   x = Alap^-1*u;
+   x = x .* Cl[];
+   @return x; // no return of local array  variable
+}
+\eFF
+/*
+To solve the problem, we make 10 iteration of the conjugate gradient,
+recompute the preconditioner and restart the conjugate gradient:
+*/
+\bFF
+   verbosity=5;
+   @int conv=0;
+   @real eps=1e-6;
+   @for(@int i=0;i<20;i++)
+   {
+     conv=NLCG(dJ,u[],nbiter=10,precon=C,veps=eps); // \index{veps=}\index{NLCG}
+     @if (conv) break;  // if converge break loop
+
+     alpha=df( dx(u)*dx(u) + dy(u)*dy(u) ); // recompute alpha optimization
+     Alap = alap(Vh,Vh,solver=Cholesky,factorize=1);
+     @cout << " restart with new preconditionner " << conv << " eps =" << eps << endl;
+    }
+
+   @plot (u,wait=1,cmm="solution with NLCG");
+\eFF
+\end{example}
+For a given symmetric positive matrix $A$, consider the quadratic form
+\[
+J(\vec{x})=\frac{1}{2}\vec{x}^TA\vec{x}-\vec{b}^T\vec{x}
+\]
+then $J(\vec{x})$ is minimized by the solution $\vec{x}$ of $A\vec{x}=\vec{b}$.
+In this case, we can use the function \texttt{LinearCG}
+\begin{quote}\texttt{
+LinearCG($A$, $\vec{x}$, precon$=M$, nbiter$=i_{\max}$, eps$=\pm\epsilon$);
+}
+\end{quote}
+If $A$ is not symmetric, we can use GMRES(Generalized Minimum Residual) algorithm by
+\begin{quote}\texttt{
+LinearGMRES($A$, $\vec{x}$, precon$=M$, nbiter$=i_{\max}$, eps$=\pm\epsilon$);
+}
+\end{quote}
+Also, we can use the non-linear version of GMRES algorithm
+(the functional $J$ is just convex)
+\begin{quote}\texttt{
+LinearGMRES($\nabla J$, $\vec{x}$, precon$=M$, nbiter$=i_{\max}$, eps$=\pm\epsilon$);
+}
+\end{quote}
+For detail of these algorithms, refer to \cite{Lucquin}[Chapter IV, 1.3].
+
+\subsection{Optimization}
+Two algorithms of
+COOOL  a package \cite{coool} are interfaced with
+the Newton Raphson method  (call \texttt{Newton}) and
+the  \texttt{BFGS} method. \index{Newton}\index{BFGS}
+Be careful these algorithms, because the
+implementation use full matrix.
+
+Example of utilization of \texttt{algo.edp}
+\bFF
+  @func real J(real[int] & x)
+    {
+      @real s=0;
+      for (int i=0;i<x.n;i++)
+         s +=(i+1)*x[i]*x[i]*0.5 - b[i]*x[i];
+         cout << "J ="<< s << " x =" <<  x[0] << " " << x[1] << "...\n" ;
+      return s;
+    }
+  b=1; x=2; // set  right hand side and initial gest
+  @BFGS(J,dJ,x,eps=1.e-6,nbiter=20,nbiterline=20);
+  @cout << "BFGS: J(x) = " << J(x) << " err=" << error(x,b) << endl;
+
+\eFF
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{Mathematical Models}
+\label{sec:MathModels}
+
+\subsection{Static Problems}
+
+\subsubsection{\setS{Soap Film}}
+Our starting point here will be the mathematical model to find the shape of
+\textbf{soap film} which is glued to the ring on the $xy-$plane
+\begin{equation*}
+C=\{(x,y);\;x=\cos t,\,y=\sin t,\,0\leq t\leq 2\pi \}.
+\end{equation*}
+We assume the shape of the film is described as the graph $(x,y,u(x,y))$ of the vertical
+displacement $u(x,y)\, (x^2+y^2<1)$ under a vertical pressure $p$
+in terms of force per unit area and an initial tension $\mu$ in terms of force
+per unit length.
+Consider ``small plane'' ABCD, A:$(x,y,u(x,y))$, B:$(x,y,u(x+\delta x,y))$, C:$(x,y,u(x+\delta x,y+\delta y))$ and D:$(x,y,u(x,y+\delta y))$.
+Let us denote by $\vec{n}(x,y)=(n_x(x,y),n_y(x,y),n_z(x,y))$ the normal vector of the surface $z=u(x,y)$.
+We see that the vertical force due to the tension $\mu$ acting along the edge
+AD is $-\mu n_x(x,y)\delta y$ and the the vertical force acting along the edge
+AD is
+\[
+\mu n_x(x+\delta x,y)\delta y\simeq \mu\left(n_x(x,y)
++\frac{\partial n_x}{\partial x}\delta x\right)(x,y)\delta y.
+\]
+\begin{figure}[htbp]
+\label{fig:soupfilm}
+\begin{center}
+\includegraphics[height=3cm]{soapfilm}
+\end{center}
+%\caption{``small plane'' ABCD}
+\label{fig:soapfilm}
+\end{figure}
+Similarly, for the edges AB and DC we have
+\[
+-\mu n_y(x,y)\delta x,\qquad
+\mu\left(n_y(x,y)+\partial n_y/\partial y\right)(x,y)\delta x.
+\]
+The force in the vertical direction on the surface ABCD due to the tension $\mu$ is given by
+\[
+\mu\left(\partial n_x/\partial x\right)\delta x\delta y+T\left(\partial n_y/\partial y\right)\delta y\delta x.
+\]
+Assuming small displacements, we have
+\begin{eqnarray*}
+\nu_x&=&(\partial u/\partial x)/\sqrt{1+(\partial u/\partial x)^2+(\partial u/\partial y)^2}\simeq \partial u/\partial x,\\
+\nu_y&=&(\partial u/\partial y)/\sqrt{1+(\partial u/\partial x)^2+(\partial u/\partial y)^2}\simeq \partial u/\partial y.
+\end{eqnarray*}
+Letting $\delta x\to dx,\, \delta y\to dy$, we have the equilibrium of the vertical displacement of soap film on ABCD by $p$
+\[
+\mu dx dy\partial^2 u/\partial x^2 +  \mu dx dy\partial^2 u/\partial y^2
++ p dx dy = 0.
+\]
+Using the Laplace operator $\Delta = \partial^2 /\partial x^2 + \partial^2 /\partial y^2$, we can find the virtual displacement write the following
+\begin{equation}
+-\Delta u = f\quad \mbox{in }\Omega
+\end{equation}%
+where $f=p/\mu$, $\Omega =\{(x,y);\;x^{2}+y^{2}<1\}$.
+ Poisson's equation (\ref{eqn:Poisson}) appear
+also in \textbf{electrostatics} taking the form of $f=\rho /\epsilon $ where
+$\rho $ is the charge density, $\epsilon $ the dielectric constant and $u$
+is named as electrostatic potential. The soap film is glued to the ring $%
+\partial \Omega =C$, then we have the boundary condition
+\begin{equation}
+u=0\quad \mbox{on }\partial \Omega
+\end{equation}%
+If the force is gravity, for simplify, we assume that $f=-1$.
+
+
+\begin{example}[a\_tutorial.edp]~
+\index{tutorial!aTutorial.edp}
+\bFF
+ 1 : @border a(t=0,2*pi){ x = cos(t); y = sin(t);label=1;};
+ 2 :
+ 3 : @mesh disk = @buildmesh(a(50));
+ 4 : @plot(disk);
+ 5 : @fespace femp1(disk,P1);
+ 6 : femp1 u,v;
+ 7 : @func f = -1;
+ 8 : @problem laplace(u,v) =
+ 9 :     @int2d(disk)( @dx(u)*@dx(v) + @dy(u)*@dy(v) )     //  bilinear form
+10 :   - @int2d(disk)( f*v )                          //  linear form
+11 :   + @on(1,u=0) ;                                // boundary condition
+12 : @func ue = (x^2+y^2-1)/4;   // ue: exact solution
+13 : laplace;
+14 : femp1 err = u - ue;
+15 :
+16 : @plot (u,ps="aTutorial.eps",value=true,wait=true);
+17 : @plot(err,value=true,wait=true);
+18 :
+19 : @cout << "error L2=" << @sqrt(@int2d(disk)( err^2) )<< @endl;
+20 : @cout << "error H10=" << @sqrt( @int2d(disk)((dx(u)-x/2)^2)
+21 :                               + @int2d(disk)((dy(u)-y/2)^2))<< @endl;
+22 :
+23 : disk = @adaptmesh(disk,u,err=0.01);
+24 : @plot(disk,wait=1);
+25 :
+26 : laplace;
+27 :
+28 : @plot (u,value=true,wait=true);
+29 : err = u - ue;  // become FE-function on adapted mesh
+30 : @plot(err,value=true,wait=true);
+31 : cout << "error L2=" << @sqrt(@int2d(disk)( err^2) )<< endl;
+32 : cout << "error H10=" << @sqrt(@int2d(disk)((@dx(u)-x/2)^2)
+33 :                              + @int2d(disk)((@dy(u)-y/2)^2))<< endl;
+\eFF
+\begin{figure}[htbp]
+\begin{minipage}{\textwidth}
+\begin{minipage}{0.4\textwidth}
+\includegraphics[width=\textwidth]{aTutorial}%
+\caption{isovalue of $u$}
+\label{aTutorial}
+\end{minipage}
+\hspace{0.5mm}
+\begin{minipage}{0.6\textwidth}
+\includegraphics[width=\textwidth]{soapfilm3d}%
+\caption{a side view of $u$}
+\end{minipage}
+\end{minipage}
+\end{figure}
+
+In 19th line, the $L^2$-error estimation between the exact solution $u_e$,
+$$
+\|u_h - u_e\|_{0,\Omega}=\left(\int_{\Omega}|u_h-u_e|^2\, dxdy\right)^{1/2}
+$$
+and from 20th line to 21th line, the $H^1$-error seminorm estimation
+$$
+|u_h - u_e|_{1,\Omega}=\left(\int_{\Omega}|\nabla u_h-\nabla u_e|^2\, dxdy\right)^{1/2}
+$$
+are done on the initial mesh. The results are
+$\|u_h - u_e\|_{0,\Omega}=0.000384045,\, |u_h - u_e|_{1,\Omega}=0.0375506$.
+
+After the adaptation, we hava
+$\|u_h - u_e\|_{0,\Omega}=0.000109043,\, |u_h - u_e|_{1,\Omega}=0.0188411$.
+So the numerical solution is improved by adaptation of mesh.
+\end{example}
+
+\subsubsection{Electrostatics}
+We assume that there is no current and a time independent charge distribution.
+Then the electric field $\vec E$ satisfy
+\begin{eqnarray}
+\label{eqn:Maxwell0}
+\mathrm{div}\vec E=\rho/\epsilon,\quad \mathrm{curl}\vec E=0
+\end{eqnarray}
+where $\rho$ is the charge density and $\epsilon$ is called the permittivity of free space. From the second equation in (\ref{eqn:Maxwell0}), we can introduce
+the electrostatic potential such that $\vec E=-\nabla \phi$.
+Then we have Poisson equation $-\Delta \phi=f$, $f=-\rho/\epsilon$.
+We now obtain the equipotential line which is the level curve of $\phi$,
+when there are no charges except conductors $\{C_i\}_{1,\cdots,K}$.
+Let us assume $K$ conductors $C_1,\cdots,C_K$ within an enclosure $C_0$.
+Each one is held
+at an electrostatic potential $\varphi_i$. We assume that the enclosure $C0$ is
+held at
+potential 0.
+In order to know $\varphi(x)$ at any point $x$ of the domain $\Omega$, we must
+solve
+\begin{equation}
+-\Delta \varphi =0\quad \textrm{in  }\Omega ,
+\end{equation}
+where $\Omega$ is the interior of $C_0$ minus the conductors $C_i$, and
+$\Gamma$ is the boundary of $\Omega$, that is $\sum_{i=0}^N C_i$.
+Here $g$ is any function of $x$ equal to $\varphi_i$ on $C_i$ and to
+0 on $C_0$. The second equation is a reduced form for:
+\begin{equation}
+\varphi =\varphi _{i}\;\text{on }C_{i},\;i=1...N,\varphi =0\;\text{on\ }%
+C_{0}.
+\end{equation}
+\begin{example}~
+First we give the geometrical informations; $C_0=\{(x,y);\; x^2+y^2=5^2\}$,
+$C_1=\{(x,y):\; \frac{1}{0.3^2}(x-2)^2+\frac{1}{3^2}y^2=1\}$,
+$C_2=\{(x,y):\; \frac{1}{0.3^2}(x+2)^2+\frac{1}{3^2}y^2=1\}$.
+Let $\Omega$ be the disk enclosed by $C_0$ with the elliptical holes enclosed
+by $C_1$ and $C_2$. Note that $C_0$ is described counterclockwise, whereas the
+elliptical holes are described clockwise, because the boundary must be oriented so that the computational domain is to its left.
+\bFF
+// a circle with center at (0 ,0) and radius 5
+border C0(t=0,2*pi) { x = 5 * cos(t); y = 5 * sin(t); }
+border C1(t=0,2*pi) { x = 2+0.3 * cos(t); y = 3*sin(t); }
+border C2(t=0,2*pi) { x = -2+0.3 * cos(t); y = 3*sin(t); }
+
+mesh Th = buildmesh(C0(60)+C1(-50)+C2(-50));
+plot(Th,ps="electroMesh"); // figure \ref{electroMesh}
+fespace Vh(Th,P1);     // P1 FE-space
+Vh uh,vh;              // unknown and test function.
+problem Electro(uh,vh) =  //  definition of  the problem
+    int2d(Th)( dx(uh)*dx(vh) + dy(uh)*dy(vh) ) //  bilinear
+    + on(C0,uh=0)       //  boundary condition on $C_0$
+    + on(C1,uh=1)       //  +1 volt on $C_1$
+    + on(C2,uh=-1) ;    //  -1 volt on $C_2$
+
+Electro; // solve the problem, see figure \ref{electro} for the solution
+plot(uh,ps="electro.eps",wait=true); // figure \ref{electro}
+\eFF
+\end{example}
+
+\twoplot[height=5cm]{electroMesh}{electro}{Disk with two elliptical holes}
+{Equipotential lines, where $C_1$ is located in right hand side}
+
+\subsubsection{Aerodynamics}
+Let us consider a wing profile $S$ in a uniform flow.
+Infinity will be represented
+by a large circle $\Gamma_{\infty}$.
+As previously, we must solve
+\begin{equation}
+\label{eqn:NACA-5-5}
+\Delta \varphi=0\quad\textrm{in }\Omega,
+\quad \varphi|_S=c,\quad
+\varphi|_{\Gamma_{\infty}}=u_{\infty 1x}-u_{\infty2x}
+\end{equation}
+where $\Omega$ is the area occupied by the
+fluid, $u_{\infty}$ is the air speed at infinity, $c$
+is a constant to be determined so that
+$\partial_n\varphi$ is continuous at the trailing edge
+$P$ of $S$ (so-called Kutta-Joukowski condition).
+Lift is proportional to $c$.
+To find $c$ we use a superposition method. As all equations in
+(\ref{eqn:NACA-5-5}) are
+linear, the solution $\varphi_c$ is a linear function of $c$
+\begin{equation}
+\label{eqn:NACA-5-6}
+\varphi_c = \varphi_0 + c\varphi_1,
+\end{equation}
+where $\varphi_0$ is a solution of (\ref{eqn:NACA-5-5}) with $c = 0$ and
+$\varphi_1$ is a solution with $c = 1$ and
+zero speed at infinity.
+With these two fields computed, we shall determine $c$
+by requiring the continuity of $\partial \varphi /\partial n$ at the trailing edge.
+An equation for the upper surface of a NACA0012 (this is a classical wing
+profile in aerodynamics; the rear of the wing is called the trailing edge) is:
+\begin{equation}
+\label{eqn:NACA-5-7}
+y := 0.17735\sqrt{x} - 0.075597x - 0.212836x^2 + 0.17363x^3 - 0.06254x^4.
+\end{equation}
+Taking an incidence angle $\alpha$ such that $\tan \alpha = 0.1$, we must solve
+\begin{equation}
+\label{eqn:NACA-5-8}
+-\Delta\varphi  = 0\qquad \textrm{in }\Omega, \qquad
+\varphi|_{\Gamma_1} = y - 0.1x,\quad \varphi |_{\Gamma_2} = c,
+\end{equation}
+where $\Gamma_2$ is the wing profile and $\Gamma_1$ is an approximation of
+infinity. One finds $c$ by solving:
+\begin{eqnarray}
+\label{eqn:NACA-5-9}
+-\Delta\varphi_0 = 0 ~~\textrm{in }\Omega,\qquad
+\varphi_0|_{\Gamma_1} = y - 0.1x, \quad \varphi_0|_{\Gamma_2} = 0,\\
+\label{eqn:NACA-5-10}
+-\Delta\varphi_1 = 0 ~~\textrm{in }\Omega, \qquad
+\varphi_1|_{\Gamma_1} = 0, \quad \varphi_1|_{\Gamma_2} = 1.
+\end{eqnarray}
+The solution $\varphi  = \varphi_0+c\varphi_1$ allows us to find $c$
+by writing that $\partial_n\varphi$  has no jump
+at the trailing edge $P = (1, 0)$.
+We have $\partial n\varphi  -(\varphi (P^+)-\varphi (P))/\delta$ where $P^+$
+is the point just above $P$ in the direction normal to the profile at a distance
+$\delta$. Thus the jump of $\partial_n\varphi$  is
+$(\varphi_0|_{P^+} +c(\varphi_1|_{P^+} -1))+(\varphi_0|_{P^-} +c(\varphi_1|_{P^-} -1))$
+divided by $\delta$ because the normal changes sign between the lower and upper
+surfaces. Thus
+\begin{equation}
+\label{eqn:NACA-5-11}
+c = -\frac{\varphi_0|_{P^+} + \varphi_0|_{P^-}}
+{(\varphi_1|_{P^+} + \varphi_1|_{P^-} - 2)} ,
+\end{equation}
+which can be programmed as:
+\begin{equation}
+\label{eqn:NACA-5-12}
+c = -\frac{\varphi_0(0.99, 0.01) + \varphi_0(0.99,-0.01)}
+{(\varphi_1(0.99, 0.01) + \varphi_1(0.99,-0.01) - 2)} .
+\end{equation}
+
+\begin{example}
+\bFF
+
+// Computation of the potential flow around a NACA0012 airfoil.
+// The method of decomposition is used to apply the Joukowski condition
+// The solution is seeked in the form psi0 + beta psi1 and beta is
+// adjusted so that the pressure is continuous at the trailing edge
+
+ at border a(t=0,2*pi) { x=5*cos(t);  y=5*sin(t); };// approximates infinity
+
+ at border upper(t=0,1) { x = t;
+     y = 0.17735*sqrt(t)-0.075597*t
+  - 0.212836*(t^2)+0.17363*(t^3)-0.06254*(t^4); }
+ at border lower(t=1,0) { x = t;
+     y= -(0.17735*sqrt(t)-0.075597*t
+  -0.212836*(t^2)+0.17363*(t^3)-0.06254*(t^4)); }
+ at border c(t=0,2*pi) { x=0.8*cos(t)+0.5;  y=0.8*sin(t); }
+
+ at wait = @true;
+ at mesh  Zoom = @buildmesh(c(30)+upper(35)+lower(35));
+ at mesh Th = @buildmesh(a(30)+upper(35)+lower(35));
+ at fespace Vh(Th,P2);     // P1 FE space
+Vh psi0,psi1,vh;              // unknown and test function.
+ at fespace ZVh(Zoom,P2);
+
+ at solve Joukowski0(psi0,vh) =     //  definition of  the problem
+    @int2d(Th)( dx(psi0)*dx(vh) + dy(psi0)*dy(vh) ) //  bilinear form
+  + @on(a,psi0=y-0.1*x)                      //  boundary condition form
+  + @on(upper,lower,psi0=0);
+ at plot(psi0);
+
+ at solve Joukowski1(psi1,vh) =     //  definition of  the problem
+    @int2d(Th)( dx(psi1)*dx(vh) + dy(psi1)*dy(vh) ) //  bilinear form
+  + @on(a,psi1=0)                      //  boundary condition form
+  + @on(upper,lower,psi1=1);
+
+ at plot(psi1);
+
+    // continuity of pressure at trailing edge
+ at real beta = psi0(0.99,0.01)+psi0(0.99,-0.01);
+ at beta = -beta / (psi1(0.99,0.01)+ psi1(0.99,-0.01)-2);
+
+
+Vh psi = beta*psi1+psi0;
+ at plot(psi);
+ZVh Zpsi=psi;
+ at plot(Zpsi,bw=true);
+Vh cp = -dx(psi)^2 - dy(psi)^2;
+ at plot(cp);
+ZVh Zcp=cp;
+ at plot(Zcp,nbiso=40);
+\eFF
+\end{example}
+\twoplot[height=5cm]{naca1}{naca2}
+{isovalue of $cp = -(\partial_x\psi)^2 - (\partial_y\psi)^2$}
+{Zooming of $cp$}
+
+
+\subsubsection{Error estimation}
+There are famous estimation between the numerical result $u_h$ and the
+exact solution $u$ of the problem \ref{eqn:Poisson} and \ref{eqn:Dirichlet}:
+If triangulations $\{\mathcal{T}_h\}_{h\downarrow 0}$ is regular
+(see \refSec{Regular Triangulation}), then we have the estimates
+\begin{eqnarray}
+\label{eqn:H1err}
+|\nabla u - \nabla u_h|_{0,\Omega}&\le& C_1h\\
+\label{eqn:L2err}
+\|u - u_h\|_{0,\Omega}&\le& C_2h^2
+\end{eqnarray}
+with constants $C_1,\, C_2$ independent of $h$,
+if $u$ is in $H^2(\Omega)$. It is known that $u\in H^2(\Omega)$
+if $\Omega$ is convex.
+
+In this section we check (\ref{eqn:H1err}) and (\ref{eqn:L2err}).
+We will pick up numericall error if we use the numerical derivative,
+so we will use the following for (\ref{eqn:H1err}).
+\begin{eqnarray*}
+\int_{\Omega}|\nabla u - \nabla u_h|^2\, dxdy
+&=&\int_{\Omega}\nabla u\cdot \nabla(u - 2u_h)\, dxdy+
+\int_{\Omega}\nabla u_h\cdot \nabla u_h\, dxdy\\
+&=&\int_{\Omega}f(u-2u_h)\, dxdy+\int_{\Omega}fu_h\, dxdy
+\end{eqnarray*}
+The constants $C_1,\, C_2$ are depend on $\mathcal{T}_h$ and $f$,
+so we will find them by \freefempp.
+In general, we cannot get the solution $u$ as a elementary functions
+(see Section \ref{sec:TwoVarFunctions}) even if spetical functions are added.
+Instead of the exact solution, here we use the approximate solution $u_0$  in
+$V_h(\mathcal{T}_h,P_2),\, h\sim 0$.
+
+\begin{example}~
+\bFF
+ 1 : @mesh Th0 = @square(100,100);
+ 2 : @fespace V0h(Th0,P2);
+ 3 : V0h u0,v0;
+ 4 : @func f = x*y; // sin(pi*x)*cos(pi*y);
+ 5 :
+ 6 : @solve Poisson0(u0,v0) =
+ 7 :     @int2d(Th0)( @dx(u0)*@dx(v0) + @dy(u0)*@dy(v0) )     //  bilinear form
+ 8 :   - @int2d(Th0)( f*v0 )                          //  linear form
+ 9 :   + @on(1,2,3,4,u0=0) ;                // boundary condition
+10 :
+11 : @plot(u0);
+12 :
+13 : @real[int] errL2(10), errH1(10);
+14 :
+15 : @for (@int i=1; i<=10; i++) {
+16 :    @mesh Th = @square(5+i*3,5+i*3);
+17 :    @fespace Vh(Th,P1);
+18 :    @fespace Ph(Th,P0);
+19 :    Ph h = hTriangle;  // get the size of all triangles
+20 :    Vh u,v;
+21 :    @solve Poisson(u,v) =
+22 :         @int2d(Th)( dx(u)*dx(v) + dy(u)*dy(v) )     //  bilinear form
+23 :         - @int2d(Th)( f*v )                          //  linear form
+24 :         + @on(1,2,3,4,u=0) ;                // boundary condition
+25 :    V0h uu = u;
+26 :    errL2[i-1] = @sqrt( @int2d(Th0)((uu - u0)^2) )/h[].max^2;
+27 :    errH1[i-1] = @sqrt( @int2d(Th0)( f*(u0-2*uu+uu) ) )/h[].max;
+28 : }
+29 : @cout << "C1 = " << errL2.max <<"("<<errL2.min<<")"<< endl;
+30 : @cout << "C2 = " << errH1.max <<"("<<errH1.min<<")"<< endl;
+\eFF
+\end{example}
+We can guess that $C_1=0.0179253(0.0173266)$ and
+$C_2=0.0729566(0.0707543)$, where the numbers inside the parentheses
+are minimum in calculation.
+
+\subsubsection{Periodic }\index{periodic}\index{fespace!periodic=}
+We now solve the Poisson equation
+$$ -\Delta u= sin(x+\pi/4.)*cos(y+\pi/4.)$$ on
+the square $]0,2\pi[^2$
+under bi-periodic boundary condition
+$u(0,y)=u(2\pi,y)$ for all $y$ and
+$u(x,0)=u(x,2\pi)$ for all $x$.
+These boundary conditions are achieved from the definition
+of the periodic finite element space.
+
+\begin{example}[periodic.edp]~
+\label{exm:periodic}
+\index{tutorial!periodic.edp}
+\bFF
+ at mesh Th=square(10,10,[2*x*pi,2*y*pi]);
+// defined the \bgroup\tt fespace\egroup  with periodic condition
+//    label :  2 and 4  are left and right   side with y the curve abscissa
+//             1 and 2  are bottom and upper side with x the curve abscissa
+ at fespace Vh(Th,P2,periodic=[[2,y],[4,y],[1,x],[3,x]]);
+ Vh uh,vh;              // unknown and test function.
+ @func f=sin(x+pi/4.)*cos(y+pi/4.);      //  right hand side function
+
+@ problem laplace(uh,vh) =                      //  definion of  the problem
+    @int2d(Th)( dx(uh)*dx(vh) + dy(uh)*dy(vh) ) //  bilinear form
+  + @int2d(Th)( -f*vh )                         //  linear form
+;
+
+  @laplace; // solve the problem plot(uh); // to see the result
+  @plot(uh,ps="period.eps",value=true);
+\eFF
+\plot[height=6cm]{period}{The isovalue of solution $u$ with periodic boundary condition}
+\end{example}
+
+The periodic condition does not necessarily require
+parallel to the axis. Example \ref{exm:periodic4}
+ give such example.
+
+\begin{example}[periodic4.edp]~
+\label{exm:periodic4}
+\index{tutorial!periodic4.edp}
+\bFF
+ at real r=0.25;
+// a diamond with a hole
+ at border a(t=0,1){x=-t+1; y=t;label=1;};
+ at border b(t=0,1){ x=-t; y=1-t;label=2;};
+ at border c(t=0,1){ x=t-1; y=-t;label=3;};
+ at border d(t=0,1){ x=t; y=-1+t;label=4;};
+ at border e(t=0,2*pi){ x=r*cos(t); y=-r*sin(t);label=0;};
+ at int n = 10;
+ at mesh Th= buildmesh(a(n)+b(n)+c(n)+d(n)+e(n));
+ at plot(Th,wait=1);
+ at real r2=1.732;
+ at func abs=sqrt(x^2+y^2);
+//  warning for periodic condition: \hfilll
+//  side a and c \hfilll
+//  @on side a (label 1) $ x \in [0,1] $ or $ x-y\in [-1,1] $ \hfilll
+//  @on side c (label 3) $ x \in [-1,0]$ or $ x-y\in[-1,1] $\hfilll
+// so the common abscissa can be respectively $x$ and $x+1$
+// or you can can try curviline abscissa $x-y$ and $x-y$
+//  1 first way \hfilll
+// @fespace Vh(Th,P2,periodic=[[2,1+x],[4,x],[1,x],[3,1+x]]);  \hfilll
+// 2 second way \hfilll
+ @fespace Vh(Th,P2,periodic=[[2,x+y],[4,x+y],[1,x-y],[3,x-y]]);
+
+ Vh uh,vh;
+
+ @func f=(y+x+1)*(y+x-1)*(y-x+1)*(y-x-1);
+ @real intf = @int2d(Th)(f);
+ @real mTh = @int2d(Th)(1);
+ @real k =  intf/mTh;
+ @cout << k << @endl;
+ @problem laplace(uh,vh) =
+    @int2d(Th)( dx(uh)*dx(vh) + dy(uh)*dy(vh) ) + @int2d(Th)( (k-f)*vh ) ;
+ laplace;
+ @plot(uh,wait=1,ps="perio4.eps");
+\eFF
+\end{example}
+\plot[height=6cm]{perio4}{The isovalue of solution $u$ for
+$ \Delta u = ((y+x)^{2}+1)((y-x)^{2}+1) - k$, in $\Omega$ and $\partial_{n} u =0 $ on hole,and with two periodic boundary condition on external border}
+
+
+\subsubsection{Poisson with mixed boundary condition}
+Here we consider the Poisson equation with mixed boundary value
+problems: For given functions $f$ and $g$, find $u$ such that
+\begin{eqnarray}
+\label{eqn:mixBoundary}
+-\Delta u &=& f\qquad \textrm{in }\Omega\nonumber\\
+u&=&g\quad \textrm{on }\Gamma_D,\quad
+\partial u/\partial n=0\quad \textrm{on }\Gamma_N
+\end{eqnarray}
+where $\Gamma_D$ is a part of the boundary $\Gamma$ and
+$\Gamma_N=\Gamma\setminus \overline{\Gamma_D}$.
+The solution $u$ has the singularity at the points
+$\{\gamma_1,\gamma_2\}=\overline{\Gamma_D}\cap\overline{\Gamma_N}$.
+When $\Omega=\{(x,y);\; -1<x<1,\, 0<y<1\}$,
+$\Gamma_N=\{(x,y);\; -1\le x<0,\, y=0\}$,\,
+$\Gamma_D=\partial \Omega\setminus \Gamma_N$,
+the singularity will appear at $\gamma_1=(0,0),\, \gamma_2(-1,0)$,
+and $u$ has the expression
+$$
+u=K_iu_S + u_R,\, u_R\in H^2(\textrm{near }\gamma_i),\, i=1,2
+$$
+with a constants $K_i$.
+Here $u_S = r_j^{1/2}\sin(\theta_j/2)$ by the local polar coordinate
+$(r_j,\theta_j$ at $\gamma_j$ such that
+$(r_1,\theta_1)=(r,\theta)$.
+Instead of poler coordinate system $(r,\theta)$, we use that
+$r=\ttCC{sqrt( x\^2+y\^2 )}$ and $\theta = \ttCC{atan2(y,x)}$
+in \freefempp.
+
+\begin{example} Assume that $f=-2\times 30(x^2+y^2)$ and
+$g=u_e=10(x^2+y^2)^{1/4}\sin\left ([\tan^{-1}(y/x)]/2\right)
++30(x^2y^2)$, where $u_e$S is the exact solution.
+\bFF
+ 1 : @border N(t=0,1) { x=-1+t; y=0; label=1; };
+ 2 : @border D1(t=0,1){ x=t;  y=0; label=2;};
+ 3 : @border D2(t=0,1){ x=1; y=t; label=2; };
+ 4 : @border D3(t=0,2){ x=1-t; y=1; label=2;};
+ 5 : @border D4(t=0,1) { x=-1; y=1-t; label=2; };
+ 6 :
+ 7 : @mesh T0h = @buildmesh(N(10)+D1(10)+D2(10)+D3(20)+D4(10));
+ 8 : @plot(T0h,wait=true);
+ 9 : @fespace V0h(T0h,P1);
+10 : V0h u0, v0;
+11 :
+12 : @func f=-2*30*(x^2+y^2); // given function
+13 : // the singular term of the solution is K*us (K: constant)
+14 : @func us = sin(atan2(y,x)/2)*sqrt( sqrt(x^2+y^2) );
+15 : @real K=10.;
+16 : @func ue = K*us + 30*(x^2*y^2);
+17 :
+18 : @solve Poisson0(u0,v0) =
+19 :     @int2d(T0h)( dx(u0)*dx(v0) + dy(u0)*dy(v0) )     //  bilinear form
+20 :   - @int2d(T0h)( f*v0 )                          //  linear form
+21 :   + @on(2,u0=ue) ;                                // boundary condition
+22 :
+23 : // adaptation by the singular term
+24 : @mesh Th = @adaptmesh(T0h,us);
+25 : @for (@int i=0;i< 5;i++)
+26 : {
+27 :   @mesh Th=@adaptmesh(Th,us);
+28 : } ;
+29 :
+30 : @fespace Vh(Th, P1);
+31 : Vh u, v;
+32 : @solve Poisson(u,v) =
+33 :     @int2d(Th)( dx(u)*dx(v) + dy(u)*dy(v) )     //  bilinear form
+34 :   - @int2d(Th)( f*v )                          //  linear form
+35 :   + @on(2,u=ue) ;                                // boundary condition
+36 :
+37 : /* plot the solution */
+38 : @plot(Th,ps="adaptDNmix.ps");
+39 : @plot(u,wait=true);
+40 :
+41 : Vh uue = ue;
+42 : @real  H1e = @sqrt( @int2d(Th)( dx(uue)^2 + dy(uue)^2 + uue^2 ) );
+43 :
+44 : /* calculate the H1 Sobolev norm */
+45 : Vh err0 = u0 - ue;
+46 : Vh  err = u - ue;
+47 : Vh  H1err0 = @int2d(Th)( dx(err0)^2+dy(err0)^2+err0^2 );
+48 : Vh  H1err = @int2d(Th)( dx(err)^2+dy(err)^2+err^2 );
+49 : @cout <<"Relative error in first mesh "<< @int2d(Th)(H1err0)/H1e<<@endl;
+50 : @cout <<"Relative error in adaptive mesh "<< @int2d(Th)(H1err)/H1e<@<endl;
+\eFF
+From 24th line to 28th, adaptation of meshes are done using the
+base of singular term.
+In 42th line, \ttCC{H1e}=$\|u_e\|_{1,\Omega}$ is calculated.
+In last 2 lines, the relative errors are calculated, that is,
+\begin{eqnarray*}
+\|u^0_h-u_e\|_{1,\Omega}/\ttCC{H1e}&=&0.120421\\
+\|u^a_h-u_e\|_{1,\Omega}/\ttCC{H1e}&=&0.0150581
+\end{eqnarray*}
+where $u^0_h$ is the numerical solution in \ttCC{T0h} and
+$u^a_h$ is \ttCC{u} in this program.
+\end{example}
+
+\subsubsection{Adaptation with residual error indicator}
+
+We do metric mesh adaption and compute the classical
+residual error indicator $\eta_{T}$ on the element $T$ for the Poisson problem.
+
+\begin{example}[adaptindicatorP2.edp]~
+\index{tutorial!adaptindicatorP2.edp}
+First, we solve the same problem as in a previous example.
+\bFF
+ 1 : @border ba(t=0,1.0){x=t;   y=0;  label=1;}; // see Fig,\ref{L-shape2}
+ 2 : @border bb(t=0,0.5){x=1;   y=t;  label=2;};
+ 3 : @border bc(t=0,0.5){x=1-t; y=0.5;label=3;};
+ 4 : @border bd(t=0.5,1){x=0.5; y=t;  label=4;};
+ 5 : @border be(t=0.5,1){x=1-t; y=1;  label=5;};
+ 6 : @border bf(t=0.0,1){x=0;   y=1-t;label=6;};
+ 7 : @mesh Th = buildmesh (ba(6) + bb(4) + bc(4) +bd(4) + be(4) + bf(6));
+ 8 : @savemesh(Th,"th.msh");
+ 9 : @fespace Vh(Th,P2);
+10 : @fespace Nh(Th,P0);
+11 : Vh u,v;
+12 : Nh rho;
+13 : real[int] viso(21);
+14 : @for (@int i=0;i<viso.n;i++)
+15 :   viso[i]=10.^(+(i-16.)/2.);
+16 : @real error=0.01;
+17 : @func f=(x-y);
+18 : @problem Probem1(u,v,solver=CG,eps=1.0e-6) =
+19 :     @int2d(Th,qforder=5)( u*v*1.0e-10+  dx(u)*dx(v) + dy(u)*dy(v))
+20 :   + @int2d(Th,qforder=5)( -f*v);
+21 : /*************
+\eFF
+\index{jump}\index{intalledges}\index{square}\index{lenEdge}\index{hTriangle}%\index{area}
+Now, the local  error indicator $\eta_{T}$ is:
+\def\Th{\mathcal{T}_{h}}
+\def\AK{\mathcal{E}_{K}}
+
+$$\eta_{T} =\left(  h_{T}^{2} || f + \Delta u_{{h}} ||_{L^{2}(T)}^{2} +\sum_{e\in \AK} h_{e} \,||\, [ \frac{\partial u_{h}}{\partial n_{k}}] \,||^{2}_{L^{2}(e)} \right)^{\frac{1}{2}}
+   $$
+where $h_{T}$ is the longest's edge of  $T$, ${\cal E}_T$ is the set of $T$ edge not on
+$\Gamma=\partial \Omega$, $n_{T}$ is the  outside unit normal to $K$, $h_{e}$ is the length of edge $e$,
+$[ g ]$ is the jump of the function $g$ across edge (left value minus right value).
+
+Of coarse, we can use a variational form to compute $\eta_{T}^{2}$,
+with test function constant function in each triangle.
+\bFF
+29 : *************/
+30 :
+31 : @varf indicator2(uu,chiK) =
+32 :      @intalledges(Th)(chiK*lenEdge*square(jump(N.x*dx(u)+N.y*dy(u))))
+33 :     + at int2d(Th)(chiK*square(hTriangle*(f+dxx(u)+dyy(u))) );
+34 : for (int i=0;i< 4;i++)
+35 : {
+36 :   Probem1;
+37 :    @cout << u[].min << " " << u[].max << endl;
+38 :    @plot(u,wait=1);
+39 :    @cout << " indicator2 " << endl;
+40 :
+41 :    rho[] = indicator2(0,Nh);
+42 :    rho=sqrt(rho);
+43 :    @cout << "rho =   min " << rho[].min << " max=" << rho[].max << @endl;
+44 :    @plot(rho,fill=1,wait=1,cmm="indicator density ",ps="rhoP2.eps",
+                                       value=1,viso=viso,nbiso=viso.n);
+45 :    @plot(Th,wait=1,cmm="Mesh ",ps="ThrhoP2.eps");
+46 :    Th=@adaptmesh(Th,[dx(u),dy(u)],err=error,anisomax=1);
+47 :    @plot(Th,wait=1);
+48 :    u=u;
+49 :    rho=rho;
+50 :   error = error/2;
+51 : } ;
+\eFF
+If the method is correct, we expect to look the graphics by an almost constant function $\eta$ on your computer as in Fig. \ref{fig:rhoP2}.
+\begin{figure}[hbt]
+\begin{center}
+\label{fig:rhoP2}
+\includegraphics[height=8cm]{rhoP2} \includegraphics[height=8cm]{ThrhoP2}
+\end{center}
+\caption{Density of the error indicator  with isotropic $P^{2}$ metric }
+\end{figure}
+\end{example}
+
+
+\subsection{Elasticity}
+
+Consider an elastic plate with undeformed shape $\Omega\times ]-h,h[$
+in $\R^3$, $\Omega\subset\R^2$.
+By the deformation of the plate,
+we assume that a point $P(x_1,x_2,x_3)$ moves to
+${\cal P}(\xi_1,\xi_2,\xi_3)$.
+The vector $\vec u=(u_1,u_2,u_3)=(\xi_1-x_1,\xi_2-x_2,\xi_3-x_3)$ is called
+\key{displacement vector}.
+By the deformation,
+the line segment
+$\overline{\mathbf{x},\mathbf{x}+\tau\Delta\mathbf{x}}$ moves approximately to
+$\overline{\mathbf{x}+u(\mathbf{x}),\mathbf{x}+\tau\Delta\mathbf{x}
++u(\mathbf{x}+\tau\Delta\mathbf{x})}$ for small $\tau$,
+where
+$\mathbf{x}=(x_1,x_2,x_3),\, \Delta\mathbf{x}
+=(\Delta x_1,\Delta x_2,\Delta x_3)$.
+We now calculate the ratio between two segments
+\[
+\eta(\tau)=\tau^{-1}|\Delta\mathbf{x}|^{-1}
+\left(|u(\mathbf{x}+\tau\Delta\mathbf{x})
+-u(\mathbf{x})+\tau\Delta\mathbf{x}|-\tau|\Delta\mathbf{x}|\right)
+\]
+then we have (see e.g. \cite[p.32]{Necas})
+\begin{eqnarray*}
+\lim_{\tau\to 0}\eta(\tau)=(1+2e_{ij}\nu_i\nu_j)^{1/2}-1,
+\quad 2e_{ij}=\frac{\partial u_k}{\partial x_i}\frac{\partial u_k}{\partial x_j}+\left(\frac{\partial u_i}{\partial x_j}+
+\frac{\partial u_j}{\partial x_i}\right)
+\end{eqnarray*}
+where $\nu_i=\Delta x_i|\Delta\mathbf{x}|^{-1}$. If the deformation is
+\emph{small}, then we may consider that
+\[
+(\partial u_k/\partial x_i)(\partial u_k/\partial x_i)\approx 0
+\]
+and the following is called \emph{small \key{strain tensor}}
+\[
+\varepsilon_{ij}(u)=\frac{1}{2}\left(\frac{\partial u_i}{\partial x_j}+
+\frac{\partial u_j}{\partial x_i}\right)
+\]
+The tensor $e_{ij}$ is called \emph{finite strain tensor}.
+
+Consider the small plane $\Delta \Pi(\mathbf{x})$
+centered at $\mathbf{x}$ with the
+unit normal direction $\vec n=(n_1,n_2,n_3)$, then the surface
+on $\Delta \Pi(\mathbf{x})$ at $\mathbf{x}$ is
+\[
+(\sigma_{1j}(\mathbf{x})n_j, \sigma_{2j}(\mathbf{x})n_j, \sigma_{3j}(\mathbf{x})n_j)
+\]
+where $\sigma_{ij}(\mathbf{x})$ is called \key{stress tensor} at $\mathbf{x}$.
+Hooke's law is the assumption of a linear relation between $\sigma_{ij}$
+and $\varepsilon_{ij}$ such as
+\[
+\sigma_{ij}(\mathbf{x})=c_{ijkl}(\mathbf{x})\varepsilon_{ij}(\mathbf{x})
+\]
+with the symmetry $c_{ijkl}=c_{jikl}, c_{ijkl}=c_{ijlk}, c_{ijkl}=c_{klij}$.
+
+If Hooke's tensor $c_{ijkl}(\mathbf{x})$ do not depend on the choice of
+coordinate system, the material is called \key{isotropic} at $\mathbf{x}$.
+If $c_{ijkl}$ is constant, the material is called \emph{homogeneous}.
+In homogeneous isotropic case, there is \emph{Lam\'{e} constants}
+$\lambda, \mu$ (see e.g. \cite[p.43]{Necas}) satisfying
+\begin{eqnarray}
+\label{eqn:isotropic}
+\sigma_{ij}=\lambda\delta_{ij}\textrm{div}u+2\mu \varepsilon_{ij}
+\end{eqnarray}
+where $\delta_{ij}$ is Kronecker's delta.
+We assume that
+the elastic plate is fixed
+on $\Gamma_D\times ]-h,h[,\, \Gamma_D\subset \partial\Omega$.
+If the body force $f=(f_1,f_2,f_3)$ is given in $\Omega\times]-h,h[$
+and surface force $g$ is given in $\Gamma_N\times]-h,h[,
+\Gamma_N=\partial\Omega\setminus\overline{\Gamma_D}$,
+then the equation of equilibrium is given as follows:
+\begin{eqnarray}
+\label{eqn:elasticity}
+-\partial_j \sigma_{ij}&=&f_i~~\textrm{in }\Omega\times ]-h,h[,\quad
+i=1,2,3\\
+\sigma_{ij}n_j&=&g_i~~\textrm{on }\Gamma_N\times ]-h,h[,\quad
+u_i=0~~\textrm{on }\Gamma_D\times ]-h,h[,\quad i=1,2,3
+\end{eqnarray}
+
+We now explain the plain elasticity.
+\begin{description}
+\item[Plain strain:]
+On the end of plate, the contact condition $u_3=0,\, g_3=$ is satisfied.
+In this case, we can suppose that $f_3=g_3=u_3=0$ and
+$\vec u(x_1,x_2,x_3)=\overline{u}(x_1,x_2)$ for all $-h<x_3<h$.
+\item[Plain stress:]
+The cylinder is assumed to be very thin and subjected to no load on the
+ends $x_3=\pm h$, that is,
+\[
+\sigma_{3i}=0,\quad x_3=\pm h,\quad i~1,2,3
+\]
+The assumption leads that $\sigma_{3i}=0$ in $\Omega\times ]-h,h[$
+and $\vec u(x_1,x_2,x_3)=\overline{u}(x_1,x_2)$ for all $-h<x_3<h$.
+\item[Generalized plain stress:]
+The cylinder is subjected to no load on the ends $x_3=\pm h$.
+Introducing the mean values with respect to thickness,
+\[
+\overline{u}_i(x_1,x_2)=\frac{1}{2h}
+\int_{-h}^h u(x_1,x_2,x_3)dx_3
+\]
+and we derive $\overline{u}_3\equiv 0$. Similarly we define the mean
+values $\overline{f},\overline{g}$ of the body force and surface force
+as well as the mean values $\overline{\varepsilon}_{ij}$ and
+$\overline{\sigma}_{ij}$ of the components of stress and strain, respectively.
+\end{description}
+In what follows we omit the overlines of
+$\overline{u}, \overline{f},\overline{g}, \overline{\varepsilon}_{ij}$ and
+$\overline{\varepsilon}_{ij}$.
+Then we obtain similar equation of equilibrium given in (\ref{eqn:elasticity})
+replacing $\Omega\times ]-h,h[$ with $\Omega$ and changing $i=1,2$.
+In the case of plane stress,
+$\sigma_{ij}=\lambda^* \delta_{ij}\textrm{div}u+2\mu\varepsilon_{ij},
+\lambda^*=(2\lambda \mu)/(\lambda+\mu)$.
+
+The equations of elasticity are naturally written in variational form
+for the displacement vector $u(x)\in V$ as
+\Blue{$$
+\int_\Omega [2\mu\epsilon_{ij}(\vec u)\epsilon_{ij}(\vec v)
++\lambda \epsilon_{ii}(\vec{u})\epsilon_{jj}(\vec v)]
+=\int_\Omega \vec f\cdot \vec v +\int_\Gamma \vec g\cdot \vec v,%\`{u}
+\forall \vec v\in V
+$$}
+where $V$ is the linear closed subspace of $H^1(\Omega)^2$.
+
+\begin{example}[Beam.edp]
+\index{tutorial!beam.edp}
+Consider  elastic plate with the undeformed rectangle shape
+$[0,10]\times [0,2]$.
+The body force is the gravity force $\vec f$ and the
+boundary force $\vec g$ is zero on lower and upper side.
+On the two vertical sides of the beam are fixed.
+\bFF
+//   a weighting beam sitting on a
+
+int bottombeam = 2;
+ at border a(t=2,0)  { x=0; y=t ;label=1;};        //  left beam
+ at border b(t=0,10) { x=t; y=0 ;label=bottombeam;};        //  bottom of beam
+ at border c(t=0,2)  { x=10; y=t ;label=1;};       //  rigth beam
+ at border d(t=0,10) { x=10-t; y=2; label=3;};     //  top beam
+ at real E = 21.5;
+ at real sigma = 0.29;
+ at real mu = E/(2*(1+sigma));
+ at real lambda = E*sigma/((1+sigma)*(1-2*sigma));
+ at real gravity = -0.05;
+ at mesh th = buildmesh( b(20)+c(5)+d(20)+a(5));
+ at fespace Vh(th,[P1,P1]);
+Vh [uu,vv], [w,s];
+ at cout << "lambda,mu,gravity ="<<lambda<< " " << mu << " " << gravity << endl;
+// deformation of a beam under its own weight
+ at solve  bb([uu,vv],[w,s])  =
+    @int2d(th)(
+          2*mu*(dx(uu)*dx(w)+dy(vv)*dy(s)+ ((dx(vv)+dy(uu))*(dx(s)+dy(w)))/2 )
+          + lambda*(dx(uu)+dy(vv))*(dx(w)+dy(s))
+    )
+  + @int2d(th) (-gravity*s)
+  + @on(1,uu=0,vv=0)
+ ;
+
+ at plot([uu,vv],wait=1);
+ at plot([uu,vv],wait=1,bb=[[-0.5,2.5],[2.5,-0.5]]);
+ at mesh th1 = movemesh(th, [x+uu, y+vv]);
+ at plot(th1,wait=1);
+\eFF
+\end{example}
+
+\subsubsection{Fracture Mechanics}
+Consider the plate with the crack whose undeformed shape is
+a curve $\Sigma$ with the two edges $\gamma_1,\, \gamma_2$.
+We assume the stress tensor $\sigma_{ij}$ is the state of
+plate stress regarding $(x,y)\in \Omega_{\Sigma}=\Omega\setminus \Sigma$.
+Here $\Omega$ stands for the undeformed shape of elastic plate
+without crack.
+If the part $\Gamma_N$ of the boundary $\partial\Omega$ is fixed
+and a load ${\cal L}=(\vec f,\vec g)\in
+L^2(\Omega)^2\times L^2(\Gamma_N)^2$  is given,
+then the displacement $\vec u$ is the minimizer of the potential energy
+functional
+\[
+{\cal E}(\vec v;{\cal L},\Omega_{\Sigma})
+=\int_{\Omega_{\Sigma}}
+\{w(x,\vec v)-\vec f\cdot \vec v\}
+-\int_{\Gamma_N}\vec g\cdot \vec v\
+\]
+over the functional space $V(\Omega_{\Sigma})$,
+\[
+V(\Omega_{\Sigma})
+=\left\{ \vec v\in H^1(\Omega_{\Sigma})^2;\;
+\vec v=0\quad \hbox{\rm on }
+\Gamma_D=\partial\Omega\setminus\overline{\Gamma_N}\right\},
+\]
+where $w(x,\vec v)=\sigma_{ij}(\vec v)\varepsilon_{ij}(\vec v)/2$,
+\[
+\sigma_{ij}(\vec v)=C_{ijkl}(x)\varepsilon_{kl}(\vec v),\quad
+\varepsilon_{ij}(\vec v)=(\partial v_i/\partial x_j+
+\partial v_j/\partial x_i)/2,
+\qquad (C_{ijkl}:\quad \hbox{\rm Hooke's tensor}).
+\]
+If the elasticity is homogeneous isotropic, then the
+displacement $\vec u(x)$ is decomposed in an open neighborhood $U_k$
+of $\gamma_k$ as in (see e.g. \cite{Ohtsuka})
+\begin{equation}
+\label{eqn:SIF}
+\vec u(x) =
+\sum_{l=1}^2 K_l(\gamma_k) r_k^{1/2} S^C_{kl}(\theta_k)
++ \vec u_{k,R}(x)
+\quad \mbox{for }x\in \Omega_{\Sigma}\cap U_k,\, k=1,2
+\end{equation}
+with $\vec u_{k,R} \in H^2(\Omega_\Sigma\cap U_k)^2$, where
+$U_k,\, k=1,2$ are open neighborhoods of $\gamma_k$ such that
+$\partial L_1\cap U_1=\gamma_1,\, \partial L_m\cap U_2=\gamma_2$,
+and
+\begin{eqnarray}
+\label{eqn:SIF2}
+ S^C_{k1}(\theta_k) & = & \frac 1 {4\mu} \frac 1 {(2\pi)^{1/2}}
+    \left[ \begin{array}{c}
+    [2\kappa-1]\cos(\theta_k/2)-\cos(3\theta_k/2)\\
+    -[2\kappa+1]\sin(\theta_k/2)+\sin(3\theta_k/2)
+    \end{array}\right],\\
+ S^C_{k2}(\theta_k) & = & \frac 1 {4\mu} \frac 1 {(2\pi)^{1/2}}
+    \left[ \begin{array}{c}
+    -[2\kappa-1]\sin(\theta_k/2)+3\sin(3\theta_k/2)\\
+    -[2\kappa+1]\cos(\theta_k/2)+\cos(3\theta_k/2)
+    \end{array}\right]. \nonumber
+\end{eqnarray}
+where $\mu$ is the shear modulus of elasticity,
+$\kappa=3-4\nu$ ($\nu$ is the Poisson's ratio) for
+plane strain and $\kappa=\frac {3-\nu} {1+\nu}$ for plane stress.
+
+The coefficients $K_1(\gamma_i)$ and $K_2(\gamma_i),$ which are important parameters in fracture mechanics,
+are called stress intensity factors of the opening mode (mode I)
+and the sliding mode (mode II), respectively.
+
+For simplicity, we consider the following simple crack
+\[
+\Omega=\{(x,y):\; -1<x<1, -1<y<1\},\qquad
+\Sigma=\{(x,y):\; -1\le x\le 0, y=0\}
+\]
+with only one crack tip $\gamma=(0,0)$.
+Unfortunately, \freefempp cannot treat crack, so we use the modification
+of the domain with U-shape channel (see Fig. \ref{U-shape})
+with $d=0.0001$. The undeformed crack $\Sigma$ is approximated by
+\begin{eqnarray*}
+\Sigma_d&=&\{(x,y):\; -1\le x\le -10*d, -d\le y\le d\}\\
+&&\cup\{(x,y):\; -10*d\le x\le 0, -d+0.1*x\le y\le d-0.1*x\}
+\end{eqnarray*}
+and $\Gamma_D=\ttCC{R}$ in Fig. \ref{U-shape}.
+In this example, we use three technique:
+\begin{itemize}
+\item
+Fast Finite Element Interpolator from the mesh \ttCC{Th}
+to \ttCC{Zoom} for the scale-up of
+near $\gamma$.
+\item
+After obtaining the displacement vector $\vec u=(u,v)$, we shall watch
+the deformation of the crack near $\gamma$ as follows,
+\bT
+mesh Plate = movemesh(Zoom,[x+u,y+v]);
+plot(Plate);
+\eT
+\item
+Important technique is adaptive mesh, because the large singularity occur at
+$\gamma$
+as shown in (\ref{eqn:SIF}).
+\end{itemize}
+First example create mode I deformation by the opposed surface force
+on \ttCC{B} and \ttCC{T}
+in the vertical direction of $\Sigma$, and
+the displacement is fixed on \ttCC{R}.
+
+In a laboratory, fracture engineer use
+photoelasticity to make stress field visible, which
+shows the principal stress difference
+\begin{eqnarray}
+\sigma_1-\sigma_2=\sqrt{(\sigma_{11}-\sigma_{22})^2+4\sigma_{12}^2}
+\end{eqnarray}
+where $\sigma_1$ and $\sigma_2$ are the principal stresses.
+In opening mode, the photoelasticity make symmetric pattern concentrated at
+$\gamma$.
+\begin{example}[Crack Opening, $K_2(\gamma)=0$]
+\bFF{CrackOpen.edp}
+ at real d = 0.0001;
+ at int n = 5;
+ at real cb=1, ca=1, tip=0.0;
+ at border L1(t=0,ca-d) { x=-cb; y=-d-t; }
+ at border L2(t=0,ca-d) { x=-cb; y=ca-t; }
+ at border B(t=0,2) { x=cb*(t-1); y=-ca; }
+ at border C1(t=0,1) { x=-ca*(1-t)+(tip-10*d)*t; y=d; }
+ at border C21(t=0,1) { x=(tip-10*d)*(1-t)+tip*t; y=d*(1-t); }
+ at border C22(t=0,1) { x=(tip-10*d)*t+tip*(1-t); y=-d*t; }
+ at border C3(t=0,1) { x=(tip-10*d)*(1-t)-ca*t; y=-d; }
+ at border C4(t=0,2*d) { x=-ca; y=-d+t; }
+ at border R(t=0,2) { x=cb; y=cb*(t-1); }
+ at border T(t=0,2) { x=cb*(1-t); y=ca; }
+ at mesh Th = @buildmesh (L1(n/2)+L2(n/2)+B(n)
+                       +C1(n)+C21(3)+C22(3)+C3(n)+R(n)+T(n));
+cb=0.1; ca=0.1;
+ at plot(Th, at wait=1);
+ at mesh Zoom = @buildmesh (L1(n/2)+L2(n/2)+B(n)+C1(n)
+                         +C21(3)+C22(3)+C3(n)+R(n)+T(n));
+ at plot(Zoom, at wait=1);
+ at real E = 21.5;
+ at real sigma = 0.29;
+ at real mu = E/(2*(1+sigma));
+ at real lambda = E*sigma/((1+sigma)*(1-2*sigma));
+ at fespace Vh(Th,[P2,P2]);
+ at fespace zVh(Zoom,P2);
+Vh [u,v], [w,s];
+ at solve  Problem([u,v],[w,s])  =
+    @int2d(Th)(
+             2*mu*(dx(u)*dx(w)+ ((dx(v)+dy(u))*(dx(s)+dy(w)))/4 )
+             + lambda*(dx(u)+dy(v))*(dx(w)+dy(s))/2
+             )
+    - at int1d(Th,T)(0.1*(4-x)*s)+ at int1d(Th,B)(0.1*(4-x)*s)
+    + at on(R,u=0)+on(R,v=0);                // fixed
+;
+
+zVh Sx, Sy, Sxy, N;
+ at for (@int i=1; i<=5; i++)
+{
+  @mesh Plate = @movemesh(Zoom,[x+u,y+v]); // deformation near $\gamma$
+  Sx = lambda*(dx(u)+dy(v)) + 2*mu*dx(u);
+  Sy = lambda*(dx(u)+dy(v)) + 2*mu*dy(v);
+  Sxy = mu*(dy(u) + dx(v));
+  N = 0.1*1*sqrt((Sx-Sy)^2+4*Sxy^2); //principal stress difference
+  @if (i==1) {
+     @plot(Plate,ps="1stCOD.eps",bw=1); // Fig. \ref{1stMode1}
+     @plot(N,ps="1stPhoto.eps",bw=1);   // Fig. \ref{1stMode1}
+  } @else @if (i==5) {
+     @plot(Plate,ps="LastCOD.eps",bw=1); // Fig. \ref{LastMode1}
+     @plot(N,ps="LastPhoto.eps",bw=1);   // Fig. \ref{LastMode1}
+     @break;
+  }
+  Th=@adaptmesh(Th,[u,v]);
+  Problem;
+}
+\eFF
+\end{example}
+
+\begin{figure}[hbt]
+\begin{multicols}{2}
+\begin{center}
+\includegraphics*[height=3cm]{1stCOD}\includegraphics*[height=3cm]{1stPhoto}
+    \caption{\label{1stMode1} Crack open displacement (COD) and Principal stress difference in the first mesh}
+\end{center}
+\begin{center}
+\includegraphics*[height=3cm]{LastCOD}\includegraphics*[height=3cm]{LastPhoto}
+    \caption{\label{LastMode1} COD and Principal stress difference in the last adaptive mesh}
+\end{center}
+\end{multicols}
+\end{figure}
+It is difficult to create mode II deformation by the opposed shear force
+on \ttCC{B} and \ttCC{T} that is observed in a laboratory.
+So we use the body shear force along $\Sigma$, that is, the $x$-component $f_1$
+of the body force $\vec f$ is given by
+\[
+f_1(x,y)=H(y-0.001)*H(0.1-y)-H(-y-0.001)*H(y+0.1)
+\]
+where $H(t)=1$ if $t>0$; $= 0$ if $t<0$.
+
+\begin{example}[Crack Sliding, $K_2(\gamma)=0$]
+\bFF
+(use the same mesh Th)
+cb=0.01; ca=0.01;
+ at mesh Zoom = @buildmesh (L1(n/2)+L2(n/2)+B(n)+C1(n)
+                         +C21(3)+C22(3)+C3(n)+R(n)+T(n));
+(use same FE-space Vh and elastic modulus)
+ at fespace Vh1(Th,P1);
+Vh1 fx = ((y>0.001)*(y<0.1))-((y<-0.001)*(y>-0.1)) ;
+
+ at solve  Problem([u,v],[w,s])  =
+    @int2d(Th)(
+             2*mu*(dx(u)*dx(w)+ ((dx(v)+dy(u))*(dx(s)+dy(w)))/4 )
+             + lambda*(dx(u)+dy(v))*(dx(w)+dy(s))/2
+             )
+    - at int2d(Th)(fx*w)
+    + at on(R,u=0)+ at on(R,v=0);        // fixed
+;
+
+ at for (@int i=1; i<=3; i++)
+{
+  @mesh Plate = @movemesh(Zoom,[x+u,y+v]); // deformation near $\gamma$
+  Sx = lambda*(dx(u)+dy(v)) + 2*mu*dx(u);
+  Sy = lambda*(dx(u)+dy(v)) + 2*mu*dy(v);
+  Sxy = mu*(dy(u) + dx(v));
+  N = 0.1*1*sqrt((Sx-Sy)^2+4*Sxy^2); //principal stress difference
+  @if (i==1) {
+     @plot(Plate,ps="1stCOD2.eps",bw=1); // Fig. \ref{LastMode2}
+     @plot(N,ps="1stPhoto2.eps",bw=1);   // Fig. \ref{1stMode2}
+  } else if (i==3) {
+     @plot(Plate,ps="LastCOD2.eps",bw=1); // Fig. \ref{LastMode2}
+     @plot(N,ps="LastPhoto2.eps",bw=1);   // Fig. \ref{LastMode2}
+     break;
+  }
+  Th=@adaptmesh(Th,[u,v]);
+  Problem;
+}
+\eFF
+\end{example}
+\begin{figure}[hbt]
+\begin{multicols}{2}
+\begin{center}
+\includegraphics*[height=3cm]{1stCOD2}\includegraphics*[height=3cm]{1stPhoto2}
+    \caption{\label{1stMode2} (COD) and Principal stress difference in the first mesh}
+\end{center}
+\begin{center}
+\includegraphics*[height=3cm]{LastCOD2}\includegraphics*[height=3cm]{LastPhoto2}
+    \caption{\label{LastMode2} COD and Principal stress difference in the last adaptive mesh}
+\end{center}
+\end{multicols}
+\end{figure}
+
+
+\subsection{Nonlinear Static Problems}
+We propose how to solve the following non-linear academic  problem of minimization
+of a functional $$J(u) = \int_\Omega f(|\nabla u|^2) - u*b $$
+where $u$ is function of $H^1_0(\Omega)$
+and $f$ defined by
+$$
+f(x) = a*x + x-ln(1+x), \quad f'(x) = a+\frac{x}{1+x}, \quad f''(x) =  \frac{1}{(1+x)^2}
+$$
+
+\subsubsection{Newton Ralphson algorithm}
+
+
+Now, we solve the Euler problem $ \nabla J (u) = 0$
+with Newton Ralphson algorithm, that is,
+$$
+u^{n+1} = u^n - ( \nabla^2 J (u^{n}))^{-1}*dJ(u^n)
+$$
+
+\index{Newton}
+First we introduice the two variational form \texttt{vdJ} and \texttt{vhJ} to
+compute respectively $ \nabla J$ and $ \nabla^2 J$
+\bFF
+//   method of  Newton Ralphson to solve dJ(u)=0; \hfilll
+//    $$ u^{n+1} = u^n - (\frac{\partial dJ}{\partial u_i})^{-1}*dJ(u^n) $$ \hfilll
+//   --------------------------------------------- \hfilll
+  Ph dalpha ; //to store = $f''( |\nabla u|^2) $  optimisation
+
+
+  // the variational form of evaluate  dJ = $ \nabla J$ \hfilll
+  // -------------------------------------- \hfilll
+  //  dJ =  f'()*( dx(u)*dx(vh) + dy(u)*dy(vh) \hfilll
+  @varf vdJ(uh,vh) =  int2d(Th)( alpha*( dx(u)*dx(vh) + dy(u)*dy(vh) ) - b*vh)
+  + on(1,2,3,4, uh=0);
+
+
+  // the variational form of evaluate  ddJ   $= \nabla^2 J$ \hfilll
+  // hJ(uh,vh) =  f'()*( dx(uh)*dx(vh) + dy(uh)*dy(vh) \hfilll
+  //            + f''()( dx(u)*dx(uh) + dy(u)*dy(uh) ) * (dx(u)*dx(vh) + dy(u)*dy(vh)) \hfilll
+  @varf vhJ(uh,vh) = int2d(Th)( alpha*( dx(uh)*dx(vh) + dy(uh)*dy(vh) )
+   +  dalpha*( dx(u)*dx(vh) + dy(u)*dy(vh)  )*( dx(u)*dx(uh) + dy(u)*dy(uh) ) )
+   + on(1,2,3,4, uh=0);
+
+ // the Newton algorithm \hfilll
+  Vh v,w;
+  u=0;
+  @for (int i=0;i<100;i++)
+   {
+    alpha = df( dx(u)*dx(u) + dy(u)*dy(u) ) ; // optimization
+    dalpha = ddf( dx(u)*dx(u) + dy(u)*dy(u) ) ; // optimization
+    v[]= vdJ(0,Vh);  // $ v = \nabla J(u) $
+    real res= v[]'*v[]; // the dot product
+    cout << i <<  " residu^2 = " <<  res  << endl;
+    @if( res< 1e-12) @break;
+    @matrix H= vhJ(Vh,Vh,factorize=1,solver=LU); //\index{matrix!factorize=}
+    w[]=H^-1*v[];
+    u[] -= w[];
+   }
+   plot (u,wait=1,cmm="solution with Newton Ralphson");
+\eFF
+
+\subsection{Eigenvalue Problems}
+
+This section depend on your FreeFem++ compilation process (see \texttt{README\_arpack}),
+of this tools.
+This tools is available in \texttt{FreeFem++}  if the word ``eigenvalue'' appear in line ``Load:'', like:
+\bFF
+-- FreeFem++ v1.28 (date Thu Dec 26 10:56:34 CET 2002)
+ file : LapEigenValue.edp
+ Load: lg_fem lg_mesh @eigenvalue
+\eFF
+This tools is based on the \texttt{arpack++} \footnote{\url{http://www.caam.rice.edu/software/ARPACK/}}
+the object-oriented version of ARPACK eigenvalue package \cite{arpack}.
+
+The function EigenValue compute the generalized eigenvalue
+of  $ A u = \lambda B u $ where sigma =$\sigma$ is the shift of the method.
+The matrix  $ OP$ is defined with $ A - \sigma B $.
+The return value is the number of converged eigenvalue (can be greater than the number of eigen value nev=)
+
+\bFF
+ at int k=@EigenValue(OP,B,nev= , sigma= );
+\eFF
+where the matrix $OP=  A - \sigma B $ with a solver and boundary condition,
+and the matrix $B$.
+
+\begin{description}
+          \item[\texttt{sym=}]    the problem is symmetric (all the eigen value are real)
+          \item[\texttt{nev=}]    the number desired eigenvalues (nev)  close to the shift.
+        \item[\texttt{value=}]    the array to store the real part of the eigenvalues
+         \item[\texttt{ivalue=}]     the array to store the imag. part of the eigenvalues
+         \item[\texttt{vector=}]    the array to store the eigenvectors.
+ For real nonsymmetric problems, complex eigenvectors are given as two consecutive vectors, so if eigenvalue $k$ and $k+1$ are complex conjugate eigenvalues, the $k$th vector will contain the real part and the $k+1$th vector the imaginary part of the corresponding complex conjugate eigenvectors.
+
+         \item[\texttt{tol=}]        the relative accuracy to which eigenvalues are to be determined;
+         \item[\texttt{sigma=}]    the shift value;
+         \item[\texttt{maxit=}]    the maximum number of iterations allowed;
+          \item[\texttt{ncv=}]     the number of Arnoldi vectors generated at each iteration of ARPACK.
+ \end{description}
+
+
+\begin{example}[lapEignenValue.edp]
+\label{exm:lapEigenValue}
+In the first example, we compute   the eigenvalue and the eigenvector of the
+ Dirichlet problem  on square $\Omega=]0,\pi[^2$.
+
+The problem is find:   $\lambda$, and $\nabla u_{\lambda}$  in $\mathbb{R}{\times} H^1_0(\Omega)$
+$$ \int_\Omega \nabla u_{\lambda} \nabla v = \lambda \int_\Omega u  v \quad  \forall v \in H^1_0(\Omega)$$
+
+The exact
+eigenvalues are $\lambda_{n,m} =(n^2+m^2), (n,m)\in {\mathbb{N}_*}^2$ with
+the associated eigenvectors are  $  u_{{m,n}}=sin(nx)*sin(my)$.
+
+
+
+We use the generalized inverse shift mode of the \texttt{arpack++} library, to find
+20 eigenvalue and eigenvector close to the shift value $\sigma=20$.
+
+\bFF
+//  Computation of the eigen value and eigen vector of the \hfilll
+//  Dirichlet problem  on square $]0,\pi[^2$ \hfilll
+// ----------------------------------------\hfilll
+// we use the inverse shift mode \hfilll
+// the shift is given with the real sigma\hfilll
+// -------------------------------------\hfilll
+//  find $\lambda$ and $u_\lambda\in H^1_0(\Omega)$ such that: \hfilll
+// \hfilll$\displaystyle  \int_{\Omega}  \nabla u_{\lambda} \nabla v = \lambda \int_{\Omega} u_{\lambda}   v , \forall v \in H^1_0(\Omega) $\hfilll
+verbosity=10;
+ at mesh Th=square(20,20,[pi*x,pi*y]);
+ at fespace Vh(Th, at P2);
+Vh u1,u2;
+
+
+ at real sigma = 20;  // value of the shift
+
+// OP = A - sigma B ;  //  the shifted matrix
+ at varf  op(u1,u2)= int2d(Th)(  dx(u1)*dx(u2) + dy(u1)*dy(u2) - sigma* u1*u2 )
+                    +  on(1,2,3,4,u1=0) ;  // Boundary condition
+
+ at varf b([u1],[u2]) = int2d(Th)(  u1*u2 ) ; // no  Boundary condition
+
+ at matrix OP= op(Vh,Vh,solver=Crout,factorize=1);  // crout solver because the matrix in not positive
+ at matrix B= b(Vh,Vh,solver=CG,eps=1e-20);
+
+// important remark:
+// the boundary condition is make with exact penalization:
+//     we put 1e30=tgv  on the diagonal term of the lock degree of freedom.
+//  So take Dirichlet boundary condition just on $a$ variational form
+// and not on  $b$ variational form.
+// because we solve $ w=OP^-1*B*v $
+
+int nev=20;  // number of computed eigen value close to sigma
+
+real[int] ev(nev); // to store the  nev eigenvalue
+Vh[int] eV(nev);   // to store the nev eigenvector \index{EigenValue}
+
+
+ at int k=@EigenValue(OP,B,sym=true,sigma=sigma,value=ev,vector=eV,
+                   tol=1e-10,maxit=0,ncv=0);
+
+//   tol= the tolerance \hfilll
+//   maxit= the maximum iteration see arpack doc.\hfilll
+//   ncv   see arpack doc. \url{http://www.caam.rice.edu/software/ARPACK/}\hfilll
+//  the return value is number of converged eigen value.\hfilll
+
+ at for (@int i=0;i<k;i++)
+{
+  u1=eV[i];
+  @real gg = int2d(Th)(dx(u1)*dx(u1) + dy(u1)*dy(u1));
+  @real mm= int2d(Th)(u1*u1) ;
+  @cout << " ---- " <<  i<< " " << ev[i]<< " err= "
+       <<int2d(Th)(dx(u1)*dx(u1) + dy(u1)*dy(u1) - (ev[i])*u1*u1) << " --- "<<endl;
+  @plot(eV[i],cmm="Eigen  Vector "+i+" valeur =" + ev[i]  ,wait=1,value=1);
+}
+
+\eFF
+
+The output of this example is:
+
+\bFF
+
+   Nb of edges on Mortars  = 0
+   Nb of edges on Boundary = 80, neb = 80
+ Nb Of Nodes = 1681
+ Nb of DF = 1681
+Real symmetric eigenvalue problem: A*x - B*x*lambda
+
+
+Thanks to ARPACK++ class ARrcSymGenEig
+Real symmetric eigenvalue problem: A*x - B*x*lambda
+Shift and invert mode  sigma=20
+
+Dimension of the system            : 1681
+Number of 'requested' eigenvalues  : 20
+Number of 'converged' eigenvalues  : 20
+Number of Arnoldi vectors generated: 41
+Number of iterations taken         : 2
+
+Eigenvalues:
+  lambda[1]: 5.0002
+  lambda[2]: 8.00074
+  lambda[3]: 10.0011
+  lambda[4]: 10.0011
+  lambda[5]: 13.002
+  lambda[6]: 13.0039
+  lambda[7]: 17.0046
+  lambda[8]: 17.0048
+  lambda[9]: 18.0083
+  lambda[10]: 20.0096
+  lambda[11]: 20.0096
+  lambda[12]: 25.014
+  lambda[13]: 25.0283
+  lambda[14]: 26.0159
+  lambda[15]: 26.0159
+  lambda[16]: 29.0258
+  lambda[17]: 29.0273
+  lambda[18]: 32.0449
+  lambda[19]: 34.049
+  lambda[20]: 34.0492
+
+ ---- 0 5.0002 err= -0.000225891 ---
+ ---- 1 8.00074 err= -0.000787446 ---
+ ---- 2 10.0011 err= -0.00134596 ---
+ ---- 3 10.0011 err= -0.00134619 ---
+ ---- 4 13.002 err= -0.00227747 ---
+ ---- 5 13.0039 err= -0.004179 ---
+ ---- 6 17.0046 err= -0.00623649 ---
+ ---- 7 17.0048 err= -0.00639952 ---
+ ---- 8 18.0083 err= -0.00862954 ---
+ ---- 9 20.0096 err= -0.0110483 ---
+ ---- 10 20.0096 err= -0.0110696 ---
+ ---- 11 25.014 err= -0.0154412 ---
+ ---- 12 25.0283 err= -0.0291014 ---
+ ---- 13 26.0159 err= -0.0218532 ---
+ ---- 14 26.0159 err= -0.0218544 ---
+ ---- 15 29.0258 err= -0.0311961 ---
+ ---- 16 29.0273 err= -0.0326472 ---
+ ---- 17 32.0449 err= -0.0457328 ---
+ ---- 18 34.049 err= -0.0530978 ---
+ ---- 19 34.0492 err= -0.0536275 ---
+\eFF
+
+\twoplot[height=8cm]{eigen11}{eigen12}{Isovalue of 11th eigenvector $u_{4,3}-u_{3,4}$}{Isovalue of 12th eigenvector $u_{4,3}+u_{3,4}$}
+\end{example}
+
+\subsection{\setS{Evolution Problems}}
+\freefempp also solve evolution problems such as the heat problem
+\begin{eqnarray}
+\label{prb:heat}
+&&\frac{\partial u}{\partial t}-\mu\Delta u=f\quad \textrm{in }\Omega\times ]0,T[,\\
+&&u(\vec x,0)=u_0(\vec x)\quad \textrm{in }\Omega; \qquad
+\left(\partial u/\partial n\right)(\vec x,t)=0\quad\textrm{on }\partial\Omega\times ]0,T[.\nonumber
+\end{eqnarray}
+with a positive viscosity coefficient $\mu$ and homogeneous Neumann boundary conditions.
+We solve (\ref{prb:heat}) by FEM in space and finite differences in time.
+We use the definition of the partial derivative of the solution in the time
+derivative,
+\[
+\frac{\partial u}{\partial t}(x,y,t) = \lim_{\tau \to 0}
+\frac{u(x,y,t)-u(x,y,t-\tau )}{\tau }
+\]
+which indicate that $u^m(x,y)=u(x,y,m\tau )$ imply
+\[
+\frac{\partial u}{\partial t}(x,y,m\tau )\simeq \frac{u^m(x,y)-u^{m-1}(x,y)}{\tau }
+\]
+The time discretization of heat equation (\ref{eqn:heat}) is as follows:
+\begin{eqnarray}
+\label{eqn:heat}
+&&\frac{u^{m+1}-u^{m}}{\tau }-\mu\Delta u^{m+1}=f^{m+1}
+\quad \textrm{in }\Omega\\
+&&u^0(\vec x)=u_0(\vec x)\quad \textrm{in }\Omega; \qquad
+\partial u^{m+1}/\partial n(\vec x)=0\quad\textrm{on }\partial\Omega,\quad
+\textrm{for all }m=0,\cdots,[T/\tau ],\nonumber
+\end{eqnarray}
+which is so-called \key{backward Euler method} for (\ref{eqn:heat}).
+Multiplying the test function $v$ both sides of the formula
+just above, we have
+\begin{equation*}
+\int_{\Omega }\{u^{m+1}v-\tau \Delta u^{m+1}v\}
+=\int_{\Omega }\{u^m+\tau  f^{m+1}\}v\, .
+\end{equation*}%
+By the divergence theorem, we have
+\begin{equation*}
+\int_{\Omega} \{u^{m+1}v+\tau \nabla u^{m+1}\cdot \nabla v\}
+-\int_{\partial\Omega} \tau \left( \partial u^{m+1}/\partial n\right) v=\int_{\Omega }\{u^mv+\tau f^{m+1}v\}.
+\end{equation*}%
+By the boundary condition $\partial u^{m+1}/\partial n=0$, it follows that
+\begin{equation}
+\label{eqn:BackEuler}
+\int_{\Omega} \{u^{m+1}v+\tau \nabla u^{m+1}\cdot \nabla v\}-
+\int_{\Omega }\{u^mv+\tau f^{m+1}v\}=0.
+\end{equation}%
+Using the identity just above, we can calculate the finite element
+approximation $u_h^m$ of $u^m$ in a step-by-step manner with respect to $t$.
+
+\begin{example}
+We now solve the following example with the exact solution $u(x,y,t)=tx^4$.
+\begin{eqnarray*}
+&&\frac{{\partial u}}{{\partial t}} - \mu \Delta u = x^4 - \mu 12tx^2 ~
+\textrm{in  } \Omega  \times ]0,3[,\, \Omega = ]0,1[^2 \\
+&&u(x,y,0) = 0\quad\textrm{on }\Omega,\qquad \left. u \right|_{\partial\Omega}  = t*x^4
+\end{eqnarray*}
+\bFF
+// heat equation  $\partial_t u = -\mu \Delta u = x^4 - \mu 12tx^2$
+ at mesh Th=@square(16,16);
+ at fespace Vh(Th,P1);
+
+Vh u,v,uu,f,g;
+ at real dt = 0.1, mu = 0.01;
+ at problem dHeat(u,v) =
+    @int2d(Th)( u*v + dt*mu*(@dx(u)*@dx(v) + @dy(u)*@dy(v)))
+    + @int2d(Th) (- uu*v - dt*f*v )
+    + @on(1,2,3,4,u=g);
+
+ at real t = 0; // start from t=0
+uu = 0;     // u(x,y,0)=0
+ at for (@int m=0;m<=3/dt;m++)
+{
+   t=t+dt;
+   f = x^4-mu*t*12*x^2;
+   g = t*x^4;
+   dHeat;
+   @plot(u,wait=true);
+   uu = u;
+   @cout <<"t="<<t<<"L^2-Error="<<@sqrt( @int2d(Th)((u-t*x^4)^2) ) << @endl;
+}
+\eFF
+In the last statement, the $L^2$-error
+$\left(\int_{\Omega}\left| u-tx^4\right|^2\right)^{1/2}$ is calculated at
+$t=m\tau , \tau =0.1$. At $t=0.1$, the error is 0.000213269.
+The errors increase with $m$ and 0.00628589 at $t=3$.
+
+The iteration of the backward Euler (\ref{eqn:BackEuler}) is made by
+\textbf{for loop} (see \refSec{Loops}).
+\end{example}
+
+\begin{note}
+The stiffness matrix in loop is used over and over again.
+\freefempp support reuses of stiffness matrix.
+\end{note}
+
+\subsubsection{Mathematical Theory on time difference}
+In this section, we show the advantage of the backward Euler.
+Let $V, H$ be separable Hilbert space and $V$ is dense in $H$.
+Let $a$ be a continuous bilinear form over $V \times V$ with coercivity and
+symmetry.
+Then $\sqrt{a(v,v)}$ become equivalent to the norm $\| v\|$ of $V$.
+
+\textbf{problem} Ev$(f,\Omega)$: For a given $f\in L^2(0,T;V'),\, u^0\in H$
+\begin{eqnarray}
+\label{eqn:Abstract}
+\frac{d}{dt}(u(t),v)+a(u(t),v)&=&( f(t),v)\qquad \forall v\in V,,\quad a.e. \, t\in [0,T]\\
+u(0)&=&u^0\nonumber
+\end{eqnarray}
+where $V'$ is the dual space of $V$.
+Then, there is an unique solution
+$u\in L^{\infty}(0,T;H)\cap L^2(0,T;V)$.
+
+Let us denote the time step by $\tau>0$, $N_T=[T/\tau]$.
+For the discretization, we put $u^n = u(n\tau)$
+and consider the time difference for each $\theta\in [0,1]$
+\begin{eqnarray}
+\label{eqn:t-method}
+\frac{1}{\tau}\left( u_h^{n+1}-u_h^n,\phi_i\right)
++a\left( u_h^{n+\theta},\phi_i\right)=\langle f^{n+\theta},\phi_i\rangle\\
+i=1,\cdots, m,\quad n=0,\cdots, N_T\nonumber\\
+u_h^{n+\theta}=\theta u_h^{n+1}+(1-\theta)u_h^n,\quad
+f^{n+\theta}=\theta f^{n+1}+(1-\theta)f^n\nonumber
+\end{eqnarray}
+Formula (\ref{eqn:t-method}) is the \emph{forward Euler scheme} if
+$\theta=0$, \emph{Crank-Nicolson scheme} if $\theta=1/2$,
+the \emph{backward Euler scheme} if $\theta=1$.
+
+Unknown vectors $u^n=(u_h^1,\cdots,u_h^M)^T$ in
+\[
+u_h^n(x)=u^n_1\phi_1(x)+\cdots+u^n_m\phi_m(x),\quad u^n_1,\cdots,u^n_m\in \R
+\]
+are obtained from solving the matrix
+\begin{eqnarray}
+\label{eqn:Evolution-1}
+(M+\theta\tau A)u^{n+1}=\{M-(1-\theta)\tau A\}u^n
++\tau\left\{\theta f^{n+1}+(1-\theta)f^n\right\}\\
+M=(m_{ij}),\quad m_{ij}=(\phi_j,\phi_i),\qquad
+A=(a_{ij}),\quad a_{ij}=a(\phi_j,\phi_i)\nonumber
+\end{eqnarray}
+Refer \cite[pp.70--75]{TA94} for solvability of (\ref{eqn:Evolution-1}).
+The stability of (\ref{eqn:Evolution-1}) is in \cite[Theorem 2.13]{TA94}:
+\begin{quotation}
+Let $\{\mathcal{T}_h\}_{h\downarrow 0}$ be regular triangulations
+(see \refSec{Regular Triangulation}).
+Then there is a number $c_0>0$ independent of $h$ such that,
+\begin{eqnarray}
+|u_h^n|^2\le
+\left\{
+\begin{array}{lr}
+\frac{1}{\delta}\left\{
+|u^0_h|^2+\tau \sum_{k=0}^{n-1}\|f^{k+\theta}\|^2_{V_h'}
+\right\}&\theta\in [0,1/2)\\
+|u^0_h|^2+\tau \sum_{k=0}^{n-1}\|f^{k+\theta}\|^2_{V_h'}&\theta\in [1/2,1]
+\end{array}
+\right.
+\end{eqnarray}
+if the following are satisfied:
+\begin{enumerate}
+  \item When $\theta\in [0,1/2)$, then we can take a time step $\tau$ in
+such a way that
+\begin{eqnarray}
+\tau <\frac{2(1-\delta)}{(1-2\theta)c_0^2}h^2
+\end{eqnarray}
+for arbitrary $\delta\in (0,1)$.
+  \item When $1/2\le \theta\le 1$, we can take $\tau$ arbitrary.
+\end{enumerate}
+\end{quotation}
+
+\begin{example}~
+\bFF
+ at mesh Th=square(12,12);
+ at fespace Vh(Th,P1);
+ at fespace Ph(Th,P0);
+
+Ph h = hTriangle; // mesh sizes for each triangle
+ at real tau = 0.1, theta=0.;
+ at func @real f(@real t) {
+   @return x^2*(x-1)^2 + t*(-2 + 12*x - 11*x^2 - 2*x^3 + x^4);
+}
+ at ofstream out("err02.csv"); // file to store calculations
+out << "mesh size = "<<h[].max<<", time step = "<<tau<<@endl;
+ at for (@int n=0;n<5/tau;n++) \\
+   out<<n*tau<<",";
+out << @endl;
+Vh u,v,oldU;
+Vh f1, f0;
+ at problem aTau(u,v) =
+  @int2d(Th)( u*v + theta*tau*(dx(u)*dx(v) + dy(u)*dy(v) + u*v))
+  - @int2d(Th)(oldU*v - (1-theta)*tau*(dx(oldU)*dx(v)+dy(oldU)*dy(v)+oldU*v))
+  - @int2d(Th)(tau*( theta*f1+(1-theta)*f0 )*v );
+
+ at while (theta <= 1.0) {
+  @real t = 0, T=3; // from t=0 to T
+  oldU = 0;     // u(x,y,0)=0
+  out <<theta<<",";
+  @for (@int n=0;n<T/tau;n++) {
+      t = t+tau;
+      f0 = f(n*tau); f1 = f((n+1)*tau);
+      aTau;
+      oldU = u;
+      @plot(u);
+      Vh uex = t*x^2*(1-x)^2; // exact sol.$=tx^2(1-x)^2$
+      Vh err = u - uex; // $err=$FE-sol - exact
+      out<< abs(err[].max)/abs(uex[].max) <<","; // $\|err \|_{L^\infty(\Omega )}/\|u_{ex} \|_{L^\infty(\Omega )}$
+  }
+  out << endl;
+  theta = theta + 0.1;
+}
+\eFF
+\begin{figure}[htbp]
+\begin{center}
+\includegraphics[height=6cm]{err02}
+\end{center}
+\caption{$\max_{x\in \Omega}|u_h^n(\theta)-u_{ex}(n\tau)|/\max_{x\in \Omega}|u_{ex}(n\tau)|$ at $n=0,1,\cdots,29$}
+\label{fig:err02}
+\end{figure}
+We can see in Fig. \ref{fig:err02} that $u_h^n(\theta)$ become unstable at $\theta=0.4$, and figures are omitted in the case $\theta<0.4$.
+\end{example}
+
+\subsubsection{Convection}
+The hyperbolic equation
+\begin{eqnarray}
+\label{eqn:conv}
+\partial_t u-\vec{\alpha} \cdot \nabla u=f;~~
+\textrm{for a vector-valued function }\vec{\alpha},~
+\partial_t=\frac{\partial}{\partial t},
+\end{eqnarray}
+appear frequently in scientific problems, for example,
+Navier-Stokes equation, Convection-Diffusion equation, etc.
+
+In the case of 1-dimensional space, we can easily find the general solution
+$(x,t)\mapsto u(x,t)=u^0(x-\alpha t)$ of the following equation, if $\alpha$ is constant,
+\begin{eqnarray}
+\label{eqn:conv0}
+\partial_t u +\alpha\partial_x u=0,\qquad u(x,0)=u^0(x),
+\end{eqnarray}
+because $\partial_t u +\alpha\partial_x u=-\alpha\dot{u}^0+a\dot{u}^0=0$,
+where $\dot{u}^0=du^0(x)/dx$.
+Even if $\alpha$ is not constant construction, the principle is similar.
+One begins the ordinary differential equation
+(with convention which $\alpha$
+is prolonged by zero apart from $(0,L)\times (0,T)$):
+\[
+\dot{X}(\tau )=-\alpha(X(\tau ),\tau ),~~~\tau \in (0,t)\quad X(t)=x
+\]%
+In this equation $\tau$ is the variable and $x,t$ is parameters,
+and we denote the solution by $X_{x,t}(\tau )$.
+Then it is noticed that $(x,t)\rightarrow v(X(\tau ),\tau )$ in
+$\tau=t$ satisfy the equation
+\[
+\partial _{t}v+\alpha\partial _{x}v=\partial _{t}X\dot{v}+a\partial _{x}X\dot{v}%
+=0
+\]%
+and by the definition $\partial _{t}X=\dot{X}=-\alpha$ and
+$\partial_{x}X=\partial _{x}x$ in $\tau=t$, because
+if $\tau =t$ we have $X(\tau )=x$.
+The general solution of (\ref{eqn:conv0}) is thus the value of the boundary condition in $X_{x, t}(0)$,
+it is has to say $u(x,t)=u^{0}(X_{x,t}(0))$ if $X_{x,t}(0)$ is on the
+$x$ axis, $u(x,t)=u^{0}(X_{x,t}(0))$ if $X_{x,t}(0)$ is on the axis of
+$t$.
+
+In higher dimension $\Omega \subset R^{d},~d=2,3$, the equation of the
+convection is written
+\[
+\partial _{t}u+\vec{\alpha}\cdot \nabla u=0\hbox{ in }\Omega \times (0,T)
+\]%
+where  $\vec{a}(x,t)\in R^{d}$.
+\freefempp implements the Characteristic-Galerkin method for convection operators. Recall that the equation (\ref{eqn:conv})
+can be discretized as
+\[
+\frac{Du}{Dt} = f\;\;\textrm{i.e. }\frac{du}{dt}\left( {X(t),t} \right) = f\left(X( t ),t \right)\textrm{  where  }\frac{dX}{dt}( t ) = \vec \alpha( {X(t),t})
+\]
+where $D$  is  the total derivative operator.
+So a good scheme is one step of backward
+convection by the method of Characteristics-Galerkin
+\begin{eqnarray}
+\label{eqn:Charac}
+\frac{1}{{\tau }}\left(u^{m + 1}(x) - u^m(X^m(x))\right) = f^m (x)
+\end{eqnarray}
+where $X^m (x)$ is an approximation of the solution at $t = m\tau $
+of the ordinary differential equation
+\[
+\frac{d\vec{X}}{dt}(t) = \vec{\alpha}^m(\vec{X}(t)),\, \vec{X}((m + 1)\tau ) = x.
+\]
+where $\vec{\alpha}^m(x)=(\alpha_1(x,m\tau ),\alpha_2(x,m\tau ))$.
+Because, by Taylor's expansion, we have
+\begin{eqnarray}
+\label{eqn:conv1}
+u^m(\vec {X}(m\tau ))&=&
+u^m(\vec{X}((m+1)\tau )) -
+\tau \sum_{i=1}^d \frac{\partial u^m}{\partial x_i}(\vec{X}((m+1)\tau ))
+\frac{\partial X_i}{\partial t}((m+1)\tau )
++o(\tau )\nonumber\\
+&=&u^m(x)-\tau \vec{\alpha}^m(x)\cdot \nabla u^m(x)+o(\tau )
+\end{eqnarray}
+where $X_i(t)$ are the i-th component of $\vec{X}(t)$,
+$u^m(x)=u(x,m\tau )$
+and we used the chain rule and $x=\vec{X}((m+1)\tau )$.
+From (\ref{eqn:conv1}), it follows that
+\begin{eqnarray}
+u^m(X^m(x))=u^m(x)-\tau \vec{\alpha}^m(x)\cdot \nabla u^m(x)+o(\tau ).
+\end{eqnarray}
+Also we apply Taylor's expansion for
+$t\mapsto u^m(x-\vec{\alpha}^m(x)t),\, 0\le t\le \tau $, then
+\[
+u^m(x-\vec{\alpha}\tau )=u^m(x)-\tau \vec{\alpha}^m(x)\cdot \nabla u^m(x)+o(\tau ).
+\]
+Putting
+\[
+\ttCC{@convect}\left( {\vec{\alpha},\tau ,u^m } \right)
+= u^m \left(x - \vec{\alpha}^m\tau  \right),
+\]
+we can get the approximation
+\[
+u^m \left( {X^m( x )} \right) \approx
+{\ttCC{@convect}}\left( {[a_1^m ,a_2^m],\tau ,u^m } \right)\;\;
+\textrm{by }x = X((m + 1)\tau ).
+\]
+
+A classical convection problem is that of the ``rotating bell''
+(quoted from \cite{Lucquin}[p.16]).
+Let $\Omega$ be the unit disk centered at 0,
+with its center rotating with speed
+$\alpha_1 = y,\, \alpha_2 = -x$
+We consider the problem (\ref{eqn:conv}) with $f=0$ and the initial condition
+$u(x,0)=u^0(x)$, that is, from (\ref{eqn:Charac})
+\begin{eqnarray*}
+u^{m + 1}(x) = u^m(X^m(x))\approx \texttt{convect}(\vec{\alpha},\tau ,u^m).
+\end{eqnarray*}
+The exact solution is $u(x, t) = u(\vec{X}(t))$
+where $\vec{X}$ equals $x$
+rotated around the origin by an angle $\theta = -t$ (rotate in clockwise).
+So, if $u^0$ in a 3D perspective
+looks like a bell, then $u$ will have exactly the same shape, but rotated by the
+same amount.
+The program consists in solving the equation until $T = 2\pi$, that is for a full
+revolution and to compare the final solution with the initial one; they should
+be equal.
+\begin{example}[convect.edp]
+\index{tutotial!convect.edp}
+\bFF
+ at border C(t=0, 2*pi) { x=cos(t);  y=sin(t); }; // the unit circle
+ at mesh Th = @buildmesh(C(70));   // triangulates the disk
+ at fespace Vh(Th,P1);
+Vh u0 = @exp(-10*((x-0.3)^2 +(y-0.3)^2));    // give $u^0$
+
+ at real dt = 0.17,t=0;       // time step
+Vh a1 = -y, a2 = x;                   // rotation velocity
+Vh u; // $u^{m+1}$
+ at for (@int m=0; m<2*pi/dt ; m++) {
+    t += dt;
+    u=@convect([a1,a2],dt,u0);  // $u^{m+1}=u^m(X^m(x))$
+    u0=u;                      // m++
+    @plot(u,cmm="convection: t="+t + ", min=" + u[].min + ", max=" +  u[].max,wait=0);
+};
+\eFF
+\end{example}
+\begin{note}
+The scheme \texttt{convect} is unconditionally stable, then
+the bell become lower and lower (the maximum of $u^{37}$ is $0.406$ as shown in Fig. \ref{BellLast}).
+\twoplot[height=5cm]{BellInit}{BellLast}{$u^0=e^{-10((x-0.3)^2 +(y-0.3)^2)}$}{The bell at $t=6.29$}
+\end{note}
+
+
+\subsubsection{Two-dimensional Black-Scholes equation}
+In mathematical finance, an option on two assets is modeled by a Black-Scholes equations in two space variables, (see for example Wilmott's book : a student introduction to mathematical finance, Cambridge University Press).
+\begin{eqnarray}
+\label{eqn:BS-1-1}
+ &&\partial _t u + \frac{{\left( {\sigma _1 x } \right)^2 }}{2}\frac{{\partial ^2 u}}{{\partial x^2 }} + \frac{{\left( {\sigma _2 y } \right)^2 }}{2}\frac{{\partial ^2 u}}{{\partial y^2 }} \\
+ &&{\rm{      }} + \rho x y \frac{{\partial ^2 u}}{{\partial x \partial y }} + rS_1 \frac{{\partial u}}{{\partial x }} + rS_2 \frac{{\partial u}}{{\partial y }} - rP = 0 \nonumber
+\end{eqnarray}
+which is to be integrated in $\left( {0,T} \right) \times \R^ +   \times \R^ +$
+subject to, in the case of a put
+\begin{eqnarray}
+\label{eqn:BS-1-2}
+u\left( {x , y ,T} \right) = \left( {K - \max \left( {x ,y } \right)} \right)^ +  .
+\end{eqnarray}
+Boundary conditions for this problem may not be so easy to device.
+As in the one dimensional case the PDE contains boundary conditions on the axis $x_1 = 0$ and on the axis $x_2 = 0$, namely two one dimensional Black-Scholes equations driven respectively by the data $u\left( {0, + \infty ,T} \right)$
+and $u\left( { + \infty ,0,T} \right)$.
+These will be automatically accounted for because they are embedded in the PDE. So if we do nothing in the variational form (i.e. if we take a Neuman boundary condition at these two axis in the strong form) there will be no disturbance to these.
+At infinity in one of the variable, as in 1D, it makes sense to match the final condition:
+\begin{eqnarray}
+\label{eqn:BS-1-3}
+u\left( {x ,y ,t} \right) \approx \left( {K - \max \left( {x ,y } \right)} \right)^ +  e^{r\left( {T - t} \right)} {\rm{    when  }}\left| {\rm{x}} \right| \to \infty
+\end{eqnarray}
+For an American put we will also have the constraint
+\begin{eqnarray}
+\label{eqn:BS-1-4}
+u\left( {x ,y ,t} \right) \ge \left( {K - \max \left( {x ,y } \right)} \right)^ +  e^{r\left( {T - t} \right)} .
+\end{eqnarray}
+We take
+\begin{eqnarray}
+\label{eqn:BS-1-5}
+\sigma _1  = 0.3,\;\;\sigma _2  = 0.3,\;\;\rho  = 0.3,\;\;r = 0.05,\;\;K = 40,\;\;T = 0.5
+\end{eqnarray}
+An implicit Euler scheme with projection is used and a mesh adaptation is done every 10 time steps. The first order terms are treated by the Characteristic Galerkin method, which, roughly, approximates
+\begin{eqnarray}
+\label{eqn:BS-1-6}
+\frac{{\partial u}}{{\partial t}} + a_1 \frac{{\partial u}}{{\partial x}} + a_2 \frac{{\partial u}}{{\partial y}} \approx \frac{1}{{\tau }}\left( {u^{n + 1} \left( x \right) - u^n \left( {x - \vec \alpha\tau } \right)} \right)
+\end{eqnarray}
+\begin{example}~
+[BlackSchol.edp]\index{tutorial!BlackSchol.edp}
+\bFF
+// verbosity=1;
+int s=10; // y-scale
+int m=30;
+int L=80;
+int LL=80;
+ at border aa(t=0,L){x=t;y=0;};
+ at border bb(t=0,LL){x=L;y=t;};
+ at border cc(t=L,0){x=t ;y=LL;};
+ at border dd(t=LL,0){x = 0; y = t;};
+
+ at mesh th = buildmesh(aa(m)+bb(m)+cc(m)+dd(m));
+ at fespace Vh(th,P1);
+
+ at real sigmax=0.3;
+ at real sigmay=0.3;
+ at real rho=0.3;
+ at real r=0.05;
+ at real K=40;
+ at real dt=0.01;
+
+ at real eps=0.3;
+
+ at func f = max(K-max(x,y),0.);
+
+Vh u=f,v,w;
+
+ at func beta = 1;//(w<=f-eps)*eps + (w>=f) + (w<f)*(w>f-eps)*(eps+(w-f+eps)/eps)*(1-eps);
+
+ at plot(u,wait=1);
+
+ th = adaptmesh(th,u,abserror=1,nbjacoby=2,
+        err=0.004, nbvx=5000, omega=1.8,ratio=1.8, nbsmooth=3,
+            splitpbedge=1, maxsubdiv=5,rescaling=1 );
+ u=u;
+
+Vh xveloc = -x*r+x*sigmax^2+x*rho*sigmax*sigmay/2;
+Vh yveloc = -y*r+y*sigmay^2+y*rho*sigmax*sigmay/2;
+
+ at int j=0;
+ at int n;
+ at problem eq1(u,v,init=j, at solver=LU) = @int2d(th)(
+                          u*v*(r+1/dt/beta)
+                        + @dx(u)*@dx(v)*(x*sigmax)^2/2.
+                        + @dy(u)*@dy(v)*(y*sigmay)^2/2.
+      + @dy(u)*@dx(v)*rho*sigmax*sigmay*x*y/2.
+                  + @dx(u)*@dy(v)*rho*sigmax*sigmay*x*y/2.   )
+            + @int2d(th)( -v*convect([xveloc,yveloc],dt,w)/dt/beta)
+                  + @on(bb,cc,u=f)//*exp(-r*t);
+;
+int ww=1;
+ at for ( n=0; n*dt <= 1.0; n++)
+{
+  @cout <<" iteration " << n   <<  " j=" << j << @endl;
+  w=u;
+  eq1;
+  v = @max(u-f,0.);
+  plot(v,wait=ww);
+  u = @max(u,f);
+  ww=0;
+
+  @if(j>10)  { cout << " adaptmesh " << endl;
+    th = adaptmesh(th,u,verbosity=1,abserror=1,nbjacoby=2,
+      err=0.001, nbvx=5000, omega=1.8, ratio=1.8, nbsmooth=3,
+            splitpbedge=1, maxsubdiv=5,rescaling=1) ;
+        j=-1;
+     xveloc = -x*r+x*sigmax^2+x*rho*sigmax*sigmay/2;
+     yveloc = -y*r+y*sigmay^2+y*rho*sigmax*sigmay/2;
+     u=u;
+     ww=1;
+    };
+  j=j+1;
+  @cout << " j = " <<  j << endl;
+};
+v = @max(u-f,0.);
+ at plot(v,wait=1,value=1);
+ at plot(u,wait=1,value=1);
+\eFF
+\end{example}
+
+\subsection{Navier-Stokes Equation}
+
+\subsubsection{Stokes and Navier-Stokes}
+
+The Stokes equations are: for a given $\vec{f}\in L^2(\Omega)^2$,
+\index{stokes}
+\Blue{
+\begin{equation} \label{eqn:Stokes}
+    \left.\begin{array}{cl}
+ -\Delta \vec{u}+\nabla p & =\vec{f} \\
+ \nabla\cdot \vec{u} &=0
+ \end{array}\right\}\quad \hbox{ in }\Omega
+\end{equation}}
+where $\vec{u}=(u_1,u_2)$ is the velocity vector and $p$ the pressure.
+For simplicity, let us choose Dirichlet boundary conditions
+on the velocity,  $\vec{u}=\vec{u}_{\Gamma}$ on $\Gamma$.
+
+In Temam [Theorem 2.2], there ia a weak form of (\ref{eqn:Stokes}):
+Find $\vec{v}=(v_1,v_2)\in \vec{V}(\Omega)$
+\[
+\vec{V}(\Omega)=\{\vec{w}\in H^1_0(\Omega)^2|\; \textrm{div}\vec{w}=0\}
+\]
+which satisfy
+\[
+\sum_{i=1}^2\int_{\Omega}\nabla u_i\cdot \nabla v_i=\int_{\Omega}\vec{f}\cdot \vec{w}
+\quad \textrm{for all }v\in V
+\]
+Here it is used the existence
+$p\in H^1(\Omega)$ such that $\vec{u}=\nabla p$, if
+\[
+\int_{\Omega}\vec{u}\cdot \vec{v}=0\quad \textrm{for all }\vec{v}\in
+V
+\]
+\medskip
+
+Another weak form is derived as follows: We put
+\begin{eqnarray*}
+\vec{V}=H^1_0(\Omega)^2;\quad
+W=\left\{q\in L^2(\Omega)\left|\; \int_{\Omega}q=0\right.\right\}
+\end{eqnarray*}
+By multiplying the first equation in (\ref{eqn:Stokes}) with $v\in V$ and the
+second with $q\in W$, subsequent integration over $\Omega$, and an
+application of Green's formula, we have
+\begin{eqnarray*}
+\int_{\Omega}\nabla\vec{u}\cdot \nabla\vec{v}-\int_{\Omega}\textrm{div}\vec{v}\, p
+&=&\int_{\Omega}\vec{f}\cdot\vec{v}\\
+\int_{\Omega}\textrm{div}\vec{u}\, q&=&0
+\end{eqnarray*}
+This yields the weak form of (\ref{eqn:Stokes}):
+Find $(\vec{u},p)\in \vec{V}\times W$ such that
+\begin{eqnarray}
+\label{eqn:wStokes-1}
+a(\vec{u},\vec{v})+b(\vec{v},p)&=&(\vec{f},\vec{v})\\
+\label{eqn:wStokes-2}
+b(\vec{u},q)&=&0
+\end{eqnarray}
+for all $(\vec{v},q)\in V\times W$, where
+\begin{eqnarray}
+\label{eqn:Stokes-a}
+a(\vec{u},\vec{v})&=&\int_{\Omega}\nabla \vec{u}\cdot \nabla\vec{v}
+=\sum_{i=1}^2\int_{\Omega}\nabla u_i\cdot \nabla v_i\\
+\label{eqn:Stokes-b}
+b(\vec{u},q)&=&-\int_{\Omega}\textrm{div}\vec{u}\, q
+\end{eqnarray}
+
+Now, we consider finite element spaces $\vec{V}_h\subset \vec{V}$ and $W_h\subset W$,
+and we assume the following basis functions
+\begin{eqnarray*}
+&&\vec{V}_h=V_h\times V_h,\quad
+V_h=\{v_h|\; v_h=v_1\phi_1+\cdots +v_{M_V}\phi_{M_V}\},\\
+&&W_h=\{q_h|\; q_h=q_1\varphi_1+\cdots +q_{M_W}\varphi_{M_W}\}
+\end{eqnarray*}
+The discrete weak form is:
+Find $(\vec{u}_{h},p_{h}) \in \vec{V}_{h} \times W_{h}$ such that
+\Blue{
+\begin{equation} \label{eqn:vfStokes}
+    \begin{array}{cll}
+   a(\vec{u}_h,\vec{v}_h)+b(\vec{v}_h,p)  &= (\vec{f},\vec{v}_h) ,
+      &\forall \vec{v}_{h} \in \vec{V}_{h} \\
+    b(\vec{u}_h,q_h)&= 0,
+     &\forall q_{h} \in W_{h}
+    \end{array}
+\end{equation}}
+\begin{note}
+Assume that:
+\begin{enumerate}
+  \item There is a constant $\alpha_h>0$ such that
+  \[
+  a(\vec{v}_h,\vec{v}_h)\ge \alpha\| \vec{v}_h\|_{1,\Omega}^2\quad \textrm{for all }\vec{v}_h\in Z_h
+  \]
+  where
+  \[
+  Z_h=\{\vec{v}_h\in \vec{V}_h|\; b(\vec{w}_h,q_h)=0\quad \textrm{for all }q_h\in W_h\}
+  \]
+  \item There is a constant $\beta_h>0$ such that
+  \[
+  \sup_{\vec{v}_h\in \vec{V}_h}\frac{b(\vec{v}_h,q_h)}{\| \vec{v}_h\|_{1,\Omega}}
+  \ge \beta_h\| q_h\|_{0,\Omega}\quad \textrm{for all }q_h\in W_h
+  \]
+\end{enumerate}
+  Then we have an unique solution $(\vec{u}_h,p_h)$ of (\ref{eqn:vfStokes})
+  satisfying
+  \[
+  \| \vec{u}-\vec{u}_h\|_{1,\Omega}+\| p-p_h\|_{0,\Omega}
+  \le C\left(
+  \inf_{\vec{v}_h\in \vec{V}_h}\| u-v_h\|_{1,\Omega}
+  +\inf_{q_h\in W_h}\| p-q_h\|_{0,\Omega}\right)
+  \]
+  with a constant $C>0$ (see e.g. \cite[Theorem 10.4]{RT93}).
+\end{note}
+Let us denote that
+\begin{eqnarray}
+A&=&(A_{ij}),\, A_{ij}=\int_{\Omega}\nabla \phi_j\cdot \nabla \phi_i\qquad
+i,j=1,\cdots,M_{\vec{V}}\\
+\vec{B}&=&(Bx_{ij},By_{ij}),\,
+Bx_{ij}=-\int_{\Omega}\partial \phi_j/\partial x\, \varphi_i\qquad
+By_{ij}=-\int_{\Omega}\partial \phi_j/\partial y\, \varphi_i\nonumber\\
+&&\qquad i=1,\cdots,M_W;j=1,\cdots,M_V\nonumber
+\end{eqnarray}
+then (\ref{eqn:vfStokes}) is written by
+\begin{eqnarray}
+\left(
+\begin{array}{cc}
+\vec{A}&\vec{\vec{B}}^*\\
+\vec{B}&0
+\end{array}
+\right)
+\left(
+\begin{array}{cc}
+\vec{U}_h\\
+\{p_h\}
+\end{array}
+\right)
+=
+\left(
+\begin{array}{cc}
+\vec{F}_h\\
+0
+\end{array}
+\right)
+\end{eqnarray}
+where
+\begin{eqnarray*}
+&&\vec{A}=\left(
+\begin{array}{cc}
+A&0\\
+0&A
+\end{array}
+\right)
+\qquad
+\vec{B}^*=\left\{
+\begin{array}{c}
+Bx^T\\
+By^T
+\end{array}
+\right\}
+\qquad
+\vec{U}_h=\left\{
+\begin{array}{c}
+\{u_{1,h}\}\\
+\{u_{2,h}\}
+\end{array}
+\right\}
+\qquad
+\vec{F}_h=\left\{
+\begin{array}{c}
+\{\textstyle{\int_{\Omega}f_1\phi_i}\}\\
+\{\textstyle{\int_{\Omega}f_2\phi_i}\}
+\end{array}
+\right\}
+\end{eqnarray*}
+
+\textbf{Penalty method:} This method consists of replacing (\ref{eqn:vfStokes}) by a more regular problem: Find
+$(\vec{v}_h^{\epsilon},p_h^{\epsilon})\in \vec{V}_h\times \tilde{W}_{h}$ satisfying
+\Blue{
+\begin{equation} \label{eqn:PvfStokes}
+    \begin{array}{cll}
+   a(\vec{u}_h^\epsilon,\vec{v}_h)+b(\vec{v}_h,p_h^{\epsilon})  &= (\vec{f},\vec{v}_h) ,
+      &\forall \vec{v}_{h} \in \vec{V}_{h} \\
+    b(\vec{u}_h^{\epsilon},q_h)-\epsilon(p_h^{\epsilon},q_h)&= 0,
+     &\forall q_{h} \in \tilde{W}_{h}
+    \end{array}
+\end{equation}}
+where $\tilde{W}_h\subset L^2(\Omega)$. Formally, we have
+\[
+\textrm{div}\vec{u}_h^{\epsilon}=\epsilon p_h^{\epsilon}
+\]
+and the corresponding algebraic problem
+\begin{eqnarray*}
+\left(
+\begin{array}{cc}
+\vec{A}&B^*\\
+B&-\epsilon I
+\end{array}
+\right)
+\left(
+\begin{array}{cc}
+\vec{U}_h^{\epsilon}\\
+\{p_h^{\epsilon}\}
+\end{array}
+\right)
+=
+\left(
+\begin{array}{cc}
+\vec{F}_h\\
+0
+\end{array}
+\right)
+\end{eqnarray*}
+\begin{note}
+We can eliminate $p_h^\epsilon=(1/\epsilon)BU_h^{\epsilon}$ to obtain
+\begin{eqnarray}
+\label{eqn:StiffPvfStokes}
+(A+(1/\epsilon)B^*B)\vec{U}_h^{\epsilon}=\vec{F}_h^{\epsilon}
+\end{eqnarray}
+Since the matrix $A+(1/\epsilon)B^*B$ is symmetric, positive-definite, and sparse, (\ref{eqn:StiffPvfStokes}) can be solved by known technique.
+There is a constant $C>0$ independent of $\epsilon$ such that
+\[
+\|\vec{u}_h-\vec{u}_h^\epsilon\|_{1,\Omega}+
+\|p_h-p_h^{\epsilon}\|_{0,\Omega}\le C\epsilon
+\]
+(see e.g. \cite[17.2]{RT93})
+\end{note}
+
+\begin{example}[Cavity.edp]
+
+The driven cavity flow problem is solved first at zero Reynolds number
+(Stokes flow) and then at Reynolds 100.  \index{fluid}The
+velocity pressure formulation is used first and then the calculation
+is repeated with the stream function vorticity formulation.
+
+We solve the driven cavity problem by the penalty method (\ref{eqn:PvfStokes}) \index{Stokes} where
+ $\vec{u}_{\Gamma}\cdot \vec{n}=0$ and $\vec{u}_{\Gamma}\cdot \vec{s}
+=1$ on the top boundary and zero elsewhere ( $\vec{n}$ is the unit normal to $\Gamma$, and $\vec{s}$ the unit tangent to $\Gamma$).
+\\
+The mesh is constructed by
+\bFF
+ at mesh Th=@square(8,8);
+\eFF
+
+We use a classical Taylor-Hood element technic to solve the problem:
+\\\\
+The velocity is approximated with the $P_{2}$ FE ( $X_{h}$ space), and the
+the pressure is approximated with the $P_{1}$ FE ( $M_{h}$ space),
+\\\\
+where
+\Blue{
+$$  X_{h} = \left\{ \vec{v} \in H^{1}(]0,1[^2) \left|\; \forall K \in \mathcal{T}_{h}
+\quad v_{|K} \in
+P_{2} \right.\right\}$$} and
+\Blue{$$  M_{h} = \left\{ v \in H^{1}(]0,1[^2) \left|\; \forall K \in \mathcal{T}_{h}
+\quad v_{|K} \in
+P_{1} \right.\right\}$$}
+
+The FE spaces and functions  are constructed by
+
+\bFF
+ at fespace Xh(Th, at P2); //  definition of the velocity component space
+ at fespace Mh(Th, at P1);  //  definition of the pressure space
+Xh u2,v2;
+Xh u1,v1;
+Xh p,q;
+\eFF
+
+The Stokes operator is implemented as a system-solve for the velocity
+$(u1,u2)$ and the pressure $p$.  The test function  for the velocity is $(v1,v2)$
+and $q$ for the pressure, so the variational form (\ref{eqn:vfStokes}) in freefem
+language is:
+\bFF
+ at solve Stokes (u1,u2,p,v1,v2,q,solver=Crout) =
+    @int2d(Th)( ( dx(u1)*dx(v1) + dy(u1)*dy(v1)
+            +  dx(u2)*dx(v2) + dy(u2)*dy(v2) )
+            - p*q*(0.000001)
+            - p*dx(v1) - p*dy(v2)
+            - dx(u1)*q - dy(u2)*q
+           )
+  + @on(3,u1=1,u2=0)
+  + @on(1,2,4,u1=0,u2=0); // see \refSec{Square} for labels 1,2,3,4
+\eFF
+Each unknown has its own boundary conditions.
+\\\\
+
+If the \index{streamlines}streamlines are required, they can be
+computed by finding $\psi$ such that rot$\psi=u$ or better,
+\Blue{$$-\Delta\psi=\nabla\times u$$}
+\bFF
+Xh psi,phi;
+
+ at solve streamlines(psi,phi) =
+      @int2d(Th)( dx(psi)*dx(phi) + dy(psi)*dy(phi))
+   +  @int2d(Th)( -phi*(dy(u1)-dx(u2)))
+   +  @on(1,2,3,4,psi=0);
+\eFF
+
+\bigskip
+
+Now the Navier-Stokes equations are solved
+\eq{
+    {\partial {u}\over\partial t} +u\cdot\nabla u-\nu \Delta u+\nabla p=0,~~~ \nabla\cdot u=0
+}
+with the same boundary conditions and with initial conditions $u=0$.
+
+This is implemented by using the convection operator \texttt{convect} for the term
+${\partial u\over\partial t} +u\cdot\nabla u$, giving a discretization in time
+\Blue{\index{Navier-Stokes}
+\begin{equation}
+    \label{eq Navier Stokes carac}
+\begin{array}{cl}
+\frac{1}{\tau } (u^{n+1}-u^n\circ X^n) -\nu\Delta u^{n+1} + \nabla p^{n+1} &=0,\\
+ \nabla\cdot u^{n+1} &= 0
+ \end{array}
+\end{equation}
+}
+The term $u^n\circ X^n(x)\approx u^n(x-u^n(x)\tau )$ will be
+computed by the operator ``convect" \index{convect} , so we obtain
+\bFF
+int i=0;
+ at real  nu=1./100.;
+ at real dt=0.1;
+ at real alpha=1/dt;
+
+Xh up1,up2;
+
+ at problem  NS (u1,u2,p,v1,v2,q,solver=Crout,init=i) =
+    @int2d(Th)(
+             alpha*( u1*v1 + u2*v2)
+            + nu * ( dx(u1)*dx(v1) + dy(u1)*dy(v1)
+            +  dx(u2)*dx(v2) + dy(u2)*dy(v2) )
+            - p*q*(0.000001)
+            - p*dx(v1) - p*dy(v2)
+            - dx(u1)*q - dy(u2)*q
+           )
+  + @int2d(Th) ( -alpha*
+       convect([up1,up2],-dt,up1)*v1 -alpha*convect([up1,up2],-dt,up2)*v2 )
+  + @on(3,u1=1,u2=0)
+  + @on(1,2,4,u1=0,u2=0)
+;
+
+ at for (i=0;i<=10;i++)
+ {
+   up1=u1;
+   up2=u2;
+   NS;
+   @if ( !(i % 10))  // plot every 10 iteration
+    @plot(coef=0.2,cmm=" [u1,u2] and p  ",p,[u1,u2]);
+ } ;
+\eFF
+Notice that the stiffness matrices are \index{Reusable matrices}
+reused (keyword
+\texttt{init=i})
+\end{example}
+
+\subsubsection{\setS{Uzawa} Conjugate Gradient}
+We solve Stokes problem without penalty.
+The classical iterative method of Uzawa is described by the algorithm
+(see e.g.\cite[17.3]{RT93}):
+\begin{description}
+  \item[Initialize:] Let $p_h^0$ be an arbitrary chosen element of
+  $L^2(\Omega)$.
+  \item[Calculate $\vec{u}_h$:] Once $p_h^n$ is known, $\vec{v}_h^n$ is the solution of
+  \[
+  \vec{u}_h^n = A^{-1}(\vec{f}_h-\vec{B}^*p_h^n)
+  \]
+  \item[Advance $p_h$:] Let $p_h^{n+1}$ be defined by
+  \[
+  p_h^{n+1}=p_h^n+\rho_n\vec{B}\vec{u}_h^n
+  \]
+\end{description}
+There is a constant $\alpha>0$ such that $\alpha\le \rho_n\le 2$ for each $n$,
+then $\vec{u}_h^n$ converges to the solution $\vec{u}_h$, and then
+$B\vec{v}_h^n\to 0$ as $n\to \infty$ from the \emph{Advance $p_h$}.
+This method in general converges quite slowly.
+
+First we define mesh, and the Taylor-Hood \index{Taylor-Hood}  approximation.
+So $X_{h}$  is the velocity space, and $M_{h}$ is the pressure space.
+\begin{example}[StokesUzawa.edp]~
+\index{tutorial!StokesUzawa.edp}
+\bFF
+ at mesh Th=@square(10,10);
+ at fespace Xh(Th, at P2),Mh(Th, at P1);
+Xh u1,u2,v1,v2;
+Mh p,q,ppp;  //  ppp is a working pressure
+\eFF
+
+\bFF
+ at varf bx(u1,q) = @int2d(Th)( -(dx(u1)*q));
+ at varf by(u1,q) = @int2d(Th)( -(dy(u1)*q));
+ at varf a(u1,u2)= @int2d(Th)(  dx(u1)*dx(u2) + dy(u1)*dy(u2) )
+                    +  on(3,u1=1)  +  @on(1,2,4,u1=0) ;
+//  remark:  put the \ttCC{@on(3,u1=1)} before  \ttCC{@on(1,2,4,u1=0)}
+//  because we want zero on intersection %\index{on!intersection}
+
+ at matrix A= a(Xh,Xh,solver=CG);
+ at matrix Bx= bx(Xh,Mh);  // $\vec{B}=(Bx\quad By)$
+ at matrix By= by(Xh,Mh);
+
+Xh bc1; bc1[] = a(0,Xh);  //  boundary condition contribution  on u1
+Xh bc2; bc2   = O ;       //  no boundary condition contribution on u2
+Xh b;
+\eFF
+
+$p_h^n\to \vec{B}A^{-1}(-\vec{B}^*p_h^n)=-\textrm{div}\vec{u}_h$
+is realized as
+the function \emph{\texttt{divup}}.
+\bFF
+ at func @real[@int] divup(@real[@int] @& pp)
+{
+   //  compute u1(pp)
+   b[]  = Bx'*pp; b[] *=-1; b[] += bc1[] ;    u1[] = A^-1*b[];
+   //  compute u2(pp)
+   b[]  = By'*pp; b[] *=-1; b[] += bc2[] ;    u2[] = A^-1*b[];
+   //  $\vec{u}^n=A^{-1}(Bx^Tp^n\quad By^Tp^n)^T$ \hfilll
+   ppp[] =   Bx*u1[];   // $  ppp= Bx u_{1} $
+   ppp[] +=  By*u2[];   // $   \quad   +  By u_{2} $
+   @return ppp[] ;
+};
+\eFF
+
+ Call now the conjugate gradient algorithm:
+
+\bFF
+p=0;q=0; // $p_h^0 = 0$
+ at LinearCG(divup,p[],eps=1.e-6,nbiter=50); // $p_h^{n+1}=p_h^n+\vec{B}\vec{u}_h^n$
+// if $n> 50$ or $|p_h^{n+1}-p_h^n|\le 10^{-6}$, then the loop end. \hfilll
+divup(p[]); // compute the final solution
+
+ at plot([u1,u2],p,wait=1,value=true,coef=0.1);
+\eFF
+\end{example}
+
+\subsubsection{NSUzawaCahouetChabart.edp}
+
+ In this example we solve the Navier-Stokes \index{Navier-Stokes} equation,
+ in the driven-cavity,
+ with the Uzawa  algorithm preconditioned by the Cahouet-Chabart method.
+
+ The idea of the preconditioner is that in a periodic domain, all
+ differential operators commute and  the  Uzawa algorithm comes to solving the
+ linear operator  $ \nabla. ( (\alpha Id + \nu \Delta)^{-1} \nabla$,
+ where $ Id $ is the identity operator.
+ So  the preconditioer suggested is $ \alpha \Delta^{-1} + \nu Id$.
+\\\\
+To implement this, we reuse the previous example, by including \index{include} a file.
+Then we define the time step $ \Delta t$, viscosity, and new variational form and matrix.
+
+\begin{example}[NSUzawaCahouetChabart.edp]~
+\index{tutorial!NSUzawaCahouetChabart.edp}
+\bFF
+ at include "StokesUzawa.edp" // include the Stokes part
+ at real dt=0.05, alpha=1/dt;  // $ \Delta t$
+
+ at cout << " alpha = " << alpha;
+ at real xnu=1./400; // viscosity $ \nu = {\hbox{Reynolds number}}^{-1} $
+
+//  the new variational form with mass term \index{varf}
+ at varf at(u1,u2)= @int2d(Th)( xnu*dx(u1)*dx(u2)
+                        + xnu*dy(u1)*dy(u2) + u1*u2*alpha  )
+                        +  @on(1,2,4,u1=0)  + @on(3,u1=1) ;
+
+A = at(Xh,Xh,solver=CG);  //  change the matrix \index{matrix!=}\index{matrix!solver=}
+
+//  set the 2 convect variational form \index{qforder=} \index{convect}
+ at varf  vfconv1(uu,vv)  = @int2d(Th,qforder=5) (@convect([u1,u2],-dt,u1)*vv*alpha);
+ at varf  vfconv2(v2,v1)  = @int2d(Th,qforder=5) (@convect([u1,u2],-dt,u2)*v1*alpha);
+
+ at int idt;       // index of of time set
+ at real temps=0;  // current time
+
+Mh pprec,prhs;
+ at varf vfMass(p,q) = int2d(Th)(p*q);
+ at matrix MassMh=vfMass(Mh,Mh,solver=CG);
+
+ at varf vfLap(p,q)  = int2d(Th)(dx(pprec)*dx(q)+dy(pprec)*dy(q) + pprec*q*1e-10);
+ at matrix LapMh= vfLap(Mh,Mh,solver=Cholesky);
+\eFF
+
+ The function to define the preconditioner
+
+\bFF
+ at func real[int]  CahouetChabart(real[int] & xx)
+{  //  xx = $ \int (div u) w_i$
+   //   $ \alpha LapMh ^{-1}  + \nu MassMh^{-1} $
+   pprec[]= LapMh^-1* xx;
+   prhs[] =  MassMh^-1*xx;
+   pprec[] = alpha*pprec[]+xnu* prhs[];
+   @return pprec[];
+};
+\eFF
+
+The loop in time.
+Warning with the stop test of the conjugate gradient, because
+we start from the previous solution and the end the previous solution
+is close to the final solution, don't take a relative  stop test to
+the first residual, take an absolute stop test ( negative here)
+\index{stop test!absolue}
+\bFF
+for (idt = 1; idt < 50; idt++)
+ {
+   temps += dt;
+   cout << " --------- temps " << temps << " \n ";
+   b1[] =  vfconv1(0,Xh);
+   b2[] =  vfconv2(0,Xh);
+   cout << "  min b1 b2  " << b1[].min << " " << b2[].min << endl;
+   cout << "  max b1 b2  " << b1[].max << " " << b2[].max << endl;
+   // call Conjugate Gradient with preconditioner '
+   //  warning eps < 0 => absolue stop test \index{precon=}
+   LinearCG(divup,p[],eps=-1.e-6,nbiter=50,precon=CahouetChabart);
+   divup(p[]);   //  computed the velocity
+
+   plot([u1,u2],p,wait=!(idt%10),value= 1,coef=0.1);
+ }
+\eFF
+\end{example}
+\subsection{Variational  inequality}
+We present, a classical examples of variational inequality.
+
+Let us denote  $\mathcal{C} = \{ u\in H^1_0(\Omega), u \le g \}$
+
+The problem is :
+
+$$
+ u = arg \min_{u\in \mathcal{C}}  J(u) = \frac{1}{2} \int_\Omega \nabla u . \nabla u - \int_\Omega f u
+$$
+where $f$ and $g$ are given function.
+
+The solution is a projection on the convex $\mathcal{C}$ of $f^\star$
+for the scalar product $((v,w)) = \int_\Omega \nabla v . \nabla w$ of
+$  H^1_0(\Omega)$
+where $ {f^\star} $ is solution of $ ((f^\star, v )) = \int_\Omega f v, \forall v \in  H^1_0(\Omega)$.
+The projection on a convex satisfy clearly
+$\forall v \in \mathcal{C}, \quad   (( u -v ,  u - \tilde{f}  )) \leq 0   $,
+and after expanding, we get the classical inequality
+$$\forall v \in \mathcal{C}, \quad   \int_\Omega \nabla(u -v) \nabla  u  \leq  \int_\Omega   (u-v) f .   $$
+
+We can also rewrite the problem as a saddle point problem
+
+Find $\lambda, u$ such that:
+$$
+  \max_{\lambda\in L^2(\Omega), \lambda\geq 0}  \min_{u\in H^1_0(\Omega)}  \mathcal{L}(u,\lambda) = \frac{1}{2} \int_\Omega \nabla u . \nabla u - \int_\Omega f u  + \int_{\Omega} \lambda (u-g)^+
+$$
+where $((u-g)^+ = max(0,u-g) $
+
+This saddle point problem is equivalent to find $ u, \lambda $ such that:
+\begin{equation}
+ \left\{
+\begin{array}{cc}
+\displaystyle \int_\Omega \nabla u . \nabla v + \lambda v^+ \,d\omega= \int_\Omega f u  , &\forall v \in H^1_0(\Omega) \cr
+\displaystyle \int_\Omega   \mu (u-g)^+ = 0  , & \forall \mu \in L^2(\Omega) , \mu \geq 0, \lambda \geq 0,
+ \end{array}\right.\label{eq:iq1}
+\end{equation}
+
+
+A algorithm to solve the previous problem is:
+
+\begin{enumerate}
+\item k=0, and choose, $\lambda_0$ belong $ H^{-1}(\Omega)$
+\item loop on $ k = 0, .....$
+ \begin{enumerate}
+\item  set $ \mathcal{I}_{k} = \{ x \in \Omega / \lambda_{k} + c * ( u_{k+1} - g)  \leq 0 \} $
+\item  $ V_{g,k+1} = \{ v\in H^1_0(\Omega) / v = g $   on ${I}_{k} \}$,
+\item  $ V_{0,k+1} = \{ v\in  H^1_0(\Omega) / v = 0$ on ${I}_{k} \}$,
+ \item Find  $ u_{k+1} \in V_{g,k+1} $ and  $\lambda_{k+1} \in H^{-1}(\Omega)$ such that
+ $$
+ \left\{\begin{array}{cc}
+ \displaystyle  \int_\Omega \nabla u_{k+1}. \nabla v_{k+1}   \,d\omega = \int_\Omega f v_{k+1}  , &\forall v_{k+1} \in  V_{0,k+1} \cr
+ \displaystyle  <\lambda_{k+1},v>  =  \int_\Omega \nabla u_{k+1}. \nabla v  -  f v \,d\omega &
+  \end{array}\right.
+ $$
+ where $<,>$ is the duality bracket between $ H^{1}_0(\Omega)$ and  $ H^{-1}(\Omega)$, and $c$
+is  a penalty constant (large enough).
+\end{enumerate}
+
+\end{enumerate}
+You can find all the mathematic  about this algorithm in \cite{ItoKunisch}.
+
+Now how to do that in \texttt{FreeFem++}
+
+The full example is:
+\begin{example}[VI.edp]
+\index{tutotial!VI.edp}
+\bFF
+
+ at mesh Th=square(20,20);
+ at real eps=1e-5;
+ at fespace Vh(Th,P1);     // P1 FE space
+ at int n = Vh.ndof; // number of Degree of freedom
+ at Vh uh,uhp;              // solution and previous one
+ at Vh Ik; //  to def the set where the containt is reached.
+ at real[int] rhs(n); // to store the right and side of the equation
+ at real c=1000;  // the penalty  parameter of the algoritm
+ at func f=1;         //  right hand side function
+ at func fd=0;         // Dirichlet   boundary condition function
+Vh g=0.05;  // the discret function g
+
+ at real[int] Aii(n),Aiin(n); // to store the diagonal of the matrix 2 version
+
+ at real tgv = 1e30; // a huge value for exact penalization
+// of boundary condition
+//  the variatonal form of the problem: \hfilll
+ at varf a(uh,vh) =                    //  definition of  the problem
+    int2d(Th)( dx(uh)*dx(vh) + dy(uh)*dy(vh) ) //  bilinear form
+  - int2d(Th)( f*vh )                          //  linear form
+  + on(1,2,3,4,uh=fd) ;                      //  boundary condition form
+
+
+// two version of the matrix of the problem  \hfilll
+ at matrix A=a(Vh,Vh,tgv=tgv,solver=CG); // one changing
+ at matrix AA=a(Vh,Vh,solver:GC); // one for computing residual
+
+ //  the mass Matrix construction: \hfilll
+ at varf vM(uh,vh) = int2d(Th)(uh*vh);
+ at matrix M=vM(Vh,Vh); // to do a fast computing of $L^2$ norm : sqrt( u'*(w=M*u))
+
+Aii=A.diag; // get the diagonal of the matrix (appear in version 1.46-1)
+
+rhs = a(0,Vh,tgv=tgv);
+Ik =0;
+uhp=-tgv; // previous value is
+Vh lambda=0;
+ at for(int iter=0;iter<100;++iter)
+{
+  @real[int] b(n) ; b=rhs;  //  get a copy of the Right hand side
+  @real[int] Ak(n); //  the complementary of Ik ( !Ik = (Ik-1))
+  // Today  the operator Ik- 1. is not implement so we do:
+  Ak= 1.; Ak  -= Ik[];  // build Ak  = ! Ik
+  //  adding new locking  condition on b and on the diagonal if (Ik ==1 )
+  b = Ik[] .* g[];      b *= tgv;     b  -=  Ak .* rhs;
+  Aiin = Ik[] *  tgv;      Aiin  +=  Ak  .* Aii;  //set  Aii= tgv  $ i \in Ik $
+  A.diag = Aiin; //  set the matrix diagonal  (appear in version 1.46-1)
+  @set(A,solver=CG); // important to change preconditioning  for solving
+  uh[] = A^-1* b;   //  solve the problem with more locking condition
+  lambda[] = AA * uh[]; //  compute the residual ( fast with matrix)
+  lambda[] += rhs; // remark rhs = $-\int f v $
+
+  Ik = ( lambda + c*( g- uh)) < 0.;  // the new of locking value
+
+   @plot(Ik, wait=1,cmm=" lock set ",value=1,ps="VI-lock.eps",fill=1 );
+   @plot(uh,wait=1,cmm="uh",ps="VI-uh.eps");
+   // trick to compute  $L^2$ norm of the variation (fast method)
+      real[int] diff(n),Mdiff(n);
+      diff= uh[]-uhp[];
+      Mdiff = M*diff;
+      real err = sqrt(Mdiff'*diff);
+  @cout << "  || u_{k=1} - u_{k} ||_2 " << err << endl;
+  @if(err< eps) @break; // stop test
+  uhp[]=uh[] ; // set the previous solution
+}
+savemesh(Th,"mm",[x,y,uh*10]); // for medit plotting
+\eFF
+\end{example}
+
+Remark, as you can see on this example, some vector , or matrix operator are not implemented
+so a way is to skip the expression and we  use operator \texttt{+=},  \texttt{-=} to merge
+the result.
+
+
+\subsection{Domain decomposition}
+We present, three classic examples, of domain decomposition
+technique:
+first, Schwarz algorithm with overlapping, second
+Schwarz algorithm without  overlapping (also call Shur complement), and
+last we show to use the conjugate gradient
+to solve the boundary problem of the Shur complement.
+
+\subsubsection{Schwarz Overlap Scheme}
+\label{schwarz-overlap}
+To solve
+\eq{ -\Delta u =f,\; \hin\Omega=\Omega_1\cup\Omega_2\quad u|_\Gamma=0}
+the Schwarz algorithm  runs like this
+\Blue{
+\begin{eqnarray*}
+   -\Delta u^{n+1}_1&=&f\hin\Omega_1\quad
+    u^{n+1}_1|_{\Gamma_1}=u^n_2\\
+    -\Delta u^{n+1}_2&=&f\hin\Omega_2\quad
+    u^{n+1}_2|_{\Gamma_2}=u^n_1
+\end{eqnarray*}}
+where $\Gamma_i$ is the boundary of $\Omega_i$ and on the
+condition that $\Omega_1\cap\Omega_2\neq\emptyset$ and that $u_i$
+are zero at iteration 1.
+\\\\
+Here we take $\Omega_1$ to be a quadrangle, $\Omega_2$ a disk and
+we apply the algorithm starting from zero.
+\begin{figure}[hbt]
+\HLINE{\hss
+\includegraphics[width=6cm]{schwarz-th} \hss}
+\caption{ The 2 overlapping mesh \texttt{TH} and \texttt{th}  }
+\end{figure}
+
+\begin{example}[Schwarz-overlap.edp]~
+\index{tutorial!Schwarz-overlap.edp}
+ \bFF
+ at int inside = 2;  //  inside boundary
+ at int outside = 1; //  outside boundary
+ at border a(t=1,2){x=t;y=0;label=outside;};
+ at border b(t=0,1){x=2;y=t;label=outside;};
+ at border c(t=2,0){x=t ;y=1;label=outside;};
+ at border d(t=1,0){x = 1-t; y = t;label=inside;};
+ at border e(t=0, pi/2){ x= cos(t); y = sin(t);label=inside;};
+ at border e1(t=pi/2, 2*pi){ x= cos(t); y = sin(t);label=outside;};
+ at int n=4;
+ at mesh th = @buildmesh( a(5*n) + b(5*n) + c(10*n) + d(5*n));
+ at mesh TH = @buildmesh( e(5*n) + e1(25*n) );
+ at plot(th,TH,wait=1);  //  to see the 2 meshes
+\eFF
+
+The space  and problem definition is :
+\bFF
+ at fespace vh(th, at P1);
+ at fespace VH(TH, at P1);
+vh u=0,v; VH U,V;
+ at int i=0;
+
+ at problem PB(U,V,init=i,solver=Cholesky) =
+    @int2d(TH)( dx(U)*dx(V)+dy(U)*dy(V) )
+  + @int2d(TH)( -V) + on(inside,U = u)  + @on(outside,U= 0 ) ;
+ at problem pb(u,v,init=i,solver=Cholesky) =
+    @int2d(th)( dx(u)*dx(v)+dy(u)*dy(v) )
+  + @int2d(th)( -v) + on(inside ,u = U) + @on(outside,u = 0 ) ;
+\eFF
+ The  calculation loop:
+\bFF
+ at for ( i=0 ;i< 10; i++)
+{
+   PB;
+   pb;
+   @plot(U,u,wait=true);
+};
+\eFF
+\end{example}
+
+\begin{figure}[hbt]
+\HLINE{\hss
+\includegraphics[width=6cm]{schwarz-u0}
+\hss
+\includegraphics[width=6cm]{schwarz-u} }
+\caption{  Isovalues of the solution at  iteration 0  and iteration 9}
+\end{figure}
+
+
+
+\subsubsection{Schwarz non Overlap Scheme}
+
+To solve\index{domain decomposition}\index{shurr}
+\eq{ -\Delta u =f \hin\Omega=\Omega_1\cup\Omega_2\quad u|_\Gamma=0,}
+the Schwarz algorithm for domain decomposition without overlapping  runs like this
+
+\begin{figure}[hbt]
+\HLINE{\hss
+\includegraphics[width=6cm]{schwarz-no-th} \hss}
+\caption{ The two none overlapping mesh \texttt{TH} and \texttt{th}  }
+\end{figure}
+
+Let introduce  $\Gamma_i$ is  common the boundary of $\Omega_1$ and
+$\Omega_2$ and    $\Gamma_e^i= \partial \Omega_i \setminus \Gamma_i$.
+
+The problem  find  $\lambda$ such that $ (u_1|_{\Gamma_i}=u_2|_{\Gamma_i}) $
+where  $u_i$ is solution of the following Laplace problem:
+\eq{
+    -\Delta u_i=f\hin\Omega_i\quad
+    u_i|_{\Gamma_i}=\lambda \quad
+    u_i|_{\Gamma_e^i} = 0
+ }
+
+To solve this problem we just make a loop
+with upgrading$\lambda$ with
+$$\lambda = \lambda {\pm} \frac{(u_1-u_2)}{2}$$
+where the sign $+$ or $-$ of ${\pm}$ is choose to have convergence.
+
+\begin{example}[Schwarz-no-overlap.edp]~
+\index{tutorial!Schwarz-no-overlap.edp}
+\bFF
+// schwarz1 without overlapping
+ at int inside = 2;
+ at int outside = 1;
+ at border a(t=1,2){x=t;y=0;label=outside;};
+ at border b(t=0,1){x=2;y=t;label=outside;};
+ at border c(t=2,0){x=t ;y=1;label=outside;};
+ at border d(t=1,0){x = 1-t; y = t;label=inside;};
+ at border e(t=0, 1){ x= 1-t; y = t;label=inside;};
+ at border e1(t=pi/2, 2*pi){ x= cos(t); y = sin(t);label=outside;};
+ at int n=4;
+ at mesh th = buildmesh( a(5*n) + b(5*n) + c(10*n) + d(5*n));
+ at mesh TH = buildmesh ( e(5*n) + e1(25*n) );
+ at plot(th,TH,wait=1,ps="schwarz-no-u.eps");
+ at fespace vh(th,P1);
+ at fespace VH(TH,P1);
+vh u=0,v; VH U,V;
+vh lambda=0;
+ at int i=0;
+
+ at problem PB(U,V,init=i,solver=Cholesky) =
+    @int2d(TH)( dx(U)*dx(V)+dy(U)*dy(V) )
+  + @int2d(TH)( -V)
+  + @int1d(TH,inside)(-lambda*V) +    on(outside,U= 0 ) ;
+ at problem pb(u,v,init=i,solver=Cholesky) =
+    @int2d(th)( dx(u)*dx(v)+dy(u)*dy(v) )
+  + @int2d(th)( -v)
+  + @int1d(th,inside)(+lambda*v) +    on(outside,u = 0 ) ;
+
+
+ at for ( i=0 ;i< 10; i++)
+{
+   PB;
+   pb;
+   lambda = lambda - (u-U)/2;
+   @plot(U,u,wait=true);
+};
+
+ at plot(U,u,ps="schwarz-no-u.eps");
+
+\eFF
+\end{example}
+
+\begin{figure}[hbt]
+\HLINE{\hss
+\includegraphics[width=6cm]{schwarz-no-u0}
+\hss
+\includegraphics[width=6cm]{schwarz-no-u} }
+\caption{  Isovalues of the solution at  iteration 0  and iteration 9 without overlapping }
+\end{figure}
+
+\subsubsection{Schwarz-gc.edp}
+To solve\index{domain decomposition}\index{shurr}
+\eq{ -\Delta u =f \hin\Omega=\Omega_1\cup\Omega_2\quad u|_\Gamma=0,}
+the Schwarz algorithm for domain decomposition without overlapping  runs like this
+
+Let introduce  $\Gamma_i$ is  common the boundary of $\Omega_1$ and
+$\Omega_2$ and    $\Gamma_e^i= \partial \Omega_i \setminus  \Gamma_i$.
+
+The problem  find  $\lambda$ such that $ (u_1|_{\Gamma_i}=u_2|_{\Gamma_i}) $
+where  $u_i$ is solution of the following Laplace problem:
+\eq{
+    -\Delta u_i=f\hin\Omega_i\quad
+    u_i|_{\Gamma_i}=\lambda \quad
+    u_i|_{\Gamma_e^i} = 0
+ }
+
+The version of this example for  Shur componant. The border problem
+is solve with conjugate gradient.
+
+First, we construct the two domain
+\begin{example}[Schwarz-gc.edp]~
+\index{tutorial!Schwarz-gc.edp}
+\bFF
+// Schwarz without overlapping (Shur complenement Neumann -> Dirichet)
+ at real cpu=clock();
+ at int inside = 2;
+ at int outside = 1;
+
+ at border Gamma1(t=1,2){x=t;y=0;label=outside;};
+ at border Gamma2(t=0,1){x=2;y=t;label=outside;};
+ at border Gamma3(t=2,0){x=t ;y=1;label=outside;};
+
+ at border GammaInside(t=1,0){x = 1-t; y = t;label=inside;};
+
+ at border GammaArc(t=pi/2, 2*pi){ x= cos(t); y = sin(t);label=outside;};
+int n=4;
+//  build the mesh of $\Omega_1$ and $\Omega_2$
+ at mesh Th1 = buildmesh( Gamma1(5*n) + Gamma2(5*n) + GammaInside(5*n) + Gamma3(5*n));
+ at mesh Th2 = buildmesh ( GammaInside(-5*n) + GammaArc(25*n) );
+ at plot(Th1,Th2);
+
+// defined the 2 FE space
+ at fespace Vh1(Th1,P1),      Vh2(Th2,P1);
+\eFF
+\begin{note}
+It is impossible to
+define a function just on a part of boundary, so the $\ lambda $
+function must be defined on the all domain $\Omega_1$
+such as
+\bFF
+ at Vh1 lambda=0;  // take $\lambda \in V_{h1}$
+\eFF
+\end{note}
+
+The two Poisson problem:
+\bFF
+ at Vh1 u1,v1;              Vh2 u2,v2;
+ at int i=0;  // for factorization optimization
+ at problem Pb2(u2,v2,init=i,solver=Cholesky) =
+    int2d(Th2)( dx(u2)*dx(v2)+dy(u2)*dy(v2) )
+  + int2d(Th2)( -v2)
+  + int1d(Th2,inside)(-lambda*v2) +    on(outside,u2= 0 ) ;
+ at problem Pb1(u1,v1,init=i,solver=Cholesky) =
+    int2d(Th1)( dx(u1)*dx(v1)+dy(u1)*dy(v1) )
+  + int2d(Th1)( -v1)
+  + int1d(Th1,inside)(+lambda*v1) +    on(outside,u1 = 0 ) ;
+\eFF
+or, we define a border matrix , because the
+ $\ lambda $ function is none zero inside the domain $\Omega_1$:
+\bFF
+ at varf b(u2,v2,solver=CG) =int1d(Th1,inside)(u2*v2);
+ at matrix B= b(Vh1,Vh1,solver=CG);
+\eFF
+
+The boundary problem function,
+  $$
+  \lambda \longrightarrow  \int_{\Gamma_i }(u_1-u_2) v_{1}
+$$
+\bFF
+ at func @real[@int] BoundaryProblem(real[int] &l)
+{
+   lambda[]=l; // make FE function form l
+   Pb1;     Pb2;
+   i++;  //  no  refactorization i !=0
+   v1=-(u1-u2);
+   lambda[]=B*v1[];
+   @return lambda[] ;
+};
+\eFF
+\begin{note}
+The  difference between the two notations \ttCC{v1} and \ttCC{v1[]}  is:
+ \ttCC{v1} is the finite element  function and \ttCC{v1[]}
+is the vector in the canonical basis of the   finite element  function  \ttCC{v1} .
+\index{[]@\verb=[]=}
+\end{note}
+\bFF
+Vh1 p=0,q=0;
+//  solve the problem with Conjugate Gradient
+LinearCG(BoundaryProblem,p[],eps=1.e-6,nbiter=100);
+//  compute the final solution, because CG works with increment
+BoundaryProblem(p[]); // solve again  to have right u1,u2
+
+cout << " -- CPU time  schwarz-gc:" <<  clock()-cpu << endl;
+plot(u1,u2); // plot
+\eFF
+\end{example}
+
+\subsection{Fluid/Structures Coupled Problem}
+
+This problem involves the Lam\'{e} system of elasticity
+and the Stokes system for viscous fluids with velocity $\vec u$ and pressure $p$:
+\begin{eqnarray*}\Blue
+-\Delta \vec u +\vec\nabla p = 0, \,
+%\`{u}
+\nabla\cdot \vec u = 0,\hbox{~~in ~}\Omega,\,
+\vec u=\vec u_\Gamma \hbox{~~on~~}\Gamma=\partial\Omega
+\end{eqnarray*}\Black
+where $u_\Gamma$ is the velocity of the boundaries. The
+force  that the fluid applies to the boundaries is the normal stress
+\Blue{$$
+\vec h =(\nabla\vec u +\nabla\vec u^T)\vec n -p\vec n
+$$}
+
+Elastic solids subject to forces deform: a point in the solid,
+at (x,y)
+goes to (X,Y) after.  When the displacement vector
+$\vec v=(v_1,v_2) = (X-x, Y-y)$  is small, Hooke's
+law relates the stress tensor $\sigma$ inside the solid to the
+deformation tensor $\epsilon$:
+\Blue{
+ $$ \sigma_{ij} = \lambda \delta_{ij} \nabla.\vec v + 2\mu\epsilon_{ij},
+\,
+\epsilon_{ij} = {1\over 2}({\partial v_i\over\partial x_j} +
+{\partial v_j\over\partial x_i} )$$
+}
+where $\delta$ is the Kronecker symbol
+and where $\lambda, \mu$ are two constants describing the material mechanical
+properties in terms of the modulus of
+elasticity, and Young's modulus.
+
+The equations of elasticity are naturally written in variational form
+for the displacement vector $v(x)\in V$ as
+\Blue{$$
+\int_\Omega [2\mu\epsilon_{ij}(\vec v)\epsilon_{ij}(\vec w)
++\lambda \epsilon_{ii}(v)\epsilon_{jj}(\vec w)]
+=\int_\Omega \vec g\cdot \vec w +\int_\Gamma \vec h\cdot \vec w,%\`{u}
+\forall \vec w\in V
+$$}
+The data are the gravity force $\vec g$ and the
+boundary stress $\vec h$.
+
+\begin{example}[Fluidstruct.edp]
+\index{tutorial!Fluidstruct.edp}
+In our example the Lam\'{e} system and the Stokes system are coupled by a
+common boundary on which
+the fluid  stress creates a displacement of the boundary and hence
+changes the shape of the domain where the Stokes problem is integrated.
+The geometry is that of a vertical driven cavity with an elastic lid.
+The lid is a beam with weight so it will
+be deformed by its own weight and by the normal stress due to the fluid reaction.
+The cavity is the $10 \times 10$ square and the lid is a rectangle of height $l=2$.
+\\\\
+A beam sits on a box full of fluid rotating because the left vertical side has velocity one.
+The beam is bent by its own weight, but the pressure of the fluid modifies the bending.
+\\
+The bending displacement of the beam is given by (uu,vv) whose solution is
+given as follows.
+\bFF
+//  Fluid-structure interaction for a weighting beam sitting on a
+// square cavity filled with a fluid.
+
+ at int bottombeam = 2; // label of bottombeam
+ at border a(t=2,0)  { x=0; y=t ;label=1;};        //  left beam
+ at border b(t=0,10) { x=t; y=0 ;label=bottombeam;};        //  bottom of beam
+ at border c(t=0,2)  { x=10; y=t ;label=1;};       //  rigth beam
+ at border d(t=0,10) { x=10-t; y=2; label=3;};     //  top beam
+ at real E = 21.5;
+ at real sigma = 0.29;
+ at real mu = E/(2*(1+sigma));
+ at real lambda = E*sigma/((1+sigma)*(1-2*sigma));
+ at real gravity = -0.05;
+ at mesh th = @buildmesh( b(20)+c(5)+d(20)+a(5));
+ at fespace Vh(th, at P1);
+Vh uu,w,vv,s,fluidforce=0;
+ at cout << "lambda,mu,gravity ="<<lambda<< " " << mu << " " << gravity << @endl;
+// deformation of a beam under its own weight
+ at solve  bb([uu,vv],[w,s])  =
+    @int2d(th)(
+                 2*mu*(dx(uu)*dx(w)+ ((dx(vv)+dy(uu))*(dx(s)+dy(w)))/4 )
+               + lambda*(dx(uu)+dy(vv))*(dx(w)+dy(s))/2
+             )
+  + @int2d(th) (-gravity*s)
+  + @on(1,uu=0,vv=0)
+  + fluidforce[];
+ ;
+
+ @plot([uu,vv],wait=1);
+ @mesh th1 = movemesh(th, [x+uu, y+vv]);
+ @plot(th1,wait=1);
+\eFF
+Then Stokes equation for fluids ast low speed are solved in the box below the beam,
+but the beam has deformed the box (see border h):
+\bFF
+//Stokes on square  b,e,f,g  driven cavite on left side g
+ at border e(t=0,10) { x=t; y=-10; label= 1; };      //  bottom
+ at border f(t=0,10) { x=10; y=-10+t ; label= 1; };   //  right
+ at border g(t=0,10) { x=0; y=-t ;label= 2;};       //  left
+ at border h(t=0,10) { x=t; y=vv(t,0)*( t>=0.001 )*(t <= 9.999);
+                    label=3;};   //  top of cavity deformed
+
+ at mesh sh = @buildmesh(h(-20)+f(10)+e(10)+g(10));
+ at plot(sh,wait=1);
+\eFF
+ We use the Uzawa conjugate gradient to solve the Stokes problem like in example \refSec{Uzawa}
+
+\bFF
+ at fespace Xh(sh,P2),Mh(sh,P1);
+Xh u1,u2,v1,v2;
+Mh p,q,ppp;
+
+
+ at varf bx(u1,q) = @int2d(sh)( -(dx(u1)*q));
+
+ at varf by(u1,q) = @int2d(sh)( -(dy(u1)*q));
+
+ at varf Lap(u1,u2)= @int2d(sh)(  dx(u1)*dx(u2) + dy(u1)*dy(u2) )
+                    +  @on(2,u1=1) +  @on(1,3,u1=0)  ;
+
+Xh bc1; bc1[] = Lap(0,Xh);
+Xh brhs;
+
+ at matrix A= Lap(Xh,Xh,solver=CG);
+ at matrix Bx= bx(Xh,Mh);
+ at matrix By= by(Xh,Mh);
+Xh bcx=0,bcy=1;
+
+ at func @real[@int] divup(@real[@int] & pp)
+{
+  @int verb=verbosity;
+   verbosity=0;
+   brhs[]  = Bx'*pp; brhs[] += bc1[] .*bcx[];
+   u1[] = A^-1*brhs[];
+   brhs[]  = By'*pp; brhs[] += bc1[] .*bcy[];
+   u2[] = A^-1*brhs[];
+   ppp[] =   Bx*u1[];
+   ppp[] +=  By*u2[];
+   verbosity=verb;
+   @return ppp[] ;
+};
+
+ p=0;q=0;u1=0;v1=0;
+
+ @LinearCG(divup,p[],eps=1.e-3,nbiter=50);
+ divup(p[]);
+\eFF
+Now the beam will feel the stress constraint from the fluid:
+\bFF
+  Vh sigma11,sigma22,sigma12;
+  Vh uu1=uu,vv1=vv;
+
+  sigma11([x+uu,y+vv]) = (2*dx(u1)-p);
+  sigma22([x+uu,y+vv]) = (2*dy(u2)-p);
+  sigma12([x+uu,y+vv]) = (dx(u1)+dy(u2));
+\eFF
+which comes as a boundary condition to the PDE of the beam:
+\bFF
+ at varf fluidf([uu,vv],[w,s]) fluidforce =
+ at solve  bbst([uu,vv],[w,s],init=i)  =
+    @int2d(th)(
+                 2*mu*(dx(uu)*dx(w)+ ((dx(vv)+dy(uu))*(dx(s)+dy(w)))/4 )
+               + lambda*(dx(uu)+dy(vv))*(dx(w)+dy(s))/2
+             )
+  + @int2d(th) (-gravity*s)
+  + @int1d(th,bottombeam)( -coef*(   sigma11*N.x*w + sigma22*N.y*s
+                                   + sigma12*(N.y*w+N.x*s) )  )
+  + @on(1,uu=0,vv=0);
+ @plot([uu,vv],wait=1);
+ @real  err = sqrt(@int2d(th)( (uu-uu1)^2 + (vv-vv1)^2 ));
+ @cout <<  " Erreur L2 = " << err << "----------\n";
+\eFF
+
+Notice that the matrix generated by bbst is reused (see \ttCC{init=i}).
+Finally we deform the beam
+\bFF
+ th1 = @movemesh(th, [x+0.2*uu, y+0.2*vv]);
+ @plot(th1,wait=1);
+\eFF
+\end{example}
+
+\subsection{\setS{Transmission Problem}}
+Consider an elastic plate whose displacement change vertically,
+which is made up of three plates of different materials,
+welded on each other.
+Let $\Omega_i,\, i=1,2,3$ be the domain occupied by $i$-th material
+with tension $\mu_i$ (see \refSec{Soap Film}).
+The computational domain $\Omega$ is the interior of
+$\overline{\Omega_1}\cup \overline{\Omega_2}\cup \overline{\Omega_3}$.
+The vertical displacement $u(x,y)$ is obtained from
+\begin{eqnarray}
+\label{eqn:transm-1}
+-\mu_i\Delta u&=&f~\textrm{in }\Omega_i\\
+\label{eqn:transm-2}
+\mu_i\partial_n u|_{\Gamma_{i}}&=&-\mu_j\partial_n u|_{\Gamma_{j}}
+\quad \textrm{on }\overline{\Omega_{i}}\cap\overline{\Omega_{j}}
+\qquad \textrm{if }1\le i< j\le 3
+\end{eqnarray}
+where $\partial_n u|_{\Gamma_{i}}$ denotes the value of
+the normal derivative $\partial_n u$ on the boundary $\Gamma_i$ of
+the domain $\Omega_i$.
+
+By introducing the characteristic function $\chi_i$ of $\Omega_i$, that is,
+\begin{equation}
+\chi_i(x)=1\quad\textrm{if }x\in \Omega_i;\qquad
+\chi_i(x)=0\quad\textrm{if }x\not\in \Omega_i
+\end{equation}
+we can easily rewrite (\ref{eqn:transm-1}) and (\ref{eqn:transm-2})
+to the weak form. Here we assume that $u=0$ on $\Gamma=\partial\Omega$.
+
+problem Transmission: For a given function $f$, find $u$ such that
+\begin{eqnarray}
+\label{eqn:transmission}
+a(u,v)&=&\ell(f,v)\quad \textrm{for all }v\in H^1_0(\Omega)\\
+a(u,v)=\int_{\Omega}\mu \nabla u\cdot \nabla v,\quad
+\ell(f,v)=\int_{\Omega}fv\nonumber
+\end{eqnarray}
+where $\mu=\mu_1\chi_1+\mu_2\chi_2+\mu_3\chi_3$.
+Here we notice that $\mu$ become the discontinuous function.
+
+With dissipation, and at the thermal equilibrium, the temperature equation
+is:
+
+This example explains the definition and manipulation of \emph{region}, i.e.
+\index{subdomains} subdomains of the whole domain.
+
+Consider this L-shaped domain with 3 diagonals as internal boundaries, defining
+4 subdomains:
+
+\bFF
+//   example using region keyword
+// construct a mesh with 4 regions (sub-domains)
+border a(t=0,1){x=t;y=0;};
+border b(t=0,0.5){x=1;y=t;};
+border c(t=0,0.5){x=1-t;y=0.5;};
+border d(t=0.5,1){x=0.5;y=t;};
+border e(t=0.5,1){x=1-t;y=1;};
+border f(t=0,1){x=0;y=1-t;};
+//  internal boundary
+border i1(t=0,0.5){x=t;y=1-t;};
+border i2(t=0,0.5){x=t;y=t;};
+border i3(t=0,0.5){x=1-t;y=t;};
+
+mesh th = buildmesh (a(6) + b(4) + c(4) +d(4) + e(4) +
+    f(6)+i1(6)+i2(6)+i3(6));
+fespace Ph(th,P0);  // constant discontinuous functions / element
+fespace Vh(th,P1);  // $P_1$ continuous functions / element
+
+Ph reg=region; //  defined the $P_0$ function  associated to region number
+plot(reg,fill=1,wait=1,value=1);
+\eFF
+\twoplot[height=8cm]{region}{region_nu}{the function \texttt{reg}}{the function \texttt{nu} }
+
+\index{region} \texttt{region}  is a keyword of freefem++ which is in fact a variable depending of
+the current position (is not a function today, use \texttt{Ph reg=region;} to  set  a function).  This variable value returned is the number of the
+subdomain of the current position.  This number is defined by "buildmesh" which scans while building the mesh all
+its connected component.  So to get the number of a region containing a particular point
+one does:
+\bFF
+
+int nupper=reg(0.4,0.9); // get the region number of point (0.4,0.9)
+int nlower=reg(0.9,0.1);  // get the region number of point (0.4,0.1)
+cout << " nlower " <<  nlower << ", nupper = " << nupper<< endl;
+//  defined the characteristics functions of upper and lower region
+Ph nu=1+5*(region==nlower) + 10*(region==nupper);
+plot(nu,fill=1,wait=1);
+\eFF
+This is particularly useful to define \index{discontinuous functions}discontinuous functions such as might occur
+when one part of the domain is copper and the other one is iron, for example.
+\\
+We this in mind we proceed to solve a Laplace equation with discontinuous coefficients
+($\nu$ is 1, 6 and 11 below).
+\bFF
+Ph nu=1+5*(region==nlower) + 10*(region==nupper);
+plot(nu,fill=1,wait=1);
+problem lap(u,v) =   int2d(th)( nu*( dx(u)*dx(v)*dy(u)*dy(v) )) + int2d(-1*v) + on(a,b,c,d,e,f,u=0);
+plot(u);
+\eFF
+\plot[height=8cm]{region_u}{the isovalue of the solution $u$}
+\newpage
+
+\subsection{Free Boundary Problem}
+
+The domain $\Omega$ is defined with:
+
+\bFF
+ at real L=10;        //longueur du domaine
+ at real h=2.1;      // hauteur du bord gauche
+ at real h1=0.35;    // hauteur du bord droite
+
+//  maillage d'un tapeze
+ at border a(t=0,L){x=t;y=0;};       // bottom:  $\Gamma_a$ \hfill
+ at border b(t=0,h1){x=L;y=t;};      // right:  $\Gamma_b$ \hfill
+ at border f(t=L,0){x=t;y=t*(h1-h)/L+h;}; //  free surface:  $\Gamma_f$ \hfill
+ at border d(t=h,0){x=0;y=t;};      // left:  $\Gamma_d$ \hfill
+
+ at int n=4;
+ at mesh Th=@buildmesh (a(10*n)+b(6*n)+f(8*n)+d(3*n));
+ at plot(Th,ps="dTh.eps");
+\eFF
+
+
+\begin{figure}[hbt]
+\includegraphics[width=15cm]{dTh}
+\caption{The mesh of the domain $\Omega$}
+\end{figure}
+
+The free boundary problem is:
+
+Find $u$ and $\Omega$ such that:
+
+ $$ \left\{\begin{array}{cl}
+ \displaystyle - \Delta u = 0  & \mbox{in } \Omega\\
+ \displaystyle      u = y         &\mbox{on } \Gamma_b \\
+ \displaystyle      {\partial u  \over \partial n} = 0   &\mbox{on } \Gamma_d \cup \Gamma_a \\
+ \displaystyle    {\partial u  \over \partial n} = { q\over K} n_x
+          \mbox{\ and \ } {u = y}  &\mbox{on\ } \Gamma_ f
+\end{array}\right. $$
+
+
+We use a fixed point method;
+$\Omega^0 = \Omega$
+
+in two step, fist we solve the classical following problem:
+$$ \left\{\begin{array}{rll}
+ \displaystyle - \Delta u &= 0  & \mbox{in } \Omega^n\\
+ \displaystyle      u &= y         &\mbox{on } \Gamma^n_b \\
+ \displaystyle      {\partial u  \over \partial n} &= 0   &\mbox{on } \Gamma^n_d \cup \Gamma^n_a\\
+ \displaystyle    u &= y        &\mbox{on\ } \Gamma^n_ f
+\end{array}\right. $$
+
+The variational formulation is:
+
+find $u$ on $V=H^1(\Omega^n)$, such than  $u=y$ on $\Gamma^n_b$ and $\Gamma^n_f$
+$$
+ \int_{\Omega^n}  \nabla u \nabla u' = 0,  \quad \forall u' \in V  \mbox{ with }  u' =0 \mbox{ on }
+\Gamma^n_b \cup \Gamma^n_f
+$$
+
+
+and secondly to construct a domain deformation $\mathcal{F}(x,y)=[x,y-v(x,y)]$
+
+where $v$ is  solution of  the following problem:
+
+ $$ \left\{\begin{array}{rll}
+ \displaystyle - \Delta v &= 0  & \mbox{in } \Omega^n\\
+ \displaystyle      v  &= 0         &\mbox{on } \Gamma^n_a \\
+ \displaystyle      {\partial v \over \partial n} &= 0   &\mbox{on } \Gamma^n_b \cup \Gamma^n_d \\
+ \displaystyle    {\partial v  \over \partial n}  &=  \displaystyle {\partial u  \over \partial n} - { q\over K} n_x
+            &\mbox{on\ } \Gamma^n_ f
+\end{array}\right. $$
+
+The variational formulation is:
+
+find $v$ on $V$, such than  $v=0$ on $\Gamma^n_a$
+$$
+ \int_{\Omega^n}  \nabla v \nabla v' = \int_{\Gamma_f^n}  ({\partial u  \over \partial n} - { q\over K} n_x )v',  \quad \forall v' \in V  \mbox{ with }  v' =0 \mbox{ on }
+\Gamma^n_a
+$$
+
+Finally the new domain
+$\Omega^{n+1} = \mathcal{F}(\Omega^n)$
+
+
+
+\begin{example}[freeboundary.edp]
+\index{tutorial!freeboundary.edp}
+The  \texttt{FreeFem++} :implementation is:
+
+\bFF
+ at real q=0.02;      //flux entrant
+ at real K=0.5;           //permeabilit\'{e}
+
+ at fespace Vh(Th,P1);
+ at int j=0;
+
+Vh u,v,uu,vv;
+
+ at problem Pu(u,uu,solver=CG) = @int2d(Th)( dx(u)*dx(uu)+dy(u)*dy(uu))
+  + @on(b,f,u=y) ;
+
+ at problem Pv(v,vv,solver=CG) = @int2d(Th)( dx(v)*dx(vv)+dy(v)*dy(vv))
+  +  @on (a, v=0) + @int1d(Th,f)(vv*((q/K)*N.y- (dx(u)*N.x+dy(u)*N.y)));
+
+
+ at real errv=1;
+ at real erradap=0.001;
+verbosity=1;
+ at while(errv>1e-6)
+{
+  j++;
+  Pu;
+  Pv;
+  @plot(Th,u,v ,wait=0);
+  errv=int1d(Th,f)(v*v);
+   real coef=1;
+
+//
+  real mintcc = @checkmovemesh(Th,[x,y])/5.;
+  real mint = @checkmovemesh(Th,[x,y-v*coef]);
+
+  if (mint<mintcc ||  j%10==0) {  // mesh to bad => remeshing
+    Th=@adaptmesh(Th,u,err=erradap ) ;
+    mintcc = @checkmovemesh(Th,[x,y])/5.;
+  }
+
+  @while (1)
+  {
+    real mint = @checkmovemesh(Th,[x,y-v*coef]);
+
+    if (mint>mintcc) break;
+
+    cout << " min |T]  " << mint << endl;
+    coef /= 1.5;
+  }
+
+  Th=@movemesh(Th,[x,y-coef*v]); // calcul de la deformation
+  cout << "\n\n"<<j <<"------------ errv = " << errv << "\n\n";
+
+}
+ at plot(Th,ps="d_Thf.eps");
+ at plot(u,wait=1,ps="d_u.eps");
+\eFF
+\end{example}
+
+\begin{figure}[hbt]
+\includegraphics[width=15cm]{d_u}
+\caption{The final solution on  the new  domain $\Omega^{72}$}
+\end{figure}
+\begin{figure}[hbt]
+\includegraphics[width=15cm]{d_Thf}
+\caption{The adapted mesh of the domain $\Omega^{72}$}
+\end{figure}
+
+\textBlack\subsection{nolinear-elas.edp}
+\textBlack
+The nonlinear elasticity  problem is find  the displacement $(u_{1},u_{2})$  minimizing  $J$
+$$ \min J(u_{1},u_{2}) = \int_{\Omega} f(F2) -  \int_{\Gamma_{p}} P_{a} \,  u_{2} $$
+where  $F2(u_{1},u_{2}) =  A(E[u_{1},u_{2}],E[u_{1},u_{2}])$ and $A(X,Y)$ is bilinear sym. positive form with respect two matrix $X,Y$.
+where $f$ is a given $\mathcal{C}^2$  function, and $E[u_{1},u_{2}] = (E_{ij})_{i=1,2,\,j=1,2}$ is the Green-Saint Venant deformation tensor defined  with:
+$$  E_{ij} = 0.5 ( \partial_i u_j + \partial_j u_i ) + \sum_k \partial_i u_k {\times} \partial_j u_k  $$
+
+
+
+The differential of $J$ is
+  $$ DJ(u_{1},u_{2})(v_{1},v_{2}) = \int 2 A(E[u_{1},u_{2}],DE[u_{1},u_{2}](v_{1},v_{2})) f'(F2(u_{1},u_{2}))) -  \int_{\Gamma_{p}} P_{a}  u_{2}  $$
+
+denote $\mathbf{u}=u_{1},u_{2}$, $\mathbf{v}=v_{1},v_{2}$, $\mathbf{w}=(w_{1},w_{2})$ and
+the second order differential is
+ {\begin{eqnarray*}
+ D^2 J(\mathbf{u})((\mathbf{v}),(\mathbf{w}))  &= & A(E[\mathbf{u}],DE[\mathbf{u}](\mathbf{v})) A(E[\mathbf{u}],DE[\mathbf{u}](\mathbf{w})) f''(F2(\mathbf{u}))) \\
+ & + &  A(DE[\mathbf{u}](\mathbf{v}),DE[\mathbf{u}](\mathbf{w})) f'(F2(\mathbf{u}))) \\
+ &+&  A(DE[\mathbf{u}],D^{2}E[\mathbf{u}]((\mathbf{v}),(\mathbf{w}))) f'(F2(\mathbf{u})))
+\end{eqnarray*}}
+ where $DE$ and $D^{2}E$ are the first and second differential of $E$.
+
+ \medskip
+
+
+The Newton Method is
+
+choose $ n=0$,and $u_O,v_O$ the initial displacement
+\begin{itemize}
+\item loop: \par
+\item  \hspace{1cm}    find $(du,dv)$ :  solution of
+$$ D^2J(u_n,v_n)((w,s),(du,dv)) =  DJ(u_n,v_n)(w,s) , \quad \forall w,s $$
+\item  \hspace{1cm}      $un =un - du,\quad vn =vn - dv$
+\item  \hspace{1cm}      until $(du,dv)$ small is enough
+\end{itemize}
+
+\color{black}The way to implement this algorithm in \freefempp is
+use a macro tool to implement  $A$ and $F2$, $f$, $f'$,$f''$.
+
+A macro\label{macro}\index{macro} is like is \texttt{ccp} preprocessor of \Cpp, but this begin by
+\texttt{macro} and the end of the macro definition is the begin of the comment $//$.
+In this case the macro is very useful because the type of parameter can be change.
+And  it is easy to make automatic differentiation.
+
+\bFF
+//  non linear elasticity model \hfilll
+//   \hfilll
+//  -------------------------------\hfilll
+//  with huge utilization of  macro\hfilll
+// ---------------------------\hfilll
+//   optimize version \hfilll
+// ------------\hfilll
+//  @problem is  find $(uu,vn)$  minimizing  $J$\hfilll
+//  $ min J(un,vn) = @int f(F2) -  @int Pa * un $\hfilll
+//   $ dJ(u,u,uu,vv) = @int dF2(u,v,uu,vv) df(F2(u,v))$ \hfilll
+//   where $F2 =  (^t {E}  A {E} )$ , \hfilll
+//   $E(U) =  1/2 (\nabla U + \nabla U^t + \nabla U^t  \nabla U) $ \hfilll
+//         ($u_1$) \hfilll
+//  with U=(   )\hfilll
+//         ($u_2$)\hfilll
+// so: \hfilll
+// \hfilll$$ E_{ij} = 0.5 ( d_i u_j + d_j u_i ) + \sum_k d_i u_k * d_j*u_k  \leqno(1)$$
+//  the 3 components of the Green Saint-Venant deformation tensor: \hfilll
+//  $E1(u1,u2) =    E_{11} $\hfilll
+//  $E2(u1,u2) =    E_{12} = E_21 $\hfilll
+//  $E3(u1,u2) =    E_{22}  $\textBlack\hfilll
+\eFF
+~
+\bFF
+// remark : we can parametrize E1,E2,E3 with:\hfilll
+//  EE(da,db,a,b,u1,u2) \hfilll
+//   where $da,db$ correspond to $d_i, d_j$ in (1)\hfilll
+//   where  $a,b$  correspond to $u_i, u_j$ in (1)\hfilll
+//   where $u1,u2$  correspond to $u_1, u_2$ in (1)\hfilll
+//  ----------------------------------------------
+
+//  first the linear part of EE linear elasticite\hfilll
+// remark a macro end with a // comment \hfilll
+ at macro EEL(di,dj,ui,uj) ( (di(uj)+dj(ui))*0.5 )    // 11
+
+// non linear par of EE (bilinear)  simple to differential \hfilll
+ at macro bEENL(di,dj,u1,u2,v1,v2) (di(u1)*dj(v1)*.5+di(u2)*dj(v2)*0.5)
+//
+ at macro EENL(di,dj,u1,u2) bEENL(di,dj,u1,u2,u1,u2) //
+ at macro dEENL(di,dj,u1,u2,du1,du2) ( bEENL(di,dj,du1,du2,u1,u2)
+                                  + bEENL(di,dj,u1,u2,du1,du2) )
+//   ------------ \hfilll
+ at macro EE(di,dj,ui,uj,u1,u2) (EEL(di,dj,u1,uj) + EENL(di,dj,u1,u2)) //
+ at macro dEE(di,dj,dui,duj,u1,u2,du1,du2) (EEL(di,dj,du1,duj)
+                                         + dEENL(di,dj,u1,u2,du1,du2)) //
+ at macro ddEE(di,dj,du1,du2,ddu1,ddu2) ( dEENL(di,dj,du1,du2,ddu1,ddu2))
+//
+// remark  : \hfilll
+// $ dEE(di,dj,dui,duj,u1,u2,du1,du2)$  is "the formal differential of EE" \hfilll
+// where $du1=\delta u1$ ,$du2=\delta u2$ \hfilll
+// $ ddEE(di,dj,dui,duj,u1,u2,du1,du2)$  is "the formal differential of dEE" \hfilll
+// where $ddu1=\delta^2 u1$ ,$ddu2=\delta^2 u2$ \hfilll
+// --- \hfilll
+
+//  the macro corresponding to the 3 componante of E \hfilll
+ at macro E1(u,v)  /*E11*/EE(dx,dx,u,u,u,v)  //
+ at macro E2(u,v)  /*E12*/EE(dx,dy,u,v,u,v)  //
+ at macro E3(u,v)  /*E22*/EE(dy,dy,v,v,u,v)  //
+
+ at macro dE1(u,v,uu,vv) /*dE11*/dEE(dx,dx,uu,uu,u,v,uu,vv) //
+ at macro dE2(u,v,uu,vv) /*dE12*/dEE(dx,dy,uu,vv,u,v,uu,vv) //
+ at macro dE3(u,v,uu,vv) /*dE22*/dEE(dy,dy,vv,vv,u,v,uu,vv) //
+ at macro ddE1(u,v,uu,vv,uuu,vvv) /*ddE11*/ddEE(dx,dx,uu,vv,uuu,vvv) //
+ at macro ddE2(u,v,uu,vv,uuu,vvv) /*ddE12*/ddEE(dx,dy,uu,vv,uuu,vvv) //
+ at macro ddE3(u,v,uu,vv,uuu,vvv) /*ddE22*/ddEE(dy,dy,uu,vv,uuu,vvv)
+//
+//  a formal bilinear term \hfilll
+ at macro PP(A,B,u,v) (A(u,v)*B(u,v))
+//
+// a formal diff  bilinear term \hfilll
+ at macro dPP(A,B,dA,dB,u,v,uu,vv) (dA(u,v,uu,vv)*B(u,v) + A(u,v)*dB(u,v,uu,vv))
+//
+// a formal $diff^2$ bilinear term \hfilll
+ at macro ddPP(A,B,dA,dB,ddA,ddB,u,v,uu,vv,uuu,vvv) (
+  dA(u,v,uu,vv)*dB(u,v,uuu,vvv) + dA(u,v,uuu,vvv)*dB(u,v,uu,vv)
+  +  ddA(u,v,uu,vv,uuu,vvv)*B(u,v) + A(u,v)*ddB(u,v,uu,vv,uuu,vvv)
+  ) //
+// so the @matrix A is 6 coef \hfilll
+//
+//     a11 a12 a13 \hfilll
+//     a12 a22 a23 \hfilll
+//     a13 a23 a33 \hfilll
+ at macro F2(u,v)  /* F2 */  (
+     a11*PP(E1,E1,u,v)
+  +  a22*PP(E2,E2,u,v)
+  +  a33*PP(E3,E3,u,v)
+  +  a13*PP(E1,E3,u,v)
+  +  a13*PP(E3,E1,u,v)
+  +  a12*PP(E1,E2,u,v)
+  +  a12*PP(E2,E1,u,v)
+  +  a23*PP(E2,E3,u,v)
+  +  a23*PP(E3,E2,u,v)
+)  // end macro F2
+
+ at macro dF2(u,v,uu,vv)  /* dF2 */  (
+       a11*dPP(E1,E1,dE1,dE1,u,v,uu,vv)
+     + a12*dPP(E1,E2,dE1,dE2,u,v,uu,vv)
+     + a13*dPP(E1,E3,dE1,dE3,u,v,uu,vv)
+     + a21*dPP(E2,E1,dE2,dE1,u,v,uu,vv)
+     + a22*dPP(E2,E2,dE2,dE2,u,v,uu,vv)
+     + a23*dPP(E2,E3,dE2,dE3,u,v,uu,vv)
+     + a31*dPP(E3,E1,dE3,dE1,u,v,uu,vv)
+     + a32*dPP(E3,E2,dE3,dE2,u,v,uu,vv)
+     + a33*dPP(E3,E3,dE3,dE3,u,v,uu,vv)
+) // end macro dF2 ($D F2$)
+
+ at macro ddF2(u,v,uu,vv,uuu,vvv)  /* ddF2 */  (
+       a11*ddPP(E1,E1,dE1,dE1,ddE1,ddE1,u,v,uu,vv,uuu,vvv)
+     + a12*ddPP(E1,E2,dE1,dE2,ddE1,ddE2,u,v,uu,vv,uuu,vvv)
+     + a13*ddPP(E1,E3,dE1,dE3,ddE1,ddE3,u,v,uu,vv,uuu,vvv)
+     + a21*ddPP(E2,E1,dE2,dE1,ddE2,ddE1,u,v,uu,vv,uuu,vvv)
+     + a22*ddPP(E2,E2,dE2,dE2,ddE2,ddE2,u,v,uu,vv,uuu,vvv)
+     + a23*ddPP(E2,E3,dE2,dE3,ddE2,ddE3,u,v,uu,vv,uuu,vvv)
+     + a31*ddPP(E3,E1,dE3,dE1,ddE3,ddE1,u,v,uu,vv,uuu,vvv)
+     + a32*ddPP(E3,E2,dE3,dE2,ddE3,ddE2,u,v,uu,vv,uuu,vvv)
+     + a33*ddPP(E3,E3,dE3,dE3,ddE3,ddE3,u,v,uu,vv,uuu,vvv)
+) // end macro ddF2  ($D^{2}  F2$)
+
+//  differential of J: \hfilll
+
+//  @for hyper elasticity @problem  \hfilll
+//  ------------------------------ \hfilll
+
+ at macro f(u) (u) // end of macro
+ at macro df(u) (1) // end of macro  $df=f'$
+ at macro ddf(u) (0) // end of macro $ddf=f''$
+
+//  -- du caoutchouc --- CF cours de Herve Le Dret. \hfilll
+// ------------------------------- \hfilll
+ at real mu = 0.012e5; //  $kg/cm^2$
+ at real lambda =  0.4e5; //  $kg/cm^2$
+//  \hfilll
+//   $  \sigma = 2 \mu E + \lambda tr(E) Id $  \hfilll
+//    \hfilll
+//   ( a b )  \hfilll
+//   ( b c )  \hfilll
+//  \hfilll
+//  tr*Id : (a,b,c) -> (a+c,0,a+c)  \hfilll
+// so the associed @matrix is:  \hfilll
+//   ( 1 0 1 )  \hfilll
+//   ( 0 0 0 )  \hfilll
+//   ( 1 0 1 )  \hfilll
+// ------------------ the coef \hfilll
+ at real a11= 2*mu +  lambda  ;
+ at real a22= 2*mu ;
+ at real a33= 2*mu +   lambda ;
+ at real a12= 0 ;
+ at real a13= lambda ;
+ at real a23= 0 ;
+//  symetric part
+ at real a21= a12 ;
+ at real a31= a13 ;
+ at real a32= a23 ;
+ at real Pa=1e2; //  a pressure of 100 Pa
+// ----------------
+
+ at int n=30,m=10;
+ at mesh Th= square(n,m,[x,.3*y]); // label: 1 bottom, 2 right, 3 up, 4 left;
+ at int bottom=1, right=2,upper=3,left=4;
+
+ at plot(Th);
+
+ at fespace Wh(Th,P1dc);
+ at fespace Vh(Th,[P1,P1]);
+ at fespace Sh(Th,P1);
+
+Wh e2,fe2,dfe2,ddfe2; // optimisation
+Wh ett,ezz,err,erz; // optimisation
+
+Vh [uu,vv], [w,s],[un,vn];
+[un,vn]=[0,0];//  intialisation
+[uu,vv]=[0,0];
+
+ at varf vmass([uu,vv],[w,s],solver=CG) =  @int2d(Th)( uu*w + vv*s );
+ at matrix M=vmass(Vh,Vh);
+
+ at problem NonLin([uu,vv],[w,s],solver=LU)=
+ @int2d(Th,qforder=1)( // $(D^2 J(un))$ part
+               ddF2(un,vn,uu,vv,w,s)* dfe2
+       + dF2(un,vn,uu,vv)*dF2(un,vn,w,s)*ddfe2
+        )
+   - at int2d(Th,<1)( // $(D J(un))$ part
+           dF2(un,vn,w,s) * dfe2  )
+   - @int1d(Th,3)(Pa*s)
+   + @on(right,left,uu=0,vv=0);
+;
+// Newton's method
+// ---------------
+Sh u1,v1;
+ at for (@int i=0;i<10;i++)
+{
+  @cout << "Loop " << i << @endl;
+  e2 = F2(un,vn);
+  dfe2 = df(e2) ;
+  ddfe2 = ddf(e2);
+  @cout << "  e2 max " <<e2[].max << " , min" << e2[].min << @endl;
+  @cout << " de2 max "<< dfe2[].max << " , min" << dfe2[].min << @endl;
+  @cout << "dde2 max "<< ddfe2[].max << " , min" << ddfe2[].min << @endl;
+  NonLin; //  compute $[uu,vv] = (D^2 J(un))^{-1}(D J(un))$
+
+  w[]   = M*uu[];
+  @real res = sqrt(w[]' * uu[]); //  norme $ L^2 of [uu,vv]$
+  u1 = uu;
+  v1 = vv;
+  @cout << " L^2 residual = " << res << @endl;
+  @cout << " u1 min =" <<u1[].min << ", u1 max= " << u1[].max << @endl;
+  @cout << " v1 min =" <<v1[].min << ", v2 max= " << v1[].max << @endl;
+  @plot([uu,vv],wait=1,cmm=" uu, vv " );
+  un[] -= uu[];
+  @plot([un,vn],wait=1,cmm=" deplacement " );
+  @if (res<1e-5) @break;
+}
+
+ at plot([un,vn],wait=1);
+ at mesh th1 = @movemesh(Th, [x+un, y+vn]);
+ at plot(th1,wait=1); //  see figure \ref{fig nl-elas}
+\eFF
+
+\begin{figure}[hbt]
+\begin{center}\includegraphics[width=16cm]{nl-elas}\end{center}
+\caption{\label{fig nl-elas} The deformated domain}
+\end{figure}
+
+
+
+\section{Parallel version experimental}
+A first test of parallelization of \texttt{FreeFem++} is make under mpi.
+We add three word in the language:
+\begin{description}
+\itemtt[mpisize] The total number of  processes\index{mpisize}
+\itemtt[mpirank]  the number of my current process in $\{0,..., mpisize-1\}$.\index{mpirank}
+\itemtt [processor] a function to set the possessor to send or receive data
+\itemtt [broadcast] a function to broadcast from a processor to all other a data \index{broadcast}\index{processor}
+\bFF
+    processor(10) << a ; // send to the process 10 the data a;
+    processor(10) >> a ; // receive from the process 10 the data a;
+
+\eFF
+\end{description}
+\subsection{Schwarz in parallel}
+If example is just the rewritting of example \texttt{schwarz-overlap}
+in section \ref{schwarz-overlap}.\index{schwarz}\index{broadcast}\index{processor}
+\index{array!mesh}
+
+How to use
+\bFF
+[examples++-mpi] Hecht%lamboot
+
+LAM 6.5.9/MPI 2 C++/ROMIO - Indiana University
+
+
+[examples++-mpi] hecht% mpirun -np 2 FreeFem++-mpi schwarz-c.edp
+\eFF
+
+\bFF
+//  a new coding version c,   methode de schwarz in parallele \hfilll
+// with 2 proc. \hfilll
+//  ------------------------------- \hfilll
+// F.Hecht december 2003 \hfilll
+// ---------------------------------- \hfilll
+//  to test the broadcast instruction \hfilll
+//  and array of mesh  \hfilll
+//  add add the stop test \hfilll
+//  --------------------------------- \hfilll
+
+ at if ( mpisize != 2 ) {
+  @cout << " sorry number of processeur !=2 " << endl;
+  exit(1);}
+ at verbosity=3;
+ at real pi=4*atan(1);
+ at int inside = 2;
+ at int outside = 1;
+ at border a(t=1,2){x=t;y=0;label=outside;};
+ at border b(t=0,1){x=2;y=t;label=outside;};
+ at border c(t=2,0){x=t ;y=1;label=outside;};
+ at border d(t=1,0){x = 1-t; y = t;label=inside;};
+ at border e(t=0, pi/2){ x= cos(t); y = sin(t);label=inside;};
+ at border e1(t=pi/2, 2*pi){ x= cos(t); y = sin(t);label=outside;};
+ at int n=4;
+ at mesh[int]  Th(mpisize);
+ at if (mpirank == 0)
+ Th[0] = buildmesh( a(5*n) + b(5*n) + c(10*n) + d(5*n));
+ at else
+ Th[1] = buildmesh ( e(5*n) + e1(25*n) );
+
+ at broadcast(@processor(0),Th[0]);
+ at broadcast(@processor(1),Th[1]);
+
+ at fespace Vh(Th[mpirank],P1);
+ at fespace Vhother(Th[1-mpirank],P1);
+
+Vh u=0,v;
+Vhother U=0;
+ at int i=0;
+
+ at problem pb(u,v,init=i,solver=Cholesky) =
+    @int2d(Th[mpirank])( dx(u)*dx(v)+dy(u)*dy(v) )
+  - @int2d(Th[mpirank])( v)
+  + @on(inside,u = U)  +  @on(outside,u= U ) ;
+
+ at for ( i=0 ;i< 20; i++)
+{
+  @cout << mpirank << " looP " << i << endl;
+   pb;
+   //  send u  to the other proc, receive in U
+   @processor(1-mpirank) << u[];   @processor(1-mpirank) >> U[];
+   @real err0,err1;
+   err0 = int1d(Th[mpirank],inside)(square(U-u)) ;
+   // send err0  to the other proc, receive in err1
+   @processor(1-mpirank)<<err0;   @processor(1-mpirank)>>err1;
+   @real err= sqrt(err0+err1);
+   @cout <<" err = " << err << " err0 = " << err0 << ", err1 = " << err1 << endl;
+   @if(err<1e-3) @break;
+};
+ at if (mpirank==0)
+    @plot(u,U,ps="uU.eps");
+
+\eFF
+
+\include{docFFGUI}
+
+\section{\setS{Mesh Files}}
+ \def\Chars#1{{\tt (C*)}  #1}
+ \def\Char#1{{\tt (C)}  #1}
+ \def\Int#1{ {\tt(I)} #1}
+ \def\Real#1{{\tt(R)} #1}
+ \def\Bool#1{{\tt(B)} #1}
+ \def\Vertex#1{{{\tt @@Vertex}#1}}
+ \def\Edge#1{{{\tt @@Edge}#1}}
+ \def\Triangle#1{{{\tt @@Tria}#1}}
+ \def\Quadrangle#1{{{\tt @@Quad}#1}}
+ \def\Tetrahedron#1{{{\tt @@Tetra}#1}}
+ \def\Hexahedron#1{{{\tt @@Hexa}#1}}
+ \def\Pentahedron#1{{{\tt @@Penta}#1}}
+ \def\Loop#1#2{{\bf\Large(}\,#1\,{\bf\Large{,\,\,}}\,#2\,{\bf\Large)}}
+ \def\requis{\hfill {\it  requis}}
+ \def\facultatif{\quad\quad facultatif}
+ \def\need#1{\hfill{\it  requiert le champ\,:\,#1}}
+
+\subsection{File mesh data structure}
+\index{file!data base}\index{file!bamg}
+The mesh data structure, output of a mesh generation algorithm,
+refers to the geometric data structure and in some case to another
+mesh data structure.
+
+In this case, the fields are
+
+\small
+\begin{itemize}
+\item {\tt MeshVersionFormatted 0}
+\end{itemize}
+\normalsize
+
+\small
+\begin{itemize}
+\item {\tt Dimension}
+  \Int{dim}
+
+\item {\tt Vertices}
+  \Int{NbOfVertices}\\
+  \Loop{\,\,\Loop{\Real{x$_i^j$}}{j=1,dim}\,\,,\,\Int{$Ref \phi_i^v$}}{i=1\,,\,NbOfVertices}
+
+\item {\tt Edges}
+  \Int{NbOfEdges} \\
+  \Loop{\Vertex{$^1_i$}\,,\,\Vertex{$^2_i$}\,,\,\Int{$Ref \phi_i^e$}}{i=1\,,\,NbOfEdges}
+
+\item {\tt Triangles}
+  \Int{NbOfTriangles} \\
+    \Loop{\Loop{\Vertex{$_i^j$}}{j=1,3}\,,\,\Int{$Ref \phi_i^t$} }{ i=1\,,\,NbOfTriangles}
+
+\item {\tt Quadrilaterals}
+  \Int{NbOfQuadrilaterals} \\
+    \Loop{\Loop{\Vertex{$_i^j$}}{j=1,4}\,,\,\Int{$Ref \phi_i^t$} }{ i=1\,,\,NbOfQuadrilaterals}
+
+\item {\tt Geometry} \\
+\Chars{FileNameOfGeometricSupport} \\
+
+\begin{itemize}
+\item {\tt VertexOnGeometricVertex} \\
+   \Int{NbOfVertexOnGeometricVertex}\\
+\Loop{\Vertex{$_i$}\,,\,\Vertex{$_i^{geo}$}}{i=1,NbOfVertexOnGeometricVertex}
+
+\item {\tt EdgeOnGeometricEdge} \\
+   \Int{NbOfEdgeOnGeometricEdge}\\
+\Loop{\Edge{$_i$}\,,\,\Edge{$_i^{geo}$}}{i=1,NbOfEdgeOnGeometricEdge}
+\end{itemize}
+
+\item {\tt CrackedEdges}
+  \Int{NbOfCrackedEdges}\\
+  \Loop{\Edge{$_i^1$}\,,\,\Edge{$_i^2$}}{i=1\,,\,{NbOfCrackedEdges}}
+
+\end{itemize}
+\normalsize
+
+When the current mesh refers to a previous mesh, we have in addition
+
+\small
+\begin{itemize}
+\item {\tt MeshSupportOfVertices} \\
+\Chars{FileNameOfMeshSupport} \\
+\begin{itemize}
+
+\item {\tt VertexOnSupportVertex} \\
+   \Int{NbOfVertexOnSupportVertex}\\
+\Loop{\Vertex{$_i$}\,,\,\Vertex{$_i^{supp}$}}{i=1,NbOfVertexOnSupportVertex}
+
+\item {\tt VertexOnSupportEdge} \\
+   \Int{NbOfVertexOnSupportEdge}\\
+\Loop{\Vertex{$_i$}\,,\,\Edge{$_i^{supp}$}\,,\,  \mbox{\Real{$u_i^{supp}$}}  }{i=1,NbOfVertexOnSupportEdge}
+
+\item {\tt VertexOnSupportTriangle} \\
+   \Int{NbOfVertexOnSupportTriangle}\\
+\Loop{\Vertex{$_i$}\,,\,\Triangle{$_i^{supp}$}\,,\,
+  \mbox{\Real{$u_i^{supp}$}}\,,\,  \mbox{\Real{$v_i^{supp}$}}  }
+{\\ \hbox to 3cm {} i=1\,,\,{NbOfVertexOnSupportTriangle}}
+
+
+\item {\tt VertexOnSupportQuadrilaterals} \\
+   \Int{NbOfVertexOnSupportQuadrilaterals}\\
+\Loop{\Vertex{$_i$}\,,\,\Quadrangle{$_i^{supp}$}\,,\,
+  \mbox{\Real{$u_i^{supp}$}}\,,\,  \mbox{\Real{$v_i^{supp}$}}  }
+{\\ \hbox to 3cm {} i=1\,,\,{NbOfVertexOnSupportQuadrilaterals}}
+
+
+\end{itemize}
+
+\end{itemize}
+\normalsize
+
+
+
+\subsection {bb File type for Store Solutions}
+The file is formatted such that:
+{\tt \obeylines
+   2 nbsol nbv 2
+  $\left(\left(\mathtt{U}_{ij}, \quad \forall i \in \{1,...,\mathtt{nbsol}\}\right), \quad \forall j \in \{1,...,\mathtt{nbv}\}\right)$
+ }
+
+where
+\begin{itemize}
+\item {\tt  nbsol} is a integer equal to  the number of solutions.
+\item  {\tt nbv} is  a integer equal to the number of vertex .
+\item  {\tt U$_{ij}$} is a real equal the value of the $i$ solution at vertex $j$
+on the associated mesh background if read file, generated if write file.
+\end{itemize}
+
+\subsection {BB File Type for Store Solutions}
+The file is formatted such that:
+{\tt \obeylines
+  $ \mathtt{ \quad 2 \quad n \quad typesol^1 \quad ... \quad typesol^n \quad  nbv \quad 2}  $
+  $\left(\left(\left( \mathtt{U}_{ij}^k, \quad \forall i \in \{1,...,\mathtt{typesol}^k\}\right), %
+\quad \forall k \in \{1,...\mathtt{n}\}\right) %
+ \quad \forall j \in \{1,...,\mathtt{nbv}\}\right)$
+ }
+
+where
+\begin{itemize}
+\item {\tt  n} is a integer equal to  the number of solutions
+\item $\mathtt{  typesol^k}$, type of the solution  number $ k$, is
+  \begin{itemize}
+   \item $\mathtt{typesol^k = 1}$ the solution {\tt k} is scalare  (1  value per vertex)
+   \item $\mathtt{typesol^k = 2}$ the solution {\tt k} is vectorial  (2 values per unknown)
+   \item $\mathtt{typesol^k = 3}$ the solution {\tt k} is a  $2{\times} 2$ symmetric matrix  (3 values per vertex)
+   \item $\mathtt{typesol^k = 4}$ the solution  {\tt k} is a  $2{\times} 2$ matrix  (4 values per vertex)
+   \end{itemize}
+
+\item  {\tt nbv} is  a integer equal to the number of vertices
+\item  {\tt U$_{ij}^k$} is a real equal the value of the component  $i$ of the solution  $k$ at vertex $j$
+on the associated mesh background if read file, generated if write file.
+\end{itemize}
+
+
+\subsection{Metric File}
+ A metric file can be of two types, isotropic or anisotropic.
+\label{Metric file}
+
+the isotropic file is such that
+{\tt \obeylines
+   nbv  1
+   h$_i \quad \forall i \in \{1,...,\mathtt{nbv}\}$
+}
+
+
+where
+\begin{itemize}
+\item {\tt  nbv} is  a integer equal to the number of vertices.
+\item   {\tt h$_i$} is the wanted mesh size near the vertex $i$ on background mesh,
+the metric is $\mathcal{M}_i=h_i^{-2} Id$, where $ Id $ is the identity matrix.
+\end{itemize}
+
+The metric anisotrope
+{\tt \obeylines
+   nbv  3
+   a11$_i$,a21$_i$,a22$_i \quad \forall i \in \{1,...,\mathtt{nbv}\}$
+}
+
+
+where
+\begin{itemize}
+\item   {\tt nbv} is  a integer equal to the number of vertices,
+\item  a11$_i$, a12$_i$, a22$_i$ is metric
+$\mathcal{M}_i = \left(\begin{smallmatrix} a11_i & a12_i \\ a12_i & a22_i \end{smallmatrix}\right)$ which define the wanted mesh size
+in a vicinity of  the vertex $i$
+such that $h$ in direction $u \in \R^2$ is equal to $ |u|/\sqrt{u\cdot\mathcal{M}_i\, u}$ , where $\cdot$ is the dot product
+in $\R^2$, and $|\cdot|$ is the classical norm.
+
+\end{itemize}
+
+\subsection{List of  AM\_FMT, AMDBA Meshes}
+ \index{file!am}\index{file!am\_fmt}\index{file!amdba}
+ The mesh is only composed of triangles and can be defined with the help of
+the following two integers and four arrays:
+
+  \begin{ttlist}
+  \item [nbt] is the number of triangles.
+  \item [nbv] is the number of vertices.
+
+  \item [nu(1:3,1:nbt)] is an integer array giving the three vertex numbers
+
+counterclockwise for each triangle.
+
+  \item [c(1:2,nbv)]    is a real array giving the two coordinates of each vertex.
+  \item [refs(nbv)]     is an integer array giving the reference numbers of the
+vertices.
+  \item [reft(nbv)]     is an integer array giving the reference numbers of the
+triangles.
+  \end{ttlist}
+
+\paragraph{AM\_FMT Files}\label{AMFMT}
+\index{file!am\_fmt}
+In fortran the  {\tt am\_fmt}  files are read as follows:
+
+\begin{verbatim}
+     open(1,file='xxx.am_fmt',form='formatted',status='old')
+       read (1,*) nbv,nbt
+       read (1,*)  ((nu(i,j),i=1,3),j=1,nbt)
+       read (1,*)  ((c(i,j),i=1,2),j=1,nbv)
+       read (1,*)  ( reft(i),i=1,nbt)
+       read (1,*)  ( refs(i),i=1,nbv)
+     close(1)
+\end{verbatim}
+
+\paragraph{AM Files}\label{AM}
+\index{file!am}
+In fortran the  {\tt am}  files are read as follows:
+
+\begin{verbatim}
+     open(1,file='xxx.am',form='unformatted',status='old')
+       read (1,*) nbv,nbt
+       read (1)  ((nu(i,j),i=1,3),j=1,nbt),
+     &   ((c(i,j),i=1,2),j=1,nbv),
+     &   ( reft(i),i=1,nbt),
+     &   ( refs(i),i=1,nbv)
+     close(1)
+\end{verbatim}
+\paragraph{AMDBA Files}\label{AMDBA}
+\index{file!amdba}
+In fortran the  {\tt amdba}  files are read as follows:
+\begin{verbatim}
+     open(1,file='xxx.amdba',form='formatted',status='old')
+       read (1,*) nbv,nbt
+       read (1,*) (k,(c(i,k),i=1,2),refs(k),j=1,nbv)
+       read (1,*) (k,(nu(i,k),i=1,3),reft(k),j=1,nbt)
+     close(1)
+\end{verbatim}
+\paragraph{msh Files}\label{MSH}
+\index{file!msh}
+First, we add the notions of boundary edges
+  \begin{ttlist}
+  \item [nbbe] is the number of boundary edge.
+  \item [nube(1:2,1:nbbe)] is an integer array giving the two vertex numbers
+  \item [refbe(1:nbbe)] is an integer array giving the two vertex numbers
+  \end{ttlist}
+In fortran the  {\tt msh}  files are read as follows:
+\begin{verbatim}
+     open(1,file='xxx.msh',form='formatted',status='old')
+       read (1,*) nbv,nbt,nbbe
+       read (1,*) ((c(i,k),i=1,2),refs(k),j=1,nbv)
+       read (1,*) ((nu(i,k),i=1,3),reft(k),j=1,nbt)
+       read (1,*) ((ne(i,k),i=1,2), refbe(k),j=1,nbbe)
+     close(1)
+\end{verbatim}
+\paragraph{ftq Files}\label{FTQ}
+\index{file!ftq}
+In fortran the  {\tt ftq}  files are read as follows:
+\begin{verbatim}
+     open(1,file='xxx.ftq',form='formatted',status='old')
+      read (1,*) nbv,nbe,nbt,nbq
+      read (1,*) (k(j),(nu(i,j),i=1,k(j)),reft(j),j=1,nbe)
+      read (1,*) ((c(i,k),i=1,2),refs(k),j=1,nbv)
+     close(1)
+\end{verbatim}
+where   if {\tt  k(j) = 3} then the element $j$  is  a triangle and if {\tt k = 4}
+the the element $j$   is a quadrilateral.
+
+\include{addfe}
+
+\appendix
+\section{Table of Notations}
+Here mathematical expressions and corresponding \freefempp commands are noted.
+\subsection{Generalities}
+\begin{description}
+  \item[$\delta_{ij}$] Kronecker delta ($0$ if $i\neq j$, 1 if $i=j$ for integers $i,j$)
+  \item[$\forall$] for all
+  \item[$\exists$] there exist
+  \item[i.e.] that is
+  \item[PDE] partial differential equation (with boundary conditions)
+  \item[$\emptyset$] the empty set
+  \item[$\N$] the set of integers ($a\in \N\Leftrightarrow \texttt{int a}$);
+  ``\texttt{int}'' means \emph{long integer} inside \freefempp
+  \item[$\R$] the set of real numbers ($a\in \R\Leftrightarrow \texttt{real a}$)  ;\emph{double} inside \freefempp
+  \item[$\C$] the set of complex numbers ($a\in \C\Leftrightarrow \texttt{complex a}$);
+  \emph{complex<double>}
+  \item[$\R^d$] $d$-dimensional Euclidean space
+\end{description}
+\subsection{Sets, Mappings, Matrices, Vectors}
+Let $E,\, F,\, G$ be three sets and $A$ subset of $E$.
+\begin{description}
+  \item[$\{x\in E|\; P\}$] the subset of $E$ consisting of the elements possessing the property $P$
+  \item[$E\cup F$] the set of elements belonging to $E$ or $F$
+  \item[$E\cap F$] the set of elements belonging to $E$ and $F$
+  \item[$E\setminus A$] the set $\{x\in E|\; x\not\in A\}$
+  \item[$E+F$] $E\cup F$ with $E\cap F=\emptyset$
+  \item[$E\times F$] the cartesian product of $E$ and $F$
+  \item[$E^n$] the $n$-th power of $E$ ($E^2=E\times E$, $E^n=E\times E^{n-1}$)
+  \item[$f:\; E\to F$] the mapping form $E$ into $F$, i.e.,
+  $E\ni x\mapsto f(x)\in F$
+  \item[$I_E$ or $I$] the identity mapping in $E$,i.e., $I(x)=x\quad \forall x\in E$
+  \item[$f\circ g$] for $f:\; F\to G$ and $g:\; E\to F$,
+  $E\ni x\mapsto (f\circ g)(x)=f(g(x))\in G$ (see \refSec{One Variable Functions})
+  \item[$f|_A$] the restriction of $f:\; E\to F$ to the subset $A$ of $E$
+  \item[$\{a_k\}$] column vector with components $a_k$
+  \item[$(a_k)$] row vector with components $a_k$
+  \item[$(a_{k})^T$] denotes the transpose of a matrix $(a_{k})$, and
+  is $\{a_{k}\}$
+  \item[$\{a_{ij}\}$] matrix with components $a_{ij}$, and $(a_{ij})^T=(a_{ji})$
+\end{description}
+
+\subsection{Numbers}
+For two real numbers $a,b$
+\begin{description}
+  \item[\quad]$[a,b]$ is the interval $\{x\in \R|\; a\le x\le b\}$
+  \item[\quad]$]a,b]$ is the interval $\{x\in \R|\; a< x\le b\}$
+  \item[\quad]$[a,b[$ is the interval $\{x\in \R|\; a\le x< b\}$
+  \item[\quad]$]a,b[$ is the interval $\{x\in \R|\; a< x< b\}$
+\end{description}
+
+\subsection{Differential Calculus}
+\begin{description}
+  \item[$\partial f/\partial x$] the partial derivative of $f:\R^d\to \R$ with respect to $x$ (\ttCC{@dx(f)})
+  \item[$\nabla f$] the gradient of $f:\Omega\to \R$,i.e., $\nabla f=(\partial f/\partial x,\, \partial f/\partial y)$
+  \item[div$\vec{f}$ or $\nabla.\vec{f}$] the divergence of $\vec{f}:\Omega\to \R^d$, i.e., div$\vec{f}=\partial f_1/\partial x+\partial f_2/\partial y$
+  \item[$\Delta f$] the Laplacian of $f:\; \Omega\to \R$, i.e.,
+  $\Delta f=\partial^2f/\partial x^2+\partial^2 f/\partial y^2$
+\end{description}
+
+\subsection{Meshes}
+\begin{description}
+  \item[$\Omega$] usually denotes a domain on which PDE is defined
+  \item[$\Gamma$] denotes the boundary of $\Omega$,i.e., $\Gamma=\partial\Omega
+$ (keyword \ttCC{@border}, see \refSec{Border})
+  \item[$\mathcal{T}_h$] the triangulation of $\Omega$, i.e., the set of triangles $T_k$, where $h$ stands for mesh size (keyword \ttCC{@mesh}, \ttCC{@buildmesh}, see \refSec{Mesh Generation})
+  \item[$n_t$] the number of triangles in $\mathcal{T}_h$ (get by \texttt{Th.nt}, see ``mesh.edp'')
+  \item[$\Omega_h$] denotes the approximated domain $\Omega_h=\cup_{k=1}^{n_t}T_k$ of $\Omega$. If $\Omega$ is polygonal domain, then it will be $\Omega=\Omega_h$
+  \item[$\Gamma_h$] the boundary of $\Omega_h$
+  \item[$n_v$] the number of vertices in $\mathcal{T}_h$ (get by \texttt{Th.nv})
+  \item[[$q^iq^j$]] the segment connecting $q^i$ and $q^j$
+  \item[$q^{k_1},q^{k_2},q^{k_3}$] the vertices of a triangle $T_k$ with anti-clock direction (get the coordinate of $q^{k_j}$ by
+  (\texttt{Th[k-1][j-1].x, Th[k-1][j-1].y}))
+  \item[$I_{\Omega}$] the set $\{i\in \N|\; q^i\not\in \Gamma_h\}$
+\end{description}
+
+\subsection{Finite Element Spaces}
+\begin{description}
+\item[$L^2(\Omega)$] the set
+$\displaystyle{
+\left\{w(x,y)\left|\; \int_{\Omega}|w(x,y)|^2dxdy<\infty\right.\right\}
+}$
+\begin{eqnarray*}
+&&\textrm{norm:}\; \| w\|_{0,\Omega}=\left(\int_{\Omega}|w(x,y)|^2dxdy\right)^{1/2}\\
+&&\textrm{scalar product:}\; (v,w)=\int_{\Omega}vw
+\end{eqnarray*}
+\item[$H^1(\Omega)$] the set
+$\displaystyle{
+\left\{w\in L^2(\Omega)\left|\; \int_{\Omega}
+\left(|\partial w/\partial x|^2+|\partial w/\partial y|^2\right)dxdy<\infty\right.\right\}
+}$
+\begin{eqnarray*}
+&&\textrm{norm:}\; \| w\|_{1,\Omega}=\left(\| w\|_{0,\Omega}^2+\|\nabla u\|_{0.\Omega}^2\right)^{1/2}
+\end{eqnarray*}
+\item[$H^m(\Omega)$] the set
+$\displaystyle{
+\left\{w\in L^2(\Omega)\left|\; \int_{\Omega}
+\frac{\partial^{|\alpha|} w}{\partial x^{\alpha_1}\partial y^{\alpha_2}}\in L^2(\Omega)\quad
+\forall \alpha=(\alpha_1,\alpha_2)\in \N^2,\, |\alpha|=\alpha_1+\alpha_2\right.
+\right\}
+}$
+\begin{eqnarray*}
+&&\textrm{scalar product:}\; (v,w)_{1,\Omega}=
+\sum_{|\alpha|\le m}\int_{\Omega} D^{\alpha}v D^{\alpha}w
+\end{eqnarray*}
+\item[$H^1_0(\Omega)$]
+the set $\left\{w\in H^1(\Omega)\left|\; u=0\quad \textrm{on }\Gamma\right.\right\}$
+\item[$L^2(\Omega)^2$] denotes $L^2(\Omega)\times L^2(\Omega)$, and also
+$H^1(\Omega)^2=H^1(\Omega)\times H^1(\Omega)$
+  \item[$V_h$] denotes the finite element space created by
+  ``\ttCC{@fespace} Vh(Th,*)'' in \freefempp (see \refSec{Finite Elements} for ``*'')
+  \item[$\Pi_h f$] the projection of the function $f$ into $V_h$
+  (``\ttCC{@func f=x\^{}2*y\^{}3; Vh v = f;}'' means \ttCC{v} = $\Pi_h$\ttCC{f})  \item[$\{v\}$]
+  for FE-function $v$ in $V_h$ means the column vector $(v_1,\cdots,v_M)^T$ if
+  $v=v_1\phi_1+\cdots+v_M\phi_M$, which is shown by
+  ``\ttCC{@fespace Vh(Th,P2); Vh v; cout << v[] << endl;}''
+\end{description}
+
+\section{Grammar}
+\subsection{Keywords}
+\bFF
+      Cmatrix
+      R3
+      bool
+      border
+      break
+      complex
+      continue
+      element
+      else
+      end
+      fespace
+      for
+      func
+      if
+      ifstream
+      include
+      int
+      load
+      macro
+      matrix
+      mesh
+      ofstream
+      problem
+      real
+      return
+      solve
+      string
+      vertex
+      varf
+      while
+
+\eFF
+\subsection{The bison grammar}
+\bFF
+
+start:   input @ENDOFFILE;
+
+input:   instructions ;
+
+instructions:  instruction
+        | instructions  instruction   ;
+
+list_of_id_args:
+            | id
+            | id '=' no_comma_expr
+            | @FESPACE id
+            | type_of_dcl id
+            | type_of_dcl '&' id
+            | '[' list_of_id_args ']'
+            | list_of_id_args ',' id
+            | list_of_id_args ',' '[' list_of_id_args ']'
+            | list_of_id_args ',' id '=' no_comma_expr
+            | list_of_id_args ',' FESPACE id
+            | list_of_id_args ',' type_of_dcl id
+            | list_of_id_args ',' type_of_dcl '&' id ;
+
+list_of_id1:  id
+            | list_of_id1 ',' id   ;
+
+id: @ID | @FESPACE ;
+
+list_of_dcls:    @ID
+              |  @ID '='   no_comma_expr
+              |  @ID  '(' parameters_list ')'
+              |  list_of_dcls ',' list_of_dcls  ;
+
+
+parameters_list:
+           no_set_expr
+        |  @FESPACE  @ID
+        |  @ID '=' no_set_expr
+        | parameters_list ',' no_set_expr
+        | parameters_list ',' id '=' no_set_expr ;
+
+type_of_dcl:   @TYPE
+             | @TYPE '[' @TYPE ']' ;
+
+ID_space:
+    @ID
+ |  @ID '[' no_set_expr ']'
+ |  @ID '=' no_set_expr
+ |  '[' list_of_id1 ']'
+ |  '[' list_of_id1 ']' '[' no_set_expr ']'
+ |  '[' list_of_id1 ']' '=' no_set_expr ;
+
+ID_array_space:
+    @ID '(' no_set_expr ')'
+ |  '[' list_of_id1 ']' '(' no_set_expr ')' ;
+
+fespace: @FESPACE ;
+
+spaceIDa  :      ID_array_space
+            |    spaceIDa ',' ID_array_space  ;
+
+spaceIDb  :      ID_space
+            |    spaceIDb ',' ID_space ;
+
+spaceIDs :    fespace               spaceIDb
+           |  fespace '[' @TYPE ']'  spaceIDa    ;
+
+fespace_def: @ID '(' parameters_list ')' ;
+
+fespace_def_list:  fespace_def
+                 | fespace_def_list ',' fespace_def ;
+
+
+declaration:   type_of_dcl list_of_dcls ';'
+             | 'fespace' fespace_def_list    ';'
+             | spaceIDs ';'
+             | @FUNCTION @ID '=' Expr ';'
+             | @FUNCTION type_of_dcl @ID  '(' list_of_id_args ')'  '{' instructions'}'
+             | @FUNCTION @ID '(' list_of_id_args ')'   '='   no_comma_expr  ';'     ;
+
+begin: '{'  ;
+end:   '}'  ;
+
+for_loop:    'for'   ;
+while_loop:  'while' ;
+
+instruction:   ';'
+         | 'include'  @STRING
+         | 'load'  @STRING
+         |  Expr  ';'
+         |  declaration
+         |  for_loop  '(' Expr ';' Expr ';' Expr ')' instruction
+         |  while_loop '(' Expr ')' instruction
+         |  'if' '(' Expr ')'   instruction
+         |  'if' '(' Expr ')'   instruction  ELSE instruction
+         |  begin  instructions end
+         |  'border'  @ID   border_expr
+         |  'border'   @ID   '['  array ']' ';'
+         |  'break'  ';'
+         |  'continue'  ';'
+         |  'return'  Expr ';'  ;
+
+
+bornes: '(' @ID '=' Expr ',' Expr ')' ;
+
+border_expr:   bornes instruction  ;
+
+Expr:    no_comma_expr
+       | Expr ',' Expr ;
+
+
+unop:     '-'
+        | '+'
+        | '!'
+        | '++'
+        | '--'  ;
+
+no_comma_expr:
+          no_set_expr
+        | no_set_expr '=' no_comma_expr
+        | no_set_expr '+=' no_comma_expr
+        | no_set_expr '-=' no_comma_expr
+        | no_set_expr '*=' no_comma_expr
+        | no_set_expr '/=' no_comma_expr ;
+
+no_set_expr:
+          unary_expr
+        | no_set_expr '*' no_set_expr
+        | no_set_expr '.*' no_set_expr
+        | no_set_expr './' no_set_expr
+        | no_set_expr '/' no_set_expr
+        | no_set_expr '%' no_set_expr
+        | no_set_expr '+' no_set_expr
+        | no_set_expr '-' no_set_expr
+        | no_set_expr '<<' no_set_expr
+        | no_set_expr '>>' no_set_expr
+        | no_set_expr '&' no_set_expr
+        | no_set_expr '&&' no_set_expr
+        | no_set_expr '|' no_set_expr
+        | no_set_expr '||' no_set_expr
+        | no_set_expr '<' no_set_expr
+        | no_set_expr '<=' no_set_expr
+        | no_set_expr '>' no_set_expr
+        | no_set_expr '>=' no_set_expr
+        | no_set_expr '==' no_set_expr
+        | no_set_expr '!=' no_set_expr ;
+
+
+parameters:
+        |   no_set_expr
+        |   @FESPACE
+        |   id '=' no_set_expr
+        |   parameters ',' @FESPACE
+        |   parameters ',' no_set_expr
+        |   parameters ',' id '=' no_set_expr ;
+
+array:   no_comma_expr
+       | array ',' no_comma_expr ;
+
+
+unary_expr:
+    pow_expr
+  | unop  pow_expr %prec UNARY ;
+
+pow_expr: primary
+  |      primary  '^' unary_expr
+  |      primary  '_' unary_expr
+  |      primary '\''  ;    //  transpose \index{transpose}
+
+primary:
+           @ID
+  |        @LNUM
+  |        @DNUM
+  |        @CNUM
+  |        @STRING
+  |        primary '('  parameters ')'
+  |        primary '[' Expr ']'
+  |        primary '['  ']'
+  |        primary '.'  ID
+  |        primary '++'
+  |        primary '--'
+  |        TYPE '('  Expr ')' ;
+  |        '(' Expr ')'
+  |        '[' array  ']' ;
+
+\eFF
+\subsection{The Types of the languages, and cast}
+%\begin{verbatim}
+% the types
+% --lgElement =  <lgElement>
+%    [,  type :<Polymorphic>
+%   operator :
+%   (    <lgVertex> :   <lgElement>, <long> )
+
+%
+% --lgVertex =  <lgVertex>
+%    label,  type :<Polymorphic>
+%   operator. :
+%   (    <long> :   <lgVertex> )
+
+%    x,  type :<Polymorphic>
+%   operator. :
+%   (    <double> :   <lgVertex> )
+
+%    y,  type :<Polymorphic>
+%   operator. :
+%   (    <double> :   <lgVertex> )
+
+% --Add_KN_<double> =  <Add_KN_<double>>
+
+% --Add_Mulc_KN_<double> * =  <Add_Mulc_KN_<double>>
+
+% --AnyTypeWithOutCheck =  <AnyTypeWithOutCheck>
+
+% --C_F0 =  <C_F0>
+
+% --DotStar_KN_<double> =  <DotStar_KN_<double>>
+
+% --E_Array =  <E_Array>
+
+% --FEbase<double> * =  <FEbase<double>>
+%    <FEbase<double>> :   <FEbase<double>>
+% --FEbase<double> ** =  <FEbase<double> **>
+
+% --FEbaseArray<double> * =  <FEbaseArray<double>>
+
+% --FEbaseArray<double> ** =  <FEbaseArray<double> **>
+%    []  type :<Polymorphic>   operator :
+%   (    <FEbase<double> **> :   <FEbaseArray<double> **>, <long> )
+
+%
+% --Fem2D::Mesh * =  <Fem2D::Mesh>
+%    <Fem2D::Mesh> :   <Fem2D::Mesh **>
+% --Fem2D::Mesh ** =  <Fem2D::Mesh **>
+%    <-,  type :<Polymorphic>
+%   (    <Fem2D::Mesh> :   <string> )
+%   (    <long> :   <Fem2D::Mesh **>, <double>, <double> )
+
+%    area,  type :<Polymorphic>   operator. :
+%   (    <double> :   <Fem2D::Mesh **> )
+
+%    nt,  type :<Polymorphic>
+%   operator. :
+%   (    <long> :   <Fem2D::Mesh **> )
+
+%    nv,  type :<Polymorphic>   operator. :
+%   (    <long> :   <Fem2D::Mesh **> )
+
+%
+% --Fem2D::MeshPoint * =  <Fem2D::MeshPoint>
+%    N,  type :<Polymorphic>   operator. :
+%   (    <Fem2D::R3> :   <Fem2D::MeshPoint> )
+
+%    P,  type :<Polymorphic>   operator. :
+%   (    <Fem2D::R3> :   <Fem2D::MeshPoint> )
+
+%
+% --Fem2D::R2 * =  <Fem2D::R2>
+
+% --Fem2D::R3 * =  <Fem2D::R3>
+%    x,  type :<Polymorphic>   operator. :
+%   (    <double *> :   <Fem2D::R3> )
+
+%    y,  type :<Polymorphic>   operator. :
+%   (    <double *> :   <Fem2D::R3> )
+
+%    z,  type :<Polymorphic>   operator. :
+%   (    <double *> :   <Fem2D::R3> )
+
+%
+% --Fem2D::TypeOfFE * =  <Fem2D::TypeOfFE>
+
+% --KN<double> =  <KN<double>>
+%    []  type :<Polymorphic>   operator :
+%   (    <double *> :   <KN<double>>, <long> )
+
+%
+% --KN<double> * =  <KN<double> *>
+%    <-,  type :<Polymorphic>
+%   (    <KN<double> *> :   <KN<double> *>, <long> )
+
+%    []  type :<Polymorphic>   operator :
+%   (    <double *> :   <KN<double> *>, <long> )
+
+%    max,  type :<Polymorphic>   operator. :
+%   (    <double> :   <KN<double> *> )
+
+%    min,  type :<Polymorphic>   operator. :
+%   (    <double> :   <KN<double> *> )
+
+%    n,  type :<Polymorphic>
+%   operator. :
+%   (    <long> :   <KN<double> *> )
+
+%    sum,  type :<Polymorphic>   operator. :
+%   (    <double> :   <KN<double> *> )
+
+%
+% --KN_<double> =  <KN_<double>>
+
+% --KN_<double> * =  <KN_<double> *>
+
+% --Matrice_Creuse<double> * =  <Matrice_Creuse<double>>
+%    <Matrice_Creuse<double>> :   <Problem>
+% --Matrice_Creuse_Transpose<double> =  <Matrice_Creuse_Transpose<double>>
+
+% --Matrice_Creuse_inv<double> =  <Matrice_Creuse_inv<double>>
+
+% --Mulc_KN_<double> =  <Mulc_KN_<double>>
+
+% --MyMap<String, double> * =  <MyMap<String, double>>
+%    []  type :<Polymorphic>   operator :
+%   (    <double *> :   <MyMap<String, double>>, <string> )
+
+%
+% --Polymorphic * =  <Polymorphic>
+
+% --Sub_KN_<double> =  <Sub_KN_<double>>
+
+% --Transpose<KN<double>> =  <Transpose<KN<double>>>
+
+% --TypeSolveMat * =  <TypeSolveMat>
+
+% --VirtualMatrice<double>::plusAtx =  <VirtualMatrice<double>::plusAtx>
+
+% --VirtualMatrice<double>::plusAx =  <VirtualMatrice<double>::plusAx>
+
+% --VirtualMatrice<double>::solveAxeqb =  <VirtualMatrice<double>::solveAxeqb>
+
+% --bool =  <bool>
+%    <bool> :   <bool *>
+% --bool * =  <bool *>
+
+% --char * =  <char>
+
+% --const BC_set<double> * =  <BC_set<double>>
+
+% --const CDomainOfIntegration * =  <CDomainOfIntegration>
+%    ()  type :<Polymorphic>   operator :
+%   (    <FormBilinear> :   <CDomainOfIntegration>, <LinearComb<std::pair<MGauche, MDroit>, C_F0>> )
+%   (    <double> :   <CDomainOfIntegration>, <double> )
+%   (    <FormLinear> :   <CDomainOfIntegration>, <LinearComb<MDroit, C_F0>> )
+
+%
+% --const C_args * =  <C_args>
+%    <C_args> :   <FormBilinear>     ()  type :<Polymorphic>   operator :
+%   (    <Call_FormLinear> :   <C_args>, <long>, <v_fes **> )
+%   (    <Call_FormBilinear> :   <C_args>, <v_fes **>, <v_fes **> )
+
+%
+% --const Call_FormBilinear * =  <Call_FormBilinear>
+
+% --const Call_FormLinear * =  <Call_FormLinear>
+
+% --const E_Border * =  <E_Border>
+
+% --const E_BorderN * =  <E_BorderN>
+
+% --const Fem2D::QuadratureFormular * =  <Fem2D::QuadratureFormular>
+
+% --const Fem2D::QuadratureFormular1d * =  <Fem2D::QuadratureFormular1d>
+
+% --const FormBilinear * =  <FormBilinear>
+%    ()  type :<Polymorphic>   operator :
+%   (    <Call_FormBilinear> :   <FormBilinear>, <v_fes **>, <v_fes **> )
+%   (    <Call_FormLinear> :   <FormBilinear>, <long>, <v_fes **> )
+
+%
+% --const FormLinear * =  <FormLinear>
+%    ()  type :<Polymorphic>   operator :
+%   (    <Call_FormLinear> :   <FormLinear>, <v_fes **> )
+
+%
+% --const IntFunction * =  <IntFunction>
+
+% --const LinearComb<MDroit, C_F0> * =  <LinearComb<MDroit, C_F0>>
+
+% --const LinearComb<MGauche, C_F0> * =  <LinearComb<MGauche, C_F0>>
+
+% --const LinearComb<std::pair<MGauche, MDroit>, C_F0> * =  <LinearComb<std::pair<MGauche, MDroit>, C_F0>>
+
+% --const Problem * =  <Problem>
+
+% --const Solve * =  <Solve>
+
+% --const char * =  <char>
+
+% --double =  <double>
+%    <double> :   <double *>     ()  type :<Polymorphic>   operator :
+%   (    <double> :   <double>, <double>, <double> )
+
+%
+% --double * =  <double *>
+
+% --interpolate_f_X_1<double>::type =  <interpolate_f_X_1<double>::type>
+
+% --long =  <long>
+%    <long> :   <long *>
+% --long * =  <long *>
+
+% --istream * =  <istream>
+%    <istream> :   <istream **>
+% --istream ** =  <istream **>
+
+% --ostream * =  <ostream>
+%    <ostream> :   <ostream **>
+% --ostream ** =  <ostream **>
+%    <-,  type :<Polymorphic>   operator( ):
+%   (    <ostream> :   <string> )
+
+%
+% --string * =  <string>
+%    <string> :   <string **>
+% --string ** =  <string **>
+
+% --std::complex<double> =  <complex>
+%    <complex> :   <complex *>
+% --std::complex<double> * =  <complex *>
+
+% --std::ios_base::openmode =  <std::ios_base::openmode>
+
+% --std::pair<FEbase<double> *, int> =  <std::pair<FEbase<double> *, int>>
+%    (),  type :<Polymorphic>   operator :
+%   (    <double> :   <std::pair<FEbase<double> *, int>>, <double>, <double> )
+%   (    <interpolate_f_X_1<double>::type> :   <std::pair<FEbase<double> *, int>>, <E_Array> )
+
+%    [],  type :<Polymorphic>  operator. :
+%   (    <KN<double> *> :   <std::pair<FEbase<double> *, int>> )
+
+%    n,  type :<Polymorphic>   operator. :
+%   (    <long> :   <std::pair<FEbase<double> *, int>> )
+% --std::pair<FEbaseArray<double> *, int> =  <std::pair<FEbaseArray<double> *, int>>
+%    []  type :<Polymorphic>
+%   operator :
+%   (    <std::pair<FEbase<double> *, int>> :   <std::pair<FEbaseArray<double> *, int>>, <long> )
+% --std::pair<Fem2D::Mesh **, int> * =  <std::pair<Fem2D::Mesh **, int>>
+% --v_fes * =  <v_fes>
+%    <v_fes> :   <v_fes **>
+% --v_fes ** =  <v_fes **>
+
+% --void =  <void>
+%\end{verbatim}
+
+\subsection{All the operators}
+\begin{verbatim}
+  - CG,  type :<TypeSolveMat>
+  - Cholesky,  type :<TypeSolveMat>
+  - Crout,  type :<TypeSolveMat>
+  - GMRES,  type :<TypeSolveMat>
+  - LU,  type :<TypeSolveMat>
+  - LinearCG,  type :<Polymorphic>   operator() :
+   (    <long> :   <Polymorphic>, <KN<double> *>, <KN<double> *> )
+
+  - N,  type :<Fem2D::R3>
+  - NoUseOfWait,  type :<bool *>
+  - P,  type :<Fem2D::R3>
+  - P0,  type :<Fem2D::TypeOfFE>
+  - P1,  type :<Fem2D::TypeOfFE>
+  - P1nc,  type :<Fem2D::TypeOfFE>
+  - P2,  type :<Fem2D::TypeOfFE>
+  - RT0,  type :<Fem2D::TypeOfFE>
+  - RTmodif,  type :<Fem2D::TypeOfFE>
+  - abs,  type :<Polymorphic>  operator() :
+   (    <double> :   <double> )
+
+  - acos,  type :<Polymorphic>   operator() :
+   (    <double> :   <double> )
+
+  - acosh,  type :<Polymorphic>   operator() :
+   (    <double> :   <double> )
+
+  - adaptmesh,  type :<Polymorphic>   operator() :
+   (    <Fem2D::Mesh> :   <Fem2D::Mesh>... )
+
+  - append,  type :<std::ios_base::openmode>
+  - asin,  type :<Polymorphic>   operator() :
+   (    <double> :   <double> )
+
+  - asinh,  type :<Polymorphic>  operator() :
+   (    <double> :   <double> )
+
+  - atan,  type :<Polymorphic>   operator() :
+   (    <double> :   <double> )
+   (    <double> :   <double>, <double> )
+
+  - atan2,  type :<Polymorphic>   operator() :
+   (    <double> :   <double>, <double> )
+
+  - atanh,  type :<Polymorphic>   operator() :
+   (    <double> :   <double> )
+
+  - buildmesh,  type :<Polymorphic>   operator() :
+   (    <Fem2D::Mesh> :   <E_BorderN> )
+
+  - buildmeshborder,  type :<Polymorphic>   operator() :
+   (    <Fem2D::Mesh> :   <E_BorderN> )
+
+  - cin,  type :<istream>
+  - clock,  type :<Polymorphic>
+   (    <double> :   )
+
+  - conj,  type :<Polymorphic>   operator() :
+   (    <complex> :   <complex> )
+
+  - convect,  type :<Polymorphic>   operator() :
+   (    <double> :   <E_Array>, <double>, <double> )
+
+  - cos,  type :<Polymorphic>  operator() :
+   (    <double> :   <double> )
+   (    <complex> :   <complex> )
+
+  - cosh,  type :<Polymorphic>   operator() :
+   (    <double> :   <double> )
+   (    <complex> :   <complex> )
+
+  - cout,  type :<ostream>
+  - dumptable,  type :<Polymorphic>   operator() :
+   (    <ostream> :   <ostream> )
+
+  - dx,  type :<Polymorphic>   operator() :
+   (    <LinearComb<MDroit, C_F0>> :   <LinearComb<MDroit, C_F0>> )
+   (    <double> :   <std::pair<FEbase<double> *, int>> )
+   (    <LinearComb<MGauche, C_F0>> :   <LinearComb<MGauche, C_F0>> )
+
+  - dy,  type :<Polymorphic>   operator() :
+   (    <LinearComb<MDroit, C_F0>> :   <LinearComb<MDroit, C_F0>> )
+   (    <double> :   <std::pair<FEbase<double> *, int>> )
+   (    <LinearComb<MGauche, C_F0>> :   <LinearComb<MGauche, C_F0>> )
+
+  - endl,  type :<char>
+  - exec,  type :<Polymorphic>   operator() :
+   (    <long> :   <string> )
+
+  - exit,  type :<Polymorphic>  operator() :
+   (    <long> :   <long> )
+
+  - exp,  type :<Polymorphic>  operator() :
+   (    <double> :   <double> )
+   (    <complex> :   <complex> )
+
+  - false,  type :<bool>
+  - imag,  type :<Polymorphic>   operator() :
+   (    <double> :   <complex> )
+
+  - int1d,  type :<Polymorphic>   operator() :
+   (    <CDomainOfIntegration> :   <Fem2D::Mesh>... )
+
+  - int2d,  type :<Polymorphic>   operator() :
+   (    <CDomainOfIntegration> :   <Fem2D::Mesh>... )
+
+  - intalledges,  type :<Polymorphic>
+   operator( :
+   (    <CDomainOfIntegration> :   <Fem2D::Mesh>... )
+
+  - jump,  type :<Polymorphic>
+   operator( :
+   (    <LinearComb<MDroit, C_F0>> :   <LinearComb<MDroit, C_F0>> )
+   (    <double> :   <double> )
+   (    <complex > :   <complex > )
+   (    <LinearComb<MGauche, C_F0>> :   <LinearComb<MGauche, C_F0>> )
+
+  - label,  type :<long *>
+  - log,  type :<Polymorphic>   operator() :
+   (    <double> :   <double> )
+   (    <complex> :   <complex> )
+
+  - log10,  type :<Polymorphic>   operator() :
+   (    <double> :   <double> )
+
+  - max,  type :<Polymorphic>   operator() :
+   (    <double> :   <double>, <double> )
+   (    <long> :   <long>, <long> )
+
+  - mean,  type :<Polymorphic>
+   operator( :
+   (    <double> :   <double> )
+   (    <complex> :   <complex> )
+
+  - min,  type :<Polymorphic>  operator() :
+   (    <double> :   <double>, <double> )
+   (    <long> :   <long>, <long> )
+
+  - movemesh,  type :<Polymorphic>   operator() :
+   (    <Fem2D::Mesh> :   <Fem2D::Mesh>, <E_Array>... )
+
+  - norm,  type :<Polymorphic>
+   operator( :
+   (    <double> :   <std::complex<double>> )
+
+  - nuTriangle,  type :<long>
+  - nuEdge,  type :<long>
+  - on,  type :<Polymorphic>   operator() :
+   (    <BC_set<double>> :   <long>... )
+
+  - otherside,  type :<Polymorphic>
+   operator( :
+   (    <LinearComb<MDroit, C_F0>> :   <LinearComb<MDroit, C_F0>> )
+   (    <LinearComb<MGauche, C_F0>> :   <LinearComb<MGauche, C_F0>> )
+
+  - pi,  type :<double>
+  - plot,  type :<Polymorphic>   operator() :
+   (    <long> :  ... )
+
+  - pow,  type :<Polymorphic>   operator() :
+   (    <double> :   <double>, <double> )
+   (    <complex> :   <complex>, <complex> )
+
+  - qf1pE,  type :<Fem2D::QuadratureFormular1d>
+  - qf1pT,  type :<Fem2D::QuadratureFormular>
+  - qf1pTlump,  type :<Fem2D::QuadratureFormular>
+  - qf2pE,  type :<Fem2D::QuadratureFormular1d>
+  - qf2pT,  type :<Fem2D::QuadratureFormular>
+  - qf2pT4P1,  type :<Fem2D::QuadratureFormular>
+  - qf3pE,  type :<Fem2D::QuadratureFormular1d>
+  - qf5pT,  type :<Fem2D::QuadratureFormular>
+
+  - readmesh,  type :<Polymorphic>   operator() :
+   (    <Fem2D::Mesh> :   <string> )
+
+  - real,  type :<Polymorphic>   operator() :
+   (    <double> :   <complex> )
+
+  - region,  type :<long *>
+  - savemesh,  type :<Polymorphic>  operator() :
+   (    <Fem2D::Mesh> :   <Fem2D::Mesh>, <string>... )
+
+  - sin,  type :<Polymorphic>   operator() :
+   (    <double> :   <double> )
+   (    <complex> :   <complex> )
+
+  - sinh,  type :<Polymorphic>   operator() :
+   (    <double> :   <double> )
+   (    <complex> :   <complex> )
+
+  - sqrt,  type :<Polymorphic>   operator() :
+   (    <double> :   <double> )
+   (    <complex> :   <complex> )
+
+  - square,  type :<Polymorphic>    operator() :
+   (    <Fem2D::Mesh> :   <long>, <long> )
+   (    <Fem2D::Mesh> :   <long>, <long>, <E_Array> )
+
+  - tan,  type :<Polymorphic>   operator() :
+   (    <double> :   <double> )
+
+  - true,  type :<bool>
+  - trunc,  type :<Polymorphic>   operator() :
+   (    <Fem2D::Mesh> :   <Fem2D::Mesh>, <bool> )
+
+  - verbosity,  type :<long *>
+  - wait,  type :<bool *>
+  - x,  type :<double *>
+  - y,  type :<double *>
+  - z,  type :<double *>
+\end{verbatim}
+
+%%%\subsection{History of the software}
+%%%{\scriptsize
+%%%\inputFF{../HISTORY}
+%%%}
+
+
+
+\begin{thebibliography}{xx}
+
+\bibitem{arpack} R. B. Lehoucq, D. C. Sorensen, and C. Yang
+{\it ARPACK Users' Guide: Solution of Large-Scale Eigenvalue Problems with Implicitly Restarted Arnoldi Methods}
+SIAM,  ISBN 0-89871-407-9 //
+ \url{http://www.caam.rice.edu/software/ARPACK/}
+
+\bibitem{Babuska71}
+Babbu\v{s}ka, I: Error bounds for finite element method, Numer. Math. 16, 322-333.
+
+\bibitem{freefemp} D. Bernardi, F.Hecht, K. Ohtsuka, O. Pironneau: {\it
+freefem+ documentation}, on the web at  ftp://www.freefem.org/freefemplus.
+
+\bibitem{freefem} D. Bernardi, F.Hecht, O. Pironneau, C. Prud'homme: {\it
+freefem documentation}, on the web at  http://www. freefem.fr/freefem
+
+
+\bibitem{umfpack}
+Davis, T. A:  {Algorithm 8xx: UMFPACK V4.1, an unsymmetric-pattern multifrontal method}
+TOMS,
+2003 (under submission)
+ \url{ http://www.cise.ufl.edu/research/sparse/umfpack}
+
+\bibitem{George}
+George, P.L: {\it Automatic triangulation}, Wiley 1996.
+
+\bibitem{bamg}
+Hecht, F: The mesh adapting software: bamg. INRIA report 1998.
+
+\bibitem{modulef}
+Library Modulef , INRIA,
+\url{http://www.inria-rocq/modulef}
+
+\bibitem{FHcpp}
+{\sc F. Hecht.}
+\newblock { C++ Tools to construct our user-level language.}
+\newblock   Vol 36, N�, 2002 pp 809-836,  Mod\'{e}l. math et Anal Num\'{e}r.
+
+\bibitem{Lions}
+J.L. Lions, O. Pironneau:
+Parallel Algorithms for boundary value problems, Note CRAS. Dec 1998.
+Also : Superpositions for composite domains (to appear)
+
+\bibitem{Lucquin} B. Lucquin, O. Pironneau: {\it Introduction to Scientific Computing}
+Wiley 1998.
+
+\bibitem{dan-hec-2003}
+I.~Danaila, F.~Hecht, and O.~Pironneau.
+\newblock {\em Simulation num\'erique en C++}.
+\newblock Dunod, Paris, 2003.
+
+\bibitem{Necas} J. Ne\v{c}as and L/ Hlav\'{a}\v{c}ek,
+Mathematical theory of elastic and elasto-plastic bodies:
+An introduction, Elsevier, 1981.
+
+\bibitem{Ohtsuka} K. Ohtsuka, O. Pironneau and F. Hecht: Theoretical and Numerical analysis of energy release rate in 2D fracture, INFORMATION \textbf{3} (2000), 303--315.
+
+\bibitem{Preparata} F. Preparata, M. Shamos; {\it Computational Geometry}
+Springer series in Computer sciences, 1984.
+
+\bibitem{Franca}R. Rannacher: On Chorin's projection method for the incompressible
+Navier-Stokes equations, in "Navier-Stokes Equations: Theory and Numerical Methods" (R.
+Rautmann, et al., eds.), Proc. Oberwolfach Conf., August 19-23, 1991, Springer, 1992
+
+\bibitem{RT93}
+Roberts, J.E. and Thomas J.-M: Mixed and Hybrid Methods, Handbook of Numerical Anaysis, Vol.II, North-Holland, 1993
+
+\bibitem{Steger} J.L. Steger: The Chimera method of flow simulation,
+Workshop on applied CFD, Univ of Tennessee Space Institute, August 1991.
+
+\bibitem{TA94}
+Tabata, M: Numerical solutions of partial differential equations II
+(in Japanese),
+Iwanami Applied Math., 1994
+
+\bibitem{Thomasset}
+Thomasset, F: Implementation of finite element methods
+of Navier-Stokes Equations, Springer-Verlag, 1981
+
+\bibitem{wirth} {\sc N. Wirth:} {\it Algorthims + Data Structures = Programs}, Prentice Hall,  1976
+
+
+\bibitem{Bison}  Bison documentation
+
+\bibitem{cpp}
+Bjarne Stroustrup:
+The \Cpp, programming language, Third edition,
+  Addison-Wesley 1997.
+
+\bibitem{coool} COOOL: a package of tools for writing optimization code and solving optimization problems,
+
+\bibitem{DGgirault}  B. Riviere, M.   Wheeler, V. Girault,
+A priori error estimates for finite element
+ methods based on discontinuous approximation spaces
+ for elliptic problems.
+  SIAM J. Numer. Anal. 39 (2001), no. 3, 902--931 (electronic).
+
+\bibitem{ItoKunisch}{\sc Kazufumi Ito,  and Karl Kunisch},
+Semi smooth newton methods for variational inequalities of the first kind ,
+M2AN, vol 37, N${}^{\circ}$, 2003, pp 41-62.
+
+\bibitem{COOLL} COOL package , \url{http://coool.mines.edu}
+
+\bibitem{0501496} {\sc M. A. Taylor,  B. A.
+Wingate  , L. P. Bos},  Several new quadrature formulas for polynomial integration in the triangle , Report-no: SAND2005-0034J,
+ \url{http://xyz.lanl.gov/format/math.NA/0501496}
+\end{thebibliography}
+\printindex
+\end{document}
diff --git a/DOC/plots/._VarIneqFill.jpg b/DOC/plots/._VarIneqFill.jpg
new file mode 100644
index 0000000..3d4ef81
Binary files /dev/null and b/DOC/plots/._VarIneqFill.jpg differ
diff --git a/DOC/plots/._VarIneqIso.jpg b/DOC/plots/._VarIneqIso.jpg
new file mode 100644
index 0000000..3d4ef81
Binary files /dev/null and b/DOC/plots/._VarIneqIso.jpg differ
diff --git a/DOC/plots/._minsurf3D.jpg b/DOC/plots/._minsurf3D.jpg
new file mode 100644
index 0000000..caef461
Binary files /dev/null and b/DOC/plots/._minsurf3D.jpg differ
diff --git a/DOC/plots/._nlopttab.pdf b/DOC/plots/._nlopttab.pdf
new file mode 100644
index 0000000..5143905
Binary files /dev/null and b/DOC/plots/._nlopttab.pdf differ
diff --git a/INNOVATION b/INNOVATION
index 65bb588..562e8a9 100644
--- a/INNOVATION
+++ b/INNOVATION
@@ -1,4 +1,34 @@
- - coorect automake TESTING part (in progress) 
+ 
+ - correct compile of load example :  paradiso, gsl automaticaly 
+ - add AutoGeneratedFile.tar.gz  a file contening all 
+    file build by autoreconf in case of non automake tools (1.13)
+ - add missing file in dist or in mercurial distribution
+ - correct download of scotch un curl 
+ - correct problem in a*[b,c, ... ]' in case of complex value   
+10/7/2013  (version 3.25)
+ - remove of Mafile.in configure for the hg distrubion 
+    use :  autoreconf -i  # too build Makefile.in 
+         before to configure 
+         need automake version 1.13 ... 
+ - merge FFCS (ALH) version and  ff++ version (FH) of freefem++ programs
+ - remove all automake file form the hg data base
+ 
+ - add new parameter to ffglut for demo of freefem++ 
+    ffglut  [-nv|-v|-vv|-vvv] [-wait 0.5] [-g 512x300+10+10] [-t title] [file]
+    all number can be change the wiat is in second 0 is default value nowait bewteew plot
+    -g 512x300+10+10 is the geometry of the  graphic window
+    -t the title of the windows 
+26/6/2013 (ALH)
+ - created a build/ subdirectory for build tools
+ - enabled parallel make ("make -j")
+ - created a separate file (acmpi.m4) for complex MPI configuration options
+ - added configuration option --enable-ffcs to make the FF source compatible with FFCS
+ - backported all current FreeFem++ patches for FreeFem++-cs into the FreeFem++
+ - started main doxygen page mainpage.dox
+9/06/2013
+ - correct extract function of mesh Lo Sala <salalo80 at gmail.com>
+ - correct int2d on levelset  see example intlevelset.edp 
+ - correct automake TESTING part (in progress) 
  - correct typo on the doc with .*= ./=  operator
  - correct bug in RT0 3d , code in the construction of the DOF.
    the bug is all dof on border  face of same elemnt have same dof number.
diff --git a/Makefile.am b/Makefile.am
index 555eaa7..43cd021 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -22,7 +22,8 @@ Install-MacOS.command.in \
 examples-bamg/NACA012/naca.awk  examples-bamg/quadloop/dotest.pl \
 examples-bamg/square/*_g.* examples-bamg/square/do* examples-bamg/NACA012/[adp]* \
 examples-bamg/test/dotest*.pl 0ldUserReadMe.txt CheckAllEdp CheckAll  \
-WHERE_LIBRARY-mkl FreeFem++-CoCoa
+WHERE_LIBRARY-mkl FreeFem++-CoCoa \
+./build/cleancrlf
 
 
 FF_MAC_PREFIX=FreeFem++v$(VERSION)$(ADD_PACKAGE_NAME)
@@ -252,3 +253,8 @@ $(PACKAGE_NAME).tgz: $(PACKAGE_NAME)
 
 clean-local::
 	-rm -r $(PACKAGE_NAME) $(PACKAGE_NAME).tgz
+autofiles:AutoGeneratedFile.tar.gz
+
+AutoGeneratedFile.tar.gz:configure List_generate_file Makefile.in configure.ac
+	tar cvfz $@  `cat List_generate_file`
+
diff --git a/Makefile.in b/Makefile.in
index 23d243c..524712f 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -65,7 +65,8 @@ DIST_COMMON = INSTALL NEWS README AUTHORS ChangeLog \
 	config.guess config.sub depcomp install-sh missing ylwrap
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/acmacros.m4 \
-	$(top_srcdir)/acoptim.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/acoptim.m4 $(top_srcdir)/acmpi.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
@@ -215,11 +216,47 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EIGENOBJ = @EIGENOBJ@
+ENABLE_FFCS = @ENABLE_FFCS@
 EPSTOPDF = @EPSTOPDF@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+FFCS_COMPILE_fflapack = @FFCS_COMPILE_fflapack@
+FFCS_COMPILE_gsl = @FFCS_COMPILE_gsl@
+FFCS_COMPILE_hips = @FFCS_COMPILE_hips@
+FFCS_COMPILE_hypre = @FFCS_COMPILE_hypre@
+FFCS_COMPILE_ipopt = @FFCS_COMPILE_ipopt@
+FFCS_COMPILE_lapack = @FFCS_COMPILE_lapack@
+FFCS_COMPILE_mmg3d = @FFCS_COMPILE_mmg3d@
+FFCS_COMPILE_mshmet = @FFCS_COMPILE_mshmet@
+FFCS_COMPILE_mumps = @FFCS_COMPILE_mumps@
+FFCS_COMPILE_mumps_seq = @FFCS_COMPILE_mumps_seq@
+FFCS_COMPILE_pardiso = @FFCS_COMPILE_pardiso@
+FFCS_COMPILE_parms = @FFCS_COMPILE_parms@
+FFCS_COMPILE_pastix = @FFCS_COMPILE_pastix@
+FFCS_COMPILE_pipe = @FFCS_COMPILE_pipe@
+FFCS_COMPILE_scotch = @FFCS_COMPILE_scotch@
+FFCS_COMPILE_superludist = @FFCS_COMPILE_superludist@
+FFCS_COMPILE_yams = @FFCS_COMPILE_yams@
+FFCS_DYLIB_fflapack = @FFCS_DYLIB_fflapack@
+FFCS_DYLIB_gsl = @FFCS_DYLIB_gsl@
+FFCS_DYLIB_hips = @FFCS_DYLIB_hips@
+FFCS_DYLIB_hypre = @FFCS_DYLIB_hypre@
+FFCS_DYLIB_ipopt = @FFCS_DYLIB_ipopt@
+FFCS_DYLIB_lapack = @FFCS_DYLIB_lapack@
+FFCS_DYLIB_mmg3d = @FFCS_DYLIB_mmg3d@
+FFCS_DYLIB_mshmet = @FFCS_DYLIB_mshmet@
+FFCS_DYLIB_mumps = @FFCS_DYLIB_mumps@
+FFCS_DYLIB_mumps_seq = @FFCS_DYLIB_mumps_seq@
+FFCS_DYLIB_pardiso = @FFCS_DYLIB_pardiso@
+FFCS_DYLIB_parms = @FFCS_DYLIB_parms@
+FFCS_DYLIB_pastix = @FFCS_DYLIB_pastix@
+FFCS_DYLIB_pipe = @FFCS_DYLIB_pipe@
+FFCS_DYLIB_scotch = @FFCS_DYLIB_scotch@
+FFCS_DYLIB_superludist = @FFCS_DYLIB_superludist@
+FFCS_DYLIB_yams = @FFCS_DYLIB_yams@
+FFCS_MAKEFLAGS = @FFCS_MAKEFLAGS@
 FFGLUTNAME = @FFGLUTNAME@
 FFGLUTPROG = @FFGLUTPROG@
 FFLAGS = @FFLAGS@
@@ -407,7 +444,8 @@ Install-MacOS.command.in \
 examples-bamg/NACA012/naca.awk  examples-bamg/quadloop/dotest.pl \
 examples-bamg/square/*_g.* examples-bamg/square/do* examples-bamg/NACA012/[adp]* \
 examples-bamg/test/dotest*.pl 0ldUserReadMe.txt CheckAllEdp CheckAll  \
-WHERE_LIBRARY-mkl FreeFem++-CoCoa
+WHERE_LIBRARY-mkl FreeFem++-CoCoa \
+./build/cleancrlf
 
 FF_MAC_PREFIX = FreeFem++v$(VERSION)$(ADD_PACKAGE_NAME)
 FF_EXAMPLES_FILES = COPYRIGHT HISTORY HISTORY_BEFORE_2005 README README_WINDOWS README_MAC BUGS TODO INSTALL INSTALL-MacOSX INNOVATION \
@@ -1088,6 +1126,10 @@ $(PACKAGE_NAME).tgz: $(PACKAGE_NAME)
 
 clean-local::
 	-rm -r $(PACKAGE_NAME) $(PACKAGE_NAME).tgz
+autofiles:AutoGeneratedFile.tar.gz
+
+AutoGeneratedFile.tar.gz:configure List_generate_file Makefile.in configure.ac
+	tar cvfz $@  `cat List_generate_file`
 
 # 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/README b/README
index 96fb01a..821b429 100644
--- a/README
+++ b/README
@@ -1,6 +1,21 @@
 Compilation of FreeFem++ under unix, MacOs X or mingw  (Windows)
 and bamg (mesh generator)
 ----------------------------------------------------------------
+REMARK:    after 4/09/2013, in hg version all 
+construct by autorecong are not on the directly in distrubution.
+
+-- to rebuild    with automake vzersion >= 1.13 autoconf :
+  # autoreconf -i
+    or take the file form the file AutoGeneratedFile.tar.gz 
+  # tar zxvf AutoGeneratedFile.tar.gz 
+
+--  to build a complete  version do
+   # ./configure --enable-download
+-- to test
+   make check
+-- to install
+   sudo make install
+
 
 New:  Test version 3.9  F. Hecht & J. Morice July  2010.
 
diff --git a/WindowsPackage.m4 b/WindowsPackage.m4
index f516e8d..8f2ab43 100644
--- a/WindowsPackage.m4
+++ b/WindowsPackage.m4
@@ -1,153 +1,153 @@
-; Creating a FreeFem++ package for Microsoft Windows with Inno Setup
-; $Id$
-
-; The Inno Setup configuration file WindowsPackage.iss is built from
-; WindowsPackage.m4 with the command "make WindowsPackage.iss".
-
-; No source file here. They are in the source tar ball.
-; suppress -cs version no fltk to day , wait the next version
-;  FH version 3.0-1
-[Setup]
-AppName=FreeFem++-VERSION
-AppVerName=FreeFem++ version VERSION
-DefaultDirName={pf}\FreeFem++
-DefaultGroupName=FreeFem++
-Compression=lzma
-SolidCompression=yes
-ChangesAssociations=yes
-OutputBaseFilename=FreeFem++-VERSION
-ChangesEnvironment=yes
-
-[Files]
-; README 
-Source: "README"; DestDir: "{app}"
-Source: "README_WINDOWS"; DestDir: "{app}"
-Source: "INNOVATION"; DestDir: "{app}"
-Source: "AUTHORS"; DestDir: "{app}"
-Source: "BUGS"; DestDir: "{app}"
-Source: "COPYRIGHT"; DestDir: "{app}"
-Source: "COPYING"; DestDir: "{app}"
-Source: "README"; DestDir: "{app}"
-Source: "crimson-freefem++.zip"; DestDir: "{app}"
-Source: "0ldUserReadMe.txt"; DestDir: "{app}"
-
-; Programs
-Source: "src\bin-win32\FreeFem++.exe"; DestDir: "{app}"
-ifelse(len(MPIPROG),0,; ,)Source: "src\bin-win32\FreeFem++-mpi.exe"; DestDir: "{app}"
-ifelse(len(MPIPROG),0,; ,)Source: "src\mpi\ff-mpirun"; DestDir: "{app}"
-Source: "src\bin-win32\launchff++.exe"; DestDir: "{app}"
-;  to day the dll version do not works so we use the static one (FH)
-;Source: "src\bin-win32\FreeFem++-cs.exe"; DestDir: "{app}"
-;Source: "src\ide\FreeFem++-cs.exe"; DestDir: "{app}"
-Source: "src\nw\ffglut.exe"; DestDir: "{app}"
-Source: "src\medit\ffmedit.exe"; DestDir: "{app}"
-Source: "src\bin-win32\FreeFem++-nw.exe"; DestDir: "{app}"
-Source: "src\bin-win32\bamg.exe"; DestDir: "{app}"
-Source: "src\bin-win32\cvmsh2.exe"; DestDir: "{app}"
-; Source: "src\bin-win32\drawbdmesh.exe"; DestDir: "{app}"
-Source: "src\bin-win32\*.dll"; DestDir: "{app}"
-Source: "examples++-load\ff-c++"; DestDir: "{app}"
-
-; mingwm10.dll is necessary when "-mthreads" is used as a compilation
-; flag.
-
-Source: "C:\MinGW\bin\mingwm10.dll"; DestDir: "{app}"
-; Source: "C:\Cygwin\bin\glut32.dll"; DestDir: "{app}"
-Source: "C:\MinGW\msys\1.0\bin\freeglut.dll"; DestDir: "{app}"
-Source: "C:\MinGW\bin\pthreadGC2.dll"; DestDir: "{app}"
-Source: "C:\MinGW\bin\libgcc_s_dw2-1.dll"; DestDir: "{app}"
-Source: "C:\MinGW\bin\libstdc++-6.dll"; DestDir: "{app}"
-Source: "C:\MinGW\bin\libgfortran-3.dll"; DestDir: "{app}"
-Source: "C:\MinGW\bin\libquadmath-0.dll"; DestDir: "{app}"
-
-
-; Does not include FreeFem++-x11 which would need the Cygwin X-Server
-; Does not include FreeFem++-glx which would need the Cygwin X-Server
-
-; Examples
-Source: "examples++\*.edp"; DestDir: "{app}\examples++"
-Source: "examples++-eigen\*.edp"; DestDir: "{app}\examples++-eigen"
-Source: "examples++-tutorial\*.edp"; DestDir: "{app}\examples++-tutorial"
-Source: "examples++-tutorial\*.idp"; DestDir: "{app}\examples++-tutorial"
-Source: "examples++-tutorial\aile.msh"; DestDir: "{app}\examples++-tutorial"
-Source: "examples++-tutorial\xyf"; DestDir: "{app}\examples++-tutorial"
-Source: "examples++-chapt3\*.edp"; DestDir: "{app}\examples++-chapt3"
-Source: "examples++-other\*.edp"; DestDir: "{app}\examples++-other"
-Source: "examples++-load\*.edp"; DestDir: "{app}\examples++-load"
-Source: "examples++-load\*.cpp"; DestDir: "{app}\examples++-load"
-Source: "examples++-load\*.pgm"; DestDir: "{app}\examples++-load"
-Source: "examples++-load\cube.msh"; DestDir: "{app}\examples++-load"
-
-Source: "examples++-load\load.link"; DestDir: "{app}\examples++-load"
-Source: "examples++-load\include-tmp\*"; DestDir: "{app}\examples++-load\include"
-Source: "examples++-3d\*.edp"; DestDir: "{app}\examples++-3d"
-Source: "examples++-3d\dodecaedre01.mesh"; DestDir: "{app}\examples++-3d"
-Source: "examples++-3d\lac-leman-v4.msh"; DestDir: "{app}\examples++-3d"
-Source: "examples++-3d\*.idp"; DestDir: "{app}\examples++-3d"
-ifelse(len(MPIPROG),0,; ,)Source: "examples++-mpi\*.idp"; DestDir: "{app}\examples++-mpi"
-ifelse(len(MPIPROG),0,; ,)Source: "examples++-mpi\ff*.txt"; DestDir: "{app}\examples++-mpi"
-ifelse(len(MPIPROG),0,; ,)Source: "examples++-mpi\*.edp"; DestDir: "{app}\examples++-mpi"
-Source: "0ldUserReadMe.txt"; DestDir: "{app}\examples++-load"
-Source: "0ldUserReadMe.txt"; DestDir: "{app}\examples++-tutorial"
-Source: "0ldUserReadMe.txt"; DestDir: "{app}\examples++-chapt3"
-Source: "0ldUserReadMe.txt"; DestDir: "{app}\examples++"
-Source: "0ldUserReadMe.txt"; DestDir: "{app}\examples++-eigen"
-
-
-
-; Documentation files may need to be copied from another machine if
-; Cygwin refuses to build them.
-
-Source: "DOC\freefem++doc.pdf"; DestDir: "{app}"
-
-; Icons for Windows can be created from a 32x32 image with icotool
-; (Linux Debian unstable), or IrfanView (Windows, not very good
-; results) or paint (Windows, save in .bmp then rename to .ico).
-
-Source: "logo.ico"; DestDir: "{app}"
-
-[Icons]
-
-; Menu
-Name: "{group}\FreeFem++"; Filename: "{app}\launchff++.exe"; IconFilename: "{app}\logo.ico"
-;Name: "{group}\FreeFem++ GUI"; Filename: "{app}\FreeFem++-cs.exe"
-Name: "{group}\PDF manual"; Filename: "{app}\freefem++doc.pdf"
-Name: "{group}\Examples\Tutorial"; Filename: "{app}\examples++-tutorial"
-Name: "{group}\Examples\chapt3"; Filename: "{app}\examples++-chapt3"
-Name: "{group}\Examples\load"; Filename: "{app}\examples++-load"
-Name: "{group}\Examples\Main"; Filename: "{app}\examples++"
-Name: "{group}\Examples\Eigenvalues"; Filename: "{app}\examples++-eigen"
-Name: "{group}\Examples\3d"; Filename: "{app}\examples++-3d"
-ifelse(len(MPIPROG),0,; ,)Name: "{group}\Examples\mpi"; Filename: "{app}\examples++-mpi"
-Name: "{group}\Uninstall FreeFem++ VERSION"; Filename: "{uninstallexe}"
-
-; Desktop
-Name: "{userdesktop}\FreeFem++ VERSION"; Filename: "{app}\FreeFem++.exe"; IconFilename: "{app}\logo.ico"
-;Name: "{userdesktop}\FreeFem++ VERSION GUI"; Filename: "{app}\FreeFem++-cs.exe"
-Name: "{userdesktop}\FreeFem++ VERSION Examples"; Filename: "{group}\Examples"
-
-
-[Registry]
-
-; Link .edp file extension to FreeFem++
-Root: HKCR; Subkey: ".edp"; ValueType: string; ValueName: ""; ValueData: "FreeFemVERSIONScript"; Flags: uninsdeletevalue
-Root: HKCR; Subkey: "FreeFemVERSIONScript"; ValueType: string; ValueName: ""; ValueData: "FreeFem++ Script"; Flags: uninsdeletekey
-Root: HKCR; Subkey: "FreeFemVERSIONScript\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\logo.ico"
-Root: HKCR; Subkey: "FreeFemVERSIONScript\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\launchff++.exe"" ""%1"""
-
-
-[Tasks]
-Name: modifypath; Description: &Add application directory to your system path (if missing you can have trouble with on-the-fly graphic ) ; Flags:  checkedonce
-; unchecked
-
-[Code]
-function ModPathDir(): TArrayOfString;
-var
-			Dir:	TArrayOfString;
-		begin
-			setArrayLength(Dir, 1)
-			Dir[0] := ExpandConstant('{app}');
-			Result := Dir;
-		end;
- #include "modpath.iss"
-
+; Creating a FreeFem++ package for Microsoft Windows with Inno Setup
+; $Id$
+
+; The Inno Setup configuration file WindowsPackage.iss is built from
+; WindowsPackage.m4 with the command "make WindowsPackage.iss".
+
+; No source file here. They are in the source tar ball.
+; suppress -cs version no fltk to day , wait the next version
+;  FH version 3.0-1
+[Setup]
+AppName=FreeFem++-VERSION
+AppVerName=FreeFem++ version VERSION
+DefaultDirName={pf}\FreeFem++
+DefaultGroupName=FreeFem++
+Compression=lzma
+SolidCompression=yes
+ChangesAssociations=yes
+OutputBaseFilename=FreeFem++-VERSION
+ChangesEnvironment=yes
+
+[Files]
+; README 
+Source: "README"; DestDir: "{app}"
+Source: "README_WINDOWS"; DestDir: "{app}"
+Source: "INNOVATION"; DestDir: "{app}"
+Source: "AUTHORS"; DestDir: "{app}"
+Source: "BUGS"; DestDir: "{app}"
+Source: "COPYRIGHT"; DestDir: "{app}"
+Source: "COPYING"; DestDir: "{app}"
+Source: "README"; DestDir: "{app}"
+Source: "crimson-freefem++.zip"; DestDir: "{app}"
+Source: "0ldUserReadMe.txt"; DestDir: "{app}"
+
+; Programs
+Source: "src\bin-win32\FreeFem++.exe"; DestDir: "{app}"
+ifelse(len(MPIPROG),0,; ,)Source: "src\bin-win32\FreeFem++-mpi.exe"; DestDir: "{app}"
+ifelse(len(MPIPROG),0,; ,)Source: "src\mpi\ff-mpirun"; DestDir: "{app}"
+Source: "src\bin-win32\launchff++.exe"; DestDir: "{app}"
+;  to day the dll version do not works so we use the static one (FH)
+;Source: "src\bin-win32\FreeFem++-cs.exe"; DestDir: "{app}"
+;Source: "src\ide\FreeFem++-cs.exe"; DestDir: "{app}"
+Source: "src\nw\ffglut.exe"; DestDir: "{app}"
+Source: "src\medit\ffmedit.exe"; DestDir: "{app}"
+Source: "src\bin-win32\FreeFem++-nw.exe"; DestDir: "{app}"
+Source: "src\bin-win32\bamg.exe"; DestDir: "{app}"
+Source: "src\bin-win32\cvmsh2.exe"; DestDir: "{app}"
+; Source: "src\bin-win32\drawbdmesh.exe"; DestDir: "{app}"
+Source: "src\bin-win32\*.dll"; DestDir: "{app}"
+Source: "examples++-load\ff-c++"; DestDir: "{app}"
+
+; mingwm10.dll is necessary when "-mthreads" is used as a compilation
+; flag.
+
+Source: "C:\MinGW\bin\mingwm10.dll"; DestDir: "{app}"
+; Source: "C:\Cygwin\bin\glut32.dll"; DestDir: "{app}"
+Source: "C:\MinGW\msys\1.0\bin\freeglut.dll"; DestDir: "{app}"
+Source: "C:\MinGW\bin\pthreadGC2.dll"; DestDir: "{app}"
+Source: "C:\MinGW\bin\libgcc_s_dw2-1.dll"; DestDir: "{app}"
+Source: "C:\MinGW\bin\libstdc++-6.dll"; DestDir: "{app}"
+Source: "C:\MinGW\bin\libgfortran-3.dll"; DestDir: "{app}"
+Source: "C:\MinGW\bin\libquadmath-0.dll"; DestDir: "{app}"
+
+
+; Does not include FreeFem++-x11 which would need the Cygwin X-Server
+; Does not include FreeFem++-glx which would need the Cygwin X-Server
+
+; Examples
+Source: "examples++\*.edp"; DestDir: "{app}\examples++"
+Source: "examples++-eigen\*.edp"; DestDir: "{app}\examples++-eigen"
+Source: "examples++-tutorial\*.edp"; DestDir: "{app}\examples++-tutorial"
+Source: "examples++-tutorial\*.idp"; DestDir: "{app}\examples++-tutorial"
+Source: "examples++-tutorial\aile.msh"; DestDir: "{app}\examples++-tutorial"
+Source: "examples++-tutorial\xyf"; DestDir: "{app}\examples++-tutorial"
+Source: "examples++-chapt3\*.edp"; DestDir: "{app}\examples++-chapt3"
+Source: "examples++-other\*.edp"; DestDir: "{app}\examples++-other"
+Source: "examples++-load\*.edp"; DestDir: "{app}\examples++-load"
+Source: "examples++-load\*.cpp"; DestDir: "{app}\examples++-load"
+Source: "examples++-load\*.pgm"; DestDir: "{app}\examples++-load"
+Source: "examples++-load\cube.msh"; DestDir: "{app}\examples++-load"
+
+Source: "examples++-load\load.link"; DestDir: "{app}\examples++-load"
+Source: "examples++-load\include-tmp\*"; DestDir: "{app}\examples++-load\include"
+Source: "examples++-3d\*.edp"; DestDir: "{app}\examples++-3d"
+Source: "examples++-3d\dodecaedre01.mesh"; DestDir: "{app}\examples++-3d"
+Source: "examples++-3d\lac-leman-v4.msh"; DestDir: "{app}\examples++-3d"
+Source: "examples++-3d\*.idp"; DestDir: "{app}\examples++-3d"
+ifelse(len(MPIPROG),0,; ,)Source: "examples++-mpi\*.idp"; DestDir: "{app}\examples++-mpi"
+ifelse(len(MPIPROG),0,; ,)Source: "examples++-mpi\ff*.txt"; DestDir: "{app}\examples++-mpi"
+ifelse(len(MPIPROG),0,; ,)Source: "examples++-mpi\*.edp"; DestDir: "{app}\examples++-mpi"
+Source: "0ldUserReadMe.txt"; DestDir: "{app}\examples++-load"
+Source: "0ldUserReadMe.txt"; DestDir: "{app}\examples++-tutorial"
+Source: "0ldUserReadMe.txt"; DestDir: "{app}\examples++-chapt3"
+Source: "0ldUserReadMe.txt"; DestDir: "{app}\examples++"
+Source: "0ldUserReadMe.txt"; DestDir: "{app}\examples++-eigen"
+
+
+
+; Documentation files may need to be copied from another machine if
+; Cygwin refuses to build them.
+
+Source: "DOC\freefem++doc.pdf"; DestDir: "{app}"
+
+; Icons for Windows can be created from a 32x32 image with icotool
+; (Linux Debian unstable), or IrfanView (Windows, not very good
+; results) or paint (Windows, save in .bmp then rename to .ico).
+
+Source: "logo.ico"; DestDir: "{app}"
+
+[Icons]
+
+; Menu
+Name: "{group}\FreeFem++"; Filename: "{app}\launchff++.exe"; IconFilename: "{app}\logo.ico"
+;Name: "{group}\FreeFem++ GUI"; Filename: "{app}\FreeFem++-cs.exe"
+Name: "{group}\PDF manual"; Filename: "{app}\freefem++doc.pdf"
+Name: "{group}\Examples\Tutorial"; Filename: "{app}\examples++-tutorial"
+Name: "{group}\Examples\chapt3"; Filename: "{app}\examples++-chapt3"
+Name: "{group}\Examples\load"; Filename: "{app}\examples++-load"
+Name: "{group}\Examples\Main"; Filename: "{app}\examples++"
+Name: "{group}\Examples\Eigenvalues"; Filename: "{app}\examples++-eigen"
+Name: "{group}\Examples\3d"; Filename: "{app}\examples++-3d"
+ifelse(len(MPIPROG),0,; ,)Name: "{group}\Examples\mpi"; Filename: "{app}\examples++-mpi"
+Name: "{group}\Uninstall FreeFem++ VERSION"; Filename: "{uninstallexe}"
+
+; Desktop
+Name: "{userdesktop}\FreeFem++ VERSION"; Filename: "{app}\FreeFem++.exe"; IconFilename: "{app}\logo.ico"
+;Name: "{userdesktop}\FreeFem++ VERSION GUI"; Filename: "{app}\FreeFem++-cs.exe"
+Name: "{userdesktop}\FreeFem++ VERSION Examples"; Filename: "{group}\Examples"
+
+
+[Registry]
+
+; Link .edp file extension to FreeFem++
+Root: HKCR; Subkey: ".edp"; ValueType: string; ValueName: ""; ValueData: "FreeFemVERSIONScript"; Flags: uninsdeletevalue
+Root: HKCR; Subkey: "FreeFemVERSIONScript"; ValueType: string; ValueName: ""; ValueData: "FreeFem++ Script"; Flags: uninsdeletekey
+Root: HKCR; Subkey: "FreeFemVERSIONScript\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\logo.ico"
+Root: HKCR; Subkey: "FreeFemVERSIONScript\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\launchff++.exe"" ""%1"""
+
+
+[Tasks]
+Name: modifypath; Description: &Add application directory to your system path (if missing you can have trouble with on-the-fly graphic ) ; Flags:  checkedonce
+; unchecked
+
+[Code]
+function ModPathDir(): TArrayOfString;
+var
+			Dir:	TArrayOfString;
+		begin
+			setArrayLength(Dir, 1)
+			Dir[0] := ExpandConstant('{app}');
+			Result := Dir;
+		end;
+ #include "modpath.iss"
+
diff --git a/acmpi.m4 b/acmpi.m4
new file mode 100644
index 0000000..10d03fe
--- /dev/null
+++ b/acmpi.m4
@@ -0,0 +1,310 @@
+# Checking wether we can produce a parallel version
+# -------------------------------------------------
+
+dnl m4_include(ax_mpi.m4)
+ff_save_path="$PATH"
+# We need to choose between mpich, openmpi  and lam for the Debian package
+AC_ARG_WITH(mpipath,[  --with-mpipath= the path of mpich under windows (no command  mpic++, ... )])
+AC_ARG_WITH(mpilibs,[  --with-mpilibs= the libs to add to c++,fc, ... (to link with c++ - ex:   -L/usr/local/lib -lmpi_f90  -lmpi_cxx -lmpi -lopen-rte -lopen-pal -lutil) ])
+AC_ARG_WITH(mpilibsc,[  --with-mpilibsc= the libs to add to c  ... (to link with cc (for pastix lib)  ex:   -L/usr/local/lib -lmpi -lopen-rte -lopen-pal -lutil) ])
+AC_ARG_WITH(mpiinc,[  --with-mpiinc= the include directory directive and preprocess directive  (no mpicc++, just use the compiler)) ])
+AC_ARG_WITH(mpi,[  --with-mpi=[yes|no|mpic++|lam|mpich|openmpi|/usr/local/bin/mpic++|... ]	or --without-mpi	Choose MPI implementation (default is mpic++)])
+if test "$with_mpi" != no ; then  
+#if test "$with_mpi" != no ; then
+#AX_MPI(with_mpi=yes, with_mpi=no)
+#fi
+
+# Default is mpic++ 
+ff_mpi_suffix="";
+if test "$with_mpi" = yes -o -z "$with_mpi" 
+then
+   ff_mpicxx=mpic++
+else 
+  case "$with_mpi" in
+ lam|mpich|openmpi)   ff_mpi_suffix=.$with_mpi;ff_mpicxx=mpic++.$with_mpi;;
+ *)  ff_mpicxx="$with_mpi" ;;
+ esac
+fi
+
+dnl AC_MSG_NOTICE([ xxxxxxxxxxxxxxxxxxxx --$with_mpilibs--]);
+if test -n "$with_mpiinc"  -a "$with_mpiinc" != no ; then
+  if test  "$with_mpi" = 'no' ; then with_mpi='yes'; fi
+  ff_MPI_INCLUDE="$with_mpiinc"
+fi
+if test -n "$with_mpilibs" -a "$with_mpilibs" != no ; then
+    ff_MPI_LIB="$with_mpilibs"
+    ff_MPI_LIBC="$with_mpilibs"
+    ff_MPI_LIBFC="$with_mpilibs"
+    MPICXX="$CXX $ff_MPI_INCLUDE"
+    MPIF77="$F77 $ff_MPI_INCLUDE"
+    MPIFC="$FC  $ff_MPI_INCLUDE"
+    MPICC="$CC  $ff_MPI_INCLUDE"
+    AC_MSG_NOTICE([   ---  set  all MPI compile to compiler:   $MPICC , $MPIF77, $MPIFC, $MPICC  ])
+fi
+
+if test -n "$with_mpilibsc" -a "$with_mpilibsc" != no ; then
+ ff_MPI_LIBC="$with_mpilibsc"
+fi
+
+AC_ARG_VAR(MPIRUN,[MPI run command ])
+AC_MSG_CHECKING(for MPIRUN)
+
+if test -z "$MPIRUN" ; then
+    AC_PATH_PROGS(MPIRUN,mpirun mpiexec mpiexec.exe,no)
+    if test "$MPIRUN" = no
+    then
+	ff_mpi=no
+    fi
+fi
+AC_MSG_RESULT($MPIRUN)
+
+AC_MSG_CHECKING(for mpipath )
+	
+if test "$with_mpi" != no -a ! -d  "$with_mpipath" -a "$ff_win32" = yes -a "$MPIRUN" != no ; then 
+#   if "$MPIRUN" != no ; tehn 
+    with_mpipath=`AS_DIRNAME(["$MPIRUN"])`
+    with_mpipath=`AS_DIRNAME(["$with_mpipath"])`
+#    else 
+#    for i in '/c/Program Files (x86)/MPICH2' '/c/Program Files/MPICH2' 'c:\Program Files (x86)\MPICH2' 'c:\Program Files\MPICH2' ; do
+#	test -d "$i" &&  with_mpipath="$i" && break 
+#    done
+#    fi
+fi
+
+dnl if test "$with_mpilibs" != "no" ; then
+dnl fi
+
+    
+if test  -d "$with_mpipath" -a "$ff_win32" = yes  ; then
+#    sed -e "s?@MPIDIR@?$with_mpipath?" -e "s?@F77@?$F77?" -e "s?@CC@?$CC?" -e "s?@CXX@?$CXX?"   -e "s?@FC@?$FC?"  <mpic++.in >mpic++
+ #   chmod a+rx mpic++ 
+  #  for i in mpicc mpif90 mpifc mpif77 ; do cp mpic++ $i; done 
+#    ff_pwd=`pwd`
+ #   with_mpi="$ff_pwd"/mpic++
+ #   MPICXX="$ff_pwd/mpic++"
+ #   MPIF77="$ff_pwd/mpif77"
+ #   MPIFC="$ff_pwd/mpif90"
+ #   MPICC="$ff_pwd/mpicc" zzzzzzzzzzz   
+    if  with_mpilibs=`which msmpi.dll` 
+    then
+	case "$ff_size_ptr"  in 
+	    4) with_mpipathlib="$with_mpipath/Lib/i386";;
+	    8) with_mpipathlib="$with_mpipath/Lib/amd64";;
+	    *) with_mpipath=no;;
+	esac
+	
+	
+	test -d "$with_mpipath/Inc" &&  ff_MPI_INCLUDE_DIR="$with_mpipath/Inc"
+	test -d "$with_mpipath/Include" &&  ff_MPI_INCLUDE_DIR="$with_mpipath/Include"
+	ff_MPI_INCLUDE="-I'$ff_MPI_INCLUDE_DIR' '-D_MSC_VER' '-D__int64=long long'"
+	with_mpiinc="$ff_MPI_INCLUDE"
+	test -z "$MPIRUN" && MPIRUN="$with_mpipath/bin/mpiexe.exe"
+	ff_MPI_LIBC="$with_mpilibs"
+	ff_MPI_LIB="$with_mpilibs"
+	ff_MPI_LIBFC="$with_mpilibs"
+	test -z "$MPICXX" && MPICXX="$CXX $ff_MPI_INCLUDE"
+	test -z "$MPIF77" && MPIF77="$F77 $ff_MPI_INCLUDE"
+	test -z "$MPIFC"  && MPIFC="$FC  $ff_MPI_INCLUDE"
+	test -z "$MPICC"  && MPICC="$CC  $ff_MPI_INCLUDE"
+    else
+	echo " #### no msmpi.dll  => no mpi under windows .... (FH) " >&AS_MESSAGE_LOG_FD
+	echo " #### no msmpi.dll  => no mpi under windows .... (FH) " >&AS_MESSAGE_FD
+	with_mpipath=no
+	with_mpi=no
+    fi
+else 
+    with_mpipath=no	   
+fi
+
+
+AC_MSG_RESULT($ff_mpi_path)
+
+
+
+
+dnl  correct ff_mpi_path august 2010 -- FH ...  
+
+
+ff_save_cxx="$CXX"
+ff_save_libs="$LIBS"
+
+
+if test "$with_mpi" != no
+then
+	ff_mpi_path=`AS_DIRNAME(["$MPIRUN"])`
+dnl	echo "ff_mpi_path '$ff_mpi_path' .............."
+	case "$ff_mpi_path" in
+	    .|"") ff_mpi_path="$PATH";ff_defmpicxx="$ff_mpicxx";;
+	    *) ff_mpi_path="$ff_mpi_path";ff_defmpicxx=`expr "//$ff_mpicxx" : '.*/\(.*\)'`;; 
+dnl if also  add $PATH they  could be missing some different mpi version... 
+	esac	 
+	AC_ARG_VAR(MPICXX,[MPI C++ compiler command])
+	if test -z "$MPICXX" ; then
+	    AC_PATH_PROGS(MPICXX,$ff_defmpicxx mpic++$ff_mpi_suffix mpicxx$ff_mpi_suffix mpiCC$ff_mpi_suffix mpCC hcp mpxlC mpxlC_r cmpic++,no,$ff_mpi_path)
+	    AC_MSG_CHECKING(for MPICXX)
+	fi
+	ff_mpicxx="eval $MPICXX"
+	CXX=$ff_mpicxx
+	LIBS="$LIBS $ff_MPI_LIB"
+	
+	AC_LINK_IFELSE(
+[AC_LANG_SOURCE([
+#include <mpi.h>
+#include <stdio.h>
+int main(int argc,char **argv){
+  char name[[BUFSIZ]];
+  int length;
+  
+  MPI_Init(&argc, &argv);
+  MPI_Get_processor_name(name, &length);
+  printf("%s: hello world\n", name);
+  MPI_Finalize();
+  return 0;
+}])],
+ff_mpi=yes,
+ff_mpi=no)
+	AC_MSG_RESULT($ff_mpi)
+
+	# Also check that mpirun is there. If it isn't, then MPI is
+	# not fully installed.
+
+
+	if test "$ff_mpi" = yes;
+	then
+
+AC_MSG_CHECKING( MPI_DOUBLE_COMPLEX)
+
+	AC_COMPILE_IFELSE(
+[AC_LANG_SOURCE([
+#include <mpi.h>
+MPI_Datatype xxxx=MPI_DOUBLE_COMPLEX;
+])],
+ff_mpi_double_complex=yes,
+ff_mpi_double_complex=no)
+	AC_MSG_RESULT($ff_mpi_double_complex)
+if test "$ff_mpi_double_complex" = yes  ; then
+AC_DEFINE(HAVE_MPI_DOUBLE_COMPLEX,1, mpi_double_complex)
+fi
+
+
+	  echo "MPI CC $ff_mpi" >config_LIB_INFO
+
+		# We do not AC_DEFINE any special flag for parallel
+		# computation here, because it must only be set when the
+ 		# parallel program is compiled (see src/mpi/Makfile.am)
+		ff_mpiprog="FreeFem++-mpi${EXEEXT}"
+   		  AC_SUBST(MPIPROG,"$ff_mpiprog")
+   		  AC_SUBST(MPISCRIPT,"ff-mpirun")
+   		  AC_SUBST(MPIRUN,$MPIRUN)
+                  AC_SUBST(MPICXX,$MPICXX)
+	else
+	        AC_SUBST(MPICXX,$ff_save_cxx)
+	fi
+
+	if test "$ff_mpi" = yes;
+	then
+	  if test "$enable_fortran" != no
+	  then	
+	      
+	      AC_ARG_VAR(MPIF77,[MPI Fortran 77 compiler command])
+	      if test -z "$MPIF77" ; then    
+		  AC_PATH_PROGS(MPIF77, mpif90$ff_mpi_suffix mpif77$ff_mpi_suffix hf77 mpxlf mpf77 mpif90 mpf90 mpxlf90 mpxlf95 mpxlf_r cmpifc cmpif90c, "",$ff_mpi_path)
+	      fi
+	      AC_SUBST(MPIF77)
+	      AC_ARG_VAR(MPIFC,[MPI Fortran 90  compiler command])
+	      if test -z "$MPIFC" ; then
+		  AC_PATH_PROGS(MPIFC, mpif90$ff_mpi_suffix mpxlf95_r mpxlf90_r mpxlf95 mpxlf90 mpf90 cmpif90c, "",$ff_mpi_path)
+	      fi		
+	      AC_SUBST(MPIFC)
+	  fi
+
+
+	ff_MPI_INCLUDE="$with_mpiinc"
+        ff_mpishow=`$MPICXX -show` 2>/dev/null
+        ff_mpicshow=`$MPICC -show` 2>/dev/null
+        ff_mpifcshow=`$MPIFC -show` 2>/dev/null
+	if test "$with_mpilibs" = no -o -z "$with_mpilibs" ; then	 
+	      [ff_MPI_INCLUDE=`echo $ff_mpishow|tr ' ' '\n'| grep -E '^-[^WLlOgp]|^-Wp,'|tr '\n' ' '`]
+	      ff_MPI_LIB_DIRS=""
+	      [ff_MPI_LIB=`echo $ff_mpishow|tr ' ' '\n'| grep -E '^-[Llp]|^-Wl,'|tr '\n' ' '`]
+	      [ff_MPI_LIBC=`echo $ff_mpicshow|tr ' ' '\n'| grep -E '^-[Llp]|^-Wl,'|tr '\n' ' '`]
+	      [ff_MPI_LIBFC=`echo $ff_mpifcshow|tr ' ' '\n'| grep -E '^-[Llp]|^-Wl,'|grep -v 'commons,use_dylibs' |tr '\n' ' '`]
+	      [ff_mpi_idir=`echo $ff_mpishow|tr ' ' '\n'| grep -E '^-I'|sed s/^-I//|tr '\n' ' '`' /usr/include']
+	  fi
+	    [ff_mpi_idir=`echo $ff_MPI_INCLUDE|tr ' ' '\n'| grep -E '^-I'|sed s/^-I//|tr '\n' ' '`' /usr/include']
+	    [ff_mpi_ldir=`echo $ff_MPI_LIB|tr ' ' '\n'| grep -E '^-[Llp]|^-Wl,'|sed -e 's/^-[Llp]//' -e 's/^-Wl,]//'  |tr '\n' ' '`' /usr/lib']
+	  
+	  if  test -z "$ff_MPI_INCLUDE_DIR" ; then  
+	  for i in $ff_mpi_idir; do
+	      if test -f "$i/mpi.h" -a -z "$ff_MPI_INCLUDE_DIR"  ;then
+		  ff_MPI_INCLUDE_DIR=$i
+	      fi
+	  done
+	  fi
+	  for i in $ff_mpi_ldir; do
+	      ff_tmp=`ls $i/libmpi.*|head -1`
+	      if test  -f "$ff_tmp"  -a -z "$ff_MPI_LIB_DIRS"  ;then
+		  ff_MPI_LIB_DIRS=$i
+	      fi
+	      done
+	  
+	  AC_SUBST(MPICXX,$MPICXX)		
+	  AC_ARG_VAR(MPICC,[MPI C compiler command in $ff_mpi_path])
+	  if test -z "$MPICC" ; then		
+	      AC_PATH_PROGS(MPICC,mpicc$ff_mpi_suffix hcc mpcc mpcc_r mpxlc cmpicc, "",$ff_mpi_path)
+	  fi
+	  AC_SUBST(MPICC,$MPICC)
+	  AC_SUBST(PASTIX_HOSTARCH,$ff_HOSTARCH_pastix)
+
+	  if test ! -f "$ff_MPI_INCLUDE_DIR/mpif.h"  ; then
+	      AC_MSG_NOTICE([ MPI without fortran no file "$ff_MPI_INCLUDE_DIR/mpif.h"  ])
+	  else
+	      if test -n "$MPIFC" ; then
+	           AC_FF_ADDWHERELIB(mpifc,$ff_MPI_LIBFC,$ff_MPI_INCLUDE)
+	           AC_FF_ADDWHERELIB(mpif77,$ff_MPI_LIBFC,$ff_MPI_INCLUDE)
+dnl		  [echo mpifc LD "'$ff_MPI_LIBFC'"   >>$ff_where_lib_conf ]
+dnl		  [echo mpifc INCLUDE "'$ff_MPI_INCLUDE'" >>$ff_where_lib_conf ]
+dnl		  [echo mpif77 LD "'$ff_MPI_LIBFC'"   >>$ff_where_lib_conf ]
+dnl		  [echo mpif77 INCLUDE "'$ff_MPI_INCLUDE'" >>$ff_where_lib_conf ]
+	      fi
+  	  fi
+	  if test -n "$MPICXX" ; then 	    
+              AC_FF_ADDWHERELIB(mpi,$ff_MPI_LIB,$ff_MPI_INCLUDE)
+dnl              [echo mpi LD "'$ff_MPI_LIB'"    >>$ff_where_lib_conf ]
+dnl              [echo mpi INCLUDE "'$ff_MPI_INCLUDE'" >>$ff_where_lib_conf ]
+	  fi
+	  AC_SUBST(MPI_INC_DIR,$ff_MPI_INCLUDE_DIR)      		
+	  AC_SUBST(MPI_INCLUDE,$ff_MPI_INCLUDE)
+	  AC_SUBST(MPI_LIB_DIRS,$ff_MPI_LIB_DIRS)
+	  AC_SUBST(MPI_LIB,$ff_MPI_LIB)
+	  AC_SUBST(MPI_LIBC,$ff_MPI_LIBC)
+	  AC_SUBST(MPI_LIBFC,$ff_MPI_LIBFC)
+          AC_SUBST(SKIP_TESTS_MPI,"no")
+	fi
+	CXX="$ff_save_cxx"
+	LIBS="$ff_save_libs"
+fi
+fi
+##  clean on MPI variable if not MPI ...
+if test "$ff_mpi" != yes ; then
+          
+	  AC_SUBST(MPIRUN,"")      		
+	  AC_SUBST(MPICC,"")      		
+	  AC_SUBST(MPICXX,"")      		
+	  AC_SUBST(MPIF77,"")      		
+	  AC_SUBST(MPIFC,"")      		
+	  AC_SUBST(MPI_INCLUDE,"")
+	  AC_SUBST(MPI_LIB_DIRS,"")
+	  AC_SUBST(MPI_LIB,"")
+	  AC_SUBST(MPI_LIBC,"")
+	  AC_SUBST(MPI_LIBFC,"")
+          AC_SUBST(SKIP_TESTS_MPI,"yes")
+	  ff_mpi=no
+
+fi
+
+# Local Variables:
+# mode:shell-script
+# ispell-local-dictionary:"british"
+# coding:utf-8
+# End:
diff --git a/acoptim.m4 b/acoptim.m4
index 2665e7d..88b52e3 100644
--- a/acoptim.m4
+++ b/acoptim.m4
@@ -83,14 +83,19 @@ fi
 AC_ARG_ENABLE(generic,
 [  --enable-generic	Turn off hardware-dependant optimization options])
 
-# Generic code
-if test "$enable_debug" != yes \
-    -a "$enable_optim" != no \
-    -a "$enable_generic" = yes
+# FFCS: remove "-mcpu=common" to allow other hardware-dependant values of cpu for PowerPC - thank you Fred (20/02/11)
+
+if test $enable_ffcs = yes
 then
+    # Generic code
+    if test "$enable_debug" != yes \
+	-a "$enable_optim" != no \
+	-a "$enable_generic" = yes
+    then
 	CHECK_COMPILE_FLAG(C,-mcpu=common,CFLAGS)
 	CHECK_COMPILE_FLAG(C++,-mcpu=common,CXXFLAGS)
 	CHECK_COMPILE_FLAG(Fortran 77,-mcpu=common,FFLAGS)
+    fi
 fi
 
 # Hardware-dependant optimization
diff --git a/build/cleancrlf b/build/cleancrlf
new file mode 100755
index 0000000..fcd62a5
--- /dev/null
+++ b/build/cleancrlf
@@ -0,0 +1,54 @@
+#!/usr/bin/perl
+# ======================================================================
+# Laboratoire Jacques-Louis Lions
+# Université Pierre et Marie Curie-Paris6, UMR 7598, Paris, F-75005 France
+# http://www.ljll.math.upmc.fr/lehyaric
+# ======================================================================
+# This file is part of Freefem++
+#
+# Freefem++ is free software; you can redistribute 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.
+#
+# Freefem++  is distributed in the hope that it will be useful,
+# 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 Freefem++; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+# 02110-1301 USA
+# ======================================================================
+# headeralh default=0 freefem perl start=04/06/2012 upmc
+
+# clean-up all CR/LF line endings (usually before patching to avoid failures after editing the same source files on
+# different systems)
+
+use strict;
+
+# change files that have been recorded in FF using DOS line endings
+my @files=`find $ARGV[0] -type f`;
+chomp @files;
+foreach my $file(@files){
+  next if $file=~/\.(jpg|eps|mcp|pdf|pgm|o|a|so|png|jpg|gz|tgz)$/;
+  next if $file=~/\.hg\//;
+  my $contents=`cat $file`;
+  my $oldcontents=$contents;
+
+  # changing line-ending conventions. all ffcs patches work from unix-style (ie no CR) files
+
+  $contents=~s/\r$//gm;
+  next if $contents eq $oldcontents;
+  print "cleancrlf: Unix line-ending for $file...\n";
+  open FILE,">$file" or die;
+  print FILE $contents;
+  close FILE;
+}
+
+# Local Variables:
+# mode:cperl
+# ispell-local-dictionary:"british"
+# coding:utf-8
+# End:
diff --git a/config-wrapper.h b/config-wrapper.h
index 8ee0e4c..b8b65ee 100755
--- a/config-wrapper.h
+++ b/config-wrapper.h
@@ -1,18 +1,18 @@
-// Include a platform-specific configuration file
-// ----------------------------------------------
-
-// $Id$
-
-// This wrapper is necessary for platforms where the configure script
-// does not run.
-
-#ifndef CONFIG_WRAPPER_H
-#define CONFIG_WRAPPER_H
-
-#ifdef __MWERKS__
-#include "config-macos9.h"
-#else
-#include <config.h>
-#endif
-
-#endif // CONFIG_WRAPPER_H
+// Include a platform-specific configuration file
+// ----------------------------------------------
+
+// $Id$
+
+// This wrapper is necessary for platforms where the configure script
+// does not run.
+
+#ifndef CONFIG_WRAPPER_H
+#define CONFIG_WRAPPER_H
+
+#ifdef __MWERKS__
+#include "config-macos9.h"
+#else
+#include <config.h>
+#endif
+
+#endif // CONFIG_WRAPPER_H
diff --git a/config.h.in b/config.h.in
index 6c05317..2db4962 100644
--- a/config.h.in
+++ b/config.h.in
@@ -1,5 +1,8 @@
 /* config.h.in.  Generated from configure.ac by autoheader.  */
 
+/* build FreeFem++ for use by FreeFem++-cs */
+#undef ENABLE_FFCS
+
 /* Define to dummy `main' function (if any) required to link to the Fortran
    libraries. */
 #undef F77_DUMMY_MAIN
@@ -77,6 +80,9 @@
 /* Define to 1 if you have the `dl' library (-ldl). */
 #undef HAVE_LIBDL
 
+/* Define to 1 if you have the `m' library (-lm). */
+#undef HAVE_LIBM
+
 /* UMFPACK */
 #undef HAVE_LIBUMFPACK
 
diff --git a/configure b/configure
index 5023bc0..384bc24 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for FreeFem++ 3.23.
+# Generated by GNU Autoconf 2.69 for FreeFem++ 3.25.
 #
 # Report bugs to <hecht at ann.jussieu.fr>.
 #
@@ -580,8 +580,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='FreeFem++'
 PACKAGE_TARNAME='freefem++'
-PACKAGE_VERSION='3.23'
-PACKAGE_STRING='FreeFem++ 3.23'
+PACKAGE_VERSION='3.25'
+PACKAGE_STRING='FreeFem++ 3.25'
 PACKAGE_BUGREPORT='hecht at ann.jussieu.fr'
 PACKAGE_URL=''
 
@@ -625,6 +625,12 @@ ac_subst_vars='am__EXEEXT_FALSE
 am__EXEEXT_TRUE
 LTLIBOBJS
 LIBOBJS
+FFCS_WINDOWS_FALSE
+FFCS_WINDOWS_TRUE
+FFCS_DYLIB_pardiso
+FFCS_COMPILE_pardiso
+FFCS_DYLIB_gsl
+FFCS_COMPILE_gsl
 TEST_FFPPMPI
 TEST_FFPP
 IDE_TESTS
@@ -638,6 +644,36 @@ FNOFLAGS
 CNOFLAGS
 LIBC_VERSION
 KERNEL_VERSION
+FFCS_DYLIB_pipe
+FFCS_COMPILE_pipe
+FFCS_DYLIB_yams
+FFCS_COMPILE_yams
+FFCS_DYLIB_superludist
+FFCS_COMPILE_superludist
+FFCS_DYLIB_scotch
+FFCS_COMPILE_scotch
+FFCS_DYLIB_pastix
+FFCS_COMPILE_pastix
+FFCS_DYLIB_parms
+FFCS_COMPILE_parms
+FFCS_DYLIB_mumps_seq
+FFCS_COMPILE_mumps_seq
+FFCS_DYLIB_mumps
+FFCS_COMPILE_mumps
+FFCS_DYLIB_mshmet
+FFCS_COMPILE_mshmet
+FFCS_DYLIB_mmg3d
+FFCS_COMPILE_mmg3d
+FFCS_DYLIB_lapack
+FFCS_COMPILE_lapack
+FFCS_DYLIB_ipopt
+FFCS_COMPILE_ipopt
+FFCS_DYLIB_hypre
+FFCS_COMPILE_hypre
+FFCS_DYLIB_hips
+FFCS_COMPILE_hips
+FFCS_DYLIB_fflapack
+FFCS_COMPILE_fflapack
 FLTK_CONFIG
 FLTK_CONFIG_PARAM
 FLTK_VERSION
@@ -691,6 +727,8 @@ DOWNLOADCOMPILE
 WGET
 ff_curl
 ff_wget
+FFCS_MPIOK_FALSE
+FFCS_MPIOK_TRUE
 SKIP_TESTS_MPI
 MPI_LIBFC
 MPI_LIBC
@@ -741,6 +779,9 @@ F77
 ac_ct_FC
 FCFLAGS
 FC
+ENABLE_FFCS_FALSE
+ENABLE_FFCS_TRUE
+ENABLE_FFCS
 SIZEOF_PTRINBIT
 SIZEOF_PTR
 SIZEOF_INT
@@ -774,6 +815,7 @@ CC
 MAINT
 MAINTAINER_MODE_FALSE
 MAINTAINER_MODE_TRUE
+FFCS_MAKEFLAGS
 RANLIB
 AM_BACKSLASH
 AM_DEFAULT_VERBOSITY
@@ -876,6 +918,23 @@ with_amd
 with_umfpack
 enable_static
 enable_pdf
+enable_fflapack
+enable_hips
+enable_hypre
+enable_ipopt
+enable_lapack
+enable_mmg3d
+enable_mshmet
+enable_mumps
+enable_mumps_seq
+enable_parms
+enable_pastix
+enable_scotch
+enable_superludist
+enable_yams
+enable_pipe
+enable_gsl
+enable_pardiso
 '
       ac_precious_vars='build_alias
 host_alias
@@ -1440,7 +1499,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures FreeFem++ 3.23 to adapt to many kinds of systems.
+\`configure' configures FreeFem++ 3.25 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1510,7 +1569,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of FreeFem++ 3.23:";;
+     short | recursive ) echo "Configuration of FreeFem++ 3.25:";;
    esac
   cat <<\_ACEOF
 
@@ -1527,6 +1586,7 @@ Optional Features:
                           do not reject slow dependency extractors
   --disable-dependency-tracking
                           speeds up one-time build
+  --enable-ffcs	build FreeFem++ for use by FreeFem++-cs
   --disable-fortran	No Fortran compiler available ( ARPACK need it)
   --disable-c		No C compiler available (C BLAS need it)
   --disable-default-fltk	Does not use default FLTK
@@ -1542,6 +1602,23 @@ Optional Features:
   --enable-download	Download missing libraries (BLAS,ARPACK,UMFPACK,FLTK)
   --enable-static	Build binaries with no shared library dependencies
   --disable-pdf	Disable PDF documentation building
+  --disable-fflapack      Do not download fflapack
+  --disable-hips      Do not download hips
+  --disable-hypre      Do not download hypre
+  --disable-ipopt      Do not download ipopt
+  --disable-lapack      Do not download lapack
+  --disable-mmg3d      Do not download mmg3d
+  --disable-mshmet      Do not download mshmet
+  --disable-mumps      Do not download mumps
+  --disable-mumps_seq      Do not download mumps_seq
+  --disable-parms      Do not download parms
+  --disable-pastix      Do not download pastix
+  --disable-scotch      Do not download scotch
+  --disable-superludist      Do not download superludist
+  --disable-yams      Do not download yams
+  --disable-pipe      Do not download pipe
+  --disable-gsl      Do not download gsl
+  --disable-pardiso      Do not download pardiso
 
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
@@ -1656,7 +1733,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-FreeFem++ configure 3.23
+FreeFem++ configure 3.25
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2510,7 +2587,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by FreeFem++ $as_me 3.23, which was
+It was created by FreeFem++ $as_me 3.25, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2860,7 +2937,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 
- # Automake 1.4 is too old
+ # Automake 1.11 is too old for check ...
 am__api_version='1.13'
 
 ac_aux_dir=
@@ -3376,7 +3453,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='freefem++'
- VERSION='3.23'
+ VERSION='3.25'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -3549,6 +3626,11 @@ else
 fi
 
 
+# FFCS - parallel make options (see [[file:../../configure/ac::FFCS_MAKEFLAGS]])
+
+FFCS_MAKEFLAGS=$FFCS_MAKEFLAGS
+
+
 ff_where_lib_conf=examples++-load/WHERE_LIBRARY-config
 
 
@@ -5117,6 +5199,32 @@ $as_echo "$as_me:  fatal error : sizeof pointer $ff_size_ptr !  or no c++ compil
   as_fn_error $? " Sorry  sizeof c++ pointer $ff_size_ptr are not  4 or 8 " "$LINENO" 5
 fi
 
+# FFCS - build the code for FreeFem++-cs
+# Check whether --enable-fortran was given.
+if test "${enable_fortran+set}" = set; then :
+  enableval=$enable_fortran;
+fi
+
+if test "$enable_ffcs" = yes
+then
+
+cat >>confdefs.h <<_ACEOF
+#define ENABLE_FFCS $enable_ffcs
+_ACEOF
+
+else
+	enable_ffcs=no
+fi
+ENABLE_FFCS="$enable_ffcs"
+
+ if test $enable_ffcs = yes; then
+  ENABLE_FFCS_TRUE=
+  ENABLE_FFCS_FALSE='#'
+else
+  ENABLE_FFCS_TRUE='#'
+  ENABLE_FFCS_FALSE=
+fi
+
 
 # dur dur car sous MacOsX le fortran n'est pas standard.
 ff_AR="ar"
@@ -5131,12 +5239,14 @@ fi
 ff_g2c_lib="";
 if test "$enable_fortran" != no
 then
+
+    # ALH-FFCS-2/3/10: add gfortran-mp-4.4 for MacPorts on MacOS 10.6
     ac_ext=${ac_fc_srcext-f}
 ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
 ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_fc_compiler_gnu
 if test -n "$ac_tool_prefix"; then
-  for ac_prog in gfortran  f90  xlf90 g95
+  for ac_prog in gfortran  f90  xlf90 g95 gfortran-mp-4.4
   do
     # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
@@ -5180,7 +5290,7 @@ fi
 fi
 if test -z "$FC"; then
   ac_ct_FC=$FC
-  for ac_prog in gfortran  f90  xlf90 g95
+  for ac_prog in gfortran  f90  xlf90 g95 gfortran-mp-4.4
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
@@ -5347,7 +5457,7 @@ ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
 ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_f77_compiler_gnu
 if test -n "$ac_tool_prefix"; then
-  for ac_prog in gfortran  f90 xlf xlf90 g95 f77 fort77 "$FC"
+  for ac_prog in gfortran f90 xlf xlf90 g95 f77 fort77 "$FC" gfortran-mp-4.4
   do
     # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
@@ -5391,7 +5501,7 @@ fi
 fi
 if test -z "$F77"; then
   ac_ct_F77=$F77
-  for ac_prog in gfortran  f90 xlf xlf90 g95 f77 fort77 "$FC"
+  for ac_prog in gfortran f90 xlf xlf90 g95 f77 fort77 "$FC" gfortran-mp-4.4
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
@@ -5553,6 +5663,7 @@ ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
 
+
 #	if test -n "$F77"
 #	then
     ff_flibs=""
@@ -7755,7 +7866,13 @@ ff_uname=`uname`
 ff_mingw=no
 case $ff_uname in
     CYGWIN*)
-	ff_nocygwin=-mno-cygwin;
+
+    	# FFCS - 17/1/12 - -mno-cygwin is not recognised by the latest version of mingw32
+	if test $enable_ffcs = no
+	then
+	    ff_nocygwin=-mno-cygwin
+	fi
+
 	GCCNOCYGWIN=$ff_nocygwin
 ;;
     MINGW*)
@@ -7766,20 +7883,44 @@ CYGWIN*|MINGW*)
 
 	ff_suffix_dylib="dll";
         ff_win32=yes;
-	FFMETIS_CFLAGS="-D__VC__ -D_MSC_VER"
+
+	# FFCS - 8/3/12 - remove -D_MSC_VER under MinGW64 because it forces system calls to be compiled into any object
+	# (which creates thousands of duplicate definitions for sytem calls like time()).
+
+	if test $enable_ffcs = yes
+	then
+	    FFMETIS_CFLAGS="-D__VC__"
+
+	else
+	    FFMETIS_CFLAGS="-D__VC__ -D_MSC_VER"
+
+	fi
 
 	# We need Mingw to avoid Cygwin's extra DLLs
 	if test "$enable_cygwindll" != yes
 	then
 # 	        CHECK_COMPILE_FLAG(C++,-mwindows,CXXFLAGS)
 	        ff_glut_ok=yes
+
+		# FFCS: on Windows, FF crashes when compiling GL/glut.h and the option "--disable-opengl" is not
+		# operational because ff_glut_ok is forced to yes here.
+		if test $enable_ffcs = yes
+		then
+	            ff_glut_ok=no
+		    enable_opengl=no
+		fi
+
                 ff_mingw=yes
                 enable_cygwindll=no;
-		#ff_pthread="-mthread"
-		CXXFLAGS="$CXXFLAGS $ff_nocygwin -I/usr/include/mingw"
-		FFLAGS="$FFLAGS $ff_nocygwin"
-		CFLAGS="$CFLAGS $ff_nocygwin -I/usr/include/mingw"
-                cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+		ff_pthread="-mthreads"
+
+		# FFCS does not use the Cygwin MinGW compilers any more
+		if test $enable_ffcs = no
+		then
+		    CXXFLAGS="$CXXFLAGS $ff_nocygwin -I/usr/include/mingw"
+		    FFLAGS="$FFLAGS $ff_nocygwin"
+		    CFLAGS="$CFLAGS $ff_nocygwin -I/usr/include/mingw"
+                    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 int a;
 _ACEOF
@@ -7787,25 +7928,33 @@ if ac_fn_cxx_try_compile "$LINENO"; then :
 
 else
   ff_nocygwin="";
-		     { $as_echo "$as_me:${as_lineno-$LINENO}: Sorry $ff_nocygwin optio is wrong try whitout , but try with gcc-3.3" >&5
+			    { $as_echo "$as_me:${as_lineno-$LINENO}: Sorry $ff_nocygwin optio is wrong try whitout , but try with gcc-3.3" >&5
 $as_echo "$as_me: Sorry $ff_nocygwin optio is wrong try whitout , but try with gcc-3.3" >&6;}
 
 fi
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-		CXXFLAGS="$CXXFLAGS $ff_nocygwin -I/usr/include/mingw"
-		FFLAGS="$FFLAGS $ff_nocygwin"
-		CFLAGS="$CFLAGS $ff_nocygwin -I/usr/include/mingw"
-		CNOFLAGS="$CNOFLAGS $ff_nocygwin -I/usr/include/mingw"
+		    CXXFLAGS="$CXXFLAGS $ff_nocygwin -I/usr/include/mingw"
+		    FFLAGS="$FFLAGS $ff_nocygwin"
+		    CFLAGS="$CFLAGS $ff_nocygwin -I/usr/include/mingw"
+		    CNOFLAGS="$CNOFLAGS $ff_nocygwin -I/usr/include/mingw"
+		fi
+
 		LIBS="$LIBS $ff_nocygwin -mthreads -lws2_32 -lcomdlg32"
 		LIBSNOCONSOLE="-mwindows"
-		test -z "$MPIRUN" &&  MPIRUN=`which mpiexe.exe`
-		if test "$enable_fortran" != no  -o  "$with_flib" != no ;   then
-		    case "$F77" in
-	 		*gfortran) FLIBS="$ff_nocygwin -lgfortran";;
-	 		*g77) FLIBS="$ff_nocygwin -lg2c";;
-			*)   as_fn_error $? " Sorry no known FLIBS with this $F77  !" "$LINENO" 5 ;;
-		    esac
+
+		# FFCS uses a specific compiler, so we specify its libraries explicitely
+		if test $enable_ffcs = no
+		then
+		    test -z "$MPIRUN" &&  MPIRUN=`which mpiexe.exe`
+		    if test "$enable_fortran" != no  -o  "$with_flib" != no ;   then
+			case "$F77" in
+	 		    *gfortran) FLIBS="$ff_nocygwin -lgfortran";;
+	 		    *g77) FLIBS="$ff_nocygwin -lg2c";;
+			    *)   as_fn_error $? " Sorry no known FLIBS with this $F77  !" "$LINENO" 5 ;;
+			esac
+		    fi
 		fi
+
                 ff_glutname="glut32"
 		#  check abort a existing function just to find in glut32.dll exist in the path
 		#  because glutInit is not the real symbol on win32 dur dur FH !!!!!!!!!
@@ -8998,11 +9147,15 @@ if test "${enable_generic+set}" = set; then :
 fi
 
 
-# Generic code
-if test "$enable_debug" != yes \
-    -a "$enable_optim" != no \
-    -a "$enable_generic" = yes
+# FFCS: remove "-mcpu=common" to allow other hardware-dependant values of cpu for PowerPC - thank you Fred (20/02/11)
+
+if test $enable_ffcs = yes
 then
+    # Generic code
+    if test "$enable_debug" != yes \
+	-a "$enable_optim" != no \
+	-a "$enable_generic" = yes
+    then
 	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler accepts -mcpu=common" >&5
 $as_echo_n "checking whether the C compiler accepts -mcpu=common... " >&6; }
 	check_save_flags="$CFLAGS"
@@ -9158,6 +9311,7 @@ ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ex
 ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
 
 
+    fi
 fi
 
 # Hardware-dependant optimization
@@ -10883,6 +11037,13 @@ $as_echo "yes" >&6; }
 
 # Checking wether we can produce a parallel version
 # -------------------------------------------------
+
+if test $enable_ffcs = no
+then
+    # FF case
+    # Checking wether we can produce a parallel version
+# -------------------------------------------------
+
 ff_save_path="$PATH"
 # We need to choose between mpich, openmpi  and lam for the Debian package
 
@@ -11533,12 +11694,15 @@ $as_echo "$as_me:     -- do not add mpi : $ff_MPI_LIB $ff_MPI_INCLUDE in  $ff_wh
 
 	  MPI_LIBFC=$ff_MPI_LIBFC
 
+          SKIP_TESTS_MPI="no"
+
 	fi
 	CXX="$ff_save_cxx"
 	LIBS="$ff_save_libs"
 fi
-
-else
+fi
+##  clean on MPI variable if not MPI ...
+if test "$ff_mpi" != yes ; then
 
 	  MPIRUN=""
 
@@ -11560,12 +11724,154 @@ else
 
 	  MPI_LIBFC=""
 
-          SKIP_TESTS_MPI=yes
+          SKIP_TESTS_MPI="yes"
 
 	  ff_mpi=no
 
 fi
-#export PATH="$ff_save_path"
+
+# Local Variables:
+# mode:shell-script
+# ispell-local-dictionary:"british"
+# coding:utf-8
+# End:
+
+else
+    # FFCS - use the same MPI configuration choices as FFCS
+    ff_mpi=yes
+    MPICXX=$MPICXX
+
+    MPICC=$MPICC
+
+    MPIF77=$MPIF77
+
+    MPIFC=$MPIFC
+
+    MPIPROG="FreeFem++-mpi${EXEEXT}"
+
+    MPI_INCLUDE="-I $MPI_INC_DIR"
+
+    MPI_INC_DIR=$MPI_INC_DIR
+
+    MPI_LIB_DIRS=""
+
+    MPI_LIB=$MPI_LIB
+
+    MPI_LIBC=""
+
+    MPI_LIBFC=""
+
+
+    # Extra MPI-dependant configuration options that are set by FF during MPI configuration. FFCS - 25/2/13 - Fred
+    # noticed that if PASTIX_HOSTARCH stays blank, pastix compilation breaks. At least i686_pc_linux and i686_mac are
+    # accepted by pastix. So we just use $ac_build_alias which is much more reliable than $ff_HOSTARCH_pastix.
+
+    PASTIX_HOSTARCH=$ac_build_alias
+
+
+    # these values should not be empty otherwise examples++-load/ff-get-dep will think that they are not defined
+    	if test -z "$ff_where_lib_conf_mpi" ; then
+	    echo "mpi LD -DDUMMY"  >>$ff_where_lib_conf
+	    test -n "-I$MPI_INC_DIR" && echo "mpi INCLUDE -I$MPI_INC_DIR "  >>$ff_where_lib_conf
+            ff_where_lib_conf_mpi=1
+	    { $as_echo "$as_me:${as_lineno-$LINENO}:     ++ add mpi : -DDUMMY -I$MPI_INC_DIR in  $ff_where_lib_conf \"" >&5
+$as_echo "$as_me:     ++ add mpi : -DDUMMY -I$MPI_INC_DIR in  $ff_where_lib_conf \"" >&6;}
+	else
+	    { $as_echo "$as_me:${as_lineno-$LINENO}:     -- do not add mpi : -DDUMMY -I$MPI_INC_DIR in  $ff_where_lib_conf \"" >&5
+$as_echo "$as_me:     -- do not add mpi : -DDUMMY -I$MPI_INC_DIR in  $ff_where_lib_conf \"" >&6;}
+        fi
+
+
+    # mpifc and mpif77 libraries should always be specified because FF never calls the Fortran MPI compiler. It always
+    # uses mpicxx in [[file:examples++-load/ff-c++]]. The resulting Fortran libraries (eg Mumps) would compile even
+    # without the proper Fortran libs, but they would not load properly.
+
+    # under Win32, libmpi_f77.a is not the right name and ff/mingw/mpicxx adds the right libraries by itself
+
+    if test $ff_win32 != yes
+    then
+        	if test -z "$ff_where_lib_conf_mpifc" ; then
+	    echo "mpifc LD -lmpi_f77"  >>$ff_where_lib_conf
+	    test -n "" && echo "mpifc INCLUDE  "  >>$ff_where_lib_conf
+            ff_where_lib_conf_mpifc=1
+	    { $as_echo "$as_me:${as_lineno-$LINENO}:     ++ add mpifc : -lmpi_f77  in  $ff_where_lib_conf \"" >&5
+$as_echo "$as_me:     ++ add mpifc : -lmpi_f77  in  $ff_where_lib_conf \"" >&6;}
+	else
+	    { $as_echo "$as_me:${as_lineno-$LINENO}:     -- do not add mpifc : -lmpi_f77  in  $ff_where_lib_conf \"" >&5
+$as_echo "$as_me:     -- do not add mpifc : -lmpi_f77  in  $ff_where_lib_conf \"" >&6;}
+        fi
+
+    		if test -z "$ff_where_lib_conf_mpif77" ; then
+	    echo "mpif77 LD -lmpi_f77"  >>$ff_where_lib_conf
+	    test -n "" && echo "mpif77 INCLUDE  "  >>$ff_where_lib_conf
+            ff_where_lib_conf_mpif77=1
+	    { $as_echo "$as_me:${as_lineno-$LINENO}:     ++ add mpif77 : -lmpi_f77  in  $ff_where_lib_conf \"" >&5
+$as_echo "$as_me:     ++ add mpif77 : -lmpi_f77  in  $ff_where_lib_conf \"" >&6;}
+	else
+	    { $as_echo "$as_me:${as_lineno-$LINENO}:     -- do not add mpif77 : -lmpi_f77  in  $ff_where_lib_conf \"" >&5
+$as_echo "$as_me:     -- do not add mpif77 : -lmpi_f77  in  $ff_where_lib_conf \"" >&6;}
+        fi
+
+    else
+        	if test -z "$ff_where_lib_conf_mpifc" ; then
+	    echo "mpifc LD -DDUMMY"  >>$ff_where_lib_conf
+	    test -n "" && echo "mpifc INCLUDE  "  >>$ff_where_lib_conf
+            ff_where_lib_conf_mpifc=1
+	    { $as_echo "$as_me:${as_lineno-$LINENO}:     ++ add mpifc : -DDUMMY  in  $ff_where_lib_conf \"" >&5
+$as_echo "$as_me:     ++ add mpifc : -DDUMMY  in  $ff_where_lib_conf \"" >&6;}
+	else
+	    { $as_echo "$as_me:${as_lineno-$LINENO}:     -- do not add mpifc : -DDUMMY  in  $ff_where_lib_conf \"" >&5
+$as_echo "$as_me:     -- do not add mpifc : -DDUMMY  in  $ff_where_lib_conf \"" >&6;}
+        fi
+
+    		if test -z "$ff_where_lib_conf_mpif77" ; then
+	    echo "mpif77 LD -DDUMMY"  >>$ff_where_lib_conf
+	    test -n "" && echo "mpif77 INCLUDE  "  >>$ff_where_lib_conf
+            ff_where_lib_conf_mpif77=1
+	    { $as_echo "$as_me:${as_lineno-$LINENO}:     ++ add mpif77 : -DDUMMY  in  $ff_where_lib_conf \"" >&5
+$as_echo "$as_me:     ++ add mpif77 : -DDUMMY  in  $ff_where_lib_conf \"" >&6;}
+	else
+	    { $as_echo "$as_me:${as_lineno-$LINENO}:     -- do not add mpif77 : -DDUMMY  in  $ff_where_lib_conf \"" >&5
+$as_echo "$as_me:     -- do not add mpif77 : -DDUMMY  in  $ff_where_lib_conf \"" >&6;}
+        fi
+
+    fi
+
+    # FFCS - MPI_DOUBLE_COMPLEX kept from original FF configure script
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking MPI_DOUBLE_COMPLEX" >&5
+$as_echo_n "checking MPI_DOUBLE_COMPLEX... " >&6; }
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <mpi.h>
+		MPI_Datatype xxxx=MPI_DOUBLE_COMPLEX;
+
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ff_mpi_double_complex=yes
+else
+  ff_mpi_double_complex=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ff_mpi_double_complex" >&5
+$as_echo "$ff_mpi_double_complex" >&6; }
+    if test "$ff_mpi_double_complex" = yes  ; then
+
+$as_echo "#define HAVE_MPI_DOUBLE_COMPLEX 1" >>confdefs.h
+
+    fi
+fi
+
+# FFCS needs to change some of the FF makefiles to compile without MPI on MacOS
+ if test $ff_mpi = yes; then
+  FFCS_MPIOK_TRUE=
+  FFCS_MPIOK_FALSE='#'
+else
+  FFCS_MPIOK_TRUE='#'
+  FFCS_MPIOK_FALSE=
+fi
+
+
 # Looking for useful configuration utilities
 # ------------------------------------------
 
@@ -12157,9 +12463,11 @@ $as_echo "$as_me:     -- do not add mkl : $ff_mkl_mlt $ff_blas_inc in  $ff_where
         fi
 
 
-
     else
 	ff_mkl_libpath=no
+
+	# FH - pardiso is there as soon as mkl is
+        enable_pardiso=no
     fi
 fi
 
@@ -12364,6 +12672,10 @@ $as_echo_n "checking for BLAS version to download... " >&6; }
 	    ff_blas_inc="-I${curdir}/download/blas/WinNT_PPRO256"
 	    ff_lapack_ok=ok
 	else
+
+            # ALH - FFCS - 23/12/8 - ATLAS compilation does not work anymore on Linux
+	    as_fn_error $? "No BLAS library found - please install one or install Lapack" "$LINENO" 5
+
 	    ff_download_blas=atlas-source
 	    ff_blas_libs="-L${curdir}/download/blas/ATLAS/lib/ff++ -lcblas -llapack -lf77blas -latlas"
 	    ff_blas_inc="-I${curdir}/download/blas/ATLAS/include"
@@ -12431,9 +12743,11 @@ done
 fi
 
 
-if test "$ff_blas_ok" = yes
+# FFCS: do not specify the default BLAS LDADD if a specific one will be built in the download directory
+
+if test "$ff_blas_ok" = yes && test "$ff_download_blas" = ""
 then
-	if test -z "$ff_where_lib_conf_blas" ; then
+    	if test -z "$ff_where_lib_conf_blas" ; then
 	    echo "blas LD $ff_blas_libs"  >>$ff_where_lib_conf
 	    test -n "" && echo "blas INCLUDE  "  >>$ff_where_lib_conf
             ff_where_lib_conf_blas=1
@@ -12444,7 +12758,7 @@ $as_echo "$as_me:     ++ add blas : $ff_blas_libs  in  $ff_where_lib_conf \"" >&
 $as_echo "$as_me:     -- do not add blas : $ff_blas_libs  in  $ff_where_lib_conf \"" >&6;}
         fi
 
-fi
+    fi
 
 # end of BLAS -------------------
 
@@ -13077,9 +13391,15 @@ $as_echo "#define HAVE_LIBUMFPACK 1" >>confdefs.h
 
 	 fi
 fi
-  if test "$ff_umfpack_ok" = yes
-  then
-      	if test -z "$ff_where_lib_conf_amd" ; then
+
+# FFCS - moved UMFPACK configuration settings in wherelib to _after_ configuring the download version, and removed
+# -I/usr/include/$ff_umfpack_dir from include options because it breaks the MingW64 compilation process.
+
+#if test $enable_ffcs = yes
+#then
+    if test "$ff_umfpack_ok" = yes
+    then
+		if test -z "$ff_where_lib_conf_amd" ; then
 	    echo "amd LD $ff_umfpack_libs"  >>$ff_where_lib_conf
 	    test -n "-I/usr/include/$ff_umfpack_dir" && echo "amd INCLUDE -I/usr/include/$ff_umfpack_dir "  >>$ff_where_lib_conf
             ff_where_lib_conf_amd=1
@@ -13090,7 +13410,7 @@ $as_echo "$as_me:     ++ add amd : $ff_umfpack_libs -I/usr/include/$ff_umfpack_d
 $as_echo "$as_me:     -- do not add amd : $ff_umfpack_libs -I/usr/include/$ff_umfpack_dir in  $ff_where_lib_conf \"" >&6;}
         fi
 
-      	if test -z "$ff_where_lib_conf_umfpack" ; then
+		if test -z "$ff_where_lib_conf_umfpack" ; then
 	    echo "umfpack LD $ff_umfpack_libs"  >>$ff_where_lib_conf
 	    test -n "-I/usr/include/$ff_umfpack_dir" && echo "umfpack INCLUDE -I/usr/include/$ff_umfpack_dir "  >>$ff_where_lib_conf
             ff_where_lib_conf_umfpack=1
@@ -13102,7 +13422,8 @@ $as_echo "$as_me:     -- do not add umfpack : $ff_umfpack_libs -I/usr/include/$f
         fi
 
 
-  fi
+				    fi
+#fi
 
 LIBS="$ff_save_libs"
 
@@ -13130,6 +13451,36 @@ $as_echo "#define HAVE_LIBUMFPACK 1" >>confdefs.h
 	ff_umfpack_ok=yes
 fi
 
+# FFCS - moved UMFPACK configuration settings in wherelib to _after_ configuring the download version, and removed
+# -I/usr/include/$ff_umfpack_dir from include options because it breaks the MingW64 compilation process.
+
+## if test $enable_ffcs = yes && test "$ff_umfpack_ok" = yes
+if  test "$ff_umfpack_ok" = yes
+then
+    	if test -z "$ff_where_lib_conf_amd" ; then
+	    echo "amd LD $ff_umfpack_libs"  >>$ff_where_lib_conf
+	    test -n "" && echo "amd INCLUDE  "  >>$ff_where_lib_conf
+            ff_where_lib_conf_amd=1
+	    { $as_echo "$as_me:${as_lineno-$LINENO}:     ++ add amd : $ff_umfpack_libs  in  $ff_where_lib_conf \"" >&5
+$as_echo "$as_me:     ++ add amd : $ff_umfpack_libs  in  $ff_where_lib_conf \"" >&6;}
+	else
+	    { $as_echo "$as_me:${as_lineno-$LINENO}:     -- do not add amd : $ff_umfpack_libs  in  $ff_where_lib_conf \"" >&5
+$as_echo "$as_me:     -- do not add amd : $ff_umfpack_libs  in  $ff_where_lib_conf \"" >&6;}
+        fi
+
+    	if test -z "$ff_where_lib_conf_umfpack" ; then
+	    echo "umfpack LD $ff_umfpack_libs"  >>$ff_where_lib_conf
+	    test -n "" && echo "umfpack INCLUDE  "  >>$ff_where_lib_conf
+            ff_where_lib_conf_umfpack=1
+	    { $as_echo "$as_me:${as_lineno-$LINENO}:     ++ add umfpack : $ff_umfpack_libs  in  $ff_where_lib_conf \"" >&5
+$as_echo "$as_me:     ++ add umfpack : $ff_umfpack_libs  in  $ff_where_lib_conf \"" >&6;}
+	else
+	    { $as_echo "$as_me:${as_lineno-$LINENO}:     -- do not add umfpack : $ff_umfpack_libs  in  $ff_where_lib_conf \"" >&5
+$as_echo "$as_me:     -- do not add umfpack : $ff_umfpack_libs  in  $ff_where_lib_conf \"" >&6;}
+        fi
+
+fi
+
 if test "$ff_umfpack_ok" = no
 then
 	 { $as_echo "$as_me:${as_lineno-$LINENO}: -- NOT  UMFPACK  ff_wget = $ff_wget" >&5
@@ -13413,6 +13764,61 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 $as_echo "$ff_dynload" >&6; }
 fi
 
+# FFCS - -lm missing for ffmedit link stage on Debian Testing
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sin in -lm" >&5
+$as_echo_n "checking for sin in -lm... " >&6; }
+if ${ac_cv_lib_m_sin+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char sin ();
+#ifdef F77_DUMMY_MAIN
+
+#  ifdef __cplusplus
+     extern "C"
+#  endif
+   int F77_DUMMY_MAIN() { return 1; }
+
+#endif
+int
+main ()
+{
+return sin ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  ac_cv_lib_m_sin=yes
+else
+  ac_cv_lib_m_sin=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sin" >&5
+$as_echo "$ac_cv_lib_m_sin" >&6; }
+if test "x$ac_cv_lib_m_sin" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBM 1
+_ACEOF
+
+  LIBS="-lm $LIBS"
+
+fi
+
+
 # Checks that we also have the corresponding library
 if test "$ff_dynload" = yes
 then
@@ -14209,7 +14615,7 @@ if test "${enable_pdf+set}" = set; then :
   enableval=$enable_pdf;
 fi
 
-if test "$enable_pdf" = yes
+if test "$enable_pdf" != no
 then
    # Extract the first word of "pdflatex", so it can be a program name with args.
 set dummy pdflatex; ac_word=$2
@@ -14311,9 +14717,22 @@ fi
 
 if test "$ff_mingw" = yes
 then
+
+    # FFCS does not use FreeFem++-std, and Pcrgraph.cpp does not compile under mingwin64
+    if test $enable_ffcs = no
+    then
 	ff_stdprog="FreeFem++-std${EXEEXT}"
 	ff_std_graph_obj=Pcrgraph.$OBJEXT
+    fi
+
+    # ALH - FFCS - 30/11/8 - I need to get the output from FF for FFCS regression tests
+    if test $enable_ffcs = yes
+    then
+	ff_std_ldflags="-mconsole -mwindows"
+    else
 	ff_std_ldflags=-mwindows
+    fi
+
 	ff_std_libs=
 fi
 STD_GRAPH_OBJ=$ff_std_graph_obj
@@ -14489,6 +14908,306 @@ else
 $as_echo "yes" >&6; }
 fi
 
+# Allow some downloaded tools not to be compiled
+# ----------------------------------------------
+
+# $1 = tool name, $2 = dynamic library name, $3 = download directory name if different from $1
+
+
+
+# Check whether --enable-fflapack was given.
+if test "${enable_fflapack+set}" = set; then :
+  enableval=$enable_fflapack;
+fi
+
+    if test "$enable_fflapack" = "no"
+    then
+        FFCS_COMPILE_fflapack=""
+
+        FFCS_DYLIB_fflapack=""
+
+    else
+        FFCS_COMPILE_fflapack=fflapack
+
+        FFCS_DYLIB_fflapack=fflapack.$DYLIB_SUFFIX
+
+    fi
+
+#  move FFCS_DISABLE_DOWNLOAD gls  , after find gsl ...
+# Check whether --enable-hips was given.
+if test "${enable_hips+set}" = set; then :
+  enableval=$enable_hips;
+fi
+
+    if test "$enable_hips" = "no"
+    then
+        FFCS_COMPILE_hips=""
+
+        FFCS_DYLIB_hips=""
+
+    else
+        FFCS_COMPILE_hips=hips
+
+        FFCS_DYLIB_hips=hips_FreeFem.$DYLIB_SUFFIX
+
+    fi
+
+# Check whether --enable-hypre was given.
+if test "${enable_hypre+set}" = set; then :
+  enableval=$enable_hypre;
+fi
+
+    if test "$enable_hypre" = "no"
+    then
+        FFCS_COMPILE_hypre=""
+
+        FFCS_DYLIB_hypre=""
+
+    else
+        FFCS_COMPILE_hypre=hypre
+
+        FFCS_DYLIB_hypre=hypre.$DYLIB_SUFFIX
+
+    fi
+
+# Check whether --enable-ipopt was given.
+if test "${enable_ipopt+set}" = set; then :
+  enableval=$enable_ipopt;
+fi
+
+    if test "$enable_ipopt" = "no"
+    then
+        FFCS_COMPILE_ipopt=""
+
+        FFCS_DYLIB_ipopt=""
+
+    else
+        FFCS_COMPILE_ipopt=ipopt
+
+        FFCS_DYLIB_ipopt=ff-Ipopt.$DYLIB_SUFFIX
+
+    fi
+
+# Check whether --enable-lapack was given.
+if test "${enable_lapack+set}" = set; then :
+  enableval=$enable_lapack;
+fi
+
+    if test "$enable_lapack" = "no"
+    then
+        FFCS_COMPILE_lapack=""
+
+        FFCS_DYLIB_lapack=""
+
+    else
+        FFCS_COMPILE_lapack=lapack
+
+        FFCS_DYLIB_lapack=lapack.$DYLIB_SUFFIX
+
+    fi
+
+# Check whether --enable-mmg3d was given.
+if test "${enable_mmg3d+set}" = set; then :
+  enableval=$enable_mmg3d;
+fi
+
+    if test "$enable_mmg3d" = "no"
+    then
+        FFCS_COMPILE_mmg3d=""
+
+        FFCS_DYLIB_mmg3d=""
+
+    else
+        FFCS_COMPILE_mmg3d=mmg3d
+
+        FFCS_DYLIB_mmg3d=mmg3d-v4.0.$DYLIB_SUFFIX
+
+    fi
+
+# Check whether --enable-mshmet was given.
+if test "${enable_mshmet+set}" = set; then :
+  enableval=$enable_mshmet;
+fi
+
+    if test "$enable_mshmet" = "no"
+    then
+        FFCS_COMPILE_mshmet=""
+
+        FFCS_DYLIB_mshmet=""
+
+    else
+        FFCS_COMPILE_mshmet=mshmet
+
+        FFCS_DYLIB_mshmet=mshmet.$DYLIB_SUFFIX
+
+    fi
+
+# Check whether --enable-mumps was given.
+if test "${enable_mumps+set}" = set; then :
+  enableval=$enable_mumps;
+fi
+
+    if test "$enable_mumps" = "no"
+    then
+        FFCS_COMPILE_mumps=""
+
+        FFCS_DYLIB_mumps=""
+
+    else
+        FFCS_COMPILE_mumps=mumps
+
+        FFCS_DYLIB_mumps="MUMPS_FreeFem.$DYLIB_SUFFIX MUMPS.$DYLIB_SUFFIX"
+
+    fi
+
+# Check whether --enable-mumps_seq was given.
+if test "${enable_mumps_seq+set}" = set; then :
+  enableval=$enable_mumps_seq;
+fi
+
+    if test "$enable_mumps_seq" = "no"
+    then
+        FFCS_COMPILE_mumps_seq=""
+
+        FFCS_DYLIB_mumps_seq=""
+
+    else
+        FFCS_COMPILE_mumps_seq=mumps-seq
+
+        FFCS_DYLIB_mumps_seq=MUMPS_seq.$DYLIB_SUFFIX
+
+    fi
+
+# Check whether --enable-parms was given.
+if test "${enable_parms+set}" = set; then :
+  enableval=$enable_parms;
+fi
+
+    if test "$enable_parms" = "no"
+    then
+        FFCS_COMPILE_parms=""
+
+        FFCS_DYLIB_parms=""
+
+    else
+        FFCS_COMPILE_parms=parms
+
+        FFCS_DYLIB_parms=parms_FreeFem.$DYLIB_SUFFIX
+
+    fi
+
+# Check whether --enable-pastix was given.
+if test "${enable_pastix+set}" = set; then :
+  enableval=$enable_pastix;
+fi
+
+    if test "$enable_pastix" = "no"
+    then
+        FFCS_COMPILE_pastix=""
+
+        FFCS_DYLIB_pastix=""
+
+    else
+        FFCS_COMPILE_pastix=pastix
+
+        FFCS_DYLIB_pastix="interfacepastix.$DYLIB_SUFFIX complex_pastix_FreeFem.$DYLIB_SUFFIX real_pastix_FreeFem.$DYLIB_SUFFIX"
+
+    fi
+
+# Check whether --enable-scotch was given.
+if test "${enable_scotch+set}" = set; then :
+  enableval=$enable_scotch;
+fi
+
+    if test "$enable_scotch" = "no"
+    then
+        FFCS_COMPILE_scotch=""
+
+        FFCS_DYLIB_scotch=""
+
+    else
+        FFCS_COMPILE_scotch=scotch
+
+        FFCS_DYLIB_scotch=scotch.$DYLIB_SUFFIX
+
+    fi
+
+# Check whether --enable-superludist was given.
+if test "${enable_superludist+set}" = set; then :
+  enableval=$enable_superludist;
+fi
+
+    if test "$enable_superludist" = "no"
+    then
+        FFCS_COMPILE_superludist=""
+
+        FFCS_DYLIB_superludist=""
+
+    else
+        FFCS_COMPILE_superludist=superludist
+
+        FFCS_DYLIB_superludist="complex_SuperLU_DIST_FreeFem.$DYLIB_SUFFIX real_SuperLU_DIST_FreeFem.$DYLIB_SUFFIX dSuperLU_DIST.$DYLIB_SUFFIX"
+
+    fi
+
+# Check whether --enable-yams was given.
+if test "${enable_yams+set}" = set; then :
+  enableval=$enable_yams;
+fi
+
+    if test "$enable_yams" = "no"
+    then
+        FFCS_COMPILE_yams=""
+
+        FFCS_DYLIB_yams=""
+
+    else
+        FFCS_COMPILE_yams=yams
+
+        FFCS_DYLIB_yams=freeyams.$DYLIB_SUFFIX
+
+    fi
+
+# Check whether --enable-pipe was given.
+if test "${enable_pipe+set}" = set; then :
+  enableval=$enable_pipe;
+fi
+
+    if test "$enable_pipe" = "no"
+    then
+        FFCS_COMPILE_pipe=""
+
+        FFCS_DYLIB_pipe=""
+
+    else
+        FFCS_COMPILE_pipe=pipe
+
+        FFCS_DYLIB_pipe=pipe.$DYLIB_SUFFIX
+
+    fi
+
+
+# FFCS - MUMPS_seq has a different Win32 compiler setup from FFCS, so we need to add some extra parameters
+if test "$OS" = Windows_NT
+then
+    CFLAGS="$CFLAGS -DWITHOUT_PTHREAD -DAdd_"
+
+    # we also need to satisfy ff-c++ that the pthread are not a blocking point
+    if test -n "$ff_pthread"  ; then
+       	if test -z "$ff_where_lib_conf_pthread" ; then
+	    echo "pthread LD """  >>$ff_where_lib_conf
+	    test -n "" && echo "pthread INCLUDE  "  >>$ff_where_lib_conf
+            ff_where_lib_conf_pthread=1
+	    { $as_echo "$as_me:${as_lineno-$LINENO}:     ++ add pthread : \"\"  in  $ff_where_lib_conf \"" >&5
+$as_echo "$as_me:     ++ add pthread : \"\"  in  $ff_where_lib_conf \"" >&6;}
+	else
+	    { $as_echo "$as_me:${as_lineno-$LINENO}:     -- do not add pthread : \"\"  in  $ff_where_lib_conf \"" >&5
+$as_echo "$as_me:     -- do not add pthread : \"\"  in  $ff_where_lib_conf \"" >&6;}
+        fi
+
+    fi
+fi
+
 # Find out kernel and libc versions
 # ---------------------------------
 
@@ -14522,7 +15241,19 @@ CNOFLAGS=$CNOFLAGS
  # The final list of executable programs
 MEDITPROG=$ff_meditprog
 
-FFGLUTPROG=$ff_ffglutprog
+
+# ALH - FFCS - 5/1/9 - ffglut cannot be compiled with FFCS under Cygwin because it requires a GLUT versions that works
+# with Mingw, and the standard Cygwin Glut is not enough. But FFCS needs a working ffglut on other platforms for testing
+# purposes.
+
+if test "$ff_win32" = yes
+then
+	FFGLUTPROG=''
+
+else
+	FFGLUTPROG=$ff_ffglutprog
+
+fi
 
 BAMGPROG=$ff_bamgprog
 
@@ -14549,7 +15280,7 @@ ff_progs="FreeFem++-nw $ff_bamgprog  $ff_mpiprog $ff_meditprog $ff_ffglutprog"
 #metis INCLUDE -I/Users/hecht/work/freefem++/download/include/metis
 # mumps LD '-L/Users/hecht/work/freefem++/download//lib  -lpord -lmumps_common -ldmumps -lzmumps -lpord'
 # mumps INCLUDE '-I/Users/hecht/work/freefem++/download/include'
-# parmetis LD -L/Users/hecht/work/freefem++/download/lib -lparmetis -lmetis
+# parmetis LD -L/Users/hecht/work/freefem++/download/lib -lparmetis -lmetispar
 # parmetis INCLUDE -I/Users/hecht/work/freefem++/download/include/metis
 # scalapack LD '-L/Users/hecht/work/freefem++/download/lib  -lscalapack '
 # scalapack INCLUDE '-I/Users/hecht/work/freefem++/download/include'
@@ -16029,6 +16760,58 @@ $as_echo "$ff_WHERE" >&6; }
 	fi
 
 
+# FFCS - 27/10/11 - Some extra conditionals for things that do not work on certain systems (eg MPI libraries under
+# Windows)
+#  remove gsl if not find ... FK
+
+if test  "$ff_where_lib_conf_gsl" == 1  -a -z "$enable_gsl" ; then enable_gsl=no; fi;
+if test  "$ff_where_lib_conf_mkl" == 1  -a -z "$enable_mkl" ; then enable_pardiso=no; fi;
+# Check whether --enable-gsl was given.
+if test "${enable_gsl+set}" = set; then :
+  enableval=$enable_gsl;
+fi
+
+    if test "$enable_gsl" = "no"
+    then
+        FFCS_COMPILE_gsl=""
+
+        FFCS_DYLIB_gsl=""
+
+    else
+        FFCS_COMPILE_gsl=gsl
+
+        FFCS_DYLIB_gsl="gsl.$DYLIB_SUFFIX NewSolver.$DYLIB_SUFFIX"
+
+    fi
+
+# Check whether --enable-pardiso was given.
+if test "${enable_pardiso+set}" = set; then :
+  enableval=$enable_pardiso;
+fi
+
+    if test "$enable_pardiso" = "no"
+    then
+        FFCS_COMPILE_pardiso=""
+
+        FFCS_DYLIB_pardiso=""
+
+    else
+        FFCS_COMPILE_pardiso=pardiso
+
+        FFCS_DYLIB_pardiso=PARDISO.$DYLIB_SUFFIX
+
+    fi
+
+
+
+ if test $OS = Windows_NT; then
+  FFCS_WINDOWS_TRUE=
+  FFCS_WINDOWS_FALSE='#'
+else
+  FFCS_WINDOWS_TRUE='#'
+  FFCS_WINDOWS_FALSE=
+fi
+
 
 # All makefiles
 ac_config_files="$ac_config_files Makefile download/Makefile download/blas/Makefile download/arpack/Makefile download/umfpack/Makefile src/Makefile src/bamglib/Makefile src/Graphics/Makefile src/femlib/Makefile src/Algo/Makefile src/lglib/Makefile src/fflib/Makefile src/nw/Makefile src/mpi/Makefile src/bamg/Makefile src/libMesh/Makefile src/medit/Makefile src/bin-win32/Makefile examples++/Makefile examples++-eigen/Makefile examples++-tutorial/Makefile examples++-mpi/Makefile examples++-l [...]
@@ -16174,10 +16957,22 @@ if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
   as_fn_error $? "conditional \"am__fastdepCXX\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${ENABLE_FFCS_TRUE}" && test -z "${ENABLE_FFCS_FALSE}"; then
+  as_fn_error $? "conditional \"ENABLE_FFCS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
   as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${FFCS_MPIOK_TRUE}" && test -z "${FFCS_MPIOK_FALSE}"; then
+  as_fn_error $? "conditional \"FFCS_MPIOK\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${FFCS_WINDOWS_TRUE}" && test -z "${FFCS_WINDOWS_FALSE}"; then
+  as_fn_error $? "conditional \"FFCS_WINDOWS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 
 : "${CONFIG_STATUS=./config.status}"
 ac_write_fail=0
@@ -16575,7 +17370,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by FreeFem++ $as_me 3.23, which was
+This file was extended by FreeFem++ $as_me 3.25, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -16641,7 +17436,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-FreeFem++ config.status 3.23
+FreeFem++ config.status 3.25
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -17580,20 +18375,29 @@ $as_echo "$as_me:       or try to download/compile the altas blas ." >&6;}
 fi  # ---  test "$enable_download" = yes  ;then
 
 
-if test "$ff_glut_ok" != yes  ; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}:      *********************************************** " >&5
+# FFCS: remove this message because it could make the user think that something is broken
+if test $enable_ffcs = no
+then
+    if test "$ff_glut_ok" != yes  ; then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:      *********************************************** " >&5
 $as_echo "$as_me:      *********************************************** " >&6;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}:      WARNING: you do not have the new grachics tools " >&5
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:      WARNING: you do not have the new grachics tools " >&5
 $as_echo "$as_me:      WARNING: you do not have the new grachics tools " >&6;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}:          because the configure do not find OpenGL, GLUT or pthread  developer stuff " >&5
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:          because the configure do not find OpenGL, GLUT or pthread  developer stuff " >&5
 $as_echo "$as_me:          because the configure do not find OpenGL, GLUT or pthread  developer stuff " >&6;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}:          read the README to find missing package  " >&5
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:          read the README to find missing package  " >&5
 $as_echo "$as_me:          read the README to find missing package  " >&6;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}:          F. Hecht  " >&5
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:          F. Hecht  " >&5
 $as_echo "$as_me:          F. Hecht  " >&6;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}:  to install missing package  under debian or ubuntu, try: sudo apt-get install freeglut3-dev " >&5
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:  to install missing package  under debian or ubuntu, try: sudo apt-get install freeglut3-dev " >&5
 $as_echo "$as_me:  to install missing package  under debian or ubuntu, try: sudo apt-get install freeglut3-dev " >&6;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}:      *********************************************** " >&5
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:      *********************************************** " >&5
 $as_echo "$as_me:      *********************************************** " >&6;}
+    fi
 fi
 
+# Local Variables:
+# mode:shell-script
+# ispell-local-dictionary:"british"
+# coding:utf-8
+# End:
diff --git a/configure.ac b/configure.ac
index 0db3140..8a7b143 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-g# Configuration script using Automake + Autoconf for FreeFem++
+# Configuration script using Automake + Autoconf for FreeFem++
 # ------------------------------------------------------------
 
 # Antoine Le Hyaric - LJLL Paris 6 - lehyaric at ann.jussieu.fr - 13/5/04
@@ -10,7 +10,7 @@ g# Configuration script using Automake + Autoconf for FreeFem++
 # number in debian/changelog.
 
 
-AC_INIT(FreeFem++,3.23,hecht at ann.jussieu.fr,freefem++)
+AC_INIT(FreeFem++,3.25,hecht at ann.jussieu.fr,freefem++)
 dnl : ${CFLAGS=""}
 dnl : ${CXXFLAGS=""}
 dnl : ${FCFLAGS=""}
@@ -19,14 +19,18 @@ dnl : ${FFLAGS=""}
 
 AC_PREREQ(2.50) dnl for AC_LANG_CASE
 dnl AC_CONFIG_SRCDIR(src/FreeFem++-CoCoa)
-# Automake 1.4 is too old
-AM_INIT_AUTOMAKE(1.6.3 dist-zip)
+# Automake 1.11 is too old for check ... 
+AM_INIT_AUTOMAKE(1.13 dist-zip)
 
 AC_CONFIG_HEADERS(config.h)
 AC_PROG_MAKE_SET
 dnl AM_COLOR_TESTS=always
 AC_PROG_RANLIB
 
+# FFCS - parallel make options (see [[file:../../configure/ac::FFCS_MAKEFLAGS]])
+
+AC_SUBST(FFCS_MAKEFLAGS,$FFCS_MAKEFLAGS)
+
 ff_where_lib_conf=examples++-load/WHERE_LIBRARY-config
 dnl search of associad software 
 m4_define([AC_FF_ADDWHERELIB],
@@ -107,6 +111,16 @@ else
   AC_MSG_ERROR([ Sorry  sizeof c++ pointer $ff_size_ptr are not  4 or 8 ])
 fi
 
+# FFCS - build the code for FreeFem++-cs
+AC_ARG_ENABLE(fortran,[  --enable-ffcs	build FreeFem++ for use by FreeFem++-cs])
+if test "$enable_ffcs" = yes
+then
+	AC_DEFINE_UNQUOTED(ENABLE_FFCS,$enable_ffcs,[build FreeFem++ for use by FreeFem++-cs])
+else
+	enable_ffcs=no
+fi
+AC_SUBST(ENABLE_FFCS,"$enable_ffcs")
+AM_CONDITIONAL([ENABLE_FFCS],[test $enable_ffcs = yes])
 
 # dur dur car sous MacOsX le fortran n'est pas standard. 
 ff_AR="ar"
@@ -117,8 +131,11 @@ AC_ARG_ENABLE(fortran,[  --disable-fortran	No Fortran compiler available ( ARPAC
 ff_g2c_lib="";	 
 if test "$enable_fortran" != no
 then
-    AC_PROG_FC(gfortran  f90  xlf90 g95  )
-    AC_PROG_F77( gfortran  f90 xlf xlf90 g95 f77 fort77 "$FC" )
+
+    # ALH-FFCS-2/3/10: add gfortran-mp-4.4 for MacPorts on MacOS 10.6
+    AC_PROG_FC(gfortran  f90  xlf90 g95 gfortran-mp-4.4)
+    AC_PROG_F77(gfortran f90 xlf xlf90 g95 f77 fort77 "$FC" gfortran-mp-4.4)
+
 #	if test -n "$F77" 
 #	then
     ff_flibs=""
@@ -363,7 +380,13 @@ ff_uname=`uname`
 ff_mingw=no
 case $ff_uname in
     CYGWIN*)	
-	ff_nocygwin=-mno-cygwin;
+
+    	# FFCS - 17/1/12 - -mno-cygwin is not recognised by the latest version of mingw32
+	if test $enable_ffcs = no
+	then
+	    ff_nocygwin=-mno-cygwin
+	fi
+
 	AC_SUBST(GCCNOCYGWIN,$ff_nocygwin);;
     MINGW*)
         enable_cygwindll=no;;
@@ -373,36 +396,67 @@ CYGWIN*|MINGW*)
 
 	ff_suffix_dylib="dll";
         ff_win32=yes;
-	AC_SUBST(FFMETIS_CFLAGS,"-D__VC__ -D_MSC_VER")
+
+	# FFCS - 8/3/12 - remove -D_MSC_VER under MinGW64 because it forces system calls to be compiled into any object
+	# (which creates thousands of duplicate definitions for sytem calls like time()).
+
+	if test $enable_ffcs = yes
+	then
+	    AC_SUBST(FFMETIS_CFLAGS,"-D__VC__")
+	else
+	    AC_SUBST(FFMETIS_CFLAGS,"-D__VC__ -D_MSC_VER")
+	fi
+
 	# We need Mingw to avoid Cygwin's extra DLLs
 	if test "$enable_cygwindll" != yes
 	then
 # 	        CHECK_COMPILE_FLAG(C++,-mwindows,CXXFLAGS)
 	        ff_glut_ok=yes
+
+		# FFCS: on Windows, FF crashes when compiling GL/glut.h and the option "--disable-opengl" is not
+		# operational because ff_glut_ok is forced to yes here.
+		if test $enable_ffcs = yes
+		then
+	            ff_glut_ok=no
+		    enable_opengl=no
+		fi
+
                 ff_mingw=yes 
                 enable_cygwindll=no;
-		#ff_pthread="-mthread"
-		CXXFLAGS="$CXXFLAGS $ff_nocygwin -I/usr/include/mingw"		
-		FFLAGS="$FFLAGS $ff_nocygwin"
-		CFLAGS="$CFLAGS $ff_nocygwin -I/usr/include/mingw"
-                AC_COMPILE_IFELSE([AC_LANG_SOURCE([int a;])],[],
-                    [ff_nocygwin="";
-		     AC_MSG_NOTICE([Sorry $ff_nocygwin optio is wrong try whitout , but try with gcc-3.3])
-                    ])
-		CXXFLAGS="$CXXFLAGS $ff_nocygwin -I/usr/include/mingw"		
-		FFLAGS="$FFLAGS $ff_nocygwin"
-		CFLAGS="$CFLAGS $ff_nocygwin -I/usr/include/mingw"
-		CNOFLAGS="$CNOFLAGS $ff_nocygwin -I/usr/include/mingw"
+		ff_pthread="-mthreads"
+
+		# FFCS does not use the Cygwin MinGW compilers any more
+		if test $enable_ffcs = no
+		then
+		    CXXFLAGS="$CXXFLAGS $ff_nocygwin -I/usr/include/mingw"		
+		    FFLAGS="$FFLAGS $ff_nocygwin"
+		    CFLAGS="$CFLAGS $ff_nocygwin -I/usr/include/mingw"
+                    AC_COMPILE_IFELSE([AC_LANG_SOURCE([int a;])],[],
+			[ff_nocygwin="";
+			    AC_MSG_NOTICE([Sorry $ff_nocygwin optio is wrong try whitout , but try with gcc-3.3])
+			    ])
+		    CXXFLAGS="$CXXFLAGS $ff_nocygwin -I/usr/include/mingw"		
+		    FFLAGS="$FFLAGS $ff_nocygwin"
+		    CFLAGS="$CFLAGS $ff_nocygwin -I/usr/include/mingw"
+		    CNOFLAGS="$CNOFLAGS $ff_nocygwin -I/usr/include/mingw"
+		fi
+
 		LIBS="$LIBS $ff_nocygwin -mthreads -lws2_32 -lcomdlg32" 
 		LIBSNOCONSOLE="-mwindows"
-		test -z "$MPIRUN" &&  MPIRUN=`which mpiexe.exe` 
-		if test "$enable_fortran" != no  -o  "$with_flib" != no ;   then
-		    case "$F77" in
-	 		*gfortran) FLIBS="$ff_nocygwin -lgfortran";;
-	 		*g77) FLIBS="$ff_nocygwin -lg2c";;
-			*)   AC_MSG_ERROR([ Sorry no known FLIBS with this $F77  !]) ;;
-		    esac 
+
+		# FFCS uses a specific compiler, so we specify its libraries explicitely
+		if test $enable_ffcs = no
+		then
+		    test -z "$MPIRUN" &&  MPIRUN=`which mpiexe.exe` 
+		    if test "$enable_fortran" != no  -o  "$with_flib" != no ;   then
+			case "$F77" in
+	 		    *gfortran) FLIBS="$ff_nocygwin -lgfortran";;
+	 		    *g77) FLIBS="$ff_nocygwin -lg2c";;
+			    *)   AC_MSG_ERROR([ Sorry no known FLIBS with this $F77  !]) ;;
+			esac 
+		    fi
 		fi
+
                 ff_glutname="glut32"
 		#  check abort a existing function just to find in glut32.dll exist in the path 
 		#  because glutInit is not the real symbol on win32 dur dur FH !!!!!!!!!
@@ -629,306 +683,68 @@ fi
 
 # Checking wether we can produce a parallel version
 # -------------------------------------------------
-dnl m4_include(ax_mpi.m4)
-ff_save_path="$PATH"
-# We need to choose between mpich, openmpi  and lam for the Debian package
-AC_ARG_WITH(mpipath,[  --with-mpipath= the path of mpich under windows (no command  mpic++, ... )])
-AC_ARG_WITH(mpilibs,[  --with-mpilibs= the libs to add to c++,fc, ... (to link with c++ - ex:   -L/usr/local/lib -lmpi_f90  -lmpi_cxx -lmpi -lopen-rte -lopen-pal -lutil) ])
-AC_ARG_WITH(mpilibsc,[  --with-mpilibsc= the libs to add to c  ... (to link with cc (for pastix lib)  ex:   -L/usr/local/lib -lmpi -lopen-rte -lopen-pal -lutil) ])
-AC_ARG_WITH(mpiinc,[  --with-mpiinc= the include directory directive and preprocess directive  (no mpicc++, just use the compiler)) ])
-AC_ARG_WITH(mpi,[  --with-mpi=[yes|no|mpic++|lam|mpich|openmpi|/usr/local/bin/mpic++|... ]	or --without-mpi	Choose MPI implementation (default is mpic++)])
-if test "$with_mpi" != no ; then  
-#if test "$with_mpi" != no ; then
-#AX_MPI(with_mpi=yes, with_mpi=no)
-#fi
 
-# Default is mpic++ 
-ff_mpi_suffix="";
-if test "$with_mpi" = yes -o -z "$with_mpi" 
+if test $enable_ffcs = no
 then
-   ff_mpicxx=mpic++
-else 
-  case "$with_mpi" in
- lam|mpich|openmpi)   ff_mpi_suffix=.$with_mpi;ff_mpicxx=mpic++.$with_mpi;;
- *)  ff_mpicxx="$with_mpi" ;;
- esac
-fi
-
-dnl AC_MSG_NOTICE([ xxxxxxxxxxxxxxxxxxxx --$with_mpilibs--]);
-if test -n "$with_mpiinc"  -a "$with_mpiinc" != no ; then
-  if test  "$with_mpi" = 'no' ; then with_mpi='yes'; fi
-  ff_MPI_INCLUDE="$with_mpiinc"
-fi
-if test -n "$with_mpilibs" -a "$with_mpilibs" != no ; then
-    ff_MPI_LIB="$with_mpilibs"
-    ff_MPI_LIBC="$with_mpilibs"
-    ff_MPI_LIBFC="$with_mpilibs"
-    MPICXX="$CXX $ff_MPI_INCLUDE"
-    MPIF77="$F77 $ff_MPI_INCLUDE"
-    MPIFC="$FC  $ff_MPI_INCLUDE"
-    MPICC="$CC  $ff_MPI_INCLUDE"
-    AC_MSG_NOTICE([   ---  set  all MPI compile to compiler:   $MPICC , $MPIF77, $MPIFC, $MPICC  ])
-fi
-
-if test -n "$with_mpilibsc" -a "$with_mpilibsc" != no ; then
- ff_MPI_LIBC="$with_mpilibsc"
-fi
-
-AC_ARG_VAR(MPIRUN,[MPI run command ])
-AC_MSG_CHECKING(for MPIRUN)
-
-if test -z "$MPIRUN" ; then
-    AC_PATH_PROGS(MPIRUN,mpirun mpiexec mpiexec.exe,no)
-    if test "$MPIRUN" = no
-    then
-	ff_mpi=no
-    fi
-fi
-AC_MSG_RESULT($MPIRUN)
-
-AC_MSG_CHECKING(for mpipath )
-	
-if test "$with_mpi" != no -a ! -d  "$with_mpipath" -a "$ff_win32" = yes -a "$MPIRUN" != no ; then 
-#   if "$MPIRUN" != no ; tehn 
-    with_mpipath=`AS_DIRNAME(["$MPIRUN"])`
-    with_mpipath=`AS_DIRNAME(["$with_mpipath"])`
-#    else 
-#    for i in '/c/Program Files (x86)/MPICH2' '/c/Program Files/MPICH2' 'c:\Program Files (x86)\MPICH2' 'c:\Program Files\MPICH2' ; do
-#	test -d "$i" &&  with_mpipath="$i" && break 
-#    done
-#    fi
-fi
-
-dnl if test "$with_mpilibs" != "no" ; then
-dnl fi
-
-    
-if test  -d "$with_mpipath" -a "$ff_win32" = yes  ; then
-#    sed -e "s?@MPIDIR@?$with_mpipath?" -e "s?@F77@?$F77?" -e "s?@CC@?$CC?" -e "s?@CXX@?$CXX?"   -e "s?@FC@?$FC?"  <mpic++.in >mpic++
- #   chmod a+rx mpic++ 
-  #  for i in mpicc mpif90 mpifc mpif77 ; do cp mpic++ $i; done 
-#    ff_pwd=`pwd`
- #   with_mpi="$ff_pwd"/mpic++
- #   MPICXX="$ff_pwd/mpic++"
- #   MPIF77="$ff_pwd/mpif77"
- #   MPIFC="$ff_pwd/mpif90"
- #   MPICC="$ff_pwd/mpicc" zzzzzzzzzzz   
-    if  with_mpilibs=`which msmpi.dll` 
+    # FF case
+    m4_include(acmpi.m4)
+else
+    # FFCS - use the same MPI configuration choices as FFCS
+    ff_mpi=yes
+    AC_SUBST(MPICXX,$MPICXX)
+    AC_SUBST(MPICC,$MPICC)
+    AC_SUBST(MPIF77,$MPIF77)
+    AC_SUBST(MPIFC,$MPIFC)
+    AC_SUBST(MPIPROG,"FreeFem++-mpi${EXEEXT}")
+    AC_SUBST(MPI_INCLUDE,"-I $MPI_INC_DIR")
+    AC_SUBST(MPI_INC_DIR,$MPI_INC_DIR)
+    AC_SUBST(MPI_LIB_DIRS,"")
+    AC_SUBST(MPI_LIB,$MPI_LIB)
+    AC_SUBST(MPI_LIBC,"")
+    AC_SUBST(MPI_LIBFC,"")
+
+    # Extra MPI-dependant configuration options that are set by FF during MPI configuration. FFCS - 25/2/13 - Fred
+    # noticed that if PASTIX_HOSTARCH stays blank, pastix compilation breaks. At least i686_pc_linux and i686_mac are
+    # accepted by pastix. So we just use $ac_build_alias which is much more reliable than $ff_HOSTARCH_pastix.
+
+    AC_SUBST(PASTIX_HOSTARCH,$ac_build_alias)
+
+    # these values should not be empty otherwise examples++-load/ff-get-dep will think that they are not defined
+    AC_FF_ADDWHERELIB(mpi,-DDUMMY,-I$MPI_INC_DIR)
+
+    # mpifc and mpif77 libraries should always be specified because FF never calls the Fortran MPI compiler. It always
+    # uses mpicxx in [[file:examples++-load/ff-c++]]. The resulting Fortran libraries (eg Mumps) would compile even
+    # without the proper Fortran libs, but they would not load properly.
+
+    # under Win32, libmpi_f77.a is not the right name and ff/mingw/mpicxx adds the right libraries by itself
+
+    if test $ff_win32 != yes
     then
-	case "$ff_size_ptr"  in 
-	    4) with_mpipathlib="$with_mpipath/Lib/i386";;
-	    8) with_mpipathlib="$with_mpipath/Lib/amd64";;
-	    *) with_mpipath=no;;
-	esac
-	
-	
-	test -d "$with_mpipath/Inc" &&  ff_MPI_INCLUDE_DIR="$with_mpipath/Inc"
-	test -d "$with_mpipath/Include" &&  ff_MPI_INCLUDE_DIR="$with_mpipath/Include"
-	ff_MPI_INCLUDE="-I'$ff_MPI_INCLUDE_DIR' '-D_MSC_VER' '-D__int64=long long'"
-	with_mpiinc="$ff_MPI_INCLUDE"
-	test -z "$MPIRUN" && MPIRUN="$with_mpipath/bin/mpiexe.exe"
-	ff_MPI_LIBC="$with_mpilibs"
-	ff_MPI_LIB="$with_mpilibs"
-	ff_MPI_LIBFC="$with_mpilibs"
-	test -z "$MPICXX" && MPICXX="$CXX $ff_MPI_INCLUDE"
-	test -z "$MPIF77" && MPIF77="$F77 $ff_MPI_INCLUDE"
-	test -z "$MPIFC"  && MPIFC="$FC  $ff_MPI_INCLUDE"
-	test -z "$MPICC"  && MPICC="$CC  $ff_MPI_INCLUDE"
+        AC_FF_ADDWHERELIB(mpifc,-lmpi_f77,)
+    	AC_FF_ADDWHERELIB(mpif77,-lmpi_f77,)
     else
-	echo " #### no msmpi.dll  => no mpi under windows .... (FH) " >&AS_MESSAGE_LOG_FD
-	echo " #### no msmpi.dll  => no mpi under windows .... (FH) " >&AS_MESSAGE_FD
-	with_mpipath=no
-	with_mpi=no
+        AC_FF_ADDWHERELIB(mpifc,-DDUMMY,)
+    	AC_FF_ADDWHERELIB(mpif77,-DDUMMY,)
     fi
-else 
-    with_mpipath=no	   
-fi
-
 
-AC_MSG_RESULT($ff_mpi_path)
-
-
-
-
-dnl  correct ff_mpi_path august 2010 -- FH ...  
-
-
-ff_save_cxx="$CXX"
-ff_save_libs="$LIBS"
-
-
-if test "$with_mpi" != no
-then
-	ff_mpi_path=`AS_DIRNAME(["$MPIRUN"])`
-dnl	echo "ff_mpi_path '$ff_mpi_path' .............."
-	case "$ff_mpi_path" in
-	    .|"") ff_mpi_path="$PATH";ff_defmpicxx="$ff_mpicxx";;
-	    *) ff_mpi_path="$ff_mpi_path";ff_defmpicxx=`expr "//$ff_mpicxx" : '.*/\(.*\)'`;; 
-dnl if also  add $PATH they  could be missing some different mpi version... 
-	esac	 
-	AC_ARG_VAR(MPICXX,[MPI C++ compiler command])
-	if test -z "$MPICXX" ; then
-	    AC_PATH_PROGS(MPICXX,$ff_defmpicxx mpic++$ff_mpi_suffix mpicxx$ff_mpi_suffix mpiCC$ff_mpi_suffix mpCC hcp mpxlC mpxlC_r cmpic++,no,$ff_mpi_path)
-	    AC_MSG_CHECKING(for MPICXX)
-	fi
-	ff_mpicxx="eval $MPICXX"
-	CXX=$ff_mpicxx
-	LIBS="$LIBS $ff_MPI_LIB"
-	
-	AC_LINK_IFELSE(
-[AC_LANG_SOURCE([
+    # FFCS - MPI_DOUBLE_COMPLEX kept from original FF configure script
+    AC_MSG_CHECKING( MPI_DOUBLE_COMPLEX)
+    AC_COMPILE_IFELSE(
+    [AC_LANG_SOURCE([
 #include <mpi.h>
-#include <stdio.h>
-int main(int argc,char **argv){
-  char name[[BUFSIZ]];
-  int length;
-  
-  MPI_Init(&argc, &argv);
-  MPI_Get_processor_name(name, &length);
-  printf("%s: hello world\n", name);
-  MPI_Finalize();
-  return 0;
-}])],
-ff_mpi=yes,
-ff_mpi=no)
-	AC_MSG_RESULT($ff_mpi)
-
-	# Also check that mpirun is there. If it isn't, then MPI is
-	# not fully installed.
-
-
-	if test "$ff_mpi" = yes;
-	then
-
-AC_MSG_CHECKING( MPI_DOUBLE_COMPLEX)
-
-	AC_COMPILE_IFELSE(
-[AC_LANG_SOURCE([
-#include <mpi.h>
-MPI_Datatype xxxx=MPI_DOUBLE_COMPLEX;
-])],
-ff_mpi_double_complex=yes,
-ff_mpi_double_complex=no)
-	AC_MSG_RESULT($ff_mpi_double_complex)
-if test "$ff_mpi_double_complex" = yes  ; then
-AC_DEFINE(HAVE_MPI_DOUBLE_COMPLEX,1, mpi_double_complex)
-fi
-
-
-	  echo "MPI CC $ff_mpi" >config_LIB_INFO
-
-		# We do not AC_DEFINE any special flag for parallel
-		# computation here, because it must only be set when the
- 		# parallel program is compiled (see src/mpi/Makfile.am)
-		ff_mpiprog="FreeFem++-mpi${EXEEXT}"
-   		  AC_SUBST(MPIPROG,"$ff_mpiprog")
-   		  AC_SUBST(MPISCRIPT,"ff-mpirun")
-   		  AC_SUBST(MPIRUN,$MPIRUN)
-                  AC_SUBST(MPICXX,$MPICXX)
-	else
-	        AC_SUBST(MPICXX,$ff_save_cxx)
-	fi
-
-	if test "$ff_mpi" = yes;
-	then
-	  if test "$enable_fortran" != no
-	  then	
-	      
-	      AC_ARG_VAR(MPIF77,[MPI Fortran 77 compiler command])
-	      if test -z "$MPIF77" ; then    
-		  AC_PATH_PROGS(MPIF77, mpif90$ff_mpi_suffix mpif77$ff_mpi_suffix hf77 mpxlf mpf77 mpif90 mpf90 mpxlf90 mpxlf95 mpxlf_r cmpifc cmpif90c, "",$ff_mpi_path)
-	      fi
-	      AC_SUBST(MPIF77)
-	      AC_ARG_VAR(MPIFC,[MPI Fortran 90  compiler command])
-	      if test -z "$MPIFC" ; then
-		  AC_PATH_PROGS(MPIFC, mpif90$ff_mpi_suffix mpxlf95_r mpxlf90_r mpxlf95 mpxlf90 mpf90 cmpif90c, "",$ff_mpi_path)
-	      fi		
-	      AC_SUBST(MPIFC)
-	  fi
-
-
-	ff_MPI_INCLUDE="$with_mpiinc"
-        ff_mpishow=`$MPICXX -show` 2>/dev/null
-        ff_mpicshow=`$MPICC -show` 2>/dev/null
-        ff_mpifcshow=`$MPIFC -show` 2>/dev/null
-	if test "$with_mpilibs" = no -o -z "$with_mpilibs" ; then	 
-	      [ff_MPI_INCLUDE=`echo $ff_mpishow|tr ' ' '\n'| grep -E '^-[^WLlOgp]|^-Wp,'|tr '\n' ' '`]
-	      ff_MPI_LIB_DIRS=""
-	      [ff_MPI_LIB=`echo $ff_mpishow|tr ' ' '\n'| grep -E '^-[Llp]|^-Wl,'|tr '\n' ' '`]
-	      [ff_MPI_LIBC=`echo $ff_mpicshow|tr ' ' '\n'| grep -E '^-[Llp]|^-Wl,'|tr '\n' ' '`]
-	      [ff_MPI_LIBFC=`echo $ff_mpifcshow|tr ' ' '\n'| grep -E '^-[Llp]|^-Wl,'|grep -v 'commons,use_dylibs' |tr '\n' ' '`]
-	      [ff_mpi_idir=`echo $ff_mpishow|tr ' ' '\n'| grep -E '^-I'|sed s/^-I//|tr '\n' ' '`' /usr/include']
-	  fi
-	    [ff_mpi_idir=`echo $ff_MPI_INCLUDE|tr ' ' '\n'| grep -E '^-I'|sed s/^-I//|tr '\n' ' '`' /usr/include']
-	    [ff_mpi_ldir=`echo $ff_MPI_LIB|tr ' ' '\n'| grep -E '^-[Llp]|^-Wl,'|sed -e 's/^-[Llp]//' -e 's/^-Wl,]//'  |tr '\n' ' '`' /usr/lib']
-	  
-	  if  test -z "$ff_MPI_INCLUDE_DIR" ; then  
-	  for i in $ff_mpi_idir; do
-	      if test -f "$i/mpi.h" -a -z "$ff_MPI_INCLUDE_DIR"  ;then
-		  ff_MPI_INCLUDE_DIR=$i
-	      fi
-	  done
-	  fi
-	  for i in $ff_mpi_ldir; do
-	      ff_tmp=`ls $i/libmpi.*|head -1`
-	      if test  -f "$ff_tmp"  -a -z "$ff_MPI_LIB_DIRS"  ;then
-		  ff_MPI_LIB_DIRS=$i
-	      fi
-	      done
-	  
-	  AC_SUBST(MPICXX,$MPICXX)		
-	  AC_ARG_VAR(MPICC,[MPI C compiler command in $ff_mpi_path])
-	  if test -z "$MPICC" ; then		
-	      AC_PATH_PROGS(MPICC,mpicc$ff_mpi_suffix hcc mpcc mpcc_r mpxlc cmpicc, "",$ff_mpi_path)
-	  fi
-	  AC_SUBST(MPICC,$MPICC)
-	  AC_SUBST(PASTIX_HOSTARCH,$ff_HOSTARCH_pastix)
-
-	  if test ! -f "$ff_MPI_INCLUDE_DIR/mpif.h"  ; then
-	      AC_MSG_NOTICE([ MPI without fortran no file "$ff_MPI_INCLUDE_DIR/mpif.h"  ])
-	  else
-	      if test -n "$MPIFC" ; then
-	           AC_FF_ADDWHERELIB(mpifc,$ff_MPI_LIBFC,$ff_MPI_INCLUDE)
-	           AC_FF_ADDWHERELIB(mpif77,$ff_MPI_LIBFC,$ff_MPI_INCLUDE)
-dnl		  [echo mpifc LD "'$ff_MPI_LIBFC'"   >>$ff_where_lib_conf ]
-dnl		  [echo mpifc INCLUDE "'$ff_MPI_INCLUDE'" >>$ff_where_lib_conf ]
-dnl		  [echo mpif77 LD "'$ff_MPI_LIBFC'"   >>$ff_where_lib_conf ]
-dnl		  [echo mpif77 INCLUDE "'$ff_MPI_INCLUDE'" >>$ff_where_lib_conf ]
-	      fi
-  	  fi
-	  if test -n "$MPICXX" ; then 	    
-              AC_FF_ADDWHERELIB(mpi,$ff_MPI_LIB,$ff_MPI_INCLUDE)
-dnl              [echo mpi LD "'$ff_MPI_LIB'"    >>$ff_where_lib_conf ]
-dnl              [echo mpi INCLUDE "'$ff_MPI_INCLUDE'" >>$ff_where_lib_conf ]
-	  fi
-	  AC_SUBST(MPI_INC_DIR,$ff_MPI_INCLUDE_DIR)      		
-	  AC_SUBST(MPI_INCLUDE,$ff_MPI_INCLUDE)
-	  AC_SUBST(MPI_LIB_DIRS,$ff_MPI_LIB_DIRS)
-	  AC_SUBST(MPI_LIB,$ff_MPI_LIB)
-	  AC_SUBST(MPI_LIBC,$ff_MPI_LIBC)
-	  AC_SUBST(MPI_LIBFC,$ff_MPI_LIBFC)
-	fi
-	CXX="$ff_save_cxx"
-	LIBS="$ff_save_libs"
+		MPI_Datatype xxxx=MPI_DOUBLE_COMPLEX;
+		])],
+    ff_mpi_double_complex=yes,
+    ff_mpi_double_complex=no)
+    AC_MSG_RESULT($ff_mpi_double_complex)
+    if test "$ff_mpi_double_complex" = yes  ; then
+	AC_DEFINE(HAVE_MPI_DOUBLE_COMPLEX,1, mpi_double_complex)
+    fi
 fi
 
-else
-          
-	  AC_SUBST(MPIRUN,"")      		
-	  AC_SUBST(MPICC,"")      		
-	  AC_SUBST(MPICXX,"")      		
-	  AC_SUBST(MPIF77,"")      		
-	  AC_SUBST(MPIFC,"")      		
-	  AC_SUBST(MPI_INCLUDE,"")
-	  AC_SUBST(MPI_LIB_DIRS,"")
-	  AC_SUBST(MPI_LIB,"")
-	  AC_SUBST(MPI_LIBC,"")
-	  AC_SUBST(MPI_LIBFC,"")
-          AC_SUBST(SKIP_TESTS_MPI,yes)
-	  ff_mpi=no
+# FFCS needs to change some of the FF makefiles to compile without MPI on MacOS
+AM_CONDITIONAL([FFCS_MPIOK],[test $ff_mpi = yes])
 
-fi
-#export PATH="$ff_save_path"
 # Looking for useful configuration utilities
 # ------------------------------------------
 
@@ -1138,9 +954,11 @@ dnl	echo lapack  LD  \'$ff_mkl_lapack\'  >>$ff_where_lib_conf
 dnl	echo scalapack  INCLUDE  \'$ff_blas_inc\' >>$ff_where_lib_conf	
 dnl	echo blacs  INCLUDE  \'$ff_blas_inc\' >>$ff_where_lib_conf	
 dnl	echo lapack INCLUDE  \'$ff_blas_inc\' >>$ff_where_lib_conf	
-
     else 
 	ff_mkl_libpath=no
+	
+	# FH - pardiso is there as soon as mkl is
+        enable_pardiso=no
     fi
 fi
 
@@ -1241,6 +1059,10 @@ then
 	    ff_blas_inc="-I${curdir}/download/blas/WinNT_PPRO256"
 	    ff_lapack_ok=ok
 	else
+
+            # ALH - FFCS - 23/12/8 - ATLAS compilation does not work anymore on Linux
+	    AC_MSG_ERROR(No BLAS library found - please install one or install Lapack)
+
 	    ff_download_blas=atlas-source
 	    ff_blas_libs="-L${curdir}/download/blas/ATLAS/lib/ff++ -lcblas -llapack -lf77blas -latlas"
 	    ff_blas_inc="-I${curdir}/download/blas/ATLAS/include"
@@ -1273,10 +1095,12 @@ then
 fi
 
 
-if test "$ff_blas_ok" = yes 
+# FFCS: do not specify the default BLAS LDADD if a specific one will be built in the download directory
+
+if test "$ff_blas_ok" = yes && test "$ff_download_blas" = ""
 then
-AC_FF_ADDWHERELIB(blas,$ff_blas_libs,)
-dnl    echo blas LD  \'$ff_blas_libs\'  >>$ff_where_lib_conf
+    AC_FF_ADDWHERELIB(blas,$ff_blas_libs,)
+    dnl    echo blas LD  \'$ff_blas_libs\'  >>$ff_where_lib_conf
 fi
 
 # end of BLAS -------------------
@@ -1512,16 +1336,23 @@ then
 		AC_DEFINE(HAVE_LIBUMFPACK,1, Umfpack is used for sparse matrices computations )			
 	 fi
 fi
-  if test "$ff_umfpack_ok" = yes 
-  then
-      AC_FF_ADDWHERELIB(amd,$ff_umfpack_libs,-I/usr/include/$ff_umfpack_dir)
-      AC_FF_ADDWHERELIB(umfpack,$ff_umfpack_libs,-I/usr/include/$ff_umfpack_dir)
 
-dnl      echo  amd LD \'$ff_umfpack_libs\'  >>$ff_where_lib_conf
-dnl      echo  amd INCLUDE  \'-I/usr/include/$ff_umfpack_dir\'  >>$ff_where_lib_conf
-dnl      echo  umfpack LD  '$ff_umfpack_libs\'   >>$ff_where_lib_conf     
-dnl       echo  umfpack  INCLUDE  \'-I/usr/include/$ff_umfpack_dir\'  >>$ff_where_lib_conf
-  fi   
+# FFCS - moved UMFPACK configuration settings in wherelib to _after_ configuring the download version, and removed
+# -I/usr/include/$ff_umfpack_dir from include options because it breaks the MingW64 compilation process.
+
+#if test $enable_ffcs = yes
+#then
+    if test "$ff_umfpack_ok" = yes 
+    then
+	AC_FF_ADDWHERELIB(amd,$ff_umfpack_libs,-I/usr/include/$ff_umfpack_dir)
+	AC_FF_ADDWHERELIB(umfpack,$ff_umfpack_libs,-I/usr/include/$ff_umfpack_dir)
+
+	dnl      echo  amd LD \'$ff_umfpack_libs\'  >>$ff_where_lib_conf
+	dnl      echo  amd INCLUDE  \'-I/usr/include/$ff_umfpack_dir\'  >>$ff_where_lib_conf
+	dnl      echo  umfpack LD  '$ff_umfpack_libs\'   >>$ff_where_lib_conf     
+	dnl       echo  umfpack  INCLUDE  \'-I/usr/include/$ff_umfpack_dir\'  >>$ff_where_lib_conf
+    fi   
+#fi
 
 LIBS="$ff_save_libs"
 
@@ -1544,6 +1375,16 @@ if test "$ff_umfpack_ok" = no -a "$enable_download" = yes
 	ff_umfpack_ok=yes
 fi
 
+# FFCS - moved UMFPACK configuration settings in wherelib to _after_ configuring the download version, and removed
+# -I/usr/include/$ff_umfpack_dir from include options because it breaks the MingW64 compilation process.
+
+## if test $enable_ffcs = yes && test "$ff_umfpack_ok" = yes 
+if  test "$ff_umfpack_ok" = yes 
+then
+    AC_FF_ADDWHERELIB(amd,$ff_umfpack_libs,)
+    AC_FF_ADDWHERELIB(umfpack,$ff_umfpack_libs,)
+fi   
+
 if test "$ff_umfpack_ok" = no
 then
 	 AC_MSG_NOTICE( -- NOT  UMFPACK  ff_wget = $ff_wget)
@@ -1624,6 +1465,9 @@ then
 	AC_MSG_RESULT($ff_dynload)
 fi
 
+# FFCS - -lm missing for ffmedit link stage on Debian Testing
+AC_CHECK_LIB(m,sin)
+
 # Checks that we also have the corresponding library
 if test "$ff_dynload" = yes
 then
@@ -1699,7 +1543,7 @@ fi
 # pdfsync.sty. So we need to be able to disable it.
 enable_pdf=yes
 AC_ARG_ENABLE(pdf,[  --disable-pdf	Disable PDF documentation building])
-if test "$enable_pdf" = yes 
+if test "$enable_pdf" != no
 then
    AC_CHECK_PROG(ff_pdflatex,pdflatex,yes,no)
    if test "$ff_pdflatex" = yes -a $EPSTOPDF != false -a $ff_convert = yes;
@@ -1725,9 +1569,22 @@ fi
 
 if test "$ff_mingw" = yes 
 then
+
+    # FFCS does not use FreeFem++-std, and Pcrgraph.cpp does not compile under mingwin64
+    if test $enable_ffcs = no
+    then
 	ff_stdprog="FreeFem++-std${EXEEXT}"
 	ff_std_graph_obj=Pcrgraph.$OBJEXT
+    fi
+
+    # ALH - FFCS - 30/11/8 - I need to get the output from FF for FFCS regression tests
+    if test $enable_ffcs = yes
+    then
+	ff_std_ldflags="-mconsole -mwindows"
+    else
 	ff_std_ldflags=-mwindows
+    fi
+
 	ff_std_libs=
 fi
 AC_SUBST(STD_GRAPH_OBJ,$ff_std_graph_obj)
@@ -1841,6 +1698,51 @@ else
 	AC_MSG_RESULT(yes)
 fi
 
+# Allow some downloaded tools not to be compiled
+# ----------------------------------------------
+
+# $1 = tool name, $2 = dynamic library name, $3 = download directory name if different from $1
+m4_define([FFCS_DISABLE_DOWNLOAD],
+    [AC_ARG_ENABLE($1,[  --disable-$1      Do not download $1])
+    if test "$enable_$1" = "no"
+    then
+        AC_SUBST([FFCS_COMPILE_$1],"")
+        AC_SUBST([FFCS_DYLIB_$1],"")
+    else
+        AC_SUBST([FFCS_COMPILE_$1],ifelse($3,,$1,$3))
+        AC_SUBST([FFCS_DYLIB_$1],$2)
+    fi
+])
+
+
+FFCS_DISABLE_DOWNLOAD(fflapack,fflapack.$DYLIB_SUFFIX)
+#  move FFCS_DISABLE_DOWNLOAD gls  , after find gsl ... 
+FFCS_DISABLE_DOWNLOAD(hips,hips_FreeFem.$DYLIB_SUFFIX)
+FFCS_DISABLE_DOWNLOAD(hypre,hypre.$DYLIB_SUFFIX)
+FFCS_DISABLE_DOWNLOAD(ipopt,ff-Ipopt.$DYLIB_SUFFIX)
+FFCS_DISABLE_DOWNLOAD(lapack,lapack.$DYLIB_SUFFIX)
+FFCS_DISABLE_DOWNLOAD(mmg3d,mmg3d-v4.0.$DYLIB_SUFFIX)
+FFCS_DISABLE_DOWNLOAD(mshmet,mshmet.$DYLIB_SUFFIX)
+FFCS_DISABLE_DOWNLOAD(mumps,"MUMPS_FreeFem.$DYLIB_SUFFIX MUMPS.$DYLIB_SUFFIX")
+FFCS_DISABLE_DOWNLOAD(mumps_seq,MUMPS_seq.$DYLIB_SUFFIX,mumps-seq)
+FFCS_DISABLE_DOWNLOAD(parms,parms_FreeFem.$DYLIB_SUFFIX)
+FFCS_DISABLE_DOWNLOAD(pastix,"interfacepastix.$DYLIB_SUFFIX complex_pastix_FreeFem.$DYLIB_SUFFIX real_pastix_FreeFem.$DYLIB_SUFFIX")
+FFCS_DISABLE_DOWNLOAD(scotch,scotch.$DYLIB_SUFFIX)
+FFCS_DISABLE_DOWNLOAD(superludist,"complex_SuperLU_DIST_FreeFem.$DYLIB_SUFFIX real_SuperLU_DIST_FreeFem.$DYLIB_SUFFIX dSuperLU_DIST.$DYLIB_SUFFIX")
+FFCS_DISABLE_DOWNLOAD(yams,freeyams.$DYLIB_SUFFIX)
+FFCS_DISABLE_DOWNLOAD(pipe,pipe.$DYLIB_SUFFIX)
+
+# FFCS - MUMPS_seq has a different Win32 compiler setup from FFCS, so we need to add some extra parameters
+if test "$OS" = Windows_NT
+then
+    CFLAGS="$CFLAGS -DWITHOUT_PTHREAD -DAdd_"
+
+    # we also need to satisfy ff-c++ that the pthread are not a blocking point
+    if test -n "$ff_pthread"  ; then
+       AC_FF_ADDWHERELIB(pthread,"",)
+    fi
+fi
+
 # Find out kernel and libc versions
 # ---------------------------------
 
@@ -1867,7 +1769,18 @@ AC_SUBST(CNOFLAGS,$CNOFLAGS) dnl for superludist CFLAGS without optim  ...
 AC_SUBST(FNOFLAGS,$FNOFLAGS) dnl for blacs CFLAGS without optim  ...
 # The final list of executable programs
 AC_SUBST(MEDITPROG,$ff_meditprog)
-AC_SUBST(FFGLUTPROG,$ff_ffglutprog)
+
+# ALH - FFCS - 5/1/9 - ffglut cannot be compiled with FFCS under Cygwin because it requires a GLUT versions that works
+# with Mingw, and the standard Cygwin Glut is not enough. But FFCS needs a working ffglut on other platforms for testing
+# purposes.
+
+if test "$ff_win32" = yes
+then
+	AC_SUBST(FFGLUTPROG,'')
+else
+	AC_SUBST(FFGLUTPROG,$ff_ffglutprog)
+fi
+
 AC_SUBST(BAMGPROG,$ff_bamgprog)
 AC_SUBST(STDPROG,$ff_stdprog)
 AC_SUBST(IDEPROG,$ff_ideprog)
@@ -1888,7 +1801,7 @@ ff_progs="FreeFem++-nw $ff_bamgprog  $ff_mpiprog $ff_meditprog $ff_ffglutprog"
 #metis INCLUDE -I/Users/hecht/work/freefem++/download/include/metis
 # mumps LD '-L/Users/hecht/work/freefem++/download//lib  -lpord -lmumps_common -ldmumps -lzmumps -lpord'
 # mumps INCLUDE '-I/Users/hecht/work/freefem++/download/include'
-# parmetis LD -L/Users/hecht/work/freefem++/download/lib -lparmetis -lmetis
+# parmetis LD -L/Users/hecht/work/freefem++/download/lib -lparmetis -lmetispar
 # parmetis INCLUDE -I/Users/hecht/work/freefem++/download/include/metis
 # scalapack LD '-L/Users/hecht/work/freefem++/download/lib  -lscalapack '
 # scalapack INCLUDE '-I/Users/hecht/work/freefem++/download/include'
@@ -2003,7 +1916,18 @@ m4_map([AC_FF_WHERELIB],[
     ]
     )
 
+# FFCS - 27/10/11 - Some extra conditionals for things that do not work on certain systems (eg MPI libraries under
+# Windows)
+#  remove gsl if not find ... FK 
 
+if test  "$ff_where_lib_conf_gsl" == 1  -a -z "$enable_gsl" ; then enable_gsl=no; fi;  
+if test  "$ff_where_lib_conf_mkl" == 1  -a -z "$enable_mkl" ; then enable_pardiso=no; fi;  
+FFCS_DISABLE_DOWNLOAD(gsl,"gsl.$DYLIB_SUFFIX NewSolver.$DYLIB_SUFFIX")
+FFCS_DISABLE_DOWNLOAD(pardiso,PARDISO.$DYLIB_SUFFIX)
+
+
+AM_CONDITIONAL([FFCS_WINDOWS],[test $OS = Windows_NT])
+ 
 # All makefiles
 AC_OUTPUT(Makefile
     download/Makefile
@@ -2083,13 +2007,22 @@ dnl    fi
 fi  # ---  test "$enable_download" = yes  ;then
 
 
-if test "$ff_glut_ok" != yes  ; then
-    AC_MSG_NOTICE([     *********************************************** ])
-    AC_MSG_NOTICE([     WARNING: you do not have the new grachics tools ])
-    AC_MSG_NOTICE([         because the configure do not find OpenGL, GLUT or pthread  developer stuff ])
-    AC_MSG_NOTICE([         read the README to find missing package  ])
-    AC_MSG_NOTICE([         F. Hecht  ])
-    AC_MSG_NOTICE([ to install missing package  under debian or ubuntu, try: sudo apt-get install freeglut3-dev ])	
-    AC_MSG_NOTICE([     *********************************************** ])
+# FFCS: remove this message because it could make the user think that something is broken
+if test $enable_ffcs = no
+then
+    if test "$ff_glut_ok" != yes  ; then
+	AC_MSG_NOTICE([     *********************************************** ])
+	AC_MSG_NOTICE([     WARNING: you do not have the new grachics tools ])
+	AC_MSG_NOTICE([         because the configure do not find OpenGL, GLUT or pthread  developer stuff ])
+	AC_MSG_NOTICE([         read the README to find missing package  ])
+	AC_MSG_NOTICE([         F. Hecht  ])
+	AC_MSG_NOTICE([ to install missing package  under debian or ubuntu, try: sudo apt-get install freeglut3-dev ])	
+	AC_MSG_NOTICE([     *********************************************** ])
+    fi
 fi
 
+# Local Variables:
+# mode:shell-script
+# ispell-local-dictionary:"british"
+# coding:utf-8
+# End:
diff --git a/download/Makefile.am b/download/Makefile.am
old mode 100644
new mode 100755
index 9fa70b4..76c3305
--- a/download/Makefile.am
+++ b/download/Makefile.am
@@ -1,141 +1,159 @@
-# Downloading and compiling extra libraries
-# -----------------------------------------
-
-# $Id: Makefile.am,v 1.16 2010/05/06 21:20:38 hecht Exp $
-
-SUBDIRS=blas arpack umfpack  
-EXTRA_DIST= \
-./nlopt/Make.inc ./nlopt/Makefile \
-./blacs/BLACS.patch \
-./blacs/Bmake-blacs.inc \
-./blacs/Makefile \
-./f2c/Makefile \
-./f2c/Makefile-MacOs \
-./f2c/f2c.h-int \
-./f2c/fort77.sed \
-./f2c/tt.f \
-./fftw/Makefile \
-./fftw/Makefile.am \
-./fltk/Makefile.am \
-./fltk/Makefile.in \
-./gmm/Makefile \
-./gmm/cxxflags \
-./headers-sparsesolver.inc \
-./hips/Makefile \
-./hips/SRC_SPKIT_makefile \
-./hips/hips-1.2b-rc4.patch \
-./hips/makefile-hips.inc \
-./hypre/Makefile \
-./hypre/ff-flags.inc \
-./metis/Makefile \
-./metis/Makefile-metis.in \
-./metis/patch-metis \
-./mmg3d/Makefile \
-./mmg3d/patch-mmg3dv4.diff \
-./mshmet/Makefile \
-./mshmet/Makefile-mshmet.inc \
-./mshmet/mshmet.2011.03.06.patch \
-./mshmet/mshmetlib-internal.h \
-./mshmet/mshmetlib.c \
-./mshmet/mshmetlib.h \
-./mumps/Makefile \
-./mumps-seq/Makefile-mumps-4.10.0.inc \
-./mumps-seq/Makefile \
-./mumps/Makefile-mumps-4.10.0.inc \
-./mumps/MUMPS_4.10.0.patch \
-./parmetis/Makefile-parmetis.in \
-./parmetis/ParMetis-3.1.1-ok/stdheaders.h \
-./parmetis/makefile \
-./parmetis/parmetis-3.1.1.patch \
-./parms/Makefile \
-./parms/makefile-parms.in \
-./pastix/Makefile \
-./pastix/config-pastix-complex.in \
-./pastix/config-pastix-real.in \
-./pastix/pastix_release_2200-blend.patch \
-./pastix/pastix_release_2200-gen.patch \
-./pastix/patch-pastix_long_complex.h \
-./scalapack/Makefile \
-./scalapack/SLmake-scalapack.inc \
-./scotch/Makefile \
-./scotch/Makefile-scotch.inc \
-./scotch/Makefile.patch \
-./scotch/scotch_5.1_esmumps.patch \
-./superlu/Makefile \
-./superlu/make.inc \
-./superludist/Makefile \
-./superludist/make-superlu.inc \
-./superludist/superludist_2.3.patch \
-./tetgen/Makefile \
-./tetgen/tetgen1.4.2.patch \
-./yams/Makefile \
-./yams/freeyams.2012.02.05.patch \
-./yams/makefile-yams.inc \
-./yams/yamslib.c \
-./yams/yamslib.h \
-./yams/yamslib_internal.h \
-ipopt/Makefile	\
-ipopt/Makefile.inc.in \
-ipopt/patch-IpBlas 
-
-# blacs is include in  scalapack 2.0.2 
-MPI_SOFT= parmetis  scalapack scotch superludist mumps pastix  hips parms 
-LIST_SOFT=tetgen superlu fftw metis mshmet yams mmg3d gmm  nlopt mumps-seq ipopt 
-all-recursive: bin lib include pkg
-
-lib: 
-	mkdir lib
-bin: 
-	mkdir bin
-include:
-	mkdir  include
-pkg:
-	mkdir pkg
-
-
-
-all-local:bin lib include pkg  $(DOWNLOADCOMPILE) 
-
-WHERE-LD: tag-compile-pkg
-	touch ../examples++-load/WHERE_LIBRARY-config ../examples++-load/WHERE_LIBRARY		
-	grep LD ../examples++-load/WHERE_LIBRARY ../examples++-load/WHERE_LIBRARY-config >WHERE-LD
-
-compile-dir: 
-	@echo "\n\n ****** $(COMPILEDIR) ****** \n\n";
-	- at if [ 0 -eq `egrep ':$(COMPILEDIR)' WHERE-LD | wc -l` ] ;then \
-	  cd $(COMPILEDIR) && $(MAKE) $(DIRTARGET) ; \
-	else \
-	 echo $(COMPILEDIR) is in WHERE- files ;\
-	fi 
-compile-pkg: tag-compile-pkg WHERE-LD
-tag-compile-pkg: bin lib include pkg FORCE
-	- at if [ -n "$(WGET)" ] ; then \
-	for d in $(LIST_SOFT) ; do $(MAKE) compile-dir COMPILEDIR=$$d ;done ;\
-	if [ -n "$(MPICC)" ] ; then \
-	for d in $(MPI_SOFT) ; do 	$(MAKE) compile-dir COMPILEDIR=$$d ; done;\
-	fi;fi
-	touch tag-compile-pkg
-FORCE:
-
-re-install:
-	-rm -rf	 include lib bin 
-	mkdir   include lib bin 	 
-	$(MAKE) compile-pkg DIRTARGET=install
-WHERE:
-	-rm -rf  lib/WHERE.*
-	$(MAKE) compile-pkg DIRTARGET=WHERE
-
-clean-local:
-	-rm -rf	 tag-* include lib bin 
-	mkdir   include lib bin 	
-	-rm */FAIT */FAIRE 
-	-if [ -n "$(WGET)" ] ; then \
-	for d in  $(LIST_SOFT)  ; do \
-	if [ -d "$$d" ] ; then  echo "$(MAKE) clean -C $$d  " ;   $(MAKE) clean -C $$d  ; else echo ** missing "$$d" directory ; fi; \
-	done ;\
-	if [ -n "$(MPICC)" ] ; then \
-	for d in $(MPI_SOFT) ; do \
-	if [ -d "$$d" ] ; then  echo "$(MAKE) clean  -C $$d  " ;   $(MAKE) clean  -C $$d  ; else echo ** missing "$$d" directory ;  fi; \
-	done ;\
-	fi; \
-	fi 
+# Downloading and compiling extra libraries
+# -----------------------------------------
+
+# $Id: Makefile.am,v 1.16 2010/05/06 21:20:38 hecht Exp $
+
+SUBDIRS=blas arpack umfpack  
+EXTRA_DIST= \
+./nlopt/Make.inc ./nlopt/Makefile \
+./blacs/BLACS.patch \
+./blacs/BLACS_gridinit_.c-return-values.patch \
+./blacs/Bmake-blacs.inc \
+./blacs/Makefile \
+./f2c/Makefile \
+./f2c/Makefile-MacOs \
+./f2c/f2c.h-int \
+./f2c/fort77.sed \
+./f2c/tt.f \
+./fftw/Makefile \
+./fftw/Makefile.am \
+./fltk/Makefile.am \
+./fltk/Makefile.in \
+./gmm/Makefile \
+./gmm/cxxflags \
+./headers-sparsesolver.inc \
+./hips/Makefile \
+./hips/SRC_SPKIT_makefile \
+./hips/hips-1.2b-rc4.patch \
+./hips/makefile-hips.inc \
+./hypre/Makefile \
+./hypre/ff-flags.inc \
+./metis/Makefile \
+./metis/Makefile-metis.in \
+./metis/patch-metis \
+./metis/metis-4.0_main_return.patch \
+./mmg3d/Makefile \
+./mmg3d/patch-mmg3dv4.diff \
+./mshmet/Makefile \
+./mshmet/Makefile-mshmet.inc \
+./mshmet/mshmet.2011.03.06.patch \
+./mshmet/mshmet.2012.04.25_i586.patch \
+./mshmet/mshmetlib-internal.h \
+./mshmet/mshmetlib.c \
+./mshmet/mshmetlib.h \
+./mumps/Makefile \
+./mumps-seq/Makefile-mumps-4.10.0.inc \
+./mumps-seq/Makefile \
+./mumps/Makefile-mumps-4.10.0.inc \
+./mumps/MUMPS_4.10.0.patch \
+./parmetis/Makefile-parmetis.in \
+./parmetis/ParMetis-3.1.1-ok/stdheaders.h \
+./parmetis/makefile \
+./parmetis/parmetis-3.1.1.patch \
+./parms/Makefile \
+./parms/makefile-parms.in \
+./pastix/Makefile \
+./pastix/config-pastix-complex.in \
+./pastix/config-pastix-real.in \
+./pastix/pastix_release_2200-blend.patch \
+./pastix/pastix_release_2200-gen.patch \
+./pastix/patch-pastix_long_complex.h \
+./scalapack/Makefile \
+./scalapack/SLmake-scalapack.inc \
+./scotch/Makefile \
+./scotch/Makefile-scotch.inc \
+./scotch/Makefile.patch \
+./scotch/scotch_5.1_esmumps.patch \
+./superlu/Makefile \
+./superlu/make.inc \
+./superludist/Makefile \
+./superludist/make-superlu.inc \
+./superludist/superludist_2.3.patch \
+./superludist/superludist_3.0-printf.patch \
+./superludist/superludist_3.0-cast_warning.patch \
+./superludist/superludist_3.0-return_values.patch \
+./superludist/superludist_3.0-operation_undefined.patch \
+./tetgen/Makefile \
+./tetgen/tetgen1.4.2.patch \
+./tetgen/patches.win64 \
+./yams/Makefile \
+./yams/freeyams.2012.02.05.patch \
+./yams/freeyams.2012.02.05-return-values.patch \
+./yams/makefile-yams.inc \
+./yams/yamslib.c \
+./yams/yamslib.h \
+./yams/yamslib_internal.h \
+ipopt/Makefile	\
+ipopt/Makefile.inc.in \
+ipopt/patch-IpBlas 
+
+# FFCS: See [[file:../../../configure.ac::tools_problems_all_platforms]] for reasons why some tools may be deactivated
+
+# <<no_more_blacs>> blacs is include in  scalapack 2.0.2 
+
+MPI_SOFT=parmetis scalapack  @FFCS_COMPILE_superludist@ @FFCS_COMPILE_mumps@	\
+	@FFCS_COMPILE_pastix@  @FFCS_COMPILE_hips@ @FFCS_COMPILE_parms@
+LIST_SOFT=tetgen superlu fftw metis @FFCS_COMPILE_scotch@ @FFCS_COMPILE_mshmet@ @FFCS_COMPILE_yams@ @FFCS_COMPILE_mmg3d@ gmm nlopt	\
+	@FFCS_COMPILE_mumps_seq@ @FFCS_COMPILE_ipopt@
+all-recursive: bin lib include pkg
+
+lib: 
+	mkdir lib
+bin: 
+	mkdir bin
+include:
+	mkdir  include
+pkg:
+	mkdir pkg
+
+# ALH - /download/yams and /download/mshmet need /src/libMesh/libmesh.a but /src is compiled after /download, so we
+# need to compile it now
+
+lib/libMesh.a:lib include
+	cd ../src/libMesh && $(MAKE) $(AM_MAKEFLAGS)
+	test -f ../src/libMesh/libMesh.a
+	mkdir -p include/libMesh
+	cp ../src/libMesh/*h  include/libMesh
+	echo libMesh  LD -L at DIR@/lib -lMesh  > lib/WHERE.libMesh
+	echo libMesh INCLUDE -I at DIR@/include/libMesh >> lib/WHERE.libMesh
+	cp ../src/libMesh/libMesh.a lib/libMesh.a
+
+all-local:bin lib include lib/libMesh.a pkg  $(DOWNLOADCOMPILE) 
+
+WHERE-LD: tag-compile-pkg
+	touch ../examples++-load/WHERE_LIBRARY-config ../examples++-load/WHERE_LIBRARY		
+	grep LD ../examples++-load/WHERE_LIBRARY ../examples++-load/WHERE_LIBRARY-config >WHERE-LD
+
+# FFCS: need to stop at the first error to make sure that all libraries are correctly compiled
+compile-dir: 
+	@echo "\n\n ****** $(COMPILEDIR) ****** \n\n";
+	@if [ 0 -eq `egrep ':$(COMPILEDIR)' WHERE-LD | wc -l` ] ;then \
+	  cd $(COMPILEDIR) && $(MAKE) $(DIRTARGET) ; \
+	else \
+	 echo $(COMPILEDIR) is in WHERE- files ;\
+	fi 
+compile-pkg: tag-compile-pkg WHERE-LD
+
+# FFCS: need to stop at the first error to make sure that all libraries are correctly compiled
+tag-compile-pkg: bin lib include pkg FORCE
+	@if [ -n "$(WGET)" ] ; then \
+	for d in $(LIST_SOFT) ; do $(MAKE) compile-dir COMPILEDIR=$$d || exit 1;done ;\
+	if [ -n "$(MPICC)" ] ; then \
+	for d in $(MPI_SOFT) ; do 	$(MAKE) compile-dir COMPILEDIR=$$d || exit 1; done;\
+	fi;fi
+	touch tag-compile-pkg
+FORCE:
+
+re-install: 
+	$(MAKE) compile-pkg DIRTARGET=install
+WHERE:
+	$(MAKE) compile-pkg DIRTARGET=WHERE
+
+clean-local:
+	-rm -rf	 tag-* include lib bin 
+	-mkdir   include lib bin 	
+	-rm */FAIT */FAIRE 
+# 	FFCS - make sure that all directories are cleaned. Thisis especially important under Windows because there is no
+# 	compilation dependencies control there (see
+# 	[[file:c:/cygwin/home/alh/ffcs/dist/configure.ac::dependency_tracking]])
+	for d in $(LIST_SOFT) $(MPI_SOFT) ; do $(MAKE) clean -C $$d ; done
diff --git a/download/Makefile.in b/download/Makefile.in
index 1a28c33..2fb9c27 100644
--- a/download/Makefile.in
+++ b/download/Makefile.in
@@ -59,7 +59,8 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(top_srcdir)/mkinstalldirs AUTHORS
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/acmacros.m4 \
-	$(top_srcdir)/acoptim.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/acoptim.m4 $(top_srcdir)/acmpi.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -189,11 +190,47 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EIGENOBJ = @EIGENOBJ@
+ENABLE_FFCS = @ENABLE_FFCS@
 EPSTOPDF = @EPSTOPDF@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+FFCS_COMPILE_fflapack = @FFCS_COMPILE_fflapack@
+FFCS_COMPILE_gsl = @FFCS_COMPILE_gsl@
+FFCS_COMPILE_hips = @FFCS_COMPILE_hips@
+FFCS_COMPILE_hypre = @FFCS_COMPILE_hypre@
+FFCS_COMPILE_ipopt = @FFCS_COMPILE_ipopt@
+FFCS_COMPILE_lapack = @FFCS_COMPILE_lapack@
+FFCS_COMPILE_mmg3d = @FFCS_COMPILE_mmg3d@
+FFCS_COMPILE_mshmet = @FFCS_COMPILE_mshmet@
+FFCS_COMPILE_mumps = @FFCS_COMPILE_mumps@
+FFCS_COMPILE_mumps_seq = @FFCS_COMPILE_mumps_seq@
+FFCS_COMPILE_pardiso = @FFCS_COMPILE_pardiso@
+FFCS_COMPILE_parms = @FFCS_COMPILE_parms@
+FFCS_COMPILE_pastix = @FFCS_COMPILE_pastix@
+FFCS_COMPILE_pipe = @FFCS_COMPILE_pipe@
+FFCS_COMPILE_scotch = @FFCS_COMPILE_scotch@
+FFCS_COMPILE_superludist = @FFCS_COMPILE_superludist@
+FFCS_COMPILE_yams = @FFCS_COMPILE_yams@
+FFCS_DYLIB_fflapack = @FFCS_DYLIB_fflapack@
+FFCS_DYLIB_gsl = @FFCS_DYLIB_gsl@
+FFCS_DYLIB_hips = @FFCS_DYLIB_hips@
+FFCS_DYLIB_hypre = @FFCS_DYLIB_hypre@
+FFCS_DYLIB_ipopt = @FFCS_DYLIB_ipopt@
+FFCS_DYLIB_lapack = @FFCS_DYLIB_lapack@
+FFCS_DYLIB_mmg3d = @FFCS_DYLIB_mmg3d@
+FFCS_DYLIB_mshmet = @FFCS_DYLIB_mshmet@
+FFCS_DYLIB_mumps = @FFCS_DYLIB_mumps@
+FFCS_DYLIB_mumps_seq = @FFCS_DYLIB_mumps_seq@
+FFCS_DYLIB_pardiso = @FFCS_DYLIB_pardiso@
+FFCS_DYLIB_parms = @FFCS_DYLIB_parms@
+FFCS_DYLIB_pastix = @FFCS_DYLIB_pastix@
+FFCS_DYLIB_pipe = @FFCS_DYLIB_pipe@
+FFCS_DYLIB_scotch = @FFCS_DYLIB_scotch@
+FFCS_DYLIB_superludist = @FFCS_DYLIB_superludist@
+FFCS_DYLIB_yams = @FFCS_DYLIB_yams@
+FFCS_MAKEFLAGS = @FFCS_MAKEFLAGS@
 FFGLUTNAME = @FFGLUTNAME@
 FFGLUTPROG = @FFGLUTPROG@
 FFLAGS = @FFLAGS@
@@ -364,6 +401,7 @@ SUBDIRS = blas arpack umfpack
 EXTRA_DIST = \
 ./nlopt/Make.inc ./nlopt/Makefile \
 ./blacs/BLACS.patch \
+./blacs/BLACS_gridinit_.c-return-values.patch \
 ./blacs/Bmake-blacs.inc \
 ./blacs/Makefile \
 ./f2c/Makefile \
@@ -387,11 +425,13 @@ EXTRA_DIST = \
 ./metis/Makefile \
 ./metis/Makefile-metis.in \
 ./metis/patch-metis \
+./metis/metis-4.0_main_return.patch \
 ./mmg3d/Makefile \
 ./mmg3d/patch-mmg3dv4.diff \
 ./mshmet/Makefile \
 ./mshmet/Makefile-mshmet.inc \
 ./mshmet/mshmet.2011.03.06.patch \
+./mshmet/mshmet.2012.04.25_i586.patch \
 ./mshmet/mshmetlib-internal.h \
 ./mshmet/mshmetlib.c \
 ./mshmet/mshmetlib.h \
@@ -423,10 +463,16 @@ EXTRA_DIST = \
 ./superludist/Makefile \
 ./superludist/make-superlu.inc \
 ./superludist/superludist_2.3.patch \
+./superludist/superludist_3.0-printf.patch \
+./superludist/superludist_3.0-cast_warning.patch \
+./superludist/superludist_3.0-return_values.patch \
+./superludist/superludist_3.0-operation_undefined.patch \
 ./tetgen/Makefile \
 ./tetgen/tetgen1.4.2.patch \
+./tetgen/patches.win64 \
 ./yams/Makefile \
 ./yams/freeyams.2012.02.05.patch \
+./yams/freeyams.2012.02.05-return-values.patch \
 ./yams/makefile-yams.inc \
 ./yams/yamslib.c \
 ./yams/yamslib.h \
@@ -436,9 +482,15 @@ ipopt/Makefile.inc.in \
 ipopt/patch-IpBlas 
 
 
-# blacs is include in  scalapack 2.0.2 
-MPI_SOFT = parmetis  scalapack scotch superludist mumps pastix  hips parms 
-LIST_SOFT = tetgen superlu fftw metis mshmet yams mmg3d gmm  nlopt mumps-seq ipopt 
+# FFCS: See [[file:../../../configure.ac::tools_problems_all_platforms]] for reasons why some tools may be deactivated
+
+# <<no_more_blacs>> blacs is include in  scalapack 2.0.2 
+MPI_SOFT = parmetis scalapack  @FFCS_COMPILE_superludist@ @FFCS_COMPILE_mumps@	\
+	@FFCS_COMPILE_pastix@  @FFCS_COMPILE_hips@ @FFCS_COMPILE_parms@
+
+LIST_SOFT = tetgen superlu fftw metis @FFCS_COMPILE_scotch@ @FFCS_COMPILE_mshmet@ @FFCS_COMPILE_yams@ @FFCS_COMPILE_mmg3d@ gmm nlopt	\
+	@FFCS_COMPILE_mumps_seq@ @FFCS_COMPILE_ipopt@
+
 all: all-recursive
 
 .SUFFIXES:
@@ -755,51 +807,57 @@ include:
 pkg:
 	mkdir pkg
 
-all-local:bin lib include pkg  $(DOWNLOADCOMPILE) 
+# ALH - /download/yams and /download/mshmet need /src/libMesh/libmesh.a but /src is compiled after /download, so we
+# need to compile it now
+
+lib/libMesh.a:lib include
+	cd ../src/libMesh && $(MAKE) $(AM_MAKEFLAGS)
+	test -f ../src/libMesh/libMesh.a
+	mkdir -p include/libMesh
+	cp ../src/libMesh/*h  include/libMesh
+	echo libMesh  LD -L at DIR@/lib -lMesh  > lib/WHERE.libMesh
+	echo libMesh INCLUDE -I at DIR@/include/libMesh >> lib/WHERE.libMesh
+	cp ../src/libMesh/libMesh.a lib/libMesh.a
+
+all-local:bin lib include lib/libMesh.a pkg  $(DOWNLOADCOMPILE) 
 
 WHERE-LD: tag-compile-pkg
 	touch ../examples++-load/WHERE_LIBRARY-config ../examples++-load/WHERE_LIBRARY		
 	grep LD ../examples++-load/WHERE_LIBRARY ../examples++-load/WHERE_LIBRARY-config >WHERE-LD
 
+# FFCS: need to stop at the first error to make sure that all libraries are correctly compiled
 compile-dir: 
 	@echo "\n\n ****** $(COMPILEDIR) ****** \n\n";
-	- at if [ 0 -eq `egrep ':$(COMPILEDIR)' WHERE-LD | wc -l` ] ;then \
+	@if [ 0 -eq `egrep ':$(COMPILEDIR)' WHERE-LD | wc -l` ] ;then \
 	  cd $(COMPILEDIR) && $(MAKE) $(DIRTARGET) ; \
 	else \
 	 echo $(COMPILEDIR) is in WHERE- files ;\
 	fi 
 compile-pkg: tag-compile-pkg WHERE-LD
+
+# FFCS: need to stop at the first error to make sure that all libraries are correctly compiled
 tag-compile-pkg: bin lib include pkg FORCE
-	- at if [ -n "$(WGET)" ] ; then \
-	for d in $(LIST_SOFT) ; do $(MAKE) compile-dir COMPILEDIR=$$d ;done ;\
+	@if [ -n "$(WGET)" ] ; then \
+	for d in $(LIST_SOFT) ; do $(MAKE) compile-dir COMPILEDIR=$$d || exit 1;done ;\
 	if [ -n "$(MPICC)" ] ; then \
-	for d in $(MPI_SOFT) ; do 	$(MAKE) compile-dir COMPILEDIR=$$d ; done;\
+	for d in $(MPI_SOFT) ; do 	$(MAKE) compile-dir COMPILEDIR=$$d || exit 1; done;\
 	fi;fi
 	touch tag-compile-pkg
 FORCE:
 
-re-install:
-	-rm -rf	 include lib bin 
-	mkdir   include lib bin 	 
+re-install: 
 	$(MAKE) compile-pkg DIRTARGET=install
 WHERE:
-	-rm -rf  lib/WHERE.*
 	$(MAKE) compile-pkg DIRTARGET=WHERE
 
 clean-local:
 	-rm -rf	 tag-* include lib bin 
-	mkdir   include lib bin 	
+	-mkdir   include lib bin 	
 	-rm */FAIT */FAIRE 
-	-if [ -n "$(WGET)" ] ; then \
-	for d in  $(LIST_SOFT)  ; do \
-	if [ -d "$$d" ] ; then  echo "$(MAKE) clean -C $$d  " ;   $(MAKE) clean -C $$d  ; else echo ** missing "$$d" directory ; fi; \
-	done ;\
-	if [ -n "$(MPICC)" ] ; then \
-	for d in $(MPI_SOFT) ; do \
-	if [ -d "$$d" ] ; then  echo "$(MAKE) clean  -C $$d  " ;   $(MAKE) clean  -C $$d  ; else echo ** missing "$$d" directory ;  fi; \
-	done ;\
-	fi; \
-	fi 
+# 	FFCS - make sure that all directories are cleaned. Thisis especially important under Windows because there is no
+# 	compilation dependencies control there (see
+# 	[[file:c:/cygwin/home/alh/ffcs/dist/configure.ac::dependency_tracking]])
+	for d in $(LIST_SOFT) $(MPI_SOFT) ; do $(MAKE) clean -C $$d ; done
 
 # 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/download/arpack/Makefile.am b/download/arpack/Makefile.am
index 59f231b..31e887a 100644
--- a/download/arpack/Makefile.am
+++ b/download/arpack/Makefile.am
@@ -1,68 +1,71 @@
-# Downloading and compiling extra libraries
-# -----------------------------------------
-
-# $Id$
-
-all-local: $(DOWNLOAD_ARPACK)
-EXTRA_DIST=ARmake.m4 arpack-patch-lapack.tar.gz 
-
-# Downloading and compiling ARPACK
-# --------------------------------
-
-# set in configure 
-#ARPACKLIB=ARPACK/libarpack_ff++.a
-DIRPKG=../pkg
-ARPACK96_TAR_GZ=$(DIRPKG)/arpack96.tar.gz
-PATCH_TAR_GZ=$(DIRPKG)/patch.tar.gz
-
-arpack: $(ARPACKLIB) 
-
-$(ARPACKLIB): ARPACK/fait
-	if [ -n '@FF_LAPACKdir@' ] ; then \
-	$(F77) -c `echo $(FFLAGS)\ |sed -e s/-O.\*\ // ` ARPACK/LAPACK/dlamch.f -o ARPACK/LAPACK/dlamch.o; \
-	fi; \
-	cd ARPACK && make lib 
-	if test -n '@FF_LAPACKdir@' ; then \
-	$(AR) $(ARFLAGS) $(LAPACK_arpack_LIB)  ARPACK/SRC/*.o  ARPACK/UTIL/*.o ARPACK/LAPACK/*.o ;\
-	else \
-	$(AR) $(ARFLAGS) $(ARPACKLIB)  ARPACK/SRC/*.o  ARPACK/UTIL/*.o ;\
-	fi
-
-
-
-ARPACK/fait: $(ARPACK96_TAR_GZ) $(PATCH_TAR_GZ) ARmake.m4 Makefile
-	-rm -rf ARPACK
-	gunzip -c $(ARPACK96_TAR_GZ) | tar xf -
-	gunzip -c $(PATCH_TAR_GZ) | tar xf -
-	gunzip -c arpack-patch-lapack.tar.gz | tar xf -
-	for i in ARPACK/SRC/*.f ; do \
-	    mv  $$i $$i.cpy; sed -e 's/, second/, secnd2/' -e 's/call *second/call secnd2/' <$$i.cpy >$$i;rm $$i.cpy; done 
-	for i in  ARPACK/UTIL/second.f;  do  \
-	   mv  $$i $$i.cpy; cat $$i.cpy| sed 's/ SECOND *(/ secnd2(/'|grep -v EXTERNAL  >$$i;rm $$i.cpy; done 
-	m4  -DFF_BLASLIB="$(BLASLIB)" \
-	    -DFF_ARPACKLIB="$(ARPACKLIB)" \
-            -DFF_LAPACK_arpack_LIB="$(LAPACK_arpack_LIB)" \
-	    -DFF_FC="@F77@" \
-            -DFF_FFLAGS="@FFLAGS@" \
-	    -DFF_LAPACKdir='@FF_LAPACKdir@' \
-            -DFF_LDFLAGS="@LDFLAGS@" \
-            -DFF_HOME=`pwd`/ARPACK \
-	    -DFF_SECOND="@FF_SECOND@" \
-	    -DFF_AR="@AR@" \
-	    -DFF_ARFLAGS="@ARFLAGS@" \
-	    -DFF_RANLIB="@RANLIB@" \
-	    ARmake.m4 >ARPACK/ARmake.inc
-#
-#	cp ARPACK/UTIL/Makefile ARPACK/Makefile_UTIL
-#	sed  -e '1,$$s/second.o/$$(SECOND_O)/' <ARPACK/Makefile_UTIL  >ARPACK/UTIL/Makefile  
-	touch ARPACK/fait
-	cd ARPACK/LAPACK;
-
-$(ARPACK96_TAR_GZ):
-	cd $(DIRPKG);@WGET@ -N http://www.caam.rice.edu/software/ARPACK/SRC/arpack96.tar.gz
-
-$(PATCH_TAR_GZ):
-	cd $(DIRPKG);@WGET@ -N http://www.caam.rice.edu/software/ARPACK/SRC/patch.tar.gz
-
-clean-local:
-	-rm -r ARPACK ../lib/libarpack.a
+# Downloading and compiling extra libraries
+# -----------------------------------------
+
+# $Id$
+
+all-local: $(DOWNLOAD_ARPACK)
+EXTRA_DIST=ARmake.m4 arpack-patch-lapack.tar.gz 
+
+# Downloading and compiling ARPACK
+# --------------------------------
+
+# set in configure 
+#ARPACKLIB=ARPACK/libarpack_ff++.a
+DIRPKG=../pkg
+ARPACK96_TAR_GZ=$(DIRPKG)/arpack96.tar.gz
+PATCH_TAR_GZ=$(DIRPKG)/patch.tar.gz
+
+arpack: $(ARPACKLIB) 
+
+# FFCS: need to add $(RANLIB) under mingw64 to avoid "archive has no index" error
+
+$(ARPACKLIB): ARPACK/fait
+	if [ -n '@FF_LAPACKdir@' ] ; then \
+	$(F77) -c `echo $(FFLAGS)\ |sed -e s/-O.\*\ // ` ARPACK/LAPACK/dlamch.f -o ARPACK/LAPACK/dlamch.o; \
+	fi; \
+	cd ARPACK && make lib 
+	if test -n '@FF_LAPACKdir@' ; then \
+	$(AR) $(ARFLAGS) $(LAPACK_arpack_LIB)  ARPACK/SRC/*.o  ARPACK/UTIL/*.o ARPACK/LAPACK/*.o ;\
+	$(RANLIB) $(LAPACK_arpack_LIB) ;\
+	else \
+	$(AR) $(ARFLAGS) $(ARPACKLIB)  ARPACK/SRC/*.o  ARPACK/UTIL/*.o ;\
+	fi
+
+
+
+ARPACK/fait: $(ARPACK96_TAR_GZ) $(PATCH_TAR_GZ) ARmake.m4 Makefile
+	-rm -rf ARPACK
+	gunzip -c $(ARPACK96_TAR_GZ) | tar xf -
+	gunzip -c $(PATCH_TAR_GZ) | tar xf -
+	gunzip -c arpack-patch-lapack.tar.gz | tar xf -
+	for i in ARPACK/SRC/*.f ; do \
+	    mv  $$i $$i.cpy; sed -e 's/, second/, secnd2/' -e 's/call *second/call secnd2/' <$$i.cpy >$$i;rm $$i.cpy; done 
+	for i in  ARPACK/UTIL/second.f;  do  \
+	   mv  $$i $$i.cpy; cat $$i.cpy| sed 's/ SECOND *(/ secnd2(/'|grep -v EXTERNAL  >$$i;rm $$i.cpy; done 
+	m4  -DFF_BLASLIB="$(BLASLIB)" \
+	    -DFF_ARPACKLIB="$(ARPACKLIB)" \
+            -DFF_LAPACK_arpack_LIB="$(LAPACK_arpack_LIB)" \
+	    -DFF_FC="@F77@" \
+            -DFF_FFLAGS="@FFLAGS@" \
+	    -DFF_LAPACKdir='@FF_LAPACKdir@' \
+            -DFF_LDFLAGS="@LDFLAGS@" \
+            -DFF_HOME=`pwd`/ARPACK \
+	    -DFF_SECOND="@FF_SECOND@" \
+	    -DFF_AR="@AR@" \
+	    -DFF_ARFLAGS="@ARFLAGS@" \
+	    -DFF_RANLIB="@RANLIB@" \
+	    ARmake.m4 >ARPACK/ARmake.inc
+#
+#	cp ARPACK/UTIL/Makefile ARPACK/Makefile_UTIL
+#	sed  -e '1,$$s/second.o/$$(SECOND_O)/' <ARPACK/Makefile_UTIL  >ARPACK/UTIL/Makefile  
+	touch ARPACK/fait
+	cd ARPACK/LAPACK;
+
+$(ARPACK96_TAR_GZ):
+	cd $(DIRPKG);@WGET@ -N http://www.caam.rice.edu/software/ARPACK/SRC/arpack96.tar.gz
+
+$(PATCH_TAR_GZ):
+	cd $(DIRPKG);@WGET@ -N http://www.caam.rice.edu/software/ARPACK/SRC/patch.tar.gz
+
+clean-local:
+	-rm -r ARPACK ../lib/libarpack.a
diff --git a/download/arpack/Makefile.in b/download/arpack/Makefile.in
index d4a7e30..d38f096 100644
--- a/download/arpack/Makefile.in
+++ b/download/arpack/Makefile.in
@@ -59,7 +59,8 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(top_srcdir)/mkinstalldirs
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/acmacros.m4 \
-	$(top_srcdir)/acoptim.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/acoptim.m4 $(top_srcdir)/acmpi.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -129,11 +130,47 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EIGENOBJ = @EIGENOBJ@
+ENABLE_FFCS = @ENABLE_FFCS@
 EPSTOPDF = @EPSTOPDF@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+FFCS_COMPILE_fflapack = @FFCS_COMPILE_fflapack@
+FFCS_COMPILE_gsl = @FFCS_COMPILE_gsl@
+FFCS_COMPILE_hips = @FFCS_COMPILE_hips@
+FFCS_COMPILE_hypre = @FFCS_COMPILE_hypre@
+FFCS_COMPILE_ipopt = @FFCS_COMPILE_ipopt@
+FFCS_COMPILE_lapack = @FFCS_COMPILE_lapack@
+FFCS_COMPILE_mmg3d = @FFCS_COMPILE_mmg3d@
+FFCS_COMPILE_mshmet = @FFCS_COMPILE_mshmet@
+FFCS_COMPILE_mumps = @FFCS_COMPILE_mumps@
+FFCS_COMPILE_mumps_seq = @FFCS_COMPILE_mumps_seq@
+FFCS_COMPILE_pardiso = @FFCS_COMPILE_pardiso@
+FFCS_COMPILE_parms = @FFCS_COMPILE_parms@
+FFCS_COMPILE_pastix = @FFCS_COMPILE_pastix@
+FFCS_COMPILE_pipe = @FFCS_COMPILE_pipe@
+FFCS_COMPILE_scotch = @FFCS_COMPILE_scotch@
+FFCS_COMPILE_superludist = @FFCS_COMPILE_superludist@
+FFCS_COMPILE_yams = @FFCS_COMPILE_yams@
+FFCS_DYLIB_fflapack = @FFCS_DYLIB_fflapack@
+FFCS_DYLIB_gsl = @FFCS_DYLIB_gsl@
+FFCS_DYLIB_hips = @FFCS_DYLIB_hips@
+FFCS_DYLIB_hypre = @FFCS_DYLIB_hypre@
+FFCS_DYLIB_ipopt = @FFCS_DYLIB_ipopt@
+FFCS_DYLIB_lapack = @FFCS_DYLIB_lapack@
+FFCS_DYLIB_mmg3d = @FFCS_DYLIB_mmg3d@
+FFCS_DYLIB_mshmet = @FFCS_DYLIB_mshmet@
+FFCS_DYLIB_mumps = @FFCS_DYLIB_mumps@
+FFCS_DYLIB_mumps_seq = @FFCS_DYLIB_mumps_seq@
+FFCS_DYLIB_pardiso = @FFCS_DYLIB_pardiso@
+FFCS_DYLIB_parms = @FFCS_DYLIB_parms@
+FFCS_DYLIB_pastix = @FFCS_DYLIB_pastix@
+FFCS_DYLIB_pipe = @FFCS_DYLIB_pipe@
+FFCS_DYLIB_scotch = @FFCS_DYLIB_scotch@
+FFCS_DYLIB_superludist = @FFCS_DYLIB_superludist@
+FFCS_DYLIB_yams = @FFCS_DYLIB_yams@
+FFCS_MAKEFLAGS = @FFCS_MAKEFLAGS@
 FFGLUTNAME = @FFGLUTNAME@
 FFGLUTPROG = @FFGLUTPROG@
 FFLAGS = @FFLAGS@
@@ -499,6 +536,8 @@ all-local: $(DOWNLOAD_ARPACK)
 
 arpack: $(ARPACKLIB) 
 
+# FFCS: need to add $(RANLIB) under mingw64 to avoid "archive has no index" error
+
 $(ARPACKLIB): ARPACK/fait
 	if [ -n '@FF_LAPACKdir@' ] ; then \
 	$(F77) -c `echo $(FFLAGS)\ |sed -e s/-O.\*\ // ` ARPACK/LAPACK/dlamch.f -o ARPACK/LAPACK/dlamch.o; \
@@ -506,6 +545,7 @@ $(ARPACKLIB): ARPACK/fait
 	cd ARPACK && make lib 
 	if test -n '@FF_LAPACKdir@' ; then \
 	$(AR) $(ARFLAGS) $(LAPACK_arpack_LIB)  ARPACK/SRC/*.o  ARPACK/UTIL/*.o ARPACK/LAPACK/*.o ;\
+	$(RANLIB) $(LAPACK_arpack_LIB) ;\
 	else \
 	$(AR) $(ARFLAGS) $(ARPACKLIB)  ARPACK/SRC/*.o  ARPACK/UTIL/*.o ;\
 	fi
diff --git a/download/blacs/BLACS.patch b/download/blacs/BLACS.patch
index 1d0b4b9..7749dfd 100644
--- a/download/blacs/BLACS.patch
+++ b/download/blacs/BLACS.patch
@@ -20,3 +20,16 @@ diff -ur BLACS/SRC/MPI/Makefile BLACS-okk/Makefile
  
  Bdef.h : ../Bdef.h
  	rm -f Bdef.h
+@@ -196,9 +196,10 @@
+ bi_f77_mpi_testall.o : mpif.h bi_f77_mpi_testall.f
+ 	$(F77) -c $(F77FLAGS) $*.f
+ 
+-mpif.h : $(MPIINCdir)/mpif.h
++# FFCS: watch out for spaces and links under Windows. Also, make dependencies cannot contain spaces.
++mpif.h :
+ 	rm -f mpif.h
+-	ln -s $(MPIINCdir)/mpif.h mpif.h
++	cp $(MPIINCdir)/mpif.h mpif.h
+ 
+ #  ------------------------------------------------------------------------
+ #  We move C .o files to .C so that we can use the portable suffix rule for
diff --git a/download/blacs/BLACS_gridinit_.c-return-values.patch b/download/blacs/BLACS_gridinit_.c-return-values.patch
new file mode 100644
index 0000000..9bdd788
--- /dev/null
+++ b/download/blacs/BLACS_gridinit_.c-return-values.patch
@@ -0,0 +1,12 @@
+--- ./BLACS/SRC/MPI/blacs_gridinit_.c.orig	2013-01-27 12:42:38.712531484 +0000
++++ ./BLACS/SRC/MPI/blacs_gridinit_.c	2013-01-27 12:49:32.411131896 +0000
+@@ -35,4 +35,9 @@
+    blacs_gridmap_(ConTxt, tmpgrid, nprow, nprow, npcol);
+ #endif
+    free(tmpgrid);
++#if (INTFACE == C_CALL)
++   return 0;
++#else
++   return NULL;
++#endif
+ }
diff --git a/download/blacs/Bmake-blacs.inc b/download/blacs/Bmake-blacs.inc
index 8026418..8ee0c5c 100644
--- a/download/blacs/Bmake-blacs.inc
+++ b/download/blacs/Bmake-blacs.inc
@@ -60,7 +60,11 @@ WGET = @WGET@
    MPIdir = $(FFMPIDIR) 
    MPIdev =  
    MPIplat = 
-   MPILIBdir = @MPI_LIB_DIRS@
+
+   # FFCS: Windows path to MPICH2 contains spaces, but FF configure --with-mpipath option should not contain quotes
+   # because FF configure adds quotes when defining MPI_LIB
+
+   MPILIBdir = '@MPI_LIB_DIRS@'
    MPIINCdir = '@MPI_INC_DIR@'
    MPILIB = @MPI_LIB@
 
diff --git a/download/blacs/Makefile b/download/blacs/Makefile
index bcf17a0..cd46685 100644
--- a/download/blacs/Makefile
+++ b/download/blacs/Makefile
@@ -1,83 +1,93 @@
-# Downloading and compiling extra libraries
-# -----------------------------------------
-
-# $Id$
-include Bmake.inc
-
-all-local: blacs 
-
-# Downloading and compiling BLACS
-# ------------------------------
-# http://www.netlib.org/blacs/
-# Hips information
-DIRPKG=../pkg
-SRCDIR=BLACS
-PACKAGE1=$(DIRPKG)/mpiblacs.tgz
-PACKAGE2=$(DIRPKG)/mpiblacs-patch03.tgz
-PACKAGE3=$(DIRPKG)/blacstester.tgz
-SERVER=http://www.netlib.org/blacs/
-INSTALL=../..
-
-SYSERRORS = 
-
-blacs:FAIRE
-
-
-FAIRE:$(SRCDIR)/FAIT
-	$(MAKE) WHERE
-	touch FAIRE
-
-Bmake.inc: ../../config.status	Makefile Bmake-blacs.inc
-	../../config.status  --file="Bmake.inc1:Bmake-blacs.inc"
-	sed s/-DAdd__/-Df77IsF2C/ <Bmake.inc1 >Bmake.inc
-	rm Bmake.inc1
-
-$(SRCDIR)/FAIT: $(SRCDIR)
-	#cd $(SRCDIR)/INSTALL/;$(MAKE) xintface xsyserrors xcmpi_sane xfmpi_sane xtc_CsameF77 xtc_UseMpich
-	cd $(SRCDIR);$(MAKE) mpi 
-	touch $(SRCDIR)/FAIT
-
-WHERE: 
-	-if [ -f $(SRCDIR)/FAIT ] ; then \
-	make install;  \
-	echo blacs LD -L at DIR@/lib/blacs -lblacs_MPI-FREEFEM-0 	-lblacsF77init_MPI-FREEFEM-0	-lblacsCinit_MPI-FREEFEM-0  -lblacs_MPI-FREEFEM-0  >$(SRCDIR)/$(INSTALL)/lib/WHERE.blacs ;\
-	fi
-
-install: $(SRCDIR)/FAIT
-	mkdir -p $(SRCDIR)/$(INSTALL)/lib/blacs
-	cp $(SRCDIR)/LIB/*.a $(SRCDIR)/$(INSTALL)/lib/blacs/
-
-$(SRCDIR): $(PACKAGE1) $(PACKAGE2) $(PACKAGE3)
-	gunzip -c $(PACKAGE1) | tar xvf -
-	gunzip -c $(PACKAGE2) | tar xvf -
-	gunzip -c $(PACKAGE3) | tar xvf -
-	cd $(SRCDIR)/SRC/MPI; patch -p1 < ../../../BLACS.patch
-	cp Bmake.inc $(SRCDIR)
-	mv $(SRCDIR)/SRC/MPI/Makefile $(SRCDIR)/SRC/MPI/Makefile.tmp
-	sed -e 's;\.C;\.oo;g'  -e 's@: $$(MPIINCdir)/mpif.h@:@' \
-	< $(SRCDIR)/SRC/MPI/Makefile.tmp \
-	> $(SRCDIR)/SRC/MPI/Makefile
-	touch $(SRCDIR)
-
-$(PACKAGE1):
-	-mkdir $(DIRPKG)
-	cd $(DIRPKG);$(WGET)  $(SERVER)/`basename $(PACKAGE1)`
-
-$(PACKAGE2):
-	-mkdir $(DIRPKG)
-	cd $(DIRPKG);$(WGET) $(SERVER)/`basename $(PACKAGE2)`
-
-$(PACKAGE3):
-	-mkdir $(DIRPKG)
-	cd $(DIRPKG);$(WGET) $(SERVER)/`basename $(PACKAGE3)`
-
-clean-local:
-	-cd $(SRCDIR)/SRC/MPI &&  $(MAKE) clean -C $(SRCDIR)/SRC/MPI
-	-rm Bmake.inc FAIRE
-	-rm $(SRCDIR)/$(INSTALL)/lib/blacs/*.a
-	-rm -rf $(SRCDIR)
-
-clean: clean-local
-
-
+# Downloading and compiling extra libraries
+# -----------------------------------------
+
+# $Id$
+include Bmake.inc
+
+all-local: blacs 
+
+# Downloading and compiling BLACS
+# ------------------------------
+# http://www.netlib.org/blacs/
+# Hips information
+DIRPKG=../pkg
+SRCDIR=BLACS
+PACKAGE1=$(DIRPKG)/mpiblacs.tgz
+PACKAGE2=$(DIRPKG)/mpiblacs-patch03.tgz
+PACKAGE3=$(DIRPKG)/blacstester.tgz
+SERVER=http://www.netlib.org/blacs/
+INSTALL=../..
+
+SYSERRORS = 
+
+blacs:FAIRE
+
+
+FAIRE:$(SRCDIR)/FAIT
+	$(MAKE) WHERE
+	touch FAIRE
+
+Bmake.inc: ../../config.status	Makefile Bmake-blacs.inc
+	../../config.status  --file="Bmake.inc1:Bmake-blacs.inc"
+	sed s/-DAdd__/-Df77IsF2C/ <Bmake.inc1 >Bmake.inc
+	rm Bmake.inc1
+
+# FFCS: make sure that this makefile fails if the BLACS do not compile. But run links2files when the compilation fails because of
+# a symbolic link (under Windows). Repeat it only by hand to avoid infinite loops!
+$(SRCDIR)/FAIT: $(SRCDIR)
+#	cd $(SRCDIR)/INSTALL/;$(MAKE) xintface xsyserrors xcmpi_sane xfmpi_sane xtc_CsameF77 xtc_UseMpich
+	-cd $(SRCDIR) && $(MAKE) mpi
+	../../../../build/links2files
+	-cd $(SRCDIR) && $(MAKE) mpi
+	../../../../build/links2files
+	cd $(SRCDIR) && $(MAKE) mpi
+	touch $(SRCDIR)/FAIT
+
+WHERE: 
+	-if [ -f $(SRCDIR)/FAIT ] ; then \
+	make install;  \
+	echo blacs LD -L at DIR@/lib/blacs -lblacs_MPI-FREEFEM-0 	-lblacsF77init_MPI-FREEFEM-0	-lblacsCinit_MPI-FREEFEM-0  -lblacs_MPI-FREEFEM-0  >$(SRCDIR)/$(INSTALL)/lib/WHERE.blacs ;\
+	fi
+
+install: $(SRCDIR)/FAIT
+	mkdir -p $(SRCDIR)/$(INSTALL)/lib/blacs
+	cp $(SRCDIR)/LIB/*.a $(SRCDIR)/$(INSTALL)/lib/blacs/
+
+# FFCS: some files in the untarred archives are symbolic links that need to be converted for MinGW compilers
+$(SRCDIR): $(PACKAGE1) $(PACKAGE2) $(PACKAGE3)
+	gunzip -c $(PACKAGE1) | tar xvf -
+	gunzip -c $(PACKAGE2) | tar xvf -
+	gunzip -c $(PACKAGE3) | tar xvf -
+	patch -p0 < BLACS_gridinit_.c-return-values.patch
+	cd $(SRCDIR)/SRC/MPI; patch -p1 < ../../../BLACS.patch
+	cp Bmake.inc $(SRCDIR)
+	mv $(SRCDIR)/SRC/MPI/Makefile $(SRCDIR)/SRC/MPI/Makefile.tmp
+	sed -e 's;\.C;\.oo;g'  -e 's@: $$(MPIINCdir)/mpif.h@:@' \
+	< $(SRCDIR)/SRC/MPI/Makefile.tmp \
+	> $(SRCDIR)/SRC/MPI/Makefile
+	../../../../build/links2files
+	touch $(SRCDIR)
+
+$(PACKAGE1):
+	-mkdir $(DIRPKG)
+	cd $(DIRPKG);$(WGET)  $(SERVER)/`basename $(PACKAGE1)`
+
+$(PACKAGE2):
+	-mkdir $(DIRPKG)
+	cd $(DIRPKG);$(WGET) $(SERVER)/`basename $(PACKAGE2)`
+
+$(PACKAGE3):
+	-mkdir $(DIRPKG)
+	cd $(DIRPKG);$(WGET) $(SERVER)/`basename $(PACKAGE3)`
+
+# FFCS: only run make clean if cd to SRCDIR worked, otherwise this is an infinite loop.
+clean-local:
+	-cd $(SRCDIR)/SRC/MPI &&  $(MAKE) clean -C $(SRCDIR)/SRC/MPI
+	-rm Bmake.inc FAIRE
+	-rm $(SRCDIR)/$(INSTALL)/lib/blacs/*.a
+	-rm -rf $(SRCDIR)
+
+clean: clean-local
+
+
 .PHONY:$(SRCDIR)/$(INSTALL)  compile install
\ No newline at end of file
diff --git a/download/blas/Makefile.am b/download/blas/Makefile.am
index 8d6634a..93f049e 100644
--- a/download/blas/Makefile.am
+++ b/download/blas/Makefile.am
@@ -1,200 +1,201 @@
-# Downloading and compiling extra libraries
-# -----------------------------------------
-
-# $Id$
-DIRPKG=../pkg
-ATLAS_TAR=$(DIRPKG)/atlas3.6.0.tar.bz2
-BLAS_TGZ=$(DIRPKG)/blas.tgz
-CBLAS_TGZ=$(DIRPKG)/cblas.tgz
-
-
-ATLASSRCLIB=ATLAS/lib/ff++/libatlas.a ATLAS/lib/ff++/libcblas.a	\
-	ATLAS/lib/ff++/libf77blas.a
-ATLASBINLIB=WinNT_PPRO256/libatlas.a
-
-all-local:: $(DOWNLOAD_BLAS)
-generic: 
-atlas-source: $(ATLASSRCLIB)
-atlas-binary: $(ATLASBINLIB)
-
-# Downloading and compiling the Blas
-# ----------------------------------
-
-# ATLAS source
-$(ATLASSRCLIB): ATLAS/Make.ff++
-	cd ATLAS && make install arch=ff++
-
-ATLAS/Make.ff++: $(ATLAS_TAR)
-	tar -x --bzip -f $(ATLAS_TAR)
-	@echo In the following questions, \"Architecture name\" must be ff++
-	@echo "(Press ENTER)"
-	@read
-	cd ATLAS && make
-
-$(ATLAS_TAR):
-	cd $(DIRPKG);@WGET@ -N http://heanet.dl.sourceforge.net/sourceforge/math-atlas/atlas3.6.0.tar.bz2
-
-clean-local::
-	-rm atlas*.tar.bz2
-	-rm -r ATLAS
-
-# ATLAS binary
-$(ATLASBINLIB): atlas321_WinNT_PPRO.zip
-	unzip atlas321_WinNT_PPRO.zip
-	touch $(ATLASBINLIB)
-
-atlas321_WinNT_PPRO.zip:
-	@WGET@ -N http://www.netlib.org/atlas/archives/windows/atlas321_WinNT_PPRO.zip
-
-clean-local::
-	-rm atlas321_WinNT_PPRO.zip
-	-rm -r WinNT_PPRO256
-
-# Generic BLAS
-noinst_LIBRARIES=@GENERIC_BLAS@
-EXTRA_LIBRARIES=libf77blas.a libcblas.a
-
-# List of files to compile (do not list them in *_SOURCES to prevent
-# them from being included in distributions).
-
-F77BLAS_SOURCES=BLAS/caxpy.f BLAS/crotg.f BLAS/dcopy.f BLAS/dsymv.f	\
-BLAS/lsame.f BLAS/sspmv.f BLAS/zaxpy.f BLAS/zhpr2.f BLAS/ccopy.f	\
-BLAS/cscal.f BLAS/ddot.f BLAS/dsyr2.f BLAS/sasum.f BLAS/sspr2.f		\
-BLAS/zcopy.f BLAS/zhpr.f BLAS/cdotc.f BLAS/csrot.f BLAS/dgbmv.f		\
-BLAS/dsyr2k.f BLAS/saxpy.f BLAS/sspr.f BLAS/zdotc.f BLAS/zrotg.f	\
-BLAS/cdotu.f BLAS/csscal.f BLAS/dgemm.f BLAS/dsyr.f BLAS/scasum.f	\
-BLAS/sswap.f BLAS/zdotu.f BLAS/zscal.f BLAS/cgbmv.f BLAS/cswap.f	\
-BLAS/dgemv.f BLAS/dsyrk.f BLAS/scnrm2.f BLAS/ssymm.f BLAS/zdrot.f	\
-BLAS/zswap.f BLAS/cgemm.f BLAS/csymm.f BLAS/dger.f BLAS/dtbmv.f		\
-BLAS/scopy.f BLAS/ssymv.f BLAS/zdscal.f BLAS/zsymm.f BLAS/cgemv.f	\
-BLAS/csyr2k.f BLAS/dnrm2.f BLAS/dtbsv.f BLAS/sdot.f BLAS/ssyr2.f	\
-BLAS/zgbmv.f BLAS/zsyr2k.f BLAS/cgerc.f BLAS/csyrk.f BLAS/drot.f	\
-BLAS/dtpmv.f BLAS/sdsdot.f BLAS/ssyr2k.f BLAS/zgemm.f BLAS/zsyrk.f	\
-BLAS/cgeru.f BLAS/ctbmv.f BLAS/drotg.f BLAS/dtpsv.f BLAS/sgbmv.f	\
-BLAS/ssyr.f BLAS/zgemv.f BLAS/ztbmv.f BLAS/chbmv.f BLAS/ctbsv.f		\
-BLAS/drotm.f BLAS/dtrmm.f BLAS/sgemm.f BLAS/ssyrk.f BLAS/zgerc.f	\
-BLAS/ztbsv.f BLAS/chemm.f BLAS/ctpmv.f BLAS/drotmg.f BLAS/dtrmv.f	\
-BLAS/sgemv.f BLAS/stbmv.f BLAS/zgeru.f BLAS/ztpmv.f BLAS/chemv.f	\
-BLAS/ctpsv.f BLAS/dsbmv.f BLAS/dtrsm.f BLAS/sger.f BLAS/stbsv.f		\
-BLAS/zhbmv.f BLAS/ztpsv.f BLAS/cher2.f BLAS/ctrmm.f BLAS/dscal.f	\
-BLAS/dtrsv.f BLAS/snrm2.f BLAS/stpmv.f BLAS/zhemm.f BLAS/ztrmm.f	\
-BLAS/cher2k.f BLAS/ctrmv.f BLAS/dsdot.f BLAS/dzasum.f BLAS/srot.f	\
-BLAS/stpsv.f BLAS/zhemv.f BLAS/ztrmv.f BLAS/cher.f BLAS/ctrsm.f		\
-BLAS/dspmv.f BLAS/dznrm2.f BLAS/srotg.f BLAS/strmm.f BLAS/zher2.f	\
-BLAS/ztrsm.f BLAS/cherk.f BLAS/ctrsv.f BLAS/dspr2.f BLAS/icamax.f	\
-BLAS/srotm.f BLAS/strmv.f BLAS/zher2k.f BLAS/ztrsv.f BLAS/chpmv.f	\
-BLAS/dasum.f BLAS/dspr.f BLAS/idamax.f BLAS/srotmg.f BLAS/strsm.f	\
-BLAS/zher.f BLAS/chpr2.f BLAS/daxpy.f BLAS/dswap.f BLAS/isamax.f	\
-BLAS/ssbmv.f BLAS/strsv.f BLAS/zherk.f BLAS/chpr.f BLAS/dcabs1.f	\
-BLAS/dsymm.f BLAS/izamax.f BLAS/sscal.f blas_xerbla.f BLAS/zhpmv.f
-
-CBLAS_SOURCES=CBLAS/src/cblas_caxpy.c CBLAS/src/cblas_drot.c		\
-CBLAS/src/cblas_sgemm.c CBLAS/src/cblas_zher2.c				\
-CBLAS/src/cblas_ccopy.c CBLAS/src/cblas_drotg.c				\
-CBLAS/src/cblas_sgemv.c CBLAS/src/cblas_zher2k.c			\
-CBLAS/src/cblas_cdotc_sub.c CBLAS/src/cblas_drotm.c			\
-CBLAS/src/cblas_sger.c CBLAS/src/cblas_zher.c				\
-CBLAS/src/cblas_cdotu_sub.c CBLAS/src/cblas_drotmg.c			\
-CBLAS/src/cblas_snrm2.c CBLAS/src/cblas_zherk.c				\
-CBLAS/src/cblas_cgbmv.c CBLAS/src/cblas_dsbmv.c CBLAS/src/cblas_srot.c	\
-CBLAS/src/cblas_zhpmv.c CBLAS/src/cblas_cgemm.c				\
-CBLAS/src/cblas_dscal.c CBLAS/src/cblas_srotg.c				\
-CBLAS/src/cblas_zhpr2.c CBLAS/src/cblas_cgemv.c				\
-CBLAS/src/cblas_dsdot.c CBLAS/src/cblas_srotm.c CBLAS/src/cblas_zhpr.c	\
-CBLAS/src/cblas_cgerc.c CBLAS/src/cblas_dspmv.c				\
-CBLAS/src/cblas_srotmg.c CBLAS/src/cblas_zscal.c			\
-CBLAS/src/cblas_cgeru.c CBLAS/src/cblas_dspr2.c				\
-CBLAS/src/cblas_ssbmv.c CBLAS/src/cblas_zswap.c				\
-CBLAS/src/cblas_chbmv.c CBLAS/src/cblas_dspr.c CBLAS/src/cblas_sscal.c	\
-CBLAS/src/cblas_zsymm.c CBLAS/src/cblas_chemm.c				\
-CBLAS/src/cblas_dswap.c CBLAS/src/cblas_sspmv.c				\
-CBLAS/src/cblas_zsyr2k.c CBLAS/src/cblas_chemv.c			\
-CBLAS/src/cblas_dsymm.c CBLAS/src/cblas_sspr2.c				\
-CBLAS/src/cblas_zsyrk.c CBLAS/src/cblas_cher2.c				\
-CBLAS/src/cblas_dsymv.c CBLAS/src/cblas_sspr.c CBLAS/src/cblas_ztbmv.c	\
-CBLAS/src/cblas_cher2k.c CBLAS/src/cblas_dsyr2.c			\
-CBLAS/src/cblas_sswap.c CBLAS/src/cblas_ztbsv.c CBLAS/src/cblas_cher.c	\
-CBLAS/src/cblas_dsyr2k.c CBLAS/src/cblas_ssymm.c			\
-CBLAS/src/cblas_ztpmv.c CBLAS/src/cblas_cherk.c CBLAS/src/cblas_dsyr.c	\
-CBLAS/src/cblas_ssymv.c CBLAS/src/cblas_ztpsv.c				\
-CBLAS/src/cblas_chpmv.c CBLAS/src/cblas_dsyrk.c				\
-CBLAS/src/cblas_ssyr2.c CBLAS/src/cblas_ztrmm.c				\
-CBLAS/src/cblas_chpr2.c CBLAS/src/cblas_dtbmv.c				\
-CBLAS/src/cblas_ssyr2k.c CBLAS/src/cblas_ztrmv.c			\
-CBLAS/src/cblas_chpr.c CBLAS/src/cblas_dtbsv.c CBLAS/src/cblas_ssyr.c	\
-CBLAS/src/cblas_ztrsm.c CBLAS/src/cblas_cscal.c				\
-CBLAS/src/cblas_dtpmv.c CBLAS/src/cblas_ssyrk.c				\
-CBLAS/src/cblas_ztrsv.c CBLAS/src/cblas_csscal.c			\
-CBLAS/src/cblas_dtpsv.c CBLAS/src/cblas_stbmv.c CBLAS/src/cdotcsub.f	\
-CBLAS/src/cblas_cswap.c CBLAS/src/cblas_dtrmm.c				\
-CBLAS/src/cblas_stbsv.c CBLAS/src/cdotusub.f CBLAS/src/cblas_csymm.c	\
-CBLAS/src/cblas_dtrmv.c CBLAS/src/cblas_stpmv.c CBLAS/src/dasumsub.f	\
-CBLAS/src/cblas_csyr2k.c CBLAS/src/cblas_dtrsm.c			\
-CBLAS/src/cblas_stpsv.c CBLAS/src/ddotsub.f CBLAS/src/cblas_csyrk.c	\
-CBLAS/src/cblas_dtrsv.c CBLAS/src/cblas_strmm.c CBLAS/src/dnrm2sub.f	\
-CBLAS/src/cblas_ctbmv.c CBLAS/src/cblas_dzasum.c			\
-CBLAS/src/cblas_strmv.c CBLAS/src/dsdotsub.f CBLAS/src/cblas_ctbsv.c	\
-CBLAS/src/cblas_dznrm2.c CBLAS/src/cblas_strsm.c CBLAS/src/dzasumsub.f	\
-CBLAS/src/cblas_ctpmv.c CBLAS/src/cblas_f77.h CBLAS/src/cblas_strsv.c	\
-CBLAS/src/dznrm2sub.f CBLAS/src/cblas_ctpsv.c				\
-CBLAS/src/cblas_globals.c CBLAS/src/cblas_xerbla.c			\
-CBLAS/src/icamaxsub.f CBLAS/src/cblas_ctrmm.c CBLAS/src/cblas.h		\
-CBLAS/src/cblas_zaxpy.c CBLAS/src/idamaxsub.f CBLAS/src/cblas_ctrmv.c	\
-CBLAS/src/cblas_icamax.c CBLAS/src/cblas_zcopy.c CBLAS/src/isamaxsub.f	\
-CBLAS/src/cblas_ctrsm.c CBLAS/src/cblas_idamax.c			\
-CBLAS/src/cblas_zdotc_sub.c CBLAS/src/izamaxsub.f			\
-CBLAS/src/cblas_ctrsv.c CBLAS/src/cblas_isamax.c			\
-CBLAS/src/cblas_zdotu_sub.c CBLAS/src/Makefile CBLAS/src/cblas_dasum.c	\
-CBLAS/src/cblas_izamax.c CBLAS/src/cblas_zdscal.c CBLAS/src/sasumsub.f	\
-CBLAS/src/cblas_daxpy.c CBLAS/src/cblas_sasum.c				\
-CBLAS/src/cblas_zgbmv.c CBLAS/src/scasumsub.f CBLAS/src/cblas_dcopy.c	\
-CBLAS/src/cblas_saxpy.c CBLAS/src/cblas_zgemm.c CBLAS/src/scnrm2sub.f	\
-CBLAS/src/cblas_ddot.c CBLAS/src/cblas_scasum.c				\
-CBLAS/src/cblas_zgemv.c CBLAS/src/sdotsub.f CBLAS/src/cblas_dgbmv.c	\
-CBLAS/src/cblas_scnrm2.c CBLAS/src/cblas_zgerc.c CBLAS/src/sdsdotsub.f	\
-CBLAS/src/cblas_dgemm.c CBLAS/src/cblas_scopy.c				\
-CBLAS/src/cblas_zgeru.c CBLAS/src/snrm2sub.f CBLAS/src/cblas_dgemv.c	\
-CBLAS/src/cblas_sdot.c CBLAS/src/cblas_zhbmv.c CBLAS/src/xerbla.c	\
-CBLAS/src/cblas_dger.c CBLAS/src/cblas_sdsdot.c				\
-CBLAS/src/cblas_zhemm.c CBLAS/src/zdotcsub.f CBLAS/src/cblas_dnrm2.c	\
-CBLAS/src/cblas_sgbmv.c CBLAS/src/cblas_zhemv.c CBLAS/src/zdotusub.f
-
-nodist_libf77blas_a_SOURCES=$(F77BLAS_SOURCES)
-nodist_libcblas_a_SOURCES=$(CBLAS_SOURCES)
-BUILT_SOURCES=@GENERIC_BLAS_BUILT_SOURCES@
-
-libcblas_a_CFLAGS=-DADD_ -ICBLAS/include 
-
-# "xerbla" exists in both BLAS and CBLAS. So we need to rename it to
-# obtain two different object files.
-
-BLAS:BLAS/fait
-
-BLAS/fait:$(BLAS_TGZ)
-	-if tar xvzf $(BLAS_TGZ) BLAS/xerbla.f 2>&1 1>/dev/null ; then \
-	tar xvzf $(BLAS_TGZ) ; \
-	else \
-	mkdir -p BLAS;cd BLAS && tar xvzf ../$(BLAS_TGZ);\
-	fi
-	cp BLAS/xerbla.f blas_xerbla.f
-	touch BLAS/fait
-$(F77BLAS_SOURCES): BLAS
-
-CBLAS:CBLAS/fait
-
-CBLAS/fait: $(CBLAS_TGZ)
-	tar xvzf $(CBLAS_TGZ)
-	cp CBLAS/include/*.h  CBLAS/src
-	touch CBLAS/fait
-$(CBLAS_SOURCES): CBLAS/fait
-
-$(BLAS_TGZ):
-	cd $(DIRPKG);@WGET@ -N http://www.netlib.org/blas/blas.tgz
-
-$(CBLAS_TGZ):
-	cd $(DIRPKG);@WGET@ -N http://www.netlib.org/blas/blast-forum/cblas.tgz
-
-
-clean-local::
-	-rm -r BLAS CBLAS blas_xerbla.f
-
+# Downloading and compiling extra libraries
+# -----------------------------------------
+
+# $Id$
+DIRPKG=../pkg
+ATLAS_TAR=$(DIRPKG)/atlas3.6.0.tar.bz2
+BLAS_TGZ=$(DIRPKG)/blas.tgz
+CBLAS_TGZ=$(DIRPKG)/cblas.tgz
+
+
+ATLASSRCLIB=ATLAS/lib/ff++/libatlas.a ATLAS/lib/ff++/libcblas.a	\
+	ATLAS/lib/ff++/libf77blas.a
+ATLASBINLIB=WinNT_PPRO256/libatlas.a
+
+all-local:: $(DOWNLOAD_BLAS)
+generic: 
+atlas-source: $(ATLASSRCLIB)
+atlas-binary: $(ATLASBINLIB)
+
+# Downloading and compiling the Blas
+# ----------------------------------
+
+# ATLAS source
+$(ATLASSRCLIB): ATLAS/Make.ff++
+	cd ATLAS && make install arch=ff++
+
+ATLAS/Make.ff++: $(ATLAS_TAR)
+	tar -x --bzip -f $(ATLAS_TAR)
+	@echo In the following questions, \"Architecture name\" must be ff++
+	@echo "(Press ENTER)"
+	@read
+	cd ATLAS && make
+
+$(ATLAS_TAR):
+	cd $(DIRPKG);@WGET@ -N http://heanet.dl.sourceforge.net/sourceforge/math-atlas/atlas3.6.0.tar.bz2
+
+clean-local::
+	-rm atlas*.tar.bz2
+	-rm -r ATLAS
+
+# ATLAS binary
+$(ATLASBINLIB): atlas321_WinNT_PPRO.zip
+	unzip atlas321_WinNT_PPRO.zip
+	touch $(ATLASBINLIB)
+
+atlas321_WinNT_PPRO.zip:
+	@WGET@ -N http://www.netlib.org/atlas/archives/windows/atlas321_WinNT_PPRO.zip
+
+clean-local::
+	-rm atlas321_WinNT_PPRO.zip
+	-rm -r WinNT_PPRO256
+
+# Generic BLAS
+noinst_LIBRARIES=@GENERIC_BLAS@
+EXTRA_LIBRARIES=libf77blas.a libcblas.a
+
+# List of files to compile (do not list them in *_SOURCES to prevent
+# them from being included in distributions).
+
+F77BLAS_SOURCES=BLAS/caxpy.f BLAS/crotg.f BLAS/dcopy.f BLAS/dsymv.f	\
+BLAS/lsame.f BLAS/sspmv.f BLAS/zaxpy.f BLAS/zhpr2.f BLAS/ccopy.f	\
+BLAS/cscal.f BLAS/ddot.f BLAS/dsyr2.f BLAS/sasum.f BLAS/sspr2.f		\
+BLAS/zcopy.f BLAS/zhpr.f BLAS/cdotc.f BLAS/csrot.f BLAS/dgbmv.f		\
+BLAS/dsyr2k.f BLAS/saxpy.f BLAS/sspr.f BLAS/zdotc.f BLAS/zrotg.f	\
+BLAS/cdotu.f BLAS/csscal.f BLAS/dgemm.f BLAS/dsyr.f BLAS/scasum.f	\
+BLAS/sswap.f BLAS/zdotu.f BLAS/zscal.f BLAS/cgbmv.f BLAS/cswap.f	\
+BLAS/dgemv.f BLAS/dsyrk.f BLAS/scnrm2.f BLAS/ssymm.f BLAS/zdrot.f	\
+BLAS/zswap.f BLAS/cgemm.f BLAS/csymm.f BLAS/dger.f BLAS/dtbmv.f		\
+BLAS/scopy.f BLAS/ssymv.f BLAS/zdscal.f BLAS/zsymm.f BLAS/cgemv.f	\
+BLAS/csyr2k.f BLAS/dnrm2.f BLAS/dtbsv.f BLAS/sdot.f BLAS/ssyr2.f	\
+BLAS/zgbmv.f BLAS/zsyr2k.f BLAS/cgerc.f BLAS/csyrk.f BLAS/drot.f	\
+BLAS/dtpmv.f BLAS/sdsdot.f BLAS/ssyr2k.f BLAS/zgemm.f BLAS/zsyrk.f	\
+BLAS/cgeru.f BLAS/ctbmv.f BLAS/drotg.f BLAS/dtpsv.f BLAS/sgbmv.f	\
+BLAS/ssyr.f BLAS/zgemv.f BLAS/ztbmv.f BLAS/chbmv.f BLAS/ctbsv.f		\
+BLAS/drotm.f BLAS/dtrmm.f BLAS/sgemm.f BLAS/ssyrk.f BLAS/zgerc.f	\
+BLAS/ztbsv.f BLAS/chemm.f BLAS/ctpmv.f BLAS/drotmg.f BLAS/dtrmv.f	\
+BLAS/sgemv.f BLAS/stbmv.f BLAS/zgeru.f BLAS/ztpmv.f BLAS/chemv.f	\
+BLAS/ctpsv.f BLAS/dsbmv.f BLAS/dtrsm.f BLAS/sger.f BLAS/stbsv.f		\
+BLAS/zhbmv.f BLAS/ztpsv.f BLAS/cher2.f BLAS/ctrmm.f BLAS/dscal.f	\
+BLAS/dtrsv.f BLAS/snrm2.f BLAS/stpmv.f BLAS/zhemm.f BLAS/ztrmm.f	\
+BLAS/cher2k.f BLAS/ctrmv.f BLAS/dsdot.f BLAS/dzasum.f BLAS/srot.f	\
+BLAS/stpsv.f BLAS/zhemv.f BLAS/ztrmv.f BLAS/cher.f BLAS/ctrsm.f		\
+BLAS/dspmv.f BLAS/dznrm2.f BLAS/srotg.f BLAS/strmm.f BLAS/zher2.f	\
+BLAS/ztrsm.f BLAS/cherk.f BLAS/ctrsv.f BLAS/dspr2.f BLAS/icamax.f	\
+BLAS/srotm.f BLAS/strmv.f BLAS/zher2k.f BLAS/ztrsv.f BLAS/chpmv.f	\
+BLAS/dasum.f BLAS/dspr.f BLAS/idamax.f BLAS/srotmg.f BLAS/strsm.f	\
+BLAS/zher.f BLAS/chpr2.f BLAS/daxpy.f BLAS/dswap.f BLAS/isamax.f	\
+BLAS/ssbmv.f BLAS/strsv.f BLAS/zherk.f BLAS/chpr.f BLAS/dcabs1.f	\
+BLAS/dsymm.f BLAS/izamax.f BLAS/sscal.f blas_xerbla.f BLAS/zhpmv.f
+
+CBLAS_SOURCES=CBLAS/src/cblas_caxpy.c CBLAS/src/cblas_drot.c		\
+CBLAS/src/cblas_sgemm.c CBLAS/src/cblas_zher2.c				\
+CBLAS/src/cblas_ccopy.c CBLAS/src/cblas_drotg.c				\
+CBLAS/src/cblas_sgemv.c CBLAS/src/cblas_zher2k.c			\
+CBLAS/src/cblas_cdotc_sub.c CBLAS/src/cblas_drotm.c			\
+CBLAS/src/cblas_sger.c CBLAS/src/cblas_zher.c				\
+CBLAS/src/cblas_cdotu_sub.c CBLAS/src/cblas_drotmg.c			\
+CBLAS/src/cblas_snrm2.c CBLAS/src/cblas_zherk.c				\
+CBLAS/src/cblas_cgbmv.c CBLAS/src/cblas_dsbmv.c CBLAS/src/cblas_srot.c	\
+CBLAS/src/cblas_zhpmv.c CBLAS/src/cblas_cgemm.c				\
+CBLAS/src/cblas_dscal.c CBLAS/src/cblas_srotg.c				\
+CBLAS/src/cblas_zhpr2.c CBLAS/src/cblas_cgemv.c				\
+CBLAS/src/cblas_dsdot.c CBLAS/src/cblas_srotm.c CBLAS/src/cblas_zhpr.c	\
+CBLAS/src/cblas_cgerc.c CBLAS/src/cblas_dspmv.c				\
+CBLAS/src/cblas_srotmg.c CBLAS/src/cblas_zscal.c			\
+CBLAS/src/cblas_cgeru.c CBLAS/src/cblas_dspr2.c				\
+CBLAS/src/cblas_ssbmv.c CBLAS/src/cblas_zswap.c				\
+CBLAS/src/cblas_chbmv.c CBLAS/src/cblas_dspr.c CBLAS/src/cblas_sscal.c	\
+CBLAS/src/cblas_zsymm.c CBLAS/src/cblas_chemm.c				\
+CBLAS/src/cblas_dswap.c CBLAS/src/cblas_sspmv.c				\
+CBLAS/src/cblas_zsyr2k.c CBLAS/src/cblas_chemv.c			\
+CBLAS/src/cblas_dsymm.c CBLAS/src/cblas_sspr2.c				\
+CBLAS/src/cblas_zsyrk.c CBLAS/src/cblas_cher2.c				\
+CBLAS/src/cblas_dsymv.c CBLAS/src/cblas_sspr.c CBLAS/src/cblas_ztbmv.c	\
+CBLAS/src/cblas_cher2k.c CBLAS/src/cblas_dsyr2.c			\
+CBLAS/src/cblas_sswap.c CBLAS/src/cblas_ztbsv.c CBLAS/src/cblas_cher.c	\
+CBLAS/src/cblas_dsyr2k.c CBLAS/src/cblas_ssymm.c			\
+CBLAS/src/cblas_ztpmv.c CBLAS/src/cblas_cherk.c CBLAS/src/cblas_dsyr.c	\
+CBLAS/src/cblas_ssymv.c CBLAS/src/cblas_ztpsv.c				\
+CBLAS/src/cblas_chpmv.c CBLAS/src/cblas_dsyrk.c				\
+CBLAS/src/cblas_ssyr2.c CBLAS/src/cblas_ztrmm.c				\
+CBLAS/src/cblas_chpr2.c CBLAS/src/cblas_dtbmv.c				\
+CBLAS/src/cblas_ssyr2k.c CBLAS/src/cblas_ztrmv.c			\
+CBLAS/src/cblas_chpr.c CBLAS/src/cblas_dtbsv.c CBLAS/src/cblas_ssyr.c	\
+CBLAS/src/cblas_ztrsm.c CBLAS/src/cblas_cscal.c				\
+CBLAS/src/cblas_dtpmv.c CBLAS/src/cblas_ssyrk.c				\
+CBLAS/src/cblas_ztrsv.c CBLAS/src/cblas_csscal.c			\
+CBLAS/src/cblas_dtpsv.c CBLAS/src/cblas_stbmv.c CBLAS/src/cdotcsub.f	\
+CBLAS/src/cblas_cswap.c CBLAS/src/cblas_dtrmm.c				\
+CBLAS/src/cblas_stbsv.c CBLAS/src/cdotusub.f CBLAS/src/cblas_csymm.c	\
+CBLAS/src/cblas_dtrmv.c CBLAS/src/cblas_stpmv.c CBLAS/src/dasumsub.f	\
+CBLAS/src/cblas_csyr2k.c CBLAS/src/cblas_dtrsm.c			\
+CBLAS/src/cblas_stpsv.c CBLAS/src/ddotsub.f CBLAS/src/cblas_csyrk.c	\
+CBLAS/src/cblas_dtrsv.c CBLAS/src/cblas_strmm.c CBLAS/src/dnrm2sub.f	\
+CBLAS/src/cblas_ctbmv.c CBLAS/src/cblas_dzasum.c			\
+CBLAS/src/cblas_strmv.c CBLAS/src/dsdotsub.f CBLAS/src/cblas_ctbsv.c	\
+CBLAS/src/cblas_dznrm2.c CBLAS/src/cblas_strsm.c CBLAS/src/dzasumsub.f	\
+CBLAS/src/cblas_ctpmv.c CBLAS/src/cblas_f77.h CBLAS/src/cblas_strsv.c	\
+CBLAS/src/dznrm2sub.f CBLAS/src/cblas_ctpsv.c				\
+CBLAS/src/cblas_globals.c CBLAS/src/cblas_xerbla.c			\
+CBLAS/src/icamaxsub.f CBLAS/src/cblas_ctrmm.c CBLAS/src/cblas.h		\
+CBLAS/src/cblas_zaxpy.c CBLAS/src/idamaxsub.f CBLAS/src/cblas_ctrmv.c	\
+CBLAS/src/cblas_icamax.c CBLAS/src/cblas_zcopy.c CBLAS/src/isamaxsub.f	\
+CBLAS/src/cblas_ctrsm.c CBLAS/src/cblas_idamax.c			\
+CBLAS/src/cblas_zdotc_sub.c CBLAS/src/izamaxsub.f			\
+CBLAS/src/cblas_ctrsv.c CBLAS/src/cblas_isamax.c			\
+CBLAS/src/cblas_zdotu_sub.c CBLAS/src/Makefile CBLAS/src/cblas_dasum.c	\
+CBLAS/src/cblas_izamax.c CBLAS/src/cblas_zdscal.c CBLAS/src/sasumsub.f	\
+CBLAS/src/cblas_daxpy.c CBLAS/src/cblas_sasum.c				\
+CBLAS/src/cblas_zgbmv.c CBLAS/src/scasumsub.f CBLAS/src/cblas_dcopy.c	\
+CBLAS/src/cblas_saxpy.c CBLAS/src/cblas_zgemm.c CBLAS/src/scnrm2sub.f	\
+CBLAS/src/cblas_ddot.c CBLAS/src/cblas_scasum.c				\
+CBLAS/src/cblas_zgemv.c CBLAS/src/sdotsub.f CBLAS/src/cblas_dgbmv.c	\
+CBLAS/src/cblas_scnrm2.c CBLAS/src/cblas_zgerc.c CBLAS/src/sdsdotsub.f	\
+CBLAS/src/cblas_dgemm.c CBLAS/src/cblas_scopy.c				\
+CBLAS/src/cblas_zgeru.c CBLAS/src/snrm2sub.f CBLAS/src/cblas_dgemv.c	\
+CBLAS/src/cblas_sdot.c CBLAS/src/cblas_zhbmv.c CBLAS/src/xerbla.c	\
+CBLAS/src/cblas_dger.c CBLAS/src/cblas_sdsdot.c				\
+CBLAS/src/cblas_zhemm.c CBLAS/src/zdotcsub.f CBLAS/src/cblas_dnrm2.c	\
+CBLAS/src/cblas_sgbmv.c CBLAS/src/cblas_zhemv.c CBLAS/src/zdotusub.f
+
+nodist_libf77blas_a_SOURCES=$(F77BLAS_SOURCES)
+nodist_libcblas_a_SOURCES=$(CBLAS_SOURCES)
+BUILT_SOURCES=@GENERIC_BLAS_BUILT_SOURCES@
+
+# -ICBLAS/include to find cblas.h
+libcblas_a_CFLAGS=-DADD_ -ICBLAS/include
+
+# "xerbla" exists in both BLAS and CBLAS. So we need to rename it to
+# obtain two different object files.
+
+BLAS:BLAS/fait
+
+BLAS/fait:$(BLAS_TGZ)
+	-if tar xvzf $(BLAS_TGZ) BLAS/xerbla.f 2>&1 1>/dev/null ; then \
+	tar xvzf $(BLAS_TGZ) ; \
+	else \
+	mkdir -p BLAS;cd BLAS && tar xvzf ../$(BLAS_TGZ);\
+	fi
+	cp BLAS/xerbla.f blas_xerbla.f
+	touch BLAS/fait
+$(F77BLAS_SOURCES): BLAS
+
+CBLAS:CBLAS/fait
+
+CBLAS/fait: $(CBLAS_TGZ)
+	tar xvzf $(CBLAS_TGZ)
+	cp CBLAS/include/*.h  CBLAS/src
+	touch CBLAS/fait
+$(CBLAS_SOURCES): CBLAS/fait
+
+$(BLAS_TGZ):
+	cd $(DIRPKG);@WGET@ -N http://www.netlib.org/blas/blas.tgz
+
+$(CBLAS_TGZ):
+	cd $(DIRPKG);@WGET@ -N http://www.netlib.org/blas/blast-forum/cblas.tgz
+
+
+clean-local::
+	-rm -r BLAS CBLAS blas_xerbla.f
+
diff --git a/download/blas/Makefile.in b/download/blas/Makefile.in
index 01b5355..f4719a3 100644
--- a/download/blas/Makefile.in
+++ b/download/blas/Makefile.in
@@ -58,7 +58,8 @@ 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)/acmacros.m4 \
-	$(top_srcdir)/acoptim.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/acoptim.m4 $(top_srcdir)/acmpi.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -382,11 +383,47 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EIGENOBJ = @EIGENOBJ@
+ENABLE_FFCS = @ENABLE_FFCS@
 EPSTOPDF = @EPSTOPDF@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+FFCS_COMPILE_fflapack = @FFCS_COMPILE_fflapack@
+FFCS_COMPILE_gsl = @FFCS_COMPILE_gsl@
+FFCS_COMPILE_hips = @FFCS_COMPILE_hips@
+FFCS_COMPILE_hypre = @FFCS_COMPILE_hypre@
+FFCS_COMPILE_ipopt = @FFCS_COMPILE_ipopt@
+FFCS_COMPILE_lapack = @FFCS_COMPILE_lapack@
+FFCS_COMPILE_mmg3d = @FFCS_COMPILE_mmg3d@
+FFCS_COMPILE_mshmet = @FFCS_COMPILE_mshmet@
+FFCS_COMPILE_mumps = @FFCS_COMPILE_mumps@
+FFCS_COMPILE_mumps_seq = @FFCS_COMPILE_mumps_seq@
+FFCS_COMPILE_pardiso = @FFCS_COMPILE_pardiso@
+FFCS_COMPILE_parms = @FFCS_COMPILE_parms@
+FFCS_COMPILE_pastix = @FFCS_COMPILE_pastix@
+FFCS_COMPILE_pipe = @FFCS_COMPILE_pipe@
+FFCS_COMPILE_scotch = @FFCS_COMPILE_scotch@
+FFCS_COMPILE_superludist = @FFCS_COMPILE_superludist@
+FFCS_COMPILE_yams = @FFCS_COMPILE_yams@
+FFCS_DYLIB_fflapack = @FFCS_DYLIB_fflapack@
+FFCS_DYLIB_gsl = @FFCS_DYLIB_gsl@
+FFCS_DYLIB_hips = @FFCS_DYLIB_hips@
+FFCS_DYLIB_hypre = @FFCS_DYLIB_hypre@
+FFCS_DYLIB_ipopt = @FFCS_DYLIB_ipopt@
+FFCS_DYLIB_lapack = @FFCS_DYLIB_lapack@
+FFCS_DYLIB_mmg3d = @FFCS_DYLIB_mmg3d@
+FFCS_DYLIB_mshmet = @FFCS_DYLIB_mshmet@
+FFCS_DYLIB_mumps = @FFCS_DYLIB_mumps@
+FFCS_DYLIB_mumps_seq = @FFCS_DYLIB_mumps_seq@
+FFCS_DYLIB_pardiso = @FFCS_DYLIB_pardiso@
+FFCS_DYLIB_parms = @FFCS_DYLIB_parms@
+FFCS_DYLIB_pastix = @FFCS_DYLIB_pastix@
+FFCS_DYLIB_pipe = @FFCS_DYLIB_pipe@
+FFCS_DYLIB_scotch = @FFCS_DYLIB_scotch@
+FFCS_DYLIB_superludist = @FFCS_DYLIB_superludist@
+FFCS_DYLIB_yams = @FFCS_DYLIB_yams@
+FFCS_MAKEFLAGS = @FFCS_MAKEFLAGS@
 FFGLUTNAME = @FFGLUTNAME@
 FFGLUTPROG = @FFGLUTPROG@
 FFLAGS = @FFLAGS@
@@ -675,7 +712,9 @@ CBLAS/src/cblas_sgbmv.c CBLAS/src/cblas_zhemv.c CBLAS/src/zdotusub.f
 nodist_libf77blas_a_SOURCES = $(F77BLAS_SOURCES)
 nodist_libcblas_a_SOURCES = $(CBLAS_SOURCES)
 BUILT_SOURCES = @GENERIC_BLAS_BUILT_SOURCES@
-libcblas_a_CFLAGS = -DADD_ -ICBLAS/include 
+
+# -ICBLAS/include to find cblas.h
+libcblas_a_CFLAGS = -DADD_ -ICBLAS/include
 all: $(BUILT_SOURCES)
 	$(MAKE) $(AM_MAKEFLAGS) all-am
 
diff --git a/download/fftw/Makefile.am b/download/fftw/Makefile.am
index 43a9682..4a6a55c 100644
--- a/download/fftw/Makefile.am
+++ b/download/fftw/Makefile.am
@@ -1,32 +1,32 @@
-# Downloading and compiling extra libraries
-# -----------------------------------------
-
-# $Id$
-
-all-local: $(DOWNLOAD_FFTW)
-
-# Downloading and compiling FLTK
-# ------------------------------
-
-# FFTW information
-SRCDIR=fltk-$(FFTW_VERSION)
-PACKAGE=fltk-$(FFTW_VERSION).tar.gz
-SERVER=http://www.fftw.org
-INSTALL=install
-
-fltk: $(SRCDIR)/$(INSTALL)
-
-$(SRCDIR)/$(INSTALL): $(SRCDIR)
-	cd $(SRCDIR) && ./configure  --prefix=`pwd`/../.. CXX=$(CXX) CC=$(CC)
-	cd $(SRCDIR) && make
-	cd $(SRCDIR) && make install
-
-$(SRCDIR): $(PACKAGE)
-	tar xvzf $(PACKAGE)
-
-$(PACKAGE):
-	@WGET@ -N $(SERVER)/$(PACKAGE)
-
-clean-local:
-	-rm -rf fftw-* 
-	-rm ../include/fftw3.f	../include/fftw3.f03	../include/fftw3.h	../include/fftw3l.f03	../include/fftw3q.f03 ../lib/libfftw3.a	../lib/libfftw3.la
+# Downloading and compiling extra libraries
+# -----------------------------------------
+
+# $Id$
+
+all-local: $(DOWNLOAD_FFTW)
+
+# Downloading and compiling FLTK
+# ------------------------------
+
+# FFTW information
+SRCDIR=fltk-$(FFTW_VERSION)
+PACKAGE=fltk-$(FFTW_VERSION).tar.gz
+SERVER=http://www.fftw.org
+INSTALL=install
+
+fltk: $(SRCDIR)/$(INSTALL)
+
+$(SRCDIR)/$(INSTALL): $(SRCDIR)
+	cd $(SRCDIR) && ./configure  --prefix=`pwd`/../.. CXX=$(CXX) CC=$(CC)
+	cd $(SRCDIR) && make
+	cd $(SRCDIR) && make install
+
+$(SRCDIR): $(PACKAGE)
+	tar xvzf $(PACKAGE)
+
+$(PACKAGE):
+	@WGET@ -N $(SERVER)/$(PACKAGE)
+
+clean-local:
+	-rm -rf fftw-* 
+	-rm ../include/fftw3.f	../include/fftw3.f03	../include/fftw3.h	../include/fftw3l.f03	../include/fftw3q.f03 ../lib/libfftw3.a	../lib/libfftw3.la
diff --git a/download/gmm/cxxflags b/download/gmm/cxxflags
index bc90bb4..e805e18 100644
--- a/download/gmm/cxxflags
+++ b/download/gmm/cxxflags
@@ -1,8 +1,8 @@
 CXX = clang++ -std=c++11
-MPICXX = /Users/hecht/openmpi-1.6/bin/mpic++
+MPICXX = 
 ac_ct_CXX = 
 CC = clang 
-MPICC = /Users/hecht/openmpi-1.6/bin/mpicc
+MPICC = 
 YACC = bison -y
 ac_ct_CC = clang 
 CXXFLAGS = -g  -m64 -fPIC -g  -DBAMG_LONG_LONG -DCHECK_KN -fno-inline  -fexceptions -fPIC
diff --git a/download/hips/Makefile b/download/hips/Makefile
index 30a6d86..223eab1 100644
--- a/download/hips/Makefile
+++ b/download/hips/Makefile
@@ -1,209 +1,211 @@
-# Downloading and compiling extra libraries
-# -----------------------------------------
-# $Id: Makefile,v 1.2 2010/03/31 08:50:56 hecht Exp $
-include makefile.inc
-
-all-local: hips
-
-# Downloading and compiling HIPS
-# ------------------------------
-# http://hips.gforge.inria.fr/release/hips-1.2b-rc4.tar.gz
-# Hips information
-
-DIRPKG=../pkg
-SRCDIR=hips-$(hips_VERSION)
-PACKAGE=$(DIRPKG)/hips-$(hips_VERSION).tar.gz
-SERVER=http://hips.gforge.inria.fr/release/
-INSTALL=../..
-hips_VERSION=1.2b-rc4
-
-# rappel ::  SRC= $(wildcard *.c) ==> permet de chopper tout les points *.c d'un repertoire
-# OBJ =  $(SRC:.c=.o)
-# ==> implique *.o dans les repertoire pour recuperer
-
-SRCPhidalCommon = $(SRCDIR)/SRC/PHIDAL/COMMON
-ObjPhidalCommon = $(SRCPhidalCommon)/*.o
-
-SRCPhidalOrdering = $(SRCDIR)/SRC/PHIDAL/ORDERING
-ObjPhidalOrdering = $(SRCPhidalOrdering)/*.o 
-
-SRCPhidalSequential = $(SRCDIR)/SRC/PHIDAL/SEQUENTIAL
-ObjPhidalSequential  = $(SRCPhidalSequential)/*.o 
-
-SRCDBMATRIX = $(SRCDIR)/SRC/BLOCK/DBMATRIX/
-ObjBlockDBMATRIX   = $(SRCDIR)/SRC/BLOCK/DBMATRIX/amalgamate.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix2PhidalMatrix.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_Build.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_Copy.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_FACTO2.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_FACTO.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_FACTOu.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_func.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_GEMM.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_GEMM_N.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_GEMMu.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMATRIX_MatVec2.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMATRIX_MatVec.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMATRIX_MLILUPrec.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMATRIX_MLIutil.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMATRIX_PrecSolve.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMATRIX_SEQ.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_Setup.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_SetupHID.o \
-  	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_solve2.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_solve.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_TRSM.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBPrec_FACTO_TRSM_GEMM_LL.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBPrec_FACTO_TRSM_GEMM_RL.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBPrec_FACTO_TRSM_GEMM_RL_DROP.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBPrec_func.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBPrec_pic.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBPrec_SchurProd.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/db_struct.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/dumpDBMatrix.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/HIPS_SymbolMatrix.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/PHIDAL_SymbolMatrix.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/print.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/SF_Direct.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/size.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMATRIX_MLICCPrec.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix2PhidalMatrix_drop.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/HIPS_Fgmresd_PH_DB.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_SetupHID.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMATRIX_MLICCPrec.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMATRIX_MLILUPrec.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBPrec_FACTO_TRSM_GEMM_LL.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBPrec_FACTO_TRSM_GEMM_LLu.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_FACTO.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_FACTO2u.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBPrec_FACTO_TRSM_GEMM_RL.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBPrec_FACTO_TRSM_GEMM_RLu.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBPrec_FACTO_TRSM_GEMM_RL_DROP.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBPrec_FACTO_TRSM_GEMM_RL_DROPu.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/HIPS_Fgmresd_DB_PH.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/HIPS_Fgmresd_PH_DB.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/HIPS_Fgmresd_DB.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/HIPS_Fgmresd_DB_DB.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/HIPS_PCG_DB_PH.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/HIPS_PCG_PH_DB.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/HIPS_PCG_DB.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/HIPS_PCG_DB_DB.o \
-	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix2PhidalMatrix_drop.o
-
-
-
-SRCBlockSOLVMATRIX = $(SRCDIR)/SRC/BLOCK/SOLVMATRIX
-ObjBlockSOLVMATRIX = $(SRCBlockSOLVMATRIX)/*.o
-
-SRCBlockSOLVMATRIX2 = $(SRCDIR)/SRC/BLOCK/SOLVMATRIX2
-ObjBlockSOLVMATRIX2 = $(SRCBlockSOLVMATRIX2)/*.o
-
-#/SRC/IO;
-ObjIO = $(SRCDIR)/SRC/IO/*.o
-
-#/SRC/PHIDAL/PARALLEL
-SRCPhidalParallel = $(SRCDIR)/SRC/PHIDAL/PARALLEL
-ObjPhidalParallel  = $(SRCPhidalParallel)/*.o 
-
-#SRC/BLOCK/PARALLEL
-ObjBlockParallel = $(SRCDIR)/SRC/BLOCK/PARALLEL/DBDistrMatrix_func.o $(SRCDIR)/SRC/BLOCK/PARALLEL/DBDistrMatrix_Build.o $(SRCDIR)/SRC/BLOCK/PARALLEL/DBDistrMatrix_Setup.o $(SRCDIR)/SRC/BLOCK/PARALLEL/DBDistrMatrix_Copy.o $(SRCDIR)/SRC/BLOCK/PARALLEL/DBDISTRMATRIX_SEQ.o $(SRCDIR)/SRC/BLOCK/PARALLEL/DBDISTRMATRIX_MLICCPrec.o $(SRCDIR)/SRC/BLOCK/PARALLEL/DBDISTRMATRIX_MLILUPrec.o $(SRCDIR)/SRC/BLOCK/PARALLEL/db_parallel_struct.o $(SRCDIR)/SRC/BLOCK/PARALLEL/DBcomm.o $(SRCDIR)/SRC/BLOCK/PARA [...]
-	$(SRCDIR)/SRC/BLOCK/PARALLEL/DBDistrPrec_FACTO_TRSM_GEMM_LL.o \
-	$(SRCDIR)/SRC/BLOCK/PARALLEL/DBDistrPrec_FACTO_TRSM_GEMM_RL.o \
-	$(SRCDIR)/SRC/BLOCK/PARALLEL/DBDistrPrec_FACTO_TRSM_GEMM_RL_DROP.o \
-	$(SRCDIR)/SRC/BLOCK/PARALLEL/DBDistrPrec_FACTO_TRSM_GEMM_LLu.o \
-	$(SRCDIR)/SRC/BLOCK/PARALLEL/DBDistrPrec_FACTO_TRSM_GEMM_RLu.o \
-	$(SRCDIR)/SRC/BLOCK/PARALLEL/DBDistrPrec_FACTO_TRSM_GEMM_RL_DROPu.o \
-	$(SRCDIR)/SRC/BLOCK/PARALLEL/DBDistrPrec_func2.o $(SRCDIR)/SRC/BLOCK/PARALLEL/DBDistrMatrix_solve_sub.o $(SRCDIR)/SRC/BLOCK/PARALLEL/DBcomm2.o $(SRCDIR)/SRC/BLOCK/PARALLEL/DBDISTRMATRIX_MatVec2.o
-
-
-#SRC/HIPS_WRAPPER
-ObjHIPS_WRAPPER= $(SRCDIR)/SRC/HIPS_WRAPPER/*.o
-
-#SRC/BLAS
-ObjBLAS= $(SRCDIR)/SRC/BLAS/zsymv.o $(SRCDIR)/SRC/BLAS/csymv.o
-
-#SRC/SPKIT pas besoin
-ObjSPKIT= $(SRCDIR)/SRC/SPKIT/skitfc.o $(SRCDIR)/SRC/SPKIT/skitf.o
-
-
-# definition of obj for librairies
-OBJLIBHIPSSEQUENTIAL = $(ObjPhidalCommon) $(ObjPhidalOrdering) $(ObjPhidalSequential) $(ObjBlockDBMATRIX) $(ObjBlockSOLVMATRIX) $(ObjBlockSOLVMATRIX2) $(ObjHIPS_WRAPPER) $(ObjBLAS)
-OBJLIBHIPS = $(ObjPhidalCommon) $(ObjPhidalOrdering) $(ObjPhidalSequential) $(ObjBlockDBMATRIX) $(ObjBlockSOLVMATRIX) $(ObjBlockSOLVMATRIX2) $(ObjPhidalParallel) $(ObjBlockParallel) $(ObjHIPS_WRAPPER) $(ObjBLAS)
-
-OBJLIBIO = $(ObjIO)
-
-ifndef FC
-OBJLIBSPKIT = 
-else
-OBJLIBSPKIT = $(ObjSPKIT)
-endif
-
-hips: FAIRE  
-
-FAIT:  
-	$(MAKE) ..  WHERE
-	touch FAIT
-
-FAIRE: FAIT 
-
-makefile.inc: ../Makefile   ../../config.status makefile-hips.inc Makefile     
-	../../config.status  --file="makefile.inc:makefile-hips.inc"
-
-
-install:..
-
-..: $(SRCDIR)/tag-ff++
-	cp makefile.inc $(SRCDIR)
-	cd $(SRCDIR); $(MAKE)
-	-rm $(SRCDIR)/LIB/*.a
-	$(AR) $(ARFLAGS) $(SRCDIR)/LIB/libhips.a $(OBJLIBHIPS)
-	$(RANLIB) $(SRCDIR)/LIB/libhips.a
-	$(AR) $(ARFLAGS) $(SRCDIR)/LIB/libhipssequential.a $(OBJLIBHIPSSEQUENTIAL)
-	$(RANLIB) $(SRCDIR)/LIB/libhipssequential.a
-	$(AR) $(ARFLAGS) $(SRCDIR)/LIB/libio.a $(OBJLIBIO) 
-	$(RANLIB) $(SRCDIR)/LIB/libio.a
-	if [ -n "$(OBJLIBSPKIT)" ] ; then \
-	$(AR) $(ARFLAGS) $(SRCDIR)/LIB/libspkit.a $(OBJLIBSPKIT) ;\
-	$(RANLIB) $(SRCDIR)/LIB/libspkit.a;\
-	fi
-	mkdir -p ../include/hips
-	cp $(SRCDIR)/LIB/*.h ../include/hips/
-	mkdir -p ../lib/hips
-	cp $(SRCDIR)/LIB/*.a ../lib/hips
-WHERE:
-	echo hips LD -L at DIR@/lib/hips -lio -lhips  >../lib/WHERE.hips
-	echo hips INCLUDE -I at DIR@/include/hips>> ../lib/WHERE.hips
-	echo hipssequential LD -L at DIR@/lib/hips -lio -lhipssequential  >>../lib/WHERE.hips
-	echo hipssequential INCLUDE -I at DIR@/include/hips  >> ../lib/WHERE.hips
-
-
-$(SRCDIR)/tag-ff++: $(PACKAGE)
-	tar xvzf $(PACKAGE)
-	cd $(SRCDIR); patch -p1 <../hips-1.2b-rc4.patch
-#	cd $(SRCDIR)/SRC/INCLUDE/; patch -p1 < ../../../hips-1.2b-rc4-1.patch;
-#	cd $(SRCDIR)/SRC/IO/; patch -p1 < ../../../hips-1.2b-rc4-2.patch;
-#	cd $(SRCDIR); for d in SRC/INCLUDE SRC/IO SRC/SPKIT TESTS/PARALLEL; do \
-#	  cp $$d/makefile $$d/makefile.orig; \
-#	  sed 's/\$$(CC).*-E/$$(CPP) $$(CFLAGS) $$(CC_OPT)/' >$$d/makefile <$$d/makefile.orig;\
-#	done
-#	cp  SRC_SPKIT_makefile $(SRCDIR)/SRC/SPKIT/makefile
-	touch $(SRCDIR)/tag-ff++
-
-$(PACKAGE):
-	-mkdir $(DIRPKG)
-	cd $(DIRPKG);$(WGET)   $(SERVER)/`basename $(PACKAGE)`
-
-clean-local:
-	-cd $(SRCDIR) && $(MAKE) clean  -C $(SRCDIR)
-	rm makefile.inc
-	-rm ../WHERE/hips
-	-rm ../lib/hips/*
-	-rm -rf ../lib/hips/
-	-rm ../include/hips/*
-	-rm -rf ../include/hips/
-	-rm -rf $(SRCDIR)
-	rm FAIT
-
-clean: clean-local
-
+# Downloading and compiling extra libraries
+# -----------------------------------------
+# $Id: Makefile,v 1.2 2010/03/31 08:50:56 hecht Exp $
+include makefile.inc
+
+all-local: hips
+
+# Downloading and compiling HIPS
+# ------------------------------
+# http://hips.gforge.inria.fr/release/hips-1.2b-rc4.tar.gz
+# Hips information
+
+DIRPKG=../pkg
+SRCDIR=hips-$(hips_VERSION)
+PACKAGE=$(DIRPKG)/hips-$(hips_VERSION).tar.gz
+SERVER=http://hips.gforge.inria.fr/release/
+INSTALL=../..
+hips_VERSION=1.2b-rc4
+
+# rappel ::  SRC= $(wildcard *.c) ==> permet de chopper tout les points *.c d'un repertoire
+# OBJ =  $(SRC:.c=.o)
+# ==> implique *.o dans les repertoire pour recuperer
+
+SRCPhidalCommon = $(SRCDIR)/SRC/PHIDAL/COMMON
+ObjPhidalCommon = $(SRCPhidalCommon)/*.o
+
+SRCPhidalOrdering = $(SRCDIR)/SRC/PHIDAL/ORDERING
+ObjPhidalOrdering = $(SRCPhidalOrdering)/*.o 
+
+SRCPhidalSequential = $(SRCDIR)/SRC/PHIDAL/SEQUENTIAL
+ObjPhidalSequential  = $(SRCPhidalSequential)/*.o 
+
+SRCDBMATRIX = $(SRCDIR)/SRC/BLOCK/DBMATRIX/
+ObjBlockDBMATRIX   = $(SRCDIR)/SRC/BLOCK/DBMATRIX/amalgamate.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix2PhidalMatrix.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_Build.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_Copy.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_FACTO2.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_FACTO.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_FACTOu.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_func.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_GEMM.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_GEMM_N.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_GEMMu.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMATRIX_MatVec2.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMATRIX_MatVec.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMATRIX_MLILUPrec.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMATRIX_MLIutil.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMATRIX_PrecSolve.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMATRIX_SEQ.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_Setup.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_SetupHID.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_solve2.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_solve.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_TRSM.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBPrec_FACTO_TRSM_GEMM_LL.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBPrec_FACTO_TRSM_GEMM_RL.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBPrec_FACTO_TRSM_GEMM_RL_DROP.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBPrec_func.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBPrec_pic.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBPrec_SchurProd.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/db_struct.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/dumpDBMatrix.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/HIPS_SymbolMatrix.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/PHIDAL_SymbolMatrix.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/print.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/SF_Direct.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/size.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMATRIX_MLICCPrec.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix2PhidalMatrix_drop.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/HIPS_Fgmresd_PH_DB.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_SetupHID.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMATRIX_MLICCPrec.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMATRIX_MLILUPrec.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBPrec_FACTO_TRSM_GEMM_LL.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBPrec_FACTO_TRSM_GEMM_LLu.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_FACTO.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix_FACTO2u.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBPrec_FACTO_TRSM_GEMM_RL.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBPrec_FACTO_TRSM_GEMM_RLu.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBPrec_FACTO_TRSM_GEMM_RL_DROP.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBPrec_FACTO_TRSM_GEMM_RL_DROPu.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/HIPS_Fgmresd_DB_PH.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/HIPS_Fgmresd_PH_DB.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/HIPS_Fgmresd_DB.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/HIPS_Fgmresd_DB_DB.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/HIPS_PCG_DB_PH.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/HIPS_PCG_PH_DB.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/HIPS_PCG_DB.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/HIPS_PCG_DB_DB.o \
+	$(SRCDIR)/SRC/BLOCK/DBMATRIX/DBMatrix2PhidalMatrix_drop.o
+
+
+
+SRCBlockSOLVMATRIX = $(SRCDIR)/SRC/BLOCK/SOLVMATRIX
+ObjBlockSOLVMATRIX = $(SRCBlockSOLVMATRIX)/*.o
+
+SRCBlockSOLVMATRIX2 = $(SRCDIR)/SRC/BLOCK/SOLVMATRIX2
+ObjBlockSOLVMATRIX2 = $(SRCBlockSOLVMATRIX2)/*.o
+
+#/SRC/IO;
+ObjIO = $(SRCDIR)/SRC/IO/*.o
+
+#/SRC/PHIDAL/PARALLEL
+SRCPhidalParallel = $(SRCDIR)/SRC/PHIDAL/PARALLEL
+ObjPhidalParallel  = $(SRCPhidalParallel)/*.o 
+
+#SRC/BLOCK/PARALLEL
+ObjBlockParallel = $(SRCDIR)/SRC/BLOCK/PARALLEL/DBDistrMatrix_func.o $(SRCDIR)/SRC/BLOCK/PARALLEL/DBDistrMatrix_Build.o $(SRCDIR)/SRC/BLOCK/PARALLEL/DBDistrMatrix_Setup.o $(SRCDIR)/SRC/BLOCK/PARALLEL/DBDistrMatrix_Copy.o $(SRCDIR)/SRC/BLOCK/PARALLEL/DBDISTRMATRIX_SEQ.o $(SRCDIR)/SRC/BLOCK/PARALLEL/DBDISTRMATRIX_MLICCPrec.o $(SRCDIR)/SRC/BLOCK/PARALLEL/DBDISTRMATRIX_MLILUPrec.o $(SRCDIR)/SRC/BLOCK/PARALLEL/db_parallel_struct.o $(SRCDIR)/SRC/BLOCK/PARALLEL/DBcomm.o $(SRCDIR)/SRC/BLOCK/PARA [...]
+	$(SRCDIR)/SRC/BLOCK/PARALLEL/DBDistrPrec_FACTO_TRSM_GEMM_LL.o \
+	$(SRCDIR)/SRC/BLOCK/PARALLEL/DBDistrPrec_FACTO_TRSM_GEMM_RL.o \
+	$(SRCDIR)/SRC/BLOCK/PARALLEL/DBDistrPrec_FACTO_TRSM_GEMM_RL_DROP.o \
+	$(SRCDIR)/SRC/BLOCK/PARALLEL/DBDistrPrec_FACTO_TRSM_GEMM_LLu.o \
+	$(SRCDIR)/SRC/BLOCK/PARALLEL/DBDistrPrec_FACTO_TRSM_GEMM_RLu.o \
+	$(SRCDIR)/SRC/BLOCK/PARALLEL/DBDistrPrec_FACTO_TRSM_GEMM_RL_DROPu.o \
+	$(SRCDIR)/SRC/BLOCK/PARALLEL/DBDistrPrec_func2.o $(SRCDIR)/SRC/BLOCK/PARALLEL/DBDistrMatrix_solve_sub.o $(SRCDIR)/SRC/BLOCK/PARALLEL/DBcomm2.o $(SRCDIR)/SRC/BLOCK/PARALLEL/DBDISTRMATRIX_MatVec2.o
+
+
+#SRC/HIPS_WRAPPER
+ObjHIPS_WRAPPER= $(SRCDIR)/SRC/HIPS_WRAPPER/*.o
+
+#SRC/BLAS
+ObjBLAS= $(SRCDIR)/SRC/BLAS/zsymv.o $(SRCDIR)/SRC/BLAS/csymv.o
+
+#SRC/SPKIT pas besoin
+ObjSPKIT= $(SRCDIR)/SRC/SPKIT/skitfc.o $(SRCDIR)/SRC/SPKIT/skitf.o
+
+
+# definition of obj for librairies
+OBJLIBHIPSSEQUENTIAL = $(ObjPhidalCommon) $(ObjPhidalOrdering) $(ObjPhidalSequential) $(ObjBlockDBMATRIX) $(ObjBlockSOLVMATRIX) $(ObjBlockSOLVMATRIX2) $(ObjHIPS_WRAPPER) $(ObjBLAS)
+OBJLIBHIPS = $(ObjPhidalCommon) $(ObjPhidalOrdering) $(ObjPhidalSequential) $(ObjBlockDBMATRIX) $(ObjBlockSOLVMATRIX) $(ObjBlockSOLVMATRIX2) $(ObjPhidalParallel) $(ObjBlockParallel) $(ObjHIPS_WRAPPER) $(ObjBLAS)
+
+OBJLIBIO = $(ObjIO)
+
+ifndef FC
+OBJLIBSPKIT = 
+else
+OBJLIBSPKIT = $(ObjSPKIT)
+endif
+
+hips: FAIRE  
+
+# FFCS: more dependencies for parallel builds
+FAIT:$(SRCDIR)/tag-ff++
+	$(MAKE) ..  WHERE
+	touch FAIT
+
+FAIRE: FAIT 
+
+makefile.inc: ../Makefile   ../../config.status makefile-hips.inc Makefile     
+	../../config.status  --file="makefile.inc:makefile-hips.inc"
+
+
+install:..
+
+..: $(SRCDIR)/tag-ff++
+	cp makefile.inc $(SRCDIR)
+	cd $(SRCDIR); $(MAKE)
+	-rm $(SRCDIR)/LIB/*.a
+	$(AR) $(ARFLAGS) $(SRCDIR)/LIB/libhips.a $(OBJLIBHIPS)
+	$(RANLIB) $(SRCDIR)/LIB/libhips.a
+	$(AR) $(ARFLAGS) $(SRCDIR)/LIB/libhipssequential.a $(OBJLIBHIPSSEQUENTIAL)
+	$(RANLIB) $(SRCDIR)/LIB/libhipssequential.a
+	$(AR) $(ARFLAGS) $(SRCDIR)/LIB/libio.a $(OBJLIBIO) 
+	$(RANLIB) $(SRCDIR)/LIB/libio.a
+	if [ -n "$(OBJLIBSPKIT)" ] ; then \
+	$(AR) $(ARFLAGS) $(SRCDIR)/LIB/libspkit.a $(OBJLIBSPKIT) ;\
+	$(RANLIB) $(SRCDIR)/LIB/libspkit.a;\
+	fi
+	mkdir -p ../include/hips
+	cp $(SRCDIR)/LIB/*.h ../include/hips/
+	mkdir -p ../lib/hips
+	cp $(SRCDIR)/LIB/*.a ../lib/hips
+WHERE:
+	echo hips LD -L at DIR@/lib/hips -lio -lhips  >../lib/WHERE.hips
+	echo hips INCLUDE -I at DIR@/include/hips>> ../lib/WHERE.hips
+	echo hipssequential LD -L at DIR@/lib/hips -lio -lhipssequential  >>../lib/WHERE.hips
+	echo hipssequential INCLUDE -I at DIR@/include/hips  >> ../lib/WHERE.hips
+
+
+$(SRCDIR)/tag-ff++: $(PACKAGE)
+	tar xvzf $(PACKAGE)
+	cd $(SRCDIR); patch -p1 <../hips-1.2b-rc4.patch
+#	cd $(SRCDIR)/SRC/INCLUDE/; patch -p1 < ../../../hips-1.2b-rc4-1.patch;
+#	cd $(SRCDIR)/SRC/IO/; patch -p1 < ../../../hips-1.2b-rc4-2.patch;
+#	cd $(SRCDIR); for d in SRC/INCLUDE SRC/IO SRC/SPKIT TESTS/PARALLEL; do \
+#	  cp $$d/makefile $$d/makefile.orig; \
+#	  sed 's/\$$(CC).*-E/$$(CPP) $$(CFLAGS) $$(CC_OPT)/' >$$d/makefile <$$d/makefile.orig;\
+#	done
+#	cp  SRC_SPKIT_makefile $(SRCDIR)/SRC/SPKIT/makefile
+	touch $(SRCDIR)/tag-ff++
+
+$(PACKAGE):
+	-mkdir $(DIRPKG)
+	cd $(DIRPKG);$(WGET)   $(SERVER)/`basename $(PACKAGE)`
+
+# FFCS: avoid loops when SRCDIR does not exist
+clean-local:
+	-cd $(SRCDIR) && $(MAKE) clean  -C $(SRCDIR)
+	rm makefile.inc
+	-rm ../WHERE/hips
+	-rm ../lib/hips/*
+	-rm -rf ../lib/hips/
+	-rm ../include/hips/*
+	-rm -rf ../include/hips/
+	-rm -rf $(SRCDIR)
+	-rm FAIT
+
+clean: clean-local
+
 .PHONY:..
\ No newline at end of file
diff --git a/download/hips/makefile-hips.inc b/download/hips/makefile-hips.inc
index 8939cb9..beb9193 100755
--- a/download/hips/makefile-hips.inc
+++ b/download/hips/makefile-hips.inc
@@ -1,6 +1,9 @@
 abs_top_builddir=@abs_top_builddir@
 DOWNLOADFF=$(abs_top_builddir)/download/
-include $(DOWNLOADFF)/headers-sparsesolver.inc
+
+# ALH - allow include to fail for make clean
+-include $(DOWNLOADFF)/headers-sparsesolver.inc
+
 ### ADD for freefem++
 ###
 ###  HIPS specific compilation flags
diff --git a/download/ipopt/Makefile b/download/ipopt/Makefile
old mode 100644
new mode 100755
index 7e313c6..8f47887
--- a/download/ipopt/Makefile
+++ b/download/ipopt/Makefile
@@ -1,74 +1,80 @@
-# Downloading and compiling extra libraries
-# -----------------------------------------
-
-# $Id$
-include Makefile.inc
-
-all-local: Ipopt
-
-# Downloading and compiling mumps
-# ------------------------------
-
-DIR=$(DOWNLOADFF)/ipopt
-DIRPKG=../pkg
-SRCDIR=Ipopt-$(VERSION)
-PACKAGE=$(DIRPKG)/Ipopt-$(VERSION).tgz
-INSTALL=../..
-VERSION=3.10.2
-# 3.10.2
-URL=http://www.coin-or.org/download/source/Ipopt
-FHSL=#$(DIRPKG)/ddeps.f $(DIRPKG)/ma27ad.f  $(DIRPKG)/mc19d.f 
-LIBMUMPS=-L$(DOWNLOADFF)/lib  -ldmumpsFREEFEM-SEQ -lzmumpsFREEFEM-SEQ -lmumps_commonFREEFEM-SEQ -lpordFREEFEM-SEQ -lmpiseqFREEFEM-SEQ
-INCMUMPS=$(DOWNLOADFF)/include/libseq 
-#/Ipopt-3.10.2.tgz
-Ipopt: $(SRCDIR)/FAIRE
-#  --enable-static  --disable-shared  
-$(SRCDIR)/FAIT: $(SRCDIR)/tag-tar
-	cd $(SRCDIR) ; \
-	 ./configure \
-		   --disable-shared --enable-static \
-                  --with-mumps='$(LIBMUMPS)' \
-	          --without-hsl \
-	          --with-mumps-incdir='$(INCMUMPS)' \
-	  CXX='$(CXX)' CXXFLAGS='$(CXXFLAGS) -I$(INCMUMPS)' \
-	  CC='$(CC)' CFLAGS='$(CFLAGS) -I$(INCMUMPS)' \
-	  F77='$(FC)' FFLAGS='$(FCFLAGS)' \
-	  CXXCPP='$(CXXCPP)'  CPP='$(CXXCPP)' \
-	 --with-blas='$(LIBBLAS)' --with-lapack='$(LIBLAPACK)' --prefix='$(DOWNLOADFF)'
-	touch $(SRCDIR)/FAIT	
-install: $(SRCDIR)/FAIT
-	$(MAKE)  -C  $(SRCDIR) install	
-
-WHERE: 
-	if [ -f $(SRCDIR)/FAIT  ] ;then \
-	$(MAKE)  -C  $(SRCDIR) install ; \
-	echo Ipopt LD -L at DIR@/lib   -lipopt   >../lib/WHERE.Ipopt;\
-	echo Ipopt INCLUDE -I at DIR@/include/coin  >> ../lib/WHERE.Ipopt ;\
-	fi
-
-Makefile.inc:
-	../../config.status  --file="Makefile.inc:Makefile.inc.in"
-
-$(SRCDIR)/FAIRE:
-	$(MAKE) install WHERE 
-	touch $(SRCDIR)/FAIRE
-
-
-
-$(SRCDIR)/tag-tar:$(PACKAGE) $(FHSL) 
-	tar xvzf $(PACKAGE)
-	patch -p0 <patch-IpBlas
-	#cp $(FHSL) $(SRCDIR)/ThirdParty/HSL/
-	touch $(SRCDIR)/tag-tar
-
-$(PACKAGE):
-	cd `dirname $@`; $(WGET)   $(URL)/`basename $(PACKAGE)`
-clean-local:
-	rm -rf  $(SRCDIR)  *~ Makefile.inc
-	-rm -rf ../include/coin
-	-rm ../lib/libipopt* ../lib/liblcoinhsl* 
-
-clean: clean-local
-
-
-.PHONY:..
\ No newline at end of file
+# Downloading and compiling extra libraries
+# -----------------------------------------
+
+# $Id$
+include Makefile.inc
+
+all-local: Ipopt
+
+# Downloading and compiling mumps
+# ------------------------------
+
+DIR=$(DOWNLOADFF)/ipopt
+DIRPKG=../pkg
+SRCDIR=Ipopt-$(VERSION)
+PACKAGE=$(DIRPKG)/Ipopt-$(VERSION).tgz
+INSTALL=../..
+VERSION=3.10.2
+# 3.10.2
+URL=http://www.coin-or.org/download/source/Ipopt
+FHSL=#$(DIRPKG)/ddeps.f $(DIRPKG)/ma27ad.f  $(DIRPKG)/mc19d.f 
+LIBMUMPS=-L$(DOWNLOADFF)/lib  -ldmumpsFREEFEM-SEQ -lzmumpsFREEFEM-SEQ -lmumps_commonFREEFEM-SEQ -lpordFREEFEM-SEQ -lmpiseqFREEFEM-SEQ
+INCMUMPS=$(DOWNLOADFF)/include/libseq 
+#/Ipopt-3.10.2.tgz
+Ipopt: $(SRCDIR)/FAIRE
+#  --enable-static  --disable-shared  
+$(SRCDIR)/FAIT: $(SRCDIR)/tag-tar
+#	FFCS - disable dependency tracking like in FFCS itself for MinGW compilation (problem with backslashes, see
+#	[[file:../../../../configure.ac::enable_dependency_tracking]])
+	cd $(SRCDIR) ; \
+	 ./configure --disable-dependency-tracking \
+		   --disable-shared --enable-static \
+                  --with-mumps='$(LIBMUMPS)' \
+	          --without-hsl \
+	          --with-mumps-incdir='$(INCMUMPS)' \
+	  CXX='$(CXX)' CXXFLAGS='$(CXXFLAGS) -I$(INCMUMPS)' \
+	  CC='$(CC)' CFLAGS='$(CFLAGS) -I$(INCMUMPS)' \
+	  F77='$(FC)' FFLAGS='$(FCFLAGS)' \
+	  CXXCPP='$(CXXCPP)'  CPP='$(CXXCPP)' \
+	 --with-blas='$(LIBBLAS)' --with-lapack='$(LIBLAPACK)' --prefix='$(DOWNLOADFF)'
+	touch $(SRCDIR)/FAIT	
+
+# FFCS - avoid remaking install every time
+install.done: $(SRCDIR)/FAIT
+	$(MAKE)  -C  $(SRCDIR) install	
+	touch $@
+clean-local::
+	-rm *.done
+
+# FFCS - install and WHERE need to be sequential
+WHERE.done: install.done
+	echo Ipopt LD -L at DIR@/lib   -lipopt   >$(SRCDIR)/$(INSTALL)/lib/WHERE.Ipopt;
+	echo Ipopt INCLUDE -I at DIR@/include/coin  >> $(SRCDIR)/$(INSTALL)/lib/WHERE.Ipopt ;
+	touch $@
+
+Makefile.inc:
+	../../config.status  --file="Makefile.inc:Makefile.inc.in"
+
+# FFCS - install and WHERE need to be sequential
+$(SRCDIR)/FAIRE: install.done WHERE.done
+	touch $@
+
+
+$(SRCDIR)/$(INSTALL): $(SRCDIR)/tag-tar
+
+$(SRCDIR)/tag-tar:$(PACKAGE) $(FHSL) 
+	tar xvzf $(PACKAGE)
+	patch -p0 <patch-IpBlas
+	touch $(SRCDIR)/tag-tar
+
+$(PACKAGE):
+	cd `dirname $@`; $(WGET)   $(URL)/`basename $(PACKAGE)`
+clean-local::
+	rm -rf  $(SRCDIR)  *~ Makefile.inc
+
+clean: clean-local
+	-rm -rf ../include/coin
+	-rm ../lib/libipopt* ../lib/liblcoinhsl* 
+	-rm $(PACKAGE)
+
+.PHONY:$(SRCDIR)/$(INSTALL)
diff --git a/download/metis/Makefile b/download/metis/Makefile
index 7986017..c446d4c 100644
--- a/download/metis/Makefile
+++ b/download/metis/Makefile
@@ -1,84 +1,93 @@
-# Downloading and compiling extra libraries
-# -----------------------------------------
-
-# $Id$
-include Makefile.in
-
-all-local: metis
-
-# Downloading and compiling Tetgen
-# ------------------------------
-# http://glaros.dtc.umn.edu/gkhome/fetch/sw/metis/metis-4.0.tar.gz
-# Metis information
-DIRPKG=../pkg
-SRCDIR=metis-$(metis_VERSION)
-PACKAGE=$(DIRPKG)/metis-$(metis_VERSION).tar.gz
-SERVER=http://www.netlib.org/linalg/
-#//http://glaros.dtc.umn.edu/gkhome/fetch/sw/metis/OLD
-INSTALL=../..
-metis_VERSION=4.0
-
-metis: FAIRE
-
-
-$(SRCDIR)/FAIT:
-	$(MAKE) install
-	touch $(SRCDIR)/FAIT
-
-install:$(SRCDIR)/tag-compile
-	cd $(SRCDIR)/Programs ;$(MAKE) 
-	-mkdir -p ../include/metis
-	cp $(SRCDIR)/Lib/*.h ../include/metis
-
-
-FAIRE: $(SRCDIR)/FAIT 
-	$(MAKE) WHERE
-	touch FAIRE
-
-Makefile.in: ../../config.status Makefile-metis.in
-	../../config.status  --file="Makefile.in:Makefile-metis.in"
-
-$(SRCDIR)/tag-compile: $(SRCDIR)/tags
-	cp Makefile.in $(SRCDIR)
-	-mkdir -p ../lib/metis
-	cd $(SRCDIR)/Lib;make
-	-cd $(SRCDIR)/Programs;make 
-	touch $(SRCDIR)/tag-compile
-
-
-
-WHERE: 
-	-if [ -f $(SRCDIR)/FAIT ] ; then \
-	echo metis LD -L at DIR@/lib/metis -lmetis  >$(SRCDIR)/$(INSTALL)/lib/WHERE.metis ;\
-	echo metis INCLUDE -I at DIR@/include/metis>> $(SRCDIR)/$(INSTALL)/lib/WHERE.metis ;\
-	fi
-
-
-
-
-$(SRCDIR)/tags: $(PACKAGE)
-	tar xvzf $(PACKAGE)
-	patch -p0  <patch-metis
-	mv  $(SRCDIR)/Programs/Makefile $(SRCDIR)/Programs/Makefile-orig
-	sed -e 's;BINDIR = ..;BINDIR = ../$(INSTALL)/bin;' \
-            -e 's;../libmetis.a;../$(INSTALL)/lib/metis/libmetis.a;' \
-            -e 's;-L[.][.];-L../$(INSTALL)/lib/metis;' \
-          <$(SRCDIR)/Programs/Makefile-orig \
-          >$(SRCDIR)/Programs/Makefile
-	mv $(SRCDIR)/Lib/Makefile $(SRCDIR)/Lib/Makefile-orig
-	sed   -e 's;../libmetis.a;../$(INSTALL)/lib/metis/libmetis.a;' \
-          <$(SRCDIR)/Lib/Makefile-orig \
-          >$(SRCDIR)/Lib/Makefile
-	touch $(SRCDIR)/tags
-
-$(PACKAGE):
-	cd $(DIRPKG);$(WGET)   $(SERVER)/`basename $(PACKAGE)`
-clean-local:
-	-cd $(SRCDIR) && $(MAKE) realclean  -C $(SRCDIR)
-	-rm -rf metis*
-	-rm -rf ../lib/metis ../lib/WHERE.metis
-	-rm -rf ../include/metis
-	-rm -rf $(SRCDIR)
-	-rm FAIRE FAIT 
-
-clean: clean-local
+# Downloading and compiling extra libraries
+# -----------------------------------------
+
+# $Id$
+include Makefile.in
+
+all-local: metis
+
+# Downloading and compiling Tetgen
+# ------------------------------
+# http://glaros.dtc.umn.edu/gkhome/fetch/sw/metis/metis-4.0.tar.gz
+# Metis information
+DIRPKG=../pkg
+SRCDIR=metis-$(metis_VERSION)
+PACKAGE=$(DIRPKG)/metis-$(metis_VERSION).tar.gz
+SERVER=http://www.netlib.org/linalg/
+#//http://glaros.dtc.umn.edu/gkhome/fetch/sw/metis/OLD
+INSTALL=../..
+
+# FFCS - 14/11/11 - version 4.0.3 is not available from netlib anymore
+metis_VERSION=4.0
+
+metis: FAIRE
+
+
+$(SRCDIR)/FAIT:
+	$(MAKE) install
+	touch $(SRCDIR)/FAIT
+
+install:$(SRCDIR)/tag-compile
+	cd $(SRCDIR)/Programs ;$(MAKE) 
+	-mkdir -p ../include/metis
+	cp $(SRCDIR)/Lib/*.h ../include/metis
+
+
+FAIRE: $(SRCDIR)/FAIT 
+	$(MAKE) WHERE
+	touch FAIRE
+
+Makefile.in: ../../config.status Makefile-metis.in
+	../../config.status  --file="Makefile.in:Makefile-metis.in"
+
+$(SRCDIR)/tag-compile: $(SRCDIR)/tags
+	cp Makefile.in $(SRCDIR)
+	-mkdir -p ../lib/metis
+	cd $(SRCDIR)/Lib;make
+	-cd $(SRCDIR)/Programs;make 
+	touch $(SRCDIR)/tag-compile
+
+
+
+WHERE: 
+	-if [ -f $(SRCDIR)/FAIT ] ; then \
+	echo metis LD -L at DIR@/lib/metis -lmetis  >$(SRCDIR)/$(INSTALL)/lib/WHERE.metis ;\
+	echo metis INCLUDE -I at DIR@/include/metis>> $(SRCDIR)/$(INSTALL)/lib/WHERE.metis ;\
+	fi
+
+
+
+
+# FFCS: patch is necessary for metis 4.0, but not for 4.0.3
+$(SRCDIR)/tags: $(PACKAGE)
+	tar xvzf $(PACKAGE)
+	patch -p0  <patch-metis
+	patch -p0  <metis-4.0_main_return.patch
+	mv  $(SRCDIR)/Programs/Makefile $(SRCDIR)/Programs/Makefile-orig
+	sed -e 's;BINDIR = ..;BINDIR = ../$(INSTALL)/bin;' \
+            -e 's;../libmetis.a;../$(INSTALL)/lib/metis/libmetis.a;' \
+            -e 's;-L[.][.];-L../$(INSTALL)/lib/metis;' \
+          <$(SRCDIR)/Programs/Makefile-orig \
+          >$(SRCDIR)/Programs/Makefile
+	mv $(SRCDIR)/Lib/Makefile $(SRCDIR)/Lib/Makefile-orig
+	sed   -e 's;../libmetis.a;../$(INSTALL)/lib/metis/libmetis.a;' \
+          <$(SRCDIR)/Lib/Makefile-orig \
+          >$(SRCDIR)/Lib/Makefile
+	touch $(SRCDIR)/tags
+
+$(PACKAGE):
+	cd $(DIRPKG);$(WGET)   $(SERVER)/`basename $(PACKAGE)`
+clean-local:
+	-cd $(SRCDIR) && $(MAKE) realclean  -C $(SRCDIR)
+	-rm -rf metis-4.0 config.log
+	-rm -rf ../lib/metis ../lib/WHERE.metis
+	-rm -rf ../include/metis
+	-rm -rf $(SRCDIR)
+	-rm FAIRE FAIT 
+
+# FFCS - 23/5/12 - $(SRCDIR)/$(INSTALL) is meaningless if $(SRCDIR) does not exist
+clean: clean-local
+	-rm ../lib/metis/libmetis.a
+	-rm ../lib/include/metis.h
+	-rm -rf $(SRCDIR)
+	-rm FAIRE FAIT 
diff --git a/download/metis/metis-4.0_main_return.patch b/download/metis/metis-4.0_main_return.patch
new file mode 100644
index 0000000..1143972
--- /dev/null
+++ b/download/metis/metis-4.0_main_return.patch
@@ -0,0 +1,176 @@
+--- metis-4.0/Programs/kmetis.c.orig	2013-01-26 21:01:39.898052768 +0000
++++ metis-4.0/Programs/kmetis.c	2013-01-26 21:01:52.186053491 +0000
+@@ -19,7 +19,7 @@
+ /*************************************************************************
+ * Let the game begin
+ **************************************************************************/
+-main(int argc, char *argv[])
++int main(int argc, char *argv[])
+ {
+   int i, nparts, options[10];
+   idxtype *part;
+@@ -100,6 +100,8 @@
+ 
+ 
+   GKfree(&graph.xadj, &graph.adjncy, &graph.vwgt, &graph.adjwgt, &part, LTERM);
++
++  return 0;
+ }  
+ 
+ 
+--- metis-4.0/Programs/pmetis.c.orig	2013-01-26 22:42:46.375724925 +0000
++++ metis-4.0/Programs/pmetis.c	2013-01-26 22:43:33.744727711 +0000
+@@ -19,7 +19,7 @@
+ /*************************************************************************
+ * Let the game begin
+ **************************************************************************/
+-main(int argc, char *argv[])
++int main(int argc, char *argv[])
+ {
+   int i, nparts, options[10];
+   idxtype *part;
+@@ -100,6 +100,8 @@
+ 
+ 
+   GKfree(&graph.xadj, &graph.adjncy, &graph.vwgt, &graph.adjwgt, &part, LTERM);
++  
++  return 0;
+ }  
+ 
+ 
+--- ./metis-4.0/Programs/graphchk.c.orig	2013-01-26 23:00:11.167253583 +0000
++++ ./metis-4.0/Programs/graphchk.c	2013-01-26 23:00:38.003255160 +0000
+@@ -19,7 +19,7 @@
+ /*************************************************************************
+ * Let the game begin
+ **************************************************************************/
+-main(int argc, char *argv[])
++int main(int argc, char *argv[])
+ {
+   GraphType graph;
+   char filename[256];
+@@ -53,6 +53,8 @@
+ 
+ 
+   GKfree(&graph.xadj, &graph.adjncy, &graph.vwgt, &graph.adjwgt, LTERM);
++  
++  return 0;
+ }  
+ 
+ 
+--- ./metis-4.0/Programs/mesh2dual.c.orig	2013-01-26 23:02:14.677260844 +0000
++++ ./metis-4.0/Programs/mesh2dual.c	2013-01-26 23:02:45.081262631 +0000
+@@ -20,7 +20,7 @@
+ /*************************************************************************
+ * Let the game begin
+ **************************************************************************/
+-main(int argc, char *argv[])
++int main(int argc, char *argv[])
+ {
+   int i, j, ne, nn, etype, numflag=0;
+   idxtype *elmnts, *xadj, *adjncy;
+@@ -67,6 +67,7 @@
+ 
+   GKfree(&elmnts, &xadj, &adjncy, LTERM);
+ 
++  return 0;
+ }
+ 
+ 
+--- ./metis-4.0/Programs/mesh2nodal.c.orig	2013-01-26 23:03:35.671265601 +0000
++++ ./metis-4.0/Programs/mesh2nodal.c	2013-01-26 23:03:59.234266985 +0000
+@@ -20,7 +20,7 @@
+ /*************************************************************************
+ * Let the game begin
+ **************************************************************************/
+-main(int argc, char *argv[])
++int main(int argc, char *argv[])
+ {
+   int i, j, ne, nn, etype, numflag=0;
+   idxtype *elmnts, *xadj, *adjncy;
+@@ -67,6 +67,7 @@
+ 
+   GKfree(&elmnts, &xadj, &adjncy, LTERM);
+ 
++  return 0;
+ }
+ 
+ 
+--- ./metis-4.0/Programs/oemetis.c.orig	2013-01-26 23:04:51.689270079 +0000
++++ ./metis-4.0/Programs/oemetis.c	2013-01-26 23:05:15.686271479 +0000
+@@ -19,7 +19,7 @@
+ /*************************************************************************
+ * Let the game begin
+ **************************************************************************/
+-main(int argc, char *argv[])
++int main(int argc, char *argv[])
+ {
+   int i, options[10];
+   idxtype *perm, *iperm;
+@@ -90,6 +90,8 @@
+ 
+ 
+   GKfree(&graph.xadj, &graph.adjncy, &perm, &iperm, LTERM);
++  
++  return 0;
+ }  
+ 
+ 
+--- ./metis-4.0/Programs/onmetis.c.orig	2013-01-26 23:06:04.908274368 +0000
++++ ./metis-4.0/Programs/onmetis.c	2013-01-26 23:06:26.011275618 +0000
+@@ -19,7 +19,7 @@
+ /*************************************************************************
+ * Let the game begin
+ **************************************************************************/
+-main(int argc, char *argv[])
++int main(int argc, char *argv[])
+ {
+   int i, options[10];
+   idxtype *perm, *iperm;
+@@ -90,6 +90,8 @@
+ 
+ 
+   GKfree(&graph.xadj, &graph.adjncy, &perm, &iperm, LTERM);
++
++  return 0;
+ }  
+ 
+ 
+--- ./metis-4.0/Programs/partdmesh.c.orig	2013-01-26 23:07:09.315278152 +0000
++++ ./metis-4.0/Programs/partdmesh.c	2013-01-26 23:07:33.761279588 +0000
+@@ -20,7 +20,7 @@
+ /*************************************************************************
+ * Let the game begin
+ **************************************************************************/
+-main(int argc, char *argv[])
++int main(int argc, char *argv[])
+ {
+   int i, j, ne, nn, etype, numflag=0, nparts, edgecut;
+   idxtype *elmnts, *epart, *npart;
+@@ -88,6 +88,7 @@
+ 
+   GKfree(&elmnts, &epart, &npart, LTERM);
+ 
++  return 0;
+ }
+ 
+ 
+--- ./metis-4.0/Programs/partnmesh.c.orig	2013-01-26 23:09:04.858284939 +0000
++++ ./metis-4.0/Programs/partnmesh.c	2013-01-26 23:09:45.701287342 +0000
+@@ -20,7 +20,7 @@
+ /*************************************************************************
+ * Let the game begin
+ **************************************************************************/
+-main(int argc, char *argv[])
++int main(int argc, char *argv[])
+ {
+   int i, j, ne, nn, etype, numflag=0, nparts, edgecut;
+   idxtype *elmnts, *epart, *npart;
+@@ -88,6 +88,7 @@
+ 
+   GKfree(&elmnts, &epart, &npart, LTERM);
+ 
++  return 0;
+ }
+ 
+ 
diff --git a/download/mmg3d/Makefile b/download/mmg3d/Makefile
index 7f7c2dc..b191916 100644
--- a/download/mmg3d/Makefile
+++ b/download/mmg3d/Makefile
@@ -1,115 +1,116 @@
-# Downloading and compiling extra libraries
-# -----------------------------------------
-
-# $Id$
-all-local: mmg3d
-
-include ff-flags
-
-# Downloading and compiling mmg3d
-# -------------------------------
-# 
-DIRPKG= ../pkg
-SRCDIR= ./mmg3d4# lib#-$(mmg3d_VERSION)
-PACKAGE=$(DIRPKG)/mmg3d4.0.tgz #mmg3dlib.tar.gz #-$(mmg3d_VERSION).tar.gz
-INSTALL=..
-mmg3d_VERSION=
-# mmg3d pas sur internet
-LIBMMG3D=$(INSTALL)/lib/libmmg3d-v4.a
-OPT=4
-# size of the PKG file ( this file change See Cecile.)
-SIZEPKG=158547
-
-OBJS= analar.o	chkmsh.o	hash.o		memory.o	optcte.o	outqua.o	simu44.o	swap44.o	zaldy.o \
-analarcutting.o	chrono.o	heap.o		mmg3d1.o	optlap.o	pattern.o	simu56.o	swap56.o \
-baryct.o	colpoi.o	inout.o		mmg3d4.o	optlen.o	quality.o	simu68.o	swap68.o \
-boulep.o	coquil.o	length.o	mmg3d9.o	optlentet.o	queue.o		simu710.o	swap710.o \
-bucket.o	cutelt.o	librnbg.o	movevertex.o	optra4.o	ratio.o		solmap.o	swapar.o \
-		delaunay.o	locate.o	optbdry.o	opttet.o	scalem.o	spledg.o	swaptet.o \
-cenrad.o	eigenv.o	matrix.o	optcoq.o	opttyp.o	simu23.o	swap23.o	typelt.o 
-
-OBJSNOP =  cendel.o swapar.o
-
-
-mmg3d: mmg3d4/build-$(SIZEPKG)
-
-
-mmg3d4/build-$(SIZEPKG):
-	pkgs=`stat -f "%z" $(PACKAGE)`; \
-	if  test $(SIZEPKG) -ne "$$pkgs" ; then \
-	echo "++++++ PB version mmg3d version  $(SIZEPKG) != $$pkgs  +++++"  ;\
-	rm $(PACKAGE); \
-	$(MAKE) clean ; \
-	else $(MAKE) tag-tar-$(SIZEPKG); fi 
-	if [ -d mmg3d4  ] ; then  $(MAKE)  $(LIBMMG3D) install-4 WHERE ; else echo "Sorry no source " ; fi
-$(LIBMMG3D):
-	cd mmg3d4/build/sources/; $(MAKE) CC='$(CC)' CFLAGS='$(CNOFLAGS)'  $(OBJSNOP) 
-	cd mmg3d4/build/sources/; $(MAKE) CC='$(CC)' CFLAGS='$(CFLAGS)'  $(OBJS) 
-	cd mmg3d4/build/sources/mmg3dmain; $(CC) -c $(CNOFLAGS)   mmg3d.c -I..
-	$(AR) $(ARFLAGS) $(LIBMMG3D) mmg3d4/build/sources/*.o mmg3d4/build/sources/mmg3dmain/mmg3d.o
-	-$(CC) $(CNOFLAGS) mmg3d4/build/sources/mmg3dmain/mmg3d.o   mmg3d4/build/sources/*.o -o ../bin/mmg3d $(STD_LIBS)
-	touch mmg3d4/build-4 mmg3d4/FAIT-4
-install-4:
-	-mkdir ../include/mmg3d-v4/		
-	cp mmg3d4/build/sources/*.h ../include/mmg3d-v4/
-	touch mmg3d4/FAIT-4
-
-mmg3d-4:$(PACKAGE)
-
-$(PACKAGE):
-	-mkdir $(DIRPKG);
-#http://www.math.u-bordeaux1.fr/~cdobrzyn/logiciels/download.php?file=mmg3d4.0.tgz
-#http://www.math.u-bordeaux1.fr/~dobj/logiciels/mmg3d.php
-	cd $(DIRPKG);$(WGET) 'http://www.math.u-bordeaux1.fr/~cdobrzyn/logiciels/download/mmg3d4.0.tgz'
-# http://www.math.u-bordeaux1.fr/~cdobrzyn/logiciels/download.php?file=mmg3d4.0.tgz -O mmg3d4.0.tgz
-#http://www.math.u-bordeaux1.fr/~dobj/logiciels/download.php?file=`basename $(PACKAGE)`
-
-
-install:install-4 WHERE
-
-WHERE: 
-	@-if [ -f mmg3d4/FAIT-4 ] ; then \
-	make install-4;  \
-	echo mmg3d-v4  LD -L at DIR@/lib -lmmg3d-v4  >../lib/WHERE.mmg3d ;\
-	echo mmg3d-v4 INCLUDE -I at DIR@/include/mmg3d-v4>> ../lib/WHERE.mmg3d ;\
-	echo build WHERE ./lib/WHERE.mmg3d ;\
-	fi
-
-
-FAIRE: mmg3d4/FAIT-4 install-4
-
-tag-tar-$(SIZEPKG): $(PACKAGE)
-	-rm -rf mmg3d4
-	if tar tfz $(PACKAGE)  mmg3d4/build/sources/mmg3d.c 2>/dev/null  1>/dev/null  ;\
-	 then  rm $(PACKAGE);   $(MAKe) $(PACKAGE); fi	
-	tar xvzf $(PACKAGE)
-	touch mmg3d4/build/sources/dataff.h 	
-	cp mmg3d4/build/sources/swapar.c mmg3d4/build/sources/swapar.c.origne
-	tr -d '\r' <mmg3d4/build/sources/swapar.c.origne >mmg3d4/build/sources/swapar.c
-	cd mmg3d4;patch -p1 <../patch-mmg3dv4.diff
-	cat </dev/null >mmg3d4/build/sources/mmg3dConfig.h
-	touch tag-tar-$(SIZEPKG)
-#	cp makefile-mmg3d.inc $(SRCDIR)/makefile
-
-clean-local:
-	-rm ff-flags ../lib/WHERE.mmg3d
-	-rm -rf ../lib/libmmg3d*.a  ../lib/libmmg3d-v4.a
-	-rm -rf ../include/mmg3d-v4
-	-rm -r $(SRCDIR)
-	-rm FAIT* mmg* flags-* build-4 tag-tar*
-
-clean:clean-local 
-
-
-ff-flags: ../Makefile Makefile
-	grep 'abs_top_builddir *=' ../Makefile > ff-flags
-	grep 'CC *=' ../Makefile >> ff-flags
-	grep 'CFLAGS *=' ../Makefile >> ff-flags
-	grep 'LDFLAGS *=' ../Makefile >> ff-flags
-	grep 'AR *=' ../Makefile >> ff-flags
-	grep 'ARFLAGS *=' ../Makefile >> ff-flags
-	grep 'RANLIB *=' ../Makefile >> ff-flags
-	grep 'WGET *=' ../Makefile >> ff-flags
-	grep 'STD_LIBS *=' ../Makefile >> ff-flags
-	grep 'CNOFLAGS *=' ../Makefile >> ff-flags
+# Downloading and compiling extra libraries
+# -----------------------------------------
+
+# $Id$
+all-local: mmg3d
+
+include ff-flags
+
+# Downloading and compiling mmg3d
+# -------------------------------
+# 
+DIRPKG= ../pkg
+SRCDIR= ./mmg3d4
+PACKAGE=$(DIRPKG)/mmg3d4.0.tgz
+INSTALL=..
+mmg3d_VERSION=
+# mmg3d pas sur internet
+LIBMMG3D=$(INSTALL)/lib/libmmg3d-v4.a
+OPT=4
+# size of the PKG file ( this file change See Cecile.) FFCS - 19/2/13 - the test for the file size (`stat -f "%z" file`)
+# is not portable from MacOS, so just leave it out in FFCS (SIZEPKG is still useful to force a remake when the package
+# changes)
+SIZEPKG=158547
+
+OBJS= analar.o	chkmsh.o	hash.o		memory.o	optcte.o	outqua.o	simu44.o	swap44.o	zaldy.o \
+analarcutting.o	chrono.o	heap.o		mmg3d1.o	optlap.o	pattern.o	simu56.o	swap56.o \
+baryct.o	colpoi.o	inout.o		mmg3d4.o	optlen.o	quality.o	simu68.o	swap68.o \
+boulep.o	coquil.o	length.o	mmg3d9.o	optlentet.o	queue.o		simu710.o	swap710.o \
+bucket.o	cutelt.o	librnbg.o	movevertex.o	optra4.o	ratio.o		solmap.o	swapar.o \
+		delaunay.o	locate.o	optbdry.o	opttet.o	scalem.o	spledg.o	swaptet.o \
+cenrad.o	eigenv.o	matrix.o	optcoq.o	opttyp.o	simu23.o	swap23.o	typelt.o 
+
+OBJSNOP =  cendel.o swapar.o
+
+# FFCS - simplify Makefile structure
+mmg3d:WHERE.done
+
+mmg3d4/FAIT-4.done:tag-tar-$(SIZEPKG)
+	cd mmg3d4/build/sources/; $(MAKE) CC='$(CC)' CFLAGS='$(CNOFLAGS) -g'   $(OBJSNOP) 
+	cd mmg3d4/build/sources/; $(MAKE) CC='$(CC)' CFLAGS='$(CFLAGS) -g'   $(OBJS) 
+	cd mmg3d4/build/sources/mmg3dmain; $(CC) -c $(CFLAGS)   mmg3d.c -I..
+	$(AR) $(ARFLAGS) $(LIBMMG3D) mmg3d4/build/sources/*.o mmg3d4/build/sources/mmg3dmain/mmg3d.o
+#
+#	FFCS - ranlib required on Windows 7 64 bits
+#
+	$(RANLIB) $(LIBMMG3D)
+	-$(CC) $(CNOFLAGS) mmg3d4/build/sources/mmg3dmain/mmg3d.o   mmg3d4/build/sources/*.o -o ../bin/mmg3d $(STD_LIBS)
+	touch mmg3d4/FAIT-4.done
+
+# FFCS - simplify Makefile structure
+install-4.done:mmg3d4/FAIT-4.done
+	-mkdir ../include/mmg3d-v4/		
+	cp mmg3d4/build/sources/*.h ../include/mmg3d-v4/
+	touch $@
+clean::
+	-rm install-4.done
+
+mmg3d-4:$(PACKAGE)
+
+$(PACKAGE):
+	-mkdir $(DIRPKG);
+# 	FFCS - 6/11/12 - curl/MacOS8 does not like redirections
+	cd $(DIRPKG);$(WGET) http://www.math.u-bordeaux1.fr/~cdobrzyn/logiciels/download/mmg3d4.0.tgz
+
+install:install-4.done WHERE.done
+
+# FFCS - keep simplest makefile structure for automatic recompilations
+WHERE.done: install-4.done
+	echo mmg3d-v4  LD -L at DIR@/lib -lmmg3d-v4  >../lib/WHERE.mmg3d ;
+	echo mmg3d-v4 INCLUDE -I at DIR@/include/mmg3d-v4>> ../lib/WHERE.mmg3d ;
+	echo build WHERE ./lib/WHERE.mmg3d ;
+	touch $@
+clean::
+	-rm WHERE.done
+
+FAIRE: mmg3d4/FAIT-4.done install-4.done
+
+# FFCS - keep it simple
+tag-tar-$(SIZEPKG): $(PACKAGE)
+	tar xvzf $(PACKAGE)
+	touch mmg3d4/build/sources/dataff.h 	
+#
+#	ALH - clean-up all CR/LF to make patching more successful
+#
+	../../build/cleancrlf mmg3d4
+#
+	cd mmg3d4;patch -p1 <../patch-mmg3dv4.diff
+	cat </dev/null >mmg3d4/build/sources/mmg3dConfig.h
+	touch tag-tar-$(SIZEPKG)
+#	cp makefile-mmg3d.inc $(SRCDIR)/makefile
+
+
+
+clean::
+	-rm ff-flags
+#
+#	FFCS - make sure that all directories are cleaned. Thisis especially important under Windows because there is no
+#	compilation dependencies control there (see
+#	[[file:c:/cygwin/home/alh/ffcs/dist/configure.ac::dependency_tracking]])
+#
+	-rm -r mmg3d4
+	-rm FAIT* mmg* flags-* tag-tar*
+	-rm $(PACKAGE)
+
+ff-flags: ../Makefile Makefile
+	grep 'abs_top_builddir *=' ../Makefile > ff-flags
+	grep 'CC *=' ../Makefile >> ff-flags
+	grep 'CFLAGS *=' ../Makefile >> ff-flags
+	grep 'LDFLAGS *=' ../Makefile >> ff-flags
+	grep 'AR *=' ../Makefile >> ff-flags
+	grep 'ARFLAGS *=' ../Makefile >> ff-flags
+	grep 'RANLIB *=' ../Makefile >> ff-flags
+	grep 'WGET *=' ../Makefile >> ff-flags
+	grep 'STD_LIBS *=' ../Makefile >> ff-flags
+	grep 'CNOFLAGS *=' ../Makefile >> ff-flags
 .PHONY:$(SRCDIR)/$(INSTALL)
\ No newline at end of file
diff --git a/download/mmg3d/patch-mmg3dv4.diff b/download/mmg3d/patch-mmg3dv4.diff
index 629be33..2741b42 100644
--- a/download/mmg3d/patch-mmg3dv4.diff
+++ b/download/mmg3d/patch-mmg3dv4.diff
@@ -1,4 +1,4 @@
-diff -r -u mmg3d4/build/sources/analarcutting.c mmg3d4-new/build/sources/analarcutting.c
+>diff -r -u mmg3d4/build/sources/analarcutting.c mmg3d4-new/build/sources/analarcutting.c
 --- mmg3d4/build/sources/analarcutting.c	2012-12-19 16:05:32.000000000 +0100
 +++ mmg3d4-new/build/sources/analarcutting.c	2013-01-18 16:33:45.000000000 +0100
 @@ -307,7 +307,7 @@
@@ -99,1625 +99,1536 @@ diff -r -u mmg3d4/build/sources/delaunay.c mmg3d4-new/build/sources/delaunay.c
    for (k=1; k<=lon; k++)
      if(tref!=mesh->tetra[list->tetra[k]/6].ref)
        printf("pbs coquil %d %d tet %d\n",tref,mesh->tetra[list->tetra[k]/6].ref,list->tetra[k]/6);
-diff -r -u mmg3d4/build/sources/inout.c mmg3d4-new/build/sources/inout.c
---- mmg3d4/build/sources/inout.c	2012-12-19 16:05:32.000000000 +0100
-+++ mmg3d4-new/build/sources/inout.c	2013-01-18 16:56:05.000000000 +0100
-@@ -44,6 +44,7 @@
- along with MMG3D. If not, see <http://www.gnu.org/licenses/>.
+diff -r -u mmg3d4/build/sources/libmmg3d.h mmg3d4-new/build/sources/libmmg3d.h
+--- mmg3d4/build/sources/libmmg3d.h	2012-12-19 16:05:36.000000000 +0100
++++ mmg3d4-new/build/sources/libmmg3d.h	2013-01-18 16:32:41.000000000 +0100
+@@ -118,12 +118,12 @@
+ typedef MMG_Sol * MMG_pSol;
+ 
+ /* inout */
+-int  MMG_loadMesh(MMG_pMesh ,char *);
+-int  MMG_loadSol(MMG_pSol ,char *,int );
+-int  MMG_loadVect(MMG_pMesh ,char *,int );
+-int  MMG_saveMesh(MMG_pMesh ,char *);
+-int  MMG_saveSol(MMG_pMesh ,MMG_pSol ,char *);
+-int  MMG_saveVect(MMG_pMesh ,char *);
++int  MMG_loadMesh(MMG_pMesh ,char *,void *);
++int  MMG_loadSol(MMG_pSol ,char *,int ,void *);
++int  MMG_loadVect(MMG_pMesh ,char *,int ,void *);
++int  MMG_saveMesh(MMG_pMesh ,char *,void *);
++int  MMG_saveSol(MMG_pMesh ,MMG_pSol ,char *,void *);
++int  MMG_saveVect(MMG_pMesh ,char *,void *);
+ 
+ #ifdef  __cplusplus
+ namespace mmg3d{
+diff -r -u mmg3d4/build/sources/mesh.h mmg3d4-new/build/sources/mesh.h
+--- mmg3d4/build/sources/mesh.h	2012-12-19 16:05:36.000000000 +0100
++++ mmg3d4-new/build/sources/mesh.h	2013-01-18 16:32:41.000000000 +0100
+@@ -405,17 +405,17 @@
+ 
+ /* function pointers */
+ typedef int (*MMG_Swap)(pMesh ,pSol ,pList );
+-MMG_Swap MMG_swpptr;
+-double (*MMG_length)(double *,double *,double *,double *);
+-double (*MMG_caltet)(pMesh ,pSol ,int );
+-double (*MMG_calte1)(pMesh ,pSol ,int );
+-int    (*MMG_caltet2)(pMesh ,pSol ,int ,int ,double ,double *);
+-int    (*MMG_cavity)(pMesh ,pSol ,int ,int ,pList ,int );
+-int    (*MMG_buckin)(pMesh ,pSol ,pBucket ,int );
+-int    (*MMG_optlen)(pMesh ,pSol ,double ,int );
+-int    (*MMG_interp)(double *,double *,double *,double );
+-int    (*MMG_optlentet)(pMesh ,pSol ,pQueue ,double ,int ,int );
+-int    (*MMG_movevertex)(pMesh ,pSol ,int ,int );
++extern MMG_Swap MMG_swpptr;
++extern double (*MMG_length)(double *,double *,double *,double *);
++extern double (*MMG_caltet)(pMesh ,pSol ,int );
++extern double (*MMG_calte1)(pMesh ,pSol ,int );
++extern int    (*MMG_caltet2)(pMesh ,pSol ,int ,int ,double ,double *);
++extern int    (*MMG_cavity)(pMesh ,pSol ,int ,int ,pList ,int );
++extern int    (*MMG_buckin)(pMesh ,pSol ,pBucket ,int );
++extern int    (*MMG_optlen)(pMesh ,pSol ,double ,int );
++extern int    (*MMG_interp)(double *,double *,double *,double );
++extern int    (*MMG_optlentet)(pMesh ,pSol ,pQueue ,double ,int ,int );
++extern int    (*MMG_movevertex)(pMesh ,pSol ,int ,int );
+ 
+ 
+ #endif
+diff -r -u mmg3d4/build/sources/mmg3d4.c mmg3d4-new/build/sources/mmg3d4.c
+--- mmg3d4/build/sources/mmg3d4.c	2012-12-19 16:05:33.000000000 +0100
++++ mmg3d4-new/build/sources/mmg3d4.c	2013-01-18 18:28:05.000000000 +0100
+@@ -3,32 +3,32 @@
+ Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+ Propriétaires :IPB - UPMC -INRIA.
+ 
+-Copyright © 2004-2005-2006-2007-2008-2009-2010-2011,
++Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
+ diffusé sous les termes et conditions de la licence publique générale de GNU
+-Version 3 ou toute version ultérieure.
++Version 3 ou toute version ultérieure.  
+ 
+ Ce fichier est une partie de MMG3D.
+ MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+ suivant les termes de la licence publique générale de GNU
+ Version 3 ou toute version ultérieure.
+-MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS
+-AUCUNE GARANTIE ; sans même garantie de valeur marchande.
++MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
++AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
+ Voir la licence publique générale de GNU pour plus de détails.
+-MMG3D est diffusé en espérant qu’il sera utile,
+-mais SANS AUCUNE GARANTIE, ni explicite ni implicite,
+-y compris les garanties de commercialisation ou
+-d’adaptation dans un but spécifique.
++MMG3D est diffusé en espérant qu’il sera utile, 
++mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
++y compris les garanties de commercialisation ou 
++d’adaptation dans un but spécifique. 
+ Reportez-vous à la licence publique générale de GNU pour plus de détails.
+-Vous devez avoir reçu une copie de la licence publique générale de GNU
+-en même temps que ce document.
++Vous devez avoir reçu une copie de la licence publique générale de GNU 
++en même temps que ce document. 
+ Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+ /****************************************************************************
+ Initial software: MMG3D Version 4.0
+ Co-authors: Cecile Dobrzynski et Pascal Frey.
+ Owners: IPB - UPMC -INRIA.
+ 
+-Copyright © 2004-2005-2006-2007-2008-2009-2010-2011,
+-spread under the terms and conditions of the license GNU General Public License
++Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
++spread under the terms and conditions of the license GNU General Public License 
+ as published Version 3, or (at your option) any later version.
+ 
+ This file is part of MMG3D
+@@ -41,26 +41,26 @@
+ 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 MMG3D. If not, see <http://www.gnu.org/licenses/>.
++along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
  ****************************************************************************/
  #include "mesh.h"
-+#include "dataff.h"
  
+-int MMG_npuiss,MMG_nvol,MMG_npres;
+-int MMG_nlen,MMG_ncal,MMG_ntopo,MMG_nex;
+-int MMG_npuisstot,MMG_nvoltot,MMG_nprestot;
+-int MMG_npdtot;
+-int MMG_nplen,MMG_npref,MMG_bouffe;
++extern int MMG_npuiss,MMG_nvol,MMG_npres;
++extern int MMG_nlen,MMG_ncal,MMG_ntopo,MMG_nex;
++extern int MMG_npuisstot,MMG_nvoltot,MMG_nprestot;
++extern int MMG_npdtot;
++extern int MMG_nplen,MMG_npref,MMG_bouffe;
  
- extern short           MMG_imprim;
-@@ -100,35 +101,424 @@
-   return(out);
- }
+ int ddebug;
  
-+
-+int MMG_loadMeshff(pMesh mesh,char *filename,DataFF *dataff) {  
-+   
-+    
-+    Hedge    				 hed,hed2;
-+    pPoint       	   ppt;
-+    pTetra           pt;
-+    pTria            pt1;
-+    int i,j,k; 
-+    int nhex=0, npris=0, netmp=0,nq=0, pp[10] , ned=0, ncor=0;
-+    int p0,p1,p2,p3,p4,p5,p6,ref ;
-+    int data[10],ldata=10;
-+    dataff->get_mesh(dataff,data,10);
-+    mesh->np = data[ff_id_vertex];
-+    ned = data[ff_id_seg];
-+    mesh->nt = data[ff_id_tria];
-+    mesh->ne = data[ff_id_tet];
-+    netmp=mesh->ne;
-+    nhex=data[ff_id_hex];
-+    npris=data[ff_id_prism]; 
-+    nq=data[ff_id_quad];
-+    ncor= data[ff_id_corner];
-+
-+    if( nhex || npris) {
-+	printf("mmg3d ff interface , hex or prism NOT SUPPORTED  to day (sorry  FH) \n");
-+	goto L0; 
-+    }
-+    
-+    mesh->ncor = 0; 
-+    mesh->ver =1;
-+    if ( abs(mesh->info.option)==10 ) {
-+	fprintf(stdout,"  -- READING %8d HEXA %8d PRISMS\n",nhex,npris);  
-+	if(!mesh->ne) netmp = 0;  
-+	mesh->ne += 6*nhex + 3*npris; 
-+    }
-+    
-+    if ( abs(mesh->info.imprim) > 5 )
-+	fprintf(stdout,"  -- READING DATA for ff interface ");
-+    
-+    if ( !mesh->np || !mesh->ne ) {
-+	fprintf(stdout,"  ** MISSING DATA yy\n");
-+	goto L0; ;
-+    }
-+    if ( !MMG_zaldy(mesh) )  goto L0; 
-+    
-+    /* read mesh vertices */
-+    mesh->npfixe = mesh->np;
-+    
-+    for (k=1; k<=mesh->np; k++) {
-+	ppt = &mesh->point[k];
-+	dataff->get_v3(dataff,k,ppt->c,&ppt->ref);
-+	ppt->tag  = M_UNUSED;    
-+    }
-+    
-+    /* read mesh triangles */
-+    mesh->ntfixe = mesh->nt;
-+
-+    for (k=1; k<=mesh->nt; k++) {
-+	pt1 = &mesh->tria[k]; 
-+	dataff->get_elmt(dataff,ff_id_tria,k,pt1->v,&pt1->ref);
-+	 
-+	}  
+ int MMG_mmg3d4(pMesh mesh,pSol sol,int *alert) {
+   Hedge    hash;
+-  pBucket        bucket;
++  pBucket	 bucket; 
+   double   declic;
+-  int              base,na,nd,ns,nna,nnd,nns,dd,it,nf,maxtou;
+-  double   lmoy,LLLONG;
+-  int k;
+-  pTetra pt;
++  int		   base,na,nd,ns,nna,nnd,nns,dd,it,nf,maxtou; 
++  double   lmoy,LLLONG;                      
++	int k;
++	pTetra pt;
+   if ( abs(mesh->info.imprim) > 3 )
+     fprintf(stdout,"  ** SIZE OPTIMIZATION\n");
+   if ( mesh->info.imprim < 0 ) {
+@@ -73,82 +73,82 @@
+   maxtou = 10;
+   nna = nns = nnd = 0;
+   it  = 0;
+-  declic = 3. / ALPHAD;
++  declic = 3. / ALPHAD;  
+   lmoy = 10.;
+   LLLONG = 1.5;
+-
++  
+   nna = 10;
+-  do {
+-    na  = nd  = ns  = 0;
++  do { 
++    na  = nd  = ns  = 0; 
+     if(0) ddebug = 1;
+     else ddebug = 0;
+-
 +    
+     if(it && !(it%2) ) {
+       bucket = MMG_newBucket(mesh,M_MAX(mesh->info.bucksiz,BUCKSIZ));
+       if ( !bucket )  return(0);
+-      //MMG_saveMesh(mesh,"avtana.mesh");
+-      MMG_analar(mesh,sol,bucket,&na,&nd,&nf,alert);
+-      //MMG_saveMesh(mesh,"apresana.mesh");
+-      if ( abs(mesh->info.imprim) > 5 )
+-	fprintf(stdout,"     %7d INSERTED  %7d REMOVED   %7d FILTERED\n",na,nd,nf);
+-
+-      M_free(bucket->head);
+-      M_free(bucket->link);
+-      M_free(bucket);
+-
++			//MMG_saveMesh(mesh,"avtana.mesh",0);
++      MMG_analar(mesh,sol,bucket,&na,&nd,&nf,alert);      
++			//MMG_saveMesh(mesh,"apresana.mesh",0);
++      if ( abs(mesh->info.imprim) > 5 ) 
++        fprintf(stdout,"     %7d INSERTED  %7d REMOVED   %7d FILTERED\n",na,nd,nf);  
 +
-+
-+    /* read mesh quads (option 10)*/ 
-+    if(abs(mesh->info.option)==10) { 
-+	fprintf(stdout,"     QUADS READING %d\n",nq);
-+	mesh->ntfixe += 4*nq;
-+        for (k=1; k<=nq; k++) {
-+	    dataff->get_elmt(dataff, ff_id_quad ,k,pp,&ref);
-+	
-+	    pt1 = &mesh->tria[++mesh->nt]; 
-+	    pt1->v[0] = pp[0];
-+	    pt1->v[1] = pp[1];
-+	    pt1->v[2] = pp[2];
-+	    pt1->ref  = ref;
-+	    pt1 = &mesh->tria[++mesh->nt]; 
-+	    pt1->v[0] = pp[0];
-+	    pt1->v[1] = pp[2];
-+	    pt1->v[2] = pp[3];
-+	    pt1->ref  = ref;
-+	    pt1 = &mesh->tria[++mesh->nt]; 
-+	    pt1->v[0] = pp[0];
-+	    pt1->v[1] = pp[1];
-+	    pt1->v[2] = pp[3];
-+	    pt1->ref  = ref;
-+	    pt1 = &mesh->tria[++mesh->nt]; 
-+	    pt1->v[0] = pp[1];
-+	    pt1->v[1] = pp[2];
-+	    pt1->v[2] = pp[3];
-+	    pt1->ref  = ref;
-+	    
-+	}
-+    }
-+    
-+    /*read and store edges*/
-+    if (ned) {         
-+	if ( !MMG_zaldy4(&hed,ned) ) {
-+	    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES IGNORED\n"); 
-+	    ned = 0;
-+	}   
-+	mesh->ned = ned;
-+	
-+	for (k=1; k<=ned; k++) { 
-+	   dataff->get_elmt(dataff, ff_id_seg ,k,pp,&ref);
-+	   
-+	    if(MMG_edgePut(&hed,pp[0],pp[1],2)>1) {
-+		fprintf(stdout,"  ## WARNING DOUBLE EDGE : %d %d\n",pp[0],pp[1]);
-+	    }
-+	}
-+    }
++	    M_free(bucket->head);
++	    M_free(bucket->link);
++	    M_free(bucket);
++        
+     } else {
+-      ++mesh->flag;
++        ++mesh->flag;
+     }
+-    //printf("IT %d $$$$$$$$$$$ LLLONG  %9.3f\n",it,LLLONG);
+-    nna = nns = nnd = 0;
+-
++    //printf("IT %d $$$$$$$$$$$ LLLONG  %9.3f\n",it,LLLONG); 
++    nna = nns = nnd = 0; 
++      
+     /*splitting*/
+     if ( !mesh->info.noinsert && (!*alert)  ) {
+       /* store points on edges */
+       if ( !MMG_zaldy4(&hash,mesh->np) ) {
+-	if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM.\n");
+-	*alert = 2;
+-	break;
++        if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM.\n"); 
++        *alert = 2;
++        break;
+       }
+-      nna = MMG_analarcutting(mesh,sol,&hash,alert,&lmoy,LLLONG);
++      nna = MMG_analarcutting(mesh,sol,&hash,alert,&lmoy,LLLONG); 
+       if ( abs(mesh->info.imprim) > 5 ) { printf("lmoy %9.5f\n",lmoy); }
+       /*puts("--------------------------------------");
+-	puts("--------------------------------------");
+-	puts("--------------------------------------");
+-      */
++      puts("--------------------------------------");
++      puts("--------------------------------------");
++      */                             
+       if ( *alert ) {
+-	fprintf(stdout," \n\n ** UNABLE TO CUT (analarcutting)\n");
+-	fprintf(stdout," ** RETRY WITH -m > %6d \n\n",mesh->info.memory);
+-	MMG_saveMesh(mesh,"crash.mesh");
+-	MMG_saveSol(mesh,sol,"crash.sol");
+-	exit(0);
++        fprintf(stdout," \n\n ** UNABLE TO CUT (analarcutting)\n");
++        fprintf(stdout," ** RETRY WITH -m > %6d \n\n",mesh->info.memory);
++        MMG_saveMesh(mesh,"crash.mesh",0);
++        MMG_saveSol(mesh,sol,"crash.sol",0); 
++        exit(0);
+       }
+-      M_free(hash.item);
++      M_free(hash.item);        
+     }
+-    else if ( *alert )  nna = 0;
+-    /* adjacencies */
++    else if ( *alert )  nna = 0;  
++    /* adjacencies */ 
+     if ( nna /*|| it == (maxtou-1)*/ ) {
+       mesh->nt = 0;
+       if ( !MMG_hashTetra(mesh) )  return(0);
+       if ( !MMG_markBdry(mesh) )   return(0);
+     }
+-    // printf("chkmsh\n");
+-    // MMG_unscaleMesh(mesh,sol);
+-    //     MMG_saveMesh(mesh,"chk.mesh");
++    // printf("chkmsh\n");   
++		// MMG_unscaleMesh(mesh,sol);
++		//     MMG_saveMesh(mesh,"chk.mesh",0);
+     //MMG_chkmsh(mesh,1,-1);
+-    //if(it==1)exit(0);
+-    /* delaunization */
+-    if ( !mesh->info.noswap && (nna || na) ) {
++		//if(it==1)exit(0);		
++     /* delaunization */
++    if ( !mesh->info.noswap && (nna || na) ) {  
+       nns   =  MMG_cendel(mesh,sol,declic,base);
+     }
+ 
+     /* deletion */
+     /*if ( 0 && nna ) {
+       nnd   = MMG_colvert(mesh,sol,base);
+-      } */
++    } */
+     if ( nna+nnd+nns && abs(mesh->info.imprim) > 3 )
+       fprintf(stdout,"     %7d INSERTED  %7d REMOVED   %7d FLIPPED\n",nna+na,nnd+nd,nns);
+-
 +    
-+    /* read mesh tetrahedra */
-+    mesh->nefixe = mesh->ne;
-+ 
+   }
+   while ( na+nd+nns+nna+nnd > 0 && ++it < maxtou && lmoy > 1.3);
+ 
+@@ -161,80 +161,80 @@
+     MMG_prilen(mesh,sol);
+   }
+ 
+-  //return(1);
+-  //MMG_saveMesh(mesh,"aprescut.mesh");
+-  fprintf(stdout,"    ---\n");
+-
++	//return(1);
++	//MMG_saveMesh(mesh,"aprescut.mesh",0);
++	fprintf(stdout,"    ---\n");
 +  
-+    for (k=1; k<=netmp; k++) { 
-+	pt = &mesh->tetra[k];
-+	dataff->get_elmt(dataff,ff_id_tet,k,pt->v,&ref);
-+	pt->ref  = ref;//0;//ref ;  
-+	for(i=0 ; i<4 ; i++)
-+	    pt->bdryref[i] = -1;  
-+	
-+	if (ned) { int nu1,nu2;
-+	    for(i=0 ; i<6 ; i++) {                         
-+		nu1 = pt->v[MMG_iare[i][0]];
-+		nu2 = pt->v[MMG_iare[i][1]];
-+		pt->bdryinfo[i] = MMG_edgePoint(&hed,nu1,nu2);
-+	    }  			
-+	    
-+	} else {
-+	    for(i=0 ; i<6 ; i++)
-+		pt->bdryinfo[i] = 0;  			
-+	}
+   /*analyze standard*/
+-  base   = mesh->flag;
+-  *alert = 0;
++    base   = mesh->flag;
++    *alert = 0;
+ 
+-  nna = 0;
+-  nnd = 0;
+-  nf  = 0;
+-  it  = 0;
+-  maxtou = 100;
+-  MMG_npdtot=0;
+-  MMG_npuisstot=0;
+-  MMG_nprestot=0;
+-  MMG_nvoltot=0;
+-
+-  /* 2. field points */
+-  if ( mesh->info.imprim < -4 ) {
+-    MMG_prilen(mesh,sol);
+-    fprintf(stdout,"  -- FIELD POINTS\n");
+-  }
+-
+-  /* create filter */
+-  bucket = MMG_newBucket(mesh,M_MAX(mesh->info.bucksiz,BUCKSIZ));
+-  if ( !bucket )  return(0);
+-
+-  do {
+-    MMG_analar(mesh,sol,bucket,&na,&nd,&nf,alert);
+-    nna += na;
+-    nnd += nd;
+-    if ( *alert ) {
+-      if ( nd < 1000 )  break;
+-      else  *alert = 0;
+-    }
+-    if ( it > 5 ) {
+-      dd = abs(nd-na);
+-      if ( dd < 5 || dd < 0.05*nd )   break;
+-      else if ( it > 12 && nd >= na )  break;
+-    }
+-    if ( na+nd && abs(mesh->info.imprim) > 3 )
+-      fprintf(stdout,"     %7d INSERTED  %7d REMOVED   %7d FILTERED\n",na,nd,nf);
+-    // MMG_saveMesh(mesh,"chk.mesh");
+-    // //if(it==1) exit(0);
+-  }
+-  while ( na+nd > 0 && ++it < maxtou );
+-
+-  if ( nna+nnd && abs(mesh->info.imprim) < 3 ) {
+-    fprintf(stdout,"     %7d INSERTED  %7d REMOVED  %7d FILTERED\n",na,nd,nf);
+-  }
+-
+-  if(MMG_npdtot>0) {
+-    fprintf(stdout,"    REJECTED : %5d\n",MMG_npdtot);
+-    fprintf(stdout,"          VOL      : %6.2f %%    %5d \n",
+-	    100*(MMG_nvoltot/(float)
+-		 MMG_npdtot),MMG_nvoltot);
+-    fprintf(stdout,"          PUISS    : %6.2f %%    %5d \n",
+-	    100*(MMG_npuisstot/(float) MMG_npdtot),MMG_npuisstot);
+-    fprintf(stdout,"         PROCHE    : %6.2f %%    %5d \n",
+-	    100*(MMG_nprestot/(float) MMG_npuisstot),MMG_nprestot);
++    nna = 0;
++    nnd = 0;
++    nf  = 0;
++    it  = 0;
++    maxtou = 100;
+     MMG_npdtot=0;
+     MMG_npuisstot=0;
++    MMG_nprestot=0;
+     MMG_nvoltot=0;
+-  }
+-  if ( mesh->info.imprim < 0 ) {
+-    MMG_outqua(mesh,sol);
+-    MMG_prilen(mesh,sol);
+-  }
+ 
+-  M_free(bucket->head);
+-  M_free(bucket->link);
+-  M_free(bucket);
++    /* 2. field points */
++    if ( mesh->info.imprim < -4 ) {
++      MMG_prilen(mesh,sol);
++      fprintf(stdout,"  -- FIELD POINTS\n");
 +    }
-+    if (ned) M_free(hed.item); 
-+    
-+    /*read corners*/ 
-+    if (ncor) {
-+	
-+	mesh->ncor = ncor;
-+	for (k=1; k<=ncor; k++) { 
-+	    dataff->get_elmt(dataff,ff_id_corner,k,&ref,0);
 +
-+	    ppt = &mesh->point[ref];
-+	    ppt->geom = M_CORNER; 
-+	} 
-+    }
-+#ifdef XXXXXXXXXXXXXXX
-+    if ( abs(mesh->info.option)==10 ) { 
-+	if(bin) {
-+	    printf("NOT SUPPORTED\n");
-+	    exit(0);
-+	} 
-+	if ( !MMG_zaldy4(&hed2,3*npris+6*nhex) ) {
-+	    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : PRISM IGNORED\n"); 
-+	    npris = 0;
-+	    nhex  = 0;
-+	}   
-+	
-+	/*read hexa and transform to tetra*/
-+	rewind(inm);
-+	fseek(inm,posnhex,SEEK_SET);
-+	for (k=1; k<=nhex; k++) {   
-+	    fscanf(inm,"%d %d %d %d %d %d %d %d %d",&p0,&p1,&p2,&p3,&p4,&p5,&p6,&p7,&ref); 
-+	    //fscanf(inm,"%d %d %d %d %d %d %d %d %d",&p0,&p4,&p2,&p1,&p3,&p5,&p6,&p7,&ref); 
-+	    //printf("hex %d : %d %d %d %d %d %d %d %d\n",k,p0,p1,p2,p3,p4,p5,p6,p7);   
-+	    MMG_cuthex(mesh,&hed2,netmp+(k-1)*6,p0,p1,p2,p3,p4,p5,p6,p7,ref);
-+	}  
-+	
-+	/*read prism and transform to tetra
-+	 ---> compatibility pbs ==> hash edge and switch case*/  
-+	rewind(inm);
-+	fseek(inm,posnpris,SEEK_SET); 
-+	nimp = 0; 
-+	ne = netmp+6*nhex;
-+	for (k=1; k<=npris; k++) {
-+	    fscanf(inm,"%d %d %d %d %d %d %d",&p0,&p1,&p2,&p3,&p4,&p5,&ref); 
-+	    if(!MMG_cutprism(mesh,&hed2,ne,p0,p1,p2,p3,p4,p5,ref))
-+	      {
-+		if(mesh->info.imprim < 0 ) fprintf(stdout,"DECOMPOSITION PRISM INVALID \n\n"); 
-+		mesh->ne += 5;
-+		ne += 8;
-+		nimp++; 
-+		continue;
-+	      }
-+	    ne += 3;
-+	}
-+	if(abs(mesh->info.imprim) > 3 )fprintf(stdout,"     %d INVALID DECOMPOSITION\n\n",nimp);
-+    }
-+#endif    
-+    if ( abs(mesh->info.imprim) > 3 ) {
-+	fprintf(stdout,"     NUMBER OF GIVEN VERTICES   %8d\n",mesh->npfixe);
-+	if ( mesh->ntfixe )
-+	    fprintf(stdout,"     NUMBER OF GIVEN TRIANGLES  %8d\n",mesh->ntfixe);
-+	fprintf(stdout,"     NUMBER OF GIVEN TETRAHEDRA %8d\n",mesh->nefixe);
-+	if ( ncor )
-+	    fprintf(stdout,"     NUMBER OF GIVEN CORNERS    %8d\n",ncor);
-+	if ( ned )
-+	    fprintf(stdout,"     NUMBER OF GIVEN EDGES      %8d\n",ned);
-+    }
-+    //    MMG_saveMesh(mesh,"XXXXX.mesh",0);
-+   dataff->mesh=0; // used 
-+    return 1; 
-+L0: 
-+    dataff->mesh=0;// used 
-+    return 1; 
-+}
-+
-+int MMG_loadSolff(pSol sol,char *filename,int npmax,DataFF *dataff) { 
-+   
-+     double     tmp , *dsol ;       
-+    int         binch,bdim,iswp;
-+    int         k,i,isol,type,bin,dim,btyp,bpos;
-+    long        posnp;
-+    char        *ptr,data[128],chaine[128];
-+    if( ! dataff->sol){
-+	fprintf(stdout,"  ** MISSING DATA metrix ff \n");
-+	return(1);
-+    }
-+    dsol = dataff->sol;
-+    dataff->sol=0;// used 
-+    
++    /* create filter */
++    bucket = MMG_newBucket(mesh,M_MAX(mesh->info.bucksiz,BUCKSIZ));
++    if ( !bucket )  return(0);
 +
-+    btyp = (dataff->typesol== 6)  ?  3: dataff->typesol ;
-+    sol->np= dataff->np;
-+    
-+    if ( !sol->np ) {
-+	fprintf(stdout,"  ** MISSING DATA zz\n");
-+	return(1);
-+    }
-+    
-+    if ( btyp!= 1 && btyp!=3 ) {
-+      fprintf(stdout,"  ** DATA IGNORED (ff) btyp=%d\n",btyp);
-+	sol->np = 0;
-+	return(1);
-+    }
-+    
-+    sol->offset = (btyp==1) ? 1 : 6;
-+    
-+    if ( abs(MMG_imprim) > 5 )
-+	fprintf(stdout,"  -- READING DATA FILE(ff) %s\n",data);
-+    
-+    if ( !sol->np ) {
-+	fprintf(stdout,"  ** MISSING DATA  no metrix  \n");
-+	return(0);
++    do {
++      MMG_analar(mesh,sol,bucket,&na,&nd,&nf,alert);    
++      nna += na;
++      nnd += nd;
++      if ( *alert ) {
++        if ( nd < 1000 )  break;
++        else  *alert = 0;
++      }
++      if ( it > 5 ) {
++        dd = abs(nd-na);
++        if ( dd < 5 || dd < 0.05*nd )   break;
++        else if ( it > 12 && nd >= na )  break;
++      }
++      if ( na+nd && abs(mesh->info.imprim) > 3 )
++        fprintf(stdout,"     %7d INSERTED  %7d REMOVED   %7d FILTERED\n",na,nd,nf);    
++			// MMG_saveMesh(mesh,"chk.mesh",0);
++			// //if(it==1) exit(0);
 +    }
-+    sol->npfixe = sol->np;
-+    sol->npmax  = npmax;
-+    if ( !MMG_zaldy3(sol) )  return(0);
-+    
-+    /* read mesh solutions */
-+    sol->npfixe = sol->np;
-+ 
-+    for (k=1; k<=sol->np; k++) {
-+	isol = (k-1) * sol->offset + 1;
-+	    for (i=0; i<sol->offset; i++) 		     
-+		    sol->met[isol + i] = *dsol++;
++    while ( na+nd > 0 && ++it < maxtou );
 +
++    if ( nna+nnd && abs(mesh->info.imprim) < 3 ) {
++      fprintf(stdout,"     %7d INSERTED  %7d REMOVED  %7d FILTERED\n",na,nd,nf);
 +    }
-+    
-+    if ( abs(MMG_imprim) > 3 )
-+	fprintf(stdout,"     NUMBER OF GIVEN DATA       %8d\n",sol->npfixe);
-+    
-+ 
-+    return(1);  
 +
-+}
-+/* load solution (metric) */
-+int MMG_loadVectff(pMesh mesh,char *filename,int npmax,DataFF *dataff) {
-+  
-+      
-+    pDispl       pd;
-+    int         binch,bdim,iswp;
-+    int         k,i,type,bin,dim,btyp,bpos,iadr;
-+    long        posnp;
-+    char        *ptr,data[128],chaine[128];
-+    double *fsol = dataff->mov;
-+    dataff->mov=0;// used 
-+    
-+    pd = mesh->disp;
-+    pd->np =mesh->np ;
-+ 
-+       if ( !pd->np || !fsol  ) {
-+	 fprintf(stdout,"  ** MISSING DATA dep ff %d %p\n",pd->np, fsol);
-+	return(0);
++  if(MMG_npdtot>0) { 
++  fprintf(stdout,"    REJECTED : %5d\n",MMG_npdtot);
++  fprintf(stdout,"          VOL      : %6.2f %%    %5d \n",
++  	100*(MMG_nvoltot/(float)
++  MMG_npdtot),MMG_nvoltot); 
++  fprintf(stdout,"          PUISS    : %6.2f %%    %5d \n",
++  	100*(MMG_npuisstot/(float) MMG_npdtot),MMG_npuisstot);
++  fprintf(stdout,"         PROCHE    : %6.2f %%    %5d \n",
++  	100*(MMG_nprestot/(float) MMG_npuisstot),MMG_nprestot);	
++  MMG_npdtot=0;
++  MMG_npuisstot=0;
++  MMG_nvoltot=0;  
++  } 
++    if ( mesh->info.imprim < 0 ) {
++      MMG_outqua(mesh,sol);
++      MMG_prilen(mesh,sol);
 +    }
-+   
-+    
-+    if ( abs(mesh->info.imprim) > 5 )
-+	fprintf(stdout,"  -- COPY DATA form ff interface  %s\n",data);
-+    
-+    /* read mesh solutions */
-+    for (k=1; k<=pd->np; k++) {
-+	iadr = (k - 1) * 3 + 1;
-+	
-+	    for (i=0; i<3; i++) {
-+		    pd->mv[iadr + i] =  *fsol++;
-+		}
-+	    } 
-+           
-+    
-+    
-+    if ( abs(mesh->info.imprim) > 3 )
-+	fprintf(stdout,"     NUMBER OF GIVEN DATA       %8d\n",pd->np);
-+       return(1);
+ 
++    M_free(bucket->head);
++    M_free(bucket->link);
++    M_free(bucket);
 +  
-+    
-+}
-+int MMG_saveMeshff(pMesh mesh,char *filename,DataFF *dataff) {  
-+    
-+    pPoint       	   ppt;
-+    pTetra           pt;
-+    pTria            pt1;
-+    int j,k,np,nc,k0;
-+    int data[10],ldata=10;
-+    int kn[10];
-+    np = 0; 
-+    nc = 0;
-+    for (k=1; k<=mesh->np; k++) {
-+      ppt = &mesh->point[k];
-+      if ( ppt->tag & M_UNUSED )  continue;  
-+      ppt->tmp = ++np;  
-+      /*      if ( ppt->geom & M_CORNER )  cor[nc++] = ppt->tmp; */
-+    } 
-+    mesh->nt=0;
-+    if(! MMG_markBdry(mesh)) 
-+      mesh->nt=0;
-+    data[ff_id_vertex]=np ;
-+    //data[ff_id_seg]=ned ;
-+    data[ff_id_tria]=mesh->nt ;
-+    int ne=0;
-+    for ( k=1; k<=mesh->ne; k++) 
-+      {
-+	pt = &mesh->tetra[k];
-+	if ( !pt->v[0] )  continue;  
-+	ne++; 
-+      }
-+    
-+    data[ff_id_tet]=ne  ;
-+    //data[ff_id_hex]=nhex;
-+    //data[ff_id_prism]=npris; 
-+    //data[ff_id_quad]=nq;
-+    // data[ff_id_corner]=ncor;
-+    
-+    dataff->set_mesh(dataff,data,10);
-+    
-+    
-+    for ( k=1; k<=mesh->np; k++) 
-+      {
-+	ppt = &mesh->point[k];
-+	if ( ppt->tag & M_UNUSED )  continue;  
-+	dataff->set_v(dataff, ppt->tmp,ppt->c,ppt->ref);	    
-+      }
-+    
-+    
-+    for (k=1; k<=mesh->nt; k++) 
-+      {
-+	pt1 = &mesh->tria[k];
-+	for(j=0;j<3;++j)
-+	  kn[j] = mesh->point[pt1->v[j]].tmp;
-+	dataff->set_elmt(dataff,ff_id_tria,k,kn,pt1->ref);
-+	
-+      }  
-+    k0=0;
-+    for ( k=1; k<=mesh->ne; k++) 
-+      {
-+	
-+	pt = &mesh->tetra[k];
-+	if ( !pt->v[0] )  continue;  
-+	k0++;
-+	for(j=0;j<4;++j)
-+	  kn[j] = mesh->point[pt->v[j]].tmp;
-+	dataff->set_elmt(dataff,ff_id_tet,k0,kn,pt->ref);
-+	
-+    }  
-+    dataff->end_mesh(dataff);
-+    return 1; 
-+}
-+int MMG_saveSolff (pMesh mesh,pSol sol,char *filename,DataFF *dataff) {
-+  return 1; 
-+}
-+/*save the node speed : coornew-coorold/dt*/
-+int MMG_saveVectff(pMesh mesh,char *filename,DataFF *dataff) {
-+   return 1; 
-+}
- /* read mesh data */
--int MMG_loadMesh(pMesh mesh,char *filename) {
-+int MMG_loadMesh(pMesh mesh,char *filename,void *dataff) {  
-   FILE*            inm;
-   Hedge            hed,hed2;
-   pPoint           ppt;
-   pTetra           pt;
-   pHexa            ph,listhexa;
-   pTria            pt1;
--  int              k,dim,ref,bin,bpos,i,tmp;
--  int              *adjahex;
-+  int              k,dim,ref,bin,bpos,i,tmp;  
-+  int              *adjahex; 
-   long             posnp,posnt,posne,posnhex,posnpris,posncor,posned,posnq;
-   char            *ptr,data[128],chaine[128];
-   int              nhex,npris,netmp,ncor,ned,nq;
--  int              p0,p1,p2,p3,p4,p5,p6,p7;
--  int              binch,bdim,iswp,nu1,nu2,nimp,ne,nbado;
--  float            fc;
--  double           volhex,volref;
-+  int              p0,p1,p2,p3,p4,p5,p6,p7;  
-+  int              binch,bdim,iswp,nu1,nu2,nimp,ne,nbado;       
-+  float            fc; 
-+  double           volhex,volref;  
-   int              iadr,reorient;
+ 
+   return(1);
+ }
+diff -r -u mmg3d4/build/sources/mmg3dConfig.h mmg3d4-new/build/sources/mmg3dConfig.h
+--- mmg3d4/build/sources/mmg3dConfig.h	2012-12-19 16:05:36.000000000 +0100
++++ mmg3d4-new/build/sources/mmg3dConfig.h	2013-01-18 16:32:41.000000000 +0100
+@@ -2,4 +2,4 @@
+ #define Tutorial_VERSION_MAJOR 
+ #define Tutorial_VERSION_MINOR 
+ 
+-#define USE_SCOTCH
++/* #undef USE_SCOTCH */
+diff -r -u mmg3d4/build/sources/mmg3dlib/mmg3dlib.c mmg3d4-new/build/sources/mmg3dlib/mmg3dlib.c
+--- mmg3d4/build/sources/mmg3dlib/mmg3dlib.c	2012-12-19 16:06:03.000000000 +0100
++++ mmg3d4-new/build/sources/mmg3dlib/mmg3dlib.c	2013-01-18 16:32:41.000000000 +0100
+@@ -385,7 +385,7 @@
+   if ( !MMG_hashTetra(mesh) )    return(1);
+   if ( !MMG_markBdry(mesh) )     return(1);
+   if (abs(mesh->info.option)==10) {
+-    MMG_saveMesh(mesh,"tetra.mesh");
++    MMG_saveMesh(mesh,"tetra.mesh",0);
+     return(0);
+   }           
+   if ( !sol->np) {
+@@ -431,7 +431,7 @@
+     if ( abs(info->option) == 9 ) {  
+       if(!MMG_mmg3d9(mesh,sol,&alert)) {
+         if ( !MMG_unscaleMesh(mesh,sol) )  return(1);
+-        MMG_saveMesh(mesh,"errormoving.mesh");
++        MMG_saveMesh(mesh,"errormoving.mesh",0);
+ 	      //MMG_saveSol(mesh,sol,mesh->outf);
+ 	      return(1);
+       }
+diff -r -u mmg3d4/build/sources/mmg3dmain/mmg3d.c mmg3d4-new/build/sources/mmg3dmain/mmg3d.c
+--- mmg3d4/build/sources/mmg3dmain/mmg3d.c	2012-12-19 16:05:53.000000000 +0100
++++ mmg3d4-new/build/sources/mmg3dmain/mmg3d.c	2013-01-18 21:44:08.000000000 +0100
+@@ -46,7 +46,7 @@
+ #include "compil.date"
+ #include "mesh.h"
+ #include "eigenv.h"
 -
-+  if(dataff)
-+    return MMG_loadMeshff( mesh,filename,(DataFF*) dataff);
-+  
++#include "dataff.h"
+ TIM_mytime         MMG_ctim[TIMEMAX];
+ short	             MMG_imprim;
+ 
+@@ -397,6 +397,7 @@
+ 	    100.*ttot/ttim[0],call[0],ttot/(float)call[0]);
+   }
+   fprintf(stdout,"\n   ELAPSED TIME  %.2f SEC.  (%.2f)\n",ttim[0],ttot);
++  fflush(stdout);
+ }
+ 
+ 
+@@ -433,8 +434,7 @@
+   return(1);
+ }
  
-   posnp = posnt = posne = posnhex = posnpris = 0;
-   netmp = ncor = ned = 0;
-   bin = 0;
-   iswp = 0;
--  mesh->np = mesh->nt = mesh->ne = mesh->ncor = 0;
-+  mesh->np = mesh->nt = mesh->ne = mesh->ncor = 0; 
-   npris = nhex = nq = 0;
 -
-+  
-   strcpy(data,filename);
--  ptr = strstr(data,".mesh");
-+  ptr = strstr(data,".mesh");  
-   if ( !ptr ) {
-     strcat(data,".meshb");
-     if( !(inm = fopen(data,"rb")) ) {
-@@ -136,8 +526,8 @@
-       *ptr = '\0';
-       strcat(data,".mesh");
-       if( !(inm = fopen(data,"r")) ) {
--	fprintf(stderr,"  ** %s  NOT FOUND.\n",data);
--	return(0);
-+        fprintf(stderr,"  ** %s  NOT FOUND.\n",data);
-+        return(0);
-       }
-     } else {
-       bin = 1;
-@@ -147,194 +537,194 @@
-     ptr = strstr(data,".meshb");
-     if( !ptr ) {
-       if( !(inm = fopen(data,"r")) ) {
--	fprintf(stderr,"  ** %s  NOT FOUND.\n",data);
--	return(0);
--      }
-+        fprintf(stderr,"  ** %s  NOT FOUND.\n",data);
-+        return(0);
-+      }      
-     } else {
-       bin = 1;
-       if( !(inm = fopen(data,"rb")) ) {
--	fprintf(stderr,"  ** %s  NOT FOUND.\n",data);
--	return(0);
-+        fprintf(stderr,"  ** %s  NOT FOUND.\n",data);
-+        return(0);
-       }
+-int main(int argc,char *argv[]) {
++int mainmmg3d(int argc,char *argv[],DataFF *dataff) { 
+   pMesh      	mesh;
+   pSol       	sol;
+   Info     	*info;
+@@ -451,7 +451,7 @@
+   signal(SIGSEGV,excfun);
+   signal(SIGTERM,excfun);
+   signal(SIGINT,excfun);
+-  atexit(endcod);
++  if(dataff==0) atexit(endcod);
+ 
+   TIM_tminit(MMG_ctim,TIMEMAX);
+   TIM_chrono(ON,&MMG_ctim[0]);
+@@ -479,15 +479,27 @@
+   info->dt       = 1.;
+   info->bdry     = 0;
+   info->optles   = 0;
 -
--    }
-+      
-+    }  
++   /* modif F. Hecht ..*/
++   if(dataff)
++     {
++       mesh->name=dataff->meshname;
++       mesh->move=dataff->movename;
++       sol->name=dataff->solname;
++       /*      printf(" #### %p %p %p --- \n",mesh->name,mesh->move,sol->name); */
++       info->imprim=dataff->imprim;
++       info->memory=dataff->memory;
++     }
++   /* end modf */ 
+   if ( !parsar(argc,argv,mesh,sol) )  return(1);
+   MMG_imprim = info->imprim;
+   
+   /* load data */
+   if ( MMG_imprim )   fprintf(stdout,"\n  -- INPUT DATA\n");
+   TIM_chrono(ON,&MMG_ctim[1]);
+-  if ( !MMG_loadMesh(mesh,mesh->name) )  return(1); 
+-  if ( !MMG_loadSol(sol,sol->name,mesh->npmax) )  return(1);
++  /* modif FH. for interface with ff++ add dataff param     */
++  if ( !MMG_loadMesh(mesh,mesh->name,dataff) )  return(1); 
++  if ( !MMG_loadSol(sol,sol->name,mesh->npmax,dataff ) )  return(1);
++
+   if ( sol->np && sol->np != mesh->np ) {
+     fprintf(stdout,"  ## WARNING: WRONG SOLUTION NUMBER. IGNORED\n");
+     sol->np = 0;
+@@ -495,7 +507,7 @@
+ 
+   if ( !parsop(mesh) )  return(1);
+ 
+-  if ( abs(info->option) == 9 && !MMG_loadVect(mesh,mesh->move,mesh->np) )  return(0);
++  if ( abs(info->option) == 9 && !MMG_loadVect(mesh,mesh->move,mesh->np,dataff) )  return(0);
+ 
+   if ( !MMG_setfunc(sol->offset) ) return(1);
+   if ( !MMG_scaleMesh(mesh,sol) )  return(1);   
+@@ -527,7 +539,7 @@
+   if ( !MMG_hashTetra(mesh) )    return(1);
+   if ( !MMG_markBdry(mesh) )     return(1);
+   if (abs(mesh->info.option)==10) {
+-    MMG_saveMesh(mesh,"tetra.mesh");
++    MMG_saveMesh(mesh,"tetra.mesh",dataff);
+     return(0);
+   }           
+ 
+@@ -571,8 +583,8 @@
+     if ( abs(info->option) == 9 ) {
+       if(!MMG_mmg3d9(mesh,sol,&alert)) {
+         if ( !MMG_unscaleMesh(mesh,sol) )  return(1);
+-        MMG_saveMesh(mesh,mesh->outf);
+-	MMG_saveSol(mesh,sol,mesh->outf);
++        MMG_saveMesh(mesh,mesh->outf,dataff);
++	MMG_saveSol(mesh,sol,mesh->outf,dataff);
+ 	return(1);
+       }
+       /*puts("appel 1");
+@@ -678,18 +690,18 @@
+     fprintf(stdout,"\n  ## WARNING: INCOMPLETE MESH  %d , %d\n",
+             mesh->np,mesh->ne);
+ 
+-  if ( MMG_imprim )  fprintf(stdout,"\n  -- WRITING DATA FILE %s\n",mesh->outf);
++  if ( MMG_imprim && !dataff)  fprintf(stdout,"\n  -- WRITING DATA FILE %s\n",mesh->outf);
+   TIM_chrono(ON,&MMG_ctim[1]);
+   if ( !MMG_unscaleMesh(mesh,sol) )  return(1);
+-  MMG_saveMesh(mesh,mesh->outf);
++  MMG_saveMesh(mesh,mesh->outf,dataff);
+   if ( info->option == 9 ) {
+-    MMG_saveSol(mesh,sol,mesh->outf);
+-    MMG_saveVect(mesh,mesh->move);    
++    MMG_saveSol(mesh,sol,mesh->outf,dataff);
++    MMG_saveVect(mesh,mesh->move,dataff);    
    }
+   else
+-    MMG_saveSol(mesh,sol,mesh->outf);
++    MMG_saveSol(mesh,sol,mesh->outf,dataff);   
+   TIM_chrono(OFF,&MMG_ctim[1]);
+-  if ( MMG_imprim )  fprintf(stdout,"  -- WRITING COMPLETED\n");
++  if ( MMG_imprim && !dataff)  fprintf(stdout,"  -- WRITING COMPLETED\n");
  
-   fprintf(stdout,"  %%%% %s OPENED\n",data);
-   if (!bin) {
--    strcpy(chaine,"D");
--    while(fscanf(inm,"%s",&chaine[0])!=EOF && strncmp(chaine,"End",strlen("End")) ) {
-+    strcpy(chaine,"D");     
-+    while(fscanf(inm,"%s",&chaine[0])!=EOF && strncmp(chaine,"End",strlen("End")) ) { 
-       if(!strncmp(chaine,"MeshVersionFormatted",strlen("MeshVersionFormatted"))) {
--	fscanf(inm,"%d",&mesh->ver);
--	continue;
-+          fscanf(inm,"%d",&mesh->ver);
-+          continue;
-       } else if(!strncmp(chaine,"Dimension",strlen("Dimension"))) {
--	fscanf(inm,"%d",&dim);
--	if(dim!=3) {
--	  fprintf(stdout,"BAD DIMENSION : %d\n",dim);
--	  return(0);
--	}
--	continue;
-+          fscanf(inm,"%d",&dim);
-+          if(dim!=3) {
-+            fprintf(stdout,"BAD DIMENSION : %d\n",dim);
-+            return(0);
-+          }
-+          continue;
-       } else if(!strncmp(chaine,"Vertices",strlen("Vertices"))) {
--	fscanf(inm,"%d",&mesh->np);
--	posnp = ftell(inm);
--	continue;
-+        fscanf(inm,"%d",&mesh->np); 
-+        posnp = ftell(inm);
-+        continue;
-       } else if(!strncmp(chaine,"Triangles",strlen("Triangles"))) {
--	fscanf(inm,"%d",&mesh->nt);
--	posnt = ftell(inm);
--	continue;
-+        fscanf(inm,"%d",&mesh->nt); 
-+        posnt = ftell(inm);
-+        continue;
-       } else if(!strncmp(chaine,"Tetrahedra",strlen("Tetrahedra"))) {
--	fscanf(inm,"%d",&mesh->ne);
--	netmp = mesh->ne;
--	posne = ftell(inm);
--	continue;
--      } else if(!strncmp(chaine,"Hexahedra",strlen("Hexahedra"))) {
--	assert(abs(mesh->info.option)==10);
--	fscanf(inm,"%d",&nhex);
--	//nhex=0;
--	posnhex = ftell(inm);
--	continue;
--      } else if(!strncmp(chaine,"Pentahedra",strlen("Pentahedra"))) {
--	assert(abs(mesh->info.option)==10);
--	fscanf(inm,"%d",&npris);
--	//npris=0;
--	posnpris = ftell(inm);
--	continue;
--      } else if(!strncmp(chaine,"Corners",strlen("Corners"))) {
--	fscanf(inm,"%d",&ncor);
--	posncor = ftell(inm);
--	continue;
--      } else if(!strncmp(chaine,"Edges",strlen("Edges"))) {
--	fscanf(inm,"%d",&ned);
--	posned = ftell(inm);
--	continue;
--      } else if(abs(mesh->info.option)==10 && !strncmp(chaine,"Quadrilaterals",strlen("Quadrilaterals"))) {
--	fscanf(inm,"%d",&nq);
--	posnq = ftell(inm);
--	continue;
--      }
--    }
-+        fscanf(inm,"%d",&mesh->ne); 
-+        netmp = mesh->ne;
-+        posne = ftell(inm);
-+        continue;
-+      } else if(!strncmp(chaine,"Hexahedra",strlen("Hexahedra"))) { 
-+        assert(abs(mesh->info.option)==10);  
-+        fscanf(inm,"%d",&nhex); 
-+				//nhex=0;
-+        posnhex = ftell(inm);
-+        continue;
-+      } else if(!strncmp(chaine,"Pentahedra",strlen("Pentahedra"))) { 
-+        assert(abs(mesh->info.option)==10); 
-+        fscanf(inm,"%d",&npris);
-+				//npris=0;
-+        posnpris = ftell(inm);
-+        continue;
-+      } else if(!strncmp(chaine,"Corners",strlen("Corners"))) { 
-+        fscanf(inm,"%d",&ncor); 
-+        posncor = ftell(inm);
-+        continue;
-+      } else if(!strncmp(chaine,"Edges",strlen("Edges"))) { 
-+	      fscanf(inm,"%d",&ned); 
-+	      posned = ftell(inm);
-+	      continue;
-+	    } else if(abs(mesh->info.option)==10 && !strncmp(chaine,"Quadrilaterals",strlen("Quadrilaterals"))) {
-+		    fscanf(inm,"%d",&nq); 
-+		    posnq = ftell(inm);
-+		    continue;
-+		  }
-+    }  
-   } else {
-     bdim = 0;
-     fread(&mesh->ver,sw,1,inm);
--    iswp=0;
--    if(mesh->ver==16777216)
--      iswp=1;
-+    iswp=0;   
-+    if(mesh->ver==16777216) 
-+      iswp=1;    
-     else if(mesh->ver!=1) {
-       fprintf(stdout,"BAD FILE ENCODING\n");
--    }
--    fread(&mesh->ver,sw,1,inm);
--    if(iswp) mesh->ver = MMG_swapbin(mesh->ver);
--    while(fread(&binch,sw,1,inm)!=0 && binch!=54 ) {
--      if(iswp) binch=MMG_swapbin(binch);
--      if(binch==54) break;
-+    } 
-+    fread(&mesh->ver,sw,1,inm); 
-+    if(iswp) mesh->ver = MMG_swapbin(mesh->ver); 
-+    while(fread(&binch,sw,1,inm)!=0 && binch!=54 ) {  
-+      if(iswp) binch=MMG_swapbin(binch);      
-+      if(binch==54) break;  
-       if(!bdim && binch==3) {  //Dimension
--	fread(&bdim,sw,1,inm);  //NulPos=>20
--	if(iswp) bdim=MMG_swapbin(bdim);
--	fread(&bdim,sw,1,inm);
--	if(iswp) bdim=MMG_swapbin(bdim);
--	if(bdim!=3) {
--	  fprintf(stdout,"BAD SOL DIMENSION : %d\n",dim);
--	  exit(0);
--	  return(1);
--	}
--	continue;
-+        fread(&bdim,sw,1,inm);  //NulPos=>20
-+        if(iswp) bdim=MMG_swapbin(bdim);
-+        fread(&bdim,sw,1,inm);  
-+        if(iswp) bdim=MMG_swapbin(bdim);
-+        if(bdim!=3) {
-+          fprintf(stdout,"BAD SOL DIMENSION : %d\n",dim);
-+          exit(0);
-+          return(1);
-+        }
-+        continue;
-       } else if(!mesh->np && binch==4) {  //Vertices
--	fread(&bpos,sw,1,inm); //NulPos
--	if(iswp) bpos=MMG_swapbin(bpos);
--	fread(&mesh->np,sw,1,inm);
--	if(iswp) mesh->np=MMG_swapbin(mesh->np);
--	posnp = ftell(inm);
--	rewind(inm);
--	fseek(inm,bpos,SEEK_SET);
--	continue;
-+        fread(&bpos,sw,1,inm); //NulPos 
-+        if(iswp) bpos=MMG_swapbin(bpos);
-+        fread(&mesh->np,sw,1,inm); 
-+        if(iswp) mesh->np=MMG_swapbin(mesh->np);
-+        posnp = ftell(inm);     
-+        rewind(inm);
-+        fseek(inm,bpos,SEEK_SET);        
-+        continue;
-       }  else if(!mesh->nt && binch==6) {//Triangles
--	fread(&bpos,sw,1,inm); //NulPos
--	if(iswp) bpos=MMG_swapbin(bpos);
--	fread(&mesh->nt,sw,1,inm);
--	if(iswp) mesh->nt=MMG_swapbin(mesh->nt);
--	posnt = ftell(inm);
--	rewind(inm);
--	fseek(inm,bpos,SEEK_SET);
--	continue;
--      } else if(!mesh->ne && binch==8) {
--	fread(&bpos,sw,1,inm); //NulPos
--	if(iswp) bpos=MMG_swapbin(bpos);
--	fread(&mesh->ne,sw,1,inm);
--	if(iswp) mesh->ne=MMG_swapbin(mesh->ne);
--	netmp = mesh->ne;
--	posne = ftell(inm);
--	rewind(inm);
--	fseek(inm,bpos,SEEK_SET);
--	continue;
--      } else if(!nhex && binch==10) {
--	assert(abs(mesh->info.option)==10);
--	fread(&bpos,sw,1,inm); //NulPos
--	if(iswp) bpos=MMG_swapbin(bpos);
--	fread(&nhex,sw,1,inm);
--	if(iswp) nhex=MMG_swapbin(nhex);
--	posnhex = ftell(inm);
--	rewind(inm);
--	fseek(inm,bpos,SEEK_SET);
--	continue;
--      } else if(!npris && binch==9) {
--	assert(abs(mesh->info.option)==10);
--	fread(&bpos,sw,1,inm); //NulPos
--	if(iswp) bpos=MMG_swapbin(bpos);
--	fread(&npris,sw,1,inm);
--	if(iswp) npris=MMG_swapbin(npris);
--	posnpris = ftell(inm);
--	rewind(inm);
--	fseek(inm,bpos,SEEK_SET);
--	continue;
--      } else if(!ncor && binch==13) {
--	fread(&bpos,sw,1,inm); //NulPos
--	if(iswp) bpos=MMG_swapbin(bpos);
--	fread(&ncor,sw,1,inm);
--	if(iswp) ncor=MMG_swapbin(ncor);
--	posncor = ftell(inm);
--	rewind(inm);
--	fseek(inm,bpos,SEEK_SET);
--	continue;
--      } else if(!ned && binch==5) { //Edges
--	fread(&bpos,sw,1,inm); //NulPos
--	if(iswp) bpos=MMG_swapbin(bpos);
--	fread(&ned,sw,1,inm);
--	if(iswp) ned=MMG_swapbin(ned);
--	posned = ftell(inm);
--	rewind(inm);
--	fseek(inm,bpos,SEEK_SET);
--	continue;
--      } else {
--	//printf("on traite ? %d\n",binch);
--	fread(&bpos,sw,1,inm); //NulPos
--	if(iswp) bpos=MMG_swapbin(bpos);
--	//printf("on avance... Nulpos %d\n",bpos);
--	rewind(inm);
--	fseek(inm,bpos,SEEK_SET);
+   /* free mem */
+   M_free(mesh->point);
+@@ -706,5 +718,24 @@
+ 
+   if ( MMG_imprim < -4 || info->ddebug )  M_memDump();
+   M_free(mesh);
++  if(MMG_imprim && dataff ) endcod();
+   return(0);
+ }
++
++int main(int argc,char *argv[])  {
++    return  mainmmg3d( argc,argv,0);
++}
++/*
++ def 
++ */
++ MMG_Swap MMG_swpptr;
++ double (*MMG_length)(double *,double *,double *,double *);
++ double (*MMG_caltet)(pMesh ,pSol ,int );
++ double (*MMG_calte1)(pMesh ,pSol ,int );
++ int    (*MMG_caltet2)(pMesh ,pSol ,int ,int ,double ,double *);
++ int    (*MMG_cavity)(pMesh ,pSol ,int ,int ,pList ,int );
++ int    (*MMG_buckin)(pMesh ,pSol ,pBucket ,int );
++ int    (*MMG_optlen)(pMesh ,pSol ,double ,int );
++ int    (*MMG_interp)(double *,double *,double *,double );
++ int    (*MMG_optlentet)(pMesh ,pSol ,pQueue ,double ,int ,int );
++ int    (*MMG_movevertex)(pMesh ,pSol ,int ,int );
+diff -r -u mmg3d4/build/sources/optlen.c mmg3d4-new/build/sources/optlen.c
+--- mmg3d4/build/sources/optlen.c	2012-12-19 16:05:33.000000000 +0100
++++ mmg3d4-new/build/sources/optlen.c	2013-01-18 16:32:41.000000000 +0100
+@@ -48,7 +48,7 @@
+ #define  HQCOEF    0.9 
+ #define  HCRIT     0.98
+ 
+-double MMG_rao(pMesh mesh,int k,int inm);
++double MMG_rao(pMesh mesh,int k,FILE* );
+ int MMG_optlen_ani(pMesh mesh,pSol sol,double declic,int base) {
+   pTetra    pt,pt1;
+   pPoint    ppa,ppb;
+diff -r -u mmg3d4/build/sources/pattern.c mmg3d4-new/build/sources/pattern.c
+--- mmg3d4/build/sources/pattern.c	2012-12-19 16:05:33.000000000 +0100
++++ mmg3d4-new/build/sources/pattern.c	2013-01-18 18:41:02.000000000 +0100
+@@ -47,7 +47,7 @@
+ 
+ 
+ unsigned char MMG_arfa[3][4] = { {2,0,1,3}, {1,2,0,3}, {0,1,2,3} };
+-extern int MMG_permar[10][4];
++extern int MMG_permar[12][4];
+ extern int MMG_pointar[64][2];
+ extern int ddebug;
+ //insert ip on ia-ib
+diff -r -u mmg3d4/build/sources/quality.c mmg3d4-new/build/sources/quality.c
+--- mmg3d4/build/sources/quality.c	2012-12-19 16:05:33.000000000 +0100
++++ mmg3d4-new/build/sources/quality.c	2013-01-18 16:32:41.000000000 +0100
+@@ -46,7 +46,7 @@
+ #include "mesh.h"  
+ 
+ 
+-double MMG_rao(pMesh mesh,int k,int inm);
++double MMG_rao(pMesh mesh,int k,FILE* inm) ;
+ double MMG_caltetrao(pMesh mesh,pSol sol,int iel) {
+ 	return(MMG_rao(mesh,iel,0));
+ }
+diff -r -u mmg3d4/build/sources/ratio.c mmg3d4-new/build/sources/ratio.c
+--- mmg3d4/build/sources/ratio.c	2012-12-19 16:05:33.000000000 +0100
++++ mmg3d4-new/build/sources/ratio.c	2013-01-18 16:32:41.000000000 +0100
+@@ -365,7 +365,7 @@
+   fprintf(stdout,"           ELEMENT   %d (%d)   %d %d %d %d\n",
+ 	  iel,ielreal,pt->v[0],pt->v[1],pt->v[2],pt->v[3]);
+ 
+-  if ( abs(mesh->info.imprim) < 5 )  return;
++  if ( abs(mesh->info.imprim) < 5 )  return (1) ;
+ 
+   fprintf(stdout,"\n     HISTOGRAMM\n");
+   for (k=1; k<9; k++) {
+diff -r -u mmg3d4/build/sources/sproto.h mmg3d4-new/build/sources/sproto.h
+--- mmg3d4/build/sources/sproto.h	2012-12-19 16:05:36.000000000 +0100
++++ mmg3d4-new/build/sources/sproto.h	2013-01-18 16:32:41.000000000 +0100
+@@ -67,13 +67,13 @@
+ int  MMG_inEdge(pHedge ,int *,int *,int *);
+ int  MMG_markBdry(pMesh );
+ 
+-/* inout */
+-int  MMG_loadMesh(pMesh ,char *);
+-int  MMG_loadSol(pSol ,char *,int );
+-int  MMG_loadVect(pMesh ,char *,int );
+-int  MMG_saveMesh(pMesh ,char *);
+-int  MMG_saveSol(pMesh ,pSol ,char *);
+-int  MMG_saveVect(pMesh ,char *);
++/* inout add param  F.H. june 2011 (dataff) */
++int  MMG_loadMesh(pMesh ,char *,void *);
++int  MMG_loadSol(pSol ,char *,int ,void *);
++int  MMG_loadVect(pMesh ,char *,int ,void *);
++int  MMG_saveMesh(pMesh ,char *,void *);
++int  MMG_saveSol(pMesh ,pSol ,char *,void *);
++int  MMG_saveVect(pMesh ,char *,void *);
+ 
+ int  MMG_loctet(pMesh ,int ,int ,double *,double *);
+ int  MMG_computeMetric(pMesh ,pSol ,int ,double * );
+diff -r -u mmg3d4/build/sources/swapar.c mmg3d4-new/build/sources/swapar.c
+--- mmg3d4/build/sources/swapar.c	2012-12-19 16:05:33.000000000 +0100
++++ mmg3d4-new/build/sources/swapar.c	2013-01-18 18:43:38.000000000 +0100
+@@ -1,106 +1,107 @@
+-/****************************************************************************
+-Logiciel initial: MMG3D Version 4.0
+-Co-auteurs : Cecile Dobrzynski et Pascal Frey.
+-Propriétaires :IPB - UPMC -INRIA.
+-
+-Copyright © 2004-2005-2006-2007-2008-2009-2010-2011,
+-diffusé sous les termes et conditions de la licence publique générale de GNU
+-Version 3 ou toute version ultérieure.
+-
+-Ce fichier est une partie de MMG3D.
+-MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
+-suivant les termes de la licence publique générale de GNU
+-Version 3 ou toute version ultérieure.
+-MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS
+-AUCUNE GARANTIE ; sans même garantie de valeur marchande.
+-Voir la licence publique générale de GNU pour plus de détails.
+-MMG3D est diffusé en espérant qu’il sera utile,
+-mais SANS AUCUNE GARANTIE, ni explicite ni implicite,
+-y compris les garanties de commercialisation ou
+-d’adaptation dans un but spécifique.
+-Reportez-vous à la licence publique générale de GNU pour plus de détails.
+-Vous devez avoir reçu une copie de la licence publique générale de GNU
+-en même temps que ce document.
+-Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
+-/****************************************************************************
+-Initial software: MMG3D Version 4.0
+-Co-authors: Cecile Dobrzynski et Pascal Frey.
+-Owners: IPB - UPMC -INRIA.
+-
+-Copyright © 2004-2005-2006-2007-2008-2009-2010-2011,
+-spread under the terms and conditions of the license GNU General Public License
+-as published Version 3, or (at your option) any later version.
+-
+-This file is part of MMG3D
+-MMG3D 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.
+-MMG3D is distributed in the hope that 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 MMG3D. If not, see <http://www.gnu.org/licenses/>.
+-****************************************************************************/
+-#include "mesh.h"
+-
+-int MMG_swapar(pMesh mesh,pSol sol,pQueue q,List *list,int lon,double crit,double declic) {
+-  pTetra   pt;
+-  int      i,l,jel,ncas,ddebug,iadr;
+-
+-  MMG_swpptr = 0;
+-  ncas   = 0;
+-  if ( !MMG_getnElt(mesh,10) )  return(-1);
+-  if(0 && list->tetra[1]/6==2352) ddebug=1;
+-  else ddebug=0;
+-
+-  switch(lon) {
+-  case 3:
+-    ncas = MMG_simu32(mesh,sol,list,crit);
+-    break;
+-  case 4:
+-    ncas = MMG_simu44(mesh,sol,list,crit);
+-    break;
+-  case 5:
+-    ncas = MMG_simu56(mesh,sol,list,crit);
+-    break;
+-  case 6:
+-    ncas = MMG_simu68(mesh,sol,list,crit);
+-    break;
+-  case 7:
+-    ncas = MMG_simu710(mesh,sol,list,crit);
+-    break;
+-  default:
+-    return(0);
+-  }
+-  if(ddebug) printf("on fait swap %d\n",ncas);
+-  if ( ncas && MMG_swpptr ) {
+-    if(ddebug) MMG_saveMesh(mesh,"avt.mesh");
+-    for (l=1; l<=lon; l++) {
+-      jel = list->tetra[l]/6;
+-      pt  = &mesh->tetra[jel];
+-      if(ddebug) {
+-	printf("tet %d : %d %d %d %d -- %d %d %d %d %d %d\n",jel,pt->v[0],pt->v[1],pt->v[2],pt->v[3],
+-	       pt->bdryinfo[0],pt->bdryinfo[1],pt->bdryinfo[2],pt->bdryinfo[3],pt->bdryinfo[4],pt->bdryinfo[5]);
+-
 -      }
+-      MMG_kiudel(q,jel);
 -    }
+-    lon = MMG_swpptr(mesh,sol,list);
+-    assert(lon);
+-    if(!lon) return(0);
 -
-+        fread(&bpos,sw,1,inm); //NulPos 
-+        if(iswp) bpos=MMG_swapbin(bpos);
-+        fread(&mesh->nt,sw,1,inm); 
-+        if(iswp) mesh->nt=MMG_swapbin(mesh->nt);
-+        posnt = ftell(inm); 
-+        rewind(inm);
-+        fseek(inm,bpos,SEEK_SET);        
-+        continue;
-+       } else if(!mesh->ne && binch==8) {  
-+         fread(&bpos,sw,1,inm); //NulPos 
-+         if(iswp) bpos=MMG_swapbin(bpos);
-+         fread(&mesh->ne,sw,1,inm); 
-+         if(iswp) mesh->ne=MMG_swapbin(mesh->ne);
-+         netmp = mesh->ne;
-+         posne = ftell(inm);
-+         rewind(inm);
-+         fseek(inm,bpos,SEEK_SET);        
-+         continue;
-+       } else if(!nhex && binch==10) { 
-+         assert(abs(mesh->info.option)==10);
-+         fread(&bpos,sw,1,inm); //NulPos 
-+         if(iswp) bpos=MMG_swapbin(bpos);
-+         fread(&nhex,sw,1,inm); 
-+         if(iswp) nhex=MMG_swapbin(nhex);
-+         posnhex = ftell(inm);
-+         rewind(inm);
-+         fseek(inm,bpos,SEEK_SET);        
-+         continue;
-+       } else if(!npris && binch==9) { 
-+         assert(abs(mesh->info.option)==10);
-+         fread(&bpos,sw,1,inm); //NulPos 
-+         if(iswp) bpos=MMG_swapbin(bpos);
-+         fread(&npris,sw,1,inm); 
-+         if(iswp) npris=MMG_swapbin(npris);
-+         posnpris = ftell(inm);
-+         rewind(inm);
-+         fseek(inm,bpos,SEEK_SET);        
-+         continue;
-+       } else if(!ncor && binch==13) { 
-+         fread(&bpos,sw,1,inm); //NulPos 
-+         if(iswp) bpos=MMG_swapbin(bpos);
-+         fread(&ncor,sw,1,inm);          
-+         if(iswp) ncor=MMG_swapbin(ncor);
-+         posncor = ftell(inm);
-+         rewind(inm);
-+         fseek(inm,bpos,SEEK_SET);        
-+         continue;
-+        } else if(!ned && binch==5) { //Edges
-+	       fread(&bpos,sw,1,inm); //NulPos 
-+	       if(iswp) bpos=MMG_swapbin(bpos);
-+	       fread(&ned,sw,1,inm); 
-+	       if(iswp) ned=MMG_swapbin(ned);
-+	       posned = ftell(inm);
-+	       rewind(inm);
-+	       fseek(inm,bpos,SEEK_SET);        
-+	       continue;
-+	      } else {
-+         //printf("on traite ? %d\n",binch);
-+         fread(&bpos,sw,1,inm); //NulPos 
-+         if(iswp) bpos=MMG_swapbin(bpos);
-+         //printf("on avance... Nulpos %d\n",bpos);         
-+         rewind(inm);
-+         fseek(inm,bpos,SEEK_SET);        
-+       }     
-+    }            
-+    
-   }
- 
-   if ( abs(mesh->info.option)==10 ) {
--    fprintf(stdout,"  -- READING %8d HEXA %8d PRISMS\n",nhex,npris);
--    if(!mesh->ne) netmp = 0;
--    mesh->ne += 6*nhex + 3*npris;
-+    fprintf(stdout,"  -- READING %8d HEXA %8d PRISMS\n",nhex,npris);  
-+    if(!mesh->ne) netmp = 0;  
-+    mesh->ne += 6*nhex + 3*npris; 
-   }
- 
-   if ( abs(mesh->info.imprim) > 5 )
-     fprintf(stdout,"  -- READING DATA FILE %s\n",data);
- 
-   if ( !mesh->np || !mesh->ne ) {
--    fprintf(stdout,"  ** MISSING DATA\n");
-+    fprintf(stdout,"  ** MISSING DAT qqA\n");
-     return(0);
-   }
--  if(abs(mesh->info.option)==10) { //allocation
-+	if(abs(mesh->info.option)==10) { //allocation
-     listhexa  = (pHexa)M_calloc(nhex+1,sizeof(Hexa),"allochexa");
--    assert(listhexa);
--    adjahex = (int*)M_calloc(6*nhex+7,sizeof(int),"allocadjhexa");
--    assert(adjahex);
+-    for (l=1; l<=lon; l++) {
+-      jel = list->tetra[l];
+-      pt  = &mesh->tetra[jel];
+-      if ( pt->qual >= declic )  MMG_kiuput(q,jel);
+-      for (i=0; i<4; i++)  mesh->point[pt->v[i]].flag = mesh->flag;
+-
+-    }
+-    if(ddebug) {MMG_saveMesh(mesh,"sw.mesh");    exit(0);}
+-    return(1);
 -  }
-+	  assert(listhexa);     
-+	  adjahex = (int*)M_calloc(6*nhex+7,sizeof(int),"allocadjhexa");
-+	  assert(adjahex);                             
-+  }  
-   if ( !MMG_zaldy(mesh) )  return(0);
-   /* read mesh vertices */
-   mesh->npfixe = mesh->np;
-@@ -342,35 +732,35 @@
-   fseek(inm,posnp,SEEK_SET);
-   for (k=1; k<=mesh->np; k++) {
-     ppt = &mesh->point[k];
--    if (mesh->ver < 2) { /*float*/
-+    if (mesh->ver < 2) { /*float*/ 
-       if (!bin) {
--	for (i=0 ; i<3 ; i++) {
--	  fscanf(inm,"%f",&fc);
--	  ppt->c[i] = (double) fc;
--	}
--	fscanf(inm,"%d",&ppt->ref);
-+        for (i=0 ; i<3 ; i++) {
-+          fscanf(inm,"%f",&fc);
-+          ppt->c[i] = (double) fc;
-+        } 
-+        fscanf(inm,"%d",&ppt->ref);
-       } else {
--	for (i=0 ; i<3 ; i++) {
--	  fread(&fc,sw,1,inm);
--	  if(iswp) fc=MMG_swapf(fc);
--	  ppt->c[i] = (double) fc;
--	}
--	fread(&ppt->ref,sw,1,inm);
--	if(iswp) ppt->ref=MMG_swapbin(ppt->ref);
-+        for (i=0 ; i<3 ; i++) {
-+          fread(&fc,sw,1,inm); 
-+          if(iswp) fc=MMG_swapf(fc);    
-+          ppt->c[i] = (double) fc;
-+        }     
-+        fread(&ppt->ref,sw,1,inm);         
-+        if(iswp) ppt->ref=MMG_swapbin(ppt->ref);    
-       }
-     } else {
--      if (!bin)
--	fscanf(inm,"%lf %lf %lf %d",&ppt->c[0],&ppt->c[1],&ppt->c[2],&ppt->ref);
-+      if (!bin) 
-+        fscanf(inm,"%lf %lf %lf %d",&ppt->c[0],&ppt->c[1],&ppt->c[2],&ppt->ref); 
-       else {
--	for (i=0 ; i<3 ; i++) {
--	  fread(&ppt->c[i],sd,1,inm);
--	  if(iswp) ppt->c[i]=MMG_swapd(ppt->c[i]);
--	}
--	fread(&ppt->ref,sw,1,inm);
--	if(iswp) ppt->ref=MMG_swapbin(ppt->ref);
--      }
--    }
--    ppt->tag  = M_UNUSED;
-+        for (i=0 ; i<3 ; i++) { 
-+          fread(&ppt->c[i],sd,1,inm);
-+          if(iswp) ppt->c[i]=MMG_swapd(ppt->c[i]); 
-+        }   
-+        fread(&ppt->ref,sw,1,inm);         
-+        if(iswp) ppt->ref=MMG_swapbin(ppt->ref);    
-+      }  
-+    }             
-+    ppt->tag  = M_UNUSED;    
-   }
- 
-   /* read mesh triangles */
-@@ -378,227 +768,226 @@
-   rewind(inm);
-   fseek(inm,posnt,SEEK_SET);
-   for (k=1; k<=mesh->nt; k++) {
--    pt1 = &mesh->tria[k];
-+    pt1 = &mesh->tria[k]; 
-     if (!bin)
-       fscanf(inm,"%d %d %d %d",&pt1->v[0],&pt1->v[1],&pt1->v[2],&pt1->ref);
-     else {
--      for (i=0 ; i<3 ; i++) {
--	fread(&pt1->v[i],sw,1,inm);
--	if(iswp) pt1->v[i]=MMG_swapbin(pt1->v[i]);
--      }
--      fread(&pt1->ref,sw,1,inm);
--      if(iswp) pt1->ref=MMG_swapbin(pt1->ref);
--    }
--  }
--  /* read mesh quads (option 10)*/
--  if(abs(mesh->info.option)==10) {
--    fprintf(stdout,"     QUADS READING %d\n",nq);
-+      for (i=0 ; i<3 ; i++) { 
-+        fread(&pt1->v[i],sw,1,inm); 
-+        if(iswp) pt1->v[i]=MMG_swapbin(pt1->v[i]);    
-+      }
-+      fread(&pt1->ref,sw,1,inm); 
-+      if(iswp) pt1->ref=MMG_swapbin(pt1->ref);           
-+    }  
-+  }
-+  /* read mesh quads (option 10)*/ 
-+	if(abs(mesh->info.option)==10) { 
-+		fprintf(stdout,"     QUADS READING %d\n",nq);
-     mesh->ntfixe += 4*nq;
- 
-     rewind(inm);
-     fseek(inm,posnq,SEEK_SET);
-     for (k=1; k<=nq; k++) {
-       if (!bin)
--	fscanf(inm,"%d %d %d %d %d",&p0,&p1,&p2,&p3,&ref);
-+        fscanf(inm,"%d %d %d %d %d",&p0,&p1,&p2,&p3,&ref);
-       else {
--	fread(&p0,sw,1,inm);
--	if(iswp) p0=MMG_swapbin(p0);
--	fread(&p1,sw,1,inm);
--	if(iswp) p1=MMG_swapbin(p1);
--	fread(&p2,sw,1,inm);
--	if(iswp) p2=MMG_swapbin(p2);
--	fread(&p3,sw,1,inm);
--	if(iswp) p3=MMG_swapbin(p3);
--	fread(&pt1->ref,sw,1,inm);
--	if(iswp) ref=MMG_swapbin(ref);
--      }
-+        fread(&p0,sw,1,inm); 
-+        if(iswp) p0=MMG_swapbin(p0);    
-+        fread(&p1,sw,1,inm); 
-+        if(iswp) p1=MMG_swapbin(p1);    
-+        fread(&p2,sw,1,inm); 
-+        if(iswp) p2=MMG_swapbin(p2);    
-+        fread(&p3,sw,1,inm); 
-+        if(iswp) p3=MMG_swapbin(p3);    
-+	      fread(&pt1->ref,sw,1,inm); 
-+	      if(iswp) ref=MMG_swapbin(ref);           
-+      } 
-       /*creation of 4 triangles per quads because we don't know how hexa will be cut*/
--      pt1 = &mesh->tria[++mesh->nt];
--      pt1->v[0] = p0;
--      pt1->v[1] = p1;
--      pt1->v[2] = p2;
--      pt1->ref  = ref;
--      pt1 = &mesh->tria[++mesh->nt];
--      pt1->v[0] = p0;
--      pt1->v[1] = p2;
--      pt1->v[2] = p3;
--      pt1->ref  = ref;
--      pt1 = &mesh->tria[++mesh->nt];
--      pt1->v[0] = p0;
--      pt1->v[1] = p1;
--      pt1->v[2] = p3;
--      pt1->ref  = ref;
--      pt1 = &mesh->tria[++mesh->nt];
--      pt1->v[0] = p1;
--      pt1->v[1] = p2;
--      pt1->v[2] = p3;
--      pt1->ref  = ref;
 -
--    }
--  }
--  /*read and store edges*/
--  if (ned) {
--    if ( !MMG_zaldy4(&hed,ned) ) {
--      if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES IGNORED\n");
--      ned = 0;
--    }
--    mesh->ned = ned;
-+      pt1 = &mesh->tria[++mesh->nt]; 
-+			pt1->v[0] = p0;
-+			pt1->v[1] = p1;
-+			pt1->v[2] = p2;
-+			pt1->ref  = ref;
-+      pt1 = &mesh->tria[++mesh->nt]; 
-+			pt1->v[0] = p0;
-+			pt1->v[1] = p2;
-+			pt1->v[2] = p3;
-+			pt1->ref  = ref;
-+      pt1 = &mesh->tria[++mesh->nt]; 
-+			pt1->v[0] = p0;
-+			pt1->v[1] = p1;
-+			pt1->v[2] = p3;
-+			pt1->ref  = ref;
-+      pt1 = &mesh->tria[++mesh->nt]; 
-+			pt1->v[0] = p1;
-+			pt1->v[1] = p2;
-+			pt1->v[2] = p3;
-+			pt1->ref  = ref;
-+ 
+-  return(0);
+-}
++/****************************************************************************
++Logiciel initial: MMG3D Version 4.0
++Co-auteurs : Cecile Dobrzynski et Pascal Frey.
++Propriétaires :IPB - UPMC -INRIA.
++
++Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
++diffusé sous les termes et conditions de la licence publique générale de GNU
++Version 3 ou toute version ultérieure.  
++
++Ce fichier est une partie de MMG3D.
++MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
++suivant les termes de la licence publique générale de GNU
++Version 3 ou toute version ultérieure.
++MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
++AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
++Voir la licence publique générale de GNU pour plus de détails.
++MMG3D est diffusé en espérant qu’il sera utile, 
++mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
++y compris les garanties de commercialisation ou 
++d’adaptation dans un but spécifique. 
++Reportez-vous à la licence publique générale de GNU pour plus de détails.
++Vous devez avoir reçu une copie de la licence publique générale de GNU 
++en même temps que ce document. 
++Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
++/****************************************************************************
++Initial software: MMG3D Version 4.0
++Co-authors: Cecile Dobrzynski et Pascal Frey.
++Owners: IPB - UPMC -INRIA.
++
++Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
++spread under the terms and conditions of the license GNU General Public License 
++as published Version 3, or (at your option) any later version.
++
++This file is part of MMG3D
++MMG3D 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.
++MMG3D is distributed in the hope that 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 MMG3D. If not, see <http://www.gnu.org/licenses/>.  
++****************************************************************************/
++#include "mesh.h"
++
++int MMG_swapar(pMesh mesh,pSol sol,pQueue q,List *list,int lon,double crit,double declic) {
++  pTetra   pt;
++  int      i,l,jel,ncas,ddebug,iadr;
++
++  MMG_swpptr = 0;
++  ncas   = 0;
++  if ( !MMG_getnElt(mesh,10) )  return(-1);
++	if(0 && list->tetra[1]/6==2352) ddebug=1;
++	else ddebug=0;
++	
++  switch(lon) {
++  case 3:
++	  ncas = MMG_simu32(mesh,sol,list,crit);
++    break;
++  case 4:
++	  ncas = MMG_simu44(mesh,sol,list,crit); 
++    break;
++  case 5:
++	ncas = MMG_simu56(mesh,sol,list,crit);
++    break;
++  case 6:
++	ncas = MMG_simu68(mesh,sol,list,crit); 
++    break;
++  case 7:
++	ncas = MMG_simu710(mesh,sol,list,crit);   
++    break;  
++  default:
++    return(0);
++  }
++	if(ddebug) printf("on fait swap %d\n",ncas);
++  if ( ncas && MMG_swpptr ) {
++		if(ddebug) MMG_saveMesh(mesh,"avt.mesh",0);
++    for (l=1; l<=lon; l++) {
++      jel = list->tetra[l]/6;
++      pt  = &mesh->tetra[jel]; 
++			if(ddebug) {
++				printf("tet %d : %d %d %d %d -- %d %d %d %d %d %d\n",jel,pt->v[0],pt->v[1],pt->v[2],pt->v[3],
++					pt->bdryinfo[0],pt->bdryinfo[1],pt->bdryinfo[2],pt->bdryinfo[3],pt->bdryinfo[4],pt->bdryinfo[5]);  
++				
++			} 
++			MMG_kiudel(q,jel);
 +    }
++    lon = MMG_swpptr(mesh,sol,list);
++    assert(lon);
++    if(!lon) return(0); 
++    
++    for (l=1; l<=lon; l++) {
++      jel = list->tetra[l];
++      pt  = &mesh->tetra[jel]; 
++      if ( pt->qual >= declic )  MMG_kiuput(q,jel);
++      for (i=0; i<4; i++)  mesh->point[pt->v[i]].flag = mesh->flag;		 
++
++   }
++    if(ddebug) {MMG_saveMesh(mesh,"sw.mesh",0);    exit(0);}
++    return(1);
 +  }
-+	/*read and store edges*/
-+  if (ned) {         
-+	  if ( !MMG_zaldy4(&hed,ned) ) {
-+      if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES IGNORED\n"); 
-+			ned = 0;
-+    }   
-+		mesh->ned = ned;
-     rewind(inm);
--    fseek(inm,posned,SEEK_SET);
--    for (k=1; k<=ned; k++) {
-+    fseek(inm,posned,SEEK_SET); 
-+    for (k=1; k<=ned; k++) { 
-       if (!bin)
--	fscanf(inm,"%d %d %d",&nu1,&nu2,&ref);
-+        fscanf(inm,"%d %d %d",&nu1,&nu2,&ref);
-       else {
--	fread(&nu1,sw,1,inm);
--	if(iswp) nu1=MMG_swapbin(nu1);
--	fread(&nu2,sw,1,inm);
--	if(iswp) nu2=MMG_swapbin(nu2);
--	fread(&ref,sw,1,inm);
--	if(iswp) ref=MMG_swapbin(ref);
--      }
--      if(MMG_edgePut(&hed,nu1,nu2,2)>1) {
--	fprintf(stdout,"  ## WARNING DOUBLE EDGE : %d %d\n",nu1,nu2);
--      }
--      mesh->point[nu1].geom = M_RIDGE_GEO;
--      mesh->point[nu2].geom = M_RIDGE_GEO;
-+        fread(&nu1,sw,1,inm); 
-+        if(iswp) nu1=MMG_swapbin(nu1);    
-+        fread(&nu2,sw,1,inm); 
-+        if(iswp) nu2=MMG_swapbin(nu2);    
-+        fread(&ref,sw,1,inm); 
-+        if(iswp) ref=MMG_swapbin(ref);    
-+      }  
-+			if(MMG_edgePut(&hed,nu1,nu2,2)>1) {
-+				fprintf(stdout,"  ## WARNING DOUBLE EDGE : %d %d\n",nu1,nu2);
-+			} 
-+			mesh->point[nu1].geom = M_RIDGE_GEO;  
-+			mesh->point[nu2].geom = M_RIDGE_GEO;  
-     }
-   }
++
++  return(0);
++}
++
+diff -u  mmg3d4/build/sources/inout.c mmg3d4-ok/build/sources/inout.c
+--- mmg3d4/build/sources/inout.c	2012-12-19 16:05:32.000000000 +0100
++++ mmg3d4-ok/build/sources/inout.c	2013-07-11 11:43:47.000000000 +0200
+@@ -44,6 +44,7 @@
+ along with MMG3D. If not, see <http://www.gnu.org/licenses/>.
+ ****************************************************************************/
+ #include "mesh.h"
++#include "dataff.h"
  
-   /* read mesh tetrahedra */
-   mesh->nefixe = mesh->ne;
-   rewind(inm);
--  fseek(inm,posne,SEEK_SET);
--  reorient = 0;
--  for (k=1; k<=netmp; k++) {
-+  fseek(inm,posne,SEEK_SET); 
-+	reorient = 0;
-+  for (k=1; k<=netmp; k++) { 
-     pt = &mesh->tetra[k];
--    if (!bin)
--      fscanf(inm,"%d %d %d %d %d",&pt->v[0],&pt->v[1],&pt->v[2],&pt->v[3],&ref);
--    else {
--
--      for (i=0 ; i<4 ; i++) {
--	fread(&pt->v[i],sw,1,inm);
--	if(iswp) pt->v[i]=MMG_swapbin(pt->v[i]);
--      }
--      fread(&ref,sw,1,inm);
--      if(iswp) ref=MMG_swapbin(ref);
--    }
-+    if (!bin) 
-+      fscanf(inm,"%d %d %d %d %d",&pt->v[0],&pt->v[1],&pt->v[2],&pt->v[3],&ref); 
-+    else {                                                                        
-+	
-+      for (i=0 ; i<4 ; i++) { 
-+        fread(&pt->v[i],sw,1,inm); 
-+        if(iswp) pt->v[i]=MMG_swapbin(pt->v[i]);    
-+      }
-+      fread(&ref,sw,1,inm);         
-+      if(iswp) ref=MMG_swapbin(ref);           
-+    }  
-     pt->ref  = ref;//0;//ref ;
  
-     /*check orientation*/
--    volref = MMG_voltet(mesh,k);
--    if(volref < 0) {
--      reorient++;
--      tmp = pt->v[2];
--      pt->v[2] = pt->v[3];
--      pt->v[3] = tmp;
--    }
--
-+		volref = MMG_voltet(mesh,k);
-+		if(volref < 0) {
-+		 if(!reorient) {
-+		   fprintf(stdout,"\n     $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ \n");
-+		   fprintf(stdout,"         BAD ORIENTATION : vol < 0 -- Some tetra will be reoriented\n");     
-+		   fprintf(stdout,"     $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ \n\n");
-+		   reorient = 1;        
-+		 }
-+		 tmp = pt->v[2];
-+     pt->v[2] = pt->v[3];
-+     pt->v[3] = tmp;
-+		}
-+	  
-     for(i=0 ; i<4 ; i++)
--      pt->bdryref[i] = -1;
--
--    if (ned) {
--      for(i=0 ; i<6 ; i++) {
--	nu1 = pt->v[MMG_iare[i][0]];
--	nu2 = pt->v[MMG_iare[i][1]];
--	pt->bdryinfo[i] = MMG_edgePoint(&hed,nu1,nu2);
--      }
--
--    } else {
--      for(i=0 ; i<6 ; i++)
--	pt->bdryinfo[i] = 0;
--    }
--  }
--  if(reorient) {
--    fprintf(stdout,"\n     $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ \n");
--    fprintf(stdout,"         BAD ORIENTATION : vol < 0 -- %8d tetra reoriented\n",reorient);
--    fprintf(stdout,"     $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ \n\n");
--    reorient = 1;
-+      pt->bdryref[i] = -1;  
-+    
-+		if (ned) {
-+	    for(i=0 ; i<6 ; i++) {                         
-+				nu1 = pt->v[MMG_iare[i][0]];
-+				nu2 = pt->v[MMG_iare[i][1]];
-+	      pt->bdryinfo[i] = MMG_edgePoint(&hed,nu1,nu2);
-+			}  			
-+			
-+		} else {
-+	    for(i=0 ; i<6 ; i++)
-+	      pt->bdryinfo[i] = 0;  			
-+		}
-   }
--   if (ned) M_free(hed.item);
-+  if (ned) M_free(hed.item); 
+ extern short           MMG_imprim;
+@@ -100,35 +101,467 @@
+   return(out);
+ }
  
--  /*read corners*/
-+  /*read corners*/ 
-   if (ncor) {
-     rewind(inm);
--    fseek(inm,posncor,SEEK_SET);
-+    fseek(inm,posncor,SEEK_SET); 
-     mesh->ncor = ncor;
--    for (k=1; k<=ncor; k++) {
-+    for (k=1; k<=ncor; k++) { 
-       if (!bin)
--	fscanf(inm,"%d",&ref);
-+        fscanf(inm,"%d",&ref);
-       else {
--	fread(&ref,sw,1,inm);
--	if(iswp) ref=MMG_swapbin(ref);
--      }
-+        fread(&ref,sw,1,inm); 
-+        if(iswp) ref=MMG_swapbin(ref);    
-+      }  
-       ppt = &mesh->point[ref];
--      ppt->geom = M_CORNER;
--    }
-+      ppt->geom = M_CORNER; 
-+    } 
-   }
--
--
--  if ( abs(mesh->info.option)==10 ) {
++
++int MMG_loadMeshff(pMesh mesh,char *filename,DataFF *dataff) {  
 +   
++    
++    Hedge    				 hed,hed2;
++    pPoint       	   ppt;
++    pTetra           pt;
++    pTria            pt1;
++    int i,j,k; 
++    int nhex=0, npris=0, netmp=0,nq=0, pp[10] , ned=0, ncor=0;
++    int p0,p1,p2,p3,p4,p5,p6,ref ;
++    int data[10],ldata=10;
++    dataff->get_mesh(dataff,data,10);
++    mesh->np = data[ff_id_vertex];
++    ned = data[ff_id_seg];
++    mesh->nt = data[ff_id_tria];
++    mesh->ne = data[ff_id_tet];
++    netmp=mesh->ne;
++    nhex=data[ff_id_hex];
++    npris=data[ff_id_prism]; 
++    nq=data[ff_id_quad];
++    ncor= data[ff_id_corner];
++
++    if( nhex || npris) {
++	printf("mmg3d ff interface , hex or prism NOT SUPPORTED  to day (sorry  FH) \n");
++	goto L0; 
++    }
++    
++    mesh->ncor = 0; 
++    mesh->ver =1;
++    if ( abs(mesh->info.option)==10 ) {
++	fprintf(stdout,"  -- READING %8d HEXA %8d PRISMS\n",nhex,npris);  
++	if(!mesh->ne) netmp = 0;  
++	mesh->ne += 6*nhex + 3*npris; 
++    }
++    
++    if ( abs(mesh->info.imprim) > 5 )
++	fprintf(stdout,"  -- READING DATA for ff interface ");
++    
++    if ( !mesh->np || !mesh->ne ) {
++	fprintf(stdout,"  ** MISSING DATA yy\n");
++	goto L0; ;
++    }
++    if ( !MMG_zaldy(mesh) )  goto L0; 
++    
++    /* read mesh vertices */
++    mesh->npfixe = mesh->np;
++    
++    for (k=1; k<=mesh->np; k++) {
++	ppt = &mesh->point[k];
++	dataff->get_v3(dataff,k,ppt->c,&ppt->ref);
++	ppt->tag  = M_UNUSED;    
++    }
++    
++    /* read mesh triangles */
++    mesh->ntfixe = mesh->nt;
++
++    for (k=1; k<=mesh->nt; k++) {
++	pt1 = &mesh->tria[k]; 
++	dataff->get_elmt(dataff,ff_id_tria,k,pt1->v,&pt1->ref);
++	 
++	}  
++    
++
++
++    /* read mesh quads (option 10)*/ 
++    if(abs(mesh->info.option)==10) { 
++	fprintf(stdout,"     QUADS READING %d\n",nq);
++	mesh->ntfixe += 4*nq;
++        for (k=1; k<=nq; k++) {
++	    dataff->get_elmt(dataff, ff_id_quad ,k,pp,&ref);
 +	
-+  if ( abs(mesh->info.option)==10 ) { 
-     if(bin) {
-       printf("NOT SUPPORTED\n");
-       exit(0);
--    }
--    if ( !MMG_zaldy4(&hed2,3*npris+6*nhex) ) {
--      if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : PRISM IGNORED\n");
--      npris = 0;
--      nhex  = 0;
--    }
-+    } 
-+	  if ( !MMG_zaldy4(&hed2,3*npris+6*nhex) ) {
-+      if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : PRISM IGNORED\n"); 
-+			npris = 0;
-+			nhex  = 0;
-+    }   
- 
-     /*read hexa and transform to tetra*/
-     rewind(inm);
--    fseek(inm,posnhex,SEEK_SET);
--    nbado = 0;
-+    fseek(inm,posnhex,SEEK_SET);   
-+		nbado = 0;
-     for (k=1; k<=nhex; k++) {
--      ph = &listhexa[k];
--      fscanf(inm,"%d %d %d %d %d %d %d %d %d",&ph->v[0],&ph->v[1],&ph->v[2],&ph->v[3],&ph->v[4],&ph->v[5],&ph->v[6],&ph->v[7],&ph->ref);
--      //fscanf(inm,"%d %d %d %d %d %d %d %d %d",&p0,&p4,&p2,&p1,&p3,&p5,&p6,&p7,&ref);
--      //printf("hex %d : %d %d %d %d %d %d %d %d\n",k,p0,p1,p2,p3,p4,p5,p6,p7);
-+			ph = &listhexa[k];   
-+      fscanf(inm,"%d %d %d %d %d %d %d %d %d",&ph->v[0],&ph->v[1],&ph->v[2],&ph->v[3],&ph->v[4],&ph->v[5],&ph->v[6],&ph->v[7],&ph->ref); 
-+      //fscanf(inm,"%d %d %d %d %d %d %d %d %d",&p0,&p4,&p2,&p1,&p3,&p5,&p6,&p7,&ref); 
-+      //printf("hex %d : %d %d %d %d %d %d %d %d\n",k,p0,p1,p2,p3,p4,p5,p6,p7); 
-       //check orientability of the hexahedra : vol of tet p0 p1 p3 p4
--      volhex = MMG_quickvol(mesh->point[ph->v[0]].c,mesh->point[ph->v[1]].c,mesh->point[ph->v[2]].c,mesh->point[ph->v[3]].c);
--      if(k==1) {
--	volref = volhex;
--	//printf("vol %e\n",volref);
--      }
--      else {
--	if(volref*volhex < 0) {
--	  fprintf(stdout,"BAD ORIENTATION OF HEXAHEDRON %d : %d %d %d %d %d %d %d %d\n",k,p0,p1,p2,p3,p4,p5,p6,p7);
--	  nbado++;
--	  tmp = ph->v[3];
--	  ph->v[3] = ph->v[1];
--	  ph->v[1] = tmp;
--	  tmp = ph->v[5];
--	  ph->v[5] = ph->v[7];
--	  ph->v[7] = tmp;
--	}
--      }
--      // MMG_cuthex(mesh,&hed2,netmp+(k-1)*6,ph->v[0],ph->v[1],ph->v[2],ph->v[3],ph->v[4],ph->v[5],ph->v[6],ph->v[7],ph->ref);
--    }
--    fprintf(stdout,"%8d HEXA REORIENTED\n",nbado);
-+			volhex = MMG_quickvol(mesh->point[ph->v[0]].c,mesh->point[ph->v[1]].c,mesh->point[ph->v[2]].c,mesh->point[ph->v[3]].c);
-+			if(k==1) {
-+				volref = volhex; 
-+				//printf("vol %e\n",volref);
-+			}
-+			else {
-+				if(volref*volhex < 0) {
-+					fprintf(stdout,"BAD ORIENTATION OF HEXAHEDRON %d : %d %d %d %d %d %d %d %d\n",k,p0,p1,p2,p3,p4,p5,p6,p7);
-+					nbado++;
-+					tmp = ph->v[3];
-+					ph->v[3] = ph->v[1];
-+					ph->v[1] = tmp;
-+					tmp = ph->v[5];
-+					ph->v[5] = ph->v[7];
-+					ph->v[7] = tmp;
-+				}
-+			} 
-+			// MMG_cuthex(mesh,&hed2,netmp+(k-1)*6,ph->v[0],ph->v[1],ph->v[2],ph->v[3],ph->v[4],ph->v[5],ph->v[6],ph->v[7],ph->ref);
-+    }  
-+		fprintf(stdout,"%8d HEXA REORIENTED\n",nbado);
- 
--    if(!MMG_hashHexa(listhexa,adjahex,nhex)) return(0);
--    MMG_cuthex(mesh,&hed2,listhexa,adjahex,nhex,netmp);
-+		if(!MMG_hashHexa(listhexa,adjahex,nhex)) return(0);  
-+	  MMG_cuthex(mesh,&hed2,listhexa,adjahex,nhex,netmp); 
-     /*read prism and transform to tetra
--      ---> compatibility pbs ==> hash edge and switch case*/
-+		---> compatibility pbs ==> hash edge and switch case*/  
-     rewind(inm);
--    fseek(inm,posnpris,SEEK_SET);
--    nimp = 0;
--    ne = netmp+6*nhex;
-+    fseek(inm,posnpris,SEEK_SET); 
-+		nimp = 0; 
-+		ne = netmp+6*nhex;
-     for (k=1; k<=npris; k++) {
--      fscanf(inm,"%d %d %d %d %d %d %d",&p0,&p1,&p2,&p3,&p4,&p5,&ref);
--      if(!MMG_cutprism(mesh,&hed2,ne,p0,p1,p2,p3,p4,p5,ref))
--	{
--	  if(mesh->info.imprim < 0 ) fprintf(stdout,"DECOMPOSITION PRISM INVALID \n\n");
--	  mesh->ne += 5;
--	  ne += 8;
--	  nimp++;
--	  continue;
--	}
--      ne += 3;
-+      fscanf(inm,"%d %d %d %d %d %d %d",&p0,&p1,&p2,&p3,&p4,&p5,&ref); 
-+			if(!MMG_cutprism(mesh,&hed2,ne,p0,p1,p2,p3,p4,p5,ref))
-+			{
-+				if(mesh->info.imprim < 0 ) fprintf(stdout,"DECOMPOSITION PRISM INVALID \n\n"); 
-+				mesh->ne += 5;
-+				ne += 8;
-+				nimp++; 
-+				continue;
-+			}
-+			ne += 3;
-     }
--    if(abs(mesh->info.imprim) > 3 )fprintf(stdout,"     %d INVALID DECOMPOSITION\n\n",nimp);
-+		if(abs(mesh->info.imprim) > 3 )fprintf(stdout,"     %d INVALID DECOMPOSITION\n\n",nimp);
-   }
--
-+  
-   if ( abs(mesh->info.imprim) > 3 && abs(mesh->info.option)!=10 ) {
-     fprintf(stdout,"     NUMBER OF GIVEN VERTICES   %8d\n",mesh->npfixe);
-     if ( mesh->ntfixe )
-@@ -609,24 +998,26 @@
-     if ( ned )
-       fprintf(stdout,"     NUMBER OF GIVEN EDGES      %8d\n",ned);
-   }
--  fclose(inm);
--  return(1);
-+ fclose(inm);
-+ return(1);
- }
- 
- 
- /* load solution (metric) */
--int MMG_loadSol(pSol sol,char *filename,int npmax) {
--  FILE       *inm;
-+int MMG_loadSol(pSol sol,char *filename,int npmax,void *dataff) { 
-+  FILE       *inm;   
-   float       fsol;
--  double      tmp;
-+  double      tmp;       
-   int         binch,bdim,iswp;
-   int         k,i,isol,type,bin,dim,btyp,bpos;
-   long        posnp;
-   char        *ptr,data[128],chaine[128];
--
--  posnp = 0;
-+    if(dataff) 
-+	return MMG_loadSolff( sol,filename,npmax,(DataFF*) dataff);
++	    pt1 = &mesh->tria[++mesh->nt]; 
++	    pt1->v[0] = pp[0];
++	    pt1->v[1] = pp[1];
++	    pt1->v[2] = pp[2];
++	    pt1->ref  = ref;
++	    pt1 = &mesh->tria[++mesh->nt]; 
++	    pt1->v[0] = pp[0];
++	    pt1->v[1] = pp[2];
++	    pt1->v[2] = pp[3];
++	    pt1->ref  = ref;
++	    pt1 = &mesh->tria[++mesh->nt]; 
++	    pt1->v[0] = pp[0];
++	    pt1->v[1] = pp[1];
++	    pt1->v[2] = pp[3];
++	    pt1->ref  = ref;
++	    pt1 = &mesh->tria[++mesh->nt]; 
++	    pt1->v[0] = pp[1];
++	    pt1->v[1] = pp[2];
++	    pt1->v[2] = pp[3];
++	    pt1->ref  = ref;
++	    
++	}
++    }
++    
++    /*read and store edges*/
++    if (ned) {         
++	if ( !MMG_zaldy4(&hed,ned) ) {
++	    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES IGNORED\n"); 
++	    ned = 0;
++	}   
++	mesh->ned = ned;
++	
++	for (k=1; k<=ned; k++) { 
++	   dataff->get_elmt(dataff, ff_id_seg ,k,pp,&ref);
++	   
++	    if(MMG_edgePut(&hed,pp[0],pp[1],2)>1) {
++		fprintf(stdout,"  ## WARNING DOUBLE EDGE : %d %d\n",pp[0],pp[1]);
++	    }
++	}
++    }
++    
++    /* read mesh tetrahedra */
++    mesh->nefixe = mesh->ne;
++ 
 +  
-+  posnp = 0; 
-   bin   = 0;
--  iswp  = 0;
-+  iswp  = 0; 
- 
-   strcpy(data,filename);
-   ptr = strstr(data,".mesh");
-@@ -645,94 +1036,94 @@
-   }
-   fprintf(stdout,"  %%%% %s OPENED\n",data);
- 
--
--  if(!bin) {
++    for (k=1; k<=netmp; k++) { 
++	pt = &mesh->tetra[k];
++	dataff->get_elmt(dataff,ff_id_tet,k,pt->v,&ref);
++	pt->ref  = ref;//0;//ref ;  
++	for(i=0 ; i<4 ; i++)
++	    pt->bdryref[i] = -1;  
++	
++	if (ned) { int nu1,nu2;
++	    for(i=0 ; i<6 ; i++) {                         
++		nu1 = pt->v[MMG_iare[i][0]];
++		nu2 = pt->v[MMG_iare[i][1]];
++		pt->bdryinfo[i] = MMG_edgePoint(&hed,nu1,nu2);
++	    }  			
++	    
++	} else {
++	    for(i=0 ; i<6 ; i++)
++		pt->bdryinfo[i] = 0;  			
++	}
++    }
++    if (ned) M_free(hed.item); 
++    
++    /*read corners*/ 
++    if (ncor) {
++	
++	mesh->ncor = ncor;
++	for (k=1; k<=ncor; k++) { 
++	    dataff->get_elmt(dataff,ff_id_corner,k,&ref,0);
++
++	    ppt = &mesh->point[ref];
++	    ppt->geom = M_CORNER; 
++	} 
++    }
++#ifdef XXXXXXXXXXXXXXX
++    if ( abs(mesh->info.option)==10 ) { 
++	if(bin) {
++	    printf("NOT SUPPORTED\n");
++	    exit(0);
++	} 
++	if ( !MMG_zaldy4(&hed2,3*npris+6*nhex) ) {
++	    if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : PRISM IGNORED\n"); 
++	    npris = 0;
++	    nhex  = 0;
++	}   
++	
++	/*read hexa and transform to tetra*/
++	rewind(inm);
++	fseek(inm,posnhex,SEEK_SET);
++	for (k=1; k<=nhex; k++) {   
++	    fscanf(inm,"%d %d %d %d %d %d %d %d %d",&p0,&p1,&p2,&p3,&p4,&p5,&p6,&p7,&ref); 
++	    //fscanf(inm,"%d %d %d %d %d %d %d %d %d",&p0,&p4,&p2,&p1,&p3,&p5,&p6,&p7,&ref); 
++	    //printf("hex %d : %d %d %d %d %d %d %d %d\n",k,p0,p1,p2,p3,p4,p5,p6,p7);   
++	    MMG_cuthex(mesh,&hed2,netmp+(k-1)*6,p0,p1,p2,p3,p4,p5,p6,p7,ref);
++	}  
++	
++	/*read prism and transform to tetra
++	 ---> compatibility pbs ==> hash edge and switch case*/  
++	rewind(inm);
++	fseek(inm,posnpris,SEEK_SET); 
++	nimp = 0; 
++	ne = netmp+6*nhex;
++	for (k=1; k<=npris; k++) {
++	    fscanf(inm,"%d %d %d %d %d %d %d",&p0,&p1,&p2,&p3,&p4,&p5,&ref); 
++	    if(!MMG_cutprism(mesh,&hed2,ne,p0,p1,p2,p3,p4,p5,ref))
++	      {
++		if(mesh->info.imprim < 0 ) fprintf(stdout,"DECOMPOSITION PRISM INVALID \n\n"); 
++		mesh->ne += 5;
++		ne += 8;
++		nimp++; 
++		continue;
++	      }
++	    ne += 3;
++	}
++	if(abs(mesh->info.imprim) > 3 )fprintf(stdout,"     %d INVALID DECOMPOSITION\n\n",nimp);
++    }
++#endif    
++    if ( abs(mesh->info.imprim) > 3 ) {
++	fprintf(stdout,"     NUMBER OF GIVEN VERTICES   %8d\n",mesh->npfixe);
++	if ( mesh->ntfixe )
++	    fprintf(stdout,"     NUMBER OF GIVEN TRIANGLES  %8d\n",mesh->ntfixe);
++	fprintf(stdout,"     NUMBER OF GIVEN TETRAHEDRA %8d\n",mesh->nefixe);
++	if ( ncor )
++	    fprintf(stdout,"     NUMBER OF GIVEN CORNERS    %8d\n",ncor);
++	if ( ned )
++	    fprintf(stdout,"     NUMBER OF GIVEN EDGES      %8d\n",ned);
++    }
++    //    MMG_saveMesh(mesh,"XXXXX.mesh",0);
++   dataff->mesh=0; // used 
++    return 1; 
++L0: 
++    dataff->mesh=0;// used 
++    return 1; 
++}
++
++int MMG_loadSolff(pSol sol,char *filename,int npmax,DataFF *dataff) { 
 +   
-+  if(!bin) {   
-     strcpy(chaine,"DDD");
--    while(fscanf(inm,"%s",&chaine[0])!=EOF && strncmp(chaine,"End",strlen("End")) ) {
-+    while(fscanf(inm,"%s",&chaine[0])!=EOF && strncmp(chaine,"End",strlen("End")) ) { 
-       if(!strncmp(chaine,"Dimension",strlen("Dimension"))) {
--	fscanf(inm,"%d",&dim);
--	if(dim!=3) {
--	  fprintf(stdout,"BAD SOL DIMENSION : %d\n",dim);
--	  return(1);
--	}
--	continue;
-+          fscanf(inm,"%d",&dim);
-+          if(dim!=3) {
-+            fprintf(stdout,"BAD SOL DIMENSION : %d\n",dim); 
-+            return(1);
-+          }
-+          continue;
-       } else if(!strncmp(chaine,"SolAtVertices",strlen("SolAtVertices"))) {
--	fscanf(inm,"%d",&sol->np);
--	fscanf(inm,"%d",&type);
--	if(type!=1) {
--	  fprintf(stdout,"SEVERAL SOLUTION => IGNORED : %d\n",type);
--	  return(1);
--	}
--	fscanf(inm,"%d",&btyp);
--	posnp = ftell(inm);
--	break;
--      }
--    }
--  } else {
--    fread(&binch,sw,1,inm);
--    iswp=0;
--    if(binch==16777216) iswp=1;
-+        fscanf(inm,"%d",&sol->np); 
-+        fscanf(inm,"%d",&type); 
-+        if(type!=1) {
-+          fprintf(stdout,"SEVERAL SOLUTION => IGNORED : %d\n",type);
-+          return(1);
-+        }
-+        fscanf(inm,"%d",&btyp);
-+        posnp = ftell(inm);
-+        break;
-+      } 
-+    }            
-+  } else {     
-+    fread(&binch,sw,1,inm); 
-+    iswp=0;   
-+    if(binch==16777216) iswp=1;    
-     else if(binch!=1) {
-       fprintf(stdout,"BAD FILE ENCODING\n");
--    }
--    fread(&sol->ver,sw,1,inm);
--    if(iswp) sol->ver = MMG_swapbin(sol->ver);
-+    } 
-+    fread(&sol->ver,sw,1,inm); 
-+    if(iswp) sol->ver = MMG_swapbin(sol->ver); 
-     while(fread(&binch,sw,1,inm)!=EOF && binch!=54 ) {
--      if(iswp) binch=MMG_swapbin(binch);
--      if(binch==54) break;
-+      if(iswp) binch=MMG_swapbin(binch);      
-+      if(binch==54) break;  
-       if(binch==3) {  //Dimension
--	fread(&bdim,sw,1,inm);  //NulPos=>20
--	if(iswp) bdim=MMG_swapbin(bdim);
--	fread(&bdim,sw,1,inm);
--	if(iswp) bdim=MMG_swapbin(bdim);
--	if(bdim!=3) {
--	  fprintf(stdout,"BAD SOL DIMENSION : %d\n",dim);
--	  exit(0);
--	  return(1);
--	}
--	continue;
-+        fread(&bdim,sw,1,inm);  //NulPos=>20
-+        if(iswp) bdim=MMG_swapbin(bdim);
-+        fread(&bdim,sw,1,inm);
-+        if(iswp) bdim=MMG_swapbin(bdim);
-+        if(bdim!=3) {
-+          fprintf(stdout,"BAD SOL DIMENSION : %d\n",dim);
-+          exit(0);
-+          return(1);
-+        }
-+        continue;
-       } else if(binch==62) {  //SolAtVertices
--	fread(&binch,sw,1,inm); //NulPos
--	if(iswp) binch=MMG_swapbin(binch);
--	fread(&sol->np,sw,1,inm);
--	if(iswp) sol->np=MMG_swapbin(sol->np);
--	fread(&binch,sw,1,inm); //nb sol
--	if(iswp) binch=MMG_swapbin(binch);
--	if(binch!=1) {
--	  fprintf(stdout,"SEVERAL SOLUTION => IGNORED : %d\n",type);
--	  return(1);
--	}
--	fread(&btyp,sw,1,inm); //typsol
--	if(iswp) btyp=MMG_swapbin(btyp);
--	posnp = ftell(inm);
--	break;
-+        fread(&binch,sw,1,inm); //NulPos
-+        if(iswp) binch=MMG_swapbin(binch);
-+        fread(&sol->np,sw,1,inm); 
-+        if(iswp) sol->np=MMG_swapbin(sol->np);
-+        fread(&binch,sw,1,inm); //nb sol
-+        if(iswp) binch=MMG_swapbin(binch);
-+        if(binch!=1) {
-+          fprintf(stdout,"SEVERAL SOLUTION => IGNORED : %d\n",type);
-+          return(1);
-+        }
-+        fread(&btyp,sw,1,inm); //typsol
-+        if(iswp) btyp=MMG_swapbin(btyp);
-+        posnp = ftell(inm);
-+        break;
-       } else {
--	fread(&bpos,sw,1,inm); //Pos
--	if(iswp) bpos=MMG_swapbin(bpos);
--	rewind(inm);
--	fseek(inm,bpos,SEEK_SET);
--      }
--    }
--
--  }
-+        fread(&bpos,sw,1,inm); //Pos 
-+        if(iswp) bpos=MMG_swapbin(bpos);
-+        rewind(inm);
-+        fseek(inm,bpos,SEEK_SET);        
-+      } 
-+    }            
++     double     tmp , *dsol ;       
++    int         binch,bdim,iswp;
++    int         k,i,isol,type,bin,dim,btyp,bpos;
++    long        posnp;
++    char        *ptr,data[128],chaine[128];
++    if( ! dataff->sol){
++	fprintf(stdout,"  ** MISSING DATA metrix ff \n");
++	return(1);
++    }
++    dsol = dataff->sol;
++    dataff->sol=0;// used 
++    
++
++    btyp = (dataff->typesol== 6)  ?  3: dataff->typesol ;
++    sol->np= dataff->np;
++    
++    if ( !sol->np ) {
++	fprintf(stdout,"  ** MISSING DATA zz\n");
++	return(1);
++    }
++    
++    if ( btyp!= 1 && btyp!=3 ) {
++      fprintf(stdout,"  ** DATA IGNORED (ff) btyp=%d\n",btyp);
++	sol->np = 0;
++	return(1);
++    }
++    
++    sol->offset = (btyp==1) ? 1 : 6;
++    
++    if ( abs(MMG_imprim) > 5 )
++	fprintf(stdout,"  -- READING DATA FILE(ff) %s\n",data);
++    
++    if ( !sol->np ) {
++	fprintf(stdout,"  ** MISSING DATA  no metrix  \n");
++	return(0);
++    }
++    sol->npfixe = sol->np;
++    sol->npmax  = npmax;
++    if ( !MMG_zaldy3(sol) )  return(0);
++    
++    /* read mesh solutions */
++    sol->npfixe = sol->np;
++ 
++    for (k=1; k<=sol->np; k++) {
++	isol = (k-1) * sol->offset + 1;
++	    for (i=0; i<sol->offset; i++) 		     
++		    sol->met[isol + i] = *dsol++;
++
++    }
++    
++    if ( abs(MMG_imprim) > 3 )
++	fprintf(stdout,"     NUMBER OF GIVEN DATA       %8d\n",sol->npfixe);
++    
++ 
++    return(1);  
++
++}
++/* load solution (metric) */
++int MMG_loadVectff(pMesh mesh,char *filename,int npmax,DataFF *dataff) {
++  
++      
++    pDispl       pd;
++    int         binch,bdim,iswp;
++    int         k,i,type,bin,dim,btyp,bpos,iadr;
++    long        posnp;
++    char        *ptr,data[128],chaine[128];
++    double *fsol = dataff->mov;
++    dataff->mov=0;// used 
 +    
-+  }       
-   if ( !sol->np ) {
--    fprintf(stdout,"  ** MISSING DATA\n");
-+    fprintf(stdout,"  ** MISSING DATA ss\n");
-     return(1);
-   }
- 
-   if ( btyp!= 1 && btyp!=3 ) {
--    fprintf(stdout,"  ** DATA IGNORED\n");
-+    fprintf(stdout,"  ** DATA IGNORED %d\n",btyp);
-     sol->np = 0;
-     return(1);
-   }
++    pd = mesh->disp;
++    pd->np =mesh->np ;
++ 
++       if ( !pd->np || !fsol  ) {
++	 fprintf(stdout,"  ** MISSING DATA dep ff %d %p\n",pd->np, fsol);
++	return(0);
++    }
++   
++    
++    if ( abs(mesh->info.imprim) > 5 )
++	fprintf(stdout,"  -- COPY DATA form ff interface  %s\n",data);
++    
++    /* read mesh solutions */
++    for (k=1; k<=pd->np; k++) {
++	iadr = (k - 1) * 3 + 1;
++	
++	    for (i=0; i<3; i++) {
++		    pd->mv[iadr + i] =  *fsol++;
++		}
++	    } 
++           
++    
++    
++    if ( abs(mesh->info.imprim) > 3 )
++	fprintf(stdout,"     NUMBER OF GIVEN DATA       %8d\n",pd->np);
++       return(1);
++  
++    
++}
++int MMG_saveMeshff(pMesh mesh,char *filename,DataFF *dataff) {  
++    
++    pPoint       	   ppt;
++    pTetra           pt;
++    pTria            pt1;
++    int j,k,np,nc,k0;
++    int data[10],ldata=10;
++    int kn[10];
++    np = 0; 
++    nc = 0;
++    // compress vertex ... fist case ... 
++    for (k=1; k<=mesh->np; k++) {
++      ppt = &mesh->point[k];
++      if ( ppt->tag & M_UNUSED )  continue;  
++      ppt->tmp = ++np;  
++      /*      if ( ppt->geom & M_CORNER )  cor[nc++] = ppt->tmp; */
++    }
++   
++    /*   seacrch vertex not in tet ???? */
++    {
++        int kk=0,npp=np;
++       for (k=1; k<=mesh->np; k++)
++       {
++            ppt = &mesh->point[k];
++           if ((ppt->tag & M_UNUSED )) ppt->tmp =-2;
++           else ppt->tmp =-1;
++
++       }
++       for ( k=1; k<=mesh->ne; k++)
++	{
++            pt = &mesh->tetra[k];
++            if ( !pt->v[0] )  continue;
++            k0++;
++            for(j=0;j<4;++j)
++              mesh->point[pt->v[j]].tmp=0;
++	}
++        np=0;
++        for (k=1; k<=mesh->np; k++)
++	{
++            ppt = &mesh->point[k];
++            
++            if ( ppt->tmp ==0) 
++               ppt->tmp = ++np; 
++            else
++            {
++                
++            if (ppt->tmp==-1)
++	    {
++                kk++;
++                ppt->tag  |= M_UNUSED;
++	    }
++                ppt->tmp=0;
++            }
++	}
++        if(kk) printf(" mmg3d: Strange nb of point %d not in tet is not zero (correct by FH)!\n" , kk);
++      
++    }
++    
++    mesh->nt=0;
++    if(! MMG_markBdry(mesh)) 
++      mesh->nt=0;
++    data[ff_id_vertex]=np ;
++    //data[ff_id_seg]=ned ;
++    data[ff_id_tria]=mesh->nt ;
++    int ne=0;
++    for ( k=1; k<=mesh->ne; k++) 
++      {
++	pt = &mesh->tetra[k];
++	if ( !pt->v[0] )  continue;  
++	ne++; 
++      }
++    
++    data[ff_id_tet]=ne  ;
++    printf(" mmg3d:  nbp = %d, nb tet %d\n",np,ne);
++    //data[ff_id_hex]=nhex;
++    //data[ff_id_prism]=npris; 
++    //data[ff_id_quad]=nq;
++    // data[ff_id_corner]=ncor;
++    
++    dataff->set_mesh(dataff,data,10);
++    
++    
++    for ( k=1; k<=mesh->np; k++) 
++      {
++	ppt = &mesh->point[k];
++	if ( ! ppt->tmp   )  continue;
++	dataff->set_v(dataff, ppt->tmp,ppt->c,ppt->ref);	    
++      }
++    
++    
++    for (k=1; k<=mesh->nt; k++) 
++      {
++	pt1 = &mesh->tria[k];
++	for(j=0;j<3;++j)
++	  kn[j] = mesh->point[pt1->v[j]].tmp;
++	dataff->set_elmt(dataff,ff_id_tria,k,kn,pt1->ref);
++	
++      }  
++    k0=0;
++    for ( k=1; k<=mesh->ne; k++) 
++      {
++	
++	pt = &mesh->tetra[k];
++	if ( !pt->v[0] )  continue;  
++	k0++;
++	for(j=0;j<4;++j)
++	  kn[j] = mesh->point[pt->v[j]].tmp;
++	dataff->set_elmt(dataff,ff_id_tet,k0,kn,pt->ref);
++	
++    }  
++    dataff->end_mesh(dataff);
++    return 1; 
++}
++int MMG_saveSolff (pMesh mesh,pSol sol,char *filename,DataFF *dataff) {
++  return 1; 
++}
++/*save the node speed : coornew-coorold/dt*/
++int MMG_saveVectff(pMesh mesh,char *filename,DataFF *dataff) {
++   return 1; 
++}
+ /* read mesh data */
+-int MMG_loadMesh(pMesh mesh,char *filename) {
++int MMG_loadMesh(pMesh mesh,char *filename,void *dataff) {  
+   FILE*            inm;
+   Hedge            hed,hed2;
+   pPoint           ppt;
+   pTetra           pt;
+   pHexa            ph,listhexa;
+   pTria            pt1;
+-  int              k,dim,ref,bin,bpos,i,tmp;
+-  int              *adjahex;
++  int              k,dim,ref,bin,bpos,i,tmp;  
++  int              *adjahex; 
+   long             posnp,posnt,posne,posnhex,posnpris,posncor,posned,posnq;
+   char            *ptr,data[128],chaine[128];
+   int              nhex,npris,netmp,ncor,ned,nq;
+-  int              p0,p1,p2,p3,p4,p5,p6,p7;
+-  int              binch,bdim,iswp,nu1,nu2,nimp,ne,nbado;
+-  float            fc;
+-  double           volhex,volref;
++  int              p0,p1,p2,p3,p4,p5,p6,p7;  
++  int              binch,bdim,iswp,nu1,nu2,nimp,ne,nbado;       
++  float            fc; 
++  double           volhex,volref;  
+   int              iadr,reorient;
 -
++  if(dataff)
++    return MMG_loadMeshff( mesh,filename,(DataFF*) dataff);
 +  
-   sol->offset = (btyp==1) ? 1 : 6;
- 
-   if ( abs(MMG_imprim) > 5 )
-     fprintf(stdout,"  -- READING DATA FILE %s\n",data);
- 
-   if ( !sol->np ) {
--    fprintf(stdout,"  ** MISSING DATA\n");
-+    fprintf(stdout,"  ** MISSING DATA xx\n");
-     return(0);
-   }
-   sol->npfixe = sol->np;
-@@ -742,31 +1133,31 @@
-   /* read mesh solutions */
-   sol->npfixe = sol->np;
-   rewind(inm);
--  fseek(inm,posnp,SEEK_SET);
-+  fseek(inm,posnp,SEEK_SET);  
-   for (k=1; k<=sol->np; k++) {
-     isol = (k-1) * sol->offset + 1;
--    if (sol->ver == 1) {
-+    if (sol->ver == 1) { 
-       for (i=0; i<sol->offset; i++) {
--	if(!bin){
--	  fscanf(inm,"%f",&fsol);
--	  sol->met[isol + i] = (double) fsol;
--	} else {
--	  fread(&fsol,sw,1,inm);
--	  if(iswp) fsol=MMG_swapf(fsol);
--	  sol->met[isol + i] = (double) fsol;
--	}
--      }
-+        if(!bin){
-+          fscanf(inm,"%f",&fsol);    
-+          sol->met[isol + i] = (double) fsol;
-+        } else {
-+          fread(&fsol,sw,1,inm);             
-+          if(iswp) fsol=MMG_swapf(fsol);
-+          sol->met[isol + i] = (double) fsol;
-+        }
-+      } 
-     } else {
-       for (i=0; i<sol->offset; i++) {
--	if(!bin){
--	  fscanf(inm,"%lf",&sol->met[isol + i]);
-+        if(!bin){
-+          fscanf(inm,"%lf",&sol->met[isol + i]); 
- 
--	} else {
--	  fread(&sol->met[isol + i],sd,1,inm);
--	  if(iswp) sol->met[isol + i]=MMG_swapd(sol->met[isol + i]);
--	}
--      }
--    }
-+        } else {
-+          fread(&sol->met[isol + i],sd,1,inm);       
-+          if(iswp) sol->met[isol + i]=MMG_swapd(sol->met[isol + i]);
-+        } 
-+      } 
-+    }             
-     /* MMG_swap data */
-     if ( sol->offset == 6 ) {
-       tmp                = sol->met[isol + 2];
-@@ -778,13 +1169,13 @@
-   if ( abs(MMG_imprim) > 3 )
-     fprintf(stdout,"     NUMBER OF GIVEN DATA       %8d\n",sol->npfixe);
- 
--  fclose(inm);
--  return(1);
-+  fclose(inm);   
-+  return(1);  
- }
- 
  
--int MMG_loadVect(pMesh mesh,char *filename,int npmax) {
--  FILE       *inm;
-+int MMG_loadVect(pMesh mesh,char *filename,int npmax,void *dataff) {
-+  FILE       *inm;   
-   pDispl       pd;
-   float       fsol;
-   int         binch,bdim,iswp;
-@@ -792,10 +1183,13 @@
-   long        posnp;
-   char        *ptr,data[128],chaine[128];
- 
--  pd = mesh->disp;
-+  if(dataff) 
-+      return MMG_loadVectff( mesh, filename,npmax,(DataFF*) dataff);
- 
--  posnp = 0;
--  bin   = 0;
-+  pd = mesh->disp;
+   posnp = posnt = posne = posnhex = posnpris = 0;
+   netmp = ncor = ned = 0;
+   bin = 0;
+   iswp = 0;
+-  mesh->np = mesh->nt = mesh->ne = mesh->ncor = 0;
++  mesh->np = mesh->nt = mesh->ne = mesh->ncor = 0; 
+   npris = nhex = nq = 0;
+-
 +  
-+  posnp = 0; 
-+  bin   = 0; 
-   iswp  = 0;
- 
    strcpy(data,filename);
-@@ -815,76 +1209,76 @@
+-  ptr = strstr(data,".mesh");
++  ptr = strstr(data,".mesh");  
+   if ( !ptr ) {
+     strcat(data,".meshb");
+     if( !(inm = fopen(data,"rb")) ) {
+@@ -136,8 +569,8 @@
+       *ptr = '\0';
+       strcat(data,".mesh");
+       if( !(inm = fopen(data,"r")) ) {
+-	fprintf(stderr,"  ** %s  NOT FOUND.\n",data);
+-	return(0);
++        fprintf(stderr,"  ** %s  NOT FOUND.\n",data);
++        return(0);
+       }
+     } else {
+       bin = 1;
+@@ -147,194 +580,194 @@
+     ptr = strstr(data,".meshb");
+     if( !ptr ) {
+       if( !(inm = fopen(data,"r")) ) {
+-	fprintf(stderr,"  ** %s  NOT FOUND.\n",data);
+-	return(0);
+-      }
++        fprintf(stderr,"  ** %s  NOT FOUND.\n",data);
++        return(0);
++      }      
+     } else {
+       bin = 1;
+       if( !(inm = fopen(data,"rb")) ) {
+-	fprintf(stderr,"  ** %s  NOT FOUND.\n",data);
+-	return(0);
++        fprintf(stderr,"  ** %s  NOT FOUND.\n",data);
++        return(0);
+       }
+-
+-    }
++      
++    }  
    }
-   fprintf(stdout,"  %%%% %s OPENED\n",data);
  
--
--  if(!bin) {
-+   
-+  if(!bin) {   
-     strcpy(chaine,"DDD");
+   fprintf(stdout,"  %%%% %s OPENED\n",data);
+   if (!bin) {
+-    strcpy(chaine,"D");
 -    while(fscanf(inm,"%s",&chaine[0])!=EOF && strncmp(chaine,"End",strlen("End")) ) {
++    strcpy(chaine,"D");     
 +    while(fscanf(inm,"%s",&chaine[0])!=EOF && strncmp(chaine,"End",strlen("End")) ) { 
-       if(!strncmp(chaine,"Dimension",strlen("Dimension"))) {
+       if(!strncmp(chaine,"MeshVersionFormatted",strlen("MeshVersionFormatted"))) {
+-	fscanf(inm,"%d",&mesh->ver);
+-	continue;
++          fscanf(inm,"%d",&mesh->ver);
++          continue;
+       } else if(!strncmp(chaine,"Dimension",strlen("Dimension"))) {
 -	fscanf(inm,"%d",&dim);
 -	if(dim!=3) {
--	  fprintf(stdout,"BAD SOL DIMENSION : %d\n",dim);
--	  return(1);
+-	  fprintf(stdout,"BAD DIMENSION : %d\n",dim);
+-	  return(0);
 -	}
 -	continue;
 +          fscanf(inm,"%d",&dim);
 +          if(dim!=3) {
-+            fprintf(stdout,"BAD SOL DIMENSION : %d\n",dim); 
-+            return(1);
++            fprintf(stdout,"BAD DIMENSION : %d\n",dim);
++            return(0);
 +          }
 +          continue;
-       } else if(!strncmp(chaine,"SolAtVertices",strlen("SolAtVertices"))) {
--	fscanf(inm,"%d",&pd->np);
--	fscanf(inm,"%d",&type);
--	if(type!=1) {
--	  fprintf(stdout,"SEVERAL SOLUTION => IGNORED : %d\n",type);
--	  return(1);
--	}
--	fscanf(inm,"%d",&btyp);
+       } else if(!strncmp(chaine,"Vertices",strlen("Vertices"))) {
+-	fscanf(inm,"%d",&mesh->np);
 -	posnp = ftell(inm);
--	break;
+-	continue;
++        fscanf(inm,"%d",&mesh->np); 
++        posnp = ftell(inm);
++        continue;
+       } else if(!strncmp(chaine,"Triangles",strlen("Triangles"))) {
+-	fscanf(inm,"%d",&mesh->nt);
+-	posnt = ftell(inm);
+-	continue;
++        fscanf(inm,"%d",&mesh->nt); 
++        posnt = ftell(inm);
++        continue;
+       } else if(!strncmp(chaine,"Tetrahedra",strlen("Tetrahedra"))) {
+-	fscanf(inm,"%d",&mesh->ne);
+-	netmp = mesh->ne;
+-	posne = ftell(inm);
+-	continue;
+-      } else if(!strncmp(chaine,"Hexahedra",strlen("Hexahedra"))) {
+-	assert(abs(mesh->info.option)==10);
+-	fscanf(inm,"%d",&nhex);
+-	//nhex=0;
+-	posnhex = ftell(inm);
+-	continue;
+-      } else if(!strncmp(chaine,"Pentahedra",strlen("Pentahedra"))) {
+-	assert(abs(mesh->info.option)==10);
+-	fscanf(inm,"%d",&npris);
+-	//npris=0;
+-	posnpris = ftell(inm);
+-	continue;
+-      } else if(!strncmp(chaine,"Corners",strlen("Corners"))) {
+-	fscanf(inm,"%d",&ncor);
+-	posncor = ftell(inm);
+-	continue;
+-      } else if(!strncmp(chaine,"Edges",strlen("Edges"))) {
+-	fscanf(inm,"%d",&ned);
+-	posned = ftell(inm);
+-	continue;
+-      } else if(abs(mesh->info.option)==10 && !strncmp(chaine,"Quadrilaterals",strlen("Quadrilaterals"))) {
+-	fscanf(inm,"%d",&nq);
+-	posnq = ftell(inm);
+-	continue;
 -      }
 -    }
--  } else {
--    fread(&pd->ver,sw,1,inm);
++        fscanf(inm,"%d",&mesh->ne); 
++        netmp = mesh->ne;
++        posne = ftell(inm);
++        continue;
++      } else if(!strncmp(chaine,"Hexahedra",strlen("Hexahedra"))) { 
++        assert(abs(mesh->info.option)==10);  
++        fscanf(inm,"%d",&nhex); 
++				//nhex=0;
++        posnhex = ftell(inm);
++        continue;
++      } else if(!strncmp(chaine,"Pentahedra",strlen("Pentahedra"))) { 
++        assert(abs(mesh->info.option)==10); 
++        fscanf(inm,"%d",&npris);
++				//npris=0;
++        posnpris = ftell(inm);
++        continue;
++      } else if(!strncmp(chaine,"Corners",strlen("Corners"))) { 
++        fscanf(inm,"%d",&ncor); 
++        posncor = ftell(inm);
++        continue;
++      } else if(!strncmp(chaine,"Edges",strlen("Edges"))) { 
++	      fscanf(inm,"%d",&ned); 
++	      posned = ftell(inm);
++	      continue;
++	    } else if(abs(mesh->info.option)==10 && !strncmp(chaine,"Quadrilaterals",strlen("Quadrilaterals"))) {
++		    fscanf(inm,"%d",&nq); 
++		    posnq = ftell(inm);
++		    continue;
++		  }
++    }  
+   } else {
+     bdim = 0;
+     fread(&mesh->ver,sw,1,inm);
 -    iswp=0;
--    if(pd->ver==16777216) iswp=1;
-+        fscanf(inm,"%d",&pd->np); 
-+        fscanf(inm,"%d",&type); 
-+        if(type!=1) {
-+          fprintf(stdout,"SEVERAL SOLUTION => IGNORED : %d\n",type);
-+          return(1);
-+        }
-+        fscanf(inm,"%d",&btyp);
-+        posnp = ftell(inm);
-+        break;
-+      } 
-+    }            
-+  } else {     
-+    fread(&pd->ver,sw,1,inm); 
+-    if(mesh->ver==16777216)
+-      iswp=1;
 +    iswp=0;   
-+    if(pd->ver==16777216) iswp=1;    
-     else if(pd->ver!=1) {
++    if(mesh->ver==16777216) 
++      iswp=1;    
+     else if(mesh->ver!=1) {
        fprintf(stdout,"BAD FILE ENCODING\n");
 -    }
--    fread(&pd->ver,sw,1,inm);
--    if(iswp) pd->ver = MMG_swapbin(pd->ver);
-+    } 
-+    fread(&pd->ver,sw,1,inm); 
-+    if(iswp) pd->ver = MMG_swapbin(pd->ver); 
-     while(fread(&binch,sw,1,inm)!=EOF && binch!=54 ) {
+-    fread(&mesh->ver,sw,1,inm);
+-    if(iswp) mesh->ver = MMG_swapbin(mesh->ver);
+-    while(fread(&binch,sw,1,inm)!=0 && binch!=54 ) {
 -      if(iswp) binch=MMG_swapbin(binch);
 -      if(binch==54) break;
++    } 
++    fread(&mesh->ver,sw,1,inm); 
++    if(iswp) mesh->ver = MMG_swapbin(mesh->ver); 
++    while(fread(&binch,sw,1,inm)!=0 && binch!=54 ) {  
 +      if(iswp) binch=MMG_swapbin(binch);      
 +      if(binch==54) break;  
-       if(binch==3) {  //Dimension
--	fread(&bdim,sw,1,inm);  //Pos=>20
+       if(!bdim && binch==3) {  //Dimension
+-	fread(&bdim,sw,1,inm);  //NulPos=>20
 -	if(iswp) bdim=MMG_swapbin(bdim);
 -	fread(&bdim,sw,1,inm);
 -	if(iswp) bdim=MMG_swapbin(bdim);
@@ -1727,1645 +1638,1777 @@ diff -r -u mmg3d4/build/sources/inout.c mmg3d4-new/build/sources/inout.c
 -	  return(1);
 -	}
 -	continue;
-+        fread(&bdim,sw,1,inm);  //Pos=>20
-+        if(iswp) bdim=MMG_swapbin(bdim);      
-+        fread(&bdim,sw,1,inm);
-+        if(iswp) bdim=MMG_swapbin(bdim);      
-+        if(bdim!=3) {
-+          fprintf(stdout,"BAD SOL DIMENSION : %d\n",dim);
-+          exit(0);
-+          return(1);
-+        }
-+        continue;
-       } else if(binch==62) {  //SolAtVertices
--	fread(&binch,sw,1,inm); //Pos
--	if(iswp) binch=MMG_swapbin(binch);
--	fread(&pd->np,sw,1,inm);
--	if(iswp) pd->np=MMG_swapbin(pd->np);
--	fread(&binch,sw,1,inm); //nb sol
--	if(iswp) binch=MMG_swapbin(binch);
--	if(binch!=1) {
--	  fprintf(stdout,"SEVERAL SOLUTION => IGNORED : %d\n",type);
--	  return(1);
--	}
--	fread(&btyp,sw,1,inm); //typsol
--	if(iswp) btyp=MMG_swapbin(btyp);
--	posnp = ftell(inm);
--	break;
-+        fread(&binch,sw,1,inm); //Pos
-+        if(iswp) binch=MMG_swapbin(binch);      
-+        fread(&pd->np,sw,1,inm); 
-+        if(iswp) pd->np=MMG_swapbin(pd->np);      
-+        fread(&binch,sw,1,inm); //nb sol
-+        if(iswp) binch=MMG_swapbin(binch);      
-+        if(binch!=1) {
-+          fprintf(stdout,"SEVERAL SOLUTION => IGNORED : %d\n",type);
-+          return(1);
-+        }
-+        fread(&btyp,sw,1,inm); //typsol
-+        if(iswp) btyp=MMG_swapbin(btyp);      
-+        posnp = ftell(inm);
-+        break;
-       } else {
--	fread(&bpos,sw,1,inm); //Pos
++        fread(&bdim,sw,1,inm);  //NulPos=>20
++        if(iswp) bdim=MMG_swapbin(bdim);
++        fread(&bdim,sw,1,inm);  
++        if(iswp) bdim=MMG_swapbin(bdim);
++        if(bdim!=3) {
++          fprintf(stdout,"BAD SOL DIMENSION : %d\n",dim);
++          exit(0);
++          return(1);
++        }
++        continue;
+       } else if(!mesh->np && binch==4) {  //Vertices
+-	fread(&bpos,sw,1,inm); //NulPos
+-	if(iswp) bpos=MMG_swapbin(bpos);
+-	fread(&mesh->np,sw,1,inm);
+-	if(iswp) mesh->np=MMG_swapbin(mesh->np);
+-	posnp = ftell(inm);
+-	rewind(inm);
+-	fseek(inm,bpos,SEEK_SET);
+-	continue;
++        fread(&bpos,sw,1,inm); //NulPos 
++        if(iswp) bpos=MMG_swapbin(bpos);
++        fread(&mesh->np,sw,1,inm); 
++        if(iswp) mesh->np=MMG_swapbin(mesh->np);
++        posnp = ftell(inm);     
++        rewind(inm);
++        fseek(inm,bpos,SEEK_SET);        
++        continue;
+       }  else if(!mesh->nt && binch==6) {//Triangles
+-	fread(&bpos,sw,1,inm); //NulPos
+-	if(iswp) bpos=MMG_swapbin(bpos);
+-	fread(&mesh->nt,sw,1,inm);
+-	if(iswp) mesh->nt=MMG_swapbin(mesh->nt);
+-	posnt = ftell(inm);
+-	rewind(inm);
+-	fseek(inm,bpos,SEEK_SET);
+-	continue;
+-      } else if(!mesh->ne && binch==8) {
+-	fread(&bpos,sw,1,inm); //NulPos
+-	if(iswp) bpos=MMG_swapbin(bpos);
+-	fread(&mesh->ne,sw,1,inm);
+-	if(iswp) mesh->ne=MMG_swapbin(mesh->ne);
+-	netmp = mesh->ne;
+-	posne = ftell(inm);
+-	rewind(inm);
+-	fseek(inm,bpos,SEEK_SET);
+-	continue;
+-      } else if(!nhex && binch==10) {
+-	assert(abs(mesh->info.option)==10);
+-	fread(&bpos,sw,1,inm); //NulPos
+-	if(iswp) bpos=MMG_swapbin(bpos);
+-	fread(&nhex,sw,1,inm);
+-	if(iswp) nhex=MMG_swapbin(nhex);
+-	posnhex = ftell(inm);
+-	rewind(inm);
+-	fseek(inm,bpos,SEEK_SET);
+-	continue;
+-      } else if(!npris && binch==9) {
+-	assert(abs(mesh->info.option)==10);
+-	fread(&bpos,sw,1,inm); //NulPos
+-	if(iswp) bpos=MMG_swapbin(bpos);
+-	fread(&npris,sw,1,inm);
+-	if(iswp) npris=MMG_swapbin(npris);
+-	posnpris = ftell(inm);
+-	rewind(inm);
+-	fseek(inm,bpos,SEEK_SET);
+-	continue;
+-      } else if(!ncor && binch==13) {
+-	fread(&bpos,sw,1,inm); //NulPos
+-	if(iswp) bpos=MMG_swapbin(bpos);
+-	fread(&ncor,sw,1,inm);
+-	if(iswp) ncor=MMG_swapbin(ncor);
+-	posncor = ftell(inm);
+-	rewind(inm);
+-	fseek(inm,bpos,SEEK_SET);
+-	continue;
+-      } else if(!ned && binch==5) { //Edges
+-	fread(&bpos,sw,1,inm); //NulPos
+-	if(iswp) bpos=MMG_swapbin(bpos);
+-	fread(&ned,sw,1,inm);
+-	if(iswp) ned=MMG_swapbin(ned);
+-	posned = ftell(inm);
+-	rewind(inm);
+-	fseek(inm,bpos,SEEK_SET);
+-	continue;
+-      } else {
+-	//printf("on traite ? %d\n",binch);
+-	fread(&bpos,sw,1,inm); //NulPos
 -	if(iswp) bpos=MMG_swapbin(bpos);
+-	//printf("on avance... Nulpos %d\n",bpos);
 -	rewind(inm);
 -	fseek(inm,bpos,SEEK_SET);
 -      }
 -    }
 -
--  }
-+        fread(&bpos,sw,1,inm); //Pos 
-+        if(iswp) bpos=MMG_swapbin(bpos);      
++        fread(&bpos,sw,1,inm); //NulPos 
++        if(iswp) bpos=MMG_swapbin(bpos);
++        fread(&mesh->nt,sw,1,inm); 
++        if(iswp) mesh->nt=MMG_swapbin(mesh->nt);
++        posnt = ftell(inm); 
 +        rewind(inm);
 +        fseek(inm,bpos,SEEK_SET);        
-+      } 
++        continue;
++       } else if(!mesh->ne && binch==8) {  
++         fread(&bpos,sw,1,inm); //NulPos 
++         if(iswp) bpos=MMG_swapbin(bpos);
++         fread(&mesh->ne,sw,1,inm); 
++         if(iswp) mesh->ne=MMG_swapbin(mesh->ne);
++         netmp = mesh->ne;
++         posne = ftell(inm);
++         rewind(inm);
++         fseek(inm,bpos,SEEK_SET);        
++         continue;
++       } else if(!nhex && binch==10) { 
++         assert(abs(mesh->info.option)==10);
++         fread(&bpos,sw,1,inm); //NulPos 
++         if(iswp) bpos=MMG_swapbin(bpos);
++         fread(&nhex,sw,1,inm); 
++         if(iswp) nhex=MMG_swapbin(nhex);
++         posnhex = ftell(inm);
++         rewind(inm);
++         fseek(inm,bpos,SEEK_SET);        
++         continue;
++       } else if(!npris && binch==9) { 
++         assert(abs(mesh->info.option)==10);
++         fread(&bpos,sw,1,inm); //NulPos 
++         if(iswp) bpos=MMG_swapbin(bpos);
++         fread(&npris,sw,1,inm); 
++         if(iswp) npris=MMG_swapbin(npris);
++         posnpris = ftell(inm);
++         rewind(inm);
++         fseek(inm,bpos,SEEK_SET);        
++         continue;
++       } else if(!ncor && binch==13) { 
++         fread(&bpos,sw,1,inm); //NulPos 
++         if(iswp) bpos=MMG_swapbin(bpos);
++         fread(&ncor,sw,1,inm);          
++         if(iswp) ncor=MMG_swapbin(ncor);
++         posncor = ftell(inm);
++         rewind(inm);
++         fseek(inm,bpos,SEEK_SET);        
++         continue;
++        } else if(!ned && binch==5) { //Edges
++	       fread(&bpos,sw,1,inm); //NulPos 
++	       if(iswp) bpos=MMG_swapbin(bpos);
++	       fread(&ned,sw,1,inm); 
++	       if(iswp) ned=MMG_swapbin(ned);
++	       posned = ftell(inm);
++	       rewind(inm);
++	       fseek(inm,bpos,SEEK_SET);        
++	       continue;
++	      } else {
++         //printf("on traite ? %d\n",binch);
++         fread(&bpos,sw,1,inm); //NulPos 
++         if(iswp) bpos=MMG_swapbin(bpos);
++         //printf("on avance... Nulpos %d\n",bpos);         
++         rewind(inm);
++         fseek(inm,bpos,SEEK_SET);        
++       }     
 +    }            
 +    
-+  }       
-   if ( !pd->np ) {
-     fprintf(stdout,"  ** MISSING DATA\n");
-     return(0);
-@@ -895,7 +1289,7 @@
    }
  
-   if ( btyp != 2 ) {
--    fprintf(stdout,"  ** DATA IGNORED\n");
-+    fprintf(stdout,"  ** DATA IGNORED %d !=2\n",btyp);
-     return(0);
+   if ( abs(mesh->info.option)==10 ) {
+-    fprintf(stdout,"  -- READING %8d HEXA %8d PRISMS\n",nhex,npris);
+-    if(!mesh->ne) netmp = 0;
+-    mesh->ne += 6*nhex + 3*npris;
++    fprintf(stdout,"  -- READING %8d HEXA %8d PRISMS\n",nhex,npris);  
++    if(!mesh->ne) netmp = 0;  
++    mesh->ne += 6*nhex + 3*npris; 
    }
  
-@@ -907,47 +1301,50 @@
+   if ( abs(mesh->info.imprim) > 5 )
+     fprintf(stdout,"  -- READING DATA FILE %s\n",data);
+ 
+   if ( !mesh->np || !mesh->ne ) {
+-    fprintf(stdout,"  ** MISSING DATA\n");
++    fprintf(stdout,"  ** MISSING DAT qqA\n");
+     return(0);
+   }
+-  if(abs(mesh->info.option)==10) { //allocation
++	if(abs(mesh->info.option)==10) { //allocation
+     listhexa  = (pHexa)M_calloc(nhex+1,sizeof(Hexa),"allochexa");
+-    assert(listhexa);
+-    adjahex = (int*)M_calloc(6*nhex+7,sizeof(int),"allocadjhexa");
+-    assert(adjahex);
+-  }
++	  assert(listhexa);     
++	  adjahex = (int*)M_calloc(6*nhex+7,sizeof(int),"allocadjhexa");
++	  assert(adjahex);                             
++  }  
+   if ( !MMG_zaldy(mesh) )  return(0);
+   /* read mesh vertices */
+   mesh->npfixe = mesh->np;
+@@ -342,35 +775,35 @@
    fseek(inm,posnp,SEEK_SET);
-   for (k=1; k<=pd->np; k++) {
-     iadr = (k - 1) * 3 + 1;
--    if (pd->ver < 2) {
-+    if (pd->ver < 2) { 
-       for (i=0; i<3; i++) {
--	if(!bin){
--	  fscanf(inm,"%f",&fsol);
--	  pd->mv[iadr + i] = (double) fsol;
--	} else {
--	  fread(&fsol,sw,1,inm);
--	  if(iswp) fsol=MMG_swapf(fsol);
--	  pd->mv[iadr + i] = (double) fsol;
--	}
--      }
-+        if(!bin){
-+          fscanf(inm,"%f",&fsol); 
-+          pd->mv[iadr + i] = (double) fsol;
-+        } else {
-+          fread(&fsol,sw,1,inm);             
-+          if(iswp) fsol=MMG_swapf(fsol);      
-+          pd->mv[iadr + i] = (double) fsol;
-+        }
-+      } 
-     } else {
-       for (i=0; i<3; i++) {
--	if(!bin){
--	  fscanf(inm,"%lf",&pd->mv[iadr + i]);
--	} else {
--	  fread(&pd->mv[iadr + i],sd,1,inm);
--	  if(iswp) pd->mv[iadr + i]=MMG_swapd(pd->mv[iadr + i]);
+   for (k=1; k<=mesh->np; k++) {
+     ppt = &mesh->point[k];
+-    if (mesh->ver < 2) { /*float*/
++    if (mesh->ver < 2) { /*float*/ 
+       if (!bin) {
+-	for (i=0 ; i<3 ; i++) {
+-	  fscanf(inm,"%f",&fc);
+-	  ppt->c[i] = (double) fc;
 -	}
--      }
--    }
-+        if(!bin){
-+          fscanf(inm,"%lf",&pd->mv[iadr + i]); 
-+        } else {
-+          fread(&pd->mv[iadr + i],sd,1,inm);
-+          if(iswp) pd->mv[iadr + i]=MMG_swapd(pd->mv[iadr + i]);      
+-	fscanf(inm,"%d",&ppt->ref);
++        for (i=0 ; i<3 ; i++) {
++          fscanf(inm,"%f",&fc);
++          ppt->c[i] = (double) fc;
 +        } 
-+      } 
-+    }             
-   }
- 
-   if ( abs(mesh->info.imprim) > 3 )
-     fprintf(stdout,"     NUMBER OF GIVEN DATA       %8d\n",pd->np);
- 
--  fclose(inm);
-+  fclose(inm); 
-   return(1);
- }
- 
- 
- /* save mesh to disk */
--int MMG_saveMesh(pMesh mesh,char *filename) {
--  FILE*        inm;
--  Hedge                          hed;
-+int MMG_saveMesh(pMesh mesh,char *filename,void *dataff) {  
-+  FILE*        inm; 
-+	Hedge				 hed;
-   pPoint       ppt;
-   pTria        pt1;
-   pTetra       pt;
-   int          i,k,np,ne,nc,ned,*cor,*ed,ref,bin,bpos;
--  char        *ptr,data[128],chaine[128];
-+  char        *ptr,data[128],chaine[128]; 
-   int          binch,nu1,nu2;
-+  if(dataff) 
-+      return MMG_saveMeshff( mesh, filename,(DataFF*)  dataff);
-+
-   mesh->ver = 2; //double precision
-   bin = 0;
-   strcpy(data,filename);
-@@ -959,28 +1356,28 @@
-       *ptr = '\0';
-       strcat(data,".mesh");
-       if( !(inm = fopen(data,"w")) ) {
--	fprintf(stderr,"  ** UNABLE TO OPEN %s.\n",data);
--	return(0);
-+        fprintf(stderr,"  ** UNABLE TO OPEN %s.\n",data);
-+        return(0);
++        fscanf(inm,"%d",&ppt->ref);
+       } else {
+-	for (i=0 ; i<3 ; i++) {
+-	  fread(&fc,sw,1,inm);
+-	  if(iswp) fc=MMG_swapf(fc);
+-	  ppt->c[i] = (double) fc;
+-	}
+-	fread(&ppt->ref,sw,1,inm);
+-	if(iswp) ppt->ref=MMG_swapbin(ppt->ref);
++        for (i=0 ; i<3 ; i++) {
++          fread(&fc,sw,1,inm); 
++          if(iswp) fc=MMG_swapf(fc);    
++          ppt->c[i] = (double) fc;
++        }     
++        fread(&ppt->ref,sw,1,inm);         
++        if(iswp) ppt->ref=MMG_swapbin(ppt->ref);    
        }
      } else {
--      bin = 1;
-+      bin = 1;   
-     }
-   }
--  else {
-+  else { 
-     ptr = strstr(data,".meshb");
-     if( ptr ) bin = 1;
-     if( !(inm = fopen(data,"w")) ) {
-       fprintf(stderr,"  ** UNABLE TO OPEN %s.\n",data);
-       return(0);
+-      if (!bin)
+-	fscanf(inm,"%lf %lf %lf %d",&ppt->c[0],&ppt->c[1],&ppt->c[2],&ppt->ref);
++      if (!bin) 
++        fscanf(inm,"%lf %lf %lf %d",&ppt->c[0],&ppt->c[1],&ppt->c[2],&ppt->ref); 
+       else {
+-	for (i=0 ; i<3 ; i++) {
+-	  fread(&ppt->c[i],sd,1,inm);
+-	  if(iswp) ppt->c[i]=MMG_swapd(ppt->c[i]);
+-	}
+-	fread(&ppt->ref,sw,1,inm);
+-	if(iswp) ppt->ref=MMG_swapbin(ppt->ref);
+-      }
 -    }
-+    } 
+-    ppt->tag  = M_UNUSED;
++        for (i=0 ; i<3 ; i++) { 
++          fread(&ppt->c[i],sd,1,inm);
++          if(iswp) ppt->c[i]=MMG_swapd(ppt->c[i]); 
++        }   
++        fread(&ppt->ref,sw,1,inm);         
++        if(iswp) ppt->ref=MMG_swapbin(ppt->ref);    
++      }  
++    }             
++    ppt->tag  = M_UNUSED;    
    }
-   fprintf(stdout,"  %%%% %s OPENED\n",data);
  
-   /*entete fichier*/
-   if(!bin) {
--    strcpy(&chaine[0],"MeshVersionFormatted 2\n");
-+    strcpy(&chaine[0],"MeshVersionFormatted 2\n"); 
-     fprintf(inm,"%s",chaine);
--    strcpy(&chaine[0],"\n\nDimension 3\n");
-+    strcpy(&chaine[0],"\n\nDimension 3\n"); 
-     fprintf(inm,"%s ",chaine);
-   } else {
-     binch = 1; //MeshVersionFormatted
-@@ -993,33 +1390,38 @@
-     fwrite(&bpos,sw,1,inm);
-     binch = 3;
-     fwrite(&binch,sw,1,inm);
--
-+    
-   }
+   /* read mesh triangles */
+@@ -378,227 +811,226 @@
+   rewind(inm);
+   fseek(inm,posnt,SEEK_SET);
+   for (k=1; k<=mesh->nt; k++) {
+-    pt1 = &mesh->tria[k];
++    pt1 = &mesh->tria[k]; 
+     if (!bin)
+       fscanf(inm,"%d %d %d %d",&pt1->v[0],&pt1->v[1],&pt1->v[2],&pt1->ref);
+     else {
+-      for (i=0 ; i<3 ; i++) {
+-	fread(&pt1->v[i],sw,1,inm);
+-	if(iswp) pt1->v[i]=MMG_swapbin(pt1->v[i]);
+-      }
+-      fread(&pt1->ref,sw,1,inm);
+-      if(iswp) pt1->ref=MMG_swapbin(pt1->ref);
+-    }
+-  }
+-  /* read mesh quads (option 10)*/
+-  if(abs(mesh->info.option)==10) {
+-    fprintf(stdout,"     QUADS READING %d\n",nq);
++      for (i=0 ; i<3 ; i++) { 
++        fread(&pt1->v[i],sw,1,inm); 
++        if(iswp) pt1->v[i]=MMG_swapbin(pt1->v[i]);    
++      }
++      fread(&pt1->ref,sw,1,inm); 
++      if(iswp) pt1->ref=MMG_swapbin(pt1->ref);           
++    }  
++  }
++  /* read mesh quads (option 10)*/ 
++	if(abs(mesh->info.option)==10) { 
++		fprintf(stdout,"     QUADS READING %d\n",nq);
+     mesh->ntfixe += 4*nq;
  
-   /* compact vertices */
--  if(mesh->ncor) {
-+  if(mesh->ncor) {   
-     cor = (int*) M_calloc(mesh->ncor,sizeof(int),"MMG_savemesh");
--    assert(cor);
-+    assert(cor);   
-   }
--  if(mesh->ned) {
--    if ( !MMG_zaldy4(&hed,mesh->ned) ) {
--      if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EXPORT EDGES IGNORED\n");
--      mesh->ned = 0;
+     rewind(inm);
+     fseek(inm,posnq,SEEK_SET);
+     for (k=1; k<=nq; k++) {
+       if (!bin)
+-	fscanf(inm,"%d %d %d %d %d",&p0,&p1,&p2,&p3,&ref);
++        fscanf(inm,"%d %d %d %d %d",&p0,&p1,&p2,&p3,&ref);
+       else {
+-	fread(&p0,sw,1,inm);
+-	if(iswp) p0=MMG_swapbin(p0);
+-	fread(&p1,sw,1,inm);
+-	if(iswp) p1=MMG_swapbin(p1);
+-	fread(&p2,sw,1,inm);
+-	if(iswp) p2=MMG_swapbin(p2);
+-	fread(&p3,sw,1,inm);
+-	if(iswp) p3=MMG_swapbin(p3);
+-	fread(&pt1->ref,sw,1,inm);
+-	if(iswp) ref=MMG_swapbin(ref);
+-      }
++        fread(&p0,sw,1,inm); 
++        if(iswp) p0=MMG_swapbin(p0);    
++        fread(&p1,sw,1,inm); 
++        if(iswp) p1=MMG_swapbin(p1);    
++        fread(&p2,sw,1,inm); 
++        if(iswp) p2=MMG_swapbin(p2);    
++        fread(&p3,sw,1,inm); 
++        if(iswp) p3=MMG_swapbin(p3);    
++	      fread(&pt1->ref,sw,1,inm); 
++	      if(iswp) ref=MMG_swapbin(ref);           
++      } 
+       /*creation of 4 triangles per quads because we don't know how hexa will be cut*/
+-      pt1 = &mesh->tria[++mesh->nt];
+-      pt1->v[0] = p0;
+-      pt1->v[1] = p1;
+-      pt1->v[2] = p2;
+-      pt1->ref  = ref;
+-      pt1 = &mesh->tria[++mesh->nt];
+-      pt1->v[0] = p0;
+-      pt1->v[1] = p2;
+-      pt1->v[2] = p3;
+-      pt1->ref  = ref;
+-      pt1 = &mesh->tria[++mesh->nt];
+-      pt1->v[0] = p0;
+-      pt1->v[1] = p1;
+-      pt1->v[2] = p3;
+-      pt1->ref  = ref;
+-      pt1 = &mesh->tria[++mesh->nt];
+-      pt1->v[0] = p1;
+-      pt1->v[1] = p2;
+-      pt1->v[2] = p3;
+-      pt1->ref  = ref;
+-
 -    }
-+  if(mesh->ned) {   
-+	  if ( !MMG_zaldy4(&hed,mesh->ned) ) {
-+      if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EXPORT EDGES IGNORED\n"); 
-+			mesh->ned = 0;
+-  }
+-  /*read and store edges*/
+-  if (ned) {
+-    if ( !MMG_zaldy4(&hed,ned) ) {
+-      if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES IGNORED\n");
+-      ned = 0;
+-    }
+-    mesh->ned = ned;
++      pt1 = &mesh->tria[++mesh->nt]; 
++			pt1->v[0] = p0;
++			pt1->v[1] = p1;
++			pt1->v[2] = p2;
++			pt1->ref  = ref;
++      pt1 = &mesh->tria[++mesh->nt]; 
++			pt1->v[0] = p0;
++			pt1->v[1] = p2;
++			pt1->v[2] = p3;
++			pt1->ref  = ref;
++      pt1 = &mesh->tria[++mesh->nt]; 
++			pt1->v[0] = p0;
++			pt1->v[1] = p1;
++			pt1->v[2] = p3;
++			pt1->ref  = ref;
++      pt1 = &mesh->tria[++mesh->nt]; 
++			pt1->v[0] = p1;
++			pt1->v[1] = p2;
++			pt1->v[2] = p3;
++			pt1->ref  = ref;
++ 
++    }
++  }
++	/*read and store edges*/
++  if (ned) {         
++	  if ( !MMG_zaldy4(&hed,ned) ) {
++      if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EDGES IGNORED\n"); 
++			ned = 0;
 +    }   
-     ed = (int*)M_calloc(2*mesh->ned,sizeof(int),"MMG_savemesh");
--    assert(ed);
-+    assert(ed);   
-   }
--  np = 0;
-+  np = 0; 
-   nc = 0;
-   for (k=1; k<=mesh->np; k++) {
-     ppt = &mesh->point[k];
--    if ( ppt->tag & M_UNUSED )  continue;
--    ppt->tmp = ++np;
-+    if ( ppt->tag & M_UNUSED )  continue;  
-+		ppt->tmp = ++np;  
-     if ( ppt->geom & M_CORNER )  cor[nc++] = ppt->tmp;
-+  } 
-+  //assert(mesh->ncor==nc);
-+  if(mesh->ncor!=nc) {
-+    fprintf(stdout,"WARNING: some corners have been added or deleted\n");
-+    mesh->ncor = nc;
-   }
--  assert(mesh->ncor==nc);
-+
-   if(!bin) {
--    strcpy(&chaine[0],"\n\nVertices\n");
-+    strcpy(&chaine[0],"\n\nVertices\n"); 
-     fprintf(inm,"%s",chaine);
-     fprintf(inm,"%d\n",np);
-   } else {
-@@ -1027,27 +1429,27 @@
-     fwrite(&binch,sw,1,inm);
-     bpos += 12+(1+3*mesh->ver)*4*np; //NullPos
-     fwrite(&bpos,sw,1,inm);
--    fwrite(&np,sw,1,inm);
-+    fwrite(&np,sw,1,inm);    
-   }
-   for(k=1; k<=mesh->np; k++) {
-     ppt = &mesh->point[k];
--    if ( ppt->tag & M_UNUSED )  continue;
--    //if(ppt->tmp==52453) printf("point %d --> %d\n",ppt->tmp,k);
-+    if ( ppt->tag & M_UNUSED )  continue;  
-+		//if(ppt->tmp==52453) printf("point %d --> %d\n",ppt->tmp,k);
-     if(!bin) {
-       fprintf(inm,"%.15lg %.15lg %.15lg %d\n",ppt->c[0],ppt->c[1],ppt->c[2],ppt->ref);
-     } else {
--      fwrite((unsigned char*)&ppt->c[0],sd,1,inm);
--      fwrite((unsigned char*)&ppt->c[1],sd,1,inm);
--      fwrite((unsigned char*)&ppt->c[2],sd,1,inm);
--      fwrite((unsigned char*)&ppt->ref,sw,1,inm);
-+      fwrite((unsigned char*)&ppt->c[0],sd,1,inm);    
-+      fwrite((unsigned char*)&ppt->c[1],sd,1,inm);    
-+      fwrite((unsigned char*)&ppt->c[2],sd,1,inm);    
-+      fwrite((unsigned char*)&ppt->ref,sw,1,inm);    
++		mesh->ned = ned;
+     rewind(inm);
+-    fseek(inm,posned,SEEK_SET);
+-    for (k=1; k<=ned; k++) {
++    fseek(inm,posned,SEEK_SET); 
++    for (k=1; k<=ned; k++) { 
+       if (!bin)
+-	fscanf(inm,"%d %d %d",&nu1,&nu2,&ref);
++        fscanf(inm,"%d %d %d",&nu1,&nu2,&ref);
+       else {
+-	fread(&nu1,sw,1,inm);
+-	if(iswp) nu1=MMG_swapbin(nu1);
+-	fread(&nu2,sw,1,inm);
+-	if(iswp) nu2=MMG_swapbin(nu2);
+-	fread(&ref,sw,1,inm);
+-	if(iswp) ref=MMG_swapbin(ref);
+-      }
+-      if(MMG_edgePut(&hed,nu1,nu2,2)>1) {
+-	fprintf(stdout,"  ## WARNING DOUBLE EDGE : %d %d\n",nu1,nu2);
+-      }
+-      mesh->point[nu1].geom = M_RIDGE_GEO;
+-      mesh->point[nu2].geom = M_RIDGE_GEO;
++        fread(&nu1,sw,1,inm); 
++        if(iswp) nu1=MMG_swapbin(nu1);    
++        fread(&nu2,sw,1,inm); 
++        if(iswp) nu2=MMG_swapbin(nu2);    
++        fread(&ref,sw,1,inm); 
++        if(iswp) ref=MMG_swapbin(ref);    
++      }  
++			if(MMG_edgePut(&hed,nu1,nu2,2)>1) {
++				fprintf(stdout,"  ## WARNING DOUBLE EDGE : %d %d\n",nu1,nu2);
++			} 
++			mesh->point[nu1].geom = M_RIDGE_GEO;  
++			mesh->point[nu2].geom = M_RIDGE_GEO;  
      }
    }
  
--  /* rebuild triangles tabular and write triangles */
-+  /* rebuild triangles tabular and write triangles */ 
-   mesh->nt = 0;
-   if(MMG_markBdry(mesh)) {
-     if(!bin) {
--      strcpy(&chaine[0],"\n\nTriangles\n");
-+      strcpy(&chaine[0],"\n\nTriangles\n"); 
-       fprintf(inm,"%s",chaine);
-       fprintf(inm,"%d \n",mesh->nt);
-     } else {
-@@ -1055,49 +1457,48 @@
-       fwrite(&binch,sw,1,inm);
-       bpos += 12+16*mesh->nt; //Pos
-       fwrite(&bpos,sw,1,inm);
--      fwrite(&mesh->nt,sw,1,inm);
-+      fwrite(&mesh->nt,sw,1,inm);    
-     }
-     for (k=1; k<=mesh->nt; k++) {
-       pt1  = &mesh->tria[k];
--      ref  = pt1->ref;
-+  	    ref  = pt1->ref;    
-       if(!bin) {
--	//if(ref==0) printf("tr %d bad ref!!\n",k);
--	fprintf(inm,"%d %d %d %d\n",mesh->point[pt1->v[0]].tmp,mesh->point[pt1->v[1]].tmp
--		,mesh->point[pt1->v[2]].tmp,ref);
-+        fprintf(inm,"%d %d %d %d\n",mesh->point[pt1->v[0]].tmp,mesh->point[pt1->v[1]].tmp
-+    							  ,mesh->point[pt1->v[2]].tmp,ref);
-       } else {
--	fwrite(&mesh->point[pt1->v[0]].tmp,sw,1,inm);
--	fwrite(&mesh->point[pt1->v[1]].tmp,sw,1,inm);
--	fwrite(&mesh->point[pt1->v[2]].tmp,sw,1,inm);
--	fwrite(&ref,sw,1,inm);
-+        fwrite(&mesh->point[pt1->v[0]].tmp,sw,1,inm);    
-+        fwrite(&mesh->point[pt1->v[1]].tmp,sw,1,inm);    
-+        fwrite(&mesh->point[pt1->v[2]].tmp,sw,1,inm);    
-+        fwrite(&ref,sw,1,inm);    
-       }
-     }
--  }
--
-+  }   
-+ 
-   /* write tetrahedra */
--  ne = 0;
--  ned = 0;
--  //printf("avt %d\n",mesh->ned);
-+  ne = 0; 
-+	ned = 0;  
-+	//printf("avt %d\n",mesh->ned);
-   for (k=1; k<=mesh->ne; k++) {
+   /* read mesh tetrahedra */
+   mesh->nefixe = mesh->ne;
+   rewind(inm);
+-  fseek(inm,posne,SEEK_SET);
+-  reorient = 0;
+-  for (k=1; k<=netmp; k++) {
++  fseek(inm,posne,SEEK_SET); 
++	reorient = 0;
++  for (k=1; k<=netmp; k++) { 
      pt = &mesh->tetra[k];
--    if ( !pt->v[0] )  continue;
--    if(mesh->ned) {
--      for (i=0 ; i<6 ; i++) {
--	if (pt->bdryinfo[i]) {
--	  nu1 = pt->v[MMG_iare[i][0]];
--	  nu2 = pt->v[MMG_iare[i][1]];
--	  if (MMG_edgePut(&hed,nu1,nu2,2)<=1) {
--	    ed[2*ned] = (mesh->point[nu1]).tmp;
--	    ed[2*ned + 1] = (mesh->point[nu2]).tmp;
--	    ned++;
--	  }
--	}
+-    if (!bin)
+-      fscanf(inm,"%d %d %d %d %d",&pt->v[0],&pt->v[1],&pt->v[2],&pt->v[3],&ref);
+-    else {
+-
+-      for (i=0 ; i<4 ; i++) {
+-	fread(&pt->v[i],sw,1,inm);
+-	if(iswp) pt->v[i]=MMG_swapbin(pt->v[i]);
 -      }
+-      fread(&ref,sw,1,inm);
+-      if(iswp) ref=MMG_swapbin(ref);
 -    }
--    ne++;
-+    if ( !pt->v[0] )  continue;  
-+		if(mesh->ned) {
-+		  for (i=0 ; i<6 ; i++) {
-+		  	if (pt->bdryinfo[i]) {
-+		  		nu1 = pt->v[MMG_iare[i][0]];
-+		  		nu2 = pt->v[MMG_iare[i][1]];
-+		  		if (MMG_edgePut(&hed,nu1,nu2,2)<=1) {
-+		  			ed[2*ned] = (mesh->point[nu1]).tmp;
-+		  			ed[2*ned + 1] = (mesh->point[nu2]).tmp;
-+		  			ned++;
-+		  		} 
-+		  	}
-+		  } 
++    if (!bin) 
++      fscanf(inm,"%d %d %d %d %d",&pt->v[0],&pt->v[1],&pt->v[2],&pt->v[3],&ref); 
++    else {                                                                        
++	
++      for (i=0 ; i<4 ; i++) { 
++        fread(&pt->v[i],sw,1,inm); 
++        if(iswp) pt->v[i]=MMG_swapbin(pt->v[i]);    
++      }
++      fread(&ref,sw,1,inm);         
++      if(iswp) ref=MMG_swapbin(ref);           
++    }  
+     pt->ref  = ref;//0;//ref ;
+ 
+     /*check orientation*/
+-    volref = MMG_voltet(mesh,k);
+-    if(volref < 0) {
+-      reorient++;
+-      tmp = pt->v[2];
+-      pt->v[2] = pt->v[3];
+-      pt->v[3] = tmp;
+-    }
+-
++		volref = MMG_voltet(mesh,k);
++		if(volref < 0) {
++		 if(!reorient) {
++		   fprintf(stdout,"\n     $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ \n");
++		   fprintf(stdout,"         BAD ORIENTATION : vol < 0 -- Some tetra will be reoriented\n");     
++		   fprintf(stdout,"     $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ \n\n");
++		   reorient = 1;        
++		 }
++		 tmp = pt->v[2];
++     pt->v[2] = pt->v[3];
++     pt->v[3] = tmp;
 +		}
-+	  ne++;  
-   }
--  //printf("ned %d\n",ned);
-+	//printf("ned %d\n",ned);
-   if(!bin) {
--    strcpy(&chaine[0],"\n\nTetrahedra\n");
-+    strcpy(&chaine[0],"\n\nTetrahedra\n"); 
-     fprintf(inm,"%s",chaine);
-     fprintf(inm,"%d\n",ne);
-   } else {
-@@ -1105,29 +1506,29 @@
-     fwrite(&binch,sw,1,inm);
-     bpos += 12 + 20*ne;//Pos
-     fwrite(&bpos,sw,1,inm);
--    fwrite((unsigned char*)&ne,sw,1,inm);
--  }
--  ne=0;
-+    fwrite((unsigned char*)&ne,sw,1,inm);    
-+  } 
-+	ne=0;
-   for (k=1; k<=mesh->ne; k++) {
-     pt = &mesh->tetra[k];
--    if ( !pt->v[0] )  continue;
--    ne++;
--    ref = pt->ref;
-+    if ( !pt->v[0] )  continue;  
-+		ne++; 
-+    ref = pt->ref;    
-     if(!bin) {
-       fprintf(inm,"%d %d %d %d %d\n",mesh->point[pt->v[0]].tmp,mesh->point[pt->v[1]].tmp
--	      ,mesh->point[pt->v[2]].tmp,mesh->point[pt->v[3]].tmp,ref);
-+  							   ,mesh->point[pt->v[2]].tmp,mesh->point[pt->v[3]].tmp,ref);
-     } else {
--      fwrite(&mesh->point[pt->v[0]].tmp,sw,1,inm);
--      fwrite(&mesh->point[pt->v[1]].tmp,sw,1,inm);
--      fwrite(&mesh->point[pt->v[2]].tmp,sw,1,inm);
--      fwrite(&mesh->point[pt->v[3]].tmp,sw,1,inm);
--      fwrite(&ref,sw,1,inm);
-+      fwrite(&mesh->point[pt->v[0]].tmp,sw,1,inm);    
-+      fwrite(&mesh->point[pt->v[1]].tmp,sw,1,inm);    
-+      fwrite(&mesh->point[pt->v[2]].tmp,sw,1,inm);    
-+      fwrite(&mesh->point[pt->v[3]].tmp,sw,1,inm);    
-+      fwrite(&ref,sw,1,inm);    
-     }
--  }
++	  
+     for(i=0 ; i<4 ; i++)
+-      pt->bdryref[i] = -1;
 -
-+  }  
-+     
-   if(mesh->ned) {
-     if(!bin) {
--      strcpy(&chaine[0],"\n\nEdges\n");
-+      strcpy(&chaine[0],"\n\nEdges\n"); 
-       fprintf(inm,"%s",chaine);
-       fprintf(inm,"%d\n",ned);
-     } else {
-@@ -1135,50 +1536,50 @@
-       fwrite(&binch,sw,1,inm);
-       bpos += 12 + 3*4*ned;//Pos
-       fwrite(&bpos,sw,1,inm);
--      fwrite((unsigned char*)&ned,sw,1,inm);
--    }
--    for (k=0; k<ned; k++) {
--      ref = 0;
--      if(!bin) {
--	fprintf(inm,"%d %d %d \n",ed[2*k],ed[2*k+1],ref);
--      } else {
--	fwrite(&ed[2*k],sw,1,inm);
--	fwrite(&ed[2*k+1],sw,1,inm);
--	fwrite(&ref,sw,1,inm);
+-    if (ned) {
+-      for(i=0 ; i<6 ; i++) {
+-	nu1 = pt->v[MMG_iare[i][0]];
+-	nu2 = pt->v[MMG_iare[i][1]];
+-	pt->bdryinfo[i] = MMG_edgePoint(&hed,nu1,nu2);
 -      }
--    }
--    M_free(hed.item);
--    M_free(ed);
-+      fwrite((unsigned char*)&ned,sw,1,inm);    
-+    } 
-+  	  for (k=0; k<ned; k++) {
-+   	    ref = 0;    
-+  	    if(!bin) {
-+  	      fprintf(inm,"%d %d %d \n",ed[2*k],ed[2*k+1],ref);
-+  	    } else {
-+  	      fwrite(&ed[2*k],sw,1,inm);    
-+  	      fwrite(&ed[2*k+1],sw,1,inm);    
-+  	      fwrite(&ref,sw,1,inm);    
-+  	    }
-+  	  }
-+  	  M_free(hed.item);
-+			M_free(ed);
-   }
 -
-+  
-   /* write corners */
-   if(!bin) {
--    strcpy(&chaine[0],"\n\nCorners\n");
-+    strcpy(&chaine[0],"\n\nCorners\n"); 
-     fprintf(inm,"%s",chaine);
-     fprintf(inm,"%d\n",mesh->ncor);
-   } else {
-     binch = 13; //Corners
-     fwrite(&binch,sw,1,inm);
--    bpos += 12 + 4*mesh->ncor;//Pos
-+    bpos += 12 + 4*mesh->ncor;//Pos  
-     fwrite(&bpos,sw,1,inm);
--    fwrite((unsigned char*)&mesh->ncor,sw,1,inm);
-+    fwrite((unsigned char*)&mesh->ncor,sw,1,inm);    
+-    } else {
+-      for(i=0 ; i<6 ; i++)
+-	pt->bdryinfo[i] = 0;
+-    }
++      pt->bdryref[i] = -1;  
++    
++		if (ned) {
++	    for(i=0 ; i<6 ; i++) {                         
++				nu1 = pt->v[MMG_iare[i][0]];
++				nu2 = pt->v[MMG_iare[i][1]];
++	      pt->bdryinfo[i] = MMG_edgePoint(&hed,nu1,nu2);
++			}  			
++			
++		} else {
++	    for(i=0 ; i<6 ; i++)
++	      pt->bdryinfo[i] = 0;  			
++		}
    }
-   for (k=0; k<mesh->ncor; k++) {
-     if(!bin) {
-       fprintf(inm,"%d \n",cor[k]);
-     } else {
--      fwrite(&cor[k],sw,1,inm);
-+      fwrite(&cor[k],sw,1,inm);    
-     }
+-  if(reorient) {
+-    fprintf(stdout,"\n     $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ \n");
+-    fprintf(stdout,"         BAD ORIENTATION : vol < 0 -- %8d tetra reoriented\n",reorient);
+-    fprintf(stdout,"     $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ \n\n");
+-    reorient = 1;
 -  }
-+  }  
-   /*fin fichier*/
-   if(!bin) {
--    strcpy(&chaine[0],"\n\nEnd\n");
-+    strcpy(&chaine[0],"\n\nEnd\n"); 
-     fprintf(inm,"%s",chaine);
-   } else {
-     binch = 54; //End
-     fwrite(&binch,sw,1,inm);
-   }
--  fclose(inm);
-+  fclose(inm); 
-   if(mesh->ncor) M_free(cor);
-   if ( mesh->info.imprim ) {
-     fprintf(stdout,"     NUMBER OF GIVEN VERTICES   %8d\n",mesh->npfixe);
-@@ -1193,20 +1594,22 @@
-     if ( mesh->ned )
-       fprintf(stdout,"     TOTAL NUMBER OF EDGES      %8d\n",ned);
-   }
--  //if(ned!=mesh->ned) exit(0);
-+	//if(ned!=mesh->ned) exit(0);
-   return(1);
- 
- }
- 
- 
--int MMG_saveSol(pMesh mesh,pSol sol,char *filename) {
-+int MMG_saveSol(pMesh mesh,pSol sol,char *filename,void *dataff) {
-   FILE*        inm;
-   pPoint       ppt;
-   float        fsol;
-   double       tmp;
-   int          i,k,nbl,isol,bin,bpos,typ;
--  char        *ptr,data[128],chaine[128];
-+  char        *ptr,data[128],chaine[128]; 
-   int          binch;
-+  if(dataff) 
-+      return MMG_saveSolff( mesh, sol, filename,(DataFF*) dataff);
+-   if (ned) M_free(hed.item);
++  if (ned) M_free(hed.item); 
  
-   if ( !sol->np )  return(1);
-   bin = 1;
-@@ -1219,24 +1622,24 @@
-       *ptr = '\0';
-       bin  = 0;
-     } else {
--      ptr = strstr(data,".solb");
--      if ( ptr ) {
--	*ptr = '\0';
--	bin  = 1;
-+	    ptr = strstr(data,".solb");
-+	    if ( ptr ) {
-+	      *ptr = '\0';
-+	      bin  = 1;	
-       } else {
--	ptr = strstr(data,".sol");
--	if ( ptr ) {
--	  *ptr = '\0';
--	  bin  = 0;
--	}
+-  /*read corners*/
++  /*read corners*/ 
+   if (ncor) {
+     rewind(inm);
+-    fseek(inm,posncor,SEEK_SET);
++    fseek(inm,posncor,SEEK_SET); 
+     mesh->ncor = ncor;
+-    for (k=1; k<=ncor; k++) {
++    for (k=1; k<=ncor; k++) { 
+       if (!bin)
+-	fscanf(inm,"%d",&ref);
++        fscanf(inm,"%d",&ref);
+       else {
+-	fread(&ref,sw,1,inm);
+-	if(iswp) ref=MMG_swapbin(ref);
 -      }
++        fread(&ref,sw,1,inm); 
++        if(iswp) ref=MMG_swapbin(ref);    
++      }  
+       ppt = &mesh->point[ref];
+-      ppt->geom = M_CORNER;
 -    }
-+			  ptr = strstr(data,".sol");
-+			  if ( ptr ) {
-+			    *ptr = '\0';
-+			    bin  = 0;	
-+			  }
-+			}
++      ppt->geom = M_CORNER; 
 +    } 
    }
--  if ( bin )
-+  if ( bin ) 
-     strcat(data,".solb");
-   else
-     strcat(data,".sol");
 -
-+  
-   sol->ver = 2;
-   if( bin && !(inm = fopen(data,"wb")) ) {
-     fprintf(stderr,"  ** UNABLE TO OPEN %s.\n",data);
-@@ -1251,9 +1654,9 @@
- 
-   /*entete fichier*/
-   if(!bin) {
--    strcpy(&chaine[0],"MeshVersionFormatted 2\n");
-+    strcpy(&chaine[0],"MeshVersionFormatted 2\n"); 
-     fprintf(inm,"%s",chaine);
--    strcpy(&chaine[0],"\n\nDimension 3\n");
-+    strcpy(&chaine[0],"\n\nDimension 3\n"); 
-     fprintf(inm,"%s ",chaine);
-   } else {
-     binch = 1; //MeshVersionFormatted
-@@ -1266,19 +1669,19 @@
-     fwrite(&bpos,sw,1,inm);
-     binch = 3;
-     fwrite(&binch,sw,1,inm);
 -
-+    
-   }
- 
- 
-   switch(sol->offset) {
-   case 1:
--    typ = 1;
--    break;
-+	 typ = 1;
-+   break;
-   case 6:
--    typ = 3;
-+	  typ = 3;
-     break;
-   default:
--    fprintf(stdout,"  ** DATA IGNORED\n");
-+    fprintf(stdout,"  ** DATA IGNORED not 1 ou 6 == %d\n",sol->offset);
-     return(0);
-   }
+-  if ( abs(mesh->info.option)==10 ) {
++   
++	
++  if ( abs(mesh->info.option)==10 ) { 
+     if(bin) {
+       printf("NOT SUPPORTED\n");
+       exit(0);
+-    }
+-    if ( !MMG_zaldy4(&hed2,3*npris+6*nhex) ) {
+-      if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : PRISM IGNORED\n");
+-      npris = 0;
+-      nhex  = 0;
+-    }
++    } 
++	  if ( !MMG_zaldy4(&hed2,3*npris+6*nhex) ) {
++      if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : PRISM IGNORED\n"); 
++			npris = 0;
++			nhex  = 0;
++    }   
  
-@@ -1287,11 +1690,11 @@
-   for (k=1; k<=mesh->np; k++) {
-     ppt = &mesh->point[k];
-     if ( ppt->tag & M_UNUSED )  continue;
--    nbl++;
-+	nbl++;
-   }
--
-+  
-   if(!bin) {
--    strcpy(&chaine[0],"\n\nSolAtVertices\n");
-+    strcpy(&chaine[0],"\n\nSolAtVertices\n"); 
-     fprintf(inm,"%s",chaine);
-     fprintf(inm,"%d\n",nbl);
-     fprintf(inm,"%d %d\n",1,typ);
-@@ -1300,7 +1703,7 @@
-     fwrite(&binch,sw,1,inm);
-     bpos += 20+(sol->offset*sol->ver)*4*nbl; //Pos
-     fwrite(&bpos,sw,1,inm);
--    fwrite(&nbl,sw,1,inm);
-+    fwrite(&nbl,sw,1,inm);    
-     binch = 1; //nb sol
-     fwrite(&binch,sw,1,inm);
-     binch = typ; //typ sol
-@@ -1317,34 +1720,34 @@
-       sol->met[isol + 3] = tmp;
-     }
-     if (sol->ver < 2) {
--      if(!bin) {
--	for (i=0; i<sol->offset; i++) {
--	  fsol = (float) sol->met[isol + i];
--	  fprintf(inm,"%f ",fsol);
+     /*read hexa and transform to tetra*/
+     rewind(inm);
+-    fseek(inm,posnhex,SEEK_SET);
+-    nbado = 0;
++    fseek(inm,posnhex,SEEK_SET);   
++		nbado = 0;
+     for (k=1; k<=nhex; k++) {
+-      ph = &listhexa[k];
+-      fscanf(inm,"%d %d %d %d %d %d %d %d %d",&ph->v[0],&ph->v[1],&ph->v[2],&ph->v[3],&ph->v[4],&ph->v[5],&ph->v[6],&ph->v[7],&ph->ref);
+-      //fscanf(inm,"%d %d %d %d %d %d %d %d %d",&p0,&p4,&p2,&p1,&p3,&p5,&p6,&p7,&ref);
+-      //printf("hex %d : %d %d %d %d %d %d %d %d\n",k,p0,p1,p2,p3,p4,p5,p6,p7);
++			ph = &listhexa[k];   
++      fscanf(inm,"%d %d %d %d %d %d %d %d %d",&ph->v[0],&ph->v[1],&ph->v[2],&ph->v[3],&ph->v[4],&ph->v[5],&ph->v[6],&ph->v[7],&ph->ref); 
++      //fscanf(inm,"%d %d %d %d %d %d %d %d %d",&p0,&p4,&p2,&p1,&p3,&p5,&p6,&p7,&ref); 
++      //printf("hex %d : %d %d %d %d %d %d %d %d\n",k,p0,p1,p2,p3,p4,p5,p6,p7); 
+       //check orientability of the hexahedra : vol of tet p0 p1 p3 p4
+-      volhex = MMG_quickvol(mesh->point[ph->v[0]].c,mesh->point[ph->v[1]].c,mesh->point[ph->v[2]].c,mesh->point[ph->v[3]].c);
+-      if(k==1) {
+-	volref = volhex;
+-	//printf("vol %e\n",volref);
+-      }
+-      else {
+-	if(volref*volhex < 0) {
+-	  fprintf(stdout,"BAD ORIENTATION OF HEXAHEDRON %d : %d %d %d %d %d %d %d %d\n",k,p0,p1,p2,p3,p4,p5,p6,p7);
+-	  nbado++;
+-	  tmp = ph->v[3];
+-	  ph->v[3] = ph->v[1];
+-	  ph->v[1] = tmp;
+-	  tmp = ph->v[5];
+-	  ph->v[5] = ph->v[7];
+-	  ph->v[7] = tmp;
 -	}
--	fprintf(inm,"\n");
-+      if(!bin) { 
-+        for (i=0; i<sol->offset; i++) {
-+          fsol = (float) sol->met[isol + i];
-+          fprintf(inm,"%f ",fsol);
-+        } 
-+        fprintf(inm,"\n");  
-       } else {
--	for (i=0; i<sol->offset; i++) {
--	  fsol = (float) sol->met[isol + i];
--	  fwrite(&fsol,sw,1,inm);
+-      }
+-      // MMG_cuthex(mesh,&hed2,netmp+(k-1)*6,ph->v[0],ph->v[1],ph->v[2],ph->v[3],ph->v[4],ph->v[5],ph->v[6],ph->v[7],ph->ref);
+-    }
+-    fprintf(stdout,"%8d HEXA REORIENTED\n",nbado);
++			volhex = MMG_quickvol(mesh->point[ph->v[0]].c,mesh->point[ph->v[1]].c,mesh->point[ph->v[2]].c,mesh->point[ph->v[3]].c);
++			if(k==1) {
++				volref = volhex; 
++				//printf("vol %e\n",volref);
++			}
++			else {
++				if(volref*volhex < 0) {
++					fprintf(stdout,"BAD ORIENTATION OF HEXAHEDRON %d : %d %d %d %d %d %d %d %d\n",k,p0,p1,p2,p3,p4,p5,p6,p7);
++					nbado++;
++					tmp = ph->v[3];
++					ph->v[3] = ph->v[1];
++					ph->v[1] = tmp;
++					tmp = ph->v[5];
++					ph->v[5] = ph->v[7];
++					ph->v[7] = tmp;
++				}
++			} 
++			// MMG_cuthex(mesh,&hed2,netmp+(k-1)*6,ph->v[0],ph->v[1],ph->v[2],ph->v[3],ph->v[4],ph->v[5],ph->v[6],ph->v[7],ph->ref);
++    }  
++		fprintf(stdout,"%8d HEXA REORIENTED\n",nbado);
+ 
+-    if(!MMG_hashHexa(listhexa,adjahex,nhex)) return(0);
+-    MMG_cuthex(mesh,&hed2,listhexa,adjahex,nhex,netmp);
++		if(!MMG_hashHexa(listhexa,adjahex,nhex)) return(0);  
++	  MMG_cuthex(mesh,&hed2,listhexa,adjahex,nhex,netmp); 
+     /*read prism and transform to tetra
+-      ---> compatibility pbs ==> hash edge and switch case*/
++		---> compatibility pbs ==> hash edge and switch case*/  
+     rewind(inm);
+-    fseek(inm,posnpris,SEEK_SET);
+-    nimp = 0;
+-    ne = netmp+6*nhex;
++    fseek(inm,posnpris,SEEK_SET); 
++		nimp = 0; 
++		ne = netmp+6*nhex;
+     for (k=1; k<=npris; k++) {
+-      fscanf(inm,"%d %d %d %d %d %d %d",&p0,&p1,&p2,&p3,&p4,&p5,&ref);
+-      if(!MMG_cutprism(mesh,&hed2,ne,p0,p1,p2,p3,p4,p5,ref))
+-	{
+-	  if(mesh->info.imprim < 0 ) fprintf(stdout,"DECOMPOSITION PRISM INVALID \n\n");
+-	  mesh->ne += 5;
+-	  ne += 8;
+-	  nimp++;
+-	  continue;
 -	}
-+        for (i=0; i<sol->offset; i++) { 
-+          fsol = (float) sol->met[isol + i];
-+          fwrite(&fsol,sw,1,inm);
-+        }    
-       }
-     } else {
--      if(!bin) {
--	for (i=0; i<sol->offset; i++)
--	  fprintf(inm,"%.15lg ",sol->met[isol + i]);
--	fprintf(inm,"\n");
-+      if(!bin) { 
-+        for (i=0; i<sol->offset; i++)
-+          fprintf(inm,"%.15lg ",sol->met[isol + i]); 
-+        fprintf(inm,"\n");  
-       } else {
--	for (i=0; i<sol->offset; i++)
--	  fwrite(&sol->met[isol + i],sd,1,inm);
-+        for (i=0; i<sol->offset; i++)
-+          fwrite(&sol->met[isol + i],sd,1,inm);    
-       }
--
-+      
+-      ne += 3;
++      fscanf(inm,"%d %d %d %d %d %d %d",&p0,&p1,&p2,&p3,&p4,&p5,&ref); 
++			if(!MMG_cutprism(mesh,&hed2,ne,p0,p1,p2,p3,p4,p5,ref))
++			{
++				if(mesh->info.imprim < 0 ) fprintf(stdout,"DECOMPOSITION PRISM INVALID \n\n"); 
++				mesh->ne += 5;
++				ne += 8;
++				nimp++; 
++				continue;
++			}
++			ne += 3;
      }
+-    if(abs(mesh->info.imprim) > 3 )fprintf(stdout,"     %d INVALID DECOMPOSITION\n\n",nimp);
++		if(abs(mesh->info.imprim) > 3 )fprintf(stdout,"     %d INVALID DECOMPOSITION\n\n",nimp);
    }
 -
 +  
-   /*fin fichier*/
-   if(!bin) {
--    strcpy(&chaine[0],"\n\nEnd\n");
-+    strcpy(&chaine[0],"\n\nEnd\n"); 
-     fprintf(inm,"%s",chaine);
-   } else {
-     binch = 54; //End
-@@ -1355,14 +1758,16 @@
+   if ( abs(mesh->info.imprim) > 3 && abs(mesh->info.option)!=10 ) {
+     fprintf(stdout,"     NUMBER OF GIVEN VERTICES   %8d\n",mesh->npfixe);
+     if ( mesh->ntfixe )
+@@ -609,24 +1041,26 @@
+     if ( ned )
+       fprintf(stdout,"     NUMBER OF GIVEN EDGES      %8d\n",ned);
+   }
+-  fclose(inm);
+-  return(1);
++ fclose(inm);
++ return(1);
  }
  
- /*save the node speed : coornew-coorold/dt*/
--int MMG_saveVect(pMesh mesh,char *filename) {
--  FILE*        inm;
-+int MMG_saveVect(pMesh mesh,char *filename,void *dataff) {
-+  FILE*        inm;  
-   pDispl        pd;
-   pPoint       ppt;
-   double       dsol,dd;
-   int          i,k,nbl,bin,bpos,typ;
--  char        *ptr,data[128],chaine[128];
-+  char        *ptr,data[128],chaine[128]; 
-   unsigned char binch;
-+  if(dataff) 
-+      return MMG_saveVectff( mesh, filename,(DataFF*) dataff);
  
-   pd      = mesh->disp;
-   pd->ver = 2;
-@@ -1378,7 +1783,7 @@
-       bin  = 0;
-     }
+ /* load solution (metric) */
+-int MMG_loadSol(pSol sol,char *filename,int npmax) {
+-  FILE       *inm;
++int MMG_loadSol(pSol sol,char *filename,int npmax,void *dataff) { 
++  FILE       *inm;   
+   float       fsol;
+-  double      tmp;
++  double      tmp;       
+   int         binch,bdim,iswp;
+   int         k,i,isol,type,bin,dim,btyp,bpos;
+   long        posnp;
+   char        *ptr,data[128],chaine[128];
+-
+-  posnp = 0;
++    if(dataff) 
++	return MMG_loadSolff( sol,filename,npmax,(DataFF*) dataff);
++  
++  posnp = 0; 
+   bin   = 0;
+-  iswp  = 0;
++  iswp  = 0; 
+ 
+   strcpy(data,filename);
+   ptr = strstr(data,".mesh");
+@@ -645,94 +1079,94 @@
    }
--  if ( bin )
-+  if ( bin ) 
-     strcat(data,".o.solb");
-   else
-     strcat(data,".o.sol");
-@@ -1395,9 +1800,9 @@
+   fprintf(stdout,"  %%%% %s OPENED\n",data);
  
-   /*entete fichier*/
-   if(!bin) {
--    strcpy(&chaine[0],"MeshVersionFormatted 2\n");
-+    strcpy(&chaine[0],"MeshVersionFormatted 2\n"); 
-     fprintf(inm,"%s",chaine);
--    strcpy(&chaine[0],"\n\nDimension 3\n");
-+    strcpy(&chaine[0],"\n\nDimension 3\n"); 
-     fprintf(inm,"%s ",chaine);
-   } else {
-     binch = 1; //MeshVersionFormatted
-@@ -1410,20 +1815,20 @@
-     fwrite(&bpos,sw,1,inm);
-     binch = 3;
-     fwrite(&binch,sw,1,inm);
 -
+-  if(!bin) {
++   
++  if(!bin) {   
+     strcpy(chaine,"DDD");
+-    while(fscanf(inm,"%s",&chaine[0])!=EOF && strncmp(chaine,"End",strlen("End")) ) {
++    while(fscanf(inm,"%s",&chaine[0])!=EOF && strncmp(chaine,"End",strlen("End")) ) { 
+       if(!strncmp(chaine,"Dimension",strlen("Dimension"))) {
+-	fscanf(inm,"%d",&dim);
+-	if(dim!=3) {
+-	  fprintf(stdout,"BAD SOL DIMENSION : %d\n",dim);
+-	  return(1);
+-	}
+-	continue;
++          fscanf(inm,"%d",&dim);
++          if(dim!=3) {
++            fprintf(stdout,"BAD SOL DIMENSION : %d\n",dim); 
++            return(1);
++          }
++          continue;
+       } else if(!strncmp(chaine,"SolAtVertices",strlen("SolAtVertices"))) {
+-	fscanf(inm,"%d",&sol->np);
+-	fscanf(inm,"%d",&type);
+-	if(type!=1) {
+-	  fprintf(stdout,"SEVERAL SOLUTION => IGNORED : %d\n",type);
+-	  return(1);
+-	}
+-	fscanf(inm,"%d",&btyp);
+-	posnp = ftell(inm);
+-	break;
+-      }
+-    }
+-  } else {
+-    fread(&binch,sw,1,inm);
+-    iswp=0;
+-    if(binch==16777216) iswp=1;
++        fscanf(inm,"%d",&sol->np); 
++        fscanf(inm,"%d",&type); 
++        if(type!=1) {
++          fprintf(stdout,"SEVERAL SOLUTION => IGNORED : %d\n",type);
++          return(1);
++        }
++        fscanf(inm,"%d",&btyp);
++        posnp = ftell(inm);
++        break;
++      } 
++    }            
++  } else {     
++    fread(&binch,sw,1,inm); 
++    iswp=0;   
++    if(binch==16777216) iswp=1;    
+     else if(binch!=1) {
+       fprintf(stdout,"BAD FILE ENCODING\n");
+-    }
+-    fread(&sol->ver,sw,1,inm);
+-    if(iswp) sol->ver = MMG_swapbin(sol->ver);
++    } 
++    fread(&sol->ver,sw,1,inm); 
++    if(iswp) sol->ver = MMG_swapbin(sol->ver); 
+     while(fread(&binch,sw,1,inm)!=EOF && binch!=54 ) {
+-      if(iswp) binch=MMG_swapbin(binch);
+-      if(binch==54) break;
++      if(iswp) binch=MMG_swapbin(binch);      
++      if(binch==54) break;  
+       if(binch==3) {  //Dimension
+-	fread(&bdim,sw,1,inm);  //NulPos=>20
+-	if(iswp) bdim=MMG_swapbin(bdim);
+-	fread(&bdim,sw,1,inm);
+-	if(iswp) bdim=MMG_swapbin(bdim);
+-	if(bdim!=3) {
+-	  fprintf(stdout,"BAD SOL DIMENSION : %d\n",dim);
+-	  exit(0);
+-	  return(1);
+-	}
+-	continue;
++        fread(&bdim,sw,1,inm);  //NulPos=>20
++        if(iswp) bdim=MMG_swapbin(bdim);
++        fread(&bdim,sw,1,inm);
++        if(iswp) bdim=MMG_swapbin(bdim);
++        if(bdim!=3) {
++          fprintf(stdout,"BAD SOL DIMENSION : %d\n",dim);
++          exit(0);
++          return(1);
++        }
++        continue;
+       } else if(binch==62) {  //SolAtVertices
+-	fread(&binch,sw,1,inm); //NulPos
+-	if(iswp) binch=MMG_swapbin(binch);
+-	fread(&sol->np,sw,1,inm);
+-	if(iswp) sol->np=MMG_swapbin(sol->np);
+-	fread(&binch,sw,1,inm); //nb sol
+-	if(iswp) binch=MMG_swapbin(binch);
+-	if(binch!=1) {
+-	  fprintf(stdout,"SEVERAL SOLUTION => IGNORED : %d\n",type);
+-	  return(1);
+-	}
+-	fread(&btyp,sw,1,inm); //typsol
+-	if(iswp) btyp=MMG_swapbin(btyp);
+-	posnp = ftell(inm);
+-	break;
++        fread(&binch,sw,1,inm); //NulPos
++        if(iswp) binch=MMG_swapbin(binch);
++        fread(&sol->np,sw,1,inm); 
++        if(iswp) sol->np=MMG_swapbin(sol->np);
++        fread(&binch,sw,1,inm); //nb sol
++        if(iswp) binch=MMG_swapbin(binch);
++        if(binch!=1) {
++          fprintf(stdout,"SEVERAL SOLUTION => IGNORED : %d\n",type);
++          return(1);
++        }
++        fread(&btyp,sw,1,inm); //typsol
++        if(iswp) btyp=MMG_swapbin(btyp);
++        posnp = ftell(inm);
++        break;
+       } else {
+-	fread(&bpos,sw,1,inm); //Pos
+-	if(iswp) bpos=MMG_swapbin(bpos);
+-	rewind(inm);
+-	fseek(inm,bpos,SEEK_SET);
+-      }
+-    }
+-
+-  }
++        fread(&bpos,sw,1,inm); //Pos 
++        if(iswp) bpos=MMG_swapbin(bpos);
++        rewind(inm);
++        fseek(inm,bpos,SEEK_SET);        
++      } 
++    }            
 +    
++  }       
+   if ( !sol->np ) {
+-    fprintf(stdout,"  ** MISSING DATA\n");
++    fprintf(stdout,"  ** MISSING DATA ss\n");
+     return(1);
    }
--  typ = 2;
-+	typ = 2;
  
-   /* write data */
-   nbl = 0;
-   for (k=1; k<=mesh->np; k++) {
-     ppt = &mesh->point[k];
-     if ( ppt->tag & M_UNUSED )  continue;
--    nbl++;
-+	nbl++;
-   }
--
-+  
-   if(!bin) {
--    strcpy(&chaine[0],"\n\nSolAtVertices\n");
-+    strcpy(&chaine[0],"\n\nSolAtVertices\n"); 
-     fprintf(inm,"%s",chaine);
-     fprintf(inm,"%d\n",nbl);
-     fprintf(inm,"%d %d\n",1,typ);
-@@ -1432,34 +1837,34 @@
-     fwrite(&binch,sw,1,inm);
-     bpos += 20+(3*pd->ver)*4*nbl; //Pos
-     fwrite(&bpos,sw,1,inm);
--    fwrite(&nbl,sw,1,inm);
-+    fwrite(&nbl,sw,1,inm);    
-     binch = 1; //nb sol
-     fwrite(&binch,sw,1,inm);
-     binch = typ; //typ sol
-     fwrite(&binch,sw,1,inm);
--  }
--
--
--  dd = mesh->info.delta / (double)PRECI;
-+  } 
-+  
-+  
-+  dd = mesh->info.delta / (double)PRECI;  
-   fprintf(stdout,"        DT %e\n",mesh->info.dt);
-   for (k=1; k<=mesh->np; k++) {
-     ppt = &mesh->point[k];
--    if ( ppt->tag & M_UNUSED )  continue;
-+    if ( ppt->tag & M_UNUSED )  continue; 
-     for (i=0 ; i<3 ; i++) {
--      dsol = (ppt->c[i] - mesh->disp->cold[3*(k-1) + 1 + i]* dd - mesh->info.min[i])/mesh->info.dt;
--      if(!bin) {
--	fprintf(inm,"%.15lg ",dsol);
-+      dsol = (ppt->c[i] - mesh->disp->cold[3*(k-1) + 1 + i]* dd - mesh->info.min[i])/mesh->info.dt; 
-+      if(!bin) { 
-+        fprintf(inm,"%.15lg ",dsol); 
-       } else {
--	fwrite(&dsol,sd,1,inm);
-+        fwrite(&dsol,sd,1,inm);    
-       }
-     }
--    if (!bin) fprintf(inm,"\n");
-+    if (!bin) fprintf(inm,"\n");  
+   if ( btyp!= 1 && btyp!=3 ) {
+-    fprintf(stdout,"  ** DATA IGNORED\n");
++    fprintf(stdout,"  ** DATA IGNORED %d\n",btyp);
+     sol->np = 0;
+     return(1);
    }
 -
--
 +  
-+  
-   /*fin fichier*/
-   if(!bin) {
--    strcpy(&chaine[0],"\n\nEnd\n");
-+    strcpy(&chaine[0],"\n\nEnd\n"); 
-     fprintf(inm,"%s",chaine);
-   } else {
-     binch = 54; //End
-diff -r -u mmg3d4/build/sources/libmmg3d.h mmg3d4-new/build/sources/libmmg3d.h
---- mmg3d4/build/sources/libmmg3d.h	2012-12-19 16:05:36.000000000 +0100
-+++ mmg3d4-new/build/sources/libmmg3d.h	2013-01-18 16:32:41.000000000 +0100
-@@ -118,12 +118,12 @@
- typedef MMG_Sol * MMG_pSol;
- 
- /* inout */
--int  MMG_loadMesh(MMG_pMesh ,char *);
--int  MMG_loadSol(MMG_pSol ,char *,int );
--int  MMG_loadVect(MMG_pMesh ,char *,int );
--int  MMG_saveMesh(MMG_pMesh ,char *);
--int  MMG_saveSol(MMG_pMesh ,MMG_pSol ,char *);
--int  MMG_saveVect(MMG_pMesh ,char *);
-+int  MMG_loadMesh(MMG_pMesh ,char *,void *);
-+int  MMG_loadSol(MMG_pSol ,char *,int ,void *);
-+int  MMG_loadVect(MMG_pMesh ,char *,int ,void *);
-+int  MMG_saveMesh(MMG_pMesh ,char *,void *);
-+int  MMG_saveSol(MMG_pMesh ,MMG_pSol ,char *,void *);
-+int  MMG_saveVect(MMG_pMesh ,char *,void *);
- 
- #ifdef  __cplusplus
- namespace mmg3d{
-diff -r -u mmg3d4/build/sources/mesh.h mmg3d4-new/build/sources/mesh.h
---- mmg3d4/build/sources/mesh.h	2012-12-19 16:05:36.000000000 +0100
-+++ mmg3d4-new/build/sources/mesh.h	2013-01-18 16:32:41.000000000 +0100
-@@ -405,17 +405,17 @@
+   sol->offset = (btyp==1) ? 1 : 6;
  
- /* function pointers */
- typedef int (*MMG_Swap)(pMesh ,pSol ,pList );
--MMG_Swap MMG_swpptr;
--double (*MMG_length)(double *,double *,double *,double *);
--double (*MMG_caltet)(pMesh ,pSol ,int );
--double (*MMG_calte1)(pMesh ,pSol ,int );
--int    (*MMG_caltet2)(pMesh ,pSol ,int ,int ,double ,double *);
--int    (*MMG_cavity)(pMesh ,pSol ,int ,int ,pList ,int );
--int    (*MMG_buckin)(pMesh ,pSol ,pBucket ,int );
--int    (*MMG_optlen)(pMesh ,pSol ,double ,int );
--int    (*MMG_interp)(double *,double *,double *,double );
--int    (*MMG_optlentet)(pMesh ,pSol ,pQueue ,double ,int ,int );
--int    (*MMG_movevertex)(pMesh ,pSol ,int ,int );
-+extern MMG_Swap MMG_swpptr;
-+extern double (*MMG_length)(double *,double *,double *,double *);
-+extern double (*MMG_caltet)(pMesh ,pSol ,int );
-+extern double (*MMG_calte1)(pMesh ,pSol ,int );
-+extern int    (*MMG_caltet2)(pMesh ,pSol ,int ,int ,double ,double *);
-+extern int    (*MMG_cavity)(pMesh ,pSol ,int ,int ,pList ,int );
-+extern int    (*MMG_buckin)(pMesh ,pSol ,pBucket ,int );
-+extern int    (*MMG_optlen)(pMesh ,pSol ,double ,int );
-+extern int    (*MMG_interp)(double *,double *,double *,double );
-+extern int    (*MMG_optlentet)(pMesh ,pSol ,pQueue ,double ,int ,int );
-+extern int    (*MMG_movevertex)(pMesh ,pSol ,int ,int );
+   if ( abs(MMG_imprim) > 5 )
+     fprintf(stdout,"  -- READING DATA FILE %s\n",data);
  
+   if ( !sol->np ) {
+-    fprintf(stdout,"  ** MISSING DATA\n");
++    fprintf(stdout,"  ** MISSING DATA xx\n");
+     return(0);
+   }
+   sol->npfixe = sol->np;
+@@ -742,31 +1176,31 @@
+   /* read mesh solutions */
+   sol->npfixe = sol->np;
+   rewind(inm);
+-  fseek(inm,posnp,SEEK_SET);
++  fseek(inm,posnp,SEEK_SET);  
+   for (k=1; k<=sol->np; k++) {
+     isol = (k-1) * sol->offset + 1;
+-    if (sol->ver == 1) {
++    if (sol->ver == 1) { 
+       for (i=0; i<sol->offset; i++) {
+-	if(!bin){
+-	  fscanf(inm,"%f",&fsol);
+-	  sol->met[isol + i] = (double) fsol;
+-	} else {
+-	  fread(&fsol,sw,1,inm);
+-	  if(iswp) fsol=MMG_swapf(fsol);
+-	  sol->met[isol + i] = (double) fsol;
+-	}
+-      }
++        if(!bin){
++          fscanf(inm,"%f",&fsol);    
++          sol->met[isol + i] = (double) fsol;
++        } else {
++          fread(&fsol,sw,1,inm);             
++          if(iswp) fsol=MMG_swapf(fsol);
++          sol->met[isol + i] = (double) fsol;
++        }
++      } 
+     } else {
+       for (i=0; i<sol->offset; i++) {
+-	if(!bin){
+-	  fscanf(inm,"%lf",&sol->met[isol + i]);
++        if(!bin){
++          fscanf(inm,"%lf",&sol->met[isol + i]); 
  
- #endif
-diff -r -u mmg3d4/build/sources/mmg3d4.c mmg3d4-new/build/sources/mmg3d4.c
---- mmg3d4/build/sources/mmg3d4.c	2012-12-19 16:05:33.000000000 +0100
-+++ mmg3d4-new/build/sources/mmg3d4.c	2013-01-18 18:28:05.000000000 +0100
-@@ -3,32 +3,32 @@
- Co-auteurs : Cecile Dobrzynski et Pascal Frey.
- Propriétaires :IPB - UPMC -INRIA.
+-	} else {
+-	  fread(&sol->met[isol + i],sd,1,inm);
+-	  if(iswp) sol->met[isol + i]=MMG_swapd(sol->met[isol + i]);
+-	}
+-      }
+-    }
++        } else {
++          fread(&sol->met[isol + i],sd,1,inm);       
++          if(iswp) sol->met[isol + i]=MMG_swapd(sol->met[isol + i]);
++        } 
++      } 
++    }             
+     /* MMG_swap data */
+     if ( sol->offset == 6 ) {
+       tmp                = sol->met[isol + 2];
+@@ -778,13 +1212,13 @@
+   if ( abs(MMG_imprim) > 3 )
+     fprintf(stdout,"     NUMBER OF GIVEN DATA       %8d\n",sol->npfixe);
  
--Copyright © 2004-2005-2006-2007-2008-2009-2010-2011,
-+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
- diffusé sous les termes et conditions de la licence publique générale de GNU
--Version 3 ou toute version ultérieure.
-+Version 3 ou toute version ultérieure.  
+-  fclose(inm);
+-  return(1);
++  fclose(inm);   
++  return(1);  
+ }
  
- Ce fichier est une partie de MMG3D.
- MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
- suivant les termes de la licence publique générale de GNU
- Version 3 ou toute version ultérieure.
--MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS
--AUCUNE GARANTIE ; sans même garantie de valeur marchande.
-+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
-+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
- Voir la licence publique générale de GNU pour plus de détails.
--MMG3D est diffusé en espérant qu’il sera utile,
--mais SANS AUCUNE GARANTIE, ni explicite ni implicite,
--y compris les garanties de commercialisation ou
--d’adaptation dans un but spécifique.
-+MMG3D est diffusé en espérant qu’il sera utile, 
-+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
-+y compris les garanties de commercialisation ou 
-+d’adaptation dans un but spécifique. 
- Reportez-vous à la licence publique générale de GNU pour plus de détails.
--Vous devez avoir reçu une copie de la licence publique générale de GNU
--en même temps que ce document.
-+Vous devez avoir reçu une copie de la licence publique générale de GNU 
-+en même temps que ce document. 
- Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
- /****************************************************************************
- Initial software: MMG3D Version 4.0
- Co-authors: Cecile Dobrzynski et Pascal Frey.
- Owners: IPB - UPMC -INRIA.
  
--Copyright © 2004-2005-2006-2007-2008-2009-2010-2011,
--spread under the terms and conditions of the license GNU General Public License
-+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
-+spread under the terms and conditions of the license GNU General Public License 
- as published Version 3, or (at your option) any later version.
+-int MMG_loadVect(pMesh mesh,char *filename,int npmax) {
+-  FILE       *inm;
++int MMG_loadVect(pMesh mesh,char *filename,int npmax,void *dataff) {
++  FILE       *inm;   
+   pDispl       pd;
+   float       fsol;
+   int         binch,bdim,iswp;
+@@ -792,10 +1226,13 @@
+   long        posnp;
+   char        *ptr,data[128],chaine[128];
  
- This file is part of MMG3D
-@@ -41,26 +41,26 @@
- 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 MMG3D. If not, see <http://www.gnu.org/licenses/>.
-+along with MMG3D. If not, see <http://www.gnu.org/licenses/>.  
- ****************************************************************************/
- #include "mesh.h"
+-  pd = mesh->disp;
++  if(dataff) 
++      return MMG_loadVectff( mesh, filename,npmax,(DataFF*) dataff);
  
--int MMG_npuiss,MMG_nvol,MMG_npres;
--int MMG_nlen,MMG_ncal,MMG_ntopo,MMG_nex;
--int MMG_npuisstot,MMG_nvoltot,MMG_nprestot;
--int MMG_npdtot;
--int MMG_nplen,MMG_npref,MMG_bouffe;
-+extern int MMG_npuiss,MMG_nvol,MMG_npres;
-+extern int MMG_nlen,MMG_ncal,MMG_ntopo,MMG_nex;
-+extern int MMG_npuisstot,MMG_nvoltot,MMG_nprestot;
-+extern int MMG_npdtot;
-+extern int MMG_nplen,MMG_npref,MMG_bouffe;
+-  posnp = 0;
+-  bin   = 0;
++  pd = mesh->disp;
++  
++  posnp = 0; 
++  bin   = 0; 
+   iswp  = 0;
  
- int ddebug;
+   strcpy(data,filename);
+@@ -815,76 +1252,76 @@
+   }
+   fprintf(stdout,"  %%%% %s OPENED\n",data);
  
- int MMG_mmg3d4(pMesh mesh,pSol sol,int *alert) {
-   Hedge    hash;
--  pBucket        bucket;
-+  pBucket	 bucket; 
-   double   declic;
--  int              base,na,nd,ns,nna,nnd,nns,dd,it,nf,maxtou;
--  double   lmoy,LLLONG;
--  int k;
--  pTetra pt;
-+  int		   base,na,nd,ns,nna,nnd,nns,dd,it,nf,maxtou; 
-+  double   lmoy,LLLONG;                      
-+	int k;
-+	pTetra pt;
-   if ( abs(mesh->info.imprim) > 3 )
-     fprintf(stdout,"  ** SIZE OPTIMIZATION\n");
-   if ( mesh->info.imprim < 0 ) {
-@@ -73,82 +73,82 @@
-   maxtou = 10;
-   nna = nns = nnd = 0;
-   it  = 0;
--  declic = 3. / ALPHAD;
-+  declic = 3. / ALPHAD;  
-   lmoy = 10.;
-   LLLONG = 1.5;
 -
-+  
-   nna = 10;
--  do {
--    na  = nd  = ns  = 0;
-+  do { 
-+    na  = nd  = ns  = 0; 
-     if(0) ddebug = 1;
-     else ddebug = 0;
+-  if(!bin) {
++   
++  if(!bin) {   
+     strcpy(chaine,"DDD");
+-    while(fscanf(inm,"%s",&chaine[0])!=EOF && strncmp(chaine,"End",strlen("End")) ) {
++    while(fscanf(inm,"%s",&chaine[0])!=EOF && strncmp(chaine,"End",strlen("End")) ) { 
+       if(!strncmp(chaine,"Dimension",strlen("Dimension"))) {
+-	fscanf(inm,"%d",&dim);
+-	if(dim!=3) {
+-	  fprintf(stdout,"BAD SOL DIMENSION : %d\n",dim);
+-	  return(1);
+-	}
+-	continue;
++          fscanf(inm,"%d",&dim);
++          if(dim!=3) {
++            fprintf(stdout,"BAD SOL DIMENSION : %d\n",dim); 
++            return(1);
++          }
++          continue;
+       } else if(!strncmp(chaine,"SolAtVertices",strlen("SolAtVertices"))) {
+-	fscanf(inm,"%d",&pd->np);
+-	fscanf(inm,"%d",&type);
+-	if(type!=1) {
+-	  fprintf(stdout,"SEVERAL SOLUTION => IGNORED : %d\n",type);
+-	  return(1);
+-	}
+-	fscanf(inm,"%d",&btyp);
+-	posnp = ftell(inm);
+-	break;
+-      }
+-    }
+-  } else {
+-    fread(&pd->ver,sw,1,inm);
+-    iswp=0;
+-    if(pd->ver==16777216) iswp=1;
++        fscanf(inm,"%d",&pd->np); 
++        fscanf(inm,"%d",&type); 
++        if(type!=1) {
++          fprintf(stdout,"SEVERAL SOLUTION => IGNORED : %d\n",type);
++          return(1);
++        }
++        fscanf(inm,"%d",&btyp);
++        posnp = ftell(inm);
++        break;
++      } 
++    }            
++  } else {     
++    fread(&pd->ver,sw,1,inm); 
++    iswp=0;   
++    if(pd->ver==16777216) iswp=1;    
+     else if(pd->ver!=1) {
+       fprintf(stdout,"BAD FILE ENCODING\n");
+-    }
+-    fread(&pd->ver,sw,1,inm);
+-    if(iswp) pd->ver = MMG_swapbin(pd->ver);
++    } 
++    fread(&pd->ver,sw,1,inm); 
++    if(iswp) pd->ver = MMG_swapbin(pd->ver); 
+     while(fread(&binch,sw,1,inm)!=EOF && binch!=54 ) {
+-      if(iswp) binch=MMG_swapbin(binch);
+-      if(binch==54) break;
++      if(iswp) binch=MMG_swapbin(binch);      
++      if(binch==54) break;  
+       if(binch==3) {  //Dimension
+-	fread(&bdim,sw,1,inm);  //Pos=>20
+-	if(iswp) bdim=MMG_swapbin(bdim);
+-	fread(&bdim,sw,1,inm);
+-	if(iswp) bdim=MMG_swapbin(bdim);
+-	if(bdim!=3) {
+-	  fprintf(stdout,"BAD SOL DIMENSION : %d\n",dim);
+-	  exit(0);
+-	  return(1);
+-	}
+-	continue;
++        fread(&bdim,sw,1,inm);  //Pos=>20
++        if(iswp) bdim=MMG_swapbin(bdim);      
++        fread(&bdim,sw,1,inm);
++        if(iswp) bdim=MMG_swapbin(bdim);      
++        if(bdim!=3) {
++          fprintf(stdout,"BAD SOL DIMENSION : %d\n",dim);
++          exit(0);
++          return(1);
++        }
++        continue;
+       } else if(binch==62) {  //SolAtVertices
+-	fread(&binch,sw,1,inm); //Pos
+-	if(iswp) binch=MMG_swapbin(binch);
+-	fread(&pd->np,sw,1,inm);
+-	if(iswp) pd->np=MMG_swapbin(pd->np);
+-	fread(&binch,sw,1,inm); //nb sol
+-	if(iswp) binch=MMG_swapbin(binch);
+-	if(binch!=1) {
+-	  fprintf(stdout,"SEVERAL SOLUTION => IGNORED : %d\n",type);
+-	  return(1);
+-	}
+-	fread(&btyp,sw,1,inm); //typsol
+-	if(iswp) btyp=MMG_swapbin(btyp);
+-	posnp = ftell(inm);
+-	break;
++        fread(&binch,sw,1,inm); //Pos
++        if(iswp) binch=MMG_swapbin(binch);      
++        fread(&pd->np,sw,1,inm); 
++        if(iswp) pd->np=MMG_swapbin(pd->np);      
++        fread(&binch,sw,1,inm); //nb sol
++        if(iswp) binch=MMG_swapbin(binch);      
++        if(binch!=1) {
++          fprintf(stdout,"SEVERAL SOLUTION => IGNORED : %d\n",type);
++          return(1);
++        }
++        fread(&btyp,sw,1,inm); //typsol
++        if(iswp) btyp=MMG_swapbin(btyp);      
++        posnp = ftell(inm);
++        break;
+       } else {
+-	fread(&bpos,sw,1,inm); //Pos
+-	if(iswp) bpos=MMG_swapbin(bpos);
+-	rewind(inm);
+-	fseek(inm,bpos,SEEK_SET);
+-      }
+-    }
 -
+-  }
++        fread(&bpos,sw,1,inm); //Pos 
++        if(iswp) bpos=MMG_swapbin(bpos);      
++        rewind(inm);
++        fseek(inm,bpos,SEEK_SET);        
++      } 
++    }            
 +    
-     if(it && !(it%2) ) {
-       bucket = MMG_newBucket(mesh,M_MAX(mesh->info.bucksiz,BUCKSIZ));
-       if ( !bucket )  return(0);
--      //MMG_saveMesh(mesh,"avtana.mesh");
--      MMG_analar(mesh,sol,bucket,&na,&nd,&nf,alert);
--      //MMG_saveMesh(mesh,"apresana.mesh");
--      if ( abs(mesh->info.imprim) > 5 )
--	fprintf(stdout,"     %7d INSERTED  %7d REMOVED   %7d FILTERED\n",na,nd,nf);
--
--      M_free(bucket->head);
--      M_free(bucket->link);
--      M_free(bucket);
--
-+			//MMG_saveMesh(mesh,"avtana.mesh",0);
-+      MMG_analar(mesh,sol,bucket,&na,&nd,&nf,alert);      
-+			//MMG_saveMesh(mesh,"apresana.mesh",0);
-+      if ( abs(mesh->info.imprim) > 5 ) 
-+        fprintf(stdout,"     %7d INSERTED  %7d REMOVED   %7d FILTERED\n",na,nd,nf);  
-+
-+	    M_free(bucket->head);
-+	    M_free(bucket->link);
-+	    M_free(bucket);
-+        
++  }       
+   if ( !pd->np ) {
+     fprintf(stdout,"  ** MISSING DATA\n");
+     return(0);
+@@ -895,7 +1332,7 @@
+   }
+ 
+   if ( btyp != 2 ) {
+-    fprintf(stdout,"  ** DATA IGNORED\n");
++    fprintf(stdout,"  ** DATA IGNORED %d !=2\n",btyp);
+     return(0);
+   }
+ 
+@@ -907,47 +1344,50 @@
+   fseek(inm,posnp,SEEK_SET);
+   for (k=1; k<=pd->np; k++) {
+     iadr = (k - 1) * 3 + 1;
+-    if (pd->ver < 2) {
++    if (pd->ver < 2) { 
+       for (i=0; i<3; i++) {
+-	if(!bin){
+-	  fscanf(inm,"%f",&fsol);
+-	  pd->mv[iadr + i] = (double) fsol;
+-	} else {
+-	  fread(&fsol,sw,1,inm);
+-	  if(iswp) fsol=MMG_swapf(fsol);
+-	  pd->mv[iadr + i] = (double) fsol;
+-	}
+-      }
++        if(!bin){
++          fscanf(inm,"%f",&fsol); 
++          pd->mv[iadr + i] = (double) fsol;
++        } else {
++          fread(&fsol,sw,1,inm);             
++          if(iswp) fsol=MMG_swapf(fsol);      
++          pd->mv[iadr + i] = (double) fsol;
++        }
++      } 
      } else {
--      ++mesh->flag;
-+        ++mesh->flag;
-     }
--    //printf("IT %d $$$$$$$$$$$ LLLONG  %9.3f\n",it,LLLONG);
--    nna = nns = nnd = 0;
--
-+    //printf("IT %d $$$$$$$$$$$ LLLONG  %9.3f\n",it,LLLONG); 
-+    nna = nns = nnd = 0; 
-+      
-     /*splitting*/
-     if ( !mesh->info.noinsert && (!*alert)  ) {
-       /* store points on edges */
-       if ( !MMG_zaldy4(&hash,mesh->np) ) {
--	if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM.\n");
--	*alert = 2;
--	break;
-+        if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM.\n"); 
-+        *alert = 2;
-+        break;
-       }
--      nna = MMG_analarcutting(mesh,sol,&hash,alert,&lmoy,LLLONG);
-+      nna = MMG_analarcutting(mesh,sol,&hash,alert,&lmoy,LLLONG); 
-       if ( abs(mesh->info.imprim) > 5 ) { printf("lmoy %9.5f\n",lmoy); }
-       /*puts("--------------------------------------");
--	puts("--------------------------------------");
--	puts("--------------------------------------");
--      */
-+      puts("--------------------------------------");
-+      puts("--------------------------------------");
-+      */                             
-       if ( *alert ) {
--	fprintf(stdout," \n\n ** UNABLE TO CUT (analarcutting)\n");
--	fprintf(stdout," ** RETRY WITH -m > %6d \n\n",mesh->info.memory);
--	MMG_saveMesh(mesh,"crash.mesh");
--	MMG_saveSol(mesh,sol,"crash.sol");
--	exit(0);
-+        fprintf(stdout," \n\n ** UNABLE TO CUT (analarcutting)\n");
-+        fprintf(stdout," ** RETRY WITH -m > %6d \n\n",mesh->info.memory);
-+        MMG_saveMesh(mesh,"crash.mesh",0);
-+        MMG_saveSol(mesh,sol,"crash.sol",0); 
-+        exit(0);
+       for (i=0; i<3; i++) {
+-	if(!bin){
+-	  fscanf(inm,"%lf",&pd->mv[iadr + i]);
+-	} else {
+-	  fread(&pd->mv[iadr + i],sd,1,inm);
+-	  if(iswp) pd->mv[iadr + i]=MMG_swapd(pd->mv[iadr + i]);
+-	}
+-      }
+-    }
++        if(!bin){
++          fscanf(inm,"%lf",&pd->mv[iadr + i]); 
++        } else {
++          fread(&pd->mv[iadr + i],sd,1,inm);
++          if(iswp) pd->mv[iadr + i]=MMG_swapd(pd->mv[iadr + i]);      
++        } 
++      } 
++    }             
+   }
+ 
+   if ( abs(mesh->info.imprim) > 3 )
+     fprintf(stdout,"     NUMBER OF GIVEN DATA       %8d\n",pd->np);
+ 
+-  fclose(inm);
++  fclose(inm); 
+   return(1);
+ }
+ 
+ 
+ /* save mesh to disk */
+-int MMG_saveMesh(pMesh mesh,char *filename) {
+-  FILE*        inm;
+-  Hedge                          hed;
++int MMG_saveMesh(pMesh mesh,char *filename,void *dataff) {  
++  FILE*        inm; 
++	Hedge				 hed;
+   pPoint       ppt;
+   pTria        pt1;
+   pTetra       pt;
+   int          i,k,np,ne,nc,ned,*cor,*ed,ref,bin,bpos;
+-  char        *ptr,data[128],chaine[128];
++  char        *ptr,data[128],chaine[128]; 
+   int          binch,nu1,nu2;
++  if(dataff) 
++      return MMG_saveMeshff( mesh, filename,(DataFF*)  dataff);
++
+   mesh->ver = 2; //double precision
+   bin = 0;
+   strcpy(data,filename);
+@@ -959,28 +1399,28 @@
+       *ptr = '\0';
+       strcat(data,".mesh");
+       if( !(inm = fopen(data,"w")) ) {
+-	fprintf(stderr,"  ** UNABLE TO OPEN %s.\n",data);
+-	return(0);
++        fprintf(stderr,"  ** UNABLE TO OPEN %s.\n",data);
++        return(0);
        }
--      M_free(hash.item);
-+      M_free(hash.item);        
-     }
--    else if ( *alert )  nna = 0;
--    /* adjacencies */
-+    else if ( *alert )  nna = 0;  
-+    /* adjacencies */ 
-     if ( nna /*|| it == (maxtou-1)*/ ) {
-       mesh->nt = 0;
-       if ( !MMG_hashTetra(mesh) )  return(0);
-       if ( !MMG_markBdry(mesh) )   return(0);
-     }
--    // printf("chkmsh\n");
--    // MMG_unscaleMesh(mesh,sol);
--    //     MMG_saveMesh(mesh,"chk.mesh");
-+    // printf("chkmsh\n");   
-+		// MMG_unscaleMesh(mesh,sol);
-+		//     MMG_saveMesh(mesh,"chk.mesh",0);
-     //MMG_chkmsh(mesh,1,-1);
--    //if(it==1)exit(0);
--    /* delaunization */
--    if ( !mesh->info.noswap && (nna || na) ) {
-+		//if(it==1)exit(0);		
-+     /* delaunization */
-+    if ( !mesh->info.noswap && (nna || na) ) {  
-       nns   =  MMG_cendel(mesh,sol,declic,base);
+     } else {
+-      bin = 1;
++      bin = 1;   
      }
+   }
+-  else {
++  else { 
+     ptr = strstr(data,".meshb");
+     if( ptr ) bin = 1;
+     if( !(inm = fopen(data,"w")) ) {
+       fprintf(stderr,"  ** UNABLE TO OPEN %s.\n",data);
+       return(0);
+-    }
++    } 
+   }
+   fprintf(stdout,"  %%%% %s OPENED\n",data);
  
-     /* deletion */
-     /*if ( 0 && nna ) {
-       nnd   = MMG_colvert(mesh,sol,base);
--      } */
-+    } */
-     if ( nna+nnd+nns && abs(mesh->info.imprim) > 3 )
-       fprintf(stdout,"     %7d INSERTED  %7d REMOVED   %7d FLIPPED\n",nna+na,nnd+nd,nns);
+   /*entete fichier*/
+   if(!bin) {
+-    strcpy(&chaine[0],"MeshVersionFormatted 2\n");
++    strcpy(&chaine[0],"MeshVersionFormatted 2\n"); 
+     fprintf(inm,"%s",chaine);
+-    strcpy(&chaine[0],"\n\nDimension 3\n");
++    strcpy(&chaine[0],"\n\nDimension 3\n"); 
+     fprintf(inm,"%s ",chaine);
+   } else {
+     binch = 1; //MeshVersionFormatted
+@@ -993,33 +1433,38 @@
+     fwrite(&bpos,sw,1,inm);
+     binch = 3;
+     fwrite(&binch,sw,1,inm);
 -
 +    
    }
-   while ( na+nd+nns+nna+nnd > 0 && ++it < maxtou && lmoy > 1.3);
  
-@@ -161,80 +161,80 @@
-     MMG_prilen(mesh,sol);
+   /* compact vertices */
+-  if(mesh->ncor) {
++  if(mesh->ncor) {   
+     cor = (int*) M_calloc(mesh->ncor,sizeof(int),"MMG_savemesh");
+-    assert(cor);
++    assert(cor);   
    }
- 
--  //return(1);
--  //MMG_saveMesh(mesh,"aprescut.mesh");
--  fprintf(stdout,"    ---\n");
--
-+	//return(1);
-+	//MMG_saveMesh(mesh,"aprescut.mesh",0);
-+	fprintf(stdout,"    ---\n");
-+  
-   /*analyze standard*/
--  base   = mesh->flag;
--  *alert = 0;
-+    base   = mesh->flag;
-+    *alert = 0;
- 
--  nna = 0;
--  nnd = 0;
--  nf  = 0;
--  it  = 0;
--  maxtou = 100;
--  MMG_npdtot=0;
--  MMG_npuisstot=0;
--  MMG_nprestot=0;
--  MMG_nvoltot=0;
--
--  /* 2. field points */
--  if ( mesh->info.imprim < -4 ) {
--    MMG_prilen(mesh,sol);
--    fprintf(stdout,"  -- FIELD POINTS\n");
+-  if(mesh->ned) {
+-    if ( !MMG_zaldy4(&hed,mesh->ned) ) {
+-      if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EXPORT EDGES IGNORED\n");
+-      mesh->ned = 0;
+-    }
++  if(mesh->ned) {   
++	  if ( !MMG_zaldy4(&hed,mesh->ned) ) {
++      if ( mesh->info.ddebug )  fprintf(stdout,"  ## MEMORY ALLOCATION PROBLEM : EXPORT EDGES IGNORED\n"); 
++			mesh->ned = 0;
++    }   
+     ed = (int*)M_calloc(2*mesh->ned,sizeof(int),"MMG_savemesh");
+-    assert(ed);
++    assert(ed);   
+   }
+-  np = 0;
++  np = 0; 
+   nc = 0;
+   for (k=1; k<=mesh->np; k++) {
+     ppt = &mesh->point[k];
+-    if ( ppt->tag & M_UNUSED )  continue;
+-    ppt->tmp = ++np;
++    if ( ppt->tag & M_UNUSED )  continue;  
++		ppt->tmp = ++np;  
+     if ( ppt->geom & M_CORNER )  cor[nc++] = ppt->tmp;
++  } 
++  //assert(mesh->ncor==nc);
++  if(mesh->ncor!=nc) {
++    fprintf(stdout,"WARNING: some corners have been added or deleted\n");
++    mesh->ncor = nc;
+   }
+-  assert(mesh->ncor==nc);
++
+   if(!bin) {
+-    strcpy(&chaine[0],"\n\nVertices\n");
++    strcpy(&chaine[0],"\n\nVertices\n"); 
+     fprintf(inm,"%s",chaine);
+     fprintf(inm,"%d\n",np);
+   } else {
+@@ -1027,27 +1472,27 @@
+     fwrite(&binch,sw,1,inm);
+     bpos += 12+(1+3*mesh->ver)*4*np; //NullPos
+     fwrite(&bpos,sw,1,inm);
+-    fwrite(&np,sw,1,inm);
++    fwrite(&np,sw,1,inm);    
+   }
+   for(k=1; k<=mesh->np; k++) {
+     ppt = &mesh->point[k];
+-    if ( ppt->tag & M_UNUSED )  continue;
+-    //if(ppt->tmp==52453) printf("point %d --> %d\n",ppt->tmp,k);
++    if ( ppt->tag & M_UNUSED )  continue;  
++		//if(ppt->tmp==52453) printf("point %d --> %d\n",ppt->tmp,k);
+     if(!bin) {
+       fprintf(inm,"%.15lg %.15lg %.15lg %d\n",ppt->c[0],ppt->c[1],ppt->c[2],ppt->ref);
+     } else {
+-      fwrite((unsigned char*)&ppt->c[0],sd,1,inm);
+-      fwrite((unsigned char*)&ppt->c[1],sd,1,inm);
+-      fwrite((unsigned char*)&ppt->c[2],sd,1,inm);
+-      fwrite((unsigned char*)&ppt->ref,sw,1,inm);
++      fwrite((unsigned char*)&ppt->c[0],sd,1,inm);    
++      fwrite((unsigned char*)&ppt->c[1],sd,1,inm);    
++      fwrite((unsigned char*)&ppt->c[2],sd,1,inm);    
++      fwrite((unsigned char*)&ppt->ref,sw,1,inm);    
+     }
+   }
+ 
+-  /* rebuild triangles tabular and write triangles */
++  /* rebuild triangles tabular and write triangles */ 
+   mesh->nt = 0;
+   if(MMG_markBdry(mesh)) {
+     if(!bin) {
+-      strcpy(&chaine[0],"\n\nTriangles\n");
++      strcpy(&chaine[0],"\n\nTriangles\n"); 
+       fprintf(inm,"%s",chaine);
+       fprintf(inm,"%d \n",mesh->nt);
+     } else {
+@@ -1055,49 +1500,48 @@
+       fwrite(&binch,sw,1,inm);
+       bpos += 12+16*mesh->nt; //Pos
+       fwrite(&bpos,sw,1,inm);
+-      fwrite(&mesh->nt,sw,1,inm);
++      fwrite(&mesh->nt,sw,1,inm);    
+     }
+     for (k=1; k<=mesh->nt; k++) {
+       pt1  = &mesh->tria[k];
+-      ref  = pt1->ref;
++  	    ref  = pt1->ref;    
+       if(!bin) {
+-	//if(ref==0) printf("tr %d bad ref!!\n",k);
+-	fprintf(inm,"%d %d %d %d\n",mesh->point[pt1->v[0]].tmp,mesh->point[pt1->v[1]].tmp
+-		,mesh->point[pt1->v[2]].tmp,ref);
++        fprintf(inm,"%d %d %d %d\n",mesh->point[pt1->v[0]].tmp,mesh->point[pt1->v[1]].tmp
++    							  ,mesh->point[pt1->v[2]].tmp,ref);
+       } else {
+-	fwrite(&mesh->point[pt1->v[0]].tmp,sw,1,inm);
+-	fwrite(&mesh->point[pt1->v[1]].tmp,sw,1,inm);
+-	fwrite(&mesh->point[pt1->v[2]].tmp,sw,1,inm);
+-	fwrite(&ref,sw,1,inm);
++        fwrite(&mesh->point[pt1->v[0]].tmp,sw,1,inm);    
++        fwrite(&mesh->point[pt1->v[1]].tmp,sw,1,inm);    
++        fwrite(&mesh->point[pt1->v[2]].tmp,sw,1,inm);    
++        fwrite(&ref,sw,1,inm);    
+       }
+     }
 -  }
 -
--  /* create filter */
--  bucket = MMG_newBucket(mesh,M_MAX(mesh->info.bucksiz,BUCKSIZ));
--  if ( !bucket )  return(0);
--
--  do {
--    MMG_analar(mesh,sol,bucket,&na,&nd,&nf,alert);
--    nna += na;
--    nnd += nd;
--    if ( *alert ) {
--      if ( nd < 1000 )  break;
--      else  *alert = 0;
--    }
--    if ( it > 5 ) {
--      dd = abs(nd-na);
--      if ( dd < 5 || dd < 0.05*nd )   break;
--      else if ( it > 12 && nd >= na )  break;
++  }   
++ 
+   /* write tetrahedra */
+-  ne = 0;
+-  ned = 0;
+-  //printf("avt %d\n",mesh->ned);
++  ne = 0; 
++	ned = 0;  
++	//printf("avt %d\n",mesh->ned);
+   for (k=1; k<=mesh->ne; k++) {
+     pt = &mesh->tetra[k];
+-    if ( !pt->v[0] )  continue;
+-    if(mesh->ned) {
+-      for (i=0 ; i<6 ; i++) {
+-	if (pt->bdryinfo[i]) {
+-	  nu1 = pt->v[MMG_iare[i][0]];
+-	  nu2 = pt->v[MMG_iare[i][1]];
+-	  if (MMG_edgePut(&hed,nu1,nu2,2)<=1) {
+-	    ed[2*ned] = (mesh->point[nu1]).tmp;
+-	    ed[2*ned + 1] = (mesh->point[nu2]).tmp;
+-	    ned++;
+-	  }
+-	}
+-      }
 -    }
--    if ( na+nd && abs(mesh->info.imprim) > 3 )
--      fprintf(stdout,"     %7d INSERTED  %7d REMOVED   %7d FILTERED\n",na,nd,nf);
--    // MMG_saveMesh(mesh,"chk.mesh");
--    // //if(it==1) exit(0);
--  }
--  while ( na+nd > 0 && ++it < maxtou );
--
--  if ( nna+nnd && abs(mesh->info.imprim) < 3 ) {
--    fprintf(stdout,"     %7d INSERTED  %7d REMOVED  %7d FILTERED\n",na,nd,nf);
--  }
--
--  if(MMG_npdtot>0) {
--    fprintf(stdout,"    REJECTED : %5d\n",MMG_npdtot);
--    fprintf(stdout,"          VOL      : %6.2f %%    %5d \n",
--	    100*(MMG_nvoltot/(float)
--		 MMG_npdtot),MMG_nvoltot);
--    fprintf(stdout,"          PUISS    : %6.2f %%    %5d \n",
--	    100*(MMG_npuisstot/(float) MMG_npdtot),MMG_npuisstot);
--    fprintf(stdout,"         PROCHE    : %6.2f %%    %5d \n",
--	    100*(MMG_nprestot/(float) MMG_npuisstot),MMG_nprestot);
-+    nna = 0;
-+    nnd = 0;
-+    nf  = 0;
-+    it  = 0;
-+    maxtou = 100;
-     MMG_npdtot=0;
-     MMG_npuisstot=0;
-+    MMG_nprestot=0;
-     MMG_nvoltot=0;
--  }
--  if ( mesh->info.imprim < 0 ) {
--    MMG_outqua(mesh,sol);
--    MMG_prilen(mesh,sol);
+-    ne++;
++    if ( !pt->v[0] )  continue;  
++		if(mesh->ned) {
++		  for (i=0 ; i<6 ; i++) {
++		  	if (pt->bdryinfo[i]) {
++		  		nu1 = pt->v[MMG_iare[i][0]];
++		  		nu2 = pt->v[MMG_iare[i][1]];
++		  		if (MMG_edgePut(&hed,nu1,nu2,2)<=1) {
++		  			ed[2*ned] = (mesh->point[nu1]).tmp;
++		  			ed[2*ned + 1] = (mesh->point[nu2]).tmp;
++		  			ned++;
++		  		} 
++		  	}
++		  } 
++		}
++	  ne++;  
+   }
+-  //printf("ned %d\n",ned);
++	//printf("ned %d\n",ned);
+   if(!bin) {
+-    strcpy(&chaine[0],"\n\nTetrahedra\n");
++    strcpy(&chaine[0],"\n\nTetrahedra\n"); 
+     fprintf(inm,"%s",chaine);
+     fprintf(inm,"%d\n",ne);
+   } else {
+@@ -1105,29 +1549,29 @@
+     fwrite(&binch,sw,1,inm);
+     bpos += 12 + 20*ne;//Pos
+     fwrite(&bpos,sw,1,inm);
+-    fwrite((unsigned char*)&ne,sw,1,inm);
 -  }
- 
--  M_free(bucket->head);
--  M_free(bucket->link);
--  M_free(bucket);
-+    /* 2. field points */
-+    if ( mesh->info.imprim < -4 ) {
-+      MMG_prilen(mesh,sol);
-+      fprintf(stdout,"  -- FIELD POINTS\n");
-+    }
-+
-+    /* create filter */
-+    bucket = MMG_newBucket(mesh,M_MAX(mesh->info.bucksiz,BUCKSIZ));
-+    if ( !bucket )  return(0);
-+
-+    do {
-+      MMG_analar(mesh,sol,bucket,&na,&nd,&nf,alert);    
-+      nna += na;
-+      nnd += nd;
-+      if ( *alert ) {
-+        if ( nd < 1000 )  break;
-+        else  *alert = 0;
-+      }
-+      if ( it > 5 ) {
-+        dd = abs(nd-na);
-+        if ( dd < 5 || dd < 0.05*nd )   break;
-+        else if ( it > 12 && nd >= na )  break;
-+      }
-+      if ( na+nd && abs(mesh->info.imprim) > 3 )
-+        fprintf(stdout,"     %7d INSERTED  %7d REMOVED   %7d FILTERED\n",na,nd,nf);    
-+			// MMG_saveMesh(mesh,"chk.mesh",0);
-+			// //if(it==1) exit(0);
-+    }
-+    while ( na+nd > 0 && ++it < maxtou );
-+
-+    if ( nna+nnd && abs(mesh->info.imprim) < 3 ) {
-+      fprintf(stdout,"     %7d INSERTED  %7d REMOVED  %7d FILTERED\n",na,nd,nf);
-+    }
-+
-+  if(MMG_npdtot>0) { 
-+  fprintf(stdout,"    REJECTED : %5d\n",MMG_npdtot);
-+  fprintf(stdout,"          VOL      : %6.2f %%    %5d \n",
-+  	100*(MMG_nvoltot/(float)
-+  MMG_npdtot),MMG_nvoltot); 
-+  fprintf(stdout,"          PUISS    : %6.2f %%    %5d \n",
-+  	100*(MMG_npuisstot/(float) MMG_npdtot),MMG_npuisstot);
-+  fprintf(stdout,"         PROCHE    : %6.2f %%    %5d \n",
-+  	100*(MMG_nprestot/(float) MMG_npuisstot),MMG_nprestot);	
-+  MMG_npdtot=0;
-+  MMG_npuisstot=0;
-+  MMG_nvoltot=0;  
+-  ne=0;
++    fwrite((unsigned char*)&ne,sw,1,inm);    
 +  } 
-+    if ( mesh->info.imprim < 0 ) {
-+      MMG_outqua(mesh,sol);
-+      MMG_prilen(mesh,sol);
-+    }
- 
-+    M_free(bucket->head);
-+    M_free(bucket->link);
-+    M_free(bucket);
-+  
- 
-   return(1);
- }
-diff -r -u mmg3d4/build/sources/mmg3dConfig.h mmg3d4-new/build/sources/mmg3dConfig.h
---- mmg3d4/build/sources/mmg3dConfig.h	2012-12-19 16:05:36.000000000 +0100
-+++ mmg3d4-new/build/sources/mmg3dConfig.h	2013-01-18 16:32:41.000000000 +0100
-@@ -2,4 +2,4 @@
- #define Tutorial_VERSION_MAJOR 
- #define Tutorial_VERSION_MINOR 
- 
--#define USE_SCOTCH
-+/* #undef USE_SCOTCH */
-diff -r -u mmg3d4/build/sources/mmg3dlib/mmg3dlib.c mmg3d4-new/build/sources/mmg3dlib/mmg3dlib.c
---- mmg3d4/build/sources/mmg3dlib/mmg3dlib.c	2012-12-19 16:06:03.000000000 +0100
-+++ mmg3d4-new/build/sources/mmg3dlib/mmg3dlib.c	2013-01-18 16:32:41.000000000 +0100
-@@ -385,7 +385,7 @@
-   if ( !MMG_hashTetra(mesh) )    return(1);
-   if ( !MMG_markBdry(mesh) )     return(1);
-   if (abs(mesh->info.option)==10) {
--    MMG_saveMesh(mesh,"tetra.mesh");
-+    MMG_saveMesh(mesh,"tetra.mesh",0);
-     return(0);
-   }           
-   if ( !sol->np) {
-@@ -431,7 +431,7 @@
-     if ( abs(info->option) == 9 ) {  
-       if(!MMG_mmg3d9(mesh,sol,&alert)) {
-         if ( !MMG_unscaleMesh(mesh,sol) )  return(1);
--        MMG_saveMesh(mesh,"errormoving.mesh");
-+        MMG_saveMesh(mesh,"errormoving.mesh",0);
- 	      //MMG_saveSol(mesh,sol,mesh->outf);
- 	      return(1);
-       }
-diff -r -u mmg3d4/build/sources/mmg3dmain/mmg3d.c mmg3d4-new/build/sources/mmg3dmain/mmg3d.c
---- mmg3d4/build/sources/mmg3dmain/mmg3d.c	2012-12-19 16:05:53.000000000 +0100
-+++ mmg3d4-new/build/sources/mmg3dmain/mmg3d.c	2013-01-18 21:44:08.000000000 +0100
-@@ -46,7 +46,7 @@
- #include "compil.date"
- #include "mesh.h"
- #include "eigenv.h"
++	ne=0;
+   for (k=1; k<=mesh->ne; k++) {
+     pt = &mesh->tetra[k];
+-    if ( !pt->v[0] )  continue;
+-    ne++;
+-    ref = pt->ref;
++    if ( !pt->v[0] )  continue;  
++		ne++; 
++    ref = pt->ref;    
+     if(!bin) {
+       fprintf(inm,"%d %d %d %d %d\n",mesh->point[pt->v[0]].tmp,mesh->point[pt->v[1]].tmp
+-	      ,mesh->point[pt->v[2]].tmp,mesh->point[pt->v[3]].tmp,ref);
++  							   ,mesh->point[pt->v[2]].tmp,mesh->point[pt->v[3]].tmp,ref);
+     } else {
+-      fwrite(&mesh->point[pt->v[0]].tmp,sw,1,inm);
+-      fwrite(&mesh->point[pt->v[1]].tmp,sw,1,inm);
+-      fwrite(&mesh->point[pt->v[2]].tmp,sw,1,inm);
+-      fwrite(&mesh->point[pt->v[3]].tmp,sw,1,inm);
+-      fwrite(&ref,sw,1,inm);
++      fwrite(&mesh->point[pt->v[0]].tmp,sw,1,inm);    
++      fwrite(&mesh->point[pt->v[1]].tmp,sw,1,inm);    
++      fwrite(&mesh->point[pt->v[2]].tmp,sw,1,inm);    
++      fwrite(&mesh->point[pt->v[3]].tmp,sw,1,inm);    
++      fwrite(&ref,sw,1,inm);    
+     }
+-  }
 -
-+#include "dataff.h"
- TIM_mytime         MMG_ctim[TIMEMAX];
- short	             MMG_imprim;
- 
-@@ -397,6 +397,7 @@
- 	    100.*ttot/ttim[0],call[0],ttot/(float)call[0]);
++  }  
++     
+   if(mesh->ned) {
+     if(!bin) {
+-      strcpy(&chaine[0],"\n\nEdges\n");
++      strcpy(&chaine[0],"\n\nEdges\n"); 
+       fprintf(inm,"%s",chaine);
+       fprintf(inm,"%d\n",ned);
+     } else {
+@@ -1135,50 +1579,50 @@
+       fwrite(&binch,sw,1,inm);
+       bpos += 12 + 3*4*ned;//Pos
+       fwrite(&bpos,sw,1,inm);
+-      fwrite((unsigned char*)&ned,sw,1,inm);
+-    }
+-    for (k=0; k<ned; k++) {
+-      ref = 0;
+-      if(!bin) {
+-	fprintf(inm,"%d %d %d \n",ed[2*k],ed[2*k+1],ref);
+-      } else {
+-	fwrite(&ed[2*k],sw,1,inm);
+-	fwrite(&ed[2*k+1],sw,1,inm);
+-	fwrite(&ref,sw,1,inm);
+-      }
+-    }
+-    M_free(hed.item);
+-    M_free(ed);
++      fwrite((unsigned char*)&ned,sw,1,inm);    
++    } 
++  	  for (k=0; k<ned; k++) {
++   	    ref = 0;    
++  	    if(!bin) {
++  	      fprintf(inm,"%d %d %d \n",ed[2*k],ed[2*k+1],ref);
++  	    } else {
++  	      fwrite(&ed[2*k],sw,1,inm);    
++  	      fwrite(&ed[2*k+1],sw,1,inm);    
++  	      fwrite(&ref,sw,1,inm);    
++  	    }
++  	  }
++  	  M_free(hed.item);
++			M_free(ed);
    }
-   fprintf(stdout,"\n   ELAPSED TIME  %.2f SEC.  (%.2f)\n",ttim[0],ttot);
-+  fflush(stdout);
- }
- 
- 
-@@ -433,8 +434,7 @@
-   return(1);
- }
- 
--
--int main(int argc,char *argv[]) {
-+int mainmmg3d(int argc,char *argv[],DataFF *dataff) { 
-   pMesh      	mesh;
-   pSol       	sol;
-   Info     	*info;
-@@ -451,7 +451,7 @@
-   signal(SIGSEGV,excfun);
-   signal(SIGTERM,excfun);
-   signal(SIGINT,excfun);
--  atexit(endcod);
-+  if(dataff==0) atexit(endcod);
- 
-   TIM_tminit(MMG_ctim,TIMEMAX);
-   TIM_chrono(ON,&MMG_ctim[0]);
-@@ -479,15 +479,27 @@
-   info->dt       = 1.;
-   info->bdry     = 0;
-   info->optles   = 0;
 -
-+   /* modif F. Hecht ..*/
-+   if(dataff)
-+     {
-+       mesh->name=dataff->meshname;
-+       mesh->move=dataff->movename;
-+       sol->name=dataff->solname;
-+       /*      printf(" #### %p %p %p --- \n",mesh->name,mesh->move,sol->name); */
-+       info->imprim=dataff->imprim;
-+       info->memory=dataff->memory;
-+     }
-+   /* end modf */ 
-   if ( !parsar(argc,argv,mesh,sol) )  return(1);
-   MMG_imprim = info->imprim;
-   
-   /* load data */
-   if ( MMG_imprim )   fprintf(stdout,"\n  -- INPUT DATA\n");
-   TIM_chrono(ON,&MMG_ctim[1]);
--  if ( !MMG_loadMesh(mesh,mesh->name) )  return(1); 
--  if ( !MMG_loadSol(sol,sol->name,mesh->npmax) )  return(1);
-+  /* modif FH. for interface with ff++ add dataff param     */
-+  if ( !MMG_loadMesh(mesh,mesh->name,dataff) )  return(1); 
-+  if ( !MMG_loadSol(sol,sol->name,mesh->npmax,dataff ) )  return(1);
-+
-   if ( sol->np && sol->np != mesh->np ) {
-     fprintf(stdout,"  ## WARNING: WRONG SOLUTION NUMBER. IGNORED\n");
-     sol->np = 0;
-@@ -495,7 +507,7 @@
- 
-   if ( !parsop(mesh) )  return(1);
- 
--  if ( abs(info->option) == 9 && !MMG_loadVect(mesh,mesh->move,mesh->np) )  return(0);
-+  if ( abs(info->option) == 9 && !MMG_loadVect(mesh,mesh->move,mesh->np,dataff) )  return(0);
- 
-   if ( !MMG_setfunc(sol->offset) ) return(1);
-   if ( !MMG_scaleMesh(mesh,sol) )  return(1);   
-@@ -527,7 +539,7 @@
-   if ( !MMG_hashTetra(mesh) )    return(1);
-   if ( !MMG_markBdry(mesh) )     return(1);
-   if (abs(mesh->info.option)==10) {
--    MMG_saveMesh(mesh,"tetra.mesh");
-+    MMG_saveMesh(mesh,"tetra.mesh",dataff);
-     return(0);
-   }           
- 
-@@ -571,8 +583,8 @@
-     if ( abs(info->option) == 9 ) {
-       if(!MMG_mmg3d9(mesh,sol,&alert)) {
-         if ( !MMG_unscaleMesh(mesh,sol) )  return(1);
--        MMG_saveMesh(mesh,mesh->outf);
--	MMG_saveSol(mesh,sol,mesh->outf);
-+        MMG_saveMesh(mesh,mesh->outf,dataff);
-+	MMG_saveSol(mesh,sol,mesh->outf,dataff);
- 	return(1);
-       }
-       /*puts("appel 1");
-@@ -678,18 +690,18 @@
-     fprintf(stdout,"\n  ## WARNING: INCOMPLETE MESH  %d , %d\n",
-             mesh->np,mesh->ne);
- 
--  if ( MMG_imprim )  fprintf(stdout,"\n  -- WRITING DATA FILE %s\n",mesh->outf);
-+  if ( MMG_imprim && !dataff)  fprintf(stdout,"\n  -- WRITING DATA FILE %s\n",mesh->outf);
-   TIM_chrono(ON,&MMG_ctim[1]);
-   if ( !MMG_unscaleMesh(mesh,sol) )  return(1);
--  MMG_saveMesh(mesh,mesh->outf);
-+  MMG_saveMesh(mesh,mesh->outf,dataff);
-   if ( info->option == 9 ) {
--    MMG_saveSol(mesh,sol,mesh->outf);
--    MMG_saveVect(mesh,mesh->move);    
-+    MMG_saveSol(mesh,sol,mesh->outf,dataff);
-+    MMG_saveVect(mesh,mesh->move,dataff);    
++  
+   /* write corners */
+   if(!bin) {
+-    strcpy(&chaine[0],"\n\nCorners\n");
++    strcpy(&chaine[0],"\n\nCorners\n"); 
+     fprintf(inm,"%s",chaine);
+     fprintf(inm,"%d\n",mesh->ncor);
+   } else {
+     binch = 13; //Corners
+     fwrite(&binch,sw,1,inm);
+-    bpos += 12 + 4*mesh->ncor;//Pos
++    bpos += 12 + 4*mesh->ncor;//Pos  
+     fwrite(&bpos,sw,1,inm);
+-    fwrite((unsigned char*)&mesh->ncor,sw,1,inm);
++    fwrite((unsigned char*)&mesh->ncor,sw,1,inm);    
    }
-   else
--    MMG_saveSol(mesh,sol,mesh->outf);
-+    MMG_saveSol(mesh,sol,mesh->outf,dataff);   
-   TIM_chrono(OFF,&MMG_ctim[1]);
--  if ( MMG_imprim )  fprintf(stdout,"  -- WRITING COMPLETED\n");
-+  if ( MMG_imprim && !dataff)  fprintf(stdout,"  -- WRITING COMPLETED\n");
- 
-   /* free mem */
-   M_free(mesh->point);
-@@ -706,5 +718,24 @@
- 
-   if ( MMG_imprim < -4 || info->ddebug )  M_memDump();
-   M_free(mesh);
-+  if(MMG_imprim && dataff ) endcod();
-   return(0);
- }
-+
-+int main(int argc,char *argv[])  {
-+    return  mainmmg3d( argc,argv,0);
-+}
-+/*
-+ def 
-+ */
-+ MMG_Swap MMG_swpptr;
-+ double (*MMG_length)(double *,double *,double *,double *);
-+ double (*MMG_caltet)(pMesh ,pSol ,int );
-+ double (*MMG_calte1)(pMesh ,pSol ,int );
-+ int    (*MMG_caltet2)(pMesh ,pSol ,int ,int ,double ,double *);
-+ int    (*MMG_cavity)(pMesh ,pSol ,int ,int ,pList ,int );
-+ int    (*MMG_buckin)(pMesh ,pSol ,pBucket ,int );
-+ int    (*MMG_optlen)(pMesh ,pSol ,double ,int );
-+ int    (*MMG_interp)(double *,double *,double *,double );
-+ int    (*MMG_optlentet)(pMesh ,pSol ,pQueue ,double ,int ,int );
-+ int    (*MMG_movevertex)(pMesh ,pSol ,int ,int );
-diff -r -u mmg3d4/build/sources/optlen.c mmg3d4-new/build/sources/optlen.c
---- mmg3d4/build/sources/optlen.c	2012-12-19 16:05:33.000000000 +0100
-+++ mmg3d4-new/build/sources/optlen.c	2013-01-18 16:32:41.000000000 +0100
-@@ -48,7 +48,7 @@
- #define  HQCOEF    0.9 
- #define  HCRIT     0.98
- 
--double MMG_rao(pMesh mesh,int k,int inm);
-+double MMG_rao(pMesh mesh,int k,FILE* );
- int MMG_optlen_ani(pMesh mesh,pSol sol,double declic,int base) {
-   pTetra    pt,pt1;
-   pPoint    ppa,ppb;
-diff -r -u mmg3d4/build/sources/pattern.c mmg3d4-new/build/sources/pattern.c
---- mmg3d4/build/sources/pattern.c	2012-12-19 16:05:33.000000000 +0100
-+++ mmg3d4-new/build/sources/pattern.c	2013-01-18 18:41:02.000000000 +0100
-@@ -47,7 +47,7 @@
- 
- 
- unsigned char MMG_arfa[3][4] = { {2,0,1,3}, {1,2,0,3}, {0,1,2,3} };
--extern int MMG_permar[10][4];
-+extern int MMG_permar[12][4];
- extern int MMG_pointar[64][2];
- extern int ddebug;
- //insert ip on ia-ib
-diff -r -u mmg3d4/build/sources/quality.c mmg3d4-new/build/sources/quality.c
---- mmg3d4/build/sources/quality.c	2012-12-19 16:05:33.000000000 +0100
-+++ mmg3d4-new/build/sources/quality.c	2013-01-18 16:32:41.000000000 +0100
-@@ -46,7 +46,7 @@
- #include "mesh.h"  
- 
+   for (k=0; k<mesh->ncor; k++) {
+     if(!bin) {
+       fprintf(inm,"%d \n",cor[k]);
+     } else {
+-      fwrite(&cor[k],sw,1,inm);
++      fwrite(&cor[k],sw,1,inm);    
+     }
+-  }
++  }  
+   /*fin fichier*/
+   if(!bin) {
+-    strcpy(&chaine[0],"\n\nEnd\n");
++    strcpy(&chaine[0],"\n\nEnd\n"); 
+     fprintf(inm,"%s",chaine);
+   } else {
+     binch = 54; //End
+     fwrite(&binch,sw,1,inm);
+   }
+-  fclose(inm);
++  fclose(inm); 
+   if(mesh->ncor) M_free(cor);
+   if ( mesh->info.imprim ) {
+     fprintf(stdout,"     NUMBER OF GIVEN VERTICES   %8d\n",mesh->npfixe);
+@@ -1193,20 +1637,22 @@
+     if ( mesh->ned )
+       fprintf(stdout,"     TOTAL NUMBER OF EDGES      %8d\n",ned);
+   }
+-  //if(ned!=mesh->ned) exit(0);
++	//if(ned!=mesh->ned) exit(0);
+   return(1);
  
--double MMG_rao(pMesh mesh,int k,int inm);
-+double MMG_rao(pMesh mesh,int k,FILE* inm) ;
- double MMG_caltetrao(pMesh mesh,pSol sol,int iel) {
- 	return(MMG_rao(mesh,iel,0));
  }
-diff -r -u mmg3d4/build/sources/ratio.c mmg3d4-new/build/sources/ratio.c
---- mmg3d4/build/sources/ratio.c	2012-12-19 16:05:33.000000000 +0100
-+++ mmg3d4-new/build/sources/ratio.c	2013-01-18 16:32:41.000000000 +0100
-@@ -365,7 +365,7 @@
-   fprintf(stdout,"           ELEMENT   %d (%d)   %d %d %d %d\n",
- 	  iel,ielreal,pt->v[0],pt->v[1],pt->v[2],pt->v[3]);
  
--  if ( abs(mesh->info.imprim) < 5 )  return;
-+  if ( abs(mesh->info.imprim) < 5 )  return (1) ;
- 
-   fprintf(stdout,"\n     HISTOGRAMM\n");
-   for (k=1; k<9; k++) {
-diff -r -u mmg3d4/build/sources/sproto.h mmg3d4-new/build/sources/sproto.h
---- mmg3d4/build/sources/sproto.h	2012-12-19 16:05:36.000000000 +0100
-+++ mmg3d4-new/build/sources/sproto.h	2013-01-18 16:32:41.000000000 +0100
-@@ -67,13 +67,13 @@
- int  MMG_inEdge(pHedge ,int *,int *,int *);
- int  MMG_markBdry(pMesh );
  
--/* inout */
--int  MMG_loadMesh(pMesh ,char *);
--int  MMG_loadSol(pSol ,char *,int );
--int  MMG_loadVect(pMesh ,char *,int );
--int  MMG_saveMesh(pMesh ,char *);
--int  MMG_saveSol(pMesh ,pSol ,char *);
--int  MMG_saveVect(pMesh ,char *);
-+/* inout add param  F.H. june 2011 (dataff) */
-+int  MMG_loadMesh(pMesh ,char *,void *);
-+int  MMG_loadSol(pSol ,char *,int ,void *);
-+int  MMG_loadVect(pMesh ,char *,int ,void *);
-+int  MMG_saveMesh(pMesh ,char *,void *);
-+int  MMG_saveSol(pMesh ,pSol ,char *,void *);
-+int  MMG_saveVect(pMesh ,char *,void *);
+-int MMG_saveSol(pMesh mesh,pSol sol,char *filename) {
++int MMG_saveSol(pMesh mesh,pSol sol,char *filename,void *dataff) {
+   FILE*        inm;
+   pPoint       ppt;
+   float        fsol;
+   double       tmp;
+   int          i,k,nbl,isol,bin,bpos,typ;
+-  char        *ptr,data[128],chaine[128];
++  char        *ptr,data[128],chaine[128]; 
+   int          binch;
++  if(dataff) 
++      return MMG_saveSolff( mesh, sol, filename,(DataFF*) dataff);
  
- int  MMG_loctet(pMesh ,int ,int ,double *,double *);
- int  MMG_computeMetric(pMesh ,pSol ,int ,double * );
-diff -r -u mmg3d4/build/sources/swapar.c mmg3d4-new/build/sources/swapar.c
---- mmg3d4/build/sources/swapar.c	2012-12-19 16:05:33.000000000 +0100
-+++ mmg3d4-new/build/sources/swapar.c	2013-01-18 18:43:38.000000000 +0100
-@@ -1,106 +1,107 @@
--/****************************************************************************
--Logiciel initial: MMG3D Version 4.0
--Co-auteurs : Cecile Dobrzynski et Pascal Frey.
--Propriétaires :IPB - UPMC -INRIA.
+   if ( !sol->np )  return(1);
+   bin = 1;
+@@ -1219,24 +1665,24 @@
+       *ptr = '\0';
+       bin  = 0;
+     } else {
+-      ptr = strstr(data,".solb");
+-      if ( ptr ) {
+-	*ptr = '\0';
+-	bin  = 1;
++	    ptr = strstr(data,".solb");
++	    if ( ptr ) {
++	      *ptr = '\0';
++	      bin  = 1;	
+       } else {
+-	ptr = strstr(data,".sol");
+-	if ( ptr ) {
+-	  *ptr = '\0';
+-	  bin  = 0;
+-	}
+-      }
+-    }
++			  ptr = strstr(data,".sol");
++			  if ( ptr ) {
++			    *ptr = '\0';
++			    bin  = 0;	
++			  }
++			}
++    } 
+   }
+-  if ( bin )
++  if ( bin ) 
+     strcat(data,".solb");
+   else
+     strcat(data,".sol");
 -
--Copyright © 2004-2005-2006-2007-2008-2009-2010-2011,
--diffusé sous les termes et conditions de la licence publique générale de GNU
--Version 3 ou toute version ultérieure.
++  
+   sol->ver = 2;
+   if( bin && !(inm = fopen(data,"wb")) ) {
+     fprintf(stderr,"  ** UNABLE TO OPEN %s.\n",data);
+@@ -1251,9 +1697,9 @@
+ 
+   /*entete fichier*/
+   if(!bin) {
+-    strcpy(&chaine[0],"MeshVersionFormatted 2\n");
++    strcpy(&chaine[0],"MeshVersionFormatted 2\n"); 
+     fprintf(inm,"%s",chaine);
+-    strcpy(&chaine[0],"\n\nDimension 3\n");
++    strcpy(&chaine[0],"\n\nDimension 3\n"); 
+     fprintf(inm,"%s ",chaine);
+   } else {
+     binch = 1; //MeshVersionFormatted
+@@ -1266,19 +1712,19 @@
+     fwrite(&bpos,sw,1,inm);
+     binch = 3;
+     fwrite(&binch,sw,1,inm);
 -
--Ce fichier est une partie de MMG3D.
--MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
--suivant les termes de la licence publique générale de GNU
--Version 3 ou toute version ultérieure.
--MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS
--AUCUNE GARANTIE ; sans même garantie de valeur marchande.
--Voir la licence publique générale de GNU pour plus de détails.
--MMG3D est diffusé en espérant qu’il sera utile,
--mais SANS AUCUNE GARANTIE, ni explicite ni implicite,
--y compris les garanties de commercialisation ou
--d’adaptation dans un but spécifique.
--Reportez-vous à la licence publique générale de GNU pour plus de détails.
--Vous devez avoir reçu une copie de la licence publique générale de GNU
--en même temps que ce document.
--Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
--/****************************************************************************
--Initial software: MMG3D Version 4.0
--Co-authors: Cecile Dobrzynski et Pascal Frey.
--Owners: IPB - UPMC -INRIA.
++    
+   }
+ 
+ 
+   switch(sol->offset) {
+   case 1:
+-    typ = 1;
+-    break;
++	 typ = 1;
++   break;
+   case 6:
+-    typ = 3;
++	  typ = 3;
+     break;
+   default:
+-    fprintf(stdout,"  ** DATA IGNORED\n");
++    fprintf(stdout,"  ** DATA IGNORED not 1 ou 6 == %d\n",sol->offset);
+     return(0);
+   }
+ 
+@@ -1287,11 +1733,11 @@
+   for (k=1; k<=mesh->np; k++) {
+     ppt = &mesh->point[k];
+     if ( ppt->tag & M_UNUSED )  continue;
+-    nbl++;
++	nbl++;
+   }
 -
--Copyright © 2004-2005-2006-2007-2008-2009-2010-2011,
--spread under the terms and conditions of the license GNU General Public License
--as published Version 3, or (at your option) any later version.
++  
+   if(!bin) {
+-    strcpy(&chaine[0],"\n\nSolAtVertices\n");
++    strcpy(&chaine[0],"\n\nSolAtVertices\n"); 
+     fprintf(inm,"%s",chaine);
+     fprintf(inm,"%d\n",nbl);
+     fprintf(inm,"%d %d\n",1,typ);
+@@ -1300,7 +1746,7 @@
+     fwrite(&binch,sw,1,inm);
+     bpos += 20+(sol->offset*sol->ver)*4*nbl; //Pos
+     fwrite(&bpos,sw,1,inm);
+-    fwrite(&nbl,sw,1,inm);
++    fwrite(&nbl,sw,1,inm);    
+     binch = 1; //nb sol
+     fwrite(&binch,sw,1,inm);
+     binch = typ; //typ sol
+@@ -1317,34 +1763,34 @@
+       sol->met[isol + 3] = tmp;
+     }
+     if (sol->ver < 2) {
+-      if(!bin) {
+-	for (i=0; i<sol->offset; i++) {
+-	  fsol = (float) sol->met[isol + i];
+-	  fprintf(inm,"%f ",fsol);
+-	}
+-	fprintf(inm,"\n");
++      if(!bin) { 
++        for (i=0; i<sol->offset; i++) {
++          fsol = (float) sol->met[isol + i];
++          fprintf(inm,"%f ",fsol);
++        } 
++        fprintf(inm,"\n");  
+       } else {
+-	for (i=0; i<sol->offset; i++) {
+-	  fsol = (float) sol->met[isol + i];
+-	  fwrite(&fsol,sw,1,inm);
+-	}
++        for (i=0; i<sol->offset; i++) { 
++          fsol = (float) sol->met[isol + i];
++          fwrite(&fsol,sw,1,inm);
++        }    
+       }
+     } else {
+-      if(!bin) {
+-	for (i=0; i<sol->offset; i++)
+-	  fprintf(inm,"%.15lg ",sol->met[isol + i]);
+-	fprintf(inm,"\n");
++      if(!bin) { 
++        for (i=0; i<sol->offset; i++)
++          fprintf(inm,"%.15lg ",sol->met[isol + i]); 
++        fprintf(inm,"\n");  
+       } else {
+-	for (i=0; i<sol->offset; i++)
+-	  fwrite(&sol->met[isol + i],sd,1,inm);
++        for (i=0; i<sol->offset; i++)
++          fwrite(&sol->met[isol + i],sd,1,inm);    
+       }
 -
--This file is part of MMG3D
--MMG3D 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.
--MMG3D is distributed in the hope that 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 MMG3D. If not, see <http://www.gnu.org/licenses/>.
--****************************************************************************/
--#include "mesh.h"
++      
+     }
+   }
 -
--int MMG_swapar(pMesh mesh,pSol sol,pQueue q,List *list,int lon,double crit,double declic) {
--  pTetra   pt;
--  int      i,l,jel,ncas,ddebug,iadr;
++  
+   /*fin fichier*/
+   if(!bin) {
+-    strcpy(&chaine[0],"\n\nEnd\n");
++    strcpy(&chaine[0],"\n\nEnd\n"); 
+     fprintf(inm,"%s",chaine);
+   } else {
+     binch = 54; //End
+@@ -1355,14 +1801,16 @@
+ }
+ 
+ /*save the node speed : coornew-coorold/dt*/
+-int MMG_saveVect(pMesh mesh,char *filename) {
+-  FILE*        inm;
++int MMG_saveVect(pMesh mesh,char *filename,void *dataff) {
++  FILE*        inm;  
+   pDispl        pd;
+   pPoint       ppt;
+   double       dsol,dd;
+   int          i,k,nbl,bin,bpos,typ;
+-  char        *ptr,data[128],chaine[128];
++  char        *ptr,data[128],chaine[128]; 
+   unsigned char binch;
++  if(dataff) 
++      return MMG_saveVectff( mesh, filename,(DataFF*) dataff);
+ 
+   pd      = mesh->disp;
+   pd->ver = 2;
+@@ -1378,7 +1826,7 @@
+       bin  = 0;
+     }
+   }
+-  if ( bin )
++  if ( bin ) 
+     strcat(data,".o.solb");
+   else
+     strcat(data,".o.sol");
+@@ -1395,9 +1843,9 @@
+ 
+   /*entete fichier*/
+   if(!bin) {
+-    strcpy(&chaine[0],"MeshVersionFormatted 2\n");
++    strcpy(&chaine[0],"MeshVersionFormatted 2\n"); 
+     fprintf(inm,"%s",chaine);
+-    strcpy(&chaine[0],"\n\nDimension 3\n");
++    strcpy(&chaine[0],"\n\nDimension 3\n"); 
+     fprintf(inm,"%s ",chaine);
+   } else {
+     binch = 1; //MeshVersionFormatted
+@@ -1410,20 +1858,20 @@
+     fwrite(&bpos,sw,1,inm);
+     binch = 3;
+     fwrite(&binch,sw,1,inm);
 -
--  MMG_swpptr = 0;
--  ncas   = 0;
--  if ( !MMG_getnElt(mesh,10) )  return(-1);
--  if(0 && list->tetra[1]/6==2352) ddebug=1;
--  else ddebug=0;
++    
+   }
+-  typ = 2;
++	typ = 2;
+ 
+   /* write data */
+   nbl = 0;
+   for (k=1; k<=mesh->np; k++) {
+     ppt = &mesh->point[k];
+     if ( ppt->tag & M_UNUSED )  continue;
+-    nbl++;
++	nbl++;
+   }
 -
--  switch(lon) {
--  case 3:
--    ncas = MMG_simu32(mesh,sol,list,crit);
--    break;
--  case 4:
--    ncas = MMG_simu44(mesh,sol,list,crit);
--    break;
--  case 5:
--    ncas = MMG_simu56(mesh,sol,list,crit);
--    break;
--  case 6:
--    ncas = MMG_simu68(mesh,sol,list,crit);
--    break;
--  case 7:
--    ncas = MMG_simu710(mesh,sol,list,crit);
--    break;
--  default:
--    return(0);
++  
+   if(!bin) {
+-    strcpy(&chaine[0],"\n\nSolAtVertices\n");
++    strcpy(&chaine[0],"\n\nSolAtVertices\n"); 
+     fprintf(inm,"%s",chaine);
+     fprintf(inm,"%d\n",nbl);
+     fprintf(inm,"%d %d\n",1,typ);
+@@ -1432,34 +1880,34 @@
+     fwrite(&binch,sw,1,inm);
+     bpos += 20+(3*pd->ver)*4*nbl; //Pos
+     fwrite(&bpos,sw,1,inm);
+-    fwrite(&nbl,sw,1,inm);
++    fwrite(&nbl,sw,1,inm);    
+     binch = 1; //nb sol
+     fwrite(&binch,sw,1,inm);
+     binch = typ; //typ sol
+     fwrite(&binch,sw,1,inm);
 -  }
--  if(ddebug) printf("on fait swap %d\n",ncas);
--  if ( ncas && MMG_swpptr ) {
--    if(ddebug) MMG_saveMesh(mesh,"avt.mesh");
--    for (l=1; l<=lon; l++) {
--      jel = list->tetra[l]/6;
--      pt  = &mesh->tetra[jel];
--      if(ddebug) {
--	printf("tet %d : %d %d %d %d -- %d %d %d %d %d %d\n",jel,pt->v[0],pt->v[1],pt->v[2],pt->v[3],
--	       pt->bdryinfo[0],pt->bdryinfo[1],pt->bdryinfo[2],pt->bdryinfo[3],pt->bdryinfo[4],pt->bdryinfo[5]);
 -
--      }
--      MMG_kiudel(q,jel);
--    }
--    lon = MMG_swpptr(mesh,sol,list);
--    assert(lon);
--    if(!lon) return(0);
 -
--    for (l=1; l<=lon; l++) {
--      jel = list->tetra[l];
--      pt  = &mesh->tetra[jel];
--      if ( pt->qual >= declic )  MMG_kiuput(q,jel);
--      for (i=0; i<4; i++)  mesh->point[pt->v[i]].flag = mesh->flag;
+-  dd = mesh->info.delta / (double)PRECI;
++  } 
++  
++  
++  dd = mesh->info.delta / (double)PRECI;  
+   fprintf(stdout,"        DT %e\n",mesh->info.dt);
+   for (k=1; k<=mesh->np; k++) {
+     ppt = &mesh->point[k];
+-    if ( ppt->tag & M_UNUSED )  continue;
++    if ( ppt->tag & M_UNUSED )  continue; 
+     for (i=0 ; i<3 ; i++) {
+-      dsol = (ppt->c[i] - mesh->disp->cold[3*(k-1) + 1 + i]* dd - mesh->info.min[i])/mesh->info.dt;
+-      if(!bin) {
+-	fprintf(inm,"%.15lg ",dsol);
++      dsol = (ppt->c[i] - mesh->disp->cold[3*(k-1) + 1 + i]* dd - mesh->info.min[i])/mesh->info.dt; 
++      if(!bin) { 
++        fprintf(inm,"%.15lg ",dsol); 
+       } else {
+-	fwrite(&dsol,sd,1,inm);
++        fwrite(&dsol,sd,1,inm);    
+       }
+     }
+-    if (!bin) fprintf(inm,"\n");
++    if (!bin) fprintf(inm,"\n");  
+   }
 -
--    }
--    if(ddebug) {MMG_saveMesh(mesh,"sw.mesh");    exit(0);}
--    return(1);
--  }
 -
--  return(0);
--}
-+/****************************************************************************
-+Logiciel initial: MMG3D Version 4.0
-+Co-auteurs : Cecile Dobrzynski et Pascal Frey.
-+Propriétaires :IPB - UPMC -INRIA.
-+
-+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
-+diffusé sous les termes et conditions de la licence publique générale de GNU
-+Version 3 ou toute version ultérieure.  
-+
-+Ce fichier est une partie de MMG3D.
-+MMG3D est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier
-+suivant les termes de la licence publique générale de GNU
-+Version 3 ou toute version ultérieure.
-+MMG3D est distribué dans l'espoir qu'il sera utile, mais SANS 
-+AUCUNE GARANTIE ; sans même garantie de valeur marchande.  
-+Voir la licence publique générale de GNU pour plus de détails.
-+MMG3D est diffusé en espérant qu’il sera utile, 
-+mais SANS AUCUNE GARANTIE, ni explicite ni implicite, 
-+y compris les garanties de commercialisation ou 
-+d’adaptation dans un but spécifique. 
-+Reportez-vous à la licence publique générale de GNU pour plus de détails.
-+Vous devez avoir reçu une copie de la licence publique générale de GNU 
-+en même temps que ce document. 
-+Si ce n’est pas le cas, aller voir <http://www.gnu.org/licenses/>.
-+/****************************************************************************
-+Initial software: MMG3D Version 4.0
-+Co-authors: Cecile Dobrzynski et Pascal Frey.
-+Owners: IPB - UPMC -INRIA.
-+
-+Copyright © 2004-2005-2006-2007-2008-2009-2010-2011, 
-+spread under the terms and conditions of the license GNU General Public License 
-+as published Version 3, or (at your option) any later version.
-+
-+This file is part of MMG3D
-+MMG3D 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.
-+MMG3D is distributed in the hope that 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 MMG3D. If not, see <http://www.gnu.org/licenses/>.  
-+****************************************************************************/
-+#include "mesh.h"
-+
-+int MMG_swapar(pMesh mesh,pSol sol,pQueue q,List *list,int lon,double crit,double declic) {
-+  pTetra   pt;
-+  int      i,l,jel,ncas,ddebug,iadr;
-+
-+  MMG_swpptr = 0;
-+  ncas   = 0;
-+  if ( !MMG_getnElt(mesh,10) )  return(-1);
-+	if(0 && list->tetra[1]/6==2352) ddebug=1;
-+	else ddebug=0;
-+	
-+  switch(lon) {
-+  case 3:
-+	  ncas = MMG_simu32(mesh,sol,list,crit);
-+    break;
-+  case 4:
-+	  ncas = MMG_simu44(mesh,sol,list,crit); 
-+    break;
-+  case 5:
-+	ncas = MMG_simu56(mesh,sol,list,crit);
-+    break;
-+  case 6:
-+	ncas = MMG_simu68(mesh,sol,list,crit); 
-+    break;
-+  case 7:
-+	ncas = MMG_simu710(mesh,sol,list,crit);   
-+    break;  
-+  default:
-+    return(0);
-+  }
-+	if(ddebug) printf("on fait swap %d\n",ncas);
-+  if ( ncas && MMG_swpptr ) {
-+		if(ddebug) MMG_saveMesh(mesh,"avt.mesh",0);
-+    for (l=1; l<=lon; l++) {
-+      jel = list->tetra[l]/6;
-+      pt  = &mesh->tetra[jel]; 
-+			if(ddebug) {
-+				printf("tet %d : %d %d %d %d -- %d %d %d %d %d %d\n",jel,pt->v[0],pt->v[1],pt->v[2],pt->v[3],
-+					pt->bdryinfo[0],pt->bdryinfo[1],pt->bdryinfo[2],pt->bdryinfo[3],pt->bdryinfo[4],pt->bdryinfo[5]);  
-+				
-+			} 
-+			MMG_kiudel(q,jel);
-+    }
-+    lon = MMG_swpptr(mesh,sol,list);
-+    assert(lon);
-+    if(!lon) return(0); 
-+    
-+    for (l=1; l<=lon; l++) {
-+      jel = list->tetra[l];
-+      pt  = &mesh->tetra[jel]; 
-+      if ( pt->qual >= declic )  MMG_kiuput(q,jel);
-+      for (i=0; i<4; i++)  mesh->point[pt->v[i]].flag = mesh->flag;		 
-+
-+   }
-+    if(ddebug) {MMG_saveMesh(mesh,"sw.mesh",0);    exit(0);}
-+    return(1);
-+  }
-+
-+  return(0);
-+}
-+
++  
++  
+   /*fin fichier*/
+   if(!bin) {
+-    strcpy(&chaine[0],"\n\nEnd\n");
++    strcpy(&chaine[0],"\n\nEnd\n"); 
+     fprintf(inm,"%s",chaine);
+   } else {
+     binch = 54; //End
diff --git a/download/mshmet/Makefile b/download/mshmet/Makefile
old mode 100644
new mode 100755
index b3ddc12..334d19b
--- a/download/mshmet/Makefile
+++ b/download/mshmet/Makefile
@@ -1,105 +1,93 @@
-# Downloading and compiling extra libraries
-# -----------------------------------------
-
-# $Id$
-all-local: mshmet
-
-include ff-flags
-
-# Downloading and compiling mshmet
-# -------------------------------
-# 
-DIRPKG= ../pkg
-SRCDIR= ./mshmet$(mshmet_VERSION)
-#-$(mshmet_VERSION)
-PACKAGE=$(DIRPKG)/mshmet$(mshmet_VERSION).tgz
-SERVER=http://www.ann.jussieu.fr/~frey/ftp/archives/
-INSTALL=../..
-mshmet_VERSION=.2012.04.25
-FAIRE=$(SRCDIR)/FAIRE
-
-# ---------------------- 
-#     mshmetlib
-
-MSHMET_DIR = $(abs_top_builddir)/download/mshmet/mshmet$(mshmet_VERSION)
-MSHMET_SRCDIRNOLIB = $(MSHMET_DIR)/sources
-MSHMET_SRCDIR = $(MSHMET_DIR)/sourceslib
-MSHMET_OBJDIR = $(MSHMET_DIR)/objects
-
-mshmet: $(FAIRE) 
-
-$(FAIRE):$(SRCDIR)/FAIT
-	$(MAKE) WHERE  
-	touch $(FAIRE)
-
-$(SRCDIR)/FAIT:$(SRCDIR)/tag-tar
-	cd $(MSHMET_DIR); $(MAKE)
-	touch $(SRCDIR)/FAIT
-
-install:$(SRCDIR)/FAIT  ../../src/libMesh/libMesh.a 
-	cp $(MSHMET_SRCDIR)/mshmetlib.h  ../include/mshmetlib.h
-	cp $(MSHMET_OBJDIR)/libmshmet.a  ../lib/libmshmet.a
-	cp ../../src/libMesh/libMesh.a  ../lib/libMesh.a
-	mkdir -p ../include/libMesh
-	cp ../../src/libMesh/*h  ../include/libMesh
-
-../../src/libMesh/libMesh.a:
-	cd ../../src/libMesh && $(MAKE) 
-
-WHERE: 
-	-if [ -f $(SRCDIR)/FAIT ] ; then \
-	make install;  \
-	echo mshmet  LD -L at DIR@/lib -lmshmet  >../lib/WHERE.mshmet ;\
-	echo mshmet INCLUDE -I at DIR@/include>> ../lib/WHERE.mshmet ;\
-	echo libMesh  LD -L at DIR@/lib -lMesh  >../lib/WHERE.libMesh ;\
-	echo libMesh INCLUDE -I at DIR@/include/libMesh >> ../lib/WHERE.libMesh ;\
-	fi
-
-
-$(SRCDIR)/tag-tar: $(PACKAGE)
-	-mkdir mshmet$(mshmet_VERSION)
-	cd mshmet$(mshmet_VERSION); tar xvzf ../$(PACKAGE)
-	-mkdir $(MSHMET_SRCDIR)
-	cp $(MSHMET_SRCDIRNOLIB)/*.c $(MSHMET_SRCDIRNOLIB)/*.h $(MSHMET_SRCDIR)
-	cp $(MSHMET_SRCDIRNOLIB)/compil.date $(MSHMET_SRCDIR)
-	cp mshmetlib-internal.h mshmetlib.c mshmetlib.h $(MSHMET_SRCDIR)/
-	cp ../../src/libMesh/chrono.h $(MSHMET_SRCDIR)
-	rm $(MSHMET_SRCDIR)/mshmet.c
-	rm $(MSHMET_SRCDIR)/chrono.c
-	cp ../../src/libMesh/eigenv.c $(MSHMET_SRCDIR)
-	cp Makefile-mshmet.inc $(MSHMET_DIR)/makefile
-	cd $(MSHMET_SRCDIR); patch -p2 < ../../mshmet.2011.03.06.patch
-	touch $(SRCDIR)/tag-tar
-
-$(PACKAGE):
-	-mkdir $(DIRPKG);
-	cd $(DIRPKG);$(WGET)   $(SERVER)/`basename $(PACKAGE)`
-
-clean-local: 
-	-make -C $(MSHMET_DIR) clean;
-	-rm $(MSHMET_OBJDIR)/libmshmet.a
-	-rm ff-flags ../lib/WHERE.mshmet
-	-rm ../lib/WHERE.libMesh ../lib/WHERE.mshmet 
-	-rm ../include/mshmetlib.h
-	-rm ../lib/libmshmet.a
-	-rm -r ../lib/libMesh.a
-	-rm -r ../include/libMesh
-	-rm -rf $(SRCDIR)
-	-rm FAIT $(FAIRE) 
-
-clean: clean-local
-
-
-ff-flags: ../Makefile 
-	grep 'abs_top_builddir *=' ../Makefile >> ff-flags
-	grep 'CC *=' ../Makefile >> ff-flags
-	grep 'CFLAGS *=' ../Makefile >> ff-flags
-	grep 'LDFLAGS *=' ../Makefile >> ff-flags
-	grep 'AR *=' ../Makefile >> ff-flags
-	grep 'ARFLAGS *=' ../Makefile >> ff-flags
-	grep 'RANLIB *=' ../Makefile >> ff-flags
-	grep 'WGET *=' ../Makefile >> ff-flags
-	grep 'mshmet_VERSION *=' ./Makefile >> ff-flags
-
-
-.PHONY:
\ No newline at end of file
+# Downloading and compiling extra libraries
+# -----------------------------------------
+
+# $Id$
+all-local: mshmet
+
+include ff-flags
+
+# Downloading and compiling mshmet
+# -------------------------------
+# 
+DIRPKG= ../pkg
+SRCDIR= ./mshmet$(mshmet_VERSION)
+#-$(mshmet_VERSION)
+PACKAGE=$(DIRPKG)/mshmet$(mshmet_VERSION).tgz
+SERVER=http://www.ann.jussieu.fr/~frey/ftp/archives/
+INSTALL=../..
+mshmet_VERSION=.2012.04.25
+FAIRE=$(SRCDIR)/FAIRE
+
+# ---------------------- 
+#     mshmetlib
+
+MSHMET_DIR = $(abs_top_builddir)/download/mshmet/mshmet$(mshmet_VERSION)
+MSHMET_SRCDIRNOLIB = $(MSHMET_DIR)/sources
+MSHMET_SRCDIR = $(MSHMET_DIR)/sourceslib
+MSHMET_OBJDIR = $(MSHMET_DIR)/objects
+
+mshmet: $(FAIRE) 
+
+$(FAIRE):$(SRCDIR)/FAIT
+	$(MAKE) WHERE $(SRCDIR)/$(INSTALL)  
+	touch $(FAIRE)
+
+$(SRCDIR)/FAIT:$(SRCDIR)/tag-tar
+	cd $(MSHMET_DIR); $(MAKE)
+	touch $(SRCDIR)/FAIT
+
+# FFCS - libMesh is also required by yams, so we move all the rules to [[file:../../../Makefile.am]]
+install:$(SRCDIR)/FAIT
+	cp $(MSHMET_SRCDIR)/mshmetlib.h  $(SRCDIR)/$(INSTALL)/include/mshmetlib.h
+	cp $(MSHMET_OBJDIR)/libmshmet.a  $(SRCDIR)/$(INSTALL)/lib/libmshmet.a
+
+# FFCS - simplify makefile structure for automatic rebuilds
+WHERE:install
+	echo mshmet  LD -L at DIR@/lib -lmshmet  >$(SRCDIR)/$(INSTALL)/lib/WHERE.mshmet
+	echo mshmet INCLUDE -I at DIR@/include>> $(SRCDIR)/$(INSTALL)/lib/WHERE.mshmet
+
+
+$(SRCDIR)/tag-tar: $(PACKAGE)
+	-mkdir mshmet$(mshmet_VERSION)
+	cd mshmet$(mshmet_VERSION); tar xvzf ../$(PACKAGE)
+	-mkdir $(MSHMET_SRCDIR)
+	cp $(MSHMET_SRCDIRNOLIB)/*.c $(MSHMET_SRCDIRNOLIB)/*.h $(MSHMET_SRCDIR)
+	cp $(MSHMET_SRCDIRNOLIB)/compil.date $(MSHMET_SRCDIR)
+	cp mshmetlib-internal.h mshmetlib.c mshmetlib.h $(MSHMET_SRCDIR)/
+	cp ../../src/libMesh/chrono.h $(MSHMET_SRCDIR)
+	rm $(MSHMET_SRCDIR)/mshmet.c
+	rm $(MSHMET_SRCDIR)/chrono.c
+	cp ../../src/libMesh/eigenv.c $(MSHMET_SRCDIR)
+	cp Makefile-mshmet.inc $(MSHMET_DIR)/makefile
+	cd $(MSHMET_SRCDIR); patch -p2 < ../../mshmet.2011.03.06.patch
+#
+#	Patch for i586 developed by John Hunt (14/2/13)
+#
+	cd $(MSHMET_SRCDIR); patch -p2 < ../../mshmet.2012.04.25_i586.patch
+	touch $(SRCDIR)/tag-tar
+
+$(PACKAGE):
+	-mkdir $(DIRPKG);
+	cd $(DIRPKG);$(WGET)   $(SERVER)/`basename $(PACKAGE)`
+
+clean:
+	-rm ff-flags
+#	FFCS - make sure that all directories are cleaned. Thisis especially important under Windows because there is no
+#	compilation dependencies control there (see
+#	[[file:c:/cygwin/home/alh/ffcs/dist/configure.ac::dependency_tracking]])
+	-rm -rf mshmet.????.??.??
+	-rm FAIT $(FAIRE) 
+
+ff-flags: ../Makefile 
+	grep 'abs_top_builddir *=' ../Makefile >> ff-flags
+	grep 'CC *=' ../Makefile >> ff-flags
+	grep 'CFLAGS *=' ../Makefile >> ff-flags
+	grep 'LDFLAGS *=' ../Makefile >> ff-flags
+	grep 'AR *=' ../Makefile >> ff-flags
+	grep 'ARFLAGS *=' ../Makefile >> ff-flags
+	grep 'RANLIB *=' ../Makefile >> ff-flags
+	grep 'WGET *=' ../Makefile >> ff-flags
+	grep 'mshmet_VERSION *=' ./Makefile >> ff-flags
+
+
+.PHONY: $(SRCDIR)/$(INSTALL)
diff --git a/download/mshmet/mshmet.2012.04.25_i586.patch b/download/mshmet/mshmet.2012.04.25_i586.patch
new file mode 100644
index 0000000..3d82255
--- /dev/null
+++ b/download/mshmet/mshmet.2012.04.25_i586.patch
@@ -0,0 +1,11 @@
+--- mshmet.2012.04.25/sourceslib/libmesh5.c.orig	2013-02-12 17:47:00.093678985 +0000
++++ mshmet.2012.04.25/sourceslib/libmesh5.c	2013-02-12 17:48:27.083684096 +0000
+@@ -1381,7 +1381,7 @@
+ 	int IntVal;
+ 	long pos;
+ 
+-	if(msh->ver >= 3)
++	if ( (msh->ver >= 3) && (sizeof(long) == 8) )
+ 		ScaDblWrd(msh, (unsigned char*)&pos);
+ 	else
+ 	{
diff --git a/download/mumps-seq/Makefile b/download/mumps-seq/Makefile
old mode 100644
new mode 100755
index 1d3e83e..de492b2
--- a/download/mumps-seq/Makefile
+++ b/download/mumps-seq/Makefile
@@ -1,67 +1,69 @@
-# Downloading and compiling extra libraries
-# -----------------------------------------
-
-# $Id$
-include Makefile.inc
-
-all-local: mumps
-
-# Downloading and compiling mumps
-# ------------------------------
-DIRPKG=../pkg
-SRCDIR=MUMPS_$(VERSION)
-PACKAGE1=$(DIRPKG)/MUMPS_$(VERSION).tar.gz
-INSTALL=../..
-VERSION=4.10.0
-
-mumps: FAIRE-$(VERSION)
-
-$(SRCDIR)/FAIT: $(SRCDIR)/tag-tar
-	cp Makefile.inc $(SRCDIR)
-	cd $(SRCDIR);make d z
-	touch $(SRCDIR)/FAIT	
-install: $(SRCDIR)/FAIT
-	-mkdir -p ../include/libseq
-	cp $(SRCDIR)/include/*.h ../include/libseq
-	cp $(SRCDIR)/libseq/*.h  ../include/libseq
-	-mkdir -p ../lib
-	cp $(SRCDIR)/lib/*.a ../lib/
-	cp $(SRCDIR)/libseq/libmpiseqFREEFEM-SEQ.a ../lib/
-
-WHERE: 
-	if [ -f $(SRCDIR)/FAIT  ] ;then \
-	$(MAKE) install ; \
-	echo mumps-seq LD -L at DIR@/lib   -ldmumpsFREEFEM-SEQ -lzmumpsFREEFEM-SEQ  -lmumps_commonFREEFEM-SEQ -lpordFREEFEM-SEQ -lpthread    >../lib/WHERE.mumpsseq ;\
-	echo mumps-seq INCLUDE -I at DIR@/include/libseq  >> ../lib/WHERE.mumpsseq ;\
-	echo libseq LD -L at DIR@/lib  -lmpiseqFREEFEM-SEQ   >>../lib/WHERE.mumpsseq ;\
-	echo libseq INCLUDE -I at DIR@/include/libseq>> ../lib/WHERE.mumpsseq ;\
-	fi
-
-
-FAIRE-$(VERSION):
-	$(MAKE) install WHERE 
-	touch FAIRE-$(VERSION)
-
-Makefile.inc: ../../config.status	Makefile Makefile-mumps-$(VERSION).inc
-	../../config.status  --file="Makefile.inc:Makefile-mumps-$(VERSION).inc"
-
-$(SRCDIR)/$(INSTALL): $(SRCDIR)/tag-tar
-
-$(SRCDIR)/tag-tar:$(PACKAGE1)
-	tar xvzf $(PACKAGE1)
-#	patch -d MUMPS_4.9.2   -p 1    <MUMPS_4.9.2.patch
-	touch $(SRCDIR)/tag-tar
-
-$(PACKAGE1):
-	cd `dirname $@`; $(WGET)   http://graal.ens-lyon.fr/MUMPS/`basename $(PACKAGE1)`
-clean-local:
-	-cd $(SRCDIR) &&  $(MAKE) clean -C $(SRCDIR) 
-	rm Makefile.inc FAIRE* *~ ../lib/WHERE.mumpsseq
-	-rm -rf ../include/*mumps*
-	-rm -rf ../lib/lib*mumps* ../lib/libpord*.a ../lib/libmpiseq*.a
-	-rm -rf $(SRCDIR)
-
-clean: clean-local
-
-
-.PHONY:$(SRCDIR)/$(INSTALL)
\ No newline at end of file
+# Downloading and compiling extra libraries
+# -----------------------------------------
+
+# $Id$
+include Makefile.inc
+
+all-local: mumps
+
+# Downloading and compiling mumps
+# ------------------------------
+DIRPKG=../pkg
+SRCDIR=MUMPS_$(VERSION)
+PACKAGE1=$(DIRPKG)/MUMPS_$(VERSION).tar.gz
+INSTALL=../..
+VERSION=4.10.0
+
+mumps: FAIRE-$(VERSION)
+
+$(SRCDIR)/FAIT: $(SRCDIR)/tag-tar
+	cp Makefile.inc $(SRCDIR)
+#	FFCS - 22/5/12 - Mumps has difficulties compiling d & z in parallel
+	cd $(SRCDIR) && make d
+	cd $(SRCDIR) && make z
+	touch $(SRCDIR)/FAIT	
+install.done: $(SRCDIR)/FAIT
+	-mkdir -p $(SRCDIR)/$(INSTALL)/include/libseq
+	cp $(SRCDIR)/include/*.h $(SRCDIR)/$(INSTALL)/include/libseq
+	cp $(SRCDIR)/libseq/*.h  $(SRCDIR)/$(INSTALL)/include/libseq
+	-mkdir -p $(SRCDIR)/$(INSTALL)/lib
+	cp $(SRCDIR)/lib/*.a $(SRCDIR)/$(INSTALL)/lib/
+	cp $(SRCDIR)/libseq/libmpiseqFREEFEM-SEQ.a $(SRCDIR)/$(INSTALL)/lib/
+	touch $@
+clean::
+	-rm *.done
+
+# FFCS - install and WHERE need to be done sequentially, even in parallel builds
+WHERE.done: install.done
+	echo mumps-seq LD -L at DIR@/lib   -ldmumpsFREEFEM-SEQ -lzmumpsFREEFEM-SEQ  -lmumps_commonFREEFEM-SEQ -lpordFREEFEM-SEQ -lpthread >$(SRCDIR)/$(INSTALL)/lib/WHERE.mumpsseq ;
+	echo mumps-seq INCLUDE -I at DIR@/include/libseq  >> $(SRCDIR)/$(INSTALL)/lib/WHERE.mumpsseq ;
+	echo libseq LD -L at DIR@/lib  -lmpiseqFREEFEM-SEQ   >>$(SRCDIR)/$(INSTALL)/lib/WHERE.mumpsseq ;
+	echo libseq INCLUDE -I at DIR@/include/libseq>> $(SRCDIR)/$(INSTALL)/lib/WHERE.mumpsseq ;
+	touch $@
+
+FAIRE-$(VERSION): install.done WHERE.done
+	touch $@
+
+Makefile.inc: ../../config.status	Makefile Makefile-mumps-$(VERSION).inc
+	../../config.status  --file="Makefile.inc:Makefile-mumps-$(VERSION).inc"
+
+$(SRCDIR)/$(INSTALL): $(SRCDIR)/tag-tar
+
+$(SRCDIR)/tag-tar:$(PACKAGE1)
+	tar xvzf $(PACKAGE1)
+#	patch -d MUMPS_4.9.2   -p 1    <MUMPS_4.9.2.patch
+	touch $(SRCDIR)/tag-tar
+
+$(PACKAGE1):
+	cd `dirname $@`; $(WGET)   http://graal.ens-lyon.fr/MUMPS/`basename $(PACKAGE1)`
+clean-local:
+	-cd $(SRCDIR) &&  $(MAKE) clean -C $(SRCDIR) 
+
+# FFCS - $(SRCDIR)/$(INSTALL) is not valid if $(SRCDIR) is not there
+clean:: clean-local
+	-rm Makefile.inc FAIRE* *~ 
+	-rm -rf ../include/*mumps*
+	-rm -rf ../lib/lib*mumps* ../lib/libpord*.a ../lib/libmpiseq*.a ../lib/WHERE.mumpsseq
+	-rm -rf $(SRCDIR)
+
+.PHONY:$(SRCDIR)/$(INSTALL)
diff --git a/download/mumps/Makefile b/download/mumps/Makefile
index 4373e8b..b52bed4 100644
--- a/download/mumps/Makefile
+++ b/download/mumps/Makefile
@@ -1,66 +1,89 @@
-# Downloading and compiling extra libraries
-# -----------------------------------------
-
-# $Id$
-include Makefile.inc
-
-all-local: mumps
-
-# Downloading and compiling mumps
-# ------------------------------
-DIRPKG=../pkg
-SRCDIR=MUMPS_$(VERSION)
-PACKAGE1=$(DIRPKG)/MUMPS_$(VERSION).tar.gz
-INSTALL=../..
-VERSION=4.10.0
-
-mumps: FAIRE-$(VERSION)
-
-$(SRCDIR)/FAIT: $(SRCDIR)/tag-tar
-	cp Makefile.inc $(SRCDIR)
-	cd $(SRCDIR);make d z
-	touch $(SRCDIR)/FAIT	
-install: $(SRCDIR)/FAIT
-	-mkdir -p ../include/libseq
-	cp $(SRCDIR)/include/*.h ../include/
-	cp $(SRCDIR)/libseq/*.h  ../include/libseq
-	-mkdir -p ../lib
-	cp $(SRCDIR)/lib/*.a ../lib/
-	cp $(SRCDIR)/libseq/libmpiseqFREEFEM.a ../lib/
-
-WHERE: 
-	if [ -f $(SRCDIR)/FAIT  ] ;then \
-	$(MAKE) install ; \
-	echo mumps LD -L at DIR@/lib   -ldmumpsFREEFEM -lzmumpsFREEFEM  -lmumps_commonFREEFEM -lpordFREEFEM  -lpthread  >../lib/WHERE.mumps ;\
-	echo mumps INCLUDE -I at DIR@/include  >> ../lib/WHERE.mumps ;\
-	fi
-
-
-FAIRE-$(VERSION):
-	$(MAKE) install WHERE 
-	touch FAIRE-$(VERSION)
-
-Makefile.inc: ../../config.status	Makefile Makefile-mumps-$(VERSION).inc
-	../../config.status  --file="Makefile.inc:Makefile-mumps-$(VERSION).inc"
-
-$(SRCDIR)/$(INSTALL): $(SRCDIR)/tag-tar
-
-$(SRCDIR)/tag-tar:$(PACKAGE1)
-	tar xvzf $(PACKAGE1)
-	patch -d MUMPS_$(VERSION)   -p 1    <MUMPS_$(VERSION).patch
-	touch $(SRCDIR)/tag-tar
-
-$(PACKAGE1):
-	cd `dirname $@`; $(WGET)   http://graal.ens-lyon.fr/MUMPS/`basename $(PACKAGE1)`
-
-clean-local:
-	-cd $(SRCDIR) &&  $(MAKE) clean -C $(SRCDIR) 
-	rm Makefile.inc FAIRE* ../lib/WHERE.mumps
-	-rm -rf ../include/*mumps*
-	-rm -rf ../lib/lib*mumps* ../lib/libpord*.a ../lib/libmpiseq*.a
-	-rm -rf $(SRCDIR)
-
-clean: clean-local
-
-
-.PHONY:$(SRCDIR)/$(INSTALL)
\ No newline at end of file
+# ======================================================================
+# Modified by Antoine Le Hyaric
+# Laboratoire Jacques-Louis Lions
+# Université Pierre et Marie Curie-Paris6, UMR 7598, Paris, F-75005 France
+# http://www.ljll.math.upmc.fr/lehyaric
+# ======================================================================
+# This file is part of Freefem++
+# 
+# Freefem++ is free software; you can redistribute 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.
+# 
+# Freefem++ is distributed in the hope that it will be useful,
+# 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 Freefem++; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+# ======================================================================
+# headeralh default=0 freefem make modified start=19/03/10 upmc
+
+include Makefile.inc
+
+all-local: mumps
+
+# Downloading and compiling mumps
+# ------------------------------
+DIRPKG=../pkg
+SRCDIR=MUMPS_$(VERSION)
+PACKAGE1=$(DIRPKG)/MUMPS_$(VERSION).tar.gz
+INSTALL=../..
+VERSION=4.10.0
+
+mumps: FAIRE-$(VERSION)
+
+$(SRCDIR)/FAIT: $(SRCDIR)/tag-tar
+	cp Makefile.inc $(SRCDIR)
+	cd $(SRCDIR);make d z
+	touch $(SRCDIR)/FAIT	
+install: $(SRCDIR)/FAIT
+	-mkdir -p ../include/libseq
+	cp $(SRCDIR)/include/*.h ../include/
+	cp $(SRCDIR)/libseq/*.h  ../include/libseq
+	-mkdir -p ../lib
+	cp $(SRCDIR)/lib/*.a ../lib/
+	cp $(SRCDIR)/libseq/libmpiseqFREEFEM.a ../lib/
+
+WHERE: 
+	if [ -f $(SRCDIR)/FAIT  ] ;then \
+	$(MAKE) install ; \
+	echo mumps LD -L at DIR@/lib   -ldmumpsFREEFEM -lzmumpsFREEFEM  -lmumps_commonFREEFEM -lpordFREEFEM  -lpthread  >../lib/WHERE.mumps ;\
+	echo mumps INCLUDE -I at DIR@/include  >> ../lib/WHERE.mumps ;\
+	fi
+
+
+FAIRE-$(VERSION):
+	$(MAKE) install WHERE 
+	touch FAIRE-$(VERSION)
+
+Makefile.inc: ../../config.status	Makefile Makefile-mumps-$(VERSION).inc
+	../../config.status  --file="Makefile.inc:Makefile-mumps-$(VERSION).inc"
+
+$(SRCDIR)/$(INSTALL): $(SRCDIR)/tag-tar
+
+$(SRCDIR)/tag-tar:$(PACKAGE1)
+	tar xvzf $(PACKAGE1)
+	patch -d MUMPS_$(VERSION)   -p 1    <MUMPS_$(VERSION).patch
+	touch $(SRCDIR)/tag-tar
+
+$(PACKAGE1):
+	cd `dirname $@`; $(WGET)   http://graal.ens-lyon.fr/MUMPS/`basename $(PACKAGE1)`
+
+clean-local:
+	-cd $(SRCDIR) &&  $(MAKE) clean -C $(SRCDIR) 
+	-rm Makefile.inc FAIRE* ../lib/WHERE.mumps
+	-rm -rf ../include/*mumps*
+	-rm -rf ../lib/lib*mumps* ../lib/libpord*.a ../lib/libmpiseq*.a
+	-rm -rf $(SRCDIR)
+
+clean: clean-local
+
+# Local Variables:
+# mode:makefile
+# ispell-local-dictionary:"british"
+# coding:utf-8
+# End:
diff --git a/download/mumps/Makefile-mumps-4.10.0.inc b/download/mumps/Makefile-mumps-4.10.0.inc
index c97a29c..4cb240d 100644
--- a/download/mumps/Makefile-mumps-4.10.0.inc
+++ b/download/mumps/Makefile-mumps-4.10.0.inc
@@ -145,7 +145,12 @@ LIBOTHERS = @LIBSPTHREAD@ @FLIBS@ $(FFLIBOTHERSMUMPS)
 CDEFS = @CFLAGSF77@
 
 #COMPILER OPTIONS
-OPTF    = -O @FFLAGS@ @MPI_INCLUDE@
+
+# FFCS - 23/4/13 - -fno-range-check required on MinGW to compile with
+# Microsoft MPI. mpif.h contains INTEGER MPI_FLOAT_INT / PARAMETER
+# (MPI_FLOAT_INT=z'8c000000') which requires this.
+
+OPTF    = -O @FFLAGS@ @MPI_INCLUDE@ -fno-range-check
 OPTC    = -O -I. @CFLAGS@  @MPI_INCLUDE@
 OPTL    = -O @FFLAGS@ @MPI_LIBFC@ 
 
diff --git a/download/nlopt/Makefile b/download/nlopt/Makefile
index 9d16039..4740a65 100644
--- a/download/nlopt/Makefile
+++ b/download/nlopt/Makefile
@@ -1,7 +1,7 @@
 URL="http://ab-initio.mit.edu/nlopt/nlopt-2.2.4.tar.gz"
 SRCDIR=nlopt-2.2.4
 TARGZ=../pkg/$(SRCDIR).tar.gz
-include Make.defs
+-include Make.defs
 
 all: FAIRE
 
@@ -9,8 +9,20 @@ FAIRE: ../pkg $(SRCDIR)/FAIT
 
 $(SRCDIR)/FAIT: $(TARGZ)
 	tar zxvf $(TARGZ)
-	cd $(SRCDIR); ./configure  --with-cxx --prefix="$(FFDOWNLOAD)" CXX="$(CXX)" CXXFLAGS="$(CXXFLAGS)" CC="$(CC)" CFLAGS="$(CFLAGS)"  CP="$(CXXCPP)" "--without-threadlocal"
-	cd $(SRCDIR); $(MAKE) install
+#
+#	FFCS - 30/11/11 - "--disable-dependency-tracking": dependencies pose problem on mixed Cygwin/MinGW setups
+#	because of slashes and backslashes
+#
+# 	FFCS - 22/10/12 - Fred - "--without-octave": patch for one machine that has octave installed on it: building of
+#	nlopt fails because it wants to install the octave components.  Not a bad idea in general but probably not when
+#	building ffcs.
+#
+	cd $(SRCDIR) && ./configure --disable-dependency-tracking --with-cxx --prefix="$(FFDOWNLOAD)" CXX="$(CXX)"	\
+	CXXFLAGS="$(CXXFLAGS)" CC="$(CC)" CFLAGS="$(CFLAGS)" CP="$(CXXCPP)" "--without-threadlocal" "--without-octave"
+#
+#	FFCS - 30/11/11 - we need to know when the building process breaks
+#
+	cd $(SRCDIR) && $(MAKE) install
 	touch $(SRCDIR)/FAIT
 	$(MAKE) WHERE
 $(TARGZ):
@@ -23,7 +35,7 @@ clean-local:
 	rm -f ../lib/libnlopt_cxx*  ../lib/WHERE.nlopt 
 	rm -f ../include/nlopt*
 
-clean:clean-local:
+clean:clean-local
 
 WHERE: 
 	-if [ -f $(SRCDIR)/FAIT ] ; then \
diff --git a/download/parmetis/Makefile-parmetis.in b/download/parmetis/Makefile-parmetis.in
index 0414d96..673fba7 100644
--- a/download/parmetis/Makefile-parmetis.in
+++ b/download/parmetis/Makefile-parmetis.in
@@ -6,7 +6,8 @@ LD=  @MPICC@
 OPTFLAGS = @CFLAGS@ 
 
 # What options to be used by the compiler
-COPTIONS =  -DHAVE_CONFIG_H -I. -I../../../.. @FFMETIS_CFLAGS@ #-D_MSC_VER
+# FFCS - add path to mpi.h (required for MacOS 10.8 + MacPorts OpenMPI)
+COPTIONS =  -DHAVE_CONFIG_H -I. -I../../../.. -I @MPI_INC_DIR@ @FFMETIS_CFLAGS@ #-D_MSC_VER
 
 # What options to be used by the loader
 LDOPTIONS = @LDFLAGS@ 
diff --git a/download/parmetis/makefile b/download/parmetis/makefile
old mode 100644
new mode 100755
index 0605fce..3911ab1
--- a/download/parmetis/makefile
+++ b/download/parmetis/makefile
@@ -14,35 +14,41 @@ DIRPKG=../pkg
 SRCDIR=ParMetis-$(parmetis_VERSION)
 PACKAGE=$(DIRPKG)/ParMetis-$(parmetis_VERSION).tar.gz
 SERVER=http://glaros.dtc.umn.edu/gkhome/fetch/sw/parmetis/OLD
+
 INSTALL=../..
 parmetis_VERSION=3.1.1
 
-parmetis: FAIRE
+parmetis: WHERE.done
 
-$(SRCDIR)/FAIT:$(SRCDIR)/tags Makefile.in
+compile.done:$(SRCDIR)/tags Makefile.in
 	-mkdir -p "../lib/parmetis"
 	-mkdir -p "../include/parmetis"
 	cp Makefile.in $(SRCDIR)
-	cd $(SRCDIR)/METISLib; $(MAKE) 
-	cd $(SRCDIR)/ParMETISLib;$(MAKE) 
-	touch $(SRCDIR)/FAIT
-install: 
+# 	FFCS - we need to know when errors occur
+	cd $(SRCDIR)/METISLib && $(MAKE) 
+	cd $(SRCDIR)/ParMETISLib && $(MAKE) 
+	touch $@
+
+# FFCS - simpler makefile
+install.done:compile.done
+#	cp $(SRCDIR)/libparmetis.a $(SRCDIR)/$(INSTALL)/lib
+#	cp $(SRCDIR)/libmetis.a $(SRCDIR)/$(INSTALL)/lib
 	cp $(SRCDIR)/parmetis.h ../include/parmetis
 	cp $(SRCDIR)/METISLib/*.h ../include/parmetis
 	sed  's;../parmetis.h;parmetis.h;' <$(SRCDIR)/METISLib/metis.h >../include/parmetis/metis.h
-	-cd $(SRCDIR)/Programs;make 
-
-
-WHERE:
-	if [ -f $(SRCDIR)/FAIT ] ;then \
-	make install ;\
-	echo parmetis LD -L at DIR@/lib/parmetis -lparmetis -lmetis  >../lib/WHERE.parmetis ;\
-	echo parmetis INCLUDE -I at DIR@/include/parmetis   >> ../lib/WHERE.parmetis ;\
-	fi
-
-FAIRE: $(SRCDIR)/FAIT 
-	$(MAKE) WHERE
-	touch FAIRE
+#
+#	FFCS - 23/5/12 - cannot keep name libmetis.a because it is identical to the library created by
+#	[[file:../metis/Makefile]] and library path mechanisms at link time pick one for the other on MinGW.
+	mv $(SRCDIR)/$(INSTALL)/lib/parmetis/libmetis.a $(SRCDIR)/$(INSTALL)/lib/libmetispar.a
+#
+	-cd $(SRCDIR)/Programs && make 
+	touch $@
+
+# FFCS - simpler makefile
+WHERE.done:install.done
+	echo parmetis LD -L at DIR@/lib/parmetis -lparmetis -lmetispar  >$(SRCDIR)/$(INSTALL)/lib/WHERE.parmetis ;
+	echo parmetis INCLUDE -I at DIR@/include/parmetis   >> $(SRCDIR)/$(INSTALL)/lib/WHERE.parmetis ;
+	touch $@
 
 Makefile.in: ../../config.status Makefile-parmetis.in
 	../../config.status  --file="Makefile.in:Makefile-parmetis.in"
@@ -74,16 +80,12 @@ $(SRCDIR)/tags: $(PACKAGE)
 $(PACKAGE):
 	cd $(DIRPKG);$(WGET)   $(SERVER)/`basename $(PACKAGE)`
 
-
-
-clean-local:
+# FFCS - 23/5/12 - corrected bug in removing .a from ../lib
+clean:
 	-cd $(SRCDIR) && $(MAKE) realclean  -C  $(SRCDIR)
-	rm Makefile.in $(SRCDIR)/tags $(SRCDIR)/FAIT
-	-rm ../lib/WHERE.parmetis
-	-rm -rf  ../include/parmetis
-	-rm -rf  ../lib/parmetis
+	-rm Makefile.in $(SRCDIR)/tags
+	-rm -rf ../lib/parmetis
+	-rm -rf ../include/parmetis
+	-rm -rf ../include/metis
 	-rm -rf $(SRCDIR)
-
-clean: clean-local
-
-.PHONY:$(SRCDIR)/$(INSTALL)
\ No newline at end of file
+	-rm *.done
diff --git a/download/parms/Makefile b/download/parms/Makefile
index c73f45a..7351c97 100644
--- a/download/parms/Makefile
+++ b/download/parms/Makefile
@@ -1,62 +1,68 @@
-# Downloading and compiling extra libraries
-# -----------------------------------------
-
-# $Id$
-include Makefile.in
-
-all-local: parms
-
-# Downloading and compiling parms
-# -------------------------------
-# http://www-users.cs.umn.edu/~saad/software/pARMS/pARMS_2.2.php
-# Parms information
-DIRPKG=../pkg
-SRCDIR=pARMS_$(parms_VERSION)
-PACKAGE=$(DIRPKG)/pARMS_$(parms_VERSION).tar.gz
-SERVER= http://www-users.cs.umn.edu/~saad/software/pARMS/pARMS_2.2.tar.gz
-INSTALL=../..
-parms_VERSION=2.2
-
-parms: FAIRE
-
-$(SRCDIR)/FAIT:
-	$(MAKE) $(SRCDIR)/$(INSTALL)  WHERE
-	touch $(SRCDIR)/FAIT
-install:$(SRCDIR)/$(INSTALL)
-
-FAIRE: $(SRCDIR)/FAIT
-
-Makefile.in: ../../config.status	Makefile makefile-parms.in
-	../../config.status  --file="Makefile.in:makefile-parms.in"
-	case `uname` in *CYGWIN*)  cp Makefile.in Makefile.inn; sed "s/COPTIONS =/COPTIONS = -D__VC__/" <Makefile.inn > Makefile.in; rm Makefile.inn ;; esac 
-
-$(SRCDIR)/$(INSTALL): $(SRCDIR)
-	cp Makefile.in $(SRCDIR)/makefile.in
-	cd $(SRCDIR); $(MAKE) ./LIB/libparms$(DBG).a
-	mkdir -p ../include/parms
-	cp $(SRCDIR)/INCLUDE/*.h ../include/parms/
-	cp $(SRCDIR)/LIB/*.a ../lib/
-
-$(SRCDIR): $(PACKAGE)
-	tar xvzf $(PACKAGE)
-	touch $(SRCDIR)
-
-$(PACKAGE):
-	-mkdir $(DIRPKG);
-	cd $(DIRPKG);$(WGET)   $(SERVER)
-
-clean-local:
-	-make cleanall -C $(SRCDIR)/src
-	-rm Makefile.in ../lib/WHERE.parms
-	-rm ../lib/libparms.*
-	-rm -rf ../include/parms
-	-rm -rf $(SRCDIR)
-clean: 
-
-
-WHERE:
-	echo parms LD -L at DIR@/lib -lparms$(DBG)  >../lib/WHERE.parms
-	echo parms INCLUDE -I at DIR@/include/parms >> ../lib/WHERE.parms
-
-.PHONY:$(SRCDIR)/$(INSTALL)
-
+# Downloading and compiling extra libraries
+# -----------------------------------------
+
+# $Id$
+include Makefile.in
+
+all-local: parms
+
+# Downloading and compiling parms
+# -------------------------------
+# http://www-users.cs.umn.edu/~saad/software/pARMS/pARMS_2.2.php
+# Parms information
+DIRPKG=../pkg
+SRCDIR=pARMS_$(parms_VERSION)
+PACKAGE=$(DIRPKG)/pARMS_$(parms_VERSION).tar.gz
+SERVER= http://www-users.cs.umn.edu/~saad/software/pARMS/pARMS_2.2.tar.gz
+INSTALL=../..
+parms_VERSION=2.2
+
+parms: FAIRE
+
+# FFCS: more dependencies for parallel builds
+$(SRCDIR)/FAIT:$(SRCDIR)
+	$(MAKE) $(SRCDIR)/$(INSTALL)  WHERE
+	touch $(SRCDIR)/FAIT
+install:$(SRCDIR)/$(INSTALL)
+
+FAIRE: $(SRCDIR)/FAIT
+
+Makefile.in: ../../config.status	Makefile makefile-parms.in
+	../../config.status  --file="Makefile.in:makefile-parms.in"
+	case `uname` in *CYGWIN*)  cp Makefile.in Makefile.inn; sed "s/COPTIONS =/COPTIONS = -D__VC__/" <Makefile.inn > Makefile.in; rm Makefile.inn ;; esac 
+
+$(SRCDIR)/$(INSTALL): $(SRCDIR)
+	cp Makefile.in $(SRCDIR)/makefile.in
+	cd $(SRCDIR); $(MAKE) ./LIB/libparms$(DBG).a
+	mkdir -p ../include/parms
+	cp $(SRCDIR)/INCLUDE/*.h ../include/parms/
+	cp $(SRCDIR)/LIB/*.a ../lib/
+
+$(SRCDIR): $(PACKAGE)
+	tar xvzf $(PACKAGE)
+	touch $(SRCDIR)
+
+$(PACKAGE):
+	-mkdir $(DIRPKG);
+	cd $(DIRPKG);$(WGET)   $(SERVER)
+
+clean-local:
+	-make cleanall -C $(SRCDIR)/src
+	-rm Makefile.in ../lib/WHERE.parms
+	-rm ../lib/libparms.*
+	-rm -rf ../include/parms
+	-rm -rf $(SRCDIR)
+clean:clean-local
+#	FFCS - make sure that all directories are cleaned. This is especially important under Windows because there is no
+#	compilation dependencies control there (see
+#	[[file:c:/cygwin/home/alh/ffcs/dist/configure.ac::dependency_tracking]])
+	-rm -rf pARMS_*
+	-rm config.log
+
+
+WHERE:
+	echo parms LD -L at DIR@/lib -lparms$(DBG)  >../lib/WHERE.parms
+	echo parms INCLUDE -I at DIR@/include/parms >> ../lib/WHERE.parms
+
+.PHONY:$(SRCDIR)/$(INSTALL)
+
diff --git a/download/parms/makefile-parms.in b/download/parms/makefile-parms.in
index 08f02c7..576603e 100644
--- a/download/parms/makefile-parms.in
+++ b/download/parms/makefile-parms.in
@@ -1,6 +1,9 @@
 abs_top_builddir = @abs_top_builddir@
 WGET=@WGET@
-include $(abs_top_builddir)/download/headers-sparsesolver.inc
+
+# FFCS - let "make clean" work even if include file is not found
+-include $(abs_top_builddir)/download/headers-sparsesolver.inc
+
 # path for this directory 
 PARMS_ROOT	= $(abs_top_builddir)/download/parms/pARMS_2.2
 
@@ -25,7 +28,10 @@ ARFLAGS	= @ARFLAGS@ #cr
 # Options for a generic LINUX configuration 
 #################################
  CC	=	@MPICC@
- CFLAGS	= $(DBG) $(DARCH) $(DCHNAME)  @CFLAGS@
+
+ # FFCS - "-I MPI_INC_DIR" required on MacOS 10.8 MacPorts+OpenMPI
+ CFLAGS	= $(DBG) $(DARCH) $(DCHNAME)  @CFLAGS@ -I @MPI_INC_DIR@
+
  INCLUDE_METIS =     #-I
  METIS_HOME  =       #-L/Users/morice/work/ParMetis-3.1.1/ -lparmetis -lmetis 
 
diff --git a/download/pastix/Makefile b/download/pastix/Makefile
index 97495fd..bf51aa5 100644
--- a/download/pastix/Makefile
+++ b/download/pastix/Makefile
@@ -1,143 +1,157 @@
-# Downloading and compiling extra libraries
-# -----------------------------------------
-
-# $Id$
-include config.in
-
-all-local: pastix
-
-# Downloading and compiling pastix
-# http://gforge.inria.fr/frs/download.php/21873/
-# ------------------------------
-DIRPKG   = ../pkg
-SRCDIR   = pastix_release_$(VERSION)
-PACKAGE1 = $(DIRPKG)/pastix_release_$(VERSION).tar.bz2
-SERVER   = http://gforge.inria.fr/frs/download.php/21873/
-INSTALL  = ../..
-VERSION  = 2200
-
-VERSIONTYPE=$(VERSIONINT)$(VERSIONPRC)$(VERSIONFLT)
-VERSIONTYPECOMPLEX=$(VERSIONINT)_complex
-VERSIONNAME=$(VERSIONBIT)$(VERSIONMPI)$(VERSIONSMP)$(VERSIONBUB)$(VERSIONTYPE)$(VERSIONORD)_$(HOSTARCH)
-PASTIX_DIR = $(abs_top_builddir)/download/pastix/$(SRCDIR)/install
-
-ifneq (,$(findstring libtool,$(ARPROG)))
-	OBJLIBTOOL = $(SRCDIR)/src/sopalin/obj/$(HOSTARCH)/*.o $(SRCDIR)/src/blend/obj/$(HOSTARCH)/*.o $(SRCDIR)/src/fax/obj/$(HOSTARCH)/*.o $(SRCDIR)/src/kass/obj/$(HOSTARCH)/*.o $(SRCDIR)/src/order/obj/$(HOSTARCH)/*.o $(SRCDIR)/src/symbol/obj/$(HOSTARCH)/*.o $(SRCDIR)/src/common/obj/$(HOSTARCH)/*.o
-else
-	OBJLIBTOOL = 
-endif
-
-pastix: FAIRE
-
-
-WHERE: 
-	if [ -f $(SRCDIR)/FAIT  ] ;then \
-	echo double_pastix LD -L at DIR@/lib/pastix/double   -lpastix   >../lib/WHERE.pastix ;\
-	echo double_pastix INCLUDE -I at DIR@/include/pastix/double >> ../lib/WHERE.pastix ;\
-	echo complex_pastix LD -L at DIR@/lib/pastix/complex   -lpastix   >>../lib/WHERE.pastix ;\
-	echo complex_pastix INCLUDE -I at DIR@/include/pastix/complex >> ../lib/WHERE.pastix ;\
-	fi
-
-FAIRE:$(SRCDIR)/FAIT 
-	$(MAKE) WHERE
-	touch FAIRE
-
-config.in: ../Makefile ../../config.status	Makefile
-	../../config.status  --file="config.in:config-pastix-real.in"
-	../../config.status  --file="config-complex.in:config-pastix-complex.in"
-
-install:$(SRCDIR)/FAIT
-
-$(SRCDIR)/FAIT: $(SRCDIR) 
-	cp config.in $(SRCDIR)/src/
-	cd $(SRCDIR)/src; $(MAKE) expor
-	#ifndef (,$(OBJLIBTOOL)) # redefinition of "cd $(SRCDIR)/src; $(MAKE) install" for libtool
-	rm -f $(SRCDIR)/install/pastix*.h $(SRCDIR)/install/pastix*.in $(SRCDIR)/install/murge*.inc
-	$(abs_top_builddir)/download/pastix/$(SRCDIR)/src/utils/bin/${HOSTARCH}/genheader $(PASTIX_DIR)/pastix$(VERSIONTYPE).h $(PASTIX_DIR)/pastix_fortran$(VERSIONTYPE).h \
-	$(PASTIX_DIR)/murge$(VERSIONTYPE).inc $(SRCDIR)/src/murge/include/murge.h $(SRCDIR)/src/murge/scripts/genfort.pl
-	cat $(SRCDIR)/src/../bin/$(HOSTARCH)/pastix.h         >> $(PASTIX_DIR)/pastix$(VERSIONTYPE).h
-	cat $(SRCDIR)/src/common/src/api.h                    >> $(PASTIX_DIR)/pastix$(VERSIONTYPE).h
-	cat $(SRCDIR)/src/../bin/$(HOSTARCH)/pastix_fortran.inc >> $(PASTIX_DIR)/murge$(VERSIONTYPE).inc
-	ln -sf $(PASTIX_DIR)/pastix$(VERSIONTYPE).h         	$(PASTIX_DIR)/pastix.h
-	ln -sf $(PASTIX_DIR)/pastix_fortran$(VERSIONTYPE).h 	$(PASTIX_DIR)/pastix_fortran.h
-	ln -sf $(PASTIX_DIR)/murge$(VERSIONTYPE).inc	 	$(PASTIX_DIR)/murge.inc
-	cp  $(SRCDIR)/src/sopalin/src/csc_utils.h                     $(PASTIX_DIR)/csc_utils$(VERSIONTYPE).h
-	ln -fs $(PASTIX_DIR)/csc_utils$(VERSIONTYPE).h $(PASTIX_DIR)/csc_utils.h
-	cp  $(SRCDIR)/src/sopalin/src/cscd_utils.h                    $(PASTIX_DIR)/cscd_utils${VERSIONTYPE}.h
-	ln -fs $(PASTIX_DIR)/cscd_utils$(VERSIONTYPE).h $(PASTIX_DIR)/cscd_utils.h
-	cp  $(SRCDIR)/src/common/src/nompi.h                          $(PASTIX_DIR)/pastix_nompi.h
-	cp  $(SRCDIR)/src/murge/include/murge.h 			 $(PASTIX_DIR)/murge.h
-	$(ARPROG) $(ARFLAGS) $(SRCDIR)/install/libpastix$(VERSIONNAME).a $(OBJLIBTOOL)
-	ranlib $(SRCDIR)/install/libpastix$(VERSIONNAME).a
-	ln -sf $(PASTIX_DIR)/libpastix$(VERSIONNAME).a $(PASTIX_DIR)/libpastix.a
-	cp $(PASTIX_DIR)/../bin/$(HOSTARCH)/libpastix_murge.a $(PASTIX_DIR)/libpastix_murge$(VERSIONNAME).a
-	ln -sf $(PASTIX_DIR)/libpastix_murge$(VERSIONNAME).a $(PASTIX_DIR)/libpastix_murge.a
-	#else
-	#cd $(SRCDIR)/src; $(MAKE) install
-	#endif 
-	mkdir -p ../include/pastix/double
-	cp $(SRCDIR)/install/*.h ../include/pastix/double/
-	mkdir -p ../lib/pastix/double
-	cp $(SRCDIR)/install/*.a ../lib/pastix/double/
-	cd $(SRCDIR)/src/ &&  $(MAKE) clean 
-	#complex version
-	cp config-complex.in $(SRCDIR)/src/config.in	
-	cd $(SRCDIR)/src/;$(MAKE) expor
-#ifdef ($(OBJLIBTOOL))
-	rm -f $(SRCDIR)/install/pastix*.h $(SRCDIR)/install/pastix*.in $(SRCDIR)/install/murge*.inc
-	$(abs_top_builddir)/download/pastix/$(SRCDIR)/src/utils/bin/${HOSTARCH}/genheader $(PASTIX_DIR)/pastix$(VERSIONTYPECOMPLEX).h $(PASTIX_DIR)/pastix_fortran$(VERSIONTYPECOMPLEX).h \
-	$(PASTIX_DIR)/murge$(VERSIONTYPECOMPLEX).inc $(SRDIR)/src/murge/include/murge.h $(SRDIR)/src/murge/scripts/genfort.pl
-	cat $(SRCDIR)/src/../bin/$(HOSTARCH)/pastix.h         >> $(PASTIX_DIR)/pastix$(VERSIONTYPECOMPLEX).h
-	cat $(SRCDIR)/src/common/src/api.h                    >> $(PASTIX_DIR)/pastix$(VERSIONTYPECOMPLEX).h
-	cat $(SRCDIR)/src/../bin/$(HOSTARCH)/pastix_fortran.inc >> $(PASTIX_DIR)/murge$(VERSIONTYPECOMPLEX).inc
-	ln -sf $(PASTIX_DIR)/pastix$(VERSIONTYPECOMPLEX).h         	$(PASTIX_DIR)/pastix.h
-	ln -sf $(PASTIX_DIR)/pastix_fortran$(VERSIONTYPECOMPLEX).h 	$(PASTIX_DIR)/pastix_fortran.h
-	ln -sf $(PASTIX_DIR)/murge$(VERSIONTYPECOMPLEX).inc	 	$(PASTIX_DIR)/murge.inc
-	cp  $(SRCDIR)/src/sopalin/src/csc_utils.h                     $(PASTIX_DIR)/csc_utils$(VERSIONTYPECOMPLEX).h
-	ln -fs $(PASTIX_DIR)/csc_utils$(VERSIONTYPECOMPLEX).h $(PASTIX_DIR)/csc_utils.h
-	cp  $(SRCDIR)/src/sopalin/src/cscd_utils.h                    $(PASTIX_DIR)/cscd_utils${VERSIONTYPECOMPLEX}.h
-	ln -fs $(PASTIX_DIR)/cscd_utils$(VERSIONTYPECOMPLEX).h $(PASTIX_DIR)/cscd_utils.h
-	cp  $(SRCDIR)/src/common/src/nompi.h                          $(PASTIX_DIR)/pastix_nompi.h
-	cp  $(SRCDIR)/src/murge/include/murge.h 			 $(PASTIX_DIR)/murge.h
-	$(ARPROG) $(ARFLAGS) $(SRCDIR)/install/libpastix$(VERSIONNAME).a $(OBJLIBTOOL)
-	ranlib $(SRCDIR)/install/libpastix$(VERSIONNAME).a
-	ln -sf $(PASTIX_DIR)/libpastix$(VERSIONNAME).a $(PASTIX_DIR)/libpastix.a
-	cp $(PASTIX_DIR)/../bin/$(HOSTARCH)/libpastix_murge.a $(PASTIX_DIR)/libpastix_murge$(VERSIONNAME).a
-	ln -sf $(PASTIX_DIR)/libpastix_murge$(VERSIONNAME).a $(PASTIX_DIR)/libpastix_murge.a
-#else
-	#cd $(SRCDIR)/src/ && $(MAKE) install -C $(SRCDIR)/src
-#endif
-	mkdir -p ../include/pastix/complex
-	cp $(SRCDIR)/install/*.h ../include/pastix/complex/
-	mkdir -p ../lib/pastix/complex
-	cp $(SRCDIR)/install/*.a ../lib/pastix/complex/
-	(cd ../include/pastix/complex/; patch pastix_long_complex.h)   <patch-pastix_long_complex.h
-	(cd ../include/pastix/complex/; patch pastix.h) <patch-pastix_long_complex.h
-	touch $(SRCDIR)/FAIT
-
-
-
-$(SRCDIR): $(PACKAGE1)
-	tar xvfj $(PACKAGE1)
-	#cd $(SRCDIR)/src/; patch -p1 < ../../pastix_release_2200-gen.patch
-	cd $(SRCDIR)/src/blend/src/; patch -p2 < ../../../../pastix_release_2200-blend.patch
-	touch $(SRCDIR)
-
-$(PACKAGE1):
-	-mkdir $(DIRPKG);
-	cd $(DIRPKG);$(WGET)   $(SERVER)/`basename $(PACKAGE1)`
-
-clean-local:
-	-rm config.in FAIRE ../lib/WHERE.parms
-	-rm $(SRCDIR)/FAIT
-	-rm -rf ../include/pastix/double
-	-rm -rf ../lib/pastix/double
-	-rm -rf ../include/pastix/complex
-	-rm -rf ../lib/pastix/complex
-	-rm -rf $(SRCDIR)
-	-cd $(SRCDIR)/src &&  $(MAKE) clean 
-
-clean: clean-local
-
-
-.PHONY:$(SRCDIR)/$(INSTALL)
\ No newline at end of file
+# Downloading and compiling extra libraries
+# -----------------------------------------
+
+include config.in
+
+all-local: pastix
+
+# Downloading and compiling pastix
+# http://gforge.inria.fr/frs/download.php/21873/
+# ------------------------------
+DIRPKG   = ../pkg
+SRCDIR   = pastix_release_$(VERSION)
+PACKAGE1 = $(DIRPKG)/pastix_release_$(VERSION).tar.bz2
+SERVER   = http://gforge.inria.fr/frs/download.php/21873/
+INSTALL  = ../..
+VERSION  = 2200
+
+VERSIONTYPE=$(VERSIONINT)$(VERSIONPRC)$(VERSIONFLT)
+VERSIONTYPECOMPLEX=$(VERSIONINT)_complex
+VERSIONNAME=$(VERSIONBIT)$(VERSIONMPI)$(VERSIONSMP)$(VERSIONBUB)$(VERSIONTYPE)$(VERSIONORD)_$(HOSTARCH)
+PASTIX_DIR = $(abs_top_builddir)/download/pastix/$(SRCDIR)/install
+
+ifneq (,$(findstring libtool,$(ARPROG)))
+	OBJLIBTOOL = $(SRCDIR)/src/sopalin/obj/$(HOSTARCH)/*.o $(SRCDIR)/src/blend/obj/$(HOSTARCH)/*.o $(SRCDIR)/src/fax/obj/$(HOSTARCH)/*.o $(SRCDIR)/src/kass/obj/$(HOSTARCH)/*.o $(SRCDIR)/src/order/obj/$(HOSTARCH)/*.o $(SRCDIR)/src/symbol/obj/$(HOSTARCH)/*.o $(SRCDIR)/src/common/obj/$(HOSTARCH)/*.o
+else
+	OBJLIBTOOL = 
+endif
+
+pastix: FAIRE
+
+
+# FFCS - parallel make rules
+WHERE: install
+	echo double_pastix LD -L at DIR@/lib/pastix/double   -lpastix   >$(SRCDIR)/$(INSTALL)/lib/WHERE.pastix ;
+	echo double_pastix INCLUDE -I at DIR@/include/pastix/double >> $(SRCDIR)/$(INSTALL)/lib/WHERE.pastix ;
+	echo complex_pastix LD -L at DIR@/lib/pastix/complex   -lpastix   >>$(SRCDIR)/$(INSTALL)/lib/WHERE.pastix ;
+	echo complex_pastix INCLUDE -I at DIR@/include/pastix/complex >> $(SRCDIR)/$(INSTALL)/lib/WHERE.pastix ;
+
+FAIRE:$(SRCDIR)/FAIT 
+	$(MAKE) WHERE
+	touch FAIRE
+
+config.in: ../Makefile ../../config.status	Makefile
+	../../config.status  --file="config.in:config-pastix-real.in"
+	../../config.status  --file="config-complex.in:config-pastix-complex.in"
+
+install:$(SRCDIR)/FAIT
+
+$(SRCDIR)/FAIT: $(SRCDIR) 
+	cp config.in $(SRCDIR)/src/
+#
+#	FFCS - 16/1/13 - this crashes in parallel
+#
+	cd $(SRCDIR)/src; $(MAKE) -j1 expor
+	#ifndef (,$(OBJLIBTOOL)) # redefinition of "cd $(SRCDIR)/src; $(MAKE) install" for libtool
+	rm -f $(SRCDIR)/install/pastix*.h $(SRCDIR)/install/pastix*.in $(SRCDIR)/install/murge*.inc
+	$(abs_top_builddir)/download/pastix/$(SRCDIR)/src/utils/bin/${HOSTARCH}/genheader $(PASTIX_DIR)/pastix$(VERSIONTYPE).h $(PASTIX_DIR)/pastix_fortran$(VERSIONTYPE).h \
+	$(PASTIX_DIR)/murge$(VERSIONTYPE).inc $(SRCDIR)/src/murge/include/murge.h $(SRCDIR)/src/murge/scripts/genfort.pl
+	cat $(SRCDIR)/src/../bin/$(HOSTARCH)/pastix.h         >> $(PASTIX_DIR)/pastix$(VERSIONTYPE).h
+	cat $(SRCDIR)/src/common/src/api.h                    >> $(PASTIX_DIR)/pastix$(VERSIONTYPE).h
+	cat $(SRCDIR)/src/../bin/$(HOSTARCH)/pastix_fortran.inc >> $(PASTIX_DIR)/murge$(VERSIONTYPE).inc
+	ln -sf $(PASTIX_DIR)/pastix$(VERSIONTYPE).h         	$(PASTIX_DIR)/pastix.h
+	ln -sf $(PASTIX_DIR)/pastix_fortran$(VERSIONTYPE).h 	$(PASTIX_DIR)/pastix_fortran.h
+	ln -sf $(PASTIX_DIR)/murge$(VERSIONTYPE).inc	 	$(PASTIX_DIR)/murge.inc
+	cp  $(SRCDIR)/src/sopalin/src/csc_utils.h                     $(PASTIX_DIR)/csc_utils$(VERSIONTYPE).h
+	ln -fs $(PASTIX_DIR)/csc_utils$(VERSIONTYPE).h $(PASTIX_DIR)/csc_utils.h
+	cp  $(SRCDIR)/src/sopalin/src/cscd_utils.h                    $(PASTIX_DIR)/cscd_utils${VERSIONTYPE}.h
+	ln -fs $(PASTIX_DIR)/cscd_utils$(VERSIONTYPE).h $(PASTIX_DIR)/cscd_utils.h
+	cp  $(SRCDIR)/src/common/src/nompi.h                          $(PASTIX_DIR)/pastix_nompi.h
+	cp  $(SRCDIR)/src/murge/include/murge.h 			 $(PASTIX_DIR)/murge.h
+	$(ARPROG) $(ARFLAGS) $(SRCDIR)/install/libpastix$(VERSIONNAME).a $(OBJLIBTOOL)
+	ranlib $(SRCDIR)/install/libpastix$(VERSIONNAME).a
+	ln -sf $(PASTIX_DIR)/libpastix$(VERSIONNAME).a $(PASTIX_DIR)/libpastix.a
+	cp $(PASTIX_DIR)/../bin/$(HOSTARCH)/libpastix_murge.a $(PASTIX_DIR)/libpastix_murge$(VERSIONNAME).a
+	ln -sf $(PASTIX_DIR)/libpastix_murge$(VERSIONNAME).a $(PASTIX_DIR)/libpastix_murge.a
+	#else
+	#cd $(SRCDIR)/src; $(MAKE) install
+	#endif 
+	mkdir -p $(SRCDIR)/$(INSTALL)/include/pastix/double
+	cp $(SRCDIR)/install/*.h $(SRCDIR)/$(INSTALL)/include/pastix/double/
+	mkdir -p $(SRCDIR)/$(INSTALL)/lib/pastix/double
+	cp $(SRCDIR)/install/*.a $(SRCDIR)/$(INSTALL)/lib/pastix/double/
+	cd $(SRCDIR)/src/ &&  $(MAKE) clean 
+	#complex version
+	cp config-complex.in $(SRCDIR)/src/config.in	
+#
+#	FFCS - 16/1/13 - this crashes in parallel
+#
+	cd $(SRCDIR)/src/;$(MAKE) -j1 expor
+#ifdef ($(OBJLIBTOOL))
+	rm -f $(SRCDIR)/install/pastix*.h $(SRCDIR)/install/pastix*.in $(SRCDIR)/install/murge*.inc
+	$(abs_top_builddir)/download/pastix/$(SRCDIR)/src/utils/bin/${HOSTARCH}/genheader $(PASTIX_DIR)/pastix$(VERSIONTYPECOMPLEX).h $(PASTIX_DIR)/pastix_fortran$(VERSIONTYPECOMPLEX).h \
+	$(PASTIX_DIR)/murge$(VERSIONTYPECOMPLEX).inc $(SRDIR)/src/murge/include/murge.h $(SRDIR)/src/murge/scripts/genfort.pl
+	cat $(SRCDIR)/src/../bin/$(HOSTARCH)/pastix.h         >> $(PASTIX_DIR)/pastix$(VERSIONTYPECOMPLEX).h
+	cat $(SRCDIR)/src/common/src/api.h                    >> $(PASTIX_DIR)/pastix$(VERSIONTYPECOMPLEX).h
+	cat $(SRCDIR)/src/../bin/$(HOSTARCH)/pastix_fortran.inc >> $(PASTIX_DIR)/murge$(VERSIONTYPECOMPLEX).inc
+	ln -sf $(PASTIX_DIR)/pastix$(VERSIONTYPECOMPLEX).h         	$(PASTIX_DIR)/pastix.h
+	ln -sf $(PASTIX_DIR)/pastix_fortran$(VERSIONTYPECOMPLEX).h 	$(PASTIX_DIR)/pastix_fortran.h
+	ln -sf $(PASTIX_DIR)/murge$(VERSIONTYPECOMPLEX).inc	 	$(PASTIX_DIR)/murge.inc
+	cp  $(SRCDIR)/src/sopalin/src/csc_utils.h                     $(PASTIX_DIR)/csc_utils$(VERSIONTYPECOMPLEX).h
+	ln -fs $(PASTIX_DIR)/csc_utils$(VERSIONTYPECOMPLEX).h $(PASTIX_DIR)/csc_utils.h
+	cp  $(SRCDIR)/src/sopalin/src/cscd_utils.h                    $(PASTIX_DIR)/cscd_utils${VERSIONTYPECOMPLEX}.h
+	ln -fs $(PASTIX_DIR)/cscd_utils$(VERSIONTYPECOMPLEX).h $(PASTIX_DIR)/cscd_utils.h
+	cp  $(SRCDIR)/src/common/src/nompi.h                          $(PASTIX_DIR)/pastix_nompi.h
+	cp  $(SRCDIR)/src/murge/include/murge.h 			 $(PASTIX_DIR)/murge.h
+	$(ARPROG) $(ARFLAGS) $(SRCDIR)/install/libpastix$(VERSIONNAME).a $(OBJLIBTOOL)
+	ranlib $(SRCDIR)/install/libpastix$(VERSIONNAME).a
+	ln -sf $(PASTIX_DIR)/libpastix$(VERSIONNAME).a $(PASTIX_DIR)/libpastix.a
+	cp $(PASTIX_DIR)/../bin/$(HOSTARCH)/libpastix_murge.a $(PASTIX_DIR)/libpastix_murge$(VERSIONNAME).a
+	ln -sf $(PASTIX_DIR)/libpastix_murge$(VERSIONNAME).a $(PASTIX_DIR)/libpastix_murge.a
+#else
+	#cd $(SRCDIR)/src/ && $(MAKE) install -C $(SRCDIR)/src
+#endif
+	mkdir -p $(SRCDIR)/$(INSTALL)/include/pastix/complex
+	cp $(SRCDIR)/install/*.h $(SRCDIR)/$(INSTALL)/include/pastix/complex/
+	mkdir -p $(SRCDIR)/$(INSTALL)/lib/pastix/complex
+	cp $(SRCDIR)/install/*.a $(SRCDIR)/$(INSTALL)/lib/pastix/complex/
+	(cd $(SRCDIR)/$(INSTALL)/include/pastix/complex/; patch pastix_long_complex.h)   <patch-pastix_long_complex.h
+	(cd $(SRCDIR)/$(INSTALL)/include/pastix/complex/; patch pastix.h) <patch-pastix_long_complex.h
+	touch $(SRCDIR)/FAIT
+
+
+
+$(SRCDIR): $(PACKAGE1)
+	tar xvfj $(PACKAGE1)
+	#cd $(SRCDIR)/src/; patch -p1 < ../../pastix_release_2200-gen.patch
+	cd $(SRCDIR)/src/blend/src/; patch -p2 < ../../../../pastix_release_2200-blend.patch
+	touch $(SRCDIR)
+
+$(PACKAGE1):
+	-mkdir $(DIRPKG);
+#
+# FFCS - 23/4/13 - --no-check-certificate always required here, even
+# if [[file:../../configure.ac::no-check-certificate]] decides otherwise.
+#
+	cd $(DIRPKG);$(WGET) --no-check-certificate $(SERVER)/`basename $(PACKAGE1)`
+
+# FFCS: avoid loops when SRCDIR does not exist
+clean-local:
+	-cd $(SRCDIR)/src &&  $(MAKE) clean 
+
+clean: clean-local
+	-rm config.in FAIRE 
+	-rm $(SRCDIR)/FAIT
+	-rm -rf $(SRCDIR)/$(INSTALL)/include/pastix/double
+	-rm -rf $(SRCDIR)/$(INSTALL)/lib/pastix/double
+	-rm -rf $(SRCDIR)/$(INSTALL)/include/pastix/complex
+	-rm -rf $(SRCDIR)/$(INSTALL)/lib/pastix/complex
+	-rm -rf $(SRCDIR)
+#
+# FFCS - also force reconfiguration
+#
+	-rm config.in config-complex.in config.log
+	-rm config.log
+	-rm $(PACKAGE1)
+
+.PHONY:$(SRCDIR)/$(INSTALL)
diff --git a/download/pastix/config-pastix-complex.in b/download/pastix/config-pastix-complex.in
index e5fa34c..3de8ff1 100644
--- a/download/pastix/config-pastix-complex.in
+++ b/download/pastix/config-pastix-complex.in
@@ -1,5 +1,5 @@
 abs_top_builddir=@abs_top_builddir@
-include $(abs_top_builddir)/download/headers-sparsesolver.inc
+-include $(abs_top_builddir)/download/headers-sparsesolver.inc
 HOSTARCH    = @PASTIX_HOSTARCH@#i686_mac
 VERSIONBIT  = _ at SIZEOF_PTRINBIT@bit
 EXEEXT      =
diff --git a/download/pastix/config-pastix-real.in b/download/pastix/config-pastix-real.in
index 543cc86..085aaad 100644
--- a/download/pastix/config-pastix-real.in
+++ b/download/pastix/config-pastix-real.in
@@ -1,5 +1,5 @@
 abs_top_builddir=@abs_top_builddir@
-include $(abs_top_builddir)/download/headers-sparsesolver.inc
+-include $(abs_top_builddir)/download/headers-sparsesolver.inc
 HOSTARCH    = @PASTIX_HOSTARCH@
 VERSIONBIT  = _ at SIZEOF_PTRINBIT@bit
 EXEEXT      =
diff --git a/download/scalapack/Makefile b/download/scalapack/Makefile
index a96e645..54c91d7 100644
--- a/download/scalapack/Makefile
+++ b/download/scalapack/Makefile
@@ -1,75 +1,80 @@
-# Downloading and compiling extra libraries
-# -----------------------------------------
-
-# $Id$
-include SLmake.inc
-
-all-local: scalapack
-
-# Downloading and compiling scalapack
-# ------------------------------
-# http://www.netlib.org/scalapack/
-# Hips information
-DIRPKG=../pkg
-SRCDIR=scalapack-2.0.2
-PACKAGE1=$(DIRPKG)/scalapack-2.0.2.tgz
-SERVER=http://www.netlib.org/scalapack/
-INSTALL=../..
-DIR1 = TOOLS/LAPACK/*.o
-DIR2 = TOOLS/*.o
-DIR3 = PBLAS/SRC/PBBLAS/*.o
-DIR4 = PBLAS/SRC/PTZBLAS/*.o
-DIR5 = PBLAS/SRC/PTOOLS/*.o
-DIR6 = PBLAS/SRC/*.o
-DIR7 = REDIST/SRC/*.o
-DIR8 = SRC/*.o
-DIR9 = BLACS/SRC/*.o BLACS/SRC/*.oo
-
-scalapack: FAIRE
-
-$(SRCDIR)/FAIT-202:$(SRCDIR)/tag-tar
-	cp SLmake.inc $(SRCDIR)
-	cd $(SRCDIR);$(MAKE) lib
-	rm $(SRCDIR)/libscalapack.a
-	cd $(SRCDIR);$(ARCH) $(ARCHFLAGS) libscalapack.a $(DIR1) $(DIR2) $(DIR3) $(DIR4) $(DIR5) $(DIR6) $(DIR7) $(DIR8) $(DIR9)	
-	$(RANLIB) $(SRCDIR)/libscalapack.a
-	touch $(SRCDIR)/FAIT-202
-install:
-	mkdir -p ../include
-	cp $(SRCDIR)/SRC/*.h ../include
-	mkdir -p ../lib
-	cp $(SRCDIR)/libscalapack.a ../lib
-
-WHERE:
-	if [ -f $(SRCDIR)/FAIT-202 ] ; then \
-	make install;  \
-	echo scalapack LD -L at DIR@/lib  -lscalapack   >../lib/WHERE.scalapack ;\
-	echo scalapack INCLUDE -I at DIR@/include  >> ../lib/WHERE.scalapack ;\
-	fi
-
-FAIRE: $(SRCDIR)/FAIT-202
-	$(MAKE) WHERE
-	touch FAIRE 
-
-SLmake.inc: ../../config.status	Makefile SLmake-scalapack.inc
-	../../config.status  --file="SLmake.inc:SLmake-scalapack.inc"
-
-$(SRCDIR)/tag-tar: $(PACKAGE1)
-	gunzip -c $(PACKAGE1) | tar xvf -
-	touch $(SRCDIR)/tag-tar
-
-$(PACKAGE1):
-	-mkdir $(DIRPKG)
-	cd $(DIRPKG);$(WGET)  $(SERVER)/`basename $(PACKAGE1)`
-
-clean-local:
-	-cd $(SRCDIR) && $(MAKE) cleanlib  -C $(SRCDIR)
-	-rm SLmake.inc FAIRE ../lib/WHERE.scalapack
-	-rm -rf ../include/{pblas.h,pxsyevx.h,tools.h}
-	-rm -rf ../lib/libscalapack.a ../lib/WHERE.scalapack 
-	-rm -rf $(SRCDIR)
-
-clean: clean-local
-
-
+# Downloading and compiling extra libraries
+# -----------------------------------------
+
+include SLmake.inc
+
+all-local: scalapack
+
+# FFCS: parallel compilation crashes on Win32 (same archive updated from 2 different parallel makes)
+MAKEFLAGS=-j 1
+
+# Downloading and compiling scalapack
+# ------------------------------
+# http://www.netlib.org/scalapack/
+# Hips information
+DIRPKG=../pkg
+SRCDIR=scalapack-2.0.2
+PACKAGE1=$(DIRPKG)/scalapack-2.0.2.tgz
+SERVER=http://www.netlib.org/scalapack/
+INSTALL=../..
+
+# FFCS: shorten argument length to avoid "sh: ../ar: Argument list too long" under Cygwin
+DIR1 = TOOLS/LAPACK/*.o
+DIR2 = TOOLS/*.o
+DIR3 = PBLAS/SRC/PBBLAS/*.o
+DIR4 = PBLAS/SRC/PTZBLAS/*.o
+DIR5 = PBLAS/SRC/PTOOLS/*.o
+DIR6 = PBLAS/SRC/*.o
+DIR7 = REDIST/SRC/*.o
+DIR8 = SRC/*.o
+DIR9 = BLACS/SRC/*.o BLACS/SRC/*.oo
+
+scalapack: FAIRE
+
+# FFCS: shorten argument length to avoid "sh: ../ar: Argument list too long" under Cygwin
+$(SRCDIR)/FAIT-202:$(SRCDIR)/tag-tar
+	cp SLmake.inc $(SRCDIR)
+	cd $(SRCDIR);$(MAKE) lib
+	rm $(SRCDIR)/libscalapack.a
+	cd $(SRCDIR) && $(ARCH) $(ARCHFLAGS) libscalapack.a $(DIR1) $(DIR2) $(DIR3) $(DIR4) $(DIR5) $(DIR6) $(DIR7) $(DIR8) $(DIR9)
+	$(RANLIB) $(SRCDIR)/libscalapack.a
+	touch $(SRCDIR)/FAIT-202
+install:
+	mkdir -p ../include
+	cp $(SRCDIR)/SRC/*.h ../include
+	mkdir -p ../lib
+	cp $(SRCDIR)/libscalapack.a ../lib
+
+WHERE:
+	if [ -f $(SRCDIR)/FAIT-202 ] ; then \
+	make install;  \
+	echo scalapack LD -L at DIR@/lib  -lscalapack   >../lib/WHERE.scalapack ;\
+	echo scalapack INCLUDE -I at DIR@/include  >> ../lib/WHERE.scalapack ;\
+	fi
+
+FAIRE: $(SRCDIR)/FAIT-202
+	$(MAKE) WHERE
+	touch FAIRE 
+
+SLmake.inc: ../../config.status	Makefile SLmake-scalapack.inc
+	../../config.status  --file="SLmake.inc:SLmake-scalapack.inc"
+
+$(SRCDIR)/tag-tar: $(PACKAGE1)
+	gunzip -c $(PACKAGE1) | tar xvf -
+	touch $(SRCDIR)/tag-tar
+
+$(PACKAGE1):
+	-mkdir $(DIRPKG)
+	cd $(DIRPKG);$(WGET)  $(SERVER)/`basename $(PACKAGE1)`
+
+clean:
+#	FFCS - need to clean completely even in case of error
+	-rm SLmake.inc FAIRE FAIT
+#	FFCS - make sure that all directories are cleaned. Thisis especially important under Windows because there is no
+#	compilation dependencies control there (see
+#	[[file:c:/cygwin/home/alh/ffcs/dist/configure.ac::dependency_tracking]])
+	-rm -rf scalapack-*
+	-rm config.log
+	-rm $(PACKAGE1)
+
 .PHONY:$(SRCDIR)/$(INSTALL)
\ No newline at end of file
diff --git a/download/scalapack/SLmake-scalapack.inc b/download/scalapack/SLmake-scalapack.inc
index 63d66c2..6eb5dc7 100644
--- a/download/scalapack/SLmake-scalapack.inc
+++ b/download/scalapack/SLmake-scalapack.inc
@@ -29,8 +29,12 @@ CDEFS         = @CFLAGSF77@ -DNO_IEEE $(USEMPI)
 FC            = @MPIF77@ 
 CC            = @MPICC@ 
 NOOPT         = -O0 @CNOFLAGS@
+
+# FFCS - some return statements without value cause trouble on MacOS
+# FFCS - add path to mpi.h (required for MacOS 10.8 + MacPorts OpenMPI)
+# FFCS - added @CNOFLAGS@ according to upstream changes
+CCFLAGS       = -O3 -Wreturn-type @CFLAGS@ -I @MPI_INC_DIR@ @CNOFLAGS@
 FCFLAGS       = -O3 @CNOFLAGS@
-CCFLAGS       = -O3 @CNOFLAGS@
 FCLOADER      = $(FC)
 CCLOADER      = $(CC)
 FCLOADFLAGS   = $(FCFLAGS)
diff --git a/download/scotch/._Makefile.patch b/download/scotch/._Makefile.patch
new file mode 100644
index 0000000..40d3196
Binary files /dev/null and b/download/scotch/._Makefile.patch differ
diff --git a/download/scotch/Makefile b/download/scotch/Makefile
index 0a3d15a..380af31 100644
--- a/download/scotch/Makefile
+++ b/download/scotch/Makefile
@@ -1,72 +1,82 @@
-# Downloading and compiling extra libraries
-# -----------------------------------------
-
-# $Id$
-include Makefile.inc
-
-all-local: scotch
-
-# Downloading and compiling scotch
-# -------------------------------
-# http://gforge.inria.fr/frs/download.php/23391/scotch_5.1.7_esmumps.tar.gz
-# Scotch information
-DIRPKG=../pkg
-SRCDIR=scotch_$(scotch_VERSION)
-PACKAGE=$(DIRPKG)/scotch_$(scotch_VERSION_LOCAL).tar.gz
-SERVER=https://gforge.inria.fr/frs/download.php/23391
-INSTALL=../..
-scotch_VERSION=5.1_esmumps
-scotch_VERSION_LOCAL=5.1.6_esmumps
-
-scotch: FAIRE
-
-$(SRCDIR)/AFAIRE:
-	$(MAKE) install 
-
-FAIRE: $(SRCDIR)/FAIT
-	$(MAKE)  WHERE
-	touch FAIRE
-Makefile.inc: ../../config.status Makefile-scotch.inc Makefile
-	../../config.status  --file="Makefile.inc:Makefile-scotch.inc"
-	case `uname` in *CYGWIN*)  cp Makefile.inc Makefile.inn; sed "s/COPTIONS =/COPTIONS = -D__VC__/" <Makefile.inn > Makefile.inc; rm Makefile.inn ;; esac 
-	case `uname` in *CYGWIN*|*MINGW*)  cp Makefile.inc Makefile.inn; sed -e "s/-DCOMMON_TIMING_OLD//" -e "s/-DCOMMON_RANDOM_FIXED_SEED/-DCOMMON_RANDOM_RAND  -DCOMMON_RANDOM_FIXED_SEED -D'pipe(pfds)=_pipe(pfds,1024,0x8000)'/" <Makefile.inn > Makefile.inc; rm Makefile.inn ;; esac 
-
-$(SRCDIR)/FAIT: $(SRCDIR)
-	cp Makefile.inc $(SRCDIR)/src/
-	cd $(SRCDIR)/src/; make scotch
-	test -z "$(CCP)" || ( cd $(SRCDIR)/src/; make ptscotch)
-	touch $(SRCDIR)/FAIT
-
-install:$(SRCDIR)/FAIT
-	mkdir -p ../include/scotch
-	cp $(SRCDIR)/include/*.h ../include/scotch/
-	cp $(SRCDIR)/lib/*.a ../lib/
-WHERE:
-	if [ -f  $(SRCDIR)/FAIT ] ; then \
-	$(MAKE) install; \
-	test -n "$(CCP)" && echo ptscotch LD -L at DIR@/lib  -lptesmumps -lptscotch -lptscotcherr   >../lib/WHERE.scotch ;\
-	test -n "$(CCP)" && echo ptscotch INCLUDE -I at DIR@/include/scotch  >> ../lib/WHERE.scotch ;\
-	echo scotch LD -L at DIR@/lib   -lscotch -lscotcherr   >>../lib/WHERE.scotch ;\
-	echo scotch INCLUDE -I at DIR@/include/scotch  >> ../lib/WHERE.scotch ;\
-	fi
-
-$(SRCDIR): $(PACKAGE)
-	tar xvzf $(PACKAGE)
-	cd $(SRCDIR)/src/libscotch/; patch -p1 < ../../../scotch_5.1_esmumps.patch
-	cd $(SRCDIR)/src/esmumps/; patch -p1 < ../../../Makefile.patch
-	touch $(SRCDIR)
-
-$(PACKAGE):
-	-mkdir $(DIRPKG);
-	cd $(DIRPKG);$(WGET)    $(SERVER)/`basename $(PACKAGE)`
-
-clean-local:
-	-cd $(SRCDIR)/src && $(MAKE)  realclean  -C $(SRCDIR)/src
-	-rm Makefile.inc ../lib/WHERE.scotch 
-	-rm -rf $(SRCDIR)
-	-rm -fr ../lib/scotch ../lib/WHERE.scotch
-	-rm -fr ../include/scotch 
-	-rm FAIRE 
-clean: clean-local
-
-.PHONY:$(SRCDIR)/$(INSTALL)
+# Downloading and compiling extra libraries
+# -----------------------------------------
+
+# $Id$
+include Makefile.inc
+
+all-local: scotch
+
+# Downloading and compiling scotch
+# -------------------------------
+# http://gforge.inria.fr/frs/download.php/23391/scotch_5.1.7_esmumps.tar.gz
+# Scotch information
+DIRPKG=../pkg
+SRCDIR=scotch_$(scotch_VERSION)
+PACKAGE=$(DIRPKG)/scotch_$(scotch_VERSION_LOCAL).tar.gz
+SERVER=https://gforge.inria.fr/frs/download.php/23391
+INSTALL=../..
+scotch_VERSION=5.1_esmumps
+scotch_VERSION_LOCAL=5.1.6_esmumps
+#  trick to no in MPI on NOT .. 
+TESTMPI= test -n '$(CCP)'
+scotch: FAIRE
+
+$(SRCDIR)/AFAIRE:
+	$(MAKE) install 
+
+FAIRE: $(SRCDIR)/FAIT
+	$(MAKE)  WHERE
+	touch FAIRE
+Makefile.inc: ../../config.status Makefile-scotch.inc Makefile
+	../../config.status  --file="Makefile.inc:Makefile-scotch.inc"
+	case `uname` in *CYGWIN*)  cp Makefile.inc Makefile.inn; sed "s/COPTIONS =/COPTIONS = -D__VC__/" <Makefile.inn > Makefile.inc; rm Makefile.inn ;; esac 
+	case `uname` in *CYGWIN*|*MINGW*)  cp Makefile.inc Makefile.inn; sed -e "s/-DCOMMON_TIMING_OLD//" -e "s/-DCOMMON_RANDOM_FIXED_SEED/-DCOMMON_RANDOM_RAND  -DCOMMON_RANDOM_FIXED_SEED -D'pipe(pfds)=_pipe(pfds,1024,0x8000)'/" <Makefile.inn > Makefile.inc; rm Makefile.inn ;; esac 
+
+# FFCS - 16/1/13 - what was "$(CCP)" used for?
+$(SRCDIR)/FAIT: $(SRCDIR) Makefile.inc
+	cp Makefile.inc $(SRCDIR)/src
+	cd $(SRCDIR)/src && $(MAKE) scotch
+#
+#	FFCS - 16/1/13 - this crashes when run in parallel
+#       FH: compile pt only if mpi is here 
+	if $(TESTMPI) ; then  cd $(SRCDIR)/src && $(MAKE) -j1 ptscotch ; fi
+	touch $(SRCDIR)/FAIT
+
+install:$(SRCDIR)/FAIT
+	mkdir -p $(SRCDIR)/$(INSTALL)/include/scotch
+	cp $(SRCDIR)/include/*.h $(SRCDIR)/$(INSTALL)/include/scotch/
+	cp $(SRCDIR)/lib/*.a $(SRCDIR)/$(INSTALL)/lib/
+
+# FFCS - 16/1/13 - simplifying make rules
+WHERE:$(SRCDIR)/FAIT
+	$(MAKE) install
+	-rm $(SRCDIR)/$(INSTALL)/lib/WHERE.scotch
+	-$(TESTMPI) &&echo ptscotch LD -L at DIR@/lib  -lptesmumps -lptscotch -lptscotcherr   >>$(SRCDIR)/$(INSTALL)/lib/WHERE.scotch
+	-$(TESTMPI) &&echo ptscotch INCLUDE -I at DIR@/include/scotch  >> $(SRCDIR)/$(INSTALL)/lib/WHERE.scotch
+	echo scotch LD -L at DIR@/lib   -lscotch -lscotcherr   >>$(SRCDIR)/$(INSTALL)/lib/WHERE.scotch
+	echo scotch INCLUDE -I at DIR@/include/scotch  >> $(SRCDIR)/$(INSTALL)/lib/WHERE.scotch
+
+$(SRCDIR): $(PACKAGE)
+	tar xvzf $(PACKAGE)
+	cd $(SRCDIR)/src/libscotch/; patch -p1 < ../../../scotch_5.1_esmumps.patch
+	cd $(SRCDIR)/src/esmumps/; patch -p1 < ../../../Makefile.patch
+	touch $(SRCDIR)
+
+# FFCS: (7/2/11) gforge.inria.fr seems to have switched from http to https
+$(PACKAGE):
+	-mkdir $(DIRPKG);
+# FH/ 06/08/13 remove -no-check-certificate  in $(WGET)  command , pb this curl...
+	cd $(DIRPKG);$(WGET)  $(SERVER)/`basename $(PACKAGE)`
+
+
+# FFCS - 28/3/13 - more cleaning
+clean-local:
+	-cd $(SRCDIR)/src && $(MAKE)  realclean  -C $(SRCDIR)/src
+	-rm config.log
+# FH 	-rm $(PACKAGE) 
+
+clean: clean-local
+	-rm Makefile.inc
+	-rm -rf $(SRCDIR)
+	-rm FAIRE 
+.PHONY:$(SRCDIR)/$(INSTALL)
diff --git a/download/scotch/Makefile-scotch.inc b/download/scotch/Makefile-scotch.inc
index b3a2c40..6eb63c2 100644
--- a/download/scotch/Makefile-scotch.inc
+++ b/download/scotch/Makefile-scotch.inc
@@ -1,4 +1,6 @@
-include @abs_top_builddir@/download/headers-sparsesolver.inc
+# ALH - avoid blocking when Makefile.inc is not built yet
+-include @abs_top_builddir@/download/headers-sparsesolver.inc
+
 EXE	=
 LIB	= .a
 OBJ	= .o
@@ -10,7 +12,15 @@ CAT	= cat
 CCS     = @CC@ 
 CCP	= @MPICC@ 
 CCD     = @CC@ -I at MPI_INC_DIR@
-CFLAGS	= @CFLAGS@ $(FFINTSCOTCH) -Drestrict=__restrict -DCOMMON_PTHREAD  -DCOMMON_RANDOM_FIXED_SEED -DCOMMON_TIMING_OLD -DSCOTCH_RENAME -DSCOTCH_DETERMINISTIC #enlever -DSCOTCH_PTHREAD do not allow thread
+
+# FFCS - 16/4/13 - some plain C files seem to need access to mpi.h too
+
+# FFCS - 23/4/13 - remove thread and fork dependency on Windows with
+# -DCOMMON_STUB_FORK without -DCOMMON_PTHREAD
+# [[file:scotch_5.1_esmumps/INSTALL.TXT::COMMON_STUB_FORK]]
+
+CFLAGS	= @CFLAGS@ -I at MPI_INC_DIR@ $(FFINTSCOTCH) -Drestrict=__restrict -DCOMMON_STUB_FORK  -DCOMMON_RANDOM_FIXED_SEED -DCOMMON_TIMING_OLD -DSCOTCH_RENAME -DSCOTCH_DETERMINISTIC
+
 LDFLAGS	= @LDFLAGS@ -lm @MPI_LIB@  @LIBSPTHREAD@  #-L/usr/local/lib/gcc/
 CP	= cp
 LEX	= @LEX@
diff --git a/download/superlu/Makefile b/download/superlu/Makefile
old mode 100644
new mode 100755
index 49976cb..c0f08dc
--- a/download/superlu/Makefile
+++ b/download/superlu/Makefile
@@ -1,138 +1,137 @@
-# Downloading and compiling extra libraries
-# -----------------------------------------
-# $Id$
-
-all-local: superlu
-
-# Downloading and compiling Tetgen
-# ------------------------------
-
-# SUPERLU information
-#http://crd.lbl.gov/~xiaoye/SuperLU/superlu_4.0.tar.gz
-DIRPKG=../pkg
-SRCDIR=SuperLU_4.3
-PACKAGE=superlu_4.3.tar.gz
-PACKAGE_PATH=$(DIRPKG)/$(PACKAGE)
-SERVER=http://crd-legacy.lbl.gov/~xiaoye/SuperLU/
-# http://crd-legacy.lbl.gov/~xiaoye/SuperLU/superlu_4.3.tar.gz
-INSTALL=../..
-SUPERLU_VERSION=4.3
-SUPERLULIB=../$(INSTALL)/lib/libsuperlu_$(SUPERLU_VERSION).a
-include  ff-FLAGS
-
-### LAPACK 
-LAAUX 	= lsame.o xerbla.o
-SLASRC 	= slacon.o 
-DLASRC	= dlacon.o
-CLASRC	= clacon.o scsum1.o icmax1.o
-ZLASRC	= zlacon.o dzsum1.o izmax1.o
-SCLAUX 	= slamch.o
-DZLAUX 	= dlamch.o
-
-### SuperLU 
-ALLAUX 	= superlu_timer.o util.o memory.o get_perm_c.o mmd.o \
-	  sp_coletree.o sp_preorder.o sp_ienv.o relax_snode.o \
-	  heap_relax_snode.o colamd.o
-
-SLUSRC = \
-	sgssv.o sgssvx.o \
-	ssp_blas2.o ssp_blas3.o sgscon.o  \
-	slangs.o sgsequ.o slaqgs.o spivotgrowth.o \
-	sgsrfs.o sgstrf.o sgstrs.o scopy_to_ucol.o \
-	ssnode_dfs.o ssnode_bmod.o \
-	spanel_dfs.o spanel_bmod.o sreadhb.o \
-	scolumn_dfs.o scolumn_bmod.o spivotL.o spruneL.o \
-	smemory.o sutil.o smyblas2.o
-
-DLUSRC = \
-	dgssv.o dgssvx.o \
-	dsp_blas2.o dsp_blas3.o dgscon.o \
-	dlangs.o dgsequ.o dlaqgs.o dpivotgrowth.o  \
-	dgsrfs.o dgstrf.o dgstrs.o dcopy_to_ucol.o \
-	dsnode_dfs.o dsnode_bmod.o \
-	dpanel_dfs.o dpanel_bmod.o dreadhb.o \
-	dcolumn_dfs.o dcolumn_bmod.o dpivotL.o dpruneL.o \
-	dmemory.o dutil.o dmyblas2.o ## dgstrsL.o dgstrsU.o
-
-CLUSRC = \
-	scomplex.o cgssv.o cgssvx.o csp_blas2.o csp_blas3.o cgscon.o \
-	clangs.o cgsequ.o claqgs.o cpivotgrowth.o  \
-	cgsrfs.o cgstrf.o cgstrs.o ccopy_to_ucol.o \
-	csnode_dfs.o csnode_bmod.o \
-	cpanel_dfs.o cpanel_bmod.o creadhb.o \
-	ccolumn_dfs.o ccolumn_bmod.o cpivotL.o cpruneL.o \
-	cmemory.o cutil.o cmyblas2.o
-
-ZLUSRC = \
-	dcomplex.o zgssv.o zgssvx.o zsp_blas2.o zsp_blas3.o zgscon.o \
-	zlangs.o zgsequ.o zlaqgs.o zpivotgrowth.o  \
-	zgsrfs.o zgstrf.o zgstrs.o zcopy_to_ucol.o \
-	zsnode_dfs.o zsnode_bmod.o \
-	zpanel_dfs.o zpanel_bmod.o zreadhb.o \
-	zcolumn_dfs.o zcolumn_bmod.o zpivotL.o zpruneL.o \
-	zmemory.o zutil.o zmyblas2.o
-
-
-OBJ_SUPERLU = $(ALLAUX) $(LAAUX) \
- $(SLUSRC)  $(SLASRC) $(SCLAUX) \
- $(DLUSRC)  $(DLASRC) $(DZLAUX) \
- $(CLUSRC)  $(CLASRC) \
- $(ZLUSRC)  $(ZLASRC) 
-
-superlu: FAIT
-
-FAIT:	
-	$(MAKE)  install WHERE
-	touch FAIT
-
-
-FAIRE:$(SRCDIR)
-	cd $(SRCDIR)/SRC; $(MAKE) -f ../../ff-FLAGS  $(OBJ_SUPERLU)
-	touch FAIRE
-
-install: FAIRE WHERE
-	cd $(SRCDIR)/SRC; $(AR) $(ARFLAGS) $(SUPERLULIB)  $(OBJ_SUPERLU)
-	cd $(SRCDIR)/SRC; $(RANLIB) $(SUPERLULIB) 
-	cp $(SRCDIR)/SRC/s*h  ../include
-WHERE:
-	echo superlu LD -L at DIR@/lib -lsuperlu_$(SUPERLU_VERSION)  >../lib/WHERE.superlu
-	echo superlu INCLUDE -I at DIR@/include >> ../lib/WHERE.superlu
-
-
-
-
-$(SRCDIR)/$(INSTALL): 
-	mkdir $(SRCDIR)/$(INSTALL)
-
-
-$(SRCDIR): $(PACKAGE_PATH)
-	tar xvzf $(PACKAGE_PATH)
-	touch $(SRCDIR)
-
-$(PACKAGE_PATH):
-	-mkdir $(DIRPKG);
-	cd $(DIRPKG);$(WGET)  $(SERVER)$(PACKAGE)
-
-clean-local:
-	-rm ../lib/WHERE.superlu
-	-rm ../lib/libsuperlu_$(SUPERLU_VERSION).*
-	-rm -rf superlu*
-	-rm $(SRCDIR)/SRC/$(SUPERLULIB)
-	-rm ../include/slu*h 
-	-rm ../include/supermatrix.h
-	-rm -r $(SRCDIR) ff-FLAGS
-	-rm -rf FAIT FAIRE
-clean:clean-local
-
-
-
-ff-FLAGS: ../Makefile  Makefile 
-	grep '^CXX *=' ../Makefile >>$@
-	grep '^CC *=' ../Makefile >>$@
-	grep '^CFLAGS *=' ../Makefile >>$@
-	grep '^BLAS[A-Z ]*='  ../Makefile|grep =  >>$@
-	grep '^AR *='  ../Makefile|grep =  >>$@
-	grep '^ARFLAGS *='  ../Makefile|grep =  >>$@
-	grep '^RANLIB *='    ../Makefile|grep =  >>$@
-	grep '^WGET *='    ../Makefile|grep =  >>$@
-
+# Downloading and compiling extra libraries
+# -----------------------------------------
+# $Id$
+
+all-local: superlu
+
+# Downloading and compiling Tetgen
+# ------------------------------
+
+# SUPERLU information
+#http://crd.lbl.gov/~xiaoye/SuperLU/superlu_4.0.tar.gz
+DIRPKG=../pkg
+SRCDIR=SuperLU_4.3
+PACKAGE=superlu_4.3.tar.gz
+PACKAGE_PATH=$(DIRPKG)/$(PACKAGE)
+SERVER=http://crd-legacy.lbl.gov/~xiaoye/SuperLU/
+# http://crd-legacy.lbl.gov/~xiaoye/SuperLU/superlu_4.3.tar.gz
+INSTALL=../..
+SUPERLU_VERSION=4.3
+SUPERLULIB=../$(INSTALL)/lib/libsuperlu_$(SUPERLU_VERSION).a
+include  ff-FLAGS
+
+### LAPACK 
+LAAUX 	= lsame.o xerbla.o
+SLASRC 	= slacon.o 
+DLASRC	= dlacon.o
+CLASRC	= clacon.o scsum1.o icmax1.o
+ZLASRC	= zlacon.o dzsum1.o izmax1.o
+SCLAUX 	= slamch.o
+DZLAUX 	= dlamch.o
+
+### SuperLU 
+ALLAUX 	= superlu_timer.o util.o memory.o get_perm_c.o mmd.o \
+	  sp_coletree.o sp_preorder.o sp_ienv.o relax_snode.o \
+	  heap_relax_snode.o colamd.o
+
+SLUSRC = \
+	sgssv.o sgssvx.o \
+	ssp_blas2.o ssp_blas3.o sgscon.o  \
+	slangs.o sgsequ.o slaqgs.o spivotgrowth.o \
+	sgsrfs.o sgstrf.o sgstrs.o scopy_to_ucol.o \
+	ssnode_dfs.o ssnode_bmod.o \
+	spanel_dfs.o spanel_bmod.o sreadhb.o \
+	scolumn_dfs.o scolumn_bmod.o spivotL.o spruneL.o \
+	smemory.o sutil.o smyblas2.o
+
+DLUSRC = \
+	dgssv.o dgssvx.o \
+	dsp_blas2.o dsp_blas3.o dgscon.o \
+	dlangs.o dgsequ.o dlaqgs.o dpivotgrowth.o  \
+	dgsrfs.o dgstrf.o dgstrs.o dcopy_to_ucol.o \
+	dsnode_dfs.o dsnode_bmod.o \
+	dpanel_dfs.o dpanel_bmod.o dreadhb.o \
+	dcolumn_dfs.o dcolumn_bmod.o dpivotL.o dpruneL.o \
+	dmemory.o dutil.o dmyblas2.o ## dgstrsL.o dgstrsU.o
+
+CLUSRC = \
+	scomplex.o cgssv.o cgssvx.o csp_blas2.o csp_blas3.o cgscon.o \
+	clangs.o cgsequ.o claqgs.o cpivotgrowth.o  \
+	cgsrfs.o cgstrf.o cgstrs.o ccopy_to_ucol.o \
+	csnode_dfs.o csnode_bmod.o \
+	cpanel_dfs.o cpanel_bmod.o creadhb.o \
+	ccolumn_dfs.o ccolumn_bmod.o cpivotL.o cpruneL.o \
+	cmemory.o cutil.o cmyblas2.o
+
+ZLUSRC = \
+	dcomplex.o zgssv.o zgssvx.o zsp_blas2.o zsp_blas3.o zgscon.o \
+	zlangs.o zgsequ.o zlaqgs.o zpivotgrowth.o  \
+	zgsrfs.o zgstrf.o zgstrs.o zcopy_to_ucol.o \
+	zsnode_dfs.o zsnode_bmod.o \
+	zpanel_dfs.o zpanel_bmod.o zreadhb.o \
+	zcolumn_dfs.o zcolumn_bmod.o zpivotL.o zpruneL.o \
+	zmemory.o zutil.o zmyblas2.o
+
+
+OBJ_SUPERLU = $(ALLAUX) $(LAAUX) \
+ $(SLUSRC)  $(SLASRC) $(SCLAUX) \
+ $(DLUSRC)  $(DLASRC) $(DZLAUX) \
+ $(CLUSRC)  $(CLASRC) \
+ $(ZLUSRC)  $(ZLASRC) 
+
+superlu: FAIT
+
+# FFCS - 18/6/12 - depend on SRCDIR to remake all when package version changes
+FAIT:$(SRCDIR)	
+	$(MAKE)  install WHERE
+	touch FAIT
+
+
+FAIRE:$(SRCDIR)
+	cd $(SRCDIR)/SRC; $(MAKE) -f ../../ff-FLAGS  $(OBJ_SUPERLU)
+	touch FAIRE
+
+# FFCS - FAIRE and WHERE need to be done sequentially, even in a parallel build (corrected by Cico, 1/3/12)
+install: FAIRE
+	$(MAKE) WHERE
+	cd $(SRCDIR)/SRC; $(AR) $(ARFLAGS) $(SUPERLULIB)  $(OBJ_SUPERLU)
+	cd $(SRCDIR)/SRC; $(RANLIB) $(SUPERLULIB) 
+	cp $(SRCDIR)/SRC/s*h  $(SRCDIR)/$(INSTALL)/include
+WHERE:
+	echo superlu LD -L at DIR@/lib -lsuperlu_$(SUPERLU_VERSION)  >$(SRCDIR)/$(INSTALL)/lib/WHERE.superlu
+	echo superlu INCLUDE -I at DIR@/include >> $(SRCDIR)/$(INSTALL)/lib/WHERE.superlu
+
+
+
+
+$(SRCDIR)/$(INSTALL): 
+	mkdir $(SRCDIR)/$(INSTALL)
+
+
+$(SRCDIR): $(PACKAGE_PATH)
+	tar xvzf $(PACKAGE_PATH)
+	touch $(SRCDIR)
+
+$(PACKAGE_PATH):
+	-mkdir $(DIRPKG);
+	cd $(DIRPKG);$(WGET)  $(SERVER)$(PACKAGE)
+
+# FFCS - make sure that all directories are cleaned. Thisis especially important under Windows because there is no
+# compilation dependencies control there (see [[file:c:/cygwin/home/alh/ffcs/dist/configure.ac::dependency_tracking]])
+
+clean:
+	-rm -rf SuperLU_* ff-FLAGS
+	-rm -rf FAIT FAIRE
+
+
+# ALH - FFCS - 18/5/9 - FHecht says he forgot to add -fPIC for 64 bit platforms, so I add it myself here.
+ff-FLAGS: ../Makefile  Makefile 
+	grep '^CXX *=' ../Makefile >>$@
+	grep '^CC *=' ../Makefile >>$@
+	grep '^CFLAGS *=' ../Makefile|sed 's/$$/ -fPIC/' >>$@
+	grep '^BLAS[A-Z ]*='  ../Makefile|grep =  >>$@
+	grep '^AR *='  ../Makefile|grep =  >>$@
+	grep '^ARFLAGS *='  ../Makefile|grep =  >>$@
+	grep '^RANLIB *='    ../Makefile|grep =  >>$@
+	grep '^WGET *='    ../Makefile|grep =  >>$@
+
diff --git a/download/superludist/Makefile b/download/superludist/Makefile
index 66daf3a..97b2f18 100644
--- a/download/superludist/Makefile
+++ b/download/superludist/Makefile
@@ -25,7 +25,8 @@ include make.inc
 
 superludist: FAIT
 
-FAIT:	
+# FFCS: more dependencies for parallel builds
+FAIT:$(SRCDIR)
 	$(MAKE) FAIRE install WHERE
 	touch FAIT
 
@@ -41,34 +42,40 @@ make.inc: ../../config.status  Makefile
 	case 'uname' in *CYGWIN_) cp make.inc Makefile.inn; sed "s/COPTIONS =/COPTIONS = -D__VC__/" <Makefile.inn > Makefile.in; rm Makefile.inn ;; esac
 	rm make-superlu-tmp.inc
 
+# FFCS: we need an error if make breaks
 $(SRCDIR)/SRC/$(DSUPERLULIB): $(SRCDIR)
 	cp make.inc $(SRCDIR)/make.inc
-	cd $(SRCDIR)/SRC; $(MAKE)
-install:
-	mkdir -p ../include/superludist
-	cp $(SRCDIR)/SRC/*.h  ../include/superludist
+	cd $(SRCDIR)/SRC && $(MAKE)
+# FFCS: we need more dependencies for parallel builds
+install:$(SRCDIR)/SRC/$(DSUPERLULIB)
+	mkdir -p $(SRCDIR)/$(INSTALL)/include/superludist
+	cp $(SRCDIR)/SRC/*.h  $(SRCDIR)/$(INSTALL)/include/superludist
 WHERE:
-	echo superlu_dist LD -L at DIR@/lib -lsuperlu_dist_3.0  >../lib/WHERE.superlu_dist
-	echo superlu_dist INCLUDE -I at DIR@/include/superludist  >> ../lib/WHERE.superlu_dist
+	echo superlu_dist LD -L at DIR@/lib -lsuperlu_dist_3.0  >$(SRCDIR)/$(INSTALL)/lib/WHERE.superlu_dist
+	echo superlu_dist INCLUDE -I at DIR@/include/superludist  >> $(SRCDIR)/$(INSTALL)/lib/WHERE.superlu_dist
 
 
 $(SRCDIR): $(PACKAGE_PATH)
 	tar xvzf $(PACKAGE_PATH)
 	cd $(SRCDIR)/SRC/; patch -p1 < ../../superludist_2.3.patch
+	cd $(SRCDIR)/SRC/; patch -p3 < ../../superludist_3.0-printf.patch
+	cd $(SRCDIR)/SRC/; patch -p2 < ../../superludist_3.0-cast_warning.patch
+	cd $(SRCDIR)/SRC/; patch -p2 < ../../superludist_3.0-return_values.patch
+	cd $(SRCDIR)/SRC/; patch -p2 < ../../superludist_3.0-operation_undefined.patch
 	touch $(SRCDIR)
 
 $(PACKAGE_PATH):
 	-mkdir $(DIRPKG);
-	cd $(DIRPKG);$(WGET)  $(SERVER)$(PACKAGE)
+	cd $(DIRPKG);$(WGET)  $(SERVER)$(PACKAGE) 
+#$(PACKAGE_PATH)
 
-clean-local:
-	-cd $(SRCDIR) &&  $(MAKE) clean -C $(SRCDIR)
-	-rm -rf $(SRCDIR)
-	-rm  ../include/superludist/*.h ../lib/WHERE.superlu_dist
+# FFCS - make sure that all directories are cleaned. Thisis especially important under Windows because there is no
+# compilation dependencies control there (see [[file:c:/cygwin/home/alh/ffcs/dist/configure.ac::dependency_tracking]])
+
+clean:
+	-rm -rf SuperLU_DIST*
+	-rm  ../include/superludist/*.h
 	-rm -r ../include/superludist/
 	-rm -r ../lib/libsuperlu_dist*.a
 	-rm -r make.inc
 	-rm -rf FAIT FAIRE
-
-clean: clean-local
-
diff --git a/download/superludist/make-superlu.inc b/download/superludist/make-superlu.inc
index 6571c3b..fe7a46a 100644
--- a/download/superludist/make-superlu.inc
+++ b/download/superludist/make-superlu.inc
@@ -1,4 +1,5 @@
-include $(abs_top_builddir)/download/headers-sparsesolver.inc
+# FFCS - let "make clean" work even if include file is not found
+-include $(abs_top_builddir)/download/headers-sparsesolver.inc
 #############################################
 #  FLAGS :: FREEFEM TO COMPILE SUPERLU_DIST
 #
@@ -17,9 +18,11 @@ RANLIB       	= @RANLIB@
 
 ############################################################################
 # C compiler setup
-CC           	= @CC@
+CC           	= @MPICC@
 # CFLAGS should be set to be the C flags that include optimization
-CFLAGS          = @CFLAGS@ @MPI_INCLUDE@
+# FFCS - problem with some return statements on MacOS
+# FFCS - -I MPI_INC_DIR required on MacOS 10.8 MacPorts+OpenMPI
+CFLAGS          = -Wreturn-type @CFLAGS@ -I @MPI_INC_DIR@
 # NOOPTS should be set to be the C flags that turn off any optimization
 NOOPTS		=  @CNOFLAGS@ 
 ############################################################################
diff --git a/download/superludist/superludist_3.0-cast_warning.patch b/download/superludist/superludist_3.0-cast_warning.patch
new file mode 100644
index 0000000..389ddb6
--- /dev/null
+++ b/download/superludist/superludist_3.0-cast_warning.patch
@@ -0,0 +1,25 @@
+diff -ur SuperLU_DIST_3.0.orig/SRC/pdgstrf.c SuperLU_DIST_3.0/SRC/pdgstrf.c
+--- SuperLU_DIST_3.0.orig/SRC/pdgstrf.c	2011-10-11 20:45:40.000000000 +0000
++++ SuperLU_DIST_3.0/SRC/pdgstrf.c	2013-02-13 12:51:45.691434748 +0000
+@@ -2597,7 +2597,7 @@
+ 		    MPI_Isend(ublk_ptr, u_diag_cnt, MPI_DOUBLE, pr,
+ 			      tag, comm, U_diag_blk_send_req + pr);
+ 		}
+-	    U_diag_blk_send_req[krow] = 1; /* flag outstanding Isend */
++	    U_diag_blk_send_req[krow] = (MPI_Request) 1; /* flag outstanding Isend */
+ 	}
+ 
+     } else  { /* non-diagonal process */
+Only in SuperLU_DIST_3.0/SRC: pdgstrf.o
+diff -ur SuperLU_DIST_3.0.orig/SRC/pzgstrf.c SuperLU_DIST_3.0/SRC/pzgstrf.c
+--- SuperLU_DIST_3.0.orig/SRC/pzgstrf.c	2011-10-11 20:45:40.000000000 +0000
++++ SuperLU_DIST_3.0/SRC/pzgstrf.c	2013-02-13 12:54:00.212442635 +0000
+@@ -2543,7 +2543,7 @@
+ 		    MPI_Isend(ublk_ptr, u_diag_cnt, SuperLU_MPI_DOUBLE_COMPLEX, pr,
+ 			      tag, comm, U_diag_blk_send_req + pr);
+ 		}
+-	    U_diag_blk_send_req[krow] = 1; /* flag outstanding Isend */
++	    U_diag_blk_send_req[krow] = (MPI_Request) 1; /* flag outstanding Isend */
+ 	}
+ 
+     } else  { /* non-diagonal process */
diff --git a/download/superludist/superludist_3.0-operation_undefined.patch b/download/superludist/superludist_3.0-operation_undefined.patch
new file mode 100644
index 0000000..3cbff19
--- /dev/null
+++ b/download/superludist/superludist_3.0-operation_undefined.patch
@@ -0,0 +1,24 @@
+--- SuperLU_DIST_3.0/SRC/util.c.orig	2013-02-20 10:23:45.674505816 +0000
++++ SuperLU_DIST_3.0/SRC/util.c	2013-02-20 10:24:09.001507187 +0000
+@@ -662,8 +662,8 @@
+ 
+     do {
+ 	++(*num_diag_procs);
+-	i = (++i) % nprow;
+-	j = (++j) % npcol;
++	i = (i + 1) % nprow;
++	j = (j + 1) % npcol;
+ 	pkk = PNUM( i, j, grid );
+     } while ( pkk != 0 ); /* Until wrap back to process 0 */
+     if ( !(*diag_procs = intMalloc_dist(*num_diag_procs)) )
+@@ -673,8 +673,8 @@
+     for (i = j = k = 0; k < *num_diag_procs; ++k) {
+ 	pkk = PNUM( i, j, grid );
+ 	(*diag_procs)[k] = pkk;
+-	i = (++i) % nprow;
+-	j = (++j) % npcol;
++	i = (i + 1) % nprow;
++	j = (j + 1) % npcol;
+     }
+     for (k = 0; k < nsupers; ++k) {
+ 	knsupc = SuperSize( k );
diff --git a/download/superludist/superludist_3.0-printf.patch b/download/superludist/superludist_3.0-printf.patch
new file mode 100644
index 0000000..0de05df
--- /dev/null
+++ b/download/superludist/superludist_3.0-printf.patch
@@ -0,0 +1,10 @@
+--- ./SuperLU_DIST_3.0/SRC/xerbla.c.orig	2013-02-13 12:21:04.893027330 +0000
++++ ./SuperLU_DIST_3.0/SRC/xerbla.c	2013-02-13 12:21:22.677028381 +0000
+@@ -9,6 +9,7 @@
+ </pre> 
+ */
+ #include "Cnames.h"
++#include <stdio.h>
+ 
+ /* Subroutine */ 
+ /*! \brief
diff --git a/download/superludist/superludist_3.0-return_values.patch b/download/superludist/superludist_3.0-return_values.patch
new file mode 100644
index 0000000..a915882
--- /dev/null
+++ b/download/superludist/superludist_3.0-return_values.patch
@@ -0,0 +1,158 @@
+Only in SuperLU_DIST_3.0/SRC: 1
+diff -ur SuperLU_DIST_3.0.orig/SRC/dutil.c SuperLU_DIST_3.0/SRC/dutil.c
+--- SuperLU_DIST_3.0.orig/SRC/dutil.c	2011-09-06 00:16:34.000000000 +0000
++++ SuperLU_DIST_3.0/SRC/dutil.c	2013-02-13 17:40:36.696123287 +0000
+@@ -185,6 +185,8 @@
+     if ( (dp = (double *) Astore->nzval) != NULL )
+         PrintDouble5("nzval", nnz_loc, dp);
+     printf("==== end CompRowLoc matrix\n");
++
++    return 0;
+ }
+ 
+ int file_dPrint_CompRowLoc_Matrix_dist(FILE *fp, SuperMatrix *A)
+@@ -205,6 +207,8 @@
+     if ( (dp = (double *) Astore->nzval) != NULL )
+         file_PrintDouble5(fp, "nzval", nnz_loc, dp);
+     fprintf(fp, "==== end CompRowLoc matrix\n");
++
++    return 0;
+ }
+ 
+ void
+@@ -355,6 +359,8 @@
+ 	fprintf(fp, "%14e", x[i]);
+     }
+     fprintf(fp, "\n");
++
++    return 0;
+ }
+ 
+ /*! \brief Print the blocks in the factored matrix L.
+@@ -461,6 +467,8 @@
+   file_PrintInt10(fp, "ptr_ind_torecv", procs+1, gsmv_comm->ptr_ind_torecv);
+   file_PrintInt10(fp, "SendCounts", procs, gsmv_comm->SendCounts);
+   file_PrintInt10(fp, "RecvCounts", procs, gsmv_comm->RecvCounts);
++
++  return 0;
+ }
+ 
+ 
+Binary files SuperLU_DIST_3.0.orig/SRC/dutil.o and SuperLU_DIST_3.0/SRC/dutil.o differ
+diff -ur SuperLU_DIST_3.0.orig/SRC/pddistribute.c SuperLU_DIST_3.0/SRC/pddistribute.c
+--- SuperLU_DIST_3.0.orig/SRC/pddistribute.c	2011-09-06 00:16:34.000000000 +0000
++++ SuperLU_DIST_3.0/SRC/pddistribute.c	2013-02-13 17:44:50.198138179 +0000
+@@ -304,6 +304,8 @@
+     CHECK_MALLOC(iam, "Exit dReDistribute_A()");
+ #endif
+  
++    return 0;
++
+ } /* dReDistribute_A */
+ 
+ float
+Binary files SuperLU_DIST_3.0.orig/SRC/pddistribute.o and SuperLU_DIST_3.0/SRC/pddistribute.o differ
+diff -ur SuperLU_DIST_3.0.orig/SRC/psymbfact.c SuperLU_DIST_3.0/SRC/psymbfact.c
+--- SuperLU_DIST_3.0.orig/SRC/psymbfact.c	2011-09-06 00:16:34.000000000 +0000
++++ SuperLU_DIST_3.0/SRC/psymbfact.c	2013-02-13 17:47:47.931004764 +0000
+@@ -2267,6 +2267,8 @@
+   
+   for (i = fstVtx_toUpd; i < nvtcs_toUpd; i++)
+     marker[i] = 0;
++
++    return 0;
+ }
+ 
+ static int_t
+@@ -4005,6 +4007,8 @@
+   if (newelts_U) SUPERLU_FREE (newelts_U);
+   if (PS->szDnsSep < mem_dnsCS)
+     PS->szDnsSep = mem_dnsCS;
++
++  return 0;
+ }
+ 
+ /*! \brief
+@@ -4534,6 +4538,8 @@
+   if (request_snd != NULL) SUPERLU_FREE (request_snd);
+   if (request_rcv != NULL) SUPERLU_FREE (request_rcv);
+   if (status != NULL) SUPERLU_FREE (status);
++
++  return 0;
+ }
+ 
+ static void
+Binary files SuperLU_DIST_3.0.orig/SRC/psymbfact.o and SuperLU_DIST_3.0/SRC/psymbfact.o differ
+diff -ur SuperLU_DIST_3.0.orig/SRC/pzdistribute.c SuperLU_DIST_3.0/SRC/pzdistribute.c
+--- SuperLU_DIST_3.0.orig/SRC/pzdistribute.c	2011-09-06 00:16:34.000000000 +0000
++++ SuperLU_DIST_3.0/SRC/pzdistribute.c	2013-02-13 17:53:06.269023492 +0000
+@@ -303,6 +303,7 @@
+     CHECK_MALLOC(iam, "Exit zReDistribute_A()");
+ #endif
+  
++    return 0;
+ } /* zReDistribute_A */
+ 
+ float
+Binary files SuperLU_DIST_3.0.orig/SRC/pzdistribute.o and SuperLU_DIST_3.0/SRC/pzdistribute.o differ
+diff -ur SuperLU_DIST_3.0.orig/SRC/util.c SuperLU_DIST_3.0/SRC/util.c
+--- SuperLU_DIST_3.0.orig/SRC/util.c	2011-10-11 21:14:16.000000000 +0000
++++ SuperLU_DIST_3.0/SRC/util.c	2013-02-13 17:54:31.042028470 +0000
+@@ -490,6 +490,7 @@
+     gstrs_comm->ptr_to_ibuf = ptr_to_ibuf;
+     gstrs_comm->ptr_to_dbuf = ptr_to_ibuf + procs;
+ 
++    return 0;
+ } /* PXGSTRS_INIT */
+ 
+ 
+@@ -763,6 +764,8 @@
+ 	fprintf(fp, "%6d", x[i]);
+     }
+     fprintf(fp, "\n");
++
++    return 0;
+ }
+ 
+ int_t
+Binary files SuperLU_DIST_3.0.orig/SRC/util.o and SuperLU_DIST_3.0/SRC/util.o differ
+diff -ur SuperLU_DIST_3.0.orig/SRC/zutil.c SuperLU_DIST_3.0/SRC/zutil.c
+--- SuperLU_DIST_3.0.orig/SRC/zutil.c	2011-09-06 00:16:34.000000000 +0000
++++ SuperLU_DIST_3.0/SRC/zutil.c	2013-02-13 17:56:24.618035143 +0000
+@@ -184,6 +184,8 @@
+     if ( (dp = (doublecomplex *) Astore->nzval) != NULL )
+         PrintDoublecomplex("nzval", nnz_loc, dp);
+     printf("==== end CompRowLoc matrix\n");
++
++    return 0;
+ }
+ 
+ int file_zPrint_CompRowLoc_Matrix_dist(FILE *fp, SuperMatrix *A)
+@@ -204,6 +206,8 @@
+     if ( (dp = (doublecomplex *) Astore->nzval) != NULL )
+         file_PrintDoublecomplex(fp, "nzval", nnz_loc, dp);
+     fprintf(fp, "==== end CompRowLoc matrix\n");
++
++    return 0;
+ }
+ 
+ void
+@@ -351,6 +355,8 @@
+     fprintf(fp, "%10s:\tReal\tImag\n", name);
+     for (i = 0; i < len; ++i)
+ 	fprintf(fp, "\t%d\t%.4f\t%.4f\n", i, x[i].r, x[i].i);
++
++    return 0;
+ }
+ 
+ /*! \brief Print the blocks in the factored matrix L.
+@@ -457,6 +463,8 @@
+   file_PrintInt10(fp, "ptr_ind_torecv", procs+1, gsmv_comm->ptr_ind_torecv);
+   file_PrintInt10(fp, "SendCounts", procs, gsmv_comm->SendCounts);
+   file_PrintInt10(fp, "RecvCounts", procs, gsmv_comm->RecvCounts);
++
++  return 0;
+ }
+ 
+ 
+Binary files SuperLU_DIST_3.0.orig/SRC/zutil.o and SuperLU_DIST_3.0/SRC/zutil.o differ
diff --git a/download/tetgen/Makefile b/download/tetgen/Makefile
old mode 100644
new mode 100755
index 3999451..43fc851
--- a/download/tetgen/Makefile
+++ b/download/tetgen/Makefile
@@ -1,69 +1,83 @@
-# and compiling extra libraries
-# -----------------------------------------
-
-# $Id$
-
-include cxxflags
-all-local: tetgen
-
-# Downloading and compiling Tetgen
-# ------------------------------
-
-# Tetgen information
-DIRPKG=../pkg
-SRCDIR=tetgen$(tetgen_VERSION)
-PACKAGE=$(DIRPKG)/tetgen$(tetgen_VERSION).tar.gz
-SERVER=http://wias-berlin.de/software/tetgen/files
-#http://tetgen.org/files
-#http://tetgen.berlios.de/files
-INSTALL=../..
-tetgen_VERSION=1.4.3
-
-tetgen: FAIRE 
-
-
-FAIRE:install $(SRCDIR)/FAIT cxxflags 
-	touch FAIRE
-
-
-$(SRCDIR)/FAIT: $(SRCDIR)/tags  cxxflags 
-	cd $(SRCDIR);$(CXX) $(CXXFLAGS) -DSELF_CHECK  -DNDEBUG -DTETLIBRARY -c tetgen.cxx
-	cd $(SRCDIR);$(CXX) $(CXXFLAGS) -DSELF_CHECK  -DNDEBUG -DTETLIBRARY -c predicates.cxx
-	touch $(SRCDIR)/FAIT
-WHERE: $(SRCDIR)/FAIT
-	echo tetgen LD -L at DIR@/lib -ltet  >../lib/WHERE.tetgen
-	echo tetgen  INCLUDE -I at DIR@/include >> ../lib/WHERE.tetgen
-install:$(SRCDIR)/FAIT WHERE
-	cd $(SRCDIR);$(AR) $(ARFLAGS)  $(INSTALL)/lib/libtet.a tetgen.o predicates.o
-	cp $(SRCDIR)/tetgen.h ../include 
-
-
-
-$(SRCDIR)/tags: $(PACKAGE)
-	tar xvzf $(PACKAGE)
-	touch $(SRCDIR)/tags
-#	cd tetgen1.4.2;patch -p1 <../tetgen1.4.2.patch 
-
-$(PACKAGE):
-	cd $(DIRPKG);$(WGET)   $(SERVER)/`basename $(PACKAGE)`
-
-
-
-clean-local:
-	-rm -rf tetgen1.4.?  FAIT FAIRE 
-	-rm ../lib/libtet.a ../lib/WHERE.tetgen 
-	-rm ../include/tetgen.h 
-	-rm FAIT
-	-rm -rf tetgen1.4.?
-
-clean: clean-local
-
-cxxflags: ../Makefile  Makefile
-	grep 'CXX *=' ../Makefile >cxxflags
-	grep 'CC *=' ../Makefile >>cxxflags
-#  bug under ubuntu et cygwin si option optime  -O3 remove optim ???
-	grep 'CXXFLAGS *=' ../Makefile | sed 's/ -O[0-9]* / /'  >>cxxflags
-	grep 'WGET *=' ../Makefile >>cxxflags
-	grep 'AR *=' ../Makefile >>cxxflags
-	grep 'ARFLAGS *=' ../Makefile >>cxxflags
+# and compiling extra libraries
+# -----------------------------------------
+
+# $Id$
+
+include cxxflags
+all-local: tetgen
+
+# Downloading and compiling Tetgen
+# ------------------------------
+
+# Tetgen information
+DIRPKG=../pkg
+tetgen_VERSION=1.4.3
+SRCDIR=tetgen$(tetgen_VERSION)
+PACKAGE=$(DIRPKG)/tetgen$(tetgen_VERSION).tar.gz
+
+# FFCS - 6/11/12 - curl is not able to follow redirections from http://tetgen.org/files
+SERVER=http://wias-berlin.de/software/tetgen/files
+
+INSTALL=../..
+
+tetgen: FAIRE 
+
+
+FAIRE:install.done $(SRCDIR)/FAIT cxxflags WHERE.done
+	touch FAIRE
+
+
+# ALH - FFCS - 18/12/8 - need '-fPIC' on Linux64 because the .a will be used in a .so (by examples++-load/tetgen.cpp).
+
+# FFCS - 30/11/10 - need ranlib on Win64. The PATH is setup so that mingw/ranlib is called
+
+$(SRCDIR)/FAIT: $(SRCDIR)/tags  cxxflags 
+	cd $(SRCDIR);$(CXX) $(CXXFLAGS) -fPIC -DSELF_CHECK  -DNDEBUG -DTETLIBRARY -c tetgen.cxx
+	cd $(SRCDIR);$(CXX) $(CXXFLAGS) -fPIC -DSELF_CHECK  -DNDEBUG -DTETLIBRARY -c predicates.cxx
+	touch $(SRCDIR)/FAIT
+WHERE.done: $(SRCDIR)/FAIT
+	echo tetgen LD -L at DIR@/lib -ltet  >$(SRCDIR)/$(INSTALL)/lib/WHERE.tetgen
+	echo tetgen  INCLUDE -I at DIR@/include >> $(SRCDIR)/$(INSTALL)/lib/WHERE.tetgen
+	touch $@
+clean-local::
+	-rm WHERE.done
+
+# FFCS - avoid remaking install every time
+install.done:$(SRCDIR)/FAIT
+	cd $(SRCDIR);$(AR) $(ARFLAGS)  $(INSTALL)/lib/libtet.a tetgen.o predicates.o
+	ranlib $(SRCDIR)/$(INSTALL)/lib/libtet.a
+	cp $(SRCDIR)/tetgen.h $(SRCDIR)/$(INSTALL)/include 
+	touch $@
+clean-local::
+	-rm install.done
+
+
+$(SRCDIR)/tags: $(PACKAGE)
+	tar xvzf $(PACKAGE)
+#       FFCS: needs to patch tetgen because mingw64 has 4-byte longs
+	cd tetgen1.4.3 && patch -u -p1 < ../patches.win64
+	touch $(SRCDIR)/tags
+#	cd tetgen1.4.2;patch -p1 <../tetgen1.4.2.patch 
+
+$(PACKAGE):
+	cd $(DIRPKG);$(WGET)   $(SERVER)/`basename $(PACKAGE)`
+
+
+
+clean-local::
+	-rm -rf tetgen1.4.?  FAIT FAIRE 
+clean:
+	-rm $(SRCDIR)/$(INSTALL)/lib/libtet.a
+	-rm $(SRCDIR)/$(INSTALL)/include/tetgen.h
+	-rm FAIT
+	-rm -rf tetgen1.4.?
+cxxflags: ../Makefile  Makefile
+	grep 'CXX *=' ../Makefile >cxxflags
+	grep 'CC *=' ../Makefile >>cxxflags
+#	FFCS - 10/5/12 - bug under Windows if -O3 is specified tetgen never returns. It could also be the case under
+#	Ubuntu. All optimisation options are removed for safety.
+	grep 'CXXFLAGS *=' ../Makefile | sed 's/ -O[0-9]* / /g'  >>cxxflags
+	grep 'WGET *=' ../Makefile >>cxxflags
+	grep 'AR *=' ../Makefile >>cxxflags
+	grep 'ARFLAGS *=' ../Makefile >>cxxflags
 .PHONY:$(SRCDIR)/$(INSTALL)
\ No newline at end of file
diff --git a/download/tetgen/patches.win64 b/download/tetgen/patches.win64
new file mode 100644
index 0000000..55630d8
--- /dev/null
+++ b/download/tetgen/patches.win64
@@ -0,0 +1,104 @@
+# -*- mode:diff;coding:raw-text; -*-
+diff -u -p1 /home/alh/tmp/tetgen1.4.3/tetgen.cxx tetgen1.4.3/tetgen.cxx
+--- /home/alh/tmp/tetgen1.4.3/tetgen.cxx	2009-12-13 22:21:08.000000000 +0100
++++ tetgen1.4.3/tetgen.cxx	2010-11-24 15:47:44.253943800 +0100
+@@ -4844,3 +4844,3 @@ void tetgenmesh::dummyinit(int tetwords,
+ {
+-  unsigned long alignptr;
++  unsigned FFCSLONG alignptr;
+ 
+@@ -4850,3 +4850,3 @@ void tetgenmesh::dummyinit(int tetwords,
+   // Align 'dummytet' on a 'tetrahedrons->alignbytes'-byte boundary.
+-  alignptr = (unsigned long) dummytetbase;
++  alignptr = (unsigned FFCSLONG) dummytetbase;
+   dummytet = (tetrahedron *)
+@@ -4875,3 +4875,3 @@ void tetgenmesh::dummyinit(int tetwords,
+     // Align 'dummysh' on a 'subfaces->alignbytes'-byte boundary.
+-    alignptr = (unsigned long) dummyshbase;
++    alignptr = (unsigned FFCSLONG) dummyshbase;
+     dummysh = (shellface *)
+@@ -15082,3 +15082,3 @@ void tetgenmesh::btree_insert(point inse
+   point *ptary;
+-  long arylen; // The array lenhgth is saved in ptary[0].
++  FFCSLONG arylen; // The array lenhgth is saved in ptary[0].
+ 
+@@ -15087,3 +15087,3 @@ void tetgenmesh::btree_insert(point inse
+   // Get the current array length.
+-  arylen = (long) ptary[0];
++  arylen = (FFCSLONG) ptary[0];
+   // Insert the point into the node.
+@@ -15106,3 +15106,3 @@ void tetgenmesh::btree_search(point inse
+   int ptsamples, ptidx;
+-  long arylen;
++  FFCSLONG arylen;
+   int i;
+@@ -15112,3 +15112,3 @@ void tetgenmesh::btree_search(point inse
+   // Get the current array length.
+-  arylen = (long) ptary[0];
++  arylen = (FFCSLONG) ptary[0];
+ 
+@@ -15165,3 +15165,3 @@ void tetgenmesh::ordervertices(point* ve
+   point *ptary;
+-  long arylen;
++  FFCSLONG arylen;
+   int index, i, j;
+@@ -15186,3 +15186,3 @@ void tetgenmesh::ordervertices(point* ve
+     ptary = *jpptary;
+-    arylen = (long) ptary[0];
++    arylen = (FFCSLONG) ptary[0];
+     for (j = 2; j <= arylen; j++) { // Skip the first point.
+@@ -21031,3 +21031,3 @@ bool tetgenmesh::delaunizecavity(arraypo
+             printf("    Queue a subface x%lx (%d, %d, %d).\n", 
+-              (unsigned long) checksh.sh, pointmark(sorg(checksh)),
++              (unsigned FFCSLONG) checksh.sh, pointmark(sorg(checksh)),
+               pointmark(sdest(checksh)), pointmark(sapex(checksh)));
+@@ -21081,3 +21081,3 @@ bool tetgenmesh::delaunizecavity(arraypo
+                 printf("    Queue a subface x%lx (%d, %d, %d).\n", 
+-                  (unsigned long) checksh.sh, pointmark(sorg(checksh)),
++                  (unsigned FFCSLONG) checksh.sh, pointmark(sorg(checksh)),
+                   pointmark(sdest(checksh)), pointmark(sapex(checksh)));
+@@ -23474,3 +23474,3 @@ bool tetgenmesh::carvecavity(list* newte
+               printf("    Intet x%lx %d (%d, %d, %d, %d) is iversed.\n", 
+-                (unsigned long) intet.tet, intet.loc, pointmark(pa),
++                (unsigned FFCSLONG) intet.tet, intet.loc, pointmark(pa),
+                 pointmark(pb), pointmark(pc), pointmark(oppo(intet)));
+@@ -23544,3 +23544,3 @@ bool tetgenmesh::carvecavity(list* newte
+             pointmark(org(neightet)), pointmark(dest(neightet)),
+-            pointmark(apex(neightet)), (unsigned long) auxsh.sh);
++            pointmark(apex(neightet)), (unsigned FFCSLONG) auxsh.sh);
+           printf("  p:draw_tet(%d, %d, %d, %d) -- in\n",
+@@ -33711,5 +33711,5 @@ int tetgenmesh::checksegments()
+             printf("    Tet: x%lx (%d, %d, %d, %d) - Seg: x%lx (%d, %d).\n", 
+-              (unsigned long) tetloop.tet, pointmark(org(tetloop)),
++              (unsigned FFCSLONG) tetloop.tet, pointmark(org(tetloop)),
+               pointmark(dest(tetloop)), pointmark(apex(tetloop)),
+-              pointmark(oppo(tetloop)), (unsigned long) sseg.sh,
++              pointmark(oppo(tetloop)), (unsigned FFCSLONG) sseg.sh,
+               pointmark(pa), pointmark(pb));
+@@ -33725,3 +33725,3 @@ int tetgenmesh::checksegments()
+                 printf("    Tet: x%lx (%d, %d, %d, %d) - ", 
+-                  (unsigned long) tetloop.tet, pointmark(org(tetloop)),
++                  (unsigned FFCSLONG) tetloop.tet, pointmark(org(tetloop)),
+                   pointmark(dest(tetloop)), pointmark(apex(tetloop)),
+@@ -33729,3 +33729,3 @@ int tetgenmesh::checksegments()
+                 if (checkseg.sh != NULL) {
+-                  printf("Seg x%lx (%d, %d).\n", (unsigned long) checkseg.sh,
++                  printf("Seg x%lx (%d, %d).\n", (unsigned FFCSLONG) checkseg.sh,
+                   pointmark(sorg(checkseg)), pointmark(sdest(checkseg))); 
+diff -u -p1 /home/alh/tmp/tetgen1.4.3/tetgen.h tetgen1.4.3/tetgen.h
+--- /home/alh/tmp/tetgen1.4.3/tetgen.h	2009-12-13 22:20:33.000000000 +0100
++++ tetgen1.4.3/tetgen.h	2010-11-24 15:43:52.687137100 +0100
+@@ -3318,5 +3318,12 @@ inline bool tetgenmesh::isfacehasedge(fa
+ 
++// FFCS: mingw64 compiler refuses to convert 8-byte pointers to 4-byte longs
++#ifdef WIN64
++#define FFCSLONG long long
++#else
++#define FFCSLONG long
++#endif
++
+ inline bool tetgenmesh::issymexist(triface* t) {
+   tetrahedron *ptr = (tetrahedron *) 
+-    ((unsigned long)(t->tet[t->loc]) & ~(unsigned long)7l);
++    ((unsigned FFCSLONG)(t->tet[t->loc]) & ~(unsigned FFCSLONG)7l);
+   return ptr != dummytet;
diff --git a/download/umfpack/Makefile.am b/download/umfpack/Makefile.am
index 527b6f3..76b6301 100644
--- a/download/umfpack/Makefile.am
+++ b/download/umfpack/Makefile.am
@@ -30,6 +30,12 @@ cholmod:$(CAMDLIB) $(COLAMDLIB)  $(AMDLIB)  $(CHOLMODLIB) $(SUITESPARSECONFIGLIB
 # the lib depend of the Makefile to force the reconstruction 
 # if the parameter change
 
+# FFCS: SuiteSparse/*/Source are not able to compile in parallel from
+# scratch ("pipe from processes is a directory"?). But specifying
+# "make -j 1" is not enough (another error pops up). Use "$(MAKE)
+# MAKEFLAGS=" instead (using "make MAKEFLAGS=" still produces an error
+# on Cygwin).
+
 $(SUITESPARSECONFIGLIB): SuiteSparse/FF 
 	cd SuiteSparse/SuiteSparse_config && make 
 	-mkdir ../include ../lib
@@ -38,7 +44,7 @@ $(SUITESPARSECONFIGLIB): SuiteSparse/FF
 	$(RANLIB) ../lib/libsuitesparseconfig.a
 
 $(UMFPACKLIB): SuiteSparse/FF 
-	cd SuiteSparse/UMFPACK/Lib && make 
+	cd SuiteSparse/UMFPACK/Lib && $(MAKE) MAKEFLAGS=
 	-mkdir ../include ../lib
 	cp -f  SuiteSparse/UMFPACK/Include/*.h ../include
 	cp -f SuiteSparse/SuiteSparse_config/SuiteSparse_config.h  ../include
@@ -46,7 +52,7 @@ $(UMFPACKLIB): SuiteSparse/FF
 	$(RANLIB) ../lib/libumfpack.a
 
 $(AMDLIB): SuiteSparse/FF 
-	cd SuiteSparse/AMD/Lib && make 
+	cd SuiteSparse/AMD/Lib && $(MAKE) MAKEFLAGS=
 	-mkdir ../include ../lib
 	cp -f  SuiteSparse/AMD/Include/*.h ../include
 	cp  SuiteSparse/AMD/Lib/libamd.a ../lib/libamd.a
@@ -90,6 +96,7 @@ SuiteSparse/SuiteSparse_config/SuiteSparse_config.mk:SuiteSparse/DATE Makefile S
 	    echo " same flags => no recompilation !  " ; \
 	else \
 	   echo "  recompile umfpack (some flags change) => clean umfpack colmod amd " ;\
+	   mkdir -p SuiteSparse/SuiteSparse_config ;\
 	   cp SuiteSparse_config.mk SuiteSparse/SuiteSparse_config/SuiteSparse_config.mk ; \
 	   (cd SuiteSparse/UMFPACK && make clean); \
 	   (cd SuiteSparse/CHOLMOD && make clean); \
@@ -130,4 +137,6 @@ clean-local:
 	-rm ../include/SuiteSparse_config.h 
 	-rm -rf UMFPACKv4.?.tar.gz UMFPACKv4.?
 	-rm SuiteSparse*gz 
-	-rm -rf SuiteSparse
\ No newline at end of file
+	-rm -rf SuiteSparse
+	-rm ../pkg/SuiteSparse-*
+	-rm SuiteSparse_config.mk
diff --git a/download/umfpack/Makefile.in b/download/umfpack/Makefile.in
index 3012332..e066d4e 100644
--- a/download/umfpack/Makefile.in
+++ b/download/umfpack/Makefile.in
@@ -59,7 +59,8 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(top_srcdir)/mkinstalldirs
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/acmacros.m4 \
-	$(top_srcdir)/acoptim.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/acoptim.m4 $(top_srcdir)/acmpi.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -129,11 +130,47 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EIGENOBJ = @EIGENOBJ@
+ENABLE_FFCS = @ENABLE_FFCS@
 EPSTOPDF = @EPSTOPDF@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+FFCS_COMPILE_fflapack = @FFCS_COMPILE_fflapack@
+FFCS_COMPILE_gsl = @FFCS_COMPILE_gsl@
+FFCS_COMPILE_hips = @FFCS_COMPILE_hips@
+FFCS_COMPILE_hypre = @FFCS_COMPILE_hypre@
+FFCS_COMPILE_ipopt = @FFCS_COMPILE_ipopt@
+FFCS_COMPILE_lapack = @FFCS_COMPILE_lapack@
+FFCS_COMPILE_mmg3d = @FFCS_COMPILE_mmg3d@
+FFCS_COMPILE_mshmet = @FFCS_COMPILE_mshmet@
+FFCS_COMPILE_mumps = @FFCS_COMPILE_mumps@
+FFCS_COMPILE_mumps_seq = @FFCS_COMPILE_mumps_seq@
+FFCS_COMPILE_pardiso = @FFCS_COMPILE_pardiso@
+FFCS_COMPILE_parms = @FFCS_COMPILE_parms@
+FFCS_COMPILE_pastix = @FFCS_COMPILE_pastix@
+FFCS_COMPILE_pipe = @FFCS_COMPILE_pipe@
+FFCS_COMPILE_scotch = @FFCS_COMPILE_scotch@
+FFCS_COMPILE_superludist = @FFCS_COMPILE_superludist@
+FFCS_COMPILE_yams = @FFCS_COMPILE_yams@
+FFCS_DYLIB_fflapack = @FFCS_DYLIB_fflapack@
+FFCS_DYLIB_gsl = @FFCS_DYLIB_gsl@
+FFCS_DYLIB_hips = @FFCS_DYLIB_hips@
+FFCS_DYLIB_hypre = @FFCS_DYLIB_hypre@
+FFCS_DYLIB_ipopt = @FFCS_DYLIB_ipopt@
+FFCS_DYLIB_lapack = @FFCS_DYLIB_lapack@
+FFCS_DYLIB_mmg3d = @FFCS_DYLIB_mmg3d@
+FFCS_DYLIB_mshmet = @FFCS_DYLIB_mshmet@
+FFCS_DYLIB_mumps = @FFCS_DYLIB_mumps@
+FFCS_DYLIB_mumps_seq = @FFCS_DYLIB_mumps_seq@
+FFCS_DYLIB_pardiso = @FFCS_DYLIB_pardiso@
+FFCS_DYLIB_parms = @FFCS_DYLIB_parms@
+FFCS_DYLIB_pastix = @FFCS_DYLIB_pastix@
+FFCS_DYLIB_pipe = @FFCS_DYLIB_pipe@
+FFCS_DYLIB_scotch = @FFCS_DYLIB_scotch@
+FFCS_DYLIB_superludist = @FFCS_DYLIB_superludist@
+FFCS_DYLIB_yams = @FFCS_DYLIB_yams@
+FFCS_MAKEFLAGS = @FFCS_MAKEFLAGS@
 FFGLUTNAME = @FFGLUTNAME@
 FFGLUTPROG = @FFGLUTPROG@
 FFLAGS = @FFLAGS@
@@ -509,6 +546,12 @@ cholmod:$(CAMDLIB) $(COLAMDLIB)  $(AMDLIB)  $(CHOLMODLIB) $(SUITESPARSECONFIGLIB
 # the lib depend of the Makefile to force the reconstruction 
 # if the parameter change
 
+# FFCS: SuiteSparse/*/Source are not able to compile in parallel from
+# scratch ("pipe from processes is a directory"?). But specifying
+# "make -j 1" is not enough (another error pops up). Use "$(MAKE)
+# MAKEFLAGS=" instead (using "make MAKEFLAGS=" still produces an error
+# on Cygwin).
+
 $(SUITESPARSECONFIGLIB): SuiteSparse/FF 
 	cd SuiteSparse/SuiteSparse_config && make 
 	-mkdir ../include ../lib
@@ -517,7 +560,7 @@ $(SUITESPARSECONFIGLIB): SuiteSparse/FF
 	$(RANLIB) ../lib/libsuitesparseconfig.a
 
 $(UMFPACKLIB): SuiteSparse/FF 
-	cd SuiteSparse/UMFPACK/Lib && make 
+	cd SuiteSparse/UMFPACK/Lib && $(MAKE) MAKEFLAGS=
 	-mkdir ../include ../lib
 	cp -f  SuiteSparse/UMFPACK/Include/*.h ../include
 	cp -f SuiteSparse/SuiteSparse_config/SuiteSparse_config.h  ../include
@@ -525,7 +568,7 @@ $(UMFPACKLIB): SuiteSparse/FF
 	$(RANLIB) ../lib/libumfpack.a
 
 $(AMDLIB): SuiteSparse/FF 
-	cd SuiteSparse/AMD/Lib && make 
+	cd SuiteSparse/AMD/Lib && $(MAKE) MAKEFLAGS=
 	-mkdir ../include ../lib
 	cp -f  SuiteSparse/AMD/Include/*.h ../include
 	cp  SuiteSparse/AMD/Lib/libamd.a ../lib/libamd.a
@@ -569,6 +612,7 @@ SuiteSparse/SuiteSparse_config/SuiteSparse_config.mk:SuiteSparse/DATE Makefile S
 	    echo " same flags => no recompilation !  " ; \
 	else \
 	   echo "  recompile umfpack (some flags change) => clean umfpack colmod amd " ;\
+	   mkdir -p SuiteSparse/SuiteSparse_config ;\
 	   cp SuiteSparse_config.mk SuiteSparse/SuiteSparse_config/SuiteSparse_config.mk ; \
 	   (cd SuiteSparse/UMFPACK && make clean); \
 	   (cd SuiteSparse/CHOLMOD && make clean); \
@@ -610,6 +654,8 @@ clean-local:
 	-rm -rf UMFPACKv4.?.tar.gz UMFPACKv4.?
 	-rm SuiteSparse*gz 
 	-rm -rf SuiteSparse
+	-rm ../pkg/SuiteSparse-*
+	-rm SuiteSparse_config.mk
 
 # 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/download/yams/._freeyams.2012.02.05.patch b/download/yams/._freeyams.2012.02.05.patch
new file mode 100644
index 0000000..6adb72e
Binary files /dev/null and b/download/yams/._freeyams.2012.02.05.patch differ
diff --git a/download/yams/Makefile b/download/yams/Makefile
index ac22627..e1e6be4 100644
--- a/download/yams/Makefile
+++ b/download/yams/Makefile
@@ -1,97 +1,109 @@
-# Downloading and compiling extra libraries
-# -----------------------------------------
-
-# $Id$
-all-local: yams
-
-include ff-flags
-
-# Downloading and compiling yams
-# -------------------------------
-# 
-DIRPKG= ../pkg
-SRCDIR= ./freeyams$(yams_VERSION)
-#-$(yams_VERSION)
-PACKAGE=$(DIRPKG)/freeyams$(yams_VERSION).tgz
-SERVER=http://www.ann.jussieu.fr/~frey/ftp/archives/
-INSTALL=../..
-yams_VERSION=.2012.02.05
-
-# ---------------------- 
-#     yamslib
-
-YAMS_DIR = $(abs_top_builddir)/download/yams/$(SRCDIR)
-YAMS_SRCDIRNOLIB = $(YAMS_DIR)/sources
-YAMS_SRCDIR = $(YAMS_DIR)/sourceslib
-YAMS_OBJDIR = $(YAMS_DIR)/objects
-
-yams: FAIRE  
-
-
-
-FAIRE: yamslib_internal.h yamslib.c yamslib.h  ../Makefile
-	$(MAKE)  install  WHERE
-	touch FAIRE
-
-$(SRCDIR)/FAIT: $(SRCDIR)/PATCH  yamslib_internal.h yamslib.c yamslib.h 
-	cp yamslib_internal.h yamslib.c yamslib.h $(YAMS_SRCDIR)/
-	cp makefile-yams.inc $(YAMS_DIR)/makefile
-	cd $(YAMS_DIR); make
-	touch $(SRCDIR)/FAIT
-install: $(SRCDIR)/FAIT
-	sed  s/defines.h/freeyams_defines.h/ <$(YAMS_SRCDIR)/yamslib.h  >../include/freeyamslib.h
-	cp $(YAMS_SRCDIR)/defines.h  ../include/freeyams_defines.h
-	-mkdir ../lib	
-	cp $(YAMS_OBJDIR)/libyams.a  ../lib/libfreeyams.a
-WHERE: 
-	-if [ -f $(SRCDIR)/FAIT ] ; then \
-	make install;  \
-	echo freeyams  LD -L at DIR@/lib -lfreeyams  >../lib/WHERE.freeyams ;\
-	echo freeyams INCLUDE -I at DIR@/include>> ../lib/WHERE.freeyams ;\
-	fi
-
-
-$(SRCDIR)/PATCH: $(PACKAGE) 
-	-mkdir -p $(SRCDIR)
-	cd $(SRCDIR); tar xvzf ../$(PACKAGE)
-	-mkdir $(YAMS_SRCDIR)
-	cp $(YAMS_SRCDIRNOLIB)/*.c $(YAMS_SRCDIRNOLIB)/*.h $(YAMS_SRCDIR)
-	rm $(YAMS_SRCDIR)/memory.c 
-	cp $(YAMS_SRCDIRNOLIB)/compil.date $(YAMS_SRCDIR)
-	cd $(YAMS_SRCDIR); patch -p2 < ../../freeyams$(yams_VERSION).patch
-	mv  $(YAMS_SRCDIR)/yams.c $(YAMS_SRCDIR)/..
-	touch $(SRCDIR)/PATCH
-
-$(PACKAGE):
-	-mkdir $(DIRPKG);
-	cd $(DIRPKG);$(WGET)   $(SERVER)/`basename $(PACKAGE)`
-
-clean-local: 
-	-rm FAIRE FAIT  $(SRCDIR)/FAIT
-	-cd $(YAMS_DIR) &&  $(MAKE) -C $(YAMS_DIR)  clean
-	-rm $(YAMS_OBJDIR)/libyams.a
-	-rm ff-flags
-	-rm ../lib/libfreeyams.a
-	-rm ../include/*freeyams*.h
-	-rm ../lib/WHERE.freeyams
-	-rm -rf $(YAMS_DIR)
-	-rm -rf $(SRCDIR)
-	-rm FAIT FAIRE
-
-clean: clean-local
-
-
-ff-flags: ../Makefile Makefile
-	grep 'abs_top_builddir *=' ../Makefile > ff-flags
-	grep 'CC *=' ../Makefile >> ff-flags
-	grep 'CFLAGS *=' ../Makefile >> ff-flags
-	grep 'LDFLAGS *=' ../Makefile >> ff-flags
-	grep 'AR *=' ../Makefile >> ff-flags
-	grep 'ARFLAGS *=' ../Makefile >> ff-flags
-	grep 'RANLIB *=' ../Makefile >> ff-flags
-	grep 'yams_VERSION *=' ./Makefile >> ff-flags
-	grep 'WGET *=' ../Makefile >> ff-flags
-	grep 'LIBS *=' ../Makefile >> ff-flags
-
-
-.PHONY: $(SRCDIR)/$(INSTALL)
\ No newline at end of file
+# Downloading and compiling extra libraries
+# -----------------------------------------
+
+# $Id$
+all-local: yams
+
+include ff-flags
+
+# Downloading and compiling yams
+# -------------------------------
+# 
+DIRPKG= ../pkg
+SRCDIR= ./freeyams$(yams_VERSION)
+#-$(yams_VERSION)
+PACKAGE=$(DIRPKG)/freeyams$(yams_VERSION).tgz
+SERVER=http://www.ann.jussieu.fr/~frey/ftp/archives/
+INSTALL=../..
+yams_VERSION=.2012.02.05
+
+# ---------------------- 
+#     yamslib
+
+YAMS_DIR = $(abs_top_builddir)/download/yams/$(SRCDIR)
+YAMS_SRCDIRNOLIB = $(YAMS_DIR)/sources
+YAMS_SRCDIR = $(YAMS_DIR)/sourceslib
+YAMS_OBJDIR = $(YAMS_DIR)/objects
+
+yams: FAIRE  
+
+
+
+# FFCS - make sure that PATCH is done sequentially otherwise its error messages are drowned into other meaningless
+# parallel compilation messages
+
+FAIRE: $(SRCDIR)/PATCH yamslib_internal.h yamslib.c yamslib.h  ../Makefile
+	$(MAKE)  install  WHERE
+	touch FAIRE
+
+$(SRCDIR)/FAIT: $(SRCDIR)/PATCH  yamslib_internal.h yamslib.c yamslib.h 
+	cp yamslib_internal.h yamslib.c yamslib.h $(YAMS_SRCDIR)/
+	cp makefile-yams.inc $(YAMS_DIR)/makefile
+	cd $(YAMS_DIR); make
+	touch $(SRCDIR)/FAIT
+install: $(SRCDIR)/FAIT
+	sed  s/defines.h/freeyams_defines.h/ <$(YAMS_SRCDIR)/yamslib.h  >../include/freeyamslib.h
+	cp $(YAMS_SRCDIR)/defines.h  ../include/freeyams_defines.h
+	-mkdir ../lib	
+	cp $(YAMS_OBJDIR)/libyams.a  ../lib/libfreeyams.a
+
+# FFCS - WHERE is made to depend on FAIT otherwise it may be built in parallel and not be activated because FAIT is not
+# there yet
+
+WHERE: $(SRCDIR)/FAIT
+	echo freeyams  LD -L at DIR@/lib -lfreeyams  >$(SRCDIR)/$(INSTALL)/lib/WHERE.freeyams ;
+	echo freeyams INCLUDE -I at DIR@/include>> $(SRCDIR)/$(INSTALL)/lib/WHERE.freeyams ;
+
+$(SRCDIR)/PATCH: $(PACKAGE) 
+	-mkdir -p $(SRCDIR)
+	cd $(SRCDIR); tar xvzf ../$(PACKAGE)
+	-mkdir $(YAMS_SRCDIR)
+	cp $(YAMS_SRCDIRNOLIB)/*.c $(YAMS_SRCDIRNOLIB)/*.h $(YAMS_SRCDIR)
+	rm $(YAMS_SRCDIR)/memory.c 
+	cp $(YAMS_SRCDIRNOLIB)/compil.date $(YAMS_SRCDIR)
+	cd $(YAMS_SRCDIR) && \
+	  patch -p2 < ../../freeyams$(yams_VERSION).patch && \
+	  patch -p2 < ../../freeyams$(yams_VERSION)-return-values.patch
+	mv  $(YAMS_SRCDIR)/yams.c $(YAMS_SRCDIR)/..
+	touch $(SRCDIR)/PATCH
+
+$(PACKAGE):
+	-mkdir $(DIRPKG);
+	cd $(DIRPKG);$(WGET)   $(SERVER)/`basename $(PACKAGE)`
+
+# FFCS: only run make clean if cd to SRCDIR worked, otherwise this is infinite loop.
+
+clean-local: 
+	-rm FAIRE FAIT  $(SRCDIR)/FAIT
+	-cd $(YAMS_DIR) &&  $(MAKE) -C $(YAMS_DIR)  clean
+	-rm $(YAMS_OBJDIR)/libyams.a
+
+# FFCS -simplifying all paths
+
+ clean: clean-local
+	-rm ff-flags
+	-rm $(SRCDIR)/$(INSTALL)/lib/libfreeyams.a
+	-rm $(SRCDIR)/$(INSTALL)/include/*freeyams*.h
+	-rm $(SRCDIR)/$(INSTALL)/lib/WHERE.freeyams
+	-rm ../lib/libfreeyams.a
+	-rm ../include/*freeyams*.h
+	-rm ../lib/WHERE.freeyams
+	-rm -rf $(YAMS_DIR)
+	-rm -rf $(SRCDIR)
+	-rm $(PACKAGE)
+	-rm FAIT FAIRE
+
+ff-flags: ../Makefile Makefile
+	grep 'abs_top_builddir *=' ../Makefile > ff-flags
+	grep 'CC *=' ../Makefile >> ff-flags
+	grep 'CFLAGS *=' ../Makefile >> ff-flags
+	grep 'LDFLAGS *=' ../Makefile >> ff-flags
+	grep 'AR *=' ../Makefile >> ff-flags
+	grep 'ARFLAGS *=' ../Makefile >> ff-flags
+	grep 'RANLIB *=' ../Makefile >> ff-flags
+	grep 'yams_VERSION *=' ./Makefile >> ff-flags
+	grep 'WGET *=' ../Makefile >> ff-flags
+	grep 'LIBS *=' ../Makefile >> ff-flags
+
+
+.PHONY: $(SRCDIR)/$(INSTALL)
diff --git a/download/yams/freeyams.2012.02.05-return-values.patch b/download/yams/freeyams.2012.02.05-return-values.patch
new file mode 100644
index 0000000..df83599
--- /dev/null
+++ b/download/yams/freeyams.2012.02.05-return-values.patch
@@ -0,0 +1,11 @@
+--- freeyams.2012.02.05/sourceslib/debug.c.orig	2013-01-27 14:24:38.489115910 +0000
++++ freeyams.2012.02.05/sourceslib/debug.c	2013-01-27 14:25:24.156118592 +0000
+@@ -178,7 +178,7 @@
+       }
+     }
+   }
+-  
++  return 0;  
+ }
+ 
+ 
diff --git a/examples++-3d/._beam-3d.edp b/examples++-3d/._beam-3d.edp
new file mode 100644
index 0000000..f7a8f68
Binary files /dev/null and b/examples++-3d/._beam-3d.edp differ
diff --git a/examples++-3d/._periodic-3d.edp b/examples++-3d/._periodic-3d.edp
new file mode 100644
index 0000000..494b436
Binary files /dev/null and b/examples++-3d/._periodic-3d.edp differ
diff --git a/examples++-3d/Lac.edp b/examples++-3d/Lac.edp
index 2ea67cb..d74cab5 100644
--- a/examples++-3d/Lac.edp
+++ b/examples++-3d/Lac.edp
@@ -16,3 +16,5 @@ mesh3 Th=buildlayers(Th2,nn,
   reffaceup = rup,
   reffacelow = rdown);
 medit("Lac",Th,wait=1);
+// FFCS: testing 3d plots
+plot(Th,cmm="Lac");
diff --git a/examples++-3d/Laplace-Adapt-3d.edp b/examples++-3d/Laplace-Adapt-3d.edp
index a47edc2..f9a33e2 100644
--- a/examples++-3d/Laplace-Adapt-3d.edp
+++ b/examples++-3d/Laplace-Adapt-3d.edp
@@ -23,7 +23,8 @@ for(int ii=0; ii<5; ii++)
   Vh h ;
   h[]=mshmet(Th3,u,normalization=1,aniso=0,nbregul=1,hmin=1e-3,hmax=0.3,err=errm);//loptions=MSHloptions,doptions=MSHdoptions);
   cout <<" h min, max = " <<  h[].min << " "<< h[].max << " " << h[].n << " " << Th3.nv << endl;
-  plot(u,wait=1);
+  // FFCS: add 3D view parameters
+  plot(u,wait=1,fill=0,boundary=0,CutPlane=0,ShowMeshes=1,LabelColors=0);
   errm*= 0.8;// change the level of error
   cout << " Th3" << Th3.nv < " " << Th3.nt << endl;
   Th3=tetgreconstruction(Th3,switch="raAQ",sizeofvolume=h*h*h/6.);
diff --git a/examples++-3d/LaplaceRT-3d.edp b/examples++-3d/LaplaceRT-3d.edp
index da7156c..f797925 100644
--- a/examples++-3d/LaplaceRT-3d.edp
+++ b/examples++-3d/LaplaceRT-3d.edp
@@ -123,7 +123,20 @@ problem laplaceMixte([u1,u2,u3,p],[v1,v2,v3,q],solver=GMRES,eps=1.0e-10,tgv=1e30
  + on(2,u1=g1n,u2=g2n,u3=g3n);
 
 laplace;
-plot(P,fill=1);
+
+// FFCS: add 3D view parameters
+real[int] CameraPositionValue = [0.0165449,3.23891,-0.991528];
+real[int] CameraFocalPointValue = [0.5,0.5,0.5];
+real[int] CameraViewUpValue = [0.671735,0.442219,0.594318];
+real[int] CutPlaneOriginValue = [0.5,0.5,1.01];
+real[int] CutPlaneNormalValue = [0.689523,0.722423,0.0516115];
+plot(P,fill=0,boundary=0,ShowMeshes=1,CutPlane=1,
+	CameraPosition=CameraPositionValue,
+	CameraFocalPoint=CameraFocalPointValue,
+	CameraViewUp=CameraViewUpValue,
+	CutPlaneOrigin=CutPlaneOriginValue,
+	CutPlaneNormal = CutPlaneNormalValue);
+
 laplaceMixte;
 
 real errL2=sqrt(int3d(Th)(square(P-p))) ;
diff --git a/examples++-3d/Makefile.am b/examples++-3d/Makefile.am
index d28f1f0..339e4bd 100644
--- a/examples++-3d/Makefile.am
+++ b/examples++-3d/Makefile.am
@@ -1,8 +1,9 @@
 # $Id$
 
 all-local: all.edp regtests.edp  freefem++.pref
-TESTS=3d-Leman.edp ArrayFE-3d.edp EqPoisson.edp Lac.edp Laplace-Adapt-3d.edp Laplace-Adapt-aniso-3d.edp Laplace3d.edp LaplaceRT-3d.edp NSI3d-carac.edp NSI3d.edp Period-Poisson-cube-ballon.edp Poisson-cube-ballon.edp Poisson.edp Poisson3d.edp Stokes.edp TruncLac.edp all.edp beam-3d.edp cone.edp convect-3d.edp cube-period.edp cylinder-3d.edp cylinder.edp fallingspheres.edp first.edp meditddm.edp p.edp periodic-3d.edp pyramide.edp  refinesphere.edp  schwarz-nm-3d.edp sphere2.edp sphere6.edp [...]
 
+TESTS=3d-Leman.edp ArrayFE-3d.edp EqPoisson.edp Lac.edp Laplace-Adapt-3d.edp Laplace-Adapt-aniso-3d.edp Laplace3d.edp LaplaceRT-3d.edp NSI3d-carac.edp NSI3d.edp Period-Poisson-cube-ballon.edp Poisson-cube-ballon.edp Poisson.edp Poisson3d.edp Stokes.edp TruncLac.edp  beam-3d.edp cone.edp convect-3d.edp cube-period.edp cylinder-3d.edp cylinder.edp fallingspheres.edp first.edp meditddm.edp p.edp periodic-3d.edp pyramide.edp  refinesphere.edp  schwarz-nm-3d.edp sphere2.edp sphere6.edp tetgen [...]
+XFAIL_TESTS=Laplace-Adapt-aniso-3d.edp fallingspheres.edp Laplace-Adapt-3d.edp Period-Poisson-cube-ballon.edp Poisson-cube-ballon.edp cylinder.edp refinesphere.edp tetgencube.edp tetgenholeregion.edp Poisson3d.edp
 LOG_DRIVER=$(SHELL) $(top_srcdir)/test-driver-ff
 TESTS_ENVIRONMENT=TEST_FFPP=$(TEST_FFPP) FLAGS_FFPP=-nw
 
@@ -28,10 +29,11 @@ Ref: makeref.edp freefem++.pref
 
 makeref.edp: regtests.m4 ../regtests.m4
 	m4 regtests.m4 > makeref.edp
+
 freefem++.pref:
 	echo loadpath = \"../examples++-load/\" >freefem++.pref
 	echo loadpath += \"./\" >>freefem++.pref
-
+3d-Leman.edp:freefem++.pref
 install-exec-local:: 
 	$(mkinstalldirs) -m 755 $(DESTDIR)$(ff_prefix_dir)/idp
 	$(INSTALL)  -m 555  $(LIST_IDP)  $(DESTDIR)$(ff_prefix_dir)/idp
diff --git a/examples++-3d/Makefile.in b/examples++-3d/Makefile.in
index ebfcd59..ab6bdff 100644
--- a/examples++-3d/Makefile.in
+++ b/examples++-3d/Makefile.in
@@ -56,7 +56,8 @@ 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)/acmacros.m4 \
-	$(top_srcdir)/acoptim.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/acoptim.m4 $(top_srcdir)/acmpi.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -329,11 +330,47 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EIGENOBJ = @EIGENOBJ@
+ENABLE_FFCS = @ENABLE_FFCS@
 EPSTOPDF = @EPSTOPDF@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+FFCS_COMPILE_fflapack = @FFCS_COMPILE_fflapack@
+FFCS_COMPILE_gsl = @FFCS_COMPILE_gsl@
+FFCS_COMPILE_hips = @FFCS_COMPILE_hips@
+FFCS_COMPILE_hypre = @FFCS_COMPILE_hypre@
+FFCS_COMPILE_ipopt = @FFCS_COMPILE_ipopt@
+FFCS_COMPILE_lapack = @FFCS_COMPILE_lapack@
+FFCS_COMPILE_mmg3d = @FFCS_COMPILE_mmg3d@
+FFCS_COMPILE_mshmet = @FFCS_COMPILE_mshmet@
+FFCS_COMPILE_mumps = @FFCS_COMPILE_mumps@
+FFCS_COMPILE_mumps_seq = @FFCS_COMPILE_mumps_seq@
+FFCS_COMPILE_pardiso = @FFCS_COMPILE_pardiso@
+FFCS_COMPILE_parms = @FFCS_COMPILE_parms@
+FFCS_COMPILE_pastix = @FFCS_COMPILE_pastix@
+FFCS_COMPILE_pipe = @FFCS_COMPILE_pipe@
+FFCS_COMPILE_scotch = @FFCS_COMPILE_scotch@
+FFCS_COMPILE_superludist = @FFCS_COMPILE_superludist@
+FFCS_COMPILE_yams = @FFCS_COMPILE_yams@
+FFCS_DYLIB_fflapack = @FFCS_DYLIB_fflapack@
+FFCS_DYLIB_gsl = @FFCS_DYLIB_gsl@
+FFCS_DYLIB_hips = @FFCS_DYLIB_hips@
+FFCS_DYLIB_hypre = @FFCS_DYLIB_hypre@
+FFCS_DYLIB_ipopt = @FFCS_DYLIB_ipopt@
+FFCS_DYLIB_lapack = @FFCS_DYLIB_lapack@
+FFCS_DYLIB_mmg3d = @FFCS_DYLIB_mmg3d@
+FFCS_DYLIB_mshmet = @FFCS_DYLIB_mshmet@
+FFCS_DYLIB_mumps = @FFCS_DYLIB_mumps@
+FFCS_DYLIB_mumps_seq = @FFCS_DYLIB_mumps_seq@
+FFCS_DYLIB_pardiso = @FFCS_DYLIB_pardiso@
+FFCS_DYLIB_parms = @FFCS_DYLIB_parms@
+FFCS_DYLIB_pastix = @FFCS_DYLIB_pastix@
+FFCS_DYLIB_pipe = @FFCS_DYLIB_pipe@
+FFCS_DYLIB_scotch = @FFCS_DYLIB_scotch@
+FFCS_DYLIB_superludist = @FFCS_DYLIB_superludist@
+FFCS_DYLIB_yams = @FFCS_DYLIB_yams@
+FFCS_MAKEFLAGS = @FFCS_MAKEFLAGS@
 FFGLUTNAME = @FFGLUTNAME@
 FFGLUTPROG = @FFGLUTPROG@
 FFLAGS = @FFLAGS@
@@ -500,7 +537,8 @@ target_alias = @target_alias@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-TESTS = 3d-Leman.edp ArrayFE-3d.edp EqPoisson.edp Lac.edp Laplace-Adapt-3d.edp Laplace-Adapt-aniso-3d.edp Laplace3d.edp LaplaceRT-3d.edp NSI3d-carac.edp NSI3d.edp Period-Poisson-cube-ballon.edp Poisson-cube-ballon.edp Poisson.edp Poisson3d.edp Stokes.edp TruncLac.edp all.edp beam-3d.edp cone.edp convect-3d.edp cube-period.edp cylinder-3d.edp cylinder.edp fallingspheres.edp first.edp meditddm.edp p.edp periodic-3d.edp pyramide.edp  refinesphere.edp  schwarz-nm-3d.edp sphere2.edp sphere6.e [...]
+TESTS = 3d-Leman.edp ArrayFE-3d.edp EqPoisson.edp Lac.edp Laplace-Adapt-3d.edp Laplace-Adapt-aniso-3d.edp Laplace3d.edp LaplaceRT-3d.edp NSI3d-carac.edp NSI3d.edp Period-Poisson-cube-ballon.edp Poisson-cube-ballon.edp Poisson.edp Poisson3d.edp Stokes.edp TruncLac.edp  beam-3d.edp cone.edp convect-3d.edp cube-period.edp cylinder-3d.edp cylinder.edp fallingspheres.edp first.edp meditddm.edp p.edp periodic-3d.edp pyramide.edp  refinesphere.edp  schwarz-nm-3d.edp sphere2.edp sphere6.edp tetg [...]
+XFAIL_TESTS = Laplace-Adapt-aniso-3d.edp fallingspheres.edp Laplace-Adapt-3d.edp Period-Poisson-cube-ballon.edp Poisson-cube-ballon.edp cylinder.edp refinesphere.edp tetgencube.edp tetgenholeregion.edp Poisson3d.edp
 LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-ff
 TESTS_ENVIRONMENT = TEST_FFPP=$(TEST_FFPP) FLAGS_FFPP=-nw
 LIST_IDP = MeshSurface.idp cube.idp
@@ -801,13 +839,6 @@ TruncLac.edp.log: TruncLac.edp
 	--log-file $$b.log --trs-file $$b.trs \
 	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
-all.edp.log: all.edp
-	@p='all.edp'; \
-	b='all.edp'; \
-	$(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) \
-	"$$tst" $(AM_TESTS_FD_REDIRECT)
 beam-3d.edp.log: beam-3d.edp
 	@p='beam-3d.edp'; \
 	b='beam-3d.edp'; \
@@ -1115,10 +1146,11 @@ Ref: makeref.edp freefem++.pref
 
 makeref.edp: regtests.m4 ../regtests.m4
 	m4 regtests.m4 > makeref.edp
+
 freefem++.pref:
 	echo loadpath = \"../examples++-load/\" >freefem++.pref
 	echo loadpath += \"./\" >>freefem++.pref
-
+3d-Leman.edp:freefem++.pref
 install-exec-local:: 
 	$(mkinstalldirs) -m 755 $(DESTDIR)$(ff_prefix_dir)/idp
 	$(INSTALL)  -m 555  $(LIST_IDP)  $(DESTDIR)$(ff_prefix_dir)/idp
diff --git a/examples++-3d/Period-Poisson-cube-ballon.edp b/examples++-3d/Period-Poisson-cube-ballon.edp
index 1dd91a9..dc9dd11 100755
--- a/examples++-3d/Period-Poisson-cube-ballon.edp
+++ b/examples++-3d/Period-Poisson-cube-ballon.edp
@@ -25,6 +25,8 @@ catch(...)
     // Tetrahelize the interior of the cube with tetgen
     medit("tetg",Th,wait=1);
     savemesh(Th,"Th-hex-sph.mesh");
+    // FFCS: testing 3d plots
+    plot(Th);
  }
 
 
diff --git a/examples++-3d/Poisson-cube-ballon.edp b/examples++-3d/Poisson-cube-ballon.edp
index 25bcc84..293a207 100644
--- a/examples++-3d/Poisson-cube-ballon.edp
+++ b/examples++-3d/Poisson-cube-ballon.edp
@@ -116,7 +116,19 @@ problem P(uh,vh)=
   
   P;
 
-plot(uh,wait=1, nbiso=6);
+// FFCS: with 3D view parameters
+real[int] CameraPositionValue = [3.50634,-2.51489,2.60313];
+real[int] CameraFocalPointValue = [0.0604689,-0.304636,-0.256484];
+real[int] CameraViewUpValue = [0.7198,0.502367,-0.479078];
+real[int] CutPlaneOriginValue = [-0.5,-0.55,0.0335184];
+real[int] CutPlaneNormalValue = [0,0,1];
+plot(uh,wait=1, nbiso=6,
+	BorderAsMesh = 1,
+	CameraPosition=CameraPositionValue,
+	CameraFocalPoint=CameraFocalPointValue,
+	CameraViewUp=CameraViewUpValue,
+	CutPlaneOrigin=CutPlaneOriginValue,
+	CutPlaneNormal = CutPlaneNormalValue);
 medit("   uh ",Th, uh,wait=1); 
 
 
diff --git a/examples++-3d/Poisson3d.edp b/examples++-3d/Poisson3d.edp
index f8a7983..b9124cb 100644
--- a/examples++-3d/Poisson3d.edp
+++ b/examples++-3d/Poisson3d.edp
@@ -34,6 +34,9 @@ mesh3 Th3=tetgtransfo(Th,transfo=[f1,f2,f3],nbofregions=1,regionlist=domaine);
 //savemesh(Th3,"sphere.meshb");
 medit("sphere",Th3);
 
+// FFCS - check 3D plots
+plot(Th3,cmm="sphere");
+
 fespace Vh(Th3,P23d);
 func ue =   2*x*x + 3*y*y + 4*z*z+ 5*x*y+6*x*z+1;
 func f= -18. ;
@@ -65,4 +68,7 @@ Vh2 u2=u,u2e=ue;
 plot(u2,wait=1);
 plot(u2,u2e,wait=1);
 
+// FFCS - check 3D plots
+plot(u);
+
 assert(err < 1e-9);
diff --git a/examples++-3d/Stokes.edp b/examples++-3d/Stokes.edp
index 64250ad..a591721 100644
--- a/examples++-3d/Stokes.edp
+++ b/examples++-3d/Stokes.edp
@@ -9,6 +9,10 @@ mesh3 Th=buildlayers(Th2,nn,
   reffaceup = rup,     reffacelow = rdown);
   
 medit("c10x10x10",Th,wait=1);
+
+// FFCS: testing 3d plots
+plot(Th);
+
 fespace VVh(Th,[P2,P2,P2,P1]);
 fespace Vh(Th,P23d);
 macro Grad(u) [dx(u),dy(u),dz(u)]// EOM
@@ -32,3 +36,9 @@ for(int i=1;i<10;i++)
     p2= p(x,yy,y);
     plot([ux,uz],p2,cmm=" cut y = "+yy,wait= 1);
   }
+
+// FFCS: testing 3d plots
+plot(u1);
+plot(u2);
+plot(u3);
+plot(p);
diff --git a/examples++-3d/TruncLac.edp b/examples++-3d/TruncLac.edp
index 9a13903..bb19ecc 100644
--- a/examples++-3d/TruncLac.edp
+++ b/examples++-3d/TruncLac.edp
@@ -22,4 +22,6 @@ func u=x^2+y^2;
 
 mesh3 Th3=trunc(Th,(u-0.5)>1.e-10,split=1,label=135);
 medit("Lac",wait=1,Th);
-medit("LacTruncated",Th3,wait=1);
\ No newline at end of file
+plot(Th); // FFCS: testing 3d plots
+medit("LacTruncated",Th3,wait=1);
+plot(Th3); // FFCS: testing 3d plots
diff --git a/examples++-3d/cone.edp b/examples++-3d/cone.edp
index 08be728..f43dbad 100644
--- a/examples++-3d/cone.edp
+++ b/examples++-3d/cone.edp
@@ -22,5 +22,6 @@ func fz= x;
 int[int] r1T=[0,0], r2T=[0,0,2,2];
 int[int] r4T=[0,2]; 
 mesh3 Th3T=buildlayers(Th2,coef= max(.01,y/max(x,0.4) ), MaxLayersT,zbound=[zminT,zmaxT],transfo=[fx,fy,fz],facemerge=1, region=r1T, labelmid=r2T);
-
-medit("cone",Th3T,wait=1);
\ No newline at end of file
+medit("cone",Th3T,wait=1);
+// FFCS: testing 3d plots
+plot(Th3T,cmm="cone");
diff --git a/examples++-3d/cube-period.edp b/examples++-3d/cube-period.edp
index c980590..d58371d 100644
--- a/examples++-3d/cube-period.edp
+++ b/examples++-3d/cube-period.edp
@@ -68,7 +68,11 @@ assert(er==0 && nnn == Vh.ndof && nnn1 == Vhh.ndof); // some verification ...
 macro Grad(u) [dx(u),dy(u),dz(u)] //;
   solve P(u,v,solver=CG)= int3d(Th)(Grad(u)'*Grad(v)) - int3d(Th)(f*v); //') ;
 cout << "Err L2 = " << sqrt(int3d(Th)( square(u-uu)) ) << endl;
-Vh2 u0=u(x,y,0);
-Vh2 u1=u(x,y,1);
 
-plot(u0,u1,wait=1);
\ No newline at end of file
+// FFCS: add 3D view
+
+///Vh2 u0=u(x,y,0);
+///Vh2 u1=u(x,y,1);
+///plot(u0,u1,wait=1);
+
+plot(u,nbiso=10);
diff --git a/examples++-3d/cylinder-3d.edp b/examples++-3d/cylinder-3d.edp
index 2f6d3a1..39c78d0 100644
--- a/examples++-3d/cylinder-3d.edp
+++ b/examples++-3d/cylinder-3d.edp
@@ -15,4 +15,6 @@ mesh3 Th=buildlayers(Baseh,nlayer,
   labelmid=rmid, 
   reffaceup = rup,
   reffacelow = rdown);
-medit("Cyl",Th,wait=1);
\ No newline at end of file
+medit("Cyl",Th,wait=1);
+// FFCS: testing 3d plots
+plot(Th,cmm="Cyl");
diff --git a/examples++-3d/cylinder.edp b/examples++-3d/cylinder.edp
index ccc03bc..b1dac8e 100644
--- a/examples++-3d/cylinder.edp
+++ b/examples++-3d/cylinder.edp
@@ -28,4 +28,6 @@ real[int] domaine = [1.5,0.,0.,1,voltet];
 mesh3 Th=tetg(Thsurf,switch="pqaaAAYYQ",nbofregions=1,regionlist=domaine);
 
 savemesh(Th,"cyl.mesh");
-medit("cyl",Th,wait=1);
\ No newline at end of file
+medit("cyl",Th,wait=1);
+// FFCS: testing 3d plots
+plot(Th,cmm="cyl");
diff --git a/examples++-3d/pyramide.edp b/examples++-3d/pyramide.edp
index d36849d..c463ba8 100644
--- a/examples++-3d/pyramide.edp
+++ b/examples++-3d/pyramide.edp
@@ -25,3 +25,5 @@ mesh3 Th3=buildlayers(Th2,coef= max(fpyramide/HH,0.01), nn,zbound=[0,fpyramide],
  region=r1T, labelup=r2up, labeldown=r2down);
 
 medit("Pyramide",Th3,wait=1);
+// FFCS: testing 3d plots
+plot(Th3);
diff --git a/examples++-3d/refinesphere.edp b/examples++-3d/refinesphere.edp
index b2f3626..063bf0a 100644
--- a/examples++-3d/refinesphere.edp
+++ b/examples++-3d/refinesphere.edp
@@ -1,54 +1,59 @@
-// file adaptsphere.edp
-load "msh3"
-load "tetgen"
-load "medit"
-
-mesh Th=square(10,20,[x*pi-pi/2,2*y*pi]);  //  $]\frac{-pi}{2},frac{-pi}{2}[\times]0,2\pi[ $
-//  a parametrization of a sphere 
-func f1 =cos(x)*cos(y);
-func f2 =cos(x)*sin(y);
-func f3 = sin(x);
-//  partiel derivative of the parametrization DF
-func f1x=sin(x)*cos(y);   
-func f1y=-cos(x)*sin(y);
-func f2x=-sin(x)*sin(y);
-func f2y=cos(x)*cos(y);
-func f3x=cos(x);
-func f3y=0;
-// $  M = DF^t DF $
-func m11=f1x^2+f2x^2+f3x^2;
-func m21=f1x*f1y+f2x*f2y+f3x*f3y;
-func m22=f1y^2+f2y^2+f3y^2;
-
-func perio=[[4,y],[2,y],[1,x],[3,x]];  
-real hh=0.1;
-real vv= 1/square(hh);
-verbosity=2;
-Th=adaptmesh(Th,m11*vv,m21*vv,m22*vv,IsMetric=1,periodic=perio);
-Th=adaptmesh(Th,m11*vv,m21*vv,m22*vv,IsMetric=1,periodic=perio);
-plot(Th,wait=1);
-
-verbosity=2;
-
-// construction of the surface of spheres
-real Rmin  = 1.;
-func f1min = Rmin*f1;
-func f2min = Rmin*f2;
-func f3min = Rmin*f3;
-
-mesh3 Th3=movemesh23(Th,transfo=[f1min,f2min,f3min]);
-
-real[int] domain = [0.,0.,0.,145,0.01];
-mesh3 Th3sph=tetg(Th3,switch="paAAQYY",nbofregions=1,regionlist=domain);
-
-int[int] newlabel = [145,18];
-real[int] domainrefine = [0.,0.,0.,145,0.0001];
-mesh3 Th3sphrefine=tetgreconstruction(Th3sph,switch="raAQ",region=newlabel,nbofregions=1,regionlist=domainrefine,sizeofvolume=0.0001);
-
-int[int] newlabel2 = [145,53];
-func fsize = 0.01/(( 1 + 5*sqrt( (x-0.5)^2+(y-0.5)^2+(z-0.5)^2) )^3);
-mesh3 Th3sphrefine2=tetgreconstruction(Th3sph,switch="raAQ",region=newlabel2,sizeofvolume=fsize);
-
- medit("sphere",Th3sph,wait=1);
- medit("sphererefinedomain",wait=1,Th3sphrefine);
-  medit("sphererefinelocal",wait=1,Th3sphrefine2);
+// file adaptsphere.edp
+load "msh3"
+load "tetgen"
+load "medit"
+
+mesh Th=square(10,20,[x*pi-pi/2,2*y*pi]);  //  $]\frac{-pi}{2},frac{-pi}{2}[\times]0,2\pi[ $
+//  a parametrization of a sphere 
+func f1 =cos(x)*cos(y);
+func f2 =cos(x)*sin(y);
+func f3 = sin(x);
+//  partiel derivative of the parametrization DF
+func f1x=sin(x)*cos(y);   
+func f1y=-cos(x)*sin(y);
+func f2x=-sin(x)*sin(y);
+func f2y=cos(x)*cos(y);
+func f3x=cos(x);
+func f3y=0;
+// $  M = DF^t DF $
+func m11=f1x^2+f2x^2+f3x^2;
+func m21=f1x*f1y+f2x*f2y+f3x*f3y;
+func m22=f1y^2+f2y^2+f3y^2;
+
+func perio=[[4,y],[2,y],[1,x],[3,x]];  
+real hh=0.1;
+real vv= 1/square(hh);
+verbosity=2;
+Th=adaptmesh(Th,m11*vv,m21*vv,m22*vv,IsMetric=1,periodic=perio);
+Th=adaptmesh(Th,m11*vv,m21*vv,m22*vv,IsMetric=1,periodic=perio);
+plot(Th,wait=1);
+
+verbosity=2;
+
+// construction of the surface of spheres
+real Rmin  = 1.;
+func f1min = Rmin*f1;
+func f2min = Rmin*f2;
+func f3min = Rmin*f3;
+
+mesh3 Th3=movemesh23(Th,transfo=[f1min,f2min,f3min]);
+
+real[int] domain = [0.,0.,0.,145,0.01];
+mesh3 Th3sph=tetg(Th3,switch="paAAQYY",nbofregions=1,regionlist=domain);
+
+int[int] newlabel = [145,18];
+real[int] domainrefine = [0.,0.,0.,145,0.0001];
+mesh3 Th3sphrefine=tetgreconstruction(Th3sph,switch="raAQ",region=newlabel,nbofregions=1,regionlist=domainrefine,sizeofvolume=0.0001);
+
+int[int] newlabel2 = [145,53];
+func fsize = 0.01/(( 1 + 5*sqrt( (x-0.5)^2+(y-0.5)^2+(z-0.5)^2) )^3);
+mesh3 Th3sphrefine2=tetgreconstruction(Th3sph,switch="raAQ",region=newlabel2,sizeofvolume=fsize);
+
+ medit("sphere",Th3sph,wait=1);
+ medit("sphererefinedomain",wait=1,Th3sphrefine);
+  medit("sphererefinelocal",wait=1,Th3sphrefine2);
+
+// FFCS: testing 3d plots
+plot(Th3sph);
+plot(Th3sphrefine);
+plot(Th3sphrefine2);
diff --git a/examples++-3d/sphere2.edp b/examples++-3d/sphere2.edp
index 170fc85..a075441 100644
--- a/examples++-3d/sphere2.edp
+++ b/examples++-3d/sphere2.edp
@@ -18,4 +18,12 @@ if(1)
     medit("Thup",Thup,wait=1);
     medit("Thdown",Thdown,wait=1);
     medit("Th",Th,wait=1);
+ 
+   // FFCS: removing medit calls for regression tests will empty the
+   // curly brackets
+   1;
   }
+// FFCS: testing 3d plots
+plot(Thup);
+plot(Thdown);
+plot(Th);
diff --git a/examples++-3d/sphere6.edp b/examples++-3d/sphere6.edp
index 5495c83..41d4a06 100644
--- a/examples++-3d/sphere6.edp
+++ b/examples++-3d/sphere6.edp
@@ -29,3 +29,5 @@ plot(Th,wait=1);
 //exec("ffmedit T.mesh");
 medit("Th",Th);
 
+// FFCS: testing 3d plots
+plot(Th);
diff --git a/examples++-3d/tetgencube.edp b/examples++-3d/tetgencube.edp
index 71b7390..a08d8be 100644
--- a/examples++-3d/tetgencube.edp
+++ b/examples++-3d/tetgencube.edp
@@ -73,5 +73,7 @@ medit("maillagesurf",Thmv2surf,wait=1);
 //savemesh(Thmv2surf,"maillagesurfacecylindre.mesh");
 //medit("maillageplein",Thmv2);
 
+// FFCS: testing 3d plots
+plot(Thmv2surf);
 
 
diff --git a/examples++-3d/tetgenholeregion.edp b/examples++-3d/tetgenholeregion.edp
index 4d0dde3..e9798d8 100755
--- a/examples++-3d/tetgenholeregion.edp
+++ b/examples++-3d/tetgenholeregion.edp
@@ -31,6 +31,7 @@ Th=adaptmesh(Th,m11*vv,m21*vv,m22*vv,IsMetric=1,periodic=perio);
 Th=adaptmesh(Th,m11*vv,m21*vv,m22*vv,IsMetric=1,periodic=perio);
 //plot(Th,wait=1);
 medit("squaremesh",Th,wait=1);
+plot(Th); // FFCS: testing 3d plots
 verbosity=2;
 
 // construction of the surface of spheres
@@ -46,6 +47,7 @@ cout << "=====================" << endl;
 cout << "=====================" << endl;
 savemesh(Th3sph,"sphereR1.mesh");
 medit("sphereR1",wait=1,Th3sph);
+plot(Th3sph); // FFCS: testing 3d plots
 real Rmax  = 2.;
 func f1max = Rmax*f1;
 func f2max = Rmax*f2;
@@ -60,6 +62,7 @@ cout << "addition" << endl;
 mesh3 Th3=Th3sph+Th3sph2;
 savemesh(Th3,"sphereAdd.mesh");
 medit("sphereSurfaceAdd",wait=1,Th3);
+plot(Th3); // FFCS: testing 3d plots
 
 
 real[int] domain2 = [1.5,0.,0.,145,0.001,0.5,0.,0.,18,0.01];
@@ -72,6 +75,7 @@ cout << "finish: tetgen call without hole" << endl;
 cout << "=============================" << endl;
 savemesh(Th3fin,"spherewithtworegion.mesh"); 
 medit("spherewithtworegion",wait=1,Th3fin);
+plot(Th3fin); // FFCS: testing 3d plots
 
 real[int] hole = [0.,0.,0.];
 real[int] domain = [1.5,0.,0.,53,0.001];
@@ -84,6 +88,7 @@ cout << "finish: tetgen call with hole   " << endl;
 cout << "=============================" << endl;
 savemesh(Th3finhole,"spherewithahole.mesh"); 
 medit("spherewithahole",wait=1,Th3finhole);
+plot(Th3finhole); // FFCS: testing 3d plots
 
 
 
diff --git a/examples++-bug/Makefile.in b/examples++-bug/Makefile.in
index 173d374..834d0f6 100644
--- a/examples++-bug/Makefile.in
+++ b/examples++-bug/Makefile.in
@@ -56,7 +56,8 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(top_srcdir)/mkinstalldirs
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/acmacros.m4 \
-	$(top_srcdir)/acoptim.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/acoptim.m4 $(top_srcdir)/acmpi.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -126,11 +127,47 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EIGENOBJ = @EIGENOBJ@
+ENABLE_FFCS = @ENABLE_FFCS@
 EPSTOPDF = @EPSTOPDF@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+FFCS_COMPILE_fflapack = @FFCS_COMPILE_fflapack@
+FFCS_COMPILE_gsl = @FFCS_COMPILE_gsl@
+FFCS_COMPILE_hips = @FFCS_COMPILE_hips@
+FFCS_COMPILE_hypre = @FFCS_COMPILE_hypre@
+FFCS_COMPILE_ipopt = @FFCS_COMPILE_ipopt@
+FFCS_COMPILE_lapack = @FFCS_COMPILE_lapack@
+FFCS_COMPILE_mmg3d = @FFCS_COMPILE_mmg3d@
+FFCS_COMPILE_mshmet = @FFCS_COMPILE_mshmet@
+FFCS_COMPILE_mumps = @FFCS_COMPILE_mumps@
+FFCS_COMPILE_mumps_seq = @FFCS_COMPILE_mumps_seq@
+FFCS_COMPILE_pardiso = @FFCS_COMPILE_pardiso@
+FFCS_COMPILE_parms = @FFCS_COMPILE_parms@
+FFCS_COMPILE_pastix = @FFCS_COMPILE_pastix@
+FFCS_COMPILE_pipe = @FFCS_COMPILE_pipe@
+FFCS_COMPILE_scotch = @FFCS_COMPILE_scotch@
+FFCS_COMPILE_superludist = @FFCS_COMPILE_superludist@
+FFCS_COMPILE_yams = @FFCS_COMPILE_yams@
+FFCS_DYLIB_fflapack = @FFCS_DYLIB_fflapack@
+FFCS_DYLIB_gsl = @FFCS_DYLIB_gsl@
+FFCS_DYLIB_hips = @FFCS_DYLIB_hips@
+FFCS_DYLIB_hypre = @FFCS_DYLIB_hypre@
+FFCS_DYLIB_ipopt = @FFCS_DYLIB_ipopt@
+FFCS_DYLIB_lapack = @FFCS_DYLIB_lapack@
+FFCS_DYLIB_mmg3d = @FFCS_DYLIB_mmg3d@
+FFCS_DYLIB_mshmet = @FFCS_DYLIB_mshmet@
+FFCS_DYLIB_mumps = @FFCS_DYLIB_mumps@
+FFCS_DYLIB_mumps_seq = @FFCS_DYLIB_mumps_seq@
+FFCS_DYLIB_pardiso = @FFCS_DYLIB_pardiso@
+FFCS_DYLIB_parms = @FFCS_DYLIB_parms@
+FFCS_DYLIB_pastix = @FFCS_DYLIB_pastix@
+FFCS_DYLIB_pipe = @FFCS_DYLIB_pipe@
+FFCS_DYLIB_scotch = @FFCS_DYLIB_scotch@
+FFCS_DYLIB_superludist = @FFCS_DYLIB_superludist@
+FFCS_DYLIB_yams = @FFCS_DYLIB_yams@
+FFCS_MAKEFLAGS = @FFCS_MAKEFLAGS@
 FFGLUTNAME = @FFGLUTNAME@
 FFGLUTPROG = @FFGLUTPROG@
 FFLAGS = @FFLAGS@
diff --git a/examples++-bug/bugifexp.edp b/examples++-bug/bugifexp.edp
new file mode 100644
index 0000000..5f6ad6c
--- /dev/null
+++ b/examples++-bug/bugifexp.edp
@@ -0,0 +1,4 @@
+mesh Th=square(10,10);
+fespace Vh(Th,P1);
+// bug due  to optimisation process .. HARD ....  FH 
+Vh u = y ? 1./y : x;
\ No newline at end of file
diff --git a/examples++-chapt3/._NSNewton.edp b/examples++-chapt3/._NSNewton.edp
new file mode 100644
index 0000000..f7a8f68
Binary files /dev/null and b/examples++-chapt3/._NSNewton.edp differ
diff --git a/examples++-chapt3/._NSprojection.edp b/examples++-chapt3/._NSprojection.edp
new file mode 100755
index 0000000..f7a8f68
Binary files /dev/null and b/examples++-chapt3/._NSprojection.edp differ
diff --git a/examples++-chapt3/._convects.edp b/examples++-chapt3/._convects.edp
new file mode 100755
index 0000000..494b436
Binary files /dev/null and b/examples++-chapt3/._convects.edp differ
diff --git a/examples++-chapt3/BlackScholes2D.edp b/examples++-chapt3/BlackScholes2D.edp
index 888d4c8..4399c65 100755
--- a/examples++-chapt3/BlackScholes2D.edp
+++ b/examples++-chapt3/BlackScholes2D.edp
@@ -1,29 +1,29 @@
-// file BlackScholes2D.edp
-int m=30,L=80,LL=80, j=100;
-real sigmax=0.3, sigmay=0.3, rho=0.3, r=0.05, K=40, dt=0.01;
-mesh th=square(m,m,[L*x,LL*y]);
-fespace Vh(th,P1);
-
-Vh u=max(K-max(x,y),0.);
-Vh xveloc, yveloc, v,uold;
-
-for (int n=0; n*dt <= 1.0; n++)
-{
-  if(j>20)  { th = adaptmesh(th,u,verbosity=1,abserror=1,nbjacoby=2,
-              err=0.001, nbvx=5000, omega=1.8, ratio=1.8, nbsmooth=3,
-              splitpbedge=1, maxsubdiv=5,rescaling=1) ;
-     j=0;
-     xveloc = -x*r+x*sigmax^2+x*rho*sigmax*sigmay/2;
-     yveloc = -y*r+y*sigmay^2+y*rho*sigmax*sigmay/2;
-     u=u;
-    };
-  uold=u;
-  solve eq1(u,v,init=j,solver=LU) = int2d(th)(  u*v*(r+1/dt)
-    + dx(u)*dx(v)*(x*sigmax)^2/2 + dy(u)*dy(v)*(y*sigmay)^2/2
-    + dy(u)*dx(v)*rho*sigmax*sigmay*x*y/2 + dx(u)*dy(v)*rho*sigmax*sigmay*x*y/2)
-    + int2d(th)( -v*convect([xveloc,yveloc],dt,uold)/dt)+ on(2,3,u=0);
-
-  j=j+1;
-};
-plot(u,wait=1,value=1);
-plot(th,wait=1);
+// file BlackScholes2D.edp
+int m=30,L=80,LL=80, j=100;
+real sigmax=0.3, sigmay=0.3, rho=0.3, r=0.05, K=40, dt=0.01;
+mesh th=square(m,m,[L*x,LL*y]);
+fespace Vh(th,P1);
+
+Vh u=max(K-max(x,y),0.);
+Vh xveloc, yveloc, v,uold;
+
+for (int n=0; n*dt <= 1.0; n++)
+{
+  if(j>20)  { th = adaptmesh(th,u,verbosity=1,abserror=1,nbjacoby=2,
+              err=0.001, nbvx=5000, omega=1.8, ratio=1.8, nbsmooth=3,
+              splitpbedge=1, maxsubdiv=5,rescaling=1) ;
+     j=0;
+     xveloc = -x*r+x*sigmax^2+x*rho*sigmax*sigmay/2;
+     yveloc = -y*r+y*sigmay^2+y*rho*sigmax*sigmay/2;
+     u=u;
+    };
+  uold=u;
+  solve eq1(u,v,init=j,solver=LU) = int2d(th)(  u*v*(r+1/dt)
+    + dx(u)*dx(v)*(x*sigmax)^2/2 + dy(u)*dy(v)*(y*sigmay)^2/2
+    + dy(u)*dx(v)*rho*sigmax*sigmay*x*y/2 + dx(u)*dy(v)*rho*sigmax*sigmay*x*y/2)
+    + int2d(th)( -v*convect([xveloc,yveloc],dt,uold)/dt)+ on(2,3,u=0);
+
+  j=j+1;
+};
+plot(u,wait=1,value=1);
+plot(th,wait=1);
diff --git a/examples++-chapt3/Makefile.am b/examples++-chapt3/Makefile.am
index 1d60f04..ca1be28 100644
--- a/examples++-chapt3/Makefile.am
+++ b/examples++-chapt3/Makefile.am
@@ -1,7 +1,10 @@
 # $Id$
 
-all-local: all.edp regtests.edp
+all-local: all.edp regtests.edp freefem++.pref
 TESTS=BlackScholes2D.edp NSNewton.edp NSprojection.edp condensor.edp convects.edp heatex.edp lame.edp membrane.edp membranerror.edp muwave.edp optimcontrol.edp potential.edp schwarz.edp sound.edp stokes.edp test1.edp testbed.edp thermal.edp thermic.edp
+# if .. no arpack ... 
+XFAIL_TESTS=sound.edp
+
 EXTRA_DIST=*.edp  all.edp regtests.edp regtests.m4 ref.edp
 LOG_DRIVER=$(SHELL) $(top_srcdir)/test-driver-ff
 TESTS_ENVIRONMENT=TEST_FFPP=$(TEST_FFPP) FLAGS_FFPP=-nw
@@ -25,4 +28,8 @@ makeref.edp: regtests.m4 ../regtests.m4
 # To check the scripts against their reference values
 regtests.edp: regtests.m4 ../regtests.m4
 	m4 -DASSERT regtests.m4 > regtests.edp
+freefem++.pref:
+	echo loadpath = \"../examples++-load/\" >freefem++.pref
+	echo loadpath += \"./\" >>freefem++.pref
+
 FORCE:
\ No newline at end of file
diff --git a/examples++-chapt3/Makefile.in b/examples++-chapt3/Makefile.in
index 6a2df52..49e7339 100644
--- a/examples++-chapt3/Makefile.in
+++ b/examples++-chapt3/Makefile.in
@@ -56,7 +56,8 @@ 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)/acmacros.m4 \
-	$(top_srcdir)/acoptim.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/acoptim.m4 $(top_srcdir)/acmpi.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -329,11 +330,47 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EIGENOBJ = @EIGENOBJ@
+ENABLE_FFCS = @ENABLE_FFCS@
 EPSTOPDF = @EPSTOPDF@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+FFCS_COMPILE_fflapack = @FFCS_COMPILE_fflapack@
+FFCS_COMPILE_gsl = @FFCS_COMPILE_gsl@
+FFCS_COMPILE_hips = @FFCS_COMPILE_hips@
+FFCS_COMPILE_hypre = @FFCS_COMPILE_hypre@
+FFCS_COMPILE_ipopt = @FFCS_COMPILE_ipopt@
+FFCS_COMPILE_lapack = @FFCS_COMPILE_lapack@
+FFCS_COMPILE_mmg3d = @FFCS_COMPILE_mmg3d@
+FFCS_COMPILE_mshmet = @FFCS_COMPILE_mshmet@
+FFCS_COMPILE_mumps = @FFCS_COMPILE_mumps@
+FFCS_COMPILE_mumps_seq = @FFCS_COMPILE_mumps_seq@
+FFCS_COMPILE_pardiso = @FFCS_COMPILE_pardiso@
+FFCS_COMPILE_parms = @FFCS_COMPILE_parms@
+FFCS_COMPILE_pastix = @FFCS_COMPILE_pastix@
+FFCS_COMPILE_pipe = @FFCS_COMPILE_pipe@
+FFCS_COMPILE_scotch = @FFCS_COMPILE_scotch@
+FFCS_COMPILE_superludist = @FFCS_COMPILE_superludist@
+FFCS_COMPILE_yams = @FFCS_COMPILE_yams@
+FFCS_DYLIB_fflapack = @FFCS_DYLIB_fflapack@
+FFCS_DYLIB_gsl = @FFCS_DYLIB_gsl@
+FFCS_DYLIB_hips = @FFCS_DYLIB_hips@
+FFCS_DYLIB_hypre = @FFCS_DYLIB_hypre@
+FFCS_DYLIB_ipopt = @FFCS_DYLIB_ipopt@
+FFCS_DYLIB_lapack = @FFCS_DYLIB_lapack@
+FFCS_DYLIB_mmg3d = @FFCS_DYLIB_mmg3d@
+FFCS_DYLIB_mshmet = @FFCS_DYLIB_mshmet@
+FFCS_DYLIB_mumps = @FFCS_DYLIB_mumps@
+FFCS_DYLIB_mumps_seq = @FFCS_DYLIB_mumps_seq@
+FFCS_DYLIB_pardiso = @FFCS_DYLIB_pardiso@
+FFCS_DYLIB_parms = @FFCS_DYLIB_parms@
+FFCS_DYLIB_pastix = @FFCS_DYLIB_pastix@
+FFCS_DYLIB_pipe = @FFCS_DYLIB_pipe@
+FFCS_DYLIB_scotch = @FFCS_DYLIB_scotch@
+FFCS_DYLIB_superludist = @FFCS_DYLIB_superludist@
+FFCS_DYLIB_yams = @FFCS_DYLIB_yams@
+FFCS_MAKEFLAGS = @FFCS_MAKEFLAGS@
 FFGLUTNAME = @FFGLUTNAME@
 FFGLUTPROG = @FFGLUTPROG@
 FFLAGS = @FFLAGS@
@@ -501,6 +538,8 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 TESTS = BlackScholes2D.edp NSNewton.edp NSprojection.edp condensor.edp convects.edp heatex.edp lame.edp membrane.edp membranerror.edp muwave.edp optimcontrol.edp potential.edp schwarz.edp sound.edp stokes.edp test1.edp testbed.edp thermal.edp thermic.edp
+# if .. no arpack ... 
+XFAIL_TESTS = sound.edp
 EXTRA_DIST = *.edp  all.edp regtests.edp regtests.m4 ref.edp
 LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-ff
 TESTS_ENVIRONMENT = TEST_FFPP=$(TEST_FFPP) FLAGS_FFPP=-nw
@@ -983,7 +1022,7 @@ uninstall-am:
 	uninstall uninstall-am
 
 
-all-local: all.edp regtests.edp
+all-local: all.edp regtests.edp freefem++.pref
 
 all.edp:
 	(echo "NoUseOfWait=true;int verbosityy=verbosity;"; \
@@ -1004,6 +1043,10 @@ makeref.edp: regtests.m4 ../regtests.m4
 # To check the scripts against their reference values
 regtests.edp: regtests.m4 ../regtests.m4
 	m4 -DASSERT regtests.m4 > regtests.edp
+freefem++.pref:
+	echo loadpath = \"../examples++-load/\" >freefem++.pref
+	echo loadpath += \"./\" >>freefem++.pref
+
 FORCE:
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/examples++-chapt3/condensor.edp b/examples++-chapt3/condensor.edp
index 2fef992..12c316a 100755
--- a/examples++-chapt3/condensor.edp
+++ b/examples++-chapt3/condensor.edp
@@ -1,34 +1,34 @@
-// file condensor.edp
-
-int C1=99, C2=98; // could be anything
-border C0(t=0,2*pi){x=5*cos(t); y=5*sin(t);}
-
-border C11(t=0,1){ x=1+t;  y=3;      label=C1;}
-border C12(t=0,1){ x=2;    y=3-6*t;  label=C1;}
-border C13(t=0,1){ x=2-t;  y=-3;     label=C1;}
-border C14(t=0,1){ x=1;    y=-3+6*t; label=C1;}
-
-border C21(t=0,1){ x=-2+t; y=3;      label=C2;}
-border C22(t=0,1){ x=-1;   y=3-6*t;  label=C2;}
-border C23(t=0,1){ x=-1-t; y=-3;     label=C2;}
-border C24(t=1,0){ x=-2;   y=-3+6*t; label=C2;}
-
-mesh Th=buildmesh(   C0(50)
-                    +C11(5)+C12(20)+C13(5)+C14(20)
-                    +C21(5)+C22(20)+C23(5)+C24(-20));
-plot(Th,wait=1);
-
-fespace Vh(Th,P1); Vh u,v;
-
-solve a(u,v)= int2d(Th)(dx(u)*dx(v)+dy(u)*dy(v))
-                +on(C0,u=0)+on(C1,u=1)+on(C2,u=-1);
-plot(u,value=true, ps="condersor.eps");
-
-// savemesh(Th,"condensor.msh");
-/*
-mesh Sh=readmesh("condensor.msh");
-fespace Vsh(Sh,P1); Vsh us,vs;
-solve b(us,vs)= int2d(Sh)(dx(us)*dx(vs)+dy(us)*dy(vs))
-                +on(1,us=0)+on(99,us=1)+on(98,us=-1);
-plot(us,value=true);
-*/
+// file condensor.edp
+
+int C1=99, C2=98; // could be anything
+border C0(t=0,2*pi){x=5*cos(t); y=5*sin(t);}
+
+border C11(t=0,1){ x=1+t;  y=3;      label=C1;}
+border C12(t=0,1){ x=2;    y=3-6*t;  label=C1;}
+border C13(t=0,1){ x=2-t;  y=-3;     label=C1;}
+border C14(t=0,1){ x=1;    y=-3+6*t; label=C1;}
+
+border C21(t=0,1){ x=-2+t; y=3;      label=C2;}
+border C22(t=0,1){ x=-1;   y=3-6*t;  label=C2;}
+border C23(t=0,1){ x=-1-t; y=-3;     label=C2;}
+border C24(t=1,0){ x=-2;   y=-3+6*t; label=C2;}
+
+mesh Th=buildmesh(   C0(50)
+                    +C11(5)+C12(20)+C13(5)+C14(20)
+                    +C21(5)+C22(20)+C23(5)+C24(-20));
+plot(Th,wait=1);
+
+fespace Vh(Th,P1); Vh u,v;
+
+solve a(u,v)= int2d(Th)(dx(u)*dx(v)+dy(u)*dy(v))
+                +on(C0,u=0)+on(C1,u=1)+on(C2,u=-1);
+plot(u,value=true, ps="condersor.eps");
+
+// savemesh(Th,"condensor.msh");
+/*
+mesh Sh=readmesh("condensor.msh");
+fespace Vsh(Sh,P1); Vsh us,vs;
+solve b(us,vs)= int2d(Sh)(dx(us)*dx(vs)+dy(us)*dy(vs))
+                +on(1,us=0)+on(99,us=1)+on(98,us=-1);
+plot(us,value=true);
+*/
diff --git a/examples++-chapt3/heatex.edp b/examples++-chapt3/heatex.edp
index 27daddf..c6dde77 100755
--- a/examples++-chapt3/heatex.edp
+++ b/examples++-chapt3/heatex.edp
@@ -1,24 +1,24 @@
-// file heatex.edp
-int C1=99, C2=98; // could be anything
-border C0(t=0,2*pi){x=5*cos(t); y=5*sin(t);}
-
-border C11(t=0,1){ x=1+t;  y=3;      label=C1;}
-border C12(t=0,1){ x=2;    y=3-6*t;  label=C1;}
-border C13(t=0,1){ x=2-t;  y=-3;     label=C1;}
-border C14(t=0,1){ x=1;    y=-3+6*t; label=C1;}
-
-border C21(t=0,1){ x=-2+t; y=3;      label=C2;}
-border C22(t=0,1){ x=-1;   y=3-6*t;  label=C2;}
-border C23(t=0,1){ x=-1-t; y=-3;     label=C2;}
-border C24(t=0,1){ x=-2;   y=-3+6*t; label=C2;}
-
-mesh Th=buildmesh(    C0(50)
-                    + C11(5)+C12(20)+C13(5)+C14(20)
-                    + C21(-5)+C22(-20)+C23(-5)+C24(-20));
-plot(Th,wait=1,ps="heatexTh.ps");
-
-fespace Vh(Th,P1); Vh u,v;
-Vh kappa=1+4*(x<-1)*(x>-2)*(y<3)*(y>-3);
-solve a(u,v)= int2d(Th)(kappa*(dx(u)*dx(v)+dy(u)*dy(v)))
-                +on(C0,u=20)+on(C1,u=100);
-plot(u,value=true,wait=1,fill=true);
+// file heatex.edp
+int C1=99, C2=98; // could be anything
+border C0(t=0,2*pi){x=5*cos(t); y=5*sin(t);}
+
+border C11(t=0,1){ x=1+t;  y=3;      label=C1;}
+border C12(t=0,1){ x=2;    y=3-6*t;  label=C1;}
+border C13(t=0,1){ x=2-t;  y=-3;     label=C1;}
+border C14(t=0,1){ x=1;    y=-3+6*t; label=C1;}
+
+border C21(t=0,1){ x=-2+t; y=3;      label=C2;}
+border C22(t=0,1){ x=-1;   y=3-6*t;  label=C2;}
+border C23(t=0,1){ x=-1-t; y=-3;     label=C2;}
+border C24(t=0,1){ x=-2;   y=-3+6*t; label=C2;}
+
+mesh Th=buildmesh(    C0(50)
+                    + C11(5)+C12(20)+C13(5)+C14(20)
+                    + C21(-5)+C22(-20)+C23(-5)+C24(-20));
+plot(Th,wait=1,ps="heatexTh.ps");
+
+fespace Vh(Th,P1); Vh u,v;
+Vh kappa=1+4*(x<-1)*(x>-2)*(y<3)*(y>-3);
+solve a(u,v)= int2d(Th)(kappa*(dx(u)*dx(v)+dy(u)*dy(v)))
+                +on(C0,u=20)+on(C1,u=100);
+plot(u,value=true,wait=1,fill=true);
diff --git a/examples++-chapt3/membrane.edp b/examples++-chapt3/membrane.edp
index e0955ca..16a8f7e 100755
--- a/examples++-chapt3/membrane.edp
+++ b/examples++-chapt3/membrane.edp
@@ -1,28 +1,28 @@
-// file membrane.edp
-real theta=4.*pi/3.;
-real a=2.,b=1.; // the length of the semimajor axis and  semiminor axis
-func z=x;
-
-border Gamma1(t=0,theta)    { x = a * cos(t); y = b*sin(t); }
-border Gamma2(t=theta,2*pi) { x = a * cos(t); y = b*sin(t); }
-mesh Th=buildmesh(Gamma1(100)+Gamma2(50));   // construction of mesh
-
-fespace Vh(Th,P2); // P2 conforming triangular FEM
-Vh phi,w, f=1;
-
-solve Laplace(phi,w)=int2d(Th)(dx(phi)*dx(w) + dy(phi)*dy(w))
-                - int2d(Th)(f*w) + on(Gamma1,phi=z);  // resolution of laplace equation
-plot(phi,wait=true, ps="membrane.eps"); //Plot Th and v
-plot(Th,wait=true, ps="membraneTh.eps"); //Plot Th and v
-
-// to build a gnuplot data file
-{ ofstream ff("graph.txt");
-   for (int i=0;i<Th.nt;i++)
-   { for (int j=0; j <3; j++)
-       ff<<Th[i][j].x  << "    "<< Th[i][j].y<< "  "<<phi[][Vh(i,j)]<<endl;
-    ff<<Th[i][0].x  << "    "<< Th[i][0].y<< "  "<<phi[][Vh(i,0)]<<endl
-      <<endl<<endl;
-   }
-}
-
-savemesh(Th,"Th.msh");
+// file membrane.edp
+real theta=4.*pi/3.;
+real a=2.,b=1.; // the length of the semimajor axis and  semiminor axis
+func z=x;
+
+border Gamma1(t=0,theta)    { x = a * cos(t); y = b*sin(t); }
+border Gamma2(t=theta,2*pi) { x = a * cos(t); y = b*sin(t); }
+mesh Th=buildmesh(Gamma1(100)+Gamma2(50));   // construction of mesh
+
+fespace Vh(Th,P2); // P2 conforming triangular FEM
+Vh phi,w, f=1;
+
+solve Laplace(phi,w)=int2d(Th)(dx(phi)*dx(w) + dy(phi)*dy(w))
+                - int2d(Th)(f*w) + on(Gamma1,phi=z);  // resolution of laplace equation
+plot(phi,wait=true, ps="membrane.eps"); //Plot Th and v
+plot(Th,wait=true, ps="membraneTh.eps"); //Plot Th and v
+
+// to build a gnuplot data file
+{ ofstream ff("graph.txt");
+   for (int i=0;i<Th.nt;i++)
+   { for (int j=0; j <3; j++)
+       ff<<Th[i][j].x  << "    "<< Th[i][j].y<< "  "<<phi[][Vh(i,j)]<<endl;
+    ff<<Th[i][0].x  << "    "<< Th[i][0].y<< "  "<<phi[][Vh(i,0)]<<endl
+      <<endl<<endl;
+   }
+}
+
+savemesh(Th,"Th.msh");
diff --git a/examples++-chapt3/membranerror.edp b/examples++-chapt3/membranerror.edp
index ba3f9be..2bafec4 100755
--- a/examples++-chapt3/membranerror.edp
+++ b/examples++-chapt3/membranerror.edp
@@ -1,29 +1,29 @@
-// file membranerror.edp
-verbosity=0;
-
-real theta=4.*pi/3.;
-real a=1.,b=1.; // the length of the semimajor axis and  semiminor axis
-border Gamma1(t=0,theta)    { x = a * cos(t); y = b*sin(t); }
-border Gamma2(t=theta,2*pi) { x = a * cos(t); y = b*sin(t); }
-
-
-func f=-4*(cos(x^2+y^2-1) -(x^2+y^2)*sin(x^2+y^2-1));
-func phiexact=sin(x^2+y^2-1);
-
-real[int] L2error(2);
-for(int n=0;n<2;n++)
-{
-  mesh Th=buildmesh(Gamma1(40*(n+1))+Gamma2(20*(n+1)));
-  fespace Vh(Th,P2); 
-   Vh phi,w;
-  
-  solve laplace(phi,w)=int2d(Th)(dx(phi)*dx(w) + dy(phi)*dy(w))
-    - int2d(Th)(f*w) - int1d(Th,Gamma2)(2*w)+ on(Gamma1,phi=0);
-  plot(Th,phi,wait=true,ps="membrane.eps"); //Plot Th and phi
-  
-  L2error[n]= sqrt(int2d(Th)((phi-phiexact)^2));
-}  
-for(int n=0;n<2;n++)
-  cout << " L2error " << n << " = "<<  L2error[n] <<endl;
-  
-cout <<" convergence rate = "<< log(L2error[0]/L2error[1])/log(2.)  <<endl;
+// file membranerror.edp
+verbosity=0;
+
+real theta=4.*pi/3.;
+real a=1.,b=1.; // the length of the semimajor axis and  semiminor axis
+border Gamma1(t=0,theta)    { x = a * cos(t); y = b*sin(t); }
+border Gamma2(t=theta,2*pi) { x = a * cos(t); y = b*sin(t); }
+
+
+func f=-4*(cos(x^2+y^2-1) -(x^2+y^2)*sin(x^2+y^2-1));
+func phiexact=sin(x^2+y^2-1);
+
+real[int] L2error(2);
+for(int n=0;n<2;n++)
+{
+  mesh Th=buildmesh(Gamma1(40*(n+1))+Gamma2(20*(n+1)));
+  fespace Vh(Th,P2); 
+   Vh phi,w;
+  
+  solve laplace(phi,w)=int2d(Th)(dx(phi)*dx(w) + dy(phi)*dy(w))
+    - int2d(Th)(f*w) - int1d(Th,Gamma2)(2*w)+ on(Gamma1,phi=0);
+  plot(Th,phi,wait=true,ps="membrane.eps"); //Plot Th and phi
+  
+  L2error[n]= sqrt(int2d(Th)((phi-phiexact)^2));
+}  
+for(int n=0;n<2;n++)
+  cout << " L2error " << n << " = "<<  L2error[n] <<endl;
+  
+cout <<" convergence rate = "<< log(L2error[0]/L2error[1])/log(2.)  <<endl;
diff --git a/examples++-chapt3/muwave.edp b/examples++-chapt3/muwave.edp
index fa6c493..6e604ad 100755
--- a/examples++-chapt3/muwave.edp
+++ b/examples++-chapt3/muwave.edp
@@ -1,34 +1,34 @@
-// file muwave.edp
-real a=20, b=20, c=15, d=8, e=2, l=12, f=2, g=2;
-border a0(t=0,1) {x=a*t; y=0;label=1;}
-border a1(t=1,2) {x=a; y= b*(t-1);label=1;}
-border a2(t=2,3) { x=a*(3-t);y=b;label=1;}
-border a3(t=3,4){x=0;y=b-(b-c)*(t-3);label=1;}
-border a4(t=4,5){x=0;y=c-(c-d)*(t-4);label=2;}
-border a5(t=5,6){ x=0; y= d*(6-t);label=1;}
-
-border b0(t=0,1) {x=a-f+e*(t-1);y=g; label=3;}
-border b1(t=1,4) {x=a-f; y=g+l*(t-1)/3; label=3;}
-border b2(t=4,5) {x=a-f-e*(t-4); y=l+g; label=3;}
-border b3(t=5,8) {x=a-e-f; y= l+g-l*(t-5)/3; label=3;}
-int n=2;
-mesh Th = buildmesh(a0(10*n)+a1(10*n)+a2(10*n)+a3(10*n)
-        +a4(10*n)+a5(10*n)+b0(5*n)+b1(10*n)+b2(5*n)+b3(10*n));
-plot(Th,wait=1);
-fespace Vh(Th,P1);
-real meat =  Th(a-f-e/2,g+l/2).region, air= Th(0.01,0.01).region;
-Vh R=(region-air)/(meat-air);
-
-Vh<complex> v,w;
-solve muwave(v,w) = int2d(Th)(v*w*(1+R)
-                -(dx(v)*dx(w)+dy(v)*dy(w))*(1-0.5i))
-   + on(1,v=0) + on(2, v=sin(pi*(y-c)/(c-d)));
-Vh vr=real(v), vi=imag(v);
-plot(vr,wait=1,ps="rmuonde.ps", fill=true);
-plot(vi,wait=1,ps="imuonde.ps", fill=true);
-
-fespace Uh(Th,P1); Uh u,uu, ff=1e5*(vr^2 + vi^2)*R;
-
-solve temperature(u,uu)= int2d(Th)(dx(u)* dx(uu)+ dy(u)* dy(uu))
-     - int2d(Th)(ff*uu) + on(1,2,u=0);
-plot(u,wait=1,ps="tempmuonde.ps", fill=true);
+// file muwave.edp
+real a=20, b=20, c=15, d=8, e=2, l=12, f=2, g=2;
+border a0(t=0,1) {x=a*t; y=0;label=1;}
+border a1(t=1,2) {x=a; y= b*(t-1);label=1;}
+border a2(t=2,3) { x=a*(3-t);y=b;label=1;}
+border a3(t=3,4){x=0;y=b-(b-c)*(t-3);label=1;}
+border a4(t=4,5){x=0;y=c-(c-d)*(t-4);label=2;}
+border a5(t=5,6){ x=0; y= d*(6-t);label=1;}
+
+border b0(t=0,1) {x=a-f+e*(t-1);y=g; label=3;}
+border b1(t=1,4) {x=a-f; y=g+l*(t-1)/3; label=3;}
+border b2(t=4,5) {x=a-f-e*(t-4); y=l+g; label=3;}
+border b3(t=5,8) {x=a-e-f; y= l+g-l*(t-5)/3; label=3;}
+int n=2;
+mesh Th = buildmesh(a0(10*n)+a1(10*n)+a2(10*n)+a3(10*n)
+        +a4(10*n)+a5(10*n)+b0(5*n)+b1(10*n)+b2(5*n)+b3(10*n));
+plot(Th,wait=1);
+fespace Vh(Th,P1);
+real meat =  Th(a-f-e/2,g+l/2).region, air= Th(0.01,0.01).region;
+Vh R=(region-air)/(meat-air);
+
+Vh<complex> v,w;
+solve muwave(v,w) = int2d(Th)(v*w*(1+R)
+                -(dx(v)*dx(w)+dy(v)*dy(w))*(1-0.5i))
+   + on(1,v=0) + on(2, v=sin(pi*(y-c)/(c-d)));
+Vh vr=real(v), vi=imag(v);
+plot(vr,wait=1,ps="rmuonde.ps", fill=true);
+plot(vi,wait=1,ps="imuonde.ps", fill=true);
+
+fespace Uh(Th,P1); Uh u,uu, ff=1e5*(vr^2 + vi^2)*R;
+
+solve temperature(u,uu)= int2d(Th)(dx(u)* dx(uu)+ dy(u)* dy(uu))
+     - int2d(Th)(ff*uu) + on(1,2,u=0);
+plot(u,wait=1,ps="tempmuonde.ps", fill=true);
diff --git a/examples++-chapt3/potential.edp b/examples++-chapt3/potential.edp
index 88e2051..3ff5077 100755
--- a/examples++-chapt3/potential.edp
+++ b/examples++-chapt3/potential.edp
@@ -1,32 +1,32 @@
-// file potential.edp
-
-real S=99;
-border C(t=0,2*pi) {  x=3*cos(t);  y=3*sin(t);}
-border Splus(t=0,1){  x = t; y = 0.17735*sqrt(t)-0.075597*t
-        - 0.212836*(t^2)+0.17363*(t^3)-0.06254*(t^4); label=S;}
-border Sminus(t=1,0){  x =t; y= -(0.17735*sqrt(t)-0.075597*t
-        -0.212836*(t^2)+0.17363*(t^3)-0.06254*(t^4)); label=S;}
-mesh Th= buildmesh(C(50)+Splus(70)+Sminus(70));
-fespace Vh(Th,P2); Vh psi,w;
-
-solve potential(psi,w)=int2d(Th)(dx(psi)*dx(w)+dy(psi)*dy(w))+
-  on(C,psi = y)+ on(S,psi=0);
-
-plot(psi,wait=1);
-border D(t=0,2){x=1+t;y=0;}
-mesh Sh = buildmesh(C(25)+Splus(-90)+Sminus(-90)+D(200));
-fespace Wh(Sh,P1); Wh v,vv;
-int steel=Sh(0.5,0).region, air=Sh(-1,0).region;
-fespace W0(Sh,P0);
-W0 k=0.01*(region==air)+0.1*(region==steel);
-W0 u1=dy(psi)*(region==air), u2=-dx(psi)*(region==air);
-Wh vold = 120*(region==steel);
-real dt=0.05, nbT=50;
-int i;
-problem thermic(v,vv,init=i,solver=LU)= int2d(Sh)(v*vv/dt + k*(dx(v) * dx(vv) + dy(v) * dy(vv))
-                + 10*(u1*dx(v)+u2*dy(v))*vv)- int2d(Sh)(vold*vv/dt);
-for(i=0;i<nbT;i++){
-    v=vold; thermic;
- plot(v);
-}
-plot(v,wait=1);
+// file potential.edp
+
+real S=99;
+border C(t=0,2*pi) {  x=3*cos(t);  y=3*sin(t);}
+border Splus(t=0,1){  x = t; y = 0.17735*sqrt(t)-0.075597*t
+        - 0.212836*(t^2)+0.17363*(t^3)-0.06254*(t^4); label=S;}
+border Sminus(t=1,0){  x =t; y= -(0.17735*sqrt(t)-0.075597*t
+        -0.212836*(t^2)+0.17363*(t^3)-0.06254*(t^4)); label=S;}
+mesh Th= buildmesh(C(50)+Splus(70)+Sminus(70));
+fespace Vh(Th,P2); Vh psi,w;
+
+solve potential(psi,w)=int2d(Th)(dx(psi)*dx(w)+dy(psi)*dy(w))+
+  on(C,psi = y)+ on(S,psi=0);
+
+plot(psi,wait=1);
+border D(t=0,2){x=1+t;y=0;}
+mesh Sh = buildmesh(C(25)+Splus(-90)+Sminus(-90)+D(200));
+fespace Wh(Sh,P1); Wh v,vv;
+int steel=Sh(0.5,0).region, air=Sh(-1,0).region;
+fespace W0(Sh,P0);
+W0 k=0.01*(region==air)+0.1*(region==steel);
+W0 u1=dy(psi)*(region==air), u2=-dx(psi)*(region==air);
+Wh vold = 120*(region==steel);
+real dt=0.05, nbT=50;
+int i;
+problem thermic(v,vv,init=i,solver=LU)= int2d(Sh)(v*vv/dt + k*(dx(v) * dx(vv) + dy(v) * dy(vv))
+                + 10*(u1*dx(v)+u2*dy(v))*vv)- int2d(Sh)(vold*vv/dt);
+for(i=0;i<nbT;i++){
+    v=vold; thermic;
+ plot(v);
+}
+plot(v,wait=1);
diff --git a/examples++-chapt3/schwarz.edp b/examples++-chapt3/schwarz.edp
index b49eef2..6463609 100755
--- a/examples++-chapt3/schwarz.edp
+++ b/examples++-chapt3/schwarz.edp
@@ -1,26 +1,26 @@
-//  Tutorial file schwarz.edp: Schwarz Algorithm
-border a(t=0,1){x=t;y=0;} // This is a rectangle
-border a1(t=1,2){x=t;y=0;}
-border b(t=0,1){x=2;y=t;}
-border c(t=2,0){x=t ;y=1;}
-border d(t=1,0){x = 0; y = t;} // next is a circle
-border e(t=0, pi/2){ x= cos(t); y = sin(t);}
-border e1(t=pi/2, 2*pi){ x= cos(t); y = sin(t);}
-real n=4;
-
-//Omega1
-mesh th = buildmesh( a(5*n) + a1(5*n) + b(5*n) + c(10*n) + d(5*n));
-fespace Vh(th,P1); Vh v,u=0;
-
-//Omega2
-mesh TH = buildmesh ( e(5*n) + e1(25*n) );
-fespace VH(TH,P1); VH V,U = 0;
-
-for( int i=0; i< 4; i++) {
-    plot(U,u, wait=1);
-    solve AA(U,V)= int2d(TH)(dx(U)* dx(V)+ dy(U)* dy(V))
-                 - int2d(TH)(V) + on(e,U=u)+ on(e1,U=0);
-    solve aa(u,v)= int2d(th)(dx(u)*dx(v)+ dy(u)* dy(v))
-                - int2d(th)(v) + on(a,d,u=U) + on(a1,b,c,u=0);
-}
-plot(U,u, wait=1);
+//  Tutorial file schwarz.edp: Schwarz Algorithm
+border a(t=0,1){x=t;y=0;} // This is a rectangle
+border a1(t=1,2){x=t;y=0;}
+border b(t=0,1){x=2;y=t;}
+border c(t=2,0){x=t ;y=1;}
+border d(t=1,0){x = 0; y = t;} // next is a circle
+border e(t=0, pi/2){ x= cos(t); y = sin(t);}
+border e1(t=pi/2, 2*pi){ x= cos(t); y = sin(t);}
+real n=4;
+
+//Omega1
+mesh th = buildmesh( a(5*n) + a1(5*n) + b(5*n) + c(10*n) + d(5*n));
+fespace Vh(th,P1); Vh v,u=0;
+
+//Omega2
+mesh TH = buildmesh ( e(5*n) + e1(25*n) );
+fespace VH(TH,P1); VH V,U = 0;
+
+for( int i=0; i< 4; i++) {
+    plot(U,u, wait=1);
+    solve AA(U,V)= int2d(TH)(dx(U)* dx(V)+ dy(U)* dy(V))
+                 - int2d(TH)(V) + on(e,U=u)+ on(e1,U=0);
+    solve aa(u,v)= int2d(th)(dx(u)*dx(v)+ dy(u)* dy(v))
+                - int2d(th)(v) + on(a,d,u=U) + on(a1,b,c,u=0);
+}
+plot(U,u, wait=1);
diff --git a/examples++-chapt3/sound.edp b/examples++-chapt3/sound.edp
index 5f768df..5d9022e 100755
--- a/examples++-chapt3/sound.edp
+++ b/examples++-chapt3/sound.edp
@@ -1,45 +1,45 @@
-real kc2=1; // try this value 19.4256;
-func g=y*(1-y);
-
-border a0(t=0,1) { x= 5; y= 1+2*t ;}
-border a1(t=0,1) { x=5-2*t; y= 3 ;}
-border a2(t=0,1) { x= 3-2*t; y=3-2*t ;}
-border a3(t=0,1) { x= 1-t; y= 1 ;}
-border a4(t=0,1) { x= 0; y= 1-t ;}
-border a5(t=0,1) { x= t; y= 0  ;}
-border a6(t=0,1) { x= 1+4*t; y= t ;}
-
-mesh Th=buildmesh( a0(20) + a1(20) + a2(20)
-        + a3(20) + a4(20) + a5(20) + a6(20));
-fespace Vh(Th,P1);  Vh u,v;
-
-solve sound(u,v)=int2d(Th)(u*v * kc2 - dx(u)*dx(v) - dy(u)*dy(v))
-                 - int1d(Th,a4)(g*v);
-plot(u, wait=1, ps="sound0.eps");
-
-Vh u1,u2;
-
-
-real sigma = 20;  // value of the shift
-
-// OP = A - sigma B ;  //  the shifted matrix
-varf  op(u1,u2)= int2d(Th)(  dx(u1)*dx(u2) + dy(u1)*dy(u2) - sigma* u1*u2 )
- ;//                   +  on(1,2,3,4,u1=0) ;  // Boundary condition
-
-varf b([u1],[u2]) = int2d(Th)(  u1*u2 ) ; // no  Boundary condition
-
-matrix OP= op(Vh,Vh,solver=Crout,factorize=1);  // crout solver because the matrix in not positive
-matrix B= b(Vh,Vh,solver=CG,eps=1e-20);
-
-
-int nev=2;  // number of computed eigen value close to sigma
-
-real[int] ev(nev); // to store the  nev eigenvalue
-Vh[int] eV(nev);   // to store the nev eigenvector \index{EigenValue}
-
-
-int k=EigenValue(OP,B,sym=true,sigma=sigma,value=ev,vector=eV,
-                   tol=1e-10,maxit=0,ncv=0);
-cout<<ev(0)<<" 2 eigen values "<<ev(1)<<endl;
-v=eV[0];
-plot(v,wait=1,ps="eigen.eps");
+real kc2=1; // try this value 19.4256;
+func g=y*(1-y);
+
+border a0(t=0,1) { x= 5; y= 1+2*t ;}
+border a1(t=0,1) { x=5-2*t; y= 3 ;}
+border a2(t=0,1) { x= 3-2*t; y=3-2*t ;}
+border a3(t=0,1) { x= 1-t; y= 1 ;}
+border a4(t=0,1) { x= 0; y= 1-t ;}
+border a5(t=0,1) { x= t; y= 0  ;}
+border a6(t=0,1) { x= 1+4*t; y= t ;}
+
+mesh Th=buildmesh( a0(20) + a1(20) + a2(20)
+        + a3(20) + a4(20) + a5(20) + a6(20));
+fespace Vh(Th,P1);  Vh u,v;
+
+solve sound(u,v)=int2d(Th)(u*v * kc2 - dx(u)*dx(v) - dy(u)*dy(v))
+                 - int1d(Th,a4)(g*v);
+plot(u, wait=1, ps="sound0.eps");
+
+Vh u1,u2;
+
+
+real sigma = 20;  // value of the shift
+
+// OP = A - sigma B ;  //  the shifted matrix
+varf  op(u1,u2)= int2d(Th)(  dx(u1)*dx(u2) + dy(u1)*dy(u2) - sigma* u1*u2 )
+ ;//                   +  on(1,2,3,4,u1=0) ;  // Boundary condition
+
+varf b([u1],[u2]) = int2d(Th)(  u1*u2 ) ; // no  Boundary condition
+
+matrix OP= op(Vh,Vh,solver=Crout,factorize=1);  // crout solver because the matrix in not positive
+matrix B= b(Vh,Vh,solver=CG,eps=1e-20);
+
+
+int nev=2;  // number of computed eigen value close to sigma
+
+real[int] ev(nev); // to store the  nev eigenvalue
+Vh[int] eV(nev);   // to store the nev eigenvector \index{EigenValue}
+
+
+int k=EigenValue(OP,B,sym=true,sigma=sigma,value=ev,vector=eV,
+                   tol=1e-10,maxit=0,ncv=0);
+cout<<ev(0)<<" 2 eigen values "<<ev(1)<<endl;
+v=eV[0];
+plot(v,wait=1,ps="eigen.eps");
diff --git a/examples++-chapt3/stokes.edp b/examples++-chapt3/stokes.edp
index 23898f3..9acaa75 100755
--- a/examples++-chapt3/stokes.edp
+++ b/examples++-chapt3/stokes.edp
@@ -1,12 +1,12 @@
-//file Stokes.edp
-int n=3;
-mesh Th=square(10*n,10*n);
-fespace Uh(Th,P1b); Uh u,v,uu,vv;
-fespace Ph(Th,P1);  Ph p,pp;
-
-solve stokes([u,v,p],[uu,vv,pp]) =
-    int2d(Th)(dx(u)*dx(uu)+dy(u)*dy(uu) + dx(v)*dx(vv)+ dy(v)*dy(vv)
+//file Stokes.edp
+int n=3;
+mesh Th=square(10*n,10*n);
+fespace Uh(Th,P1b); Uh u,v,uu,vv;
+fespace Ph(Th,P1);  Ph p,pp;
+
+solve stokes([u,v,p],[uu,vv,pp]) =
+    int2d(Th)(dx(u)*dx(uu)+dy(u)*dy(uu) + dx(v)*dx(vv)+ dy(v)*dy(vv)
             + dx(p)*uu + dy(p)*vv + pp*(dx(u)+dy(v))
-            -1e-10*p*pp)            
-            + on(1,2,4,u=0,v=0) + on(3,u=1,v=0);
-plot([u,v],p,wait=1);
+            -1e-10*p*pp)            
+            + on(1,2,4,u=0,v=0) + on(3,u=1,v=0);
+plot([u,v],p,wait=1);
diff --git a/examples++-chapt3/test1.edp b/examples++-chapt3/test1.edp
index fcc71e1..511de23 100755
--- a/examples++-chapt3/test1.edp
+++ b/examples++-chapt3/test1.edp
@@ -1,28 +1,28 @@
-//Tutorial file test1.pde
-// YOUR FIRST PROGRAM
-
-border C(t=0,2*pi){x=cos(t); y=sin(t);}                    // the boundary
-mesh Th = buildmesh (C(50));                // of the domain and its mesh
-fespace Vh(Th,P1);      // Finite Element of degree 2 defined here for Vh
- Vh u,v;            // defines u and v as piecewise-P2 continuous functions
- func f= x*y;                       // definition of an algebraic function
- real cpu = clock();
- solve Poisson(u,v,solver=LU) =               // defines and solves the PDE
-    int2d(Th)( dx(u)*dx(v) + dy(u)*dy(v))               //  bilinear part
-    - int2d(Th)( f*v)                                   // right hand side
-    + on(C,u=0)  ;                          // Dirichlet boundary condition
-
-  plot(u,wait=1);
- cout << " CPU time = " << clock()-cpu << endl;
-
-// ENDS HERE
-
-// FOR THE PRO: The same done with total control over the algebra
-varf a(u,v) = int2d(Th)( dx(u)*dx(v) + dy(u)*dy(v))+ on(C,u=0) ;
-matrix A=a(Vh,Vh);  // stiffness matrix, see (\ref{eqn:Stiffness0})
-varf b(u,v) = int2d(Th)( u*v ) ;
-matrix B=b(Vh,Vh);
-Vh F=f;
-v[] = B*F[];
-u[]=A^-1*v[];
-plot(u,wait=1);
+//Tutorial file test1.pde
+// YOUR FIRST PROGRAM
+
+border C(t=0,2*pi){x=cos(t); y=sin(t);}                    // the boundary
+mesh Th = buildmesh (C(50));                // of the domain and its mesh
+fespace Vh(Th,P1);      // Finite Element of degree 2 defined here for Vh
+ Vh u,v;            // defines u and v as piecewise-P2 continuous functions
+ func f= x*y;                       // definition of an algebraic function
+ real cpu = clock();
+ solve Poisson(u,v,solver=LU) =               // defines and solves the PDE
+    int2d(Th)( dx(u)*dx(v) + dy(u)*dy(v))               //  bilinear part
+    - int2d(Th)( f*v)                                   // right hand side
+    + on(C,u=0)  ;                          // Dirichlet boundary condition
+
+  plot(u,wait=1);
+ cout << " CPU time = " << clock()-cpu << endl;
+
+// ENDS HERE
+
+// FOR THE PRO: The same done with total control over the algebra
+varf a(u,v) = int2d(Th)( dx(u)*dx(v) + dy(u)*dy(v))+ on(C,u=0) ;
+matrix A=a(Vh,Vh);  // stiffness matrix, see (\ref{eqn:Stiffness0})
+varf b(u,v) = int2d(Th)( u*v ) ;
+matrix B=b(Vh,Vh);
+Vh F=f;
+v[] = B*F[];
+u[]=A^-1*v[];
+plot(u,wait=1);
diff --git a/examples++-chapt3/testbed.edp b/examples++-chapt3/testbed.edp
index 43f27e4..7ccf588 100755
--- a/examples++-chapt3/testbed.edp
+++ b/examples++-chapt3/testbed.edp
@@ -1,19 +1,19 @@
-cout << " "<< endl;
-/*  Ne compile pas FH ?? 
-for (idt = 1; idt < 50; idt++)
- {
-   temps += dt;
-   cout << " --------- temps " << temps << " \n ";
-   b1[] =  vfconv1(0,Xh);
-   b2[] =  vfconv2(0,Xh);
-   cout << "  min b1 b2  " << b1[].min << " " << b2[].min << endl;
-   cout << "  max b1 b2  " << b1[].max << " " << b2[].max << endl;
-   // call Conjugate Gradient with preconditioner '
-   //  warning eps < 0 => absolue stop test \index{precon=}
-   LinearCG(divup,p[],eps=-1.e-6,nbiter=50,precon=CahouetChabart);
-   divup(p[]);   //  computed the velocity
-
-   plot([u1,u2],p,wait=!(idt%10),value= 1,coef=0.1);
- }
- 
+cout << " "<< endl;
+/*  Ne compile pas FH ?? 
+for (idt = 1; idt < 50; idt++)
+ {
+   temps += dt;
+   cout << " --------- temps " << temps << " \n ";
+   b1[] =  vfconv1(0,Xh);
+   b2[] =  vfconv2(0,Xh);
+   cout << "  min b1 b2  " << b1[].min << " " << b2[].min << endl;
+   cout << "  max b1 b2  " << b1[].max << " " << b2[].max << endl;
+   // call Conjugate Gradient with preconditioner '
+   //  warning eps < 0 => absolue stop test \index{precon=}
+   LinearCG(divup,p[],eps=-1.e-6,nbiter=50,precon=CahouetChabart);
+   divup(p[]);   //  computed the velocity
+
+   plot([u1,u2],p,wait=!(idt%10),value= 1,coef=0.1);
+ }
+ 
 */
\ No newline at end of file
diff --git a/examples++-chapt3/thermal.edp b/examples++-chapt3/thermal.edp
index f4f9547..1453983 100755
--- a/examples++-chapt3/thermal.edp
+++ b/examples++-chapt3/thermal.edp
@@ -1,24 +1,24 @@
-// file heatex.edp
-int C1=99, C2=98; // could be anything
-border C0(t=0,2*pi){x=5*cos(t); y=5*sin(t);}
-
-border C11(t=0,1){ x=1+t;  y=3;      label=C1;}
-border C12(t=0,1){ x=2;    y=3-6*t;  label=C1;}
-border C13(t=0,1){ x=2-t;  y=-3;     label=C1;}
-border C14(t=0,1){ x=1;    y=-3+6*t; label=C1;}
-
-border C21(t=0,1){ x=-2+t; y=3;      label=C2;}
-border C22(t=0,1){ x=-1;   y=3-6*t;  label=C2;}
-border C23(t=0,1){ x=-1-t; y=-3;     label=C2;}
-border C24(t=0,1){ x=-2;   y=-3+6*t; label=C2;}
-
-mesh Th=buildmesh(    C0(50)
-                    + C11(5)+C12(20)+C13(5)+C14(20)
-                    + C21(-5)+C22(-20)+C23(-5)+C24(-20));
-plot(Th,wait=1);
-
-fespace Vh(Th,P1); Vh u,v;
-Vh kappa=1+4*(x<-1)*(x>-2)*(y<3)*(y>-3);
-solve a(u,v)= int2d(Th)(kappa*(dx(u)*dx(v)+dy(u)*dy(v)))
-                +on(C0,u=20)+on(C1,u=100);
-plot(u,value=true,wait=1,fill=true);
+// file heatex.edp
+int C1=99, C2=98; // could be anything
+border C0(t=0,2*pi){x=5*cos(t); y=5*sin(t);}
+
+border C11(t=0,1){ x=1+t;  y=3;      label=C1;}
+border C12(t=0,1){ x=2;    y=3-6*t;  label=C1;}
+border C13(t=0,1){ x=2-t;  y=-3;     label=C1;}
+border C14(t=0,1){ x=1;    y=-3+6*t; label=C1;}
+
+border C21(t=0,1){ x=-2+t; y=3;      label=C2;}
+border C22(t=0,1){ x=-1;   y=3-6*t;  label=C2;}
+border C23(t=0,1){ x=-1-t; y=-3;     label=C2;}
+border C24(t=0,1){ x=-2;   y=-3+6*t; label=C2;}
+
+mesh Th=buildmesh(    C0(50)
+                    + C11(5)+C12(20)+C13(5)+C14(20)
+                    + C21(-5)+C22(-20)+C23(-5)+C24(-20));
+plot(Th,wait=1);
+
+fespace Vh(Th,P1); Vh u,v;
+Vh kappa=1+4*(x<-1)*(x>-2)*(y<3)*(y>-3);
+solve a(u,v)= int2d(Th)(kappa*(dx(u)*dx(v)+dy(u)*dy(v)))
+                +on(C0,u=20)+on(C1,u=100);
+plot(u,value=true,wait=1,fill=true);
diff --git a/examples++-chapt3/thermic.edp b/examples++-chapt3/thermic.edp
index 7987b44..7e46694 100755
--- a/examples++-chapt3/thermic.edp
+++ b/examples++-chapt3/thermic.edp
@@ -1,44 +1,44 @@
-// file thermal.edp
-
-func u0 =10+90*x/6;
-func k = 1.8*(y<0.5)+0.2;
-real ue = 25, alpha=0.25, T=5, dt=0.1 ;
-
-mesh Th=square(30,5,[6*x,y]);
-fespace Vh(Th,P1);
-/*
-Vh u=u0,v,uold;
-// for the flat plate
-problem thermic(u,v)= int2d(Th)(u*v/dt + k*(dx(u) * dx(v) + dy(u) * dy(v)))
-                + int1d(Th,1,3)(alpha*u*v)
-                - int1d(Th,1,3)(alpha*ue*v)
-                - int2d(Th)(uold*v/dt) + on(2,4,u=u0);
-// for the rod
-problem thermaxi(u,v)=int2d(Th)((u*v/dt + dx(u)*dx(v) + dy(u)*dy(v))*x)
-                + int1d(Th,3)(alpha*x*u*v) - int1d(Th,3)(alpha*x*ue*v)
-                - int2d(Th)(uold*v*x/dt) + on(2,4,u=u0);
-ofstream ff("thermic.dat");
-for(real t=0;t<T;t+=dt){
-    uold=u;
-    // thermaxi; thermic; // choose one of the two
-    ff<<t<<" "<<u(3,0.5)<<endl;
-    plot(u);
-}
-for(int i=0;i<20;i++) cout<<dy(u)(6.0*i/20.0,0.9)<<endl;
-plot(u,fill=true,wait=true,ps="thermic.eps");
-*/
-real rad=1e-8, uek=ue+273;
-Vh vold,w,v=u0-ue,b;
-problem thermradia(v,w)
-    = int2d(Th)(v*w/dt + k*(dx(v) * dx(w) + dy(v) * dy(w)))
-                + int1d(Th,1,3)(b*v*w)
-                - int2d(Th)(vold*w/dt) + on(2,4,v=u0-ue);
-
-for(real t=0;t<T;t+=dt){
-    vold=v;
-    for(int m=0;m<5;m++){
-       b= alpha + rad * (v + 2*uek) * ((v+uek)^2 + uek^2);
-       thermradia;
-    }
-}
-vold=v+ue; plot(vold);
+// file thermal.edp
+
+func u0 =10+90*x/6;
+func k = 1.8*(y<0.5)+0.2;
+real ue = 25, alpha=0.25, T=5, dt=0.1 ;
+
+mesh Th=square(30,5,[6*x,y]);
+fespace Vh(Th,P1);
+/*
+Vh u=u0,v,uold;
+// for the flat plate
+problem thermic(u,v)= int2d(Th)(u*v/dt + k*(dx(u) * dx(v) + dy(u) * dy(v)))
+                + int1d(Th,1,3)(alpha*u*v)
+                - int1d(Th,1,3)(alpha*ue*v)
+                - int2d(Th)(uold*v/dt) + on(2,4,u=u0);
+// for the rod
+problem thermaxi(u,v)=int2d(Th)((u*v/dt + dx(u)*dx(v) + dy(u)*dy(v))*x)
+                + int1d(Th,3)(alpha*x*u*v) - int1d(Th,3)(alpha*x*ue*v)
+                - int2d(Th)(uold*v*x/dt) + on(2,4,u=u0);
+ofstream ff("thermic.dat");
+for(real t=0;t<T;t+=dt){
+    uold=u;
+    // thermaxi; thermic; // choose one of the two
+    ff<<t<<" "<<u(3,0.5)<<endl;
+    plot(u);
+}
+for(int i=0;i<20;i++) cout<<dy(u)(6.0*i/20.0,0.9)<<endl;
+plot(u,fill=true,wait=true,ps="thermic.eps");
+*/
+real rad=1e-8, uek=ue+273;
+Vh vold,w,v=u0-ue,b;
+problem thermradia(v,w)
+    = int2d(Th)(v*w/dt + k*(dx(v) * dx(w) + dy(v) * dy(w)))
+                + int1d(Th,1,3)(b*v*w)
+                - int2d(Th)(vold*w/dt) + on(2,4,v=u0-ue);
+
+for(real t=0;t<T;t+=dt){
+    vold=v;
+    for(int m=0;m<5;m++){
+       b= alpha + rad * (v + 2*uek) * ((v+uek)^2 + uek^2);
+       thermradia;
+    }
+}
+vold=v+ue; plot(vold);
diff --git a/examples++-eigen/Lap3dEigenValue.edp b/examples++-eigen/Lap3dEigenValue.edp
index 589b542..efa3b40 100644
--- a/examples++-eigen/Lap3dEigenValue.edp
+++ b/examples++-eigen/Lap3dEigenValue.edp
@@ -79,4 +79,7 @@ for (int i=0;i<k;i++)
     cout << " ---- " <<  i<< " " << ev[i] << " == " << eev[i] << " err= " << err << " --- "<<endl;
     plot(eV[i],cmm="Eigen 3d  Vector "+i+" valeur =" + ev[i]+ " == " + eev[i]    ,wait=1,value=1,ps="eigen"+i+".eps");
   }
-assert(nerr==0);
+
+// FFCS: avoid this assert because the list of eigenvalues is not
+// always sorted in the same way
+//assert(nerr==0);
diff --git a/examples++-eigen/LapComplexEigenValue.edp b/examples++-eigen/LapComplexEigenValue.edp
index 7edcf97..6b3a233 100644
--- a/examples++-eigen/LapComplexEigenValue.edp
+++ b/examples++-eigen/LapComplexEigenValue.edp
@@ -55,5 +55,8 @@ for (int kk=0;kk<k;kk++)
   ui=imag(eV[i]);
 //  plot(ur,cmm="Eigen  Vector (real)  "+i+" valeur =" + v  ,wait=1,value=1);
 //  plot(ui,cmm="Eigen  Vector (imag)  "+i+" valeur =" + v  ,wait=1,value=1);
+
+    // FFCS: add 3d view
+    plot(eV[i],dim=3,fill=1);
 }
 
diff --git a/examples++-eigen/LapEigenValue.edp b/examples++-eigen/LapEigenValue.edp
index d388577..17393e3 100644
--- a/examples++-eigen/LapEigenValue.edp
+++ b/examples++-eigen/LapEigenValue.edp
@@ -60,6 +60,8 @@ for (int i=0;i<k;i++)
   if(abs(err) > 1e-6) nerr++;
   if(abs(ev[i]-eev[i]) > 1e-1) nerr++;
   cout << " ---- " <<  i<< " " << ev[i] << " == " << eev[i] << " err= " << err << " --- "<<endl;
-  plot(eV[i],cmm="Eigen  Vector "+i+" valeur =" + ev[i]  ,wait=1,value=1,ps="eigen"+i+".eps");
+
+  // FFCS: add 3D view capabilities
+  plot(eV[i],cmm="Eigen  Vector "+i+" valeur =" + ev[i]  ,wait=1,value=1,ps="eigen"+i+".eps",dim=3,fill=1,CutPlane=0,ShowAxes=0);
 }
 assert(nerr==0);
diff --git a/examples++-eigen/LapnosymEigenValue.edp b/examples++-eigen/LapnosymEigenValue.edp
index e03c4fa..a15797c 100644
--- a/examples++-eigen/LapnosymEigenValue.edp
+++ b/examples++-eigen/LapnosymEigenValue.edp
@@ -65,6 +65,13 @@ for (int kk=0;kk<k;kk++)
   complex xAx = u1[]'*Au1 + u2[]'*Au2 + 1i*(u1[]'*Au2 - u2[]'*Au1);
   complex eigenvalue = xAx/xBx;
   cout << " ---- " <<  i<< " " <<  v <<" eigenvalue= " << eigenvalue << endl;
-  plot(eV[i],cmm="Eigen  Vector "+i+" valeur =" + er + " , " + ei  ,wait=1,value=1);
+
+  // FFCS: add 3D view
+  plot(eV[i],cmm="Eigen  Vector "+i+" valeur =" + er + " , " + ei  ,wait=1,value=1,dim=3,fill=1);
 }
 
+// FFCS: order of eigenvalues may change, and biggest eigenvalue
+// (95.xxx) may not be picked up at all.
+
+real regtest=0;
+for(int i=1;i<nev;i++)if(ev[i]<95 && regtest<ev[i])regtest=ev[i];
diff --git a/examples++-eigen/Makefile.am b/examples++-eigen/Makefile.am
index 6f321aa..1108872 100644
--- a/examples++-eigen/Makefile.am
+++ b/examples++-eigen/Makefile.am
@@ -1,6 +1,6 @@
 # $Id$
+all-local: all.edp freefem++.pref
 
-all-local: all.edp
 LOG_DRIVER=$(SHELL) $(top_srcdir)/test-driver-ff
 TESTS_ENVIRONMENT=TEST_FFPP=$(TEST_FFPP) FLAGS_FFPP=-nw SKIP=$(SKIP_TESTS_EIGEN)
 
@@ -16,3 +16,8 @@ all.edp:
 		echo \{ include \"$$i\"\;\}\; ;\
 		echo ' cout << "------------------------------------------------------------------------------ " << endl;' ;\
 	done) > $@
+
+freefem++.pref:
+	echo loadpath = \"../examples++-load/\" >freefem++.pref
+	echo loadpath += \"./\" >>freefem++.pref
+
diff --git a/examples++-eigen/Makefile.in b/examples++-eigen/Makefile.in
index 7e08634..a9a1fdb 100644
--- a/examples++-eigen/Makefile.in
+++ b/examples++-eigen/Makefile.in
@@ -13,8 +13,6 @@
 # PARTICULAR PURPOSE.
 
 @SET_MAKE@
-
-# $Id$
 VPATH = @srcdir@
 am__make_dryrun = \
   { \
@@ -56,7 +54,8 @@ 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)/acmacros.m4 \
-	$(top_srcdir)/acoptim.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/acoptim.m4 $(top_srcdir)/acmpi.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -329,11 +328,47 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EIGENOBJ = @EIGENOBJ@
+ENABLE_FFCS = @ENABLE_FFCS@
 EPSTOPDF = @EPSTOPDF@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+FFCS_COMPILE_fflapack = @FFCS_COMPILE_fflapack@
+FFCS_COMPILE_gsl = @FFCS_COMPILE_gsl@
+FFCS_COMPILE_hips = @FFCS_COMPILE_hips@
+FFCS_COMPILE_hypre = @FFCS_COMPILE_hypre@
+FFCS_COMPILE_ipopt = @FFCS_COMPILE_ipopt@
+FFCS_COMPILE_lapack = @FFCS_COMPILE_lapack@
+FFCS_COMPILE_mmg3d = @FFCS_COMPILE_mmg3d@
+FFCS_COMPILE_mshmet = @FFCS_COMPILE_mshmet@
+FFCS_COMPILE_mumps = @FFCS_COMPILE_mumps@
+FFCS_COMPILE_mumps_seq = @FFCS_COMPILE_mumps_seq@
+FFCS_COMPILE_pardiso = @FFCS_COMPILE_pardiso@
+FFCS_COMPILE_parms = @FFCS_COMPILE_parms@
+FFCS_COMPILE_pastix = @FFCS_COMPILE_pastix@
+FFCS_COMPILE_pipe = @FFCS_COMPILE_pipe@
+FFCS_COMPILE_scotch = @FFCS_COMPILE_scotch@
+FFCS_COMPILE_superludist = @FFCS_COMPILE_superludist@
+FFCS_COMPILE_yams = @FFCS_COMPILE_yams@
+FFCS_DYLIB_fflapack = @FFCS_DYLIB_fflapack@
+FFCS_DYLIB_gsl = @FFCS_DYLIB_gsl@
+FFCS_DYLIB_hips = @FFCS_DYLIB_hips@
+FFCS_DYLIB_hypre = @FFCS_DYLIB_hypre@
+FFCS_DYLIB_ipopt = @FFCS_DYLIB_ipopt@
+FFCS_DYLIB_lapack = @FFCS_DYLIB_lapack@
+FFCS_DYLIB_mmg3d = @FFCS_DYLIB_mmg3d@
+FFCS_DYLIB_mshmet = @FFCS_DYLIB_mshmet@
+FFCS_DYLIB_mumps = @FFCS_DYLIB_mumps@
+FFCS_DYLIB_mumps_seq = @FFCS_DYLIB_mumps_seq@
+FFCS_DYLIB_pardiso = @FFCS_DYLIB_pardiso@
+FFCS_DYLIB_parms = @FFCS_DYLIB_parms@
+FFCS_DYLIB_pastix = @FFCS_DYLIB_pastix@
+FFCS_DYLIB_pipe = @FFCS_DYLIB_pipe@
+FFCS_DYLIB_scotch = @FFCS_DYLIB_scotch@
+FFCS_DYLIB_superludist = @FFCS_DYLIB_superludist@
+FFCS_DYLIB_yams = @FFCS_DYLIB_yams@
+FFCS_MAKEFLAGS = @FFCS_MAKEFLAGS@
 FFGLUTNAME = @FFGLUTNAME@
 FFGLUTPROG = @FFGLUTPROG@
 FFLAGS = @FFLAGS@
@@ -914,7 +949,8 @@ uninstall-am:
 	uninstall uninstall-am
 
 
-all-local: all.edp
+# $Id$
+all-local: all.edp freefem++.pref
 
 all.edp:
 	(echo "NoUseOfWait=true;int verbosityy=verbosity;"; \
@@ -925,6 +961,10 @@ all.edp:
 		echo ' cout << "------------------------------------------------------------------------------ " << endl;' ;\
 	done) > $@
 
+freefem++.pref:
+	echo loadpath = \"../examples++-load/\" >freefem++.pref
+	echo loadpath += \"./\" >>freefem++.pref
+
 # 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.
 .NOEXPORT:
diff --git a/examples++-eigen/Stokes-eigen.edp b/examples++-eigen/Stokes-eigen.edp
index d2c35fa..62a0f4b 100644
--- a/examples++-eigen/Stokes-eigen.edp
+++ b/examples++-eigen/Stokes-eigen.edp
@@ -44,7 +44,9 @@ for (int i=0;i<k;i++)
   u1=eu1[i];
   u2=eu2[i];
   p=ep[i];
-  plot([u1,u2],p,cmm="Eigen  Vector "+i+" valeur =" + ev[i]  ,wait=1,value=1,ps="Stokes-eigen"+i+".eps");
+
+  // FFCS: changed to 3D view
+  plot([u1,u2],p,cmm="Eigen  Vector "+i+" valeur =" + ev[i]  ,value=1,ArrowSize=-1.6,dim=3,fill=1);
 }
 
 cout << "CPU " << clock()-s0 << "s " << endl;     
diff --git a/examples++-eigen/VP-Steklov-Poincare.edp b/examples++-eigen/VP-Steklov-Poincare.edp
index 6a8f92a..69cfcbb 100644
--- a/examples++-eigen/VP-Steklov-Poincare.edp
+++ b/examples++-eigen/VP-Steklov-Poincare.edp
@@ -18,5 +18,5 @@ int k=EigenValue(A,B,sym=true,sigma=sigma,value=ev,vector=eV);
 k=min(k,nev); //  some time the number of converged eigen value is  greater then nev..
 cout << ev <<endl;
 for(int i=0;i<k;++i)
- 	plot(eV[i],cmm=" vp " + ev[i],wait=1);
+ 	plot(eV[i],cmm=" vp " + ev[i],wait=1,dim=3,fill=1);
  
\ No newline at end of file
diff --git a/examples++-eigen/neuman.edp b/examples++-eigen/neuman.edp
index 90181fa..cf36a72 100644
--- a/examples++-eigen/neuman.edp
+++ b/examples++-eigen/neuman.edp
@@ -22,5 +22,9 @@ int k=EigenValue(A,B,sym=true,sigma=sigma,value=ev,vector=eV,tol=1e-10,maxit=0,n
 k=min(k,nev); //  some time the number of converged eigen value 
               // can be greater than nev;
 
-for(int i=0;i<k;i++)
-  cout << " Valeur propre " << i << " = " << ev[i] << endl;
\ No newline at end of file
+for(int i=0;i<k;i++){
+  cout << " Valeur propre " << i << " = " << ev[i] << endl;
+
+  // FFCS: add 3D view
+  plot(eV[i],dim=3,fill=1);
+}
diff --git a/examples++-load/._APk-AdaptEpsDeltaPk.edp b/examples++-load/._APk-AdaptEpsDeltaPk.edp
new file mode 100755
index 0000000..098cb96
Binary files /dev/null and b/examples++-load/._APk-AdaptEpsDeltaPk.edp differ
diff --git a/examples++-load/._APk-ExplicitPkTest.edp b/examples++-load/._APk-ExplicitPkTest.edp
new file mode 100755
index 0000000..cce600e
Binary files /dev/null and b/examples++-load/._APk-ExplicitPkTest.edp differ
diff --git a/examples++-load/._APk-MetricPk.edp b/examples++-load/._APk-MetricPk.edp
new file mode 100755
index 0000000..817f9ec
Binary files /dev/null and b/examples++-load/._APk-MetricPk.edp differ
diff --git a/examples++-load/._Element_P3.cpp b/examples++-load/._Element_P3.cpp
new file mode 100644
index 0000000..14f037e
Binary files /dev/null and b/examples++-load/._Element_P3.cpp differ
diff --git a/examples++-load/._IpOptMinSurf.edp b/examples++-load/._IpOptMinSurf.edp
new file mode 100644
index 0000000..f7a8f68
Binary files /dev/null and b/examples++-load/._IpOptMinSurf.edp differ
diff --git a/examples++-load/._IpoptVI2.edp b/examples++-load/._IpoptVI2.edp
new file mode 100644
index 0000000..7b1c764
Binary files /dev/null and b/examples++-load/._IpoptVI2.edp differ
diff --git a/examples++-load/._PARDISO.cpp b/examples++-load/._PARDISO.cpp
new file mode 100755
index 0000000..14f037e
Binary files /dev/null and b/examples++-load/._PARDISO.cpp differ
diff --git a/examples++-load/._TensorK.hpp b/examples++-load/._TensorK.hpp
new file mode 100755
index 0000000..14f037e
Binary files /dev/null and b/examples++-load/._TensorK.hpp differ
diff --git a/examples++-load/._ch.pts b/examples++-load/._ch.pts
new file mode 100644
index 0000000..f7a8f68
Binary files /dev/null and b/examples++-load/._ch.pts differ
diff --git a/examples++-load/._cmaes.cpp b/examples++-load/._cmaes.cpp
new file mode 100644
index 0000000..cf206fb
Binary files /dev/null and b/examples++-load/._cmaes.cpp differ
diff --git a/examples++-load/._cmaes.h b/examples++-load/._cmaes.h
new file mode 100644
index 0000000..cf206fb
Binary files /dev/null and b/examples++-load/._cmaes.h differ
diff --git a/examples++-load/._cmaes_interface.h b/examples++-load/._cmaes_interface.h
new file mode 100644
index 0000000..3d4ef81
Binary files /dev/null and b/examples++-load/._cmaes_interface.h differ
diff --git a/examples++-load/._ff-Ipopt.cpp b/examples++-load/._ff-Ipopt.cpp
new file mode 100644
index 0000000..14f037e
Binary files /dev/null and b/examples++-load/._ff-Ipopt.cpp differ
diff --git a/examples++-load/._ff-NLopt.cpp b/examples++-load/._ff-NLopt.cpp
new file mode 100644
index 0000000..6adb72e
Binary files /dev/null and b/examples++-load/._ff-NLopt.cpp differ
diff --git a/examples++-load/._gsl.cpp b/examples++-load/._gsl.cpp
new file mode 100644
index 0000000..14f037e
Binary files /dev/null and b/examples++-load/._gsl.cpp differ
diff --git a/examples++-load/._isoline.cpp b/examples++-load/._isoline.cpp
new file mode 100644
index 0000000..14f037e
Binary files /dev/null and b/examples++-load/._isoline.cpp differ
diff --git a/examples++-load/._isoline.edp b/examples++-load/._isoline.edp
new file mode 100644
index 0000000..f7a8f68
Binary files /dev/null and b/examples++-load/._isoline.edp differ
diff --git a/examples++-load/._mat_dervieux.cpp b/examples++-load/._mat_dervieux.cpp
new file mode 100644
index 0000000..6adb72e
Binary files /dev/null and b/examples++-load/._mat_dervieux.cpp differ
diff --git a/examples++-load/._pipe.edp b/examples++-load/._pipe.edp
new file mode 100644
index 0000000..f7a8f68
Binary files /dev/null and b/examples++-load/._pipe.edp differ
diff --git a/examples++-load/._scotch.edp b/examples++-load/._scotch.edp
new file mode 100644
index 0000000..de04ca6
Binary files /dev/null and b/examples++-load/._scotch.edp differ
diff --git a/examples++-load/._shell.cpp b/examples++-load/._shell.cpp
new file mode 100644
index 0000000..14f037e
Binary files /dev/null and b/examples++-load/._shell.cpp differ
diff --git a/examples++-load/._splitedges.cpp b/examples++-load/._splitedges.cpp
new file mode 100644
index 0000000..6adb72e
Binary files /dev/null and b/examples++-load/._splitedges.cpp differ
diff --git a/examples++-load/._symmetrizeCSR.cpp b/examples++-load/._symmetrizeCSR.cpp
new file mode 100644
index 0000000..e63f378
Binary files /dev/null and b/examples++-load/._symmetrizeCSR.cpp differ
diff --git a/examples++-load/._tetgen.cpp b/examples++-load/._tetgen.cpp
new file mode 100644
index 0000000..63e1130
Binary files /dev/null and b/examples++-load/._tetgen.cpp differ
diff --git a/examples++-load/BinaryIO.cpp b/examples++-load/BinaryIO.cpp
index 033a67e..ea05eb3 100644
--- a/examples++-load/BinaryIO.cpp
+++ b/examples++-load/BinaryIO.cpp
@@ -68,6 +68,7 @@ long int Flag;
  Flag= *FLAG;   
  outfile.write ((char*) &Flag, sizeof(long int));
 outfile.close();
+ return 0.0;
 }
 
 
diff --git a/examples++-load/DxWriter.cpp b/examples++-load/DxWriter.cpp
index 349f12e..dd34cd9 100644
--- a/examples++-load/DxWriter.cpp
+++ b/examples++-load/DxWriter.cpp
@@ -1,344 +1,350 @@
-// -*- Mode : c++ -*-
-//
-// SUMMARY  : 
-// USAGE    :        
-// ORG      : 
-// AUTHOR   : Sala Lorenzo
-// E-MAIL   : salalo80 at gmail.com
-//
-
-#include "mode_open.hpp"
-#include <iostream>
-#include <cfloat>
-#include <cmath>
-#include <iterator>
-using namespace std;
-#include "ff++.hpp"
-using namespace Fem2D;
-
-
-/*!The class DxWriter permits to save in opendx format a "field" 
-(in the dx-language a "field" means the values of a function f(x,y,z) on a grid),
-a time series (an ordered collection of "fields", so we have field0=f(x,y,z,t0), field1=f(x,y,z,t1)
-and so on).
-DxWriter creates two files: one with extension .data where it puts the position of the grid, the connessions, 
-the values; and one with extension.dx where it puts the time series.
-Now you can save only scalar fields. 
-An example <code>
-load "DxWriter"
-mesh Th=square(5,5);
-DxWriter ff("pippo");
-Dxaddmesh(ff, Th);
-Dxaddtimeseries(ff, "Vx",Th);
-fespace Vh(Th, P1);
-Vh vx=x*y;
-Dxaddsol2ts(ff,"Vx",1.0, vx);
-vx=0.5*x*y^2+0.2;
-Dxaddsol2ts(ff,"Vx",2.0, vx);
-cout<<"Ciao";
-</code>
-*/
-
-class DxWriter {
-	struct tsinfo{
-		int imesh;//!<index of the mesh
-		std::string name;
-		std::vector<double> vecistant;
-	};
-private:
-std::vector<Fem2D::Mesh*> _vecmesh;
-std::vector<tsinfo> _vecofts;
-std::string _nameoffile;
-/*! This string contains the name of data file with \\ where there's a \ in the path*/
-std::string _nameofdatafile;
-//!files containing the data and the timeseries
-std::ofstream _ofdata, _ofts;
-
-/*!This function is called frequently, so if the main program crashes the files are good
-and you need only write "end" at the end of data file: echo end>>nameoffile.data and then the files are good
-*/
-void save_header(){
-		std::string s=_nameoffile;
-		s.append(".dx");
-		_ofts.open(s.c_str(), std::ios_base::out);
-		for(int i=0;i<_vecofts.size();++i){
-				_ofts<<"object \""<<_vecofts[i].name<<"\" class series"<<std::endl;  
-				for(int j=0;j<_vecofts[i].vecistant.size();++j){
-					_ofts<<"member "<<j<<" value file \""<<_nameofdatafile<<"\",\""<<_vecofts[i].name<<"_"<<j<<"\" position "<<_vecofts[i].vecistant[j]<<std::endl;
-				}
-				_ofts<<std::endl;
-		}
-		_ofts<<"end"<<std::endl;
-		_ofts.close();
-	}
-	
-
-public:
-  DxWriter() { std::cout << "Constructor of DxWriter" << endl;  }
-  void openfiles(const std::string& s){
-		_nameoffile=s;
-		std::string tmp=s+".data";
-		std::cout<<tmp<<" ";
-		_ofdata.open(tmp.c_str(), std::ios_base::out);
-		_nameofdatafile="";
-		for(int i=0;i<tmp.length();++i){
-			if(tmp.at(i)=='\\')
-				_nameofdatafile.append(1,'\\');
-			_nameofdatafile.append(1,tmp.at(i));
-		}
-  }
-	
-  void addmesh(Fem2D::Mesh* mesh){
-		Fem2D::Mesh& Th(*mesh);
-		_vecmesh.push_back(mesh);
-		_ofdata.flags(std::ios_base::scientific);
-		_ofdata.precision(15);
-		_ofdata<<"object \"pos_"<<_vecmesh.size()-1 <<"\" class array type float rank 1 shape 2 items "<<Th.nv<<" data follows"<<std::endl;
-		for(int k=0;k<Th.nv;++k){//Scorre tutti i vertici
-			_ofdata << Th(k).x<<" "<<Th(k).y<<endl;
-		}
-		_ofdata<<std::endl;
-		_ofdata.flags(std::ios_base::fixed);
-		_ofdata<<"object \"conn_"<<_vecmesh.size()-1<<"\" class array type int rank 1 shape 3 items "<<Th.nt<<" data follows "<<endl;
-		for (int i=0;i<Th.nt;i++){
-			for (int j=0; j <3; j++)
-				_ofdata << Th(i,j) << " ";
-			_ofdata<< endl;
-		}
-		_ofdata<<"attribute \"element type\" string \"triangles\" "<<std::endl;
-		_ofdata<<"attribute \"ref\" string \"positions\" "<<std::endl<<std::endl;
-  }
-  /*!Add a new time series, defined on the mesh*/
-	void addtimeseries(const string& nameofts, Fem2D::Mesh* mesh){
-		tsinfo ts;ts.name=nameofts;
-		std::vector<Fem2D::Mesh*>::const_iterator first=_vecmesh.begin(), last=_vecmesh.end();
-		if(std::find(first, last, mesh)==last){
-			addmesh(mesh);
-			ts.imesh=_vecmesh.size()-1;
-		}else{
-			ts.imesh=std::distance(first, std::find(first, last, mesh));
-		}
-		_vecofts.push_back(ts);
-	}
-  
-	/*!Add an instant to a time series name*/
-	void addistant2ts(const string& nameofts, const double t, const KN<double>&val){
-		int jj=-1;
-		for(int i=0;i<_vecofts.size();++i){
-			if(_vecofts[i].name==nameofts)jj=i;
-		}
-		_vecofts[jj].vecistant.push_back(t);
-		_ofdata.flags(std::ios_base::scientific);
-		_ofdata.precision(15);
-		_ofdata<<"object \""<<nameofts<<"_data_"<<_vecofts[jj].vecistant.size()-1<<"\" class array type float rank 0 items "<<
-			val.size()<<" data follows"<<std::endl;
-		for(int i=0;i<val.size();++i)
-			_ofdata<<val[i]<<std::endl;
-		_ofdata<<"attribute \"dep\" string \"positions\""<<std::endl<<std::endl;
-		_ofdata<<"object \""<<nameofts<<"_"<<_vecofts[jj].vecistant.size()-1<<"\" class field"<<std::endl;
-		_ofdata<<"component \"positions\" value \"pos_"<<_vecofts[jj].imesh<<"\""<<std::endl;
-		_ofdata<<"component \"connections\" value \"conn_"<<_vecofts[jj].imesh<<"\""<<std::endl;
-		_ofdata<<"component \"data\" value \""<<nameofts<<"_data_"<<_vecofts[jj].vecistant.size()-1<<"\""<<std::endl<<std::endl;
-		_ofdata.flush();
-		save_header();
-	}
-	
-	/*!Add a field*/
-	void addfield(const string& nameoffield, Fem2D::Mesh* mesh, const KN<double>&val){
-		std::vector<Fem2D::Mesh*>::const_iterator first=_vecmesh.begin(), last=_vecmesh.end();
-		int im;
-		if(std::find(first, last, mesh)==last){
-			addmesh(mesh);
-			im=_vecmesh.size()-1;
-		}else{
-			im=std::distance(first, std::find(first, last, mesh));
-		}
-		_ofdata.flags(std::ios_base::scientific);
-		_ofdata.precision(15);
-		_ofdata<<"object \""<<nameoffield<<"_data\" class array type float rank 0 items "<<
-			val.size()<<" data follows"<<std::endl;
-		for(int i=0;i<val.size();++i)
-			_ofdata<<val[i]<<std::endl;
-		_ofdata<<"attribute \"dep\" string \"positions\""<<std::endl<<std::endl;
-		_ofdata<<"object \""<<nameoffield<<"\" class field"<<std::endl;
-		_ofdata<<"component \"positions\" value \"pos_"<<im<<"\""<<std::endl;
-		_ofdata<<"component \"connections\" value \"conn_"<<im<<"\""<<std::endl;
-		_ofdata<<"component \"data\" value \""<<nameoffield<<"_data\""<<std::endl<<std::endl;
-		_ofdata.flush();
-	}
-	
-	/*!Get the mesh associated with the series nameofts*/
-	Fem2D::Mesh* getmeshts(const string& nameofts){
-		for(int i=0;i<_vecofts.size();++i){
-			if(_vecofts[i].name==nameofts)return _vecmesh[_vecofts[i].imesh];
-		}
-		return NULL;
-	}
- 
-  void init(){
-		new(this)DxWriter(); 
-  }
-	
-  void destroy() {
-		if(_ofdata.is_open()){
-			_ofdata<<std::endl<<"end"<<std::endl;
-			_ofdata.close(); 		
-		}
-  } 
-};
-
-
-class Dxwritesol_Op : public E_F0mps 
-{
-public:
-  typedef long  Result;
-	Expression edx;
-  Expression ename;//!<name of time series or field
-	Expression et;//!<time
-  long what; // 1 scalar, 2 vector, 3 symtensor
-  long nbfloat; // 1 scalar, n vector (3D), n symtensor(3D)
-  Expression evct;
-
-public:
-  Dxwritesol_Op(const basicAC_F0 &  args) :  what(0), nbfloat(0)
-  {
-		evct=0;
-    int nbofsol;
-    int ddim=2;
-    int stsize=3;
-		//There's no named parameter
-    args.SetNameParam();
-		if(args.size()!=4){
-			CompileError("Dxwritesol accepts only 4 parameters");
-		}
-		if (BCastTo<DxWriter *>(args[0])) edx = CastTo<DxWriter *>(args[0]);
-		if (BCastTo<string *>(args[1])) ename = CastTo<string *>(args[1]);
-    if (BCastTo<double>(args[2]))    et = CastTo<double>(args[2]);
-    
-    if ( args[3].left()==atype<double>() ){
-			what=1;
-			nbfloat=1;
-			evct=to<double>( args[3] );
-		}
-		else if ( args[3].left()==atype<double *>() )
-		{
-			what=1;
-			nbfloat=1;
-			evct=to<double>( args[3] );
-		}
-    else if ( BCastTo<pfer>(args[3]) )
-		{
-			what=1;
-			nbfloat=1;
-			evct=to<double>( args[3] );
-		}
-    else if ( args[3].left()==atype<E_Array>() )
-		{
-			CompileError("Until now only scalar solution");
-			
-			/*const E_Array * a0  = dynamic_cast<const E_Array *>( args[i].LeftValue() );
-			//cout << "taille" << a0->size() << endl;
-			//if (a0->size() != ddim || a0->size() != stsize) 
-			//  CompileError("savesol in 2D: vector solution is 2 composant, symmetric solution is 3 composant");
-			if( a0->size() == ddim){
-				// vector solution
-				what=2;
-				nbfloat=a0->size();
-				for(int j=0; j<l[i].nbfloat; j++){
-					//evct[j] = to<double>( (*a0)[j]);
-				}
-			}
-			else if( a0->size() == stsize){
-				// symmetric tensor solution
-				what=3;
-				nbfloat=a0->size();
-				for(int j=0; j<l[i].nbfloat; j++){
-					//evct[j] = to<double>( (*a0)[j]);
-				}
-			}*/
-		}
-    else {
-			CompileError("savesol in 2D: Sorry no way to save this kind of data");
-    }
-      
-  }
-  static ArrayOfaType  typeargs() { return  ArrayOfaType(atype<DxWriter *>(), atype<string *>(), atype<double>(), true); }// all type
-  static  E_F0 * f(const basicAC_F0 & args) { return new Dxwritesol_Op(args);} 
-  AnyType operator()(Stack stack)  const ;
-};
-
-
-AnyType Dxwritesol_Op::operator()(Stack stack)  const 
-{ 
-  MeshPoint *mp(MeshPointStack(stack)) , mps=*mp;
-	DxWriter &dx=*(GetAny<DxWriter *>((*edx)(stack)));
-  string &name=*(GetAny<string *>((*ename)(stack)));
-	double t=GetAny<double>((*et)(stack));
-	Mesh &Th=*(dx.getmeshts(name));
-
-  int nt = Th.nt;
-  int nv = Th.nv;
-
-  int nbsol=nv;
-  long longdefault;
-
-  KN<double> valsol(nbsol);
-  valsol=0.;
-  KN<int> takemesh(nbsol);
-	takemesh=0;
-  MeshPoint *mp3(MeshPointStack(stack));
-  for (int it=0;it<nt;it++){
-    for(int iv=0;iv<3;iv++){
-			int i=Th(it,iv);
-			mp3->setP(&Th,it,iv);					
-			valsol[i] = valsol[i] + GetAny< double >((*evct)(stack));			
-			++takemesh[i];
-		}
-	}
-	for(int i=0; i<nbsol; i++){
-		valsol[i] /= takemesh[i]; 
-	}
-	
-	//Writes valsol on the file file
-	dx.addistant2ts(name, t, valsol);	
-	
-  return longdefault;
-}
-
-// le vrai constructeur est la
-DxWriter* init_DxWriter(DxWriter * const &a, string * const & s)
-{
-  std::cout << "start init_DxWriter" << std::endl;
-  a->init();
-  a->openfiles(*s);
-  std::cout << "end init_DxWriter" << std::endl;
-  return a;
-} 
-
-void* call_addmesh( DxWriter * const & mt, Fem2D::Mesh* const & pTh)
-{ mt->addmesh(pTh);}
-
-void* call_addtimeseries( DxWriter * const & mt,string * const & name, Fem2D::Mesh* const & pTh)
-{ mt->addtimeseries(*name, pTh);}
-
-
-//   Add the function name to the freefem++ table 
-class Init { public:
-  Init();
-};
-LOADINIT(Init);
-Init::Init(){
-
-  Dcl_Type<DxWriter*>(InitP<DxWriter>,Destroy<DxWriter>); // declare deux nouveau type pour freefem++  un pointeur et 
-  
-  zzzfff->Add("DxWriter",atype<DxWriter*>()); // ajoute le type myType a freefem++ 
-  // constructeur  d'un type myType  dans freefem 
-  TheOperators->Add("<-", new OneOperator2_<DxWriter*, DxWriter* ,string*>(&init_DxWriter));
-  
-  Global.Add("Dxaddmesh","(",new OneOperator2_<void *, DxWriter*, Fem2D::Mesh*>(call_addmesh)); 
-	Global.Add("Dxaddtimeseries","(",new OneOperator3_<void *, DxWriter*, std::string*, Fem2D::Mesh*>(call_addtimeseries)); 
-	
-	Global.Add("Dxaddsol2ts","(",new OneOperatorCode< Dxwritesol_Op> );
-  
-  //atype< myType * >()->Add("(","",new OneOperator3_<myType_uv,myType *,double,double  >(set_myType_uv));
-}
+// -*- Mode : c++ -*-
+//
+// SUMMARY  : 
+// USAGE    :        
+// ORG      : 
+// AUTHOR   : Sala Lorenzo
+// E-MAIL   : salalo80 at gmail.com
+//
+
+#include "mode_open.hpp"
+#include <iostream>
+#include <cfloat>
+#include <cmath>
+#include <iterator>
+using namespace std;
+#include "ff++.hpp"
+using namespace Fem2D;
+
+
+/*!The class DxWriter permits to save in opendx format a "field" 
+(in the dx-language a "field" means the values of a function f(x,y,z) on a grid),
+a time series (an ordered collection of "fields", so we have field0=f(x,y,z,t0), field1=f(x,y,z,t1)
+and so on).
+DxWriter creates two files: one with extension .data where it puts the position of the grid, the connessions, 
+the values; and one with extension.dx where it puts the time series.
+Now you can save only scalar fields. 
+An example <code>
+load "DxWriter"
+mesh Th=square(5,5);
+DxWriter ff("pippo");
+Dxaddmesh(ff, Th);
+Dxaddtimeseries(ff, "Vx",Th);
+fespace Vh(Th, P1);
+Vh vx=x*y;
+Dxaddsol2ts(ff,"Vx",1.0, vx);
+vx=0.5*x*y^2+0.2;
+Dxaddsol2ts(ff,"Vx",2.0, vx);
+cout<<"Ciao";
+</code>
+*/
+
+class DxWriter {
+	struct tsinfo{
+		int imesh;//!<index of the mesh
+		std::string name;
+		std::vector<double> vecistant;
+	};
+private:
+std::vector<Fem2D::Mesh*> _vecmesh;
+std::vector<tsinfo> _vecofts;
+std::string _nameoffile;
+/*! This string contains the name of data file with \\ where there's a \ in the path*/
+std::string _nameofdatafile;
+//!files containing the data and the timeseries
+std::ofstream _ofdata, _ofts;
+
+/*!This function is called frequently, so if the main program crashes the files are good
+and you need only write "end" at the end of data file: echo end>>nameoffile.data and then the files are good
+*/
+void save_header(){
+		std::string s=_nameoffile;
+		s.append(".dx");
+		_ofts.open(s.c_str(), std::ios_base::out);
+		for(int i=0;i<_vecofts.size();++i){
+				_ofts<<"object \""<<_vecofts[i].name<<"\" class series"<<std::endl;  
+				for(int j=0;j<_vecofts[i].vecistant.size();++j){
+					_ofts<<"member "<<j<<" value file \""<<_nameofdatafile<<"\",\""<<_vecofts[i].name<<"_"<<j<<"\" position "<<_vecofts[i].vecistant[j]<<std::endl;
+				}
+				_ofts<<std::endl;
+		}
+		_ofts<<"end"<<std::endl;
+		_ofts.close();
+	}
+	
+
+public:
+  DxWriter() { std::cout << "Constructor of DxWriter" << endl;  }
+  void openfiles(const std::string& s){
+		_nameoffile=s;
+		std::string tmp=s+".data";
+		std::cout<<tmp<<" ";
+		_ofdata.open(tmp.c_str(), std::ios_base::out);
+		_nameofdatafile="";
+		for(int i=0;i<tmp.length();++i){
+			if(tmp.at(i)=='\\')
+				_nameofdatafile.append(1,'\\');
+			_nameofdatafile.append(1,tmp.at(i));
+		}
+  }
+	
+  void addmesh(Fem2D::Mesh* mesh){
+		Fem2D::Mesh& Th(*mesh);
+		_vecmesh.push_back(mesh);
+		_ofdata.flags(std::ios_base::scientific);
+		_ofdata.precision(15);
+		_ofdata<<"object \"pos_"<<_vecmesh.size()-1 <<"\" class array type float rank 1 shape 2 items "<<Th.nv<<" data follows"<<std::endl;
+		for(int k=0;k<Th.nv;++k){//Scorre tutti i vertici
+			_ofdata << Th(k).x<<" "<<Th(k).y<<endl;
+		}
+		_ofdata<<std::endl;
+		_ofdata.flags(std::ios_base::fixed);
+		_ofdata<<"object \"conn_"<<_vecmesh.size()-1<<"\" class array type int rank 1 shape 3 items "<<Th.nt<<" data follows "<<endl;
+		for (int i=0;i<Th.nt;i++){
+			for (int j=0; j <3; j++)
+				_ofdata << Th(i,j) << " ";
+			_ofdata<< endl;
+		}
+		_ofdata<<"attribute \"element type\" string \"triangles\" "<<std::endl;
+		_ofdata<<"attribute \"ref\" string \"positions\" "<<std::endl<<std::endl;
+  }
+  /*!Add a new time series, defined on the mesh*/
+	void addtimeseries(const string& nameofts, Fem2D::Mesh* mesh){
+		tsinfo ts;ts.name=nameofts;
+		std::vector<Fem2D::Mesh*>::const_iterator first=_vecmesh.begin(), last=_vecmesh.end();
+		if(std::find(first, last, mesh)==last){
+			addmesh(mesh);
+			ts.imesh=_vecmesh.size()-1;
+		}else{
+			ts.imesh=std::distance(first, std::find(first, last, mesh));
+		}
+		_vecofts.push_back(ts);
+	}
+  
+	/*!Add an instant to a time series name*/
+	void addistant2ts(const string& nameofts, const double t, const KN<double>&val){
+		int jj=-1;
+		for(int i=0;i<_vecofts.size();++i){
+			if(_vecofts[i].name==nameofts)jj=i;
+		}
+		_vecofts[jj].vecistant.push_back(t);
+		_ofdata.flags(std::ios_base::scientific);
+		_ofdata.precision(15);
+		_ofdata<<"object \""<<nameofts<<"_data_"<<_vecofts[jj].vecistant.size()-1<<"\" class array type float rank 0 items "<<
+			val.size()<<" data follows"<<std::endl;
+		for(int i=0;i<val.size();++i)
+			_ofdata<<val[i]<<std::endl;
+		_ofdata<<"attribute \"dep\" string \"positions\""<<std::endl<<std::endl;
+		_ofdata<<"object \""<<nameofts<<"_"<<_vecofts[jj].vecistant.size()-1<<"\" class field"<<std::endl;
+		_ofdata<<"component \"positions\" value \"pos_"<<_vecofts[jj].imesh<<"\""<<std::endl;
+		_ofdata<<"component \"connections\" value \"conn_"<<_vecofts[jj].imesh<<"\""<<std::endl;
+		_ofdata<<"component \"data\" value \""<<nameofts<<"_data_"<<_vecofts[jj].vecistant.size()-1<<"\""<<std::endl<<std::endl;
+		_ofdata.flush();
+		save_header();
+	}
+	
+	/*!Add a field*/
+	void addfield(const string& nameoffield, Fem2D::Mesh* mesh, const KN<double>&val){
+		std::vector<Fem2D::Mesh*>::const_iterator first=_vecmesh.begin(), last=_vecmesh.end();
+		int im;
+		if(std::find(first, last, mesh)==last){
+			addmesh(mesh);
+			im=_vecmesh.size()-1;
+		}else{
+			im=std::distance(first, std::find(first, last, mesh));
+		}
+		_ofdata.flags(std::ios_base::scientific);
+		_ofdata.precision(15);
+		_ofdata<<"object \""<<nameoffield<<"_data\" class array type float rank 0 items "<<
+			val.size()<<" data follows"<<std::endl;
+		for(int i=0;i<val.size();++i)
+			_ofdata<<val[i]<<std::endl;
+		_ofdata<<"attribute \"dep\" string \"positions\""<<std::endl<<std::endl;
+		_ofdata<<"object \""<<nameoffield<<"\" class field"<<std::endl;
+		_ofdata<<"component \"positions\" value \"pos_"<<im<<"\""<<std::endl;
+		_ofdata<<"component \"connections\" value \"conn_"<<im<<"\""<<std::endl;
+		_ofdata<<"component \"data\" value \""<<nameoffield<<"_data\""<<std::endl<<std::endl;
+		_ofdata.flush();
+	}
+	
+	/*!Get the mesh associated with the series nameofts*/
+	Fem2D::Mesh* getmeshts(const string& nameofts){
+		for(int i=0;i<_vecofts.size();++i){
+			if(_vecofts[i].name==nameofts)return _vecmesh[_vecofts[i].imesh];
+		}
+		return NULL;
+	}
+ 
+  void init(){
+		new(this)DxWriter(); 
+  }
+	
+  void destroy() {
+		if(_ofdata.is_open()){
+			_ofdata<<std::endl<<"end"<<std::endl;
+			_ofdata.close(); 		
+		}
+  } 
+};
+
+
+class Dxwritesol_Op : public E_F0mps 
+{
+public:
+  typedef long  Result;
+	Expression edx;
+  Expression ename;//!<name of time series or field
+	Expression et;//!<time
+  long what; // 1 scalar, 2 vector, 3 symtensor
+  long nbfloat; // 1 scalar, n vector (3D), n symtensor(3D)
+  Expression evct;
+
+public:
+  Dxwritesol_Op(const basicAC_F0 &  args) :  what(0), nbfloat(0)
+  {
+		evct=0;
+    int nbofsol;
+    int ddim=2;
+    int stsize=3;
+		//There's no named parameter
+    args.SetNameParam();
+		if(args.size()!=4){
+			CompileError("Dxwritesol accepts only 4 parameters");
+		}
+		if (BCastTo<DxWriter *>(args[0])) edx = CastTo<DxWriter *>(args[0]);
+		if (BCastTo<string *>(args[1])) ename = CastTo<string *>(args[1]);
+    if (BCastTo<double>(args[2]))    et = CastTo<double>(args[2]);
+    
+    if ( args[3].left()==atype<double>() ){
+			what=1;
+			nbfloat=1;
+			evct=to<double>( args[3] );
+		}
+		else if ( args[3].left()==atype<double *>() )
+		{
+			what=1;
+			nbfloat=1;
+			evct=to<double>( args[3] );
+		}
+    else if ( BCastTo<pfer>(args[3]) )
+		{
+			what=1;
+			nbfloat=1;
+			evct=to<double>( args[3] );
+		}
+    else if ( args[3].left()==atype<E_Array>() )
+		{
+			CompileError("Until now only scalar solution");
+			
+			/*const E_Array * a0  = dynamic_cast<const E_Array *>( args[i].LeftValue() );
+			//cout << "taille" << a0->size() << endl;
+			//if (a0->size() != ddim || a0->size() != stsize) 
+			//  CompileError("savesol in 2D: vector solution is 2 composant, symmetric solution is 3 composant");
+			if( a0->size() == ddim){
+				// vector solution
+				what=2;
+				nbfloat=a0->size();
+				for(int j=0; j<l[i].nbfloat; j++){
+					//evct[j] = to<double>( (*a0)[j]);
+				}
+			}
+			else if( a0->size() == stsize){
+				// symmetric tensor solution
+				what=3;
+				nbfloat=a0->size();
+				for(int j=0; j<l[i].nbfloat; j++){
+					//evct[j] = to<double>( (*a0)[j]);
+				}
+			}*/
+		}
+    else {
+			CompileError("savesol in 2D: Sorry no way to save this kind of data");
+    }
+      
+  }
+  static ArrayOfaType  typeargs() { return  ArrayOfaType(atype<DxWriter *>(), atype<string *>(), atype<double>(), true); }// all type
+  static  E_F0 * f(const basicAC_F0 & args) { return new Dxwritesol_Op(args);} 
+  AnyType operator()(Stack stack)  const ;
+};
+
+
+AnyType Dxwritesol_Op::operator()(Stack stack)  const 
+{ 
+  MeshPoint *mp(MeshPointStack(stack)) , mps=*mp;
+	DxWriter &dx=*(GetAny<DxWriter *>((*edx)(stack)));
+  string &name=*(GetAny<string *>((*ename)(stack)));
+	double t=GetAny<double>((*et)(stack));
+	Mesh &Th=*(dx.getmeshts(name));
+
+  int nt = Th.nt;
+  int nv = Th.nv;
+
+  int nbsol=nv;
+  long longdefault;
+
+  KN<double> valsol(nbsol);
+  valsol=0.;
+  KN<int> takemesh(nbsol);
+	takemesh=0;
+  MeshPoint *mp3(MeshPointStack(stack));
+  for (int it=0;it<nt;it++){
+    for(int iv=0;iv<3;iv++){
+			int i=Th(it,iv);
+			mp3->setP(&Th,it,iv);					
+			valsol[i] = valsol[i] + GetAny< double >((*evct)(stack));			
+			++takemesh[i];
+		}
+	}
+	for(int i=0; i<nbsol; i++){
+		valsol[i] /= takemesh[i]; 
+	}
+	
+	//Writes valsol on the file file
+	dx.addistant2ts(name, t, valsol);	
+	
+  return longdefault;
+}
+
+// le vrai constructeur est la
+DxWriter* init_DxWriter(DxWriter * const &a, string * const & s)
+{
+  std::cout << "start init_DxWriter" << std::endl;
+  a->init();
+  a->openfiles(*s);
+  std::cout << "end init_DxWriter" << std::endl;
+  return a;
+} 
+
+void* call_addmesh( DxWriter * const & mt, Fem2D::Mesh* const & pTh)
+{ 
+  mt->addmesh(pTh);
+  return NULL;
+}
+
+void* call_addtimeseries( DxWriter * const & mt,string * const & name, Fem2D::Mesh* const & pTh)
+{ 
+  mt->addtimeseries(*name, pTh);
+  return NULL;
+}
+
+
+//   Add the function name to the freefem++ table 
+class Init { public:
+  Init();
+};
+LOADINIT(Init);
+Init::Init(){
+
+  Dcl_Type<DxWriter*>(InitP<DxWriter>,Destroy<DxWriter>); // declare deux nouveau type pour freefem++  un pointeur et 
+  
+  zzzfff->Add("DxWriter",atype<DxWriter*>()); // ajoute le type myType a freefem++ 
+  // constructeur  d'un type myType  dans freefem 
+  TheOperators->Add("<-", new OneOperator2_<DxWriter*, DxWriter* ,string*>(&init_DxWriter));
+  
+  Global.Add("Dxaddmesh","(",new OneOperator2_<void *, DxWriter*, Fem2D::Mesh*>(call_addmesh)); 
+	Global.Add("Dxaddtimeseries","(",new OneOperator3_<void *, DxWriter*, std::string*, Fem2D::Mesh*>(call_addtimeseries)); 
+	
+	Global.Add("Dxaddsol2ts","(",new OneOperatorCode< Dxwritesol_Op> );
+  
+  //atype< myType * >()->Add("(","",new OneOperator3_<myType_uv,myType *,double,double  >(set_myType_uv));
+}
diff --git a/examples++-load/IpoptMinSurfVol.edp b/examples++-load/IpoptMinSurfVol.edp
index c2c2760..dfa5bc3 100644
--- a/examples++-load/IpoptMinSurfVol.edp
+++ b/examples++-load/IpoptMinSurfVol.edp
@@ -1,3 +1,7 @@
+// this exemple is buggus in some case ...
+// strange ...  FH.  , S Auliac  (will be correct in test ???)
+// remove the test  (no loop)  
+int nadapt=0;//  3 is teh previous value..
 load "msh3";
 load "medit";
 load "ff-Ipopt";
@@ -6,6 +10,9 @@ real alpha=0.9;
 int np=30;
 mesh Th = square(2*np,np,[2*pi*x,pi*y]);
 
+// FFCS regression reference value
+real regtest;
+
 fespace Vh(Th,P1,periodic=[[2,y],[4,y]/*,[1,x],[3,x]*/]);
 
 /*
@@ -20,7 +27,7 @@ Vh uz=1.,lz=1.;
 real[int] lm=[1];
 
 
-int nadapt=3;
+
 for(int kkk=0;kkk<nadapt;++kkk) //Mesh adaptation loop
 {
 
@@ -225,9 +232,8 @@ real[int] clb=0.,cub=[(1-alpha)*Vobj + alpha*Vnvc];
 /*
  * Call to IPOPT
  */
- 
-IPOPT(Area,GradArea,ipHessianLag,ipVolume,ipGradVolume,rc[],ub=ub[],lb=lb[],clb=clb,cub=cub,checkindex=1,maxiter=kkk<nadapt-1 ? 40:150,warmstart=kkk,lm=lm,uz=uz[],lz=lz[],tol=0.00001,structjacc=[gvi,gvj]);
-
+int res=IPOPT(Area,GradArea,ipHessianLag,ipVolume,ipGradVolume,rc[],ub=ub[],lb=lb[],clb=clb,cub=cub,checkindex=1,maxiter=kkk<nadapt-1 ? 40:150,warmstart=kkk,lm=lm,uz=uz[],lz=lz[],tol=0.00001,structjacc=[gvi,gvj]);
+cout << " IPOPT: res =" << res << endl ;
 /*
  * Display the final mesh
  */
@@ -241,5 +247,8 @@ if(kkk<nadapt-1)
 	uz=uz;//dual variables interpolation
 	lz=lz;
 }
+
+// FFCS regression reference value
+regtest=rc[]'*rc[];
 }
 
diff --git a/examples++-load/MUMPS_seq.cpp b/examples++-load/MUMPS_seq.cpp
index d8f2f98..230f565 100644
--- a/examples++-load/MUMPS_seq.cpp
+++ b/examples++-load/MUMPS_seq.cpp
@@ -280,7 +280,6 @@ DefSparseSolverSym<Complex>::SparseMatSolver SparseMatSolverSym_C;
 // the default probleme solver 
 TypeSolveMat::TSolveMat  TypeSolveMatdefaultvalue=TypeSolveMat::defaultvalue;
 
-
 bool SetMUMPS_seq()
 {
     if(verbosity>1)
diff --git a/examples++-load/Makefile.am b/examples++-load/Makefile.am
index 0c65527..5ba5e10 100644
--- a/examples++-load/Makefile.am
+++ b/examples++-load/Makefile.am
@@ -1,9 +1,7 @@
-# $Id$
-
 all-local: @LOAD_COMPILE@
-TESTS=APk-AdaptEpsDeltaPk.edp APk-ExplicitPkTest.edp APk-FreeFemQA.edp APk-MetricPk.edp IPOTest.edp IpOptMinSurf.edp IpoptLap.edp IpoptMinSurfVol.edp IpoptVI.edp IpoptVI2.edp LapDG3.edp LapDG4.edp LapLNewSolver.edp LapMUMPS_seq.edp LapNewSolver.edp LapUmfpack64.edp LaplaceP3.edp LaplaceP4.edp LaplaceRT1.edp Leman-mesh.edp MetricKuate.edp NSP2BRP0.edp PARDISO.edp SuperLU.edp VarIneq2.edp  bilapMorley.edp bmo.edp buildlayermesh.edp checkglumeshcube.edp cmaes-VarIneq.edp cmaes-oven.edp conv [...]
+TESTS=APk-AdaptEpsDeltaPk.edp APk-ExplicitPkTest.edp APk-FreeFemQA.edp APk-MetricPk.edp IPOTest.edp IpOptMinSurf.edp IpoptLap.edp IpoptMinSurfVol.edp IpoptVI.edp IpoptVI2.edp LapDG3.edp LapDG4.edp LapLNewSolver.edp LapMUMPS_seq.edp LapNewSolver.edp LapUmfpack64.edp LaplaceP3.edp LaplaceP4.edp LaplaceRT1.edp Leman-mesh.edp MetricKuate.edp NSP2BRP0.edp PARDISO.edp SuperLU.edp VarIneq2.edp  bilapMorley.edp bmo.edp buildlayermesh.edp checkglumeshcube.edp cmaes-VarIneq.edp cmaes-oven.edp conv [...]
 # all test can fail must but clean ????  FH... 
-XFAILS_TESTS=$(TESTS)
+XFAIL_TESTS=$(TESTS)
 
 LOG_DRIVER=$(SHELL) $(top_srcdir)/test-driver-ff
 TESTS_ENVIRONMENT=TEST_FFPP=$(TEST_FFPP) FLAGS_FFPP=-nw
@@ -69,34 +67,74 @@ LIST_COMPILE=myfunction.$(DYLIB_SUFFIX)  BernadiRaugel.$(DYLIB_SUFFIX) \
 	splitedges.$(DYLIB_SUFFIX) Element_Mixte.$(DYLIB_SUFFIX) \
 	myfunction2.$(DYLIB_SUFFIX) \
 	MetricPk.$(DYLIB_SUFFIX) FreeFemQA.$(DYLIB_SUFFIX) shell.$(DYLIB_SUFFIX) \
-	pipe.$(DYLIB_SUFFIX)  symmetrizeCSR.$(DYLIB_SUFFIX) 
+	@FFCS_DYLIB_pipe@ symmetrizeCSR.$(DYLIB_SUFFIX) 
 
-LIST_COMPILE_PKG= 	tetgen.$(DYLIB_SUFFIX) SuperLu.$(DYLIB_SUFFIX) dfft.$(DYLIB_SUFFIX) \
-	metis.$(DYLIB_SUFFIX) UMFPACK64.$(DYLIB_SUFFIX) NewSolver.$(DYLIB_SUFFIX) \
-	lapack.$(DYLIB_SUFFIX)  fflapack.$(DYLIB_SUFFIX) ffnewuoa.$(DYLIB_SUFFIX) ilut.$(DYLIB_SUFFIX) \
-	freeyams.$(DYLIB_SUFFIX) mmg3d-v4.0.$(DYLIB_SUFFIX) mshmet.$(DYLIB_SUFFIX) \
-	gsl.$(DYLIB_SUFFIX) MUMPS_seq.$(DYLIB_SUFFIX) 	 ff-Ipopt.$(DYLIB_SUFFIX) \
-	ff-NLopt.$(DYLIB_SUFFIX)  ff-cmaes.$(DYLIB_SUFFIX) scotch.$(DYLIB_SUFFIX) \
-	PARDISO.$(DYLIB_SUFFIX)
+# FFCS - some libraries are skipped because the corresponding tool is deactivated.
 
-bin_PROGRAMS=
+LIST_COMPILE_PKG=tetgen.$(DYLIB_SUFFIX) SuperLu.$(DYLIB_SUFFIX) dfft.$(DYLIB_SUFFIX) metis.$(DYLIB_SUFFIX)		\
+	UMFPACK64.$(DYLIB_SUFFIX) NewSolver.$(DYLIB_SUFFIX) @FFCS_DYLIB_lapack@ @FFCS_DYLIB_fflapack@			\
+	ffnewuoa.$(DYLIB_SUFFIX) ilut.$(DYLIB_SUFFIX) @FFCS_DYLIB_yams@ @FFCS_DYLIB_mmg3d@ @FFCS_DYLIB_mshmet@		\
+	@FFCS_DYLIB_gsl@ @FFCS_DYLIB_mumps_seq@ @FFCS_DYLIB_ipopt@ ff-NLopt.$(DYLIB_SUFFIX) ff-cmaes.$(DYLIB_SUFFIX)	\
+	@FFCS_DYLIB_scotch@ @FFCS_DYLIB_pardiso@
 
+bin_PROGRAMS=
 
+# FFCS parallel make: some targets need to be built first, sequentially
 
-load_compile:ff-c++ freefem++.pref WHERE_LIBRARY-download  include  $(LIST_COMPILE)  $(LIST_COMPILE_PKG)
+load_compile: ff-c++ WHERE_LIBRARY-download include.done freefem++.pref
+#
+# max_load
+	-rm "Missing-plugins-$(DYLIB_SUFFIX).log" 2>/dev/null
+	$(MAKE) $(AM_MAKEFLAGS) $(LIST_COMPILE) $(LIST_COMPILE_PKG)
+	@if test -f Missing-plugins-$(DYLIB_SUFFIX).log ; then cat Missing-plugins-$(DYLIB_SUFFIX).log; fi; exit 0 
+	@echo Warning missing plugin: `for i in $(LIST_COMPILE) $(LIST_COMPILE_PKG); do if test ! -s $i ; then j=1; echo "$i," ;fi; done`
 	echo " finish build list $(DYLIB_SUFFIX)"
 
-
-
 .cpp.$(DYLIB_SUFFIX): ff-c++
-	 ./ff-c++ -auto  $< 
+	 ./ff-c++ -auto $< 
+
+# FFCS - 26/10/11 - Unpacking include.tar.gz is very often buggy under Cygwin (softlinks are randomly replaced with empty files
+# without any access right). So just replace the whole thing with a plain copy.
+
+if ENABLE_FFCS
+allheaders=../src/fflib/AddNewFE.h ../src/fflib/AFunction_ext.hpp ../src/fflib/AFunction.hpp ../src/fflib/AnyType.hpp	\
+	../src/fflib/array_init.hpp ../src/fflib/array_resize.hpp ../src/fflib/array_tlp.hpp				\
+	../src/femlib/assertion.hpp ../src/femlib/BamgFreeFem.hpp ../src/Algo/BFGS.hpp ../src/Algo/BrentLS.hpp		\
+	../src/Algo/CG.hpp ../src/femlib/CGNL.hpp ../src/fflib/CodeAlloc.hpp ../config.h ../config-wrapper.h		\
+	../src/Algo/CubicLS.hpp ../src/Algo/defs.hpp ../src/femlib/DOperator.hpp ../src/libMesh/eigenv.h		\
+	../src/fflib/endian.hpp ../src/fflib/environment.hpp ../src/fflib/error.hpp ../src/femlib/fem3.hpp		\
+	../src/femlib/fem.hpp ../src/femlib/FESpace.hpp ../src/femlib/FESpacen.hpp ../src/fflib/ff++.hpp		\
+	../src/fflib/ffstack.hpp ../src/femlib/FQuadTree.hpp ../src/femlib/GenericMesh.hpp				\
+	../src/Graphics/getprog-unix.hpp ../src/Graphics/glrgraph.hpp ../src/femlib/gmres.hpp				\
+	../src/femlib/GQuadTree.hpp ../src/femlib/HashTable.hpp ../src/femlib/HeapSort.hpp ../src/fflib/InitFunct.hpp	\
+	../src/fflib/ffapi.hpp ../src/femlib/Label.hpp ../src/fflib/lex.hpp ../src/fflib/lgfem.hpp			\
+	../src/fflib/lgmesh3.hpp ../src/fflib/lgsolver.hpp ../src/lglib/lg.tab.hpp ../src/femlib/libmesh5.h		\
+	../src/Algo/LineSearch.hpp ../src/femlib/MatriceCreuse.hpp ../src/femlib/MatriceCreuse_tpl.hpp			\
+	../src/femlib/Mesh1dn.hpp ../src/femlib/Mesh2dn.hpp ../src/bamglib/Mesh2.h ../src/femlib/Mesh3dn.hpp		\
+	../src/bamglib/Meshio.h ../src/femlib/MeshPoint.hpp ../src/bamglib/meshtype.h ../src/bamglib/Metric.h		\
+	../src/Graphics/mode_open.hpp ../src/Algo/NewtonRaphson.hpp ../src/Algo/NRJ.hpp ../src/fflib/Operator.hpp	\
+	../src/Algo/Optima.hpp ../src/Algo/Param.hpp ../src/femlib/PkLagrange.hpp ../src/fflib/PlotStream.hpp		\
+	../src/fflib/problem.hpp ../src/femlib/QuadratureFormular.hpp ../src/bamglib/QuadTree.h ../src/femlib/R1.hpp	\
+	../src/bamglib/R2.h ../src/femlib/R2.hpp ../src/femlib/R3.hpp ../src/femlib/RefCounter.hpp			\
+	../src/Graphics/rgraph.hpp ../src/femlib/RNM.hpp ../src/femlib/RNM_opc.hpp ../src/femlib/RNM_op.hpp		\
+	../src/femlib/RNM_tpl.hpp ../src/Algo/RosenBrock.hpp ../src/fflib/Serialize.hpp ../src/bamglib/SetOfE4.h	\
+	../src/fflib/showverb.hpp ../src/femlib/splitsimplex.hpp ../src/fflib/String.hpp				\
+	../src/fflib/strversionnumber.hpp ../src/fflib/throwassert.hpp ../src/femlib/ufunction.hpp			\
+	../src/fflib/versionnumber.hpp
+
+include.done: $(allheaders)
+	mkdir -p include
+	cp $^ include
+	touch $@
 
-include: include.tar.gz
+else
+include.done: include.tar.gz
 	rm -rf include 
 	gunzip -c include.tar.gz| tar xvf -
 	-rm -f include/._*
-	touch include 
+	touch $@
 #	-cp -rf ../download/include/* include/.
+endif
 
 Ref: makeref.edp
 	../src/nw/FreeFem++-nw makeref.edp
@@ -106,8 +144,11 @@ makeref.edp: regtests.m4 ../regtests.m4
 
 all-local: all.edp regtests.edp load_compile
 
-all.edp: Makefile
-	(echo "NoGraphicWindow=true;NoUseOfWait=true;int verbosityy=verbosity;"; \
+# FFCS - 27/2/13 - remove dependency on Makefile to avoid recompiling everything everytime something is changed in the
+# configuration step
+
+all.edp:
+	@(echo "NoGraphicWindow=true;NoUseOfWait=true;int verbosityy=verbosity;"; \
 	for i in *`ls *.edp|grep -v -E '^(all|regtests|makeref|ref)\.edp$$'` ; do  \
 		echo ' cout << "--------- file : '$$i' --------------------------------------------------------" << endl;' ;\
 		echo "verbosity=verbosityy;" ; \
@@ -119,23 +160,26 @@ all.edp: Makefile
 regtests.edp: regtests.m4 ../regtests.m4
 	m4 -DASSERT regtests.m4 > regtests.edp
 
-$(LIST_COMPILE):ff-c++ include Makefile 
+# FFCS - 27/2/13 - remove dependency on Makefile to avoid recompiling everything everytime something is changed in the
+# configuration step
+
+$(LIST_COMPILE):ff-c++ include.done
 
 clean-local:
-	-rm *.o  load.link WHERE_LIBRARY-download ff-get-dep ff-c++ ff-pkg-download \
+	-rm *.o *.$(DYLIB_SUFFIX) load.link WHERE_LIBRARY-download ff-get-dep ff-c++ ff-pkg-download \
 	  $(LIST_COMPILE) $(LIST_COMPILE_PKG)  regtests.edp makeref.edp
-	-rm -rf include
-ff-c++:load.link.in  Makefile load.link WHERE_LIBRARY-download ff-get-dep
+	-rm -rf include include.done
+ff-c++:load.link.in load.link WHERE_LIBRARY-download ff-get-dep ../config.status
 	../config.status  --file=ff-c++:load.link.in
 	chmod a+x ff-c++
-load.link:load.link.in  Makefile
+load.link:load.link.in ../config.status
 	../config.status  --file=load.link:load.link.in
 	chmod a+x load.link
-ff-pkg-download:ff-pkg-download.in Makefile
+ff-pkg-download:ff-pkg-download.in ../config.status
 	../config.status  --file=$@:$@.in
 	chmod a+x $@
 	cp $@ ../download/bin
-ff-get-dep:ff-get-dep.in Makefile
+ff-get-dep:ff-get-dep.in ../config.status
 	../config.status  --file=$@:$@.in
 	chmod a+x $@
 	-if [ -d ../download/bin ] ;then cp $@ ../download/bin; fi
@@ -165,3 +209,8 @@ install-exec-local:: load_compile
 
 
 
+# FFCS: add tags for files that are not specified to automake by a SOURCE directive (this tags file is automatically
+# taken into account by automake when it sees it).
+
+TAGS:
+	etags *.?pp
diff --git a/examples++-load/Makefile.in b/examples++-load/Makefile.in
index ef5f65c..fba62a1 100644
--- a/examples++-load/Makefile.in
+++ b/examples++-load/Makefile.in
@@ -14,8 +14,6 @@
 
 @SET_MAKE@
 
-# $Id$
-
 VPATH = @srcdir@
 am__make_dryrun = \
   { \
@@ -58,7 +56,8 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(top_srcdir)/mkinstalldirs $(top_srcdir)/test-driver README
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/acmacros.m4 \
-	$(top_srcdir)/acoptim.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/acoptim.m4 $(top_srcdir)/acmpi.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -333,11 +332,47 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EIGENOBJ = @EIGENOBJ@
+ENABLE_FFCS = @ENABLE_FFCS@
 EPSTOPDF = @EPSTOPDF@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+FFCS_COMPILE_fflapack = @FFCS_COMPILE_fflapack@
+FFCS_COMPILE_gsl = @FFCS_COMPILE_gsl@
+FFCS_COMPILE_hips = @FFCS_COMPILE_hips@
+FFCS_COMPILE_hypre = @FFCS_COMPILE_hypre@
+FFCS_COMPILE_ipopt = @FFCS_COMPILE_ipopt@
+FFCS_COMPILE_lapack = @FFCS_COMPILE_lapack@
+FFCS_COMPILE_mmg3d = @FFCS_COMPILE_mmg3d@
+FFCS_COMPILE_mshmet = @FFCS_COMPILE_mshmet@
+FFCS_COMPILE_mumps = @FFCS_COMPILE_mumps@
+FFCS_COMPILE_mumps_seq = @FFCS_COMPILE_mumps_seq@
+FFCS_COMPILE_pardiso = @FFCS_COMPILE_pardiso@
+FFCS_COMPILE_parms = @FFCS_COMPILE_parms@
+FFCS_COMPILE_pastix = @FFCS_COMPILE_pastix@
+FFCS_COMPILE_pipe = @FFCS_COMPILE_pipe@
+FFCS_COMPILE_scotch = @FFCS_COMPILE_scotch@
+FFCS_COMPILE_superludist = @FFCS_COMPILE_superludist@
+FFCS_COMPILE_yams = @FFCS_COMPILE_yams@
+FFCS_DYLIB_fflapack = @FFCS_DYLIB_fflapack@
+FFCS_DYLIB_gsl = @FFCS_DYLIB_gsl@
+FFCS_DYLIB_hips = @FFCS_DYLIB_hips@
+FFCS_DYLIB_hypre = @FFCS_DYLIB_hypre@
+FFCS_DYLIB_ipopt = @FFCS_DYLIB_ipopt@
+FFCS_DYLIB_lapack = @FFCS_DYLIB_lapack@
+FFCS_DYLIB_mmg3d = @FFCS_DYLIB_mmg3d@
+FFCS_DYLIB_mshmet = @FFCS_DYLIB_mshmet@
+FFCS_DYLIB_mumps = @FFCS_DYLIB_mumps@
+FFCS_DYLIB_mumps_seq = @FFCS_DYLIB_mumps_seq@
+FFCS_DYLIB_pardiso = @FFCS_DYLIB_pardiso@
+FFCS_DYLIB_parms = @FFCS_DYLIB_parms@
+FFCS_DYLIB_pastix = @FFCS_DYLIB_pastix@
+FFCS_DYLIB_pipe = @FFCS_DYLIB_pipe@
+FFCS_DYLIB_scotch = @FFCS_DYLIB_scotch@
+FFCS_DYLIB_superludist = @FFCS_DYLIB_superludist@
+FFCS_DYLIB_yams = @FFCS_DYLIB_yams@
+FFCS_MAKEFLAGS = @FFCS_MAKEFLAGS@
 FFGLUTNAME = @FFGLUTNAME@
 FFGLUTPROG = @FFGLUTPROG@
 FFLAGS = @FFLAGS@
@@ -524,10 +559,10 @@ TESTS = APk-AdaptEpsDeltaPk.edp APk-ExplicitPkTest.edp \
 	splitedges.edp splitmesh3.edp splitmesh6.edp \
 	test-ElementMixte.edp testFE-P3.edp testFE-P3dc.edp \
 	testFE-P4.edp testFE-P4dc.edp testFE-PkEdge.edp testFE.edp \
-	testFEMorley.edp tetgencube.edp tetgenholeregion.edp \
-	tetgenholeregion_rugby.edp thresholdings.edp ttestio.edp
+	testFEMorley.edp tetgencube.edp tetgenholeregion_rugby.edp \
+	thresholdings.edp ttestio.edp
 # all test can fail must but clean ????  FH... 
-XFAILS_TESTS = $(TESTS)
+XFAIL_TESTS = $(TESTS)
 LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-ff
 TESTS_ENVIRONMENT = TEST_FFPP=$(TEST_FFPP) FLAGS_FFPP=-nw
 EXTRA_DIST = $(TESTS) all.edp makeref.edp regtests.edp \
@@ -591,15 +626,43 @@ LIST_COMPILE = myfunction.$(DYLIB_SUFFIX)  BernadiRaugel.$(DYLIB_SUFFIX) \
 	splitedges.$(DYLIB_SUFFIX) Element_Mixte.$(DYLIB_SUFFIX) \
 	myfunction2.$(DYLIB_SUFFIX) \
 	MetricPk.$(DYLIB_SUFFIX) FreeFemQA.$(DYLIB_SUFFIX) shell.$(DYLIB_SUFFIX) \
-	pipe.$(DYLIB_SUFFIX)  symmetrizeCSR.$(DYLIB_SUFFIX) 
-
-LIST_COMPILE_PKG = tetgen.$(DYLIB_SUFFIX) SuperLu.$(DYLIB_SUFFIX) dfft.$(DYLIB_SUFFIX) \
-	metis.$(DYLIB_SUFFIX) UMFPACK64.$(DYLIB_SUFFIX) NewSolver.$(DYLIB_SUFFIX) \
-	lapack.$(DYLIB_SUFFIX)  fflapack.$(DYLIB_SUFFIX) ffnewuoa.$(DYLIB_SUFFIX) ilut.$(DYLIB_SUFFIX) \
-	freeyams.$(DYLIB_SUFFIX) mmg3d-v4.0.$(DYLIB_SUFFIX) mshmet.$(DYLIB_SUFFIX) \
-	gsl.$(DYLIB_SUFFIX) MUMPS_seq.$(DYLIB_SUFFIX) 	 ff-Ipopt.$(DYLIB_SUFFIX) \
-	ff-NLopt.$(DYLIB_SUFFIX)  ff-cmaes.$(DYLIB_SUFFIX) scotch.$(DYLIB_SUFFIX) \
-	PARDISO.$(DYLIB_SUFFIX)
+	@FFCS_DYLIB_pipe@ symmetrizeCSR.$(DYLIB_SUFFIX) 
+
+
+# FFCS - some libraries are skipped because the corresponding tool is deactivated.
+LIST_COMPILE_PKG = tetgen.$(DYLIB_SUFFIX) SuperLu.$(DYLIB_SUFFIX) dfft.$(DYLIB_SUFFIX) metis.$(DYLIB_SUFFIX)		\
+	UMFPACK64.$(DYLIB_SUFFIX) NewSolver.$(DYLIB_SUFFIX) @FFCS_DYLIB_lapack@ @FFCS_DYLIB_fflapack@			\
+	ffnewuoa.$(DYLIB_SUFFIX) ilut.$(DYLIB_SUFFIX) @FFCS_DYLIB_yams@ @FFCS_DYLIB_mmg3d@ @FFCS_DYLIB_mshmet@		\
+	@FFCS_DYLIB_gsl@ @FFCS_DYLIB_mumps_seq@ @FFCS_DYLIB_ipopt@ ff-NLopt.$(DYLIB_SUFFIX) ff-cmaes.$(DYLIB_SUFFIX)	\
+	@FFCS_DYLIB_scotch@ @FFCS_DYLIB_pardiso@
+
+
+# FFCS - 26/10/11 - Unpacking include.tar.gz is very often buggy under Cygwin (softlinks are randomly replaced with empty files
+# without any access right). So just replace the whole thing with a plain copy.
+ at ENABLE_FFCS_TRUE@allheaders = ../src/fflib/AddNewFE.h ../src/fflib/AFunction_ext.hpp ../src/fflib/AFunction.hpp ../src/fflib/AnyType.hpp	\
+ at ENABLE_FFCS_TRUE@	../src/fflib/array_init.hpp ../src/fflib/array_resize.hpp ../src/fflib/array_tlp.hpp				\
+ at ENABLE_FFCS_TRUE@	../src/femlib/assertion.hpp ../src/femlib/BamgFreeFem.hpp ../src/Algo/BFGS.hpp ../src/Algo/BrentLS.hpp		\
+ at ENABLE_FFCS_TRUE@	../src/Algo/CG.hpp ../src/femlib/CGNL.hpp ../src/fflib/CodeAlloc.hpp ../config.h ../config-wrapper.h		\
+ at ENABLE_FFCS_TRUE@	../src/Algo/CubicLS.hpp ../src/Algo/defs.hpp ../src/femlib/DOperator.hpp ../src/libMesh/eigenv.h		\
+ at ENABLE_FFCS_TRUE@	../src/fflib/endian.hpp ../src/fflib/environment.hpp ../src/fflib/error.hpp ../src/femlib/fem3.hpp		\
+ at ENABLE_FFCS_TRUE@	../src/femlib/fem.hpp ../src/femlib/FESpace.hpp ../src/femlib/FESpacen.hpp ../src/fflib/ff++.hpp		\
+ at ENABLE_FFCS_TRUE@	../src/fflib/ffstack.hpp ../src/femlib/FQuadTree.hpp ../src/femlib/GenericMesh.hpp				\
+ at ENABLE_FFCS_TRUE@	../src/Graphics/getprog-unix.hpp ../src/Graphics/glrgraph.hpp ../src/femlib/gmres.hpp				\
+ at ENABLE_FFCS_TRUE@	../src/femlib/GQuadTree.hpp ../src/femlib/HashTable.hpp ../src/femlib/HeapSort.hpp ../src/fflib/InitFunct.hpp	\
+ at ENABLE_FFCS_TRUE@	../src/fflib/ffapi.hpp ../src/femlib/Label.hpp ../src/fflib/lex.hpp ../src/fflib/lgfem.hpp			\
+ at ENABLE_FFCS_TRUE@	../src/fflib/lgmesh3.hpp ../src/fflib/lgsolver.hpp ../src/lglib/lg.tab.hpp ../src/femlib/libmesh5.h		\
+ at ENABLE_FFCS_TRUE@	../src/Algo/LineSearch.hpp ../src/femlib/MatriceCreuse.hpp ../src/femlib/MatriceCreuse_tpl.hpp			\
+ at ENABLE_FFCS_TRUE@	../src/femlib/Mesh1dn.hpp ../src/femlib/Mesh2dn.hpp ../src/bamglib/Mesh2.h ../src/femlib/Mesh3dn.hpp		\
+ at ENABLE_FFCS_TRUE@	../src/bamglib/Meshio.h ../src/femlib/MeshPoint.hpp ../src/bamglib/meshtype.h ../src/bamglib/Metric.h		\
+ at ENABLE_FFCS_TRUE@	../src/Graphics/mode_open.hpp ../src/Algo/NewtonRaphson.hpp ../src/Algo/NRJ.hpp ../src/fflib/Operator.hpp	\
+ at ENABLE_FFCS_TRUE@	../src/Algo/Optima.hpp ../src/Algo/Param.hpp ../src/femlib/PkLagrange.hpp ../src/fflib/PlotStream.hpp		\
+ at ENABLE_FFCS_TRUE@	../src/fflib/problem.hpp ../src/femlib/QuadratureFormular.hpp ../src/bamglib/QuadTree.h ../src/femlib/R1.hpp	\
+ at ENABLE_FFCS_TRUE@	../src/bamglib/R2.h ../src/femlib/R2.hpp ../src/femlib/R3.hpp ../src/femlib/RefCounter.hpp			\
+ at ENABLE_FFCS_TRUE@	../src/Graphics/rgraph.hpp ../src/femlib/RNM.hpp ../src/femlib/RNM_opc.hpp ../src/femlib/RNM_op.hpp		\
+ at ENABLE_FFCS_TRUE@	../src/femlib/RNM_tpl.hpp ../src/Algo/RosenBrock.hpp ../src/fflib/Serialize.hpp ../src/bamglib/SetOfE4.h	\
+ at ENABLE_FFCS_TRUE@	../src/fflib/showverb.hpp ../src/femlib/splitsimplex.hpp ../src/fflib/String.hpp				\
+ at ENABLE_FFCS_TRUE@	../src/fflib/strversionnumber.hpp ../src/fflib/throwassert.hpp ../src/femlib/ufunction.hpp			\
+ at ENABLE_FFCS_TRUE@	../src/fflib/versionnumber.hpp
 
 all: all-am
 
@@ -1371,13 +1434,6 @@ tetgencube.edp.log: tetgencube.edp
 	--log-file $$b.log --trs-file $$b.trs \
 	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
-tetgenholeregion.edp.log: tetgenholeregion.edp
-	@p='tetgenholeregion.edp'; \
-	b='tetgenholeregion.edp'; \
-	$(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) \
-	"$$tst" $(AM_TESTS_FD_REDIRECT)
 tetgenholeregion_rugby.edp.log: tetgenholeregion_rugby.edp
 	@p='tetgenholeregion_rugby.edp'; \
 	b='tetgenholeregion_rugby.edp'; \
@@ -1566,20 +1622,32 @@ uninstall-am: uninstall-binPROGRAMS
 	mostlyclean-generic pdf pdf-am ps ps-am recheck tags-am \
 	uninstall uninstall-am uninstall-binPROGRAMS
 
-
 all-local: @LOAD_COMPILE@
 
-load_compile:ff-c++ freefem++.pref WHERE_LIBRARY-download  include  $(LIST_COMPILE)  $(LIST_COMPILE_PKG)
+# FFCS parallel make: some targets need to be built first, sequentially
+
+load_compile: ff-c++ WHERE_LIBRARY-download include.done freefem++.pref
+#
+# max_load
+	-rm "Missing-plugins-$(DYLIB_SUFFIX).log" 2>/dev/null
+	$(MAKE) $(AM_MAKEFLAGS) $(LIST_COMPILE) $(LIST_COMPILE_PKG)
+	@if test -f Missing-plugins-$(DYLIB_SUFFIX).log ; then cat Missing-plugins-$(DYLIB_SUFFIX).log; fi; exit 0 
+	@echo Warning missing plugin: `for i in $(LIST_COMPILE) $(LIST_COMPILE_PKG); do if test ! -s $i ; then j=1; echo "$i," ;fi; done`
 	echo " finish build list $(DYLIB_SUFFIX)"
 
 .cpp.$(DYLIB_SUFFIX): ff-c++
-	 ./ff-c++ -auto  $< 
-
-include: include.tar.gz
-	rm -rf include 
-	gunzip -c include.tar.gz| tar xvf -
-	-rm -f include/._*
-	touch include 
+	 ./ff-c++ -auto $< 
+
+ at ENABLE_FFCS_TRUE@include.done: $(allheaders)
+ at ENABLE_FFCS_TRUE@	mkdir -p include
+ at ENABLE_FFCS_TRUE@	cp $^ include
+ at ENABLE_FFCS_TRUE@	touch $@
+
+ at ENABLE_FFCS_FALSE@include.done: include.tar.gz
+ at ENABLE_FFCS_FALSE@	rm -rf include 
+ at ENABLE_FFCS_FALSE@	gunzip -c include.tar.gz| tar xvf -
+ at ENABLE_FFCS_FALSE@	-rm -f include/._*
+ at ENABLE_FFCS_FALSE@	touch $@
 #	-cp -rf ../download/include/* include/.
 
 Ref: makeref.edp
@@ -1590,8 +1658,11 @@ makeref.edp: regtests.m4 ../regtests.m4
 
 all-local: all.edp regtests.edp load_compile
 
-all.edp: Makefile
-	(echo "NoGraphicWindow=true;NoUseOfWait=true;int verbosityy=verbosity;"; \
+# FFCS - 27/2/13 - remove dependency on Makefile to avoid recompiling everything everytime something is changed in the
+# configuration step
+
+all.edp:
+	@(echo "NoGraphicWindow=true;NoUseOfWait=true;int verbosityy=verbosity;"; \
 	for i in *`ls *.edp|grep -v -E '^(all|regtests|makeref|ref)\.edp$$'` ; do  \
 		echo ' cout << "--------- file : '$$i' --------------------------------------------------------" << endl;' ;\
 		echo "verbosity=verbosityy;" ; \
@@ -1603,23 +1674,26 @@ all.edp: Makefile
 regtests.edp: regtests.m4 ../regtests.m4
 	m4 -DASSERT regtests.m4 > regtests.edp
 
-$(LIST_COMPILE):ff-c++ include Makefile 
+# FFCS - 27/2/13 - remove dependency on Makefile to avoid recompiling everything everytime something is changed in the
+# configuration step
+
+$(LIST_COMPILE):ff-c++ include.done
 
 clean-local:
-	-rm *.o  load.link WHERE_LIBRARY-download ff-get-dep ff-c++ ff-pkg-download \
+	-rm *.o *.$(DYLIB_SUFFIX) load.link WHERE_LIBRARY-download ff-get-dep ff-c++ ff-pkg-download \
 	  $(LIST_COMPILE) $(LIST_COMPILE_PKG)  regtests.edp makeref.edp
-	-rm -rf include
-ff-c++:load.link.in  Makefile load.link WHERE_LIBRARY-download ff-get-dep
+	-rm -rf include include.done
+ff-c++:load.link.in load.link WHERE_LIBRARY-download ff-get-dep ../config.status
 	../config.status  --file=ff-c++:load.link.in
 	chmod a+x ff-c++
-load.link:load.link.in  Makefile
+load.link:load.link.in ../config.status
 	../config.status  --file=load.link:load.link.in
 	chmod a+x load.link
-ff-pkg-download:ff-pkg-download.in Makefile
+ff-pkg-download:ff-pkg-download.in ../config.status
 	../config.status  --file=$@:$@.in
 	chmod a+x $@
 	cp $@ ../download/bin
-ff-get-dep:ff-get-dep.in Makefile
+ff-get-dep:ff-get-dep.in ../config.status
 	../config.status  --file=$@:$@.in
 	chmod a+x $@
 	-if [ -d ../download/bin ] ;then cp $@ ../download/bin; fi
@@ -1646,6 +1720,12 @@ install-exec-local:: load_compile
 	-for i in $(LIST_COMPILE_PKG); do \
 	 if [ -f $$i ] ; then 	$(INSTALL)  -m 555 $$i $(DESTDIR)$(ff_prefix_dir)/lib; fi; done
 
+# FFCS: add tags for files that are not specified to automake by a SOURCE directive (this tags file is automatically
+# taken into account by automake when it sees it).
+
+TAGS:
+	etags *.?pp
+
 # 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.
 .NOEXPORT:
diff --git a/examples++-load/MetricKuate.edp b/examples++-load/MetricKuate.edp
index 0d7a806..be77f41 100644
--- a/examples++-load/MetricKuate.edp
+++ b/examples++-load/MetricKuate.edp
@@ -47,6 +47,8 @@ for(int i=1;i<4;i++)
   }
    Th=square(5,5,[(x-0.5)*2,(y-0.5)*2]);
 
+// FFCS - regression tests
+real regtest;
 
  real cerr= 0.005*(0.000961606/0.000582183)^0.66; 
   for(int i=1;i<4;i++)
@@ -66,5 +68,6 @@ for(int i=1;i<4;i++)
     plot(leh,fill=1,wait=1,viso=viso,value=1,ps="leh2.eps");
     cout << i << " .... " << eh[].min << " "<< eh[].max << " "<< eh[].sum/eh[].n << " " 
          << int2d(Th)(eh)/Th.area << " " << Th.nt << " " << Th.nv << endl;
+    regtest=eh[]'*eh[];//'
   }
 
diff --git a/examples++-load/NewSolver.cpp b/examples++-load/NewSolver.cpp
index e48cbe0..c228364 100644
--- a/examples++-load/NewSolver.cpp
+++ b/examples++-load/NewSolver.cpp
@@ -1,5 +1,5 @@
 //  file to add UMFPACK solver with dynamic load.
-//ff-c++-LIBRARY-dep:  amd  umfpack blas 
+//ff-c++-LIBRARY-dep: umfpack amd blas 
 //ff-c++-cpp-dep: 
 
 #include  <iostream>
diff --git a/examples++-load/PARDISO.edp b/examples++-load/PARDISO.edp
index a4061f1..be450b8 100755
--- a/examples++-load/PARDISO.edp
+++ b/examples++-load/PARDISO.edp
@@ -1,4 +1,4 @@
-//load "PARDISO" 
+load "PARDISO" 
 load "symmetrizeCSR"
 load "shell"
 //if(ompgetnumthreads() < 2 & getenv("OMP_NUM_THREAD") =="" ) 
diff --git a/examples++-load/SuperLU.edp b/examples++-load/SuperLU.edp
index 2fa6d90..9f4cee0 100644
--- a/examples++-load/SuperLU.edp
+++ b/examples++-load/SuperLU.edp
@@ -23,6 +23,8 @@ problem laplace(uh,vh,solver=sparsesolver,tgv=1e5) =                    //  defi
   plot(uh,ps="Laplace.eps",value=true); 
 }
 
+// FFCS: need to declare it globally to print out its value for regression tests
+complex[int] lastx(4);
 
 for(int i=0;i<3;++i)
 {
@@ -57,6 +59,7 @@ for(int i=0;i<3;++i)
     set(A,solver=sparsesolver);
     x = A^-1*b;
     cout << "x=" << endl; cout << x << endl;
+    lastx=x;
   }
   if(i==0)defaulttoGMRES();
   if(i==1)defaultsolver();
diff --git a/examples++-load/SuperLu.cpp b/examples++-load/SuperLu.cpp
index 8f98b64..aee411d 100644
--- a/examples++-load/SuperLu.cpp
+++ b/examples++-load/SuperLu.cpp
@@ -529,6 +529,7 @@ public:
     xarow=AA.lg;
 
     /* FreeFem++ use Morse Format */ 
+    // FFCS - "this->" required by g++ 4.7
     this->CompRow_to_CompCol(m, n, nnz, arow, asubrow, xarow, 
 		       &a, &asub, &xa);
 
@@ -578,6 +579,7 @@ public:
 
     Dtype_t R_SLU = SuperLUDriver<R>::R_SLU_T(); 
 
+    // FFCS - "this->" required by g++ 4.7
     this->Create_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, R_SLU, SLU_GE);
   
     this->Create_Dense_Matrix(&B, m, 0, (R*) 0, m, SLU_DN, R_SLU, SLU_GE);
@@ -663,6 +665,7 @@ public:
 	  KN_2Ptr<R> xx(x),bb(b);
 	  // cout << " xx #### " << xx.c.N() << " "<< xx.ca.N() <<  " " << xx.ca.step << endl;
 	  //cout << " bb #### " << bb.c.N() << " "<< bb.ca.N() << " " << bb.ca.step <<endl;
+	  // FFCS - "this->" required by g++ 4.7
 	  this->Create_Dense_Matrix(&B, m, 1, bb, m, SLU_DN, R_SLU, SLU_GE);
 	  this->Create_Dense_Matrix(&X, m, 1, xx, m, SLU_DN, R_SLU, SLU_GE);
 	  
@@ -759,7 +762,6 @@ DefSparseSolver<Complex>::SparseMatSolver SparseMatSolver_C;
 // the default probleme solver 
 TypeSolveMat::TSolveMat  TypeSolveMatdefaultvalue=TypeSolveMat::defaultvalue;
 
-
 bool SetSuperLU()
 {
     if(verbosity>1)
diff --git a/examples++-load/UMFPACK64.cpp b/examples++-load/UMFPACK64.cpp
index 67ec1e1..2ef20ac 100644
--- a/examples++-load/UMFPACK64.cpp
+++ b/examples++-load/UMFPACK64.cpp
@@ -13,6 +13,7 @@ using namespace std;
 
 #include "MatriceCreuse_tpl.hpp"
 
+#include <wchar.h>
  
 #ifdef HAVE_LIBUMFPACK
 extern "C" {
@@ -85,7 +86,12 @@ public:
       cout << "\n";      
     }
     //  convert   array in long ...
+    // FFCS: Win64 long pb
+#ifdef WIN64
+    KN<long long> Alg(n+1),Acl(A.nbcoef);
+#else
     KN<long> Alg(n+1),Acl(A.nbcoef);
+#endif
     for(int i=0;i<=n;++i)
       Alg[i]=A.lg[i];
 
@@ -133,7 +139,12 @@ public:
     
      umfpack_dl_defaults (Control) ;
     //  convert   array in long ...
+     // FFCS: Win64 long pb
+#ifdef WIN64
+    KN<long long> Alg(n+1),Acl(A.nbcoef);
+#else
     KN<long> Alg(n+1),Acl(A.nbcoef);
+#endif
     for(int i=0;i<=n;++i)
       Alg[i]=A.lg[i];
 
@@ -224,7 +235,13 @@ public:
     }
 
     //  convert   array in long ...
+
+    // FFCS: need a longlong on Win64 because longs are 32 bits
+#ifdef WIN64
+    KN<long long> Alg(n+1),Acl(A.nbcoef);
+#else
     KN<long> Alg(n+1),Acl(A.nbcoef);
+#endif
     for(int i=0;i<=n;++i)
       Alg[i]=A.lg[i];
 
@@ -276,7 +293,13 @@ public:
      // change UMFPACK_At to UMFPACK_Aat in complex  oct 2005
 
     //  convert   array in long ...
+     // FFCS: Win64 long pb
+#ifdef WIN64
+    KN<long long> Alg(n+1),Acl(A.nbcoef);
+#else
     KN<long> Alg(n+1),Acl(A.nbcoef);
+#endif
+
     for(int i=0;i<=n;++i)
       Alg[i]=A.lg[i];
 
@@ -346,7 +369,6 @@ DefSparseSolver<Complex>::SparseMatSolver SparseMatSolver_C;
 // the default probleme solver 
 TypeSolveMat::TSolveMat  TypeSolveMatdefaultvalue=TypeSolveMat::defaultvalue;
 
-
 bool SetUMFPACK64()
 {
     if(verbosity>1)
diff --git a/examples++-load/VTK_writer.cpp b/examples++-load/VTK_writer.cpp
index e2e1ba3..dfced4e 100644
--- a/examples++-load/VTK_writer.cpp
+++ b/examples++-load/VTK_writer.cpp
@@ -1,336 +1,339 @@
-// -*- Mode : c++ -*-
-//
-// SUMMARY  : 
-// USAGE    :        
-// ORG      : 
-// AUTHOR   : Cedric Ody (not an expert in c++)
-// E-MAIL   : cedric.listes at gmail.com
-// from the work of  Sala Lorenzo (Dxwriter)
-
-#include "mode_open.hpp"
-#include <iostream>
-#include <cfloat>
-#include <cmath>
-#include <iterator>
-using namespace std;
-#include "ff++.hpp"
-using namespace Fem2D;
-
-class VtkWriter 
-{
- struct tsinfo
- {
-  int imesh;//!<index of the mesh
-  std::string name;
-  std::vector<double> vecistant;
- };
- 
-private:
- std::vector<Fem2D::Mesh*> _vecmesh;
- //std::vector<tsinfo> _vecofts;
- std::string _nameoffile;
-
- /*! This string contains the name of data file with \\ where there's a \ in the path*/
- std::string _nameofdatafile;
-
- //!files containing the data and the timeseries
- std::ofstream _ofdata;
-
-public:
- VtkWriter() { std::cout << "Constructor of VtkWriter" << endl;  }
- void openfiles(const std::string& s)
-  {
-   _nameoffile=s;
-   std::string tmp=s+".vtu";
-   std::cout<<tmp<<" ";
-   _ofdata.open(tmp.c_str(), std::ios_base::out);
-   _nameofdatafile="";
-   for(int i=0;i<tmp.length();++i)
-    {
-     if(tmp.at(i)=='\\')
-      _nameofdatafile.append(1,'\\');
-     _nameofdatafile.append(1,tmp.at(i));
-    }
-  }
-
- void addmesh(Fem2D::Mesh* mesh)
-  {
-   Fem2D::Mesh& Th(*mesh);
-   _vecmesh.push_back(mesh);
-   _ofdata.flags(std::ios_base::scientific);
-   _ofdata.precision(15);
-
-   _ofdata << "<?xml version=\"1.0\"?>" << std::endl;
-   _ofdata << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">" ;
-   _ofdata << std::endl;
-   _ofdata << "<UnstructuredGrid>" ; _ofdata << std::endl;
-   _ofdata << "<Piece NumberOfPoints=\"" << Th.nv << "\" NumberOfCells=\"" << Th.nt << "\">"; 
-   _ofdata << std::endl;
-   _ofdata << "<Points>" << std::endl;
-   _ofdata << "<DataArray type=\"Float32\" Name=\"Position\" NumberOfComponents=\"3\" format=\"ascii\">"; 
-   _ofdata << std::endl;
-   for(int k=0;k<Th.nv;++k) _ofdata << Th(k).x<<" "<<Th(k).y<< " " << 0.0 << std::endl;
-   _ofdata << "</DataArray>" << std::endl;
-   _ofdata << "</Points>" << std::endl;
-   _ofdata << "<Cells>" << std::endl;
-   _ofdata << "<DataArray type=\"Int32\" Name=\"connectivity\" NumberOfComponents=\"1\" format=\"ascii\">"; 
-   _ofdata << std::endl;
-   for(int i=0;i<Th.nt;++i)
-    for (int j=0; j <3; j++) _ofdata << Th(i,j) << " " ;
-   _ofdata << std::endl;
-   _ofdata << "</DataArray>" << std::endl;
-   _ofdata << "<DataArray type=\"Int32\" Name=\"offsets\" NumberOfComponents=\"1\" format=\"ascii\">"; 
-   _ofdata << std::endl;	
-   for(int i=0;i<Th.nt;++i)  _ofdata << 3+3*(i) << " ";
-   _ofdata << std::endl;
-   _ofdata << "</DataArray>" << std::endl;
-   _ofdata << "<DataArray type=\"UInt8\" Name=\"types\" NumberOfComponents=\"1\" format=\"ascii\">" ; 
-   _ofdata<< std::endl;	
-   for(int i=0;i<Th.nt;++i)  _ofdata << 5 << " ";
-   _ofdata << std::endl;
-   _ofdata << "</DataArray>" << std::endl;
-   _ofdata << "</Cells>" << std::endl; 
-   _ofdata << "<PointData >" << endl; 
-  }
- 
- double checkprecision(double val)
-  {
-   double tmp;
-   if ( val >= 0. ) tmp=max(0.,val);
-   if ( val <  0. ) tmp=min(0.,val);
-   return tmp;
-  }
-
- /*!Add a field*/
- void addscalar(const string& nameoffield, Fem2D::Mesh* mesh, const KN<double>&val)
-  {
-   _ofdata.flags(std::ios_base::scientific);
-   _ofdata.precision(15);
-
-   _ofdata << "<DataArray type=\"Float32\" Name=\"";
-   _ofdata << nameoffield<<"\" NumberOfComponents=\"1\" format=\"ascii\">";
-   _ofdata << std::endl;
-   for(int i=0;i<val.size();++i) _ofdata<<checkprecision(val[i])<<std::endl;
-   _ofdata << "</DataArray>" << std::endl;
-   
-   _ofdata.flush();
-  }
- 
-  /*!Add a field*/
- void addvector(const string& nameoffield, Fem2D::Mesh* mesh, const KN<double>&val, const KN<double>&val2)
-  {
-   _ofdata.flags(std::ios_base::scientific);
-   _ofdata.precision(15);
-
-   _ofdata << "<DataArray type=\"Float32\" Name=\"";
-   _ofdata << nameoffield<<"\" NumberOfComponents=\"3\" format=\"ascii\">";
-   _ofdata << std::endl;
-   for(int i=0;i<val.size();++i) _ofdata<<checkprecision(val[i])<< " " << checkprecision(val2[i]) << " " << 0.0 << std::endl;
-   _ofdata << "</DataArray>" << std::endl;
-   _ofdata.flush();
-  }
-
- /*!Get the mesh associated with the series nameofts*/
- Fem2D::Mesh* getmeshts(const string& nameofts)
-  {
-   return _vecmesh[0];
-  }
- 
- void init()
-  {
-   new(this)VtkWriter(); 
-  }
- 
- void destroy() 
-  {
-   if(_ofdata.is_open())
-    {
-     _ofdata << "</PointData>" << endl;	
-     _ofdata << "<CellData>" << endl; 	
-     _ofdata << "</CellData>" << endl; 
-     _ofdata << "</Piece>" << endl;
-     _ofdata << "</UnstructuredGrid>" << endl;
-     _ofdata << "</VTKFile>" << endl;
-     _ofdata.close(); 		
-    }
-  } 
-}; //End of class
-
-class Vtkwritesol_Op : public E_F0mps 
-{
-public:
- typedef long  Result;
- Expression edx;
- Expression ename;//!<name of time series or field
- Expression et;//!<time
- long what; // 1 scalar, 2 vector, 3 symtensor
- long nbfloat; // 1 scalar, n vector (3D), n symtensor(3D)
- Expression evct,evct2;
- 
-public:
- Vtkwritesol_Op(const basicAC_F0 &  args) :  what(0), nbfloat(0)
-  {
-   evct=0;
-   evct2=0;
-   int nbofsol;
-   int ddim=2;
-   //There's no named parameter
-   args.SetNameParam();
-   if(args.size()!=3)
-    {
-     CompileError("Vtkwritesol accepts only 4 parameters");
-    }
-   if (BCastTo<VtkWriter *>(args[0])) edx = CastTo<VtkWriter *>(args[0]);
-   if (BCastTo<string *>(args[1])) ename = CastTo<string *>(args[1]);
-   
-   if ( args[2].left()==atype<double>() )
-    {
-     what=1;
-     nbfloat=1;
-     evct=to<double>( args[2] );
-    }
-   else if ( args[2].left()==atype<double *>() )
-    {
-     what=1;
-     nbfloat=1;
-     evct=to<double>( args[2] );
-    }
-   else if ( BCastTo<pfer>(args[2]) )
-    {
-     what=1;
-     nbfloat=1;
-     evct=to<double>( args[2] );
-    }
-   else if ( args[2].left()==atype<E_Array>() )
-    {
-     std::cout << "Until now only scalar solution" << std::endl;
-     
-     int i=2;
-     const E_Array * a0  = dynamic_cast<const E_Array *>( args[i].LeftValue() );
-         
-     if( a0->size() == ddim){
-      // vector solution
-      what=2;
-      nbfloat=a0->size();
-      evct = to<double>( (*a0)[0]);
-      evct2 = to<double>( (*a0)[1]);
-      
-     }
-      cout << "Passed Until now only scalar solution" << std::endl;
-    }
-   else 
-    {
-     CompileError("savesol in 2D: Sorry no way to save this kind of data");
-    }
-   
-  }
- // all type
- static ArrayOfaType  typeargs() { return  ArrayOfaType(atype<VtkWriter *>(), atype<string *>(), true); }
- static  E_F0 * f(const basicAC_F0 & args) { return new Vtkwritesol_Op(args);} 
- AnyType operator()(Stack stack)  const ;
-}; // end of class
-
-
-AnyType Vtkwritesol_Op::operator()(Stack stack)  const 
-{ 
- MeshPoint *mp(MeshPointStack(stack)) , mps=*mp;
- VtkWriter &dx=*(GetAny<VtkWriter *>((*edx)(stack)));
- string &name=*(GetAny<string *>((*ename)(stack)));
- //double t=GetAny<double>((*et)(stack));
- Mesh &Th=*(dx.getmeshts(name));
- 
- int nt = Th.nt;
- int nv = Th.nv;
- 
- int nbsol=nv;
- long longdefault;
- 
- KN<double> valsol(nbsol);
- valsol=0.;
- KN<int> takemesh(nbsol);
- takemesh=0;
- MeshPoint *mp3(MeshPointStack(stack));
- for (int it=0;it<nt;it++)
-  {
-  for(int iv=0;iv<3;iv++)
-   {
-    int i=Th(it,iv);
-    mp3->setP(&Th,it,iv);					
-    valsol[i] = valsol[i] + GetAny< double >((*evct)(stack));			
-    ++takemesh[i];
-   }
-  }
- for(int i=0; i<nbsol; i++)
-  {
-   valsol[i] /= takemesh[i]; 
-  }
- 
- //Writes valsol on the file file
- if (what==1) dx.addscalar(name,&Th,valsol);
-
- if (what == 2)
-  {
-   KN<double> valsol2(nbsol);
-   valsol2=0.;
-   KN<int> takemesh(nbsol);
-   takemesh=0;
-   MeshPoint *mp3(MeshPointStack(stack));
-   for (int it=0;it<nt;it++)
-    {
-     for(int iv=0;iv<3;iv++)
-      {
-       int i=Th(it,iv);
-       mp3->setP(&Th,it,iv);					
-       valsol2[i] = valsol2[i] + GetAny< double >((*evct2)(stack));			
-       ++takemesh[i];
-      }
-    }
-   for(int i=0; i<nbsol; i++)
-    {
-     valsol2[i] /= takemesh[i]; 
-    }
-   
-   //Writes valsol on the file file
-   dx.addvector(name,&Th,valsol,valsol2);
-   
-  }
-
- return longdefault;
-
-}
-
-
-
-// le vrai constructeur est la
-VtkWriter* init_VtkWriter(VtkWriter * const &a, string * const & s)
-{
- std::cout << "start init_VtkWriter" << std::endl;
- a->init();
- a->openfiles(*s);
- std::cout << "end init_VtkWriter" << std::endl;
- return a;
-} 
-
-void* call_addmesh( VtkWriter * const & mt, Fem2D::Mesh* const & pTh) { mt->addmesh(pTh);}
- 
-//   Add the function name to the freefem++ table 
-class Init 
-{ 
-public:
- Init();
-};
-
-LOADINIT(Init);
-Init::Init()
-{
- 
- Dcl_Type<VtkWriter*>(InitP<VtkWriter>,Destroy<VtkWriter>); 
-// declare deux nouveau type pour freefem++  un pointeur et 
-
- zzzfff->Add("VtkWriter",atype<VtkWriter*>()); // ajoute le type myType a freefem++ 
- // constructeur  d'un type myType  dans freefem 
- TheOperators->Add("<-", new OneOperator2_<VtkWriter*, VtkWriter* ,string*>(&init_VtkWriter));
- Global.Add("Vtkaddmesh","(",new OneOperator2_<void *, VtkWriter*, Fem2D::Mesh*>(call_addmesh)); 
- Global.Add("Vtkaddscalar","(",new OneOperatorCode< Vtkwritesol_Op> );
- 
-}
+// -*- Mode : c++ -*-
+//
+// SUMMARY  : 
+// USAGE    :        
+// ORG      : 
+// AUTHOR   : Cedric Ody (not an expert in c++)
+// E-MAIL   : cedric.listes at gmail.com
+// from the work of  Sala Lorenzo (Dxwriter)
+
+#include "mode_open.hpp"
+#include <iostream>
+#include <cfloat>
+#include <cmath>
+#include <iterator>
+using namespace std;
+#include "ff++.hpp"
+using namespace Fem2D;
+
+class VtkWriter 
+{
+ struct tsinfo
+ {
+  int imesh;//!<index of the mesh
+  std::string name;
+  std::vector<double> vecistant;
+ };
+ 
+private:
+ std::vector<Fem2D::Mesh*> _vecmesh;
+ //std::vector<tsinfo> _vecofts;
+ std::string _nameoffile;
+
+ /*! This string contains the name of data file with \\ where there's a \ in the path*/
+ std::string _nameofdatafile;
+
+ //!files containing the data and the timeseries
+ std::ofstream _ofdata;
+
+public:
+ VtkWriter() { std::cout << "Constructor of VtkWriter" << endl;  }
+ void openfiles(const std::string& s)
+  {
+   _nameoffile=s;
+   std::string tmp=s+".vtu";
+   std::cout<<tmp<<" ";
+   _ofdata.open(tmp.c_str(), std::ios_base::out);
+   _nameofdatafile="";
+   for(int i=0;i<tmp.length();++i)
+    {
+     if(tmp.at(i)=='\\')
+      _nameofdatafile.append(1,'\\');
+     _nameofdatafile.append(1,tmp.at(i));
+    }
+  }
+
+ void addmesh(Fem2D::Mesh* mesh)
+  {
+   Fem2D::Mesh& Th(*mesh);
+   _vecmesh.push_back(mesh);
+   _ofdata.flags(std::ios_base::scientific);
+   _ofdata.precision(15);
+
+   _ofdata << "<?xml version=\"1.0\"?>" << std::endl;
+   _ofdata << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">" ;
+   _ofdata << std::endl;
+   _ofdata << "<UnstructuredGrid>" ; _ofdata << std::endl;
+   _ofdata << "<Piece NumberOfPoints=\"" << Th.nv << "\" NumberOfCells=\"" << Th.nt << "\">"; 
+   _ofdata << std::endl;
+   _ofdata << "<Points>" << std::endl;
+   _ofdata << "<DataArray type=\"Float32\" Name=\"Position\" NumberOfComponents=\"3\" format=\"ascii\">"; 
+   _ofdata << std::endl;
+   for(int k=0;k<Th.nv;++k) _ofdata << Th(k).x<<" "<<Th(k).y<< " " << 0.0 << std::endl;
+   _ofdata << "</DataArray>" << std::endl;
+   _ofdata << "</Points>" << std::endl;
+   _ofdata << "<Cells>" << std::endl;
+   _ofdata << "<DataArray type=\"Int32\" Name=\"connectivity\" NumberOfComponents=\"1\" format=\"ascii\">"; 
+   _ofdata << std::endl;
+   for(int i=0;i<Th.nt;++i)
+    for (int j=0; j <3; j++) _ofdata << Th(i,j) << " " ;
+   _ofdata << std::endl;
+   _ofdata << "</DataArray>" << std::endl;
+   _ofdata << "<DataArray type=\"Int32\" Name=\"offsets\" NumberOfComponents=\"1\" format=\"ascii\">"; 
+   _ofdata << std::endl;	
+   for(int i=0;i<Th.nt;++i)  _ofdata << 3+3*(i) << " ";
+   _ofdata << std::endl;
+   _ofdata << "</DataArray>" << std::endl;
+   _ofdata << "<DataArray type=\"UInt8\" Name=\"types\" NumberOfComponents=\"1\" format=\"ascii\">" ; 
+   _ofdata<< std::endl;	
+   for(int i=0;i<Th.nt;++i)  _ofdata << 5 << " ";
+   _ofdata << std::endl;
+   _ofdata << "</DataArray>" << std::endl;
+   _ofdata << "</Cells>" << std::endl; 
+   _ofdata << "<PointData >" << endl; 
+  }
+ 
+ double checkprecision(double val)
+  {
+   double tmp;
+   if ( val >= 0. ) tmp=max(0.,val);
+   if ( val <  0. ) tmp=min(0.,val);
+   return tmp;
+  }
+
+ /*!Add a field*/
+ void addscalar(const string& nameoffield, Fem2D::Mesh* mesh, const KN<double>&val)
+  {
+   _ofdata.flags(std::ios_base::scientific);
+   _ofdata.precision(15);
+
+   _ofdata << "<DataArray type=\"Float32\" Name=\"";
+   _ofdata << nameoffield<<"\" NumberOfComponents=\"1\" format=\"ascii\">";
+   _ofdata << std::endl;
+   for(int i=0;i<val.size();++i) _ofdata<<checkprecision(val[i])<<std::endl;
+   _ofdata << "</DataArray>" << std::endl;
+   
+   _ofdata.flush();
+  }
+ 
+  /*!Add a field*/
+ void addvector(const string& nameoffield, Fem2D::Mesh* mesh, const KN<double>&val, const KN<double>&val2)
+  {
+   _ofdata.flags(std::ios_base::scientific);
+   _ofdata.precision(15);
+
+   _ofdata << "<DataArray type=\"Float32\" Name=\"";
+   _ofdata << nameoffield<<"\" NumberOfComponents=\"3\" format=\"ascii\">";
+   _ofdata << std::endl;
+   for(int i=0;i<val.size();++i) _ofdata<<checkprecision(val[i])<< " " << checkprecision(val2[i]) << " " << 0.0 << std::endl;
+   _ofdata << "</DataArray>" << std::endl;
+   _ofdata.flush();
+  }
+
+ /*!Get the mesh associated with the series nameofts*/
+ Fem2D::Mesh* getmeshts(const string& nameofts)
+  {
+   return _vecmesh[0];
+  }
+ 
+ void init()
+  {
+   new(this)VtkWriter(); 
+  }
+ 
+ void destroy() 
+  {
+   if(_ofdata.is_open())
+    {
+     _ofdata << "</PointData>" << endl;	
+     _ofdata << "<CellData>" << endl; 	
+     _ofdata << "</CellData>" << endl; 
+     _ofdata << "</Piece>" << endl;
+     _ofdata << "</UnstructuredGrid>" << endl;
+     _ofdata << "</VTKFile>" << endl;
+     _ofdata.close(); 		
+    }
+  } 
+}; //End of class
+
+class Vtkwritesol_Op : public E_F0mps 
+{
+public:
+ typedef long  Result;
+ Expression edx;
+ Expression ename;//!<name of time series or field
+ Expression et;//!<time
+ long what; // 1 scalar, 2 vector, 3 symtensor
+ long nbfloat; // 1 scalar, n vector (3D), n symtensor(3D)
+ Expression evct,evct2;
+ 
+public:
+ Vtkwritesol_Op(const basicAC_F0 &  args) :  what(0), nbfloat(0)
+  {
+   evct=0;
+   evct2=0;
+   int nbofsol;
+   int ddim=2;
+   //There's no named parameter
+   args.SetNameParam();
+   if(args.size()!=3)
+    {
+     CompileError("Vtkwritesol accepts only 4 parameters");
+    }
+   if (BCastTo<VtkWriter *>(args[0])) edx = CastTo<VtkWriter *>(args[0]);
+   if (BCastTo<string *>(args[1])) ename = CastTo<string *>(args[1]);
+   
+   if ( args[2].left()==atype<double>() )
+    {
+     what=1;
+     nbfloat=1;
+     evct=to<double>( args[2] );
+    }
+   else if ( args[2].left()==atype<double *>() )
+    {
+     what=1;
+     nbfloat=1;
+     evct=to<double>( args[2] );
+    }
+   else if ( BCastTo<pfer>(args[2]) )
+    {
+     what=1;
+     nbfloat=1;
+     evct=to<double>( args[2] );
+    }
+   else if ( args[2].left()==atype<E_Array>() )
+    {
+     std::cout << "Until now only scalar solution" << std::endl;
+     
+     int i=2;
+     const E_Array * a0  = dynamic_cast<const E_Array *>( args[i].LeftValue() );
+         
+     if( a0->size() == ddim){
+      // vector solution
+      what=2;
+      nbfloat=a0->size();
+      evct = to<double>( (*a0)[0]);
+      evct2 = to<double>( (*a0)[1]);
+      
+     }
+      cout << "Passed Until now only scalar solution" << std::endl;
+    }
+   else 
+    {
+     CompileError("savesol in 2D: Sorry no way to save this kind of data");
+    }
+   
+  }
+ // all type
+ static ArrayOfaType  typeargs() { return  ArrayOfaType(atype<VtkWriter *>(), atype<string *>(), true); }
+ static  E_F0 * f(const basicAC_F0 & args) { return new Vtkwritesol_Op(args);} 
+ AnyType operator()(Stack stack)  const ;
+}; // end of class
+
+
+AnyType Vtkwritesol_Op::operator()(Stack stack)  const 
+{ 
+ MeshPoint *mp(MeshPointStack(stack)) , mps=*mp;
+ VtkWriter &dx=*(GetAny<VtkWriter *>((*edx)(stack)));
+ string &name=*(GetAny<string *>((*ename)(stack)));
+ //double t=GetAny<double>((*et)(stack));
+ Mesh &Th=*(dx.getmeshts(name));
+ 
+ int nt = Th.nt;
+ int nv = Th.nv;
+ 
+ int nbsol=nv;
+ long longdefault;
+ 
+ KN<double> valsol(nbsol);
+ valsol=0.;
+ KN<int> takemesh(nbsol);
+ takemesh=0;
+ MeshPoint *mp3(MeshPointStack(stack));
+ for (int it=0;it<nt;it++)
+  {
+  for(int iv=0;iv<3;iv++)
+   {
+    int i=Th(it,iv);
+    mp3->setP(&Th,it,iv);					
+    valsol[i] = valsol[i] + GetAny< double >((*evct)(stack));			
+    ++takemesh[i];
+   }
+  }
+ for(int i=0; i<nbsol; i++)
+  {
+   valsol[i] /= takemesh[i]; 
+  }
+ 
+ //Writes valsol on the file file
+ if (what==1) dx.addscalar(name,&Th,valsol);
+
+ if (what == 2)
+  {
+   KN<double> valsol2(nbsol);
+   valsol2=0.;
+   KN<int> takemesh(nbsol);
+   takemesh=0;
+   MeshPoint *mp3(MeshPointStack(stack));
+   for (int it=0;it<nt;it++)
+    {
+     for(int iv=0;iv<3;iv++)
+      {
+       int i=Th(it,iv);
+       mp3->setP(&Th,it,iv);					
+       valsol2[i] = valsol2[i] + GetAny< double >((*evct2)(stack));			
+       ++takemesh[i];
+      }
+    }
+   for(int i=0; i<nbsol; i++)
+    {
+     valsol2[i] /= takemesh[i]; 
+    }
+   
+   //Writes valsol on the file file
+   dx.addvector(name,&Th,valsol,valsol2);
+   
+  }
+
+ return longdefault;
+
+}
+
+
+
+// le vrai constructeur est la
+VtkWriter* init_VtkWriter(VtkWriter * const &a, string * const & s)
+{
+ std::cout << "start init_VtkWriter" << std::endl;
+ a->init();
+ a->openfiles(*s);
+ std::cout << "end init_VtkWriter" << std::endl;
+ return a;
+} 
+
+void* call_addmesh( VtkWriter * const & mt, Fem2D::Mesh* const & pTh) {
+  mt->addmesh(pTh);
+  return NULL;
+}
+ 
+//   Add the function name to the freefem++ table 
+class Init 
+{ 
+public:
+ Init();
+};
+
+LOADINIT(Init);
+Init::Init()
+{
+ 
+ Dcl_Type<VtkWriter*>(InitP<VtkWriter>,Destroy<VtkWriter>); 
+// declare deux nouveau type pour freefem++  un pointeur et 
+
+ zzzfff->Add("VtkWriter",atype<VtkWriter*>()); // ajoute le type myType a freefem++ 
+ // constructeur  d'un type myType  dans freefem 
+ TheOperators->Add("<-", new OneOperator2_<VtkWriter*, VtkWriter* ,string*>(&init_VtkWriter));
+ Global.Add("Vtkaddmesh","(",new OneOperator2_<void *, VtkWriter*, Fem2D::Mesh*>(call_addmesh)); 
+ Global.Add("Vtkaddscalar","(",new OneOperatorCode< Vtkwritesol_Op> );
+ 
+}
diff --git a/examples++-load/VTK_writer_3d.cpp b/examples++-load/VTK_writer_3d.cpp
index 9c940d5..3ebc2d2 100644
--- a/examples++-load/VTK_writer_3d.cpp
+++ b/examples++-load/VTK_writer_3d.cpp
@@ -1,364 +1,367 @@
-// -*- Mode : c++ -*-
-//
-// SUMMARY  : 
-// USAGE    :        
-// ORG      : 
-// AUTHOR   : Cedric Ody (not an expert in c++)
-// E-MAIL   : cedric.listes at gmail.com
-// from the work of  Sala Lorenzo (Dxwriter)
-
-#include "mode_open.hpp"
-#include <iostream>
-#include <cfloat>
-#include <cmath>
-#include <iterator>
-using namespace std;
-#include "ff++.hpp"
-//using namespace Fem2D;
-#include <set>
-#include <vector>
-//#include "msh3.hpp"
-
-class VtkWriter 
-{
- struct tsinfo
- {
-  int imesh;//!<index of the mesh
-  std::string name;
-  std::vector<double> vecistant;
- };
- 
-private:
- std::vector<Mesh3*> _vecmesh;
- //std::vector<tsinfo> _vecofts;
- std::string _nameoffile;
-
- /*! This string contains the name of data file with \\ where there's a \ in the path*/
- std::string _nameofdatafile;
-
- //!files containing the data and the timeseries
- std::ofstream _ofdata;
-
-public:
- VtkWriter() { std::cout << "Constructor of VtkWriter" << endl;  }
- void openfiles(const std::string& s)
-  {
-   _nameoffile=s;
-   std::string tmp=s+".vtu";
-   std::cout<<tmp<<" ";
-   _ofdata.open(tmp.c_str(), std::ios_base::out);
-   _nameofdatafile="";
-   for(int i=0;i<tmp.length();++i)
-    {
-     if(tmp.at(i)=='\\')
-      _nameofdatafile.append(1,'\\');
-     _nameofdatafile.append(1,tmp.at(i));
-    }
-  }
-
- void addmesh(Mesh3* mesh)
-  {
-   Mesh3& Th(*mesh);
-   _vecmesh.push_back(mesh);
-   _ofdata.flags(std::ios_base::scientific);
-   _ofdata.precision(15);
-
-   _ofdata << "<?xml version=\"1.0\"?>" << std::endl;
-   _ofdata << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">" << std::endl;
-   _ofdata << "<UnstructuredGrid>" << std::endl;
-   _ofdata << "<Piece NumberOfPoints=\"" << Th.nv << "\" NumberOfCells=\"" << Th.nt << "\">" << std::endl;
-   _ofdata << "<Points>" << std::endl;
-   _ofdata << "<DataArray type=\"Float32\" Name=\"Position\" NumberOfComponents=\"3\" format=\"ascii\">" << std::endl;
-   for(int k=0;k<Th.nv;++k) _ofdata << Th(k).x<<" "<<Th(k).y<< " "<<Th(k).z<<std::endl;
-   _ofdata << "</DataArray>" << std::endl;
-   _ofdata << "</Points>" << std::endl;
-   _ofdata << "<Cells>" << std::endl;
-   _ofdata << "<DataArray type=\"Int32\" Name=\"connectivity\" NumberOfComponents=\"1\" format=\"ascii\">" << std::endl;
-   for(int i=0;i<Th.nt;++i)
-    for (int j=0; j <4; j++) _ofdata << Th(i,j) << " " ;
-   _ofdata << std::endl;
-   _ofdata << "</DataArray>" << std::endl;
-   _ofdata << "<DataArray type=\"Int32\" Name=\"offsets\" NumberOfComponents=\"1\" format=\"ascii\">" << std::endl;	
-   for(int i=0;i<Th.nt;++i)  _ofdata << 4+4*(i) << " ";
-   _ofdata << std::endl;
-   _ofdata << "</DataArray>" << std::endl;
-   _ofdata << "<DataArray type=\"UInt8\" Name=\"types\" NumberOfComponents=\"1\" format=\"ascii\">" << std::endl;	
-   for(int i=0;i<Th.nt;++i)  _ofdata << 10 << " ";
-   _ofdata << std::endl;
-   _ofdata << "</DataArray>" << std::endl;
-   _ofdata << "</Cells>" << std::endl; 
-   _ofdata << "<PointData >" << endl; 
-  }
- 
- /*!Add a field*/
- void addscalar(const string& nameoffield, Mesh3* mesh, const KN<double>&val)
-  {
-   _ofdata.flags(std::ios_base::scientific);
-   _ofdata.precision(15);
-
-   _ofdata << "<DataArray type=\"Float32\" Name=\""<<nameoffield<<"\" NumberOfComponents=\"1\" format=\"ascii\">" << std::endl;
-   for(int i=0;i<val.size();++i) _ofdata<<checkprecision(val[i])<<std::endl;
-   _ofdata << "</DataArray>" << std::endl;
-   
-   _ofdata.flush();
-  }
- 
- double checkprecision(double val)
-  {
-   double tmp;
-   if ( val >= 0. ) tmp=max(0.,val);
-   if ( val <  0. ) tmp=min(0.,val);
-   return tmp;
-  }
-
-  /*!Add a field*/
- void addvector(const string& nameoffield, Mesh3* mesh, const KN<double>&val,
-                const KN<double>&val2,const KN<double>&val3 )
-  {
-   _ofdata.flags(std::ios_base::scientific);
-   _ofdata.precision(15);
-
-   _ofdata << "<DataArray type=\"Float32\" Name=\""<<nameoffield<<"\" NumberOfComponents=\"3\" format=\"ascii\">" << std::endl;
-   for(int i=0;i<val.size();++i) _ofdata<<checkprecision(val[i])<< " " << checkprecision(val2[i]) << " " << checkprecision(val3[i]) << std::endl;
-   _ofdata << "</DataArray>" << std::endl;
-   _ofdata.flush();
-  }
-
-
- /*!Get the mesh associated with the series nameofts*/
- Mesh3* getmeshts(const string& nameofts)
-  {
-   return _vecmesh[0];
-  }
- 
- void init()
-  {
-   new(this)VtkWriter(); 
-  }
- 
- void destroy() 
-  {
-   if(_ofdata.is_open())
-    {
-     _ofdata << "</PointData>" << endl;	
-     _ofdata << "<CellData>" << endl; 	
-     _ofdata << "</CellData>" << endl; 
-     _ofdata << "</Piece>" << endl;
-     _ofdata << "</UnstructuredGrid>" << endl;
-     _ofdata << "</VTKFile>" << endl;
-     _ofdata.close(); 		
-    }
-  } 
-}; //End of class
-
-class Vtkwritesol_Op : public E_F0mps 
-{
-public:
- typedef long  Result;
- Expression edx;
- Expression ename;//!<name of time series or field
- Expression et;//!<time
- long what; // 1 scalar, 2 vector, 3 symtensor
- long nbfloat; // 1 scalar, n vector (3D), n symtensor(3D)
- Expression evct,evct2,evct3;
- 
-public:
- Vtkwritesol_Op(const basicAC_F0 &  args) :  what(0), nbfloat(0)
-  {
-   evct=0;
-   evct2=0;
-   evct3=0;
-   int nbofsol;
-   int ddim=3;
-   //There's no named parameter
-   args.SetNameParam();
-   if(args.size()!=3)
-    {
-     CompileError("Vtkwritesol accepts only 4 parameters");
-    }
-   if (BCastTo<VtkWriter *>(args[0])) edx = CastTo<VtkWriter *>(args[0]);
-   if (BCastTo<string *>(args[1])) ename = CastTo<string *>(args[1]);
-   
-   if ( args[2].left()==atype<double>() )
-    {
-     what=1;
-     nbfloat=1;
-     evct=to<double>( args[2] );
-    }
-   else if ( args[2].left()==atype<double *>() )
-    {
-     what=1;
-     nbfloat=1;
-     evct=to<double>( args[2] );
-    }
-   else if ( BCastTo<pfer>(args[2]) )
-    {
-     what=1;
-     nbfloat=1;
-     evct=to<double>( args[2] );
-    }
-   else if ( args[2].left()==atype<E_Array>() )
-    {
-     std::cout << "Until now only scalar solution" << std::endl;
-     
-     int i=2;
-     const E_Array * a0  = dynamic_cast<const E_Array *>( args[i].LeftValue() );
-       
-
-      if( a0->size() == 1){
-      // scalar solution
-      what=1;
-      nbfloat=a0->size();
-      evct = to<double>( (*a0)[0]);
-      
-     }
-  
-     if( a0->size() == ddim){
-      // vector solution
-      what=2;
-      nbfloat=a0->size();
-      evct = to<double>( (*a0)[0]);
-      evct2 = to<double>( (*a0)[1]);
-      evct3 = to<double>( (*a0)[2]);
-      
-     }
-      cout << "Passed Until now only scalar solution" << std::endl;
-    }
-   else 
-    {
-     CompileError("savesol in 2D: Sorry no way to save this kind of data");
-    }
-   
-  }
- static ArrayOfaType  typeargs() { return  ArrayOfaType(atype<VtkWriter *>(), atype<string *>(), true); }// all type
- static  E_F0 * f(const basicAC_F0 & args) { return new Vtkwritesol_Op(args);} 
- AnyType operator()(Stack stack)  const ;
-}; // end of class
-
-
-AnyType Vtkwritesol_Op::operator()(Stack stack)  const 
-{ 
- MeshPoint *mp(MeshPointStack(stack)) , mps=*mp;
- VtkWriter &dx=*(GetAny<VtkWriter *>((*edx)(stack)));
- string &name=*(GetAny<string *>((*ename)(stack)));
- //double t=GetAny<double>((*et)(stack));
- Mesh3 &Th=*(dx.getmeshts(name));
- 
- int nt = Th.nt;
- int nv = Th.nv;
- 
- int nbsol=nv;
- long longdefault;
- 
- KN<double> valsol(nbsol);
- valsol=0.;
- KN<int> takemesh(nbsol);
- takemesh=0;
- MeshPoint *mp3(MeshPointStack(stack));
- for (int it=0;it<nt;it++)
-  {
-  for(int iv=0;iv<4;iv++)
-   {
-    int i=Th(it,iv);
-    mp3->setP(&Th,it,iv);					
-    valsol[i] = valsol[i] + GetAny< double >((*evct)(stack));			
-    ++takemesh[i];
-   }
-  }
- for(int i=0; i<nbsol; i++)
-  {
-   valsol[i] /= takemesh[i]; 
-  }
- 
- //Writes valsol on the file file
- if (what==1) 
-   dx.addscalar(name,&Th,valsol);
-
- if (what == 2)
-  {
-   KN<double> valsol2(nbsol);
-   valsol2=0.;
-   KN<int> takemesh(nbsol);
-   takemesh=0;
-   MeshPoint *mp3(MeshPointStack(stack));
-   for (int it=0;it<nt;it++)
-    {
-     for(int iv=0;iv<4;iv++)
-      {
-       int i=Th(it,iv);
-       mp3->setP(&Th,it,iv);					
-       valsol2[i] = valsol2[i] + GetAny< double >((*evct2)(stack));			
-       ++takemesh[i];
-      }
-    }
-   for(int i=0; i<nbsol; i++)
-    {
-     valsol2[i] /= takemesh[i]; 
-    }
-   
-   {
-    KN<double> valsol3(nbsol);
-    valsol3=0.;
-    KN<int> takemesh(nbsol);
-    takemesh=0;
-    MeshPoint *mp3(MeshPointStack(stack));
-    for (int it=0;it<nt;it++)
-     {
-      for(int iv=0;iv<4;iv++)
-       {
-        int i=Th(it,iv);
-        mp3->setP(&Th,it,iv);					
-        valsol3[i] = valsol3[i] + GetAny< double >((*evct3)(stack));			
-        ++takemesh[i];
-       }
-     }
-    for(int i=0; i<nbsol; i++)
-     {
-      valsol3[i] /= takemesh[i]; 
-     }
-
-   //Writes valsol on the file file
-   dx.addvector(name,&Th,valsol,valsol2,valsol3);
-
-      }
-   
-  }
-
- return longdefault;
-
-}
-
-
-
-// le vrai constructeur est la
-VtkWriter* init_VtkWriter(VtkWriter * const &a, string * const & s)
-{
- std::cout << "start init_VtkWriter" << std::endl;
- a->init();
- a->openfiles(*s);
- std::cout << "end init_VtkWriter" << std::endl;
- return a;
-} 
-
-void* call_addmesh( VtkWriter * const & mt, Mesh3* const & pTh) { mt->addmesh(pTh);}
- 
-//   Add the function name to the freefem++ table 
-class Init 
-{ 
-public:
- Init();
-};
-
-LOADINIT(Init);
-Init::Init()
-{
- 
- Dcl_Type<VtkWriter*>(InitP<VtkWriter>,Destroy<VtkWriter>); // declare deux nouveau type pour freefem++  un pointeur et 
- 
- zzzfff->Add("VtkWriter",atype<VtkWriter*>()); // ajoute le type myType a freefem++ 
- // constructeur  d'un type myType  dans freefem 
- TheOperators->Add("<-", new OneOperator2_<VtkWriter*, VtkWriter* ,string*>(&init_VtkWriter));
- Global.Add("Vtkaddmesh","(",new OneOperator2_<void *, VtkWriter*, Mesh3*>(call_addmesh)); 
- Global.Add("Vtkaddscalar","(",new OneOperatorCode< Vtkwritesol_Op> );
- 
-}
+// -*- Mode : c++ -*-
+//
+// SUMMARY  : 
+// USAGE    :        
+// ORG      : 
+// AUTHOR   : Cedric Ody (not an expert in c++)
+// E-MAIL   : cedric.listes at gmail.com
+// from the work of  Sala Lorenzo (Dxwriter)
+
+#include "mode_open.hpp"
+#include <iostream>
+#include <cfloat>
+#include <cmath>
+#include <iterator>
+using namespace std;
+#include "ff++.hpp"
+//using namespace Fem2D;
+#include <set>
+#include <vector>
+//#include "msh3.hpp"
+
+class VtkWriter 
+{
+ struct tsinfo
+ {
+  int imesh;//!<index of the mesh
+  std::string name;
+  std::vector<double> vecistant;
+ };
+ 
+private:
+ std::vector<Mesh3*> _vecmesh;
+ //std::vector<tsinfo> _vecofts;
+ std::string _nameoffile;
+
+ /*! This string contains the name of data file with \\ where there's a \ in the path*/
+ std::string _nameofdatafile;
+
+ //!files containing the data and the timeseries
+ std::ofstream _ofdata;
+
+public:
+ VtkWriter() { std::cout << "Constructor of VtkWriter" << endl;  }
+ void openfiles(const std::string& s)
+  {
+   _nameoffile=s;
+   std::string tmp=s+".vtu";
+   std::cout<<tmp<<" ";
+   _ofdata.open(tmp.c_str(), std::ios_base::out);
+   _nameofdatafile="";
+   for(int i=0;i<tmp.length();++i)
+    {
+     if(tmp.at(i)=='\\')
+      _nameofdatafile.append(1,'\\');
+     _nameofdatafile.append(1,tmp.at(i));
+    }
+  }
+
+ void addmesh(Mesh3* mesh)
+  {
+   Mesh3& Th(*mesh);
+   _vecmesh.push_back(mesh);
+   _ofdata.flags(std::ios_base::scientific);
+   _ofdata.precision(15);
+
+   _ofdata << "<?xml version=\"1.0\"?>" << std::endl;
+   _ofdata << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">" << std::endl;
+   _ofdata << "<UnstructuredGrid>" << std::endl;
+   _ofdata << "<Piece NumberOfPoints=\"" << Th.nv << "\" NumberOfCells=\"" << Th.nt << "\">" << std::endl;
+   _ofdata << "<Points>" << std::endl;
+   _ofdata << "<DataArray type=\"Float32\" Name=\"Position\" NumberOfComponents=\"3\" format=\"ascii\">" << std::endl;
+   for(int k=0;k<Th.nv;++k) _ofdata << Th(k).x<<" "<<Th(k).y<< " "<<Th(k).z<<std::endl;
+   _ofdata << "</DataArray>" << std::endl;
+   _ofdata << "</Points>" << std::endl;
+   _ofdata << "<Cells>" << std::endl;
+   _ofdata << "<DataArray type=\"Int32\" Name=\"connectivity\" NumberOfComponents=\"1\" format=\"ascii\">" << std::endl;
+   for(int i=0;i<Th.nt;++i)
+    for (int j=0; j <4; j++) _ofdata << Th(i,j) << " " ;
+   _ofdata << std::endl;
+   _ofdata << "</DataArray>" << std::endl;
+   _ofdata << "<DataArray type=\"Int32\" Name=\"offsets\" NumberOfComponents=\"1\" format=\"ascii\">" << std::endl;	
+   for(int i=0;i<Th.nt;++i)  _ofdata << 4+4*(i) << " ";
+   _ofdata << std::endl;
+   _ofdata << "</DataArray>" << std::endl;
+   _ofdata << "<DataArray type=\"UInt8\" Name=\"types\" NumberOfComponents=\"1\" format=\"ascii\">" << std::endl;	
+   for(int i=0;i<Th.nt;++i)  _ofdata << 10 << " ";
+   _ofdata << std::endl;
+   _ofdata << "</DataArray>" << std::endl;
+   _ofdata << "</Cells>" << std::endl; 
+   _ofdata << "<PointData >" << endl; 
+  }
+ 
+ /*!Add a field*/
+ void addscalar(const string& nameoffield, Mesh3* mesh, const KN<double>&val)
+  {
+   _ofdata.flags(std::ios_base::scientific);
+   _ofdata.precision(15);
+
+   _ofdata << "<DataArray type=\"Float32\" Name=\""<<nameoffield<<"\" NumberOfComponents=\"1\" format=\"ascii\">" << std::endl;
+   for(int i=0;i<val.size();++i) _ofdata<<checkprecision(val[i])<<std::endl;
+   _ofdata << "</DataArray>" << std::endl;
+   
+   _ofdata.flush();
+  }
+ 
+ double checkprecision(double val)
+  {
+   double tmp;
+   if ( val >= 0. ) tmp=max(0.,val);
+   if ( val <  0. ) tmp=min(0.,val);
+   return tmp;
+  }
+
+  /*!Add a field*/
+ void addvector(const string& nameoffield, Mesh3* mesh, const KN<double>&val,
+                const KN<double>&val2,const KN<double>&val3 )
+  {
+   _ofdata.flags(std::ios_base::scientific);
+   _ofdata.precision(15);
+
+   _ofdata << "<DataArray type=\"Float32\" Name=\""<<nameoffield<<"\" NumberOfComponents=\"3\" format=\"ascii\">" << std::endl;
+   for(int i=0;i<val.size();++i) _ofdata<<checkprecision(val[i])<< " " << checkprecision(val2[i]) << " " << checkprecision(val3[i]) << std::endl;
+   _ofdata << "</DataArray>" << std::endl;
+   _ofdata.flush();
+  }
+
+
+ /*!Get the mesh associated with the series nameofts*/
+ Mesh3* getmeshts(const string& nameofts)
+  {
+   return _vecmesh[0];
+  }
+ 
+ void init()
+  {
+   new(this)VtkWriter(); 
+  }
+ 
+ void destroy() 
+  {
+   if(_ofdata.is_open())
+    {
+     _ofdata << "</PointData>" << endl;	
+     _ofdata << "<CellData>" << endl; 	
+     _ofdata << "</CellData>" << endl; 
+     _ofdata << "</Piece>" << endl;
+     _ofdata << "</UnstructuredGrid>" << endl;
+     _ofdata << "</VTKFile>" << endl;
+     _ofdata.close(); 		
+    }
+  } 
+}; //End of class
+
+class Vtkwritesol_Op : public E_F0mps 
+{
+public:
+ typedef long  Result;
+ Expression edx;
+ Expression ename;//!<name of time series or field
+ Expression et;//!<time
+ long what; // 1 scalar, 2 vector, 3 symtensor
+ long nbfloat; // 1 scalar, n vector (3D), n symtensor(3D)
+ Expression evct,evct2,evct3;
+ 
+public:
+ Vtkwritesol_Op(const basicAC_F0 &  args) :  what(0), nbfloat(0)
+  {
+   evct=0;
+   evct2=0;
+   evct3=0;
+   int nbofsol;
+   int ddim=3;
+   //There's no named parameter
+   args.SetNameParam();
+   if(args.size()!=3)
+    {
+     CompileError("Vtkwritesol accepts only 4 parameters");
+    }
+   if (BCastTo<VtkWriter *>(args[0])) edx = CastTo<VtkWriter *>(args[0]);
+   if (BCastTo<string *>(args[1])) ename = CastTo<string *>(args[1]);
+   
+   if ( args[2].left()==atype<double>() )
+    {
+     what=1;
+     nbfloat=1;
+     evct=to<double>( args[2] );
+    }
+   else if ( args[2].left()==atype<double *>() )
+    {
+     what=1;
+     nbfloat=1;
+     evct=to<double>( args[2] );
+    }
+   else if ( BCastTo<pfer>(args[2]) )
+    {
+     what=1;
+     nbfloat=1;
+     evct=to<double>( args[2] );
+    }
+   else if ( args[2].left()==atype<E_Array>() )
+    {
+     std::cout << "Until now only scalar solution" << std::endl;
+     
+     int i=2;
+     const E_Array * a0  = dynamic_cast<const E_Array *>( args[i].LeftValue() );
+       
+
+      if( a0->size() == 1){
+      // scalar solution
+      what=1;
+      nbfloat=a0->size();
+      evct = to<double>( (*a0)[0]);
+      
+     }
+  
+     if( a0->size() == ddim){
+      // vector solution
+      what=2;
+      nbfloat=a0->size();
+      evct = to<double>( (*a0)[0]);
+      evct2 = to<double>( (*a0)[1]);
+      evct3 = to<double>( (*a0)[2]);
+      
+     }
+      cout << "Passed Until now only scalar solution" << std::endl;
+    }
+   else 
+    {
+     CompileError("savesol in 2D: Sorry no way to save this kind of data");
+    }
+   
+  }
+ static ArrayOfaType  typeargs() { return  ArrayOfaType(atype<VtkWriter *>(), atype<string *>(), true); }// all type
+ static  E_F0 * f(const basicAC_F0 & args) { return new Vtkwritesol_Op(args);} 
+ AnyType operator()(Stack stack)  const ;
+}; // end of class
+
+
+AnyType Vtkwritesol_Op::operator()(Stack stack)  const 
+{ 
+ MeshPoint *mp(MeshPointStack(stack)) , mps=*mp;
+ VtkWriter &dx=*(GetAny<VtkWriter *>((*edx)(stack)));
+ string &name=*(GetAny<string *>((*ename)(stack)));
+ //double t=GetAny<double>((*et)(stack));
+ Mesh3 &Th=*(dx.getmeshts(name));
+ 
+ int nt = Th.nt;
+ int nv = Th.nv;
+ 
+ int nbsol=nv;
+ long longdefault;
+ 
+ KN<double> valsol(nbsol);
+ valsol=0.;
+ KN<int> takemesh(nbsol);
+ takemesh=0;
+ MeshPoint *mp3(MeshPointStack(stack));
+ for (int it=0;it<nt;it++)
+  {
+  for(int iv=0;iv<4;iv++)
+   {
+    int i=Th(it,iv);
+    mp3->setP(&Th,it,iv);					
+    valsol[i] = valsol[i] + GetAny< double >((*evct)(stack));			
+    ++takemesh[i];
+   }
+  }
+ for(int i=0; i<nbsol; i++)
+  {
+   valsol[i] /= takemesh[i]; 
+  }
+ 
+ //Writes valsol on the file file
+ if (what==1) 
+   dx.addscalar(name,&Th,valsol);
+
+ if (what == 2)
+  {
+   KN<double> valsol2(nbsol);
+   valsol2=0.;
+   KN<int> takemesh(nbsol);
+   takemesh=0;
+   MeshPoint *mp3(MeshPointStack(stack));
+   for (int it=0;it<nt;it++)
+    {
+     for(int iv=0;iv<4;iv++)
+      {
+       int i=Th(it,iv);
+       mp3->setP(&Th,it,iv);					
+       valsol2[i] = valsol2[i] + GetAny< double >((*evct2)(stack));			
+       ++takemesh[i];
+      }
+    }
+   for(int i=0; i<nbsol; i++)
+    {
+     valsol2[i] /= takemesh[i]; 
+    }
+   
+   {
+    KN<double> valsol3(nbsol);
+    valsol3=0.;
+    KN<int> takemesh(nbsol);
+    takemesh=0;
+    MeshPoint *mp3(MeshPointStack(stack));
+    for (int it=0;it<nt;it++)
+     {
+      for(int iv=0;iv<4;iv++)
+       {
+        int i=Th(it,iv);
+        mp3->setP(&Th,it,iv);					
+        valsol3[i] = valsol3[i] + GetAny< double >((*evct3)(stack));			
+        ++takemesh[i];
+       }
+     }
+    for(int i=0; i<nbsol; i++)
+     {
+      valsol3[i] /= takemesh[i]; 
+     }
+
+   //Writes valsol on the file file
+   dx.addvector(name,&Th,valsol,valsol2,valsol3);
+
+      }
+   
+  }
+
+ return longdefault;
+
+}
+
+
+
+// le vrai constructeur est la
+VtkWriter* init_VtkWriter(VtkWriter * const &a, string * const & s)
+{
+ std::cout << "start init_VtkWriter" << std::endl;
+ a->init();
+ a->openfiles(*s);
+ std::cout << "end init_VtkWriter" << std::endl;
+ return a;
+} 
+
+void* call_addmesh( VtkWriter * const & mt, Mesh3* const & pTh) {
+  mt->addmesh(pTh);
+  return NULL;
+}
+ 
+//   Add the function name to the freefem++ table 
+class Init 
+{ 
+public:
+ Init();
+};
+
+LOADINIT(Init);
+Init::Init()
+{
+ 
+ Dcl_Type<VtkWriter*>(InitP<VtkWriter>,Destroy<VtkWriter>); // declare deux nouveau type pour freefem++  un pointeur et 
+ 
+ zzzfff->Add("VtkWriter",atype<VtkWriter*>()); // ajoute le type myType a freefem++ 
+ // constructeur  d'un type myType  dans freefem 
+ TheOperators->Add("<-", new OneOperator2_<VtkWriter*, VtkWriter* ,string*>(&init_VtkWriter));
+ Global.Add("Vtkaddmesh","(",new OneOperator2_<void *, VtkWriter*, Mesh3*>(call_addmesh)); 
+ Global.Add("Vtkaddscalar","(",new OneOperatorCode< Vtkwritesol_Op> );
+ 
+}
diff --git a/examples++-load/VarIneq2.edp b/examples++-load/VarIneq2.edp
index 8fab223..b1344cd 100644
--- a/examples++-load/VarIneq2.edp
+++ b/examples++-load/VarIneq2.edp
@@ -169,4 +169,4 @@ Th = adaptmesh(Th,best1,best2);
 
 oldu1=best1;
 oldu2=best2;
-}
\ No newline at end of file
+}
diff --git a/examples++-load/addNewType.cpp b/examples++-load/addNewType.cpp
index a87a9b8..67eae91 100644
--- a/examples++-load/addNewType.cpp
+++ b/examples++-load/addNewType.cpp
@@ -25,6 +25,7 @@ myType * init_MyType(myType * const &a, string * const & s)
 {
   a->nom = new string(* s);
   cout << " build MyType " << *a->nom << endl;
+  return NULL; // return value never used for now (13.1)
 } 
 
 
diff --git a/examples++-load/buildlayermesh.edp b/examples++-load/buildlayermesh.edp
index c7355f6..1740676 100644
--- a/examples++-load/buildlayermesh.edp
+++ b/examples++-load/buildlayermesh.edp
@@ -1,57 +1,57 @@
-// file buildlayermesh.edp
-load "msh3"
-load "tetgen"
-// Test 1
-
-int C1=99, C2=98; // could be anything
-
-border C01(t=0,pi){ x=t;  y=0;      label=1;}
-border C02(t=0,2*pi){ x=pi; y=t;  label=1;}
-border C03(t=0,pi){ x=pi-t;  y=2*pi;    label=1;}
-border C04(t=0,2*pi){ x=0;    y=2*pi-t; label=1;}
-
-
-border C11(t=0,0.7){ x=0.5+t;  y=2.5;      label=C1;}
-border C12(t=0,2){ x=1.2;    y=2.5+t;  label=C1;}
-border C13(t=0,0.7){ x=1.2-t;  y=4.5;     label=C1;}
-border C14(t=0,2){ x=0.5;    y=4.5-t; label=C1;}
-
-
-border C21(t=0,0.7){ x= 2.3+t;     y=2.5;  label=C2;}
-border C22(t=0,2){        x=3;   y=2.5+t;  label=C2;}
-border C23(t=0,0.7){   x=3-t;     y=4.5;  label=C2;}
-border C24(t=0,2){       x=2.3;   y=4.5-t; label=C2;}
-
-mesh Th=buildmesh(    C01(10)+C02(10)+ C03(10)+C04(10)
-                    + C11(5)+C12(5)+C13(5)+C14(5) 
-                    + C21(-5)+C22(-5)+C23(-5)+C24(-5));
-
-mesh Ths=buildmesh(    C01(10)+C02(10)+ C03(10)+C04(10)
-                    + C11(5)+C12(5)+C13(5)+C14(5) );
-                    
-// construction of a box with one hole and two regions
-func zmin=0.;
-func zmax=1.;
-int MaxLayer=10;
-
-int[int] r1=[0,41];
-int[int] r2=[98,98,99,99,1,56];
-int[int] r3=[4,12];    //  The triangles of upper surface generated by the triangle in the 2D region of mesh Th of label 4 as label 12.
-int[int] r4=[4,45];    //  The triangles of lower surface generated by the triangle in the 2D region of mesh Th of label 4 as label 45.
- 
-mesh3 Th3=buildlayers(Th, MaxLayer, zbound=[zmin,zmax], region=r1, labelmid=r2, reffaceup = r3, reffacelow = r4 );
-savemesh(Th3,"box2region1hole.mesh");
-
-
-// Construction of a sphere with tetgen 
-func XX1 = cos(y)*sin(x);
-func YY1 = sin(y)*sin(x);
-func ZZ1 = cos(x);
-
-real [int] domain = [0.,0.,0.,0,0.001];
-string test="paACQ";
-cout << endl;
-cout << "test=" << test << endl;
-mesh3 Th3sph=tetgtransfo(Ths,transfo=[XX1,YY1,ZZ1],switch=test,nbofregions=1,regionlist=domain);
-savemesh(Th3sph,"sphere2region.mesh");
-
+// file buildlayermesh.edp
+load "msh3"
+load "tetgen"
+// Test 1
+
+int C1=99, C2=98; // could be anything
+
+border C01(t=0,pi){ x=t;  y=0;      label=1;}
+border C02(t=0,2*pi){ x=pi; y=t;  label=1;}
+border C03(t=0,pi){ x=pi-t;  y=2*pi;    label=1;}
+border C04(t=0,2*pi){ x=0;    y=2*pi-t; label=1;}
+
+
+border C11(t=0,0.7){ x=0.5+t;  y=2.5;      label=C1;}
+border C12(t=0,2){ x=1.2;    y=2.5+t;  label=C1;}
+border C13(t=0,0.7){ x=1.2-t;  y=4.5;     label=C1;}
+border C14(t=0,2){ x=0.5;    y=4.5-t; label=C1;}
+
+
+border C21(t=0,0.7){ x= 2.3+t;     y=2.5;  label=C2;}
+border C22(t=0,2){        x=3;   y=2.5+t;  label=C2;}
+border C23(t=0,0.7){   x=3-t;     y=4.5;  label=C2;}
+border C24(t=0,2){       x=2.3;   y=4.5-t; label=C2;}
+
+mesh Th=buildmesh(    C01(10)+C02(10)+ C03(10)+C04(10)
+                    + C11(5)+C12(5)+C13(5)+C14(5) 
+                    + C21(-5)+C22(-5)+C23(-5)+C24(-5));
+
+mesh Ths=buildmesh(    C01(10)+C02(10)+ C03(10)+C04(10)
+                    + C11(5)+C12(5)+C13(5)+C14(5) );
+                    
+// construction of a box with one hole and two regions
+func zmin=0.;
+func zmax=1.;
+int MaxLayer=10;
+
+int[int] r1=[0,41];
+int[int] r2=[98,98,99,99,1,56];
+int[int] r3=[4,12];    //  The triangles of upper surface generated by the triangle in the 2D region of mesh Th of label 4 as label 12.
+int[int] r4=[4,45];    //  The triangles of lower surface generated by the triangle in the 2D region of mesh Th of label 4 as label 45.
+ 
+mesh3 Th3=buildlayers(Th, MaxLayer, zbound=[zmin,zmax], region=r1, labelmid=r2, reffaceup = r3, reffacelow = r4 );
+savemesh(Th3,"box2region1hole.mesh");
+
+
+// Construction of a sphere with tetgen 
+func XX1 = cos(y)*sin(x);
+func YY1 = sin(y)*sin(x);
+func ZZ1 = cos(x);
+
+real [int] domain = [0.,0.,0.,0,0.001];
+string test="paACQ";
+cout << endl;
+cout << "test=" << test << endl;
+mesh3 Th3sph=tetgtransfo(Ths,transfo=[XX1,YY1,ZZ1],switch=test,nbofregions=1,regionlist=domain);
+savemesh(Th3sph,"sphere2region.mesh");
+
diff --git a/examples++-load/cmaes-VarIneq.edp b/examples++-load/cmaes-VarIneq.edp
index 9b5a6a3..b94d749 100644
--- a/examples++-load/cmaes-VarIneq.edp
+++ b/examples++-load/cmaes-VarIneq.edp
@@ -120,4 +120,4 @@ Th = adaptmesh(Th,best1,best2);
 ou1 = best1;
 ou2 = best2;
 
-}
\ No newline at end of file
+}
diff --git a/examples++-load/cmaes-oven.edp b/examples++-load/cmaes-oven.edp
index 7e02f1e..36005aa 100644
--- a/examples++-load/cmaes-oven.edp
+++ b/examples++-load/cmaes-oven.edp
@@ -7,7 +7,8 @@ real eps=1e-2,hugeval=1.e30;		//a small value governing collisions and a huge on
 int nbres=6;		//number of resistors (should not be changed) 
 int NPres=NP*(2*pi*R);
 real[int] pr(nbres+2), K(nbres+2); 
-int regi=nbres, rege=nbres+1, lext=1;
K=1;	K[regi]=10;
+int regi=nbres, rege=nbres+1, lext=1;
+K=1;	K[regi]=10;
 
 macro Grad(u) [dx(u),dy(u)]//EOM
 macro Resistor(i,cx,cy,lab)
@@ -160,4 +161,6 @@ real[int] start=[pst,L/6,l/6,pst,L/2,l/6,pst,5*L/6,l/6,pst,L/6,5*l/6,pst,L/2,5*l
 cout << cmaes(J,start,initialStdDevs=isd,stopTolFun=1e-1,stopMaxIter=200,stopMaxFunEval=1000);
 //BFGS(J,dJ,start,nbiterline=10,nbiter=3000,eps=1.e-8);
 iter = 1000;
-J(start);
\ No newline at end of file
+
+// FFCS - regression test reference value
+real regtest=J(start);
diff --git a/examples++-load/convect_dervieux.edp b/examples++-load/convect_dervieux.edp
index 6ca46e0..0ea801c 100644
--- a/examples++-load/convect_dervieux.edp
+++ b/examples++-load/convect_dervieux.edp
@@ -40,4 +40,4 @@ for ( real t=0; t< pi ; t+=dt){
   rhs[] = A * vold[] ;
   FVM;
   plot(v,wait=0);
-};
\ No newline at end of file
+};
diff --git a/examples++-load/ff-Ipopt.cpp b/examples++-load/ff-Ipopt.cpp
index cc0baa7..71a3645 100644
--- a/examples++-load/ff-Ipopt.cpp
+++ b/examples++-load/ff-Ipopt.cpp
@@ -25,7 +25,7 @@
  */
 //ff-c++-LIBRARY-dep:  Ipopt mumps-seq blas  libseq  fc  
 
-using namespace std;
+//using namespace std;
 #include "IpTNLP.hpp"
 #include "IpIpoptApplication.hpp"
 #include "ff++.hpp"
@@ -100,6 +100,7 @@ template<class K> class ffcalfunc
 		ffcalfunc(const ffcalfunc &f) : stack(f.stack) {}
 		ffcalfunc(Stack _stack) : stack(_stack) {}
 		virtual K J(Rn_) const = 0;
+    virtual  ~ffcalfunc() {}
 };
 
 
@@ -219,7 +220,9 @@ template<> class ffcalfunc<Matrice_Creuse<R> *>
 		ffcalfunc(Stack s) : stack(s) {}
 		virtual K J(Rn_) const = 0;
 		virtual K J(Rn_,double,Rn_) const = 0;
-		virtual bool NLCHPEnabled() const = 0; //Non Linear Constraints Hessian Prototype 
+  		virtual bool NLCHPEnabled() const = 0; //Non Linear Constraints Hessian Prototype
+    virtual ~ffcalfunc(){}
+    
 };
 
 /*****************************************************************************************************************************
@@ -472,7 +475,7 @@ ffNLP::ffNLP(Rn &x,const Rn &_xl,const Rn &_xu,const Rn &_gl,const Rn &_gu,Scala
 ffNLP::ffNLP(Rn &x,const Rn &_xl,const Rn &_xu,const Rn &_gl,const Rn &_gu,ScalarFunc * _fitness,VectorFunc * _dfitness,SparseMatFunc * _hessian,
 						 VectorFunc * _constraints,SparseMatFunc * _dconstraints, int _mm,int _nnz_jac,int _nnz_h) : 
 				  xstart(&x), xl(_xl), xu(_xu), gl(_gl), gu(_gu),hessian(_hessian),final_value(299792458.),//sym(0),unsymind(),
-					fitness(_fitness),dfitness(dfitness),constraints(_constraints),dconstraints(_dconstraints),uz_start(),lz_start(),
+					fitness(_fitness),dfitness(_dfitness),constraints(_constraints),dconstraints(_dconstraints),uz_start(),lz_start(),
 					mm(_mm),nnz_jac(_nnz_jac),nnz_h(_nnz_h),HesStruct(true),JacStruct(false),sigma_start(1.),lambda_start(),x_start(x),checkstruct(1) {}
 
 ffNLP::~ffNLP()
@@ -596,19 +599,25 @@ bool ffNLP::get_starting_point(Index n, bool init_x, Number* x,bool init_z, Numb
 	{
 		if(uz_start.N() != n) 
 		{
-			cout << "ff-IPOPT warm start : upper simple bounds start multipliers array doesn't have the expected size (" << uz_start.N() << "!=" << n << ")." << endl;
-			cout << "                   ";
-			if(uz_start.N()==0) cout << "maybe because no upper bounds multiplier has been given. " << endl;
-			cout << " Initializing them to 1..." << endl;
+      if(xu.min() < 1.e19)
+      {
+        cout << "ff-IPOPT warm start : upper simple bounds start multipliers array doesn't have the expected size (" << uz_start.N() << "!=" << n << ")." << endl;
+        cout << "                   ";
+        if(uz_start.N()==0) cout << "maybe because no upper bounds multiplier has been given. " << endl;
+        cout << " Initializing them to 1..." << endl;
+      }
 			uz_start.resize(n);
 			uz_start=1.;
 		}
 		if(lz_start.N() != n) 
 		{
-			cout << "ff-IPOPT warm start : lower simple bounds start multipliers array doesn't have the expected size (" << lz_start.N() << "!=" << n << ")." << endl;
-			cout << "                   ";
-			if(lz_start.N()==0) cout << "maybe because no lower bounds multiplier has been given. " << endl;
-			cout << " Initializing them to 1..." << endl;
+			if(xl.max() > -1e19)
+			{
+        cout << "ff-IPOPT warm start : lower simple bounds start multipliers array doesn't have the expected size (" << lz_start.N() << "!=" << n << ")." << endl;
+        cout << "                   ";
+        if(lz_start.N()==0) cout << "maybe because no lower bounds multiplier has been given. " << endl;
+        cout << " Initializing them to 1..." << endl;
+      }
 			lz_start.resize(n);
 			lz_start=1.;
 		}
@@ -862,6 +871,7 @@ class GenericFitnessFunctionDatas
 		GenericFitnessFunctionDatas() : CompletelyNonLinearConstraints(true),JJ(0),GradJ(0),Hessian(0) {}
 		virtual const AssumptionF A() const {return undeff;}
 		virtual void operator()(Stack,const C_F0&,const C_F0&,const C_F0&,Expression const *,ScalarFunc *&,VectorFunc *&,SparseMatFunc *&,bool) const = 0; //Build the functions
+   virtual ~GenericFitnessFunctionDatas() {}
 };
 template<AssumptionF AF> class FitnessFunctionDatas : public GenericFitnessFunctionDatas  //not really a template, since most of the methods of all cases have to be specialized
 {
@@ -869,6 +879,7 @@ template<AssumptionF AF> class FitnessFunctionDatas : public GenericFitnessFunct
 		FitnessFunctionDatas(const basicAC_F0 &,Expression const *,const C_F0 &,const C_F0 &,const C_F0 &);
 		const AssumptionF A() const {return AF;}
 		void operator()(Stack,const C_F0&,const C_F0&,const C_F0&,Expression const *,ScalarFunc *&,VectorFunc *&,SparseMatFunc *&,bool) const;
+    
 };
 
 class GenericConstraintFunctionDatas
@@ -879,7 +890,9 @@ class GenericConstraintFunctionDatas
 		GenericConstraintFunctionDatas() : Constraints(0),GradConstraints(0) {}
 		virtual const AssumptionG A() const {return undefg;}
 		virtual const bool WC() const =0;//with constraints
-		virtual void operator()(Stack,const C_F0 &,Expression const *,VectorFunc *&,SparseMatFunc *&,bool) const = 0;//build the functions
+		virtual void operator()(Stack,const C_F0 &,Expression const *,VectorFunc *&,SparseMatFunc *&,bool) const = 0;//build the functions`
+   virtual  ~GenericConstraintFunctionDatas() {}
+    
 };
 template<AssumptionG AG> class ConstraintFunctionDatas : public GenericConstraintFunctionDatas
 {
@@ -913,7 +926,7 @@ class OptimIpopt : public OneOperator
 				std::set<unsigned short> unused_name_param; //In some case, some parameter are usless, this is the list of their index in nargs
 				void InitUNP(); //Initialize unusued_name_param at freefem compile time
 				static basicAC_F0::name_and_type name_param[];
-				static const int n_name_param=27;
+				static const int n_name_param=29;
 				Expression nargs[n_name_param];
 				Expression X;
 				mutable Rn lm;
@@ -1151,8 +1164,10 @@ class OptimIpopt : public OneOperator
 					if(nargs[23]) app->Options()->SetNumericValue("mumps_pivtol",GetAny<double>((*nargs[23])(stack)));
 					if(nargs[24]) app->Options()->SetNumericValue("bound_relax_factor",GetAny<double>((*nargs[24])(stack)));
 					if(nargs[25]) app->Options()->SetStringValue("mu_strategy",GetAny<string*>((*nargs[25])(stack))->c_str());
+					if(nargs[27]) app->Options()->SetNumericValue("mu_min",GetAny<double>((*nargs[27])(stack)));
+          if(nargs[28]) if(!GetAny<bool>((*nargs[28])(stack))) app->Options()->SetStringValue("accept_every_trial_step","yes");
 					//if(nargs[26]) app->Options()->SetNumericValue("obj_scaling_factor",GetAny<double>((*nargs[26])(stack)));
-				
+          if(verbosity>1) app->Options()->SetStringValue("print_user_options","yes");
 					app->Options()->SetStringValue("output_file", "ipopt.out");
 					if(AF!=no_assumption_f && AF!=unavailable_hessian && AG!=no_assumption_g) app->Options()->SetStringValue("mehrotra_algorithm", "yes");
 					
@@ -1160,14 +1175,7 @@ class OptimIpopt : public OneOperator
 					app->Initialize();
 			
 					// Ask Ipopt to solve the problem
-					try
-					{
-						status = app->OptimizeTNLP(optim);
-					}
-					catch(...)
-					{
-						cout << "error caught" << endl;
-					}
+          status = app->OptimizeTNLP(optim);
 				
 					if(lag_mul) *lag_mul = _optim->lambda_start;
 					if(l_z) *l_z = _optim->lz_start;
@@ -1179,8 +1187,14 @@ class OptimIpopt : public OneOperator
 						double *pfv = GetAny<double*>((*nargs[26])(stack));
 						*pfv = cost;
 					}
-					if(verbosity) {if(status == Solve_Succeeded) printf("\n\n*** Ipopt succeeded \n"); else printf("\n\n*** Ipopt failure!\n");}
-					
+					if(verbosity)
+					{
+						if(status == Solve_Succeeded) printf("\n\n*** Ipopt succeeded \n");
+						else if(static_cast<int>(status)<0) printf("\n\n*** Ipopt failure!\n");
+						else printf("\n\n*** Ipopt mixed results.\n");
+					}
+          
+          
 					clean(lag_mul);
 					clean(l_z);
 					clean(u_z);
@@ -1192,7 +1206,7 @@ class OptimIpopt : public OneOperator
 					if(lm) lm.destroy(); // clean memory of LM 
 					closetheparam.eval(stack); // clean memory 
 					WhereStackOfPtr2Free(stack)->clean(); // FH mars 2005 
-					return SetAny<long>(static_cast<long>(status)); //SetAny<long>(0);  Modif FH  july 2005       
+					return SetAny<long>(static_cast<long>(static_cast<int>(status))); //SetAny<long>(0);  Modif FH  july 2005
 				}
 				    
 				operator aType () const { return atype<long>();} 
@@ -1204,100 +1218,100 @@ class OptimIpopt : public OneOperator
 		//Constructors - they define the different prototype of the overloaded IPOPT function reachable in freefem scripts
 		
 		OptimIpopt(Case<no_assumption_f,no_assumption_g>) : 
-			OneOperator(atype<double>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<KN<R> *>()),
+			OneOperator(atype<long>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<KN<R> *>()),
 			AF(no_assumption_f),AG(no_assumption_g) {}
 		OptimIpopt(Case<no_assumption_f,without_constraints>) :
-			OneOperator(atype<double>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<KN<R> *>()),
+			OneOperator(atype<long>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<KN<R> *>()),
 			AF(no_assumption_f),AG(without_constraints) {}
 		OptimIpopt(Case<no_assumption_f,P1_g>) :
-			OneOperator(atype<double>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Matrice_Creuse<R> *>(),atype<KN<R> *>()),
+			OneOperator(atype<long>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Matrice_Creuse<R> *>(),atype<KN<R> *>()),
 			AF(no_assumption_f),AG(P1_g) {}
 		OptimIpopt(Case<no_assumption_f,mv_P1_g>) :
-			OneOperator(atype<double>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<E_Array>(),atype<KN<R> *>()),
+			OneOperator(atype<long>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<E_Array>(),atype<KN<R> *>()),
 			AF(no_assumption_f),AG(mv_P1_g) {}
 		OptimIpopt(Case<no_assumption_f,linear_g>) :
-			OneOperator(atype<double>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Matrice_Creuse<R>*>(),atype<KN<R> *>()),
+			OneOperator(atype<long>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Matrice_Creuse<R>*>(),atype<KN<R> *>()),
 			AF(no_assumption_f),AG(linear_g) {}
 
 
 		OptimIpopt(Case<P2_f,P1_g>) :
-			OneOperator(atype<double>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Matrice_Creuse<R> *>(),atype<Polymorphic*>(),atype<Matrice_Creuse<R> *>(),atype<KN<R> *>()),
+			OneOperator(atype<long>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Matrice_Creuse<R> *>(),atype<Polymorphic*>(),atype<Matrice_Creuse<R> *>(),atype<KN<R> *>()),
 			AF(P2_f),AG(P1_g) {}
 		OptimIpopt(Case<P2_f,without_constraints>) :
-			OneOperator(atype<double>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Matrice_Creuse<R> *>(),atype<KN<R> *>()),
+			OneOperator(atype<long>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Matrice_Creuse<R> *>(),atype<KN<R> *>()),
 			AF(P2_f),AG(without_constraints) {}
 		OptimIpopt(Case<P2_f,no_assumption_g>) :
-			OneOperator(atype<double>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Matrice_Creuse<R> *>(),atype<Polymorphic*>(),atype<Polymorphic *>(),atype<KN<R> *>()),
+			OneOperator(atype<long>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Matrice_Creuse<R> *>(),atype<Polymorphic*>(),atype<Polymorphic *>(),atype<KN<R> *>()),
 			AF(P2_f),AG(no_assumption_g) {}
 		OptimIpopt(Case<P2_f,mv_P1_g>) :
-			OneOperator(atype<double>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Matrice_Creuse<R>*>(),atype<E_Array>(),atype<KN<R> *>()),
+			OneOperator(atype<long>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Matrice_Creuse<R>*>(),atype<E_Array>(),atype<KN<R> *>()),
 			AF(P2_f),AG(mv_P1_g) {}
 		OptimIpopt(Case<P2_f,linear_g>) :
-			OneOperator(atype<double>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Matrice_Creuse<R>*>(),atype<Matrice_Creuse<R>*>(),atype<KN<R> *>()),
+			OneOperator(atype<long>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Matrice_Creuse<R>*>(),atype<Matrice_Creuse<R>*>(),atype<KN<R> *>()),
 			AF(P2_f),AG(linear_g) {}
 			
 		OptimIpopt(Case<unavailable_hessian,no_assumption_g>) :
-			OneOperator(atype<double>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<KN<R> *>()),
+			OneOperator(atype<long>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<KN<R> *>()),
 			AF(unavailable_hessian),AG(no_assumption_g) {}
 		OptimIpopt(Case<unavailable_hessian,without_constraints>) :
-			OneOperator(atype<double>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<KN<R> *>()),AF(unavailable_hessian),AG(without_constraints) {}
+			OneOperator(atype<long>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<KN<R> *>()),AF(unavailable_hessian),AG(without_constraints) {}
 		OptimIpopt(Case<unavailable_hessian,P1_g>) :
-			OneOperator(atype<double>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Matrice_Creuse<R>*>(),atype<KN<R> *>()),
+			OneOperator(atype<long>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Matrice_Creuse<R>*>(),atype<KN<R> *>()),
 			AF(unavailable_hessian),AG(P1_g) {}
 		OptimIpopt(Case<unavailable_hessian,mv_P1_g>) :
-			OneOperator(atype<double>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<E_Array>(),atype<KN<R>*>()),
+			OneOperator(atype<long>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<E_Array>(),atype<KN<R>*>()),
 			AF(unavailable_hessian),AG(mv_P1_g) {}
 		OptimIpopt(Case<unavailable_hessian,linear_g>) :
-			OneOperator(atype<double>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Matrice_Creuse<R>*>(),atype<KN<R>*>()),
+			OneOperator(atype<long>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<Matrice_Creuse<R>*>(),atype<KN<R>*>()),
 			AF(unavailable_hessian),AG(linear_g) {}
 			
 		OptimIpopt(Case<mv_P2_f,no_assumption_g>) :
-			OneOperator(atype<double>(),atype<E_Array>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<KN<R>*>()),
+			OneOperator(atype<long>(),atype<E_Array>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<KN<R>*>()),
 			AF(mv_P2_f),AG(no_assumption_g) {}
 		OptimIpopt(Case<mv_P2_f,without_constraints>) :
-			OneOperator(atype<double>(),atype<E_Array>(),atype<KN<R>*>()),
+			OneOperator(atype<long>(),atype<E_Array>(),atype<KN<R>*>()),
 			AF(mv_P2_f),AG(without_constraints) {}
 		OptimIpopt(Case<mv_P2_f,P1_g>) :
-			OneOperator(atype<double>(),atype<E_Array>(),atype<Polymorphic*>(),atype<Matrice_Creuse<R>*>(),atype<KN<R>*>()),
+			OneOperator(atype<long>(),atype<E_Array>(),atype<Polymorphic*>(),atype<Matrice_Creuse<R>*>(),atype<KN<R>*>()),
 			AF(mv_P2_f),AG(P1_g) {}
 		OptimIpopt(Case<mv_P2_f,mv_P1_g>) :
-			OneOperator(atype<double>(),atype<E_Array>(),atype<E_Array>(),atype<KN<R>*>()),
+			OneOperator(atype<long>(),atype<E_Array>(),atype<E_Array>(),atype<KN<R>*>()),
 			AF(mv_P2_f),AG(mv_P1_g) {}
 		OptimIpopt(Case<mv_P2_f,linear_g>) :
-			OneOperator(atype<double>(),atype<E_Array>(),atype<Matrice_Creuse<R>*>(),atype<KN<R>*>()),
+			OneOperator(atype<long>(),atype<E_Array>(),atype<Matrice_Creuse<R>*>(),atype<KN<R>*>()),
 			AF(mv_P2_f),AG(linear_g) {}
 		
 		OptimIpopt(Case<quadratic_f,no_assumption_g>) :
-			OneOperator(atype<double>(),atype<Matrice_Creuse<R>*>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<KN<R>*>()),
+			OneOperator(atype<long>(),atype<Matrice_Creuse<R>*>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<KN<R>*>()),
 			AF(quadratic_f),AG(no_assumption_g) {}
 		OptimIpopt(Case<quadratic_f,without_constraints>) :
-			OneOperator(atype<double>(),atype<Matrice_Creuse<R>*>(),atype<KN<R>*>()),
+			OneOperator(atype<long>(),atype<Matrice_Creuse<R>*>(),atype<KN<R>*>()),
 			AF(quadratic_f),AG(without_constraints) {}
 		OptimIpopt(Case<quadratic_f,P1_g>) :
-			OneOperator(atype<double>(),atype<Matrice_Creuse<R>*>(),atype<Polymorphic*>(),atype<Matrice_Creuse<R>*>(),atype<KN<R>*>()),
+			OneOperator(atype<long>(),atype<Matrice_Creuse<R>*>(),atype<Polymorphic*>(),atype<Matrice_Creuse<R>*>(),atype<KN<R>*>()),
 			AF(quadratic_f),AG(P1_g) {}
 		OptimIpopt(Case<quadratic_f,mv_P1_g>) :
-			OneOperator(atype<double>(),atype<Matrice_Creuse<R>*>(),atype<E_Array>(),atype<KN<R>*>()),
+			OneOperator(atype<long>(),atype<Matrice_Creuse<R>*>(),atype<E_Array>(),atype<KN<R>*>()),
 			AF(quadratic_f),AG(mv_P1_g) {}
 		OptimIpopt(Case<quadratic_f,linear_g>) :
-			OneOperator(atype<double>(),atype<Matrice_Creuse<R>*>(),atype<Matrice_Creuse<R>*>(),atype<KN<R>*>()),
+			OneOperator(atype<long>(),atype<Matrice_Creuse<R>*>(),atype<Matrice_Creuse<R>*>(),atype<KN<R>*>()),
 			AF(quadratic_f),AG(linear_g) {}
 			
 			
 		OptimIpopt(Case<linear_f,no_assumption_g>) :
-			OneOperator(atype<double>(),atype<KN<R>*>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<KN<R>*>()),
+			OneOperator(atype<long>(),atype<KN<R>*>(),atype<Polymorphic*>(),atype<Polymorphic*>(),atype<KN<R>*>()),
 			AF(linear_f),AG(no_assumption_g) {}
 		OptimIpopt(Case<linear_f,without_constraints>) :
-			OneOperator(atype<double>(),atype<KN<R>*>(),atype<KN<R>*>()),
+			OneOperator(atype<long>(),atype<KN<R>*>(),atype<KN<R>*>()),
 			AF(linear_f),AG(without_constraints) {}
 		OptimIpopt(Case<linear_f,P1_g>) :
-			OneOperator(atype<double>(),atype<KN<R>*>(),atype<Polymorphic*>(),atype<Matrice_Creuse<R>*>(),atype<KN<R>*>()),
+			OneOperator(atype<long>(),atype<KN<R>*>(),atype<Polymorphic*>(),atype<Matrice_Creuse<R>*>(),atype<KN<R>*>()),
 			AF(linear_f),AG(P1_g) {}
 		OptimIpopt(Case<linear_f,mv_P1_g>) :
-			OneOperator(atype<double>(),atype<KN<R>*>(),atype<E_Array>(),atype<KN<R>*>()),
+			OneOperator(atype<long>(),atype<KN<R>*>(),atype<E_Array>(),atype<KN<R>*>()),
 			AF(linear_f),AG(mv_P1_g) {}
 		OptimIpopt(Case<linear_f,linear_g>) :
-			OneOperator(atype<double>(),atype<KN<R>*>(),atype<Matrice_Creuse<R>*>(),atype<KN<R>*>()),
+			OneOperator(atype<long>(),atype<KN<R>*>(),atype<Matrice_Creuse<R>*>(),atype<KN<R>*>()),
 			AF(linear_f),AG(linear_g) {}
 		
 };
@@ -1377,7 +1391,9 @@ basicAC_F0::name_and_type  OptimIpopt::E_Ipopt::name_param[]=
 	{"pivtol",		&typeid(double) },											//23 -  pivot tolerance for the linear solver
 	{"brf",				&typeid(double) },											//24 -  bounds relax factor
 	{"mustrategy",&typeid(string*) },											//25 -  strategy for barrier parameter update
-	{"objvalue",  &typeid(double*) }											//26 -  to get the last objective function value
+	{"objvalue",  &typeid(double*) },											//26 -  to get the last objective function value
+	{"mumin",			&typeid(double) },											//27 -  minimal value for the barrier parameter
+  {"linesearch",&typeid(bool) }                         //28 -  use the line search or not (if no, the usual Newton step is kept)
 	//{"osf",				&typeid(double) }												//26 -  objective function scalling factor
 };
 
diff --git a/examples++-load/ff-get-dep.in b/examples++-load/ff-get-dep.in
index 9f7c52c..c15a636 100755
--- a/examples++-load/ff-get-dep.in
+++ b/examples++-load/ff-get-dep.in
@@ -20,14 +20,18 @@ case "$1" in
 	for i in $@ ; do
 	#    echo "$1" 
 	#    echo 	awk -v p="$1" -v m=INCLUDE ' ($1 == p) && ($2 == m) { for (i=3;i<=NF;++i) {print $i," ";}}' $wherelib  $wherelib-download
-         awk -v p="$i" -v m=INCLUDE ' ($1 == p) && ($2 == m) && (!first){ first=1;for (i=3;i<=NF;++i) {print $i," ";}}' "$wherelib"  "$wherelib"-config "$wherelib"-download
+	    
+	    # FFCS: print everything on the same line to avoid splitting paths containing spaces
+         awk -v p="$i" -v m=INCLUDE ' ($1 == p) && ($2 == m) && (!first){ first=1;for (i=3;i<=NF;++i) {printf("%s ",$i);}}' "$wherelib"  "$wherelib"-config "$wherelib"-download
 	done
 	
 	;;
     -l*)
 	shift;
 	for i in $@ ; do   
-	    awk -v p="$i" -v  m=LD ' ($1 == p) && ($2 == m) && (!first) {first=1; for (i=3;i<=NF;++i) {print $i," "};} 
+
+	    # FFCS: print everything on the same line to avoid splitting paths containing spaces
+	    awk -v p="$i" -v  m=LD ' ($1 == p) && ($2 == m) && (!first) {first=1; for (i=3;i<=NF;++i) {printf("%s ",$i);}} 
           END  { if(!first) print "ERROR-missing-lib:" p;} ' "$wherelib"  "$wherelib"-config "$wherelib"-download 
 	done
 	;;
@@ -49,7 +53,8 @@ case "$1" in
 	 if [ -n "$ldlibs" -o -z "$libs" ]; then
 	     echo "$cpp" "$inclins" "$ldlibs"
 	 else
-	     echo " erreur find libs of $0 :  $libs " 1>&2
+	     # FFCS - we need errors returns to insure that all compilations run well. ERROR is detected by ff-c++
+	     echo "ERROR: find libs of $0 :  $libs "
 	 fi
 	;;
   *)  
diff --git a/examples++-load/fflapack.cpp b/examples++-load/fflapack.cpp
index 6744990..824c3ea 100644
--- a/examples++-load/fflapack.cpp
+++ b/examples++-load/fflapack.cpp
@@ -834,7 +834,9 @@ KNM<R>* mult(KNM<R >* a,Mult<KNM<R >*> bc)
 	return  mult<R,init,ibeta>(a,*bc.a,bc.b->t()) ;
     else if((bc.ta == 1) && (bc.tb == 1))
 	return  mult<R,init,ibeta>(a,bc.a->t(),bc.b->t()) ;
-
+    else
+        // should never happen
+        return NULL; 
 }
 
 KNM<Complex>* SolveC(KNM<Complex>* a,Inverse<KNM<Complex >*> b) 
diff --git a/examples++-load/ffrandom.cpp b/examples++-load/ffrandom.cpp
index 61799c9..c1c9be3 100644
--- a/examples++-load/ffrandom.cpp
+++ b/examples++-load/ffrandom.cpp
@@ -14,6 +14,12 @@ using namespace std;
 #include <fstream>
 #include <ctime>
 
+// FFCS: random() and srandom() do not seem to be available in MinGW
+#ifdef WIN32
+#define random rand
+#define srandom srand
+#endif
+
 unsigned long good_seed()
 {
   unsigned long random_seed,  random_seed_a,random_seed_b;
@@ -57,6 +63,11 @@ public:
   OneOperator_0(func  ff): OneOperator(map_type[typeid(R).name()]),f(ff){}
 };
 
+// FFCS: rand() wants an int on Win32 and Win64, so we need to have a new function "long ffrandom()" to create the OneOperator
+// object which requires longs (and the MinGW compiler (g++ 4.5) refuses to compile if OneOperator and the underlying function do
+// not have the same type). FFCS patched this source with "long ffrandom(){return random();}" but FF now comes with
+// "genrand_int31()".
+
 #ifdef WIN32
 
 void init_by_array(unsigned long init_key[], int key_length);
@@ -64,13 +75,14 @@ long genrand_int31(void);
 void init_genrand(unsigned long);
 //  hach for window ... F. HEcht 
 long ffsrandom(long  s) { init_genrand( (unsigned int ) s); return 0;}
-long random() { return genrand_int31();}
+long ffrandom() { return genrand_int31();}
 long ffsrandomdev() { 
   init_genrand(good_seed());
   return 0;}
 #else 
 
 long ffsrandom(long  s) { srandom( (unsigned int ) s); return 0;}
+long ffrandom(){return random();}
 long ffsrandomdev() { 
 #ifdef HAVE_SRANDOMDEV
   srandomdev(); 
@@ -85,7 +97,7 @@ return 0;}
 void init(){
   Global.Add("srandomdev","(",new OneOperator_0<long>(ffsrandomdev));
   Global.Add("srandom","(",new OneOperator1<long>(ffsrandom));
-  Global.Add("random","(",new OneOperator_0<long>(random));
+  Global.Add("random","(",new OneOperator_0<long>(ffrandom));
 }
 LOADFUNC(init); 
 /* These real versions are due to Isaku Wada, 2002/01/09 added */
diff --git a/examples++-load/gsl.cpp b/examples++-load/gsl.cpp
index ee6e705..1ded47d 100644
--- a/examples++-load/gsl.cpp
+++ b/examples++-load/gsl.cpp
@@ -37,13 +37,16 @@
 #include <gsl/gsl_sf_zeta.h>
 #include <gsl/gsl_poly.h>
 
+#include <gsl/gsl_bspline.h>
+#include <gsl/gsl_multifit.h>
+
 #include "ff_gsl_awk.hpp"
 
 long gslpolysolvequadratic( KN_<double> a,  KN_<double> x)
 {
   ffassert(a.N()>2 && x.N()>1);
   return gsl_poly_solve_quadratic (a[2],a[1],a[0],&(x[0]),&(x[1]));
-  }
+}
 long gslpolysolvecubic( KN_<double> a,  KN_<double> x)
 {
   ffassert(a.N()>2 && x.N()>2);
@@ -61,7 +64,7 @@ long gslpolycomplexsolve( KN_<double> a,  KN_<Complex> x)
   for (long i = 0; i < n-1; i++)
     x[i] = Complex(z[2*i], z[2*i+1]);
   return ok; 
-  }
+}
 
 class Init { public:
   Init();
@@ -72,5 +75,11 @@ Init::Init(){
   Global.Add("gslpolysolvequadratic","(",new OneOperator2<long,KN_<double>,KN_<double> >( gslpolysolvequadratic));
   Global.Add("gslpolysolvecubic","(",new OneOperator2<long,KN_<double>,KN_<double> >(gslpolysolvecubic));
   Global.Add("gslpolycomplexsolve","(",new OneOperator2<long,KN_<double>,KN_<Complex> >( gslpolycomplexsolve));
-
+/* spline gsl and June 2013 */
+    /*
+    Dcl_Type<gsl_bspline_workspace**>(::InitializePtr<gsl_bspline_workspace **>,::DeletePtr<gsl_bspline_workspace **>);
+    zzzfff->Add("gslbspline",atype<gsl_bspline_workspace ** >());
+    TheOperators->Add("<-",
+                      new OneOperator3_<gsl_bspline_workspace **,gsl_bspline_workspace **,KNM_<double>  >(pBuilQFd<R1>),
+*/
 }
diff --git a/examples++-load/gsl.edp b/examples++-load/gsl.edp
index 2d17837..d40f6fc 100644
--- a/examples++-load/gsl.edp
+++ b/examples++-load/gsl.edp
@@ -110,14 +110,16 @@ cout << "gsl_sf_zetam1(0.55) =  " << gslsfzetam1(0.55)  << endl;
 cout << "gsl_sf_zetam1_int(2) =  " << gslsfzetam1int(2)  << endl; 
 cout << "gsl_sf_eta_int(1) =  " << gslsfetaint(1)  << endl; 
 cout << "gsl_sf_eta(0.55) =  " << gslsfeta(0.55)  << endl; 
-real [int] P2=[ 2,-3,1];
-real [int] P3=[ 8,-10,1,1];
+
+// FFCS - avoid using P2 and P3 which already define something very precise
+real [int] p2=[ 2,-3,1];
+real [int] p3=[ 8,-10,1,1];
 real [int] X(3);
 complex[int] Z(4);
 real [int] Q4=[ -1,0,0,0,1];
-gslpolysolvequadratic(P2,X);
+gslpolysolvequadratic(p2,X);
 cout << X[0] << " " << X[1] << endl; 
-gslpolysolvecubic(P3,X);
+gslpolysolvecubic(p3,X);
 cout << X[0] << " " << X[1] << " " << X[2] << endl; 
 gslpolycomplexsolve(Q4,Z); 
 cout << Z[0] << " " << Z[1] << " " << Z[2] << " " << Z[3] <<endl; 
diff --git a/examples++-load/iovtk.cpp b/examples++-load/iovtk.cpp
index 7f78b38..1bbc806 100644
--- a/examples++-load/iovtk.cpp
+++ b/examples++-load/iovtk.cpp
@@ -2455,6 +2455,7 @@ AnyType VTK_WriteMesh_Op::operator()(Stack stack)  const
   }
 
   delete [] pch;
+  return (Mesh *) NULL;
 }
 
 
@@ -3912,6 +3913,7 @@ AnyType VTK_WriteMesh3_Op::operator()(Stack stack)  const
     delete [] nameofuser[iiii];
   }
   delete [] pch;
+  return (Mesh3 *) NULL;
 }
 //==============================================
 // FIN ECRITURE DE FICHIER .vtk (3D)
diff --git a/examples++-load/lap-solvers.edp b/examples++-load/lap-solvers.edp
index c782129..54f55eb 100644
--- a/examples++-load/lap-solvers.edp
+++ b/examples++-load/lap-solvers.edp
@@ -27,4 +27,3 @@ defaulttoSuperLU();
 cpu=clock() ;
 laplace0; // solve the problem plot(uh); // to see the result
 cout << "-- lap SuperLU " << nn << "x" << nn << "  : " <<  -cpu+clock() << " s,  max =" << uh[].max << endl;
-uh=0;
diff --git a/examples++-load/lapack.cpp b/examples++-load/lapack.cpp
index dad0cb9..0d28dbf 100644
--- a/examples++-load/lapack.cpp
+++ b/examples++-load/lapack.cpp
@@ -834,7 +834,9 @@ KNM<R>* mult(KNM<R >* a,Mult<KNM<R >*> bc)
 	return  mult<R,init,ibeta>(a,*bc.a,bc.b->t()) ;
     else if((bc.ta == 1) && (bc.tb == 1))
 	return  mult<R,init,ibeta>(a,bc.a->t(),bc.b->t()) ;
-
+    else
+        // should never happen
+        return NULL;
 }
 
 KNM<Complex>* SolveC(KNM<Complex>* a,Inverse<KNM<Complex >*> b) 
diff --git a/examples++-load/lapack.edp b/examples++-load/lapack.edp
index cc5d87b..1fbbf08 100644
--- a/examples++-load/lapack.edp
+++ b/examples++-load/lapack.edp
@@ -93,6 +93,9 @@ cout << B << endl;
   // A1+A^-1;  attention ne marche pas 
 }
 
+// FFCS - value for regression checks
+real regtest=0;
+
 {
 
 int n=5;
@@ -147,5 +150,8 @@ assert( C.linfty < 1e-10);
 C = A*B;
 C -=E; 
 assert( C.linfty < 1e-10);
+
+// FFCS - value for regression checks
+regtest=C.linfty;
+}
 }
-}
\ No newline at end of file
diff --git a/examples++-load/load.link.in b/examples++-load/load.link.in
index e0a7652..89d5f9f 100755
--- a/examples++-load/load.link.in
+++ b/examples++-load/load.link.in
@@ -9,6 +9,7 @@ FFCXXFLAGS='@CXXFLAGS@ @CPPFLAGS@'
 FFFFLAGS='@FFLAGS@'
 FFFLIBS='@FLIBS@'
 INCFF=
+if [ "@ENABLE_FFCS@" != "yes" ] ;then ffcs=0; else ffcs=1;fi 
 if [ -z "$CXX" ] ; then CXX='@CXX@' ; fi
 if [ -z "$MPICXX" ] ; then MPICXX="@MPICXX@" ; fi
 if [ -z "$MPI_LIB" ] ; then MPI_LIB="@MPI_LIB@" ; fi
@@ -123,7 +124,7 @@ while [ $# -ne 0 ]  ; do
 	-I*)    INC="$INC '$1'";;
 	-D*)    INC="$INC '$1'";;
 	-dll)   DLL="$DLL '$2'";shift;;
-	-[Ll]*)    LIBS="$LIBS $1" ;;
+	-[Ll]*)    LIBS="$LIBS '$1'" ;; # FFCS - 27/10/11 - need quotes for MPICH libraries in 'Program Files' under Windows
 	*.a)     LIBS="$LIBS $1" ;;
 	*.so)    LIBS="$LIBS $1" ;;
 	*.dll)   if [ -f "$1" ] ; then  LIBS="$LIBS '$1'"  
@@ -145,6 +146,11 @@ while [ $# -ne 0 ]  ; do
     esac
     shift
 done
+
+#  remove old file... FH sep 2013..
+SUF=@DYLIB_SUFFIX@
+rm $out.$SUF
+
 if [ -n "$autodep"  ] ; then
 #    echo "$thecommand" $args  `eval "'$dircommand/ff-get-dep'" -ff $files`
     argsdep=`eval "'$dircommand/ff-get-dep'" -ff $files`
@@ -152,11 +158,18 @@ if [ -n "$autodep"  ] ; then
      error=`echo "$argsdep"| grep ERROR`
      if [ -n "$error" ] ; then
 	 echo " ERROR in  auto dependance seach.  sorry : $error "
-	 exit 0;
+
+	 # FFCS - 28/11/11 - we need to stop compiling as soon as there is an error because we want a fixed set of features in
+	 # FFCS
+	 # return a error when FFCS enable .. FH. 
+	 echo " -- $error " >>Missing-plugins- at DYLIB_SUFFIX@.log
+	 exit $ffcs;
      fi
     echo eval "$thecommand" $args  $argsdep
     eval "$thecommand" $args  $argsdep
-    exit 0;
+
+    # FFCS needs an error exit code to make sure that all libraries are correctly compiled
+    exit $?;
 fi
 
 if [  -n "$onwin32" -a ! -f "$bin/libff.dll"  ] ; then 
@@ -174,29 +187,34 @@ if [ -n "$withmpi" ]; then  CXX=$MPICXX;fi
 test "$withmpi" = "yes" && WMPI_LIB="$MPI_LIB"
 
 INC="$INCFF $INC"  
-SUF=so
 SHARED="-shared"
 case "$WIN32$uu" in
     Darwin*) 
 #        echo "export MACOSX_DEPLOYMENT_TARGET=10.3"
 #	export MACOSX_DEPLOYMENT_TARGET=10.4
-	SUF=dylib
+#	SUF=dylib
 	SHARED="-bundle -undefined dynamic_lookup"  ;;
     win32-CYGWIN*|win32-win32)
         echo " Window without cygwin "
 	WMPI_LIB=''
         b="$bin"
-        LIBS=" '$b/libff.dll' $LIBS $DLL"
-        SHARED="-shared  -Wl,--enable-auto-import" #--unresolved-symbols=ignore-all
-        FLAGS= # '  -mno-cygwin '
-        SUF=dll;;
+        LIBS=" '$b/libff.dll' '$b/FreeFem++-api.dll' $LIBS $DLL"
+
+	# FFCS - 17/10/12 - --unresolved-symbols=ignore-all is not understood by the current mingw64 compilers
+        SHARED="-shared -Wl,--enable-auto-import"
+
+	# FFCS - 17/10/12 - -mno-cygwin is not understood by the current mingw64 compilers
+        ###FLAGS='  -mno-cygwin '
+#        SUF=dll
+	;;
     win32-cygwin-version)
         echo " cygwin-version "
 	WMPI_LIB=''
         b=$bin
         FLAGS=' '
         LIBS="'$b/libff.dll' $LIBS $DLL"
-        SUF=dll;;
+#        SUF=dll
+	;;
     FreeBSD|NetBSD)
 	SHARED="-shared" 
 	FLAGS='-fPIC';;
diff --git a/examples++-load/mat_psi.cpp b/examples++-load/mat_psi.cpp
index 96d2b64..81c1153 100644
--- a/examples++-load/mat_psi.cpp
+++ b/examples++-load/mat_psi.cpp
@@ -193,6 +193,7 @@ AnyType MatrixUpWind0::operator()(Stack stack) const
 int   Marco(const Mesh3::Element & K, R3 U,R c[4], double a[4][4] )  //PSI Deconninck
 {
     ExecError("Not Implemented Sorry Marco!");
+    return 0;
 }
 AnyType MatrixUpWind3::operator()(Stack stack) const 
 {
diff --git a/examples++-load/medit.cpp b/examples++-load/medit.cpp
index 843e067..1ed8101 100644
--- a/examples++-load/medit.cpp
+++ b/examples++-load/medit.cpp
@@ -28,7 +28,7 @@
  Thank to the ARN ()  FF2A3 grant
  ref:ANR-07-CIS7-002-01 
  */
-#include "mode_open.hpp"
+#include "../src/Graphics/mode_open.hpp" // ALH - there should be a '-I'?
 #include "ff++.hpp"
 #define WrdSiz 4
 
diff --git a/examples++-load/msh3.cpp b/examples++-load/msh3.cpp
index 706a990..efe4303 100644
--- a/examples++-load/msh3.cpp
+++ b/examples++-load/msh3.cpp
@@ -2405,6 +2405,9 @@ AnyType SetMesh3D_Op::operator()(Stack stack)  const
       
       return mpq;
     }
+
+  Mesh3 *mpq = NULL;
+  return mpq;
 }
 
 
@@ -5446,6 +5449,13 @@ AnyType ExtractMesh2D_Op::operator()(Stack stack)  const
 		
 		
 		Mesh *pThnew = new Mesh(nv,nt,ns,v,t,b);  // attention aux composantes connexes.
+		//Lorenzo
+		R2 Pn,Px;
+		pThnew->BoundingBox(Pn,Px);
+		if(!pThnew->quadtree)
+			pThnew->quadtree=new Fem2D::FQuadTree(pTh,Pn,Px,pTh->nv);
+		//Lorenzo
+				
 		return pThnew;
 		
 	}
@@ -5696,7 +5706,7 @@ AnyType ExtractMesh_Op::operator()(Stack stack)  const
     
     Mesh3 *pThnew = new Mesh3(nv,nt,ns,v,t,b);  // peut etre a définir ???
     // attention aux composantes connexes.
-		
+	pThnew->BuildGTree();  //Lorenzo
     
     return pThnew;
     
@@ -5757,10 +5767,12 @@ AnyType ExtractMesh_Op::operator()(Stack stack)  const
     
     cout <<" nv" << nv << " ns " << endl;  
     Mesh3 *pThnew = new Mesh3(nv,ns,v,b);  
-		
+	pThnew->BuildGTree();  //Lorenzo	
     return pThnew;    
   }
-
+   
+  Mesh3 *pThnew = NULL;
+  return pThnew;    
 }
 
 
diff --git a/examples++-load/newuoa.f b/examples++-load/newuoa.f
index 97d648d..ef003a0 100644
--- a/examples++-load/newuoa.f
+++ b/examples++-load/newuoa.f
@@ -1,1455 +1,1455 @@
-C  version modif by F. HECHT
-C ---------------------------
-C The code in fortran is totally free, and the interface is under LGPL 
-C http://www.inrialpes.fr/bipop/people/guilbert/newuoa/newuoa.pdf 
-C  original source :
-C http://www.inrialpees.fr/bipop/people/guilbert/newuoa/newuoa.tar.gz
-C --------------------
-      SUBROUTINE BIGDEN (N,NPT,XOPT,XPT,BMAT,ZMAT,IDZ,NDIM,KOPT,
-     1  KNEW,D,W,VLAG,BETA,S,WVEC,PROD)
-      IMPLICIT REAL*8 (A-H,O-Z)
-      DIMENSION XOPT(*),XPT(NPT,*),BMAT(NDIM,*),ZMAT(NPT,*),D(*),
-     1  W(*),VLAG(*),S(*),WVEC(NDIM,*),PROD(NDIM,*)
-      DIMENSION DEN(9),DENEX(9),PAR(9)
-C
-C     N is the number of variables.
-C     NPT is the number of interpolation equations.
-C     XOPT is the best interpolation point so far.
-C     XPT contains the coordinates of the current interpolation points.
-C     BMAT provides the last N columns of H.
-C     ZMAT and IDZ give a factorization of the first NPT by NPT submatrix of H.
-C     NDIM is the first dimension of BMAT and has the value NPT+N.
-C     KOPT is the index of the optimal interpolation point.
-C     KNEW is the index of the interpolation point that is going to be moved.
-C     D will be set to the step from XOPT to the new point, and on entry it
-C       should be the D that was calculated by the last call of BIGLAG. The
-C       length of the initial D provides a trust region bound on the final D.
-C     W will be set to Wcheck for the final choice of D.
-C     VLAG will be set to Theta*Wcheck+e_b for the final choice of D.
-C     BETA will be set to the value that will occur in the updating formula
-C       when the KNEW-th interpolation point is moved to its new position.
-C     S, WVEC, PROD and the private arrays DEN, DENEX and PAR will be used
-C       for working space.
-C
-C     D is calculated in a way that should provide a denominator with a large
-C     modulus in the updating formula when the KNEW-th interpolation point is
-C     shifted to the new position XOPT+D.
-C
-C     Set some constants.
-C
-      HALF=0.5D0
-      ONE=1.0D0
-      QUART=0.25D0
-      TWO=2.0D0
-      ZERO=0.0D0
-      TWOPI=8.0D0*DATAN(ONE)
-      NPTM=NPT-N-1
-C
-C     Store the first NPT elements of the KNEW-th column of H in W(N+1)
-C     to W(N+NPT).
-C
-      DO 10 K=1,NPT
-   10 W(N+K)=ZERO
-      DO 20 J=1,NPTM
-      TEMP=ZMAT(KNEW,J)
-      IF (J .LT. IDZ) TEMP=-TEMP
-      DO 20 K=1,NPT
-   20 W(N+K)=W(N+K)+TEMP*ZMAT(K,J)
-      ALPHA=W(N+KNEW)
-C
-C     The initial search direction D is taken from the last call of BIGLAG,
-C     and the initial S is set below, usually to the direction from X_OPT
-C     to X_KNEW, but a different direction to an interpolation point may
-C     be chosen, in order to prevent S from being nearly parallel to D.
-C
-      DD=ZERO
-      DS=ZERO
-      SS=ZERO
-      XOPTSQ=ZERO
-      DO 30 I=1,N
-      DD=DD+D(I)**2
-      S(I)=XPT(KNEW,I)-XOPT(I)
-      DS=DS+D(I)*S(I)
-      SS=SS+S(I)**2
-   30 XOPTSQ=XOPTSQ+XOPT(I)**2
-      IF (DS*DS .GT. 0.99D0*DD*SS) THEN
-          KSAV=KNEW
-          DTEST=DS*DS/SS
-          DO 50 K=1,NPT
-          IF (K .NE. KOPT) THEN
-              DSTEMP=ZERO
-              SSTEMP=ZERO
-              DO 40 I=1,N
-              DIFF=XPT(K,I)-XOPT(I)
-              DSTEMP=DSTEMP+D(I)*DIFF
-   40         SSTEMP=SSTEMP+DIFF*DIFF
-              IF (DSTEMP*DSTEMP/SSTEMP .LT. DTEST) THEN
-                  KSAV=K
-                  DTEST=DSTEMP*DSTEMP/SSTEMP
-                  DS=DSTEMP
-                  SS=SSTEMP
-              END IF
-          END IF
-   50     CONTINUE
-          DO 60 I=1,N
-   60     S(I)=XPT(KSAV,I)-XOPT(I)
-      END IF
-      SSDEN=DD*SS-DS*DS
-      ITERC=0
-      DENSAV=ZERO
-C
-C     Begin the iteration by overwriting S with a vector that has the
-C     required length and direction.
-C
-   70 ITERC=ITERC+1
-      TEMP=ONE/DSQRT(SSDEN)
-      XOPTD=ZERO
-      XOPTS=ZERO
-      DO 80 I=1,N
-      S(I)=TEMP*(DD*S(I)-DS*D(I))
-      XOPTD=XOPTD+XOPT(I)*D(I)
-   80 XOPTS=XOPTS+XOPT(I)*S(I)
-C
-C     Set the coefficients of the first two terms of BETA.
-C
-      TEMPA=HALF*XOPTD*XOPTD
-      TEMPB=HALF*XOPTS*XOPTS
-      DEN(1)=DD*(XOPTSQ+HALF*DD)+TEMPA+TEMPB
-      DEN(2)=TWO*XOPTD*DD
-      DEN(3)=TWO*XOPTS*DD
-      DEN(4)=TEMPA-TEMPB
-      DEN(5)=XOPTD*XOPTS
-      DO 90 I=6,9
-   90 DEN(I)=ZERO
-C
-C     Put the coefficients of Wcheck in WVEC.
-C
-      DO 110 K=1,NPT
-      TEMPA=ZERO
-      TEMPB=ZERO
-      TEMPC=ZERO
-      DO 100 I=1,N
-      TEMPA=TEMPA+XPT(K,I)*D(I)
-      TEMPB=TEMPB+XPT(K,I)*S(I)
-  100 TEMPC=TEMPC+XPT(K,I)*XOPT(I)
-      WVEC(K,1)=QUART*(TEMPA*TEMPA+TEMPB*TEMPB)
-      WVEC(K,2)=TEMPA*TEMPC
-      WVEC(K,3)=TEMPB*TEMPC
-      WVEC(K,4)=QUART*(TEMPA*TEMPA-TEMPB*TEMPB)
-  110 WVEC(K,5)=HALF*TEMPA*TEMPB
-      DO 120 I=1,N
-      IP=I+NPT
-      WVEC(IP,1)=ZERO
-      WVEC(IP,2)=D(I)
-      WVEC(IP,3)=S(I)
-      WVEC(IP,4)=ZERO
-  120 WVEC(IP,5)=ZERO
-C
-C     Put the coefficents of THETA*Wcheck in PROD.
-C
-      DO 190 JC=1,5
-      NW=NPT
-      IF (JC .EQ. 2 .OR. JC .EQ. 3) NW=NDIM
-      DO 130 K=1,NPT
-  130 PROD(K,JC)=ZERO
-      DO 150 J=1,NPTM
-      SUM=ZERO
-      DO 140 K=1,NPT
-  140 SUM=SUM+ZMAT(K,J)*WVEC(K,JC)
-      IF (J .LT. IDZ) SUM=-SUM
-      DO 150 K=1,NPT
-  150 PROD(K,JC)=PROD(K,JC)+SUM*ZMAT(K,J)
-      IF (NW .EQ. NDIM) THEN
-          DO 170 K=1,NPT
-          SUM=ZERO
-          DO 160 J=1,N
-  160     SUM=SUM+BMAT(K,J)*WVEC(NPT+J,JC)
-  170     PROD(K,JC)=PROD(K,JC)+SUM
-      END IF
-      DO 190 J=1,N
-      SUM=ZERO
-      DO 180 I=1,NW
-  180 SUM=SUM+BMAT(I,J)*WVEC(I,JC)
-  190 PROD(NPT+J,JC)=SUM
-C
-C     Include in DEN the part of BETA that depends on THETA.
-C
-      DO 210 K=1,NDIM
-      SUM=ZERO
-      DO 200 I=1,5
-      PAR(I)=HALF*PROD(K,I)*WVEC(K,I)
-  200 SUM=SUM+PAR(I)
-      DEN(1)=DEN(1)-PAR(1)-SUM
-      TEMPA=PROD(K,1)*WVEC(K,2)+PROD(K,2)*WVEC(K,1)
-      TEMPB=PROD(K,2)*WVEC(K,4)+PROD(K,4)*WVEC(K,2)
-      TEMPC=PROD(K,3)*WVEC(K,5)+PROD(K,5)*WVEC(K,3)
-      DEN(2)=DEN(2)-TEMPA-HALF*(TEMPB+TEMPC)
-      DEN(6)=DEN(6)-HALF*(TEMPB-TEMPC)
-      TEMPA=PROD(K,1)*WVEC(K,3)+PROD(K,3)*WVEC(K,1)
-      TEMPB=PROD(K,2)*WVEC(K,5)+PROD(K,5)*WVEC(K,2)
-      TEMPC=PROD(K,3)*WVEC(K,4)+PROD(K,4)*WVEC(K,3)
-      DEN(3)=DEN(3)-TEMPA-HALF*(TEMPB-TEMPC)
-      DEN(7)=DEN(7)-HALF*(TEMPB+TEMPC)
-      TEMPA=PROD(K,1)*WVEC(K,4)+PROD(K,4)*WVEC(K,1)
-      DEN(4)=DEN(4)-TEMPA-PAR(2)+PAR(3)
-      TEMPA=PROD(K,1)*WVEC(K,5)+PROD(K,5)*WVEC(K,1)
-      TEMPB=PROD(K,2)*WVEC(K,3)+PROD(K,3)*WVEC(K,2)
-      DEN(5)=DEN(5)-TEMPA-HALF*TEMPB
-      DEN(8)=DEN(8)-PAR(4)+PAR(5)
-      TEMPA=PROD(K,4)*WVEC(K,5)+PROD(K,5)*WVEC(K,4)
-  210 DEN(9)=DEN(9)-HALF*TEMPA
-C
-C     Extend DEN so that it holds all the coefficients of DENOM.
-C
-      SUM=ZERO
-      DO 220 I=1,5
-      PAR(I)=HALF*PROD(KNEW,I)**2
-  220 SUM=SUM+PAR(I)
-      DENEX(1)=ALPHA*DEN(1)+PAR(1)+SUM
-      TEMPA=TWO*PROD(KNEW,1)*PROD(KNEW,2)
-      TEMPB=PROD(KNEW,2)*PROD(KNEW,4)
-      TEMPC=PROD(KNEW,3)*PROD(KNEW,5)
-      DENEX(2)=ALPHA*DEN(2)+TEMPA+TEMPB+TEMPC
-      DENEX(6)=ALPHA*DEN(6)+TEMPB-TEMPC
-      TEMPA=TWO*PROD(KNEW,1)*PROD(KNEW,3)
-      TEMPB=PROD(KNEW,2)*PROD(KNEW,5)
-      TEMPC=PROD(KNEW,3)*PROD(KNEW,4)
-      DENEX(3)=ALPHA*DEN(3)+TEMPA+TEMPB-TEMPC
-      DENEX(7)=ALPHA*DEN(7)+TEMPB+TEMPC
-      TEMPA=TWO*PROD(KNEW,1)*PROD(KNEW,4)
-      DENEX(4)=ALPHA*DEN(4)+TEMPA+PAR(2)-PAR(3)
-      TEMPA=TWO*PROD(KNEW,1)*PROD(KNEW,5)
-      DENEX(5)=ALPHA*DEN(5)+TEMPA+PROD(KNEW,2)*PROD(KNEW,3)
-      DENEX(8)=ALPHA*DEN(8)+PAR(4)-PAR(5)
-      DENEX(9)=ALPHA*DEN(9)+PROD(KNEW,4)*PROD(KNEW,5)
-C
-C     Seek the value of the angle that maximizes the modulus of DENOM.
-C
-      SUM=DENEX(1)+DENEX(2)+DENEX(4)+DENEX(6)+DENEX(8)
-      DENOLD=SUM
-      DENMAX=SUM
-      ISAVE=0
-      IU=49
-      TEMP=TWOPI/DFLOAT(IU+1)
-      PAR(1)=ONE
-      DO 250 I=1,IU
-      ANGLE=DFLOAT(I)*TEMP
-      PAR(2)=DCOS(ANGLE)
-      PAR(3)=DSIN(ANGLE)
-      DO 230 J=4,8,2
-      PAR(J)=PAR(2)*PAR(J-2)-PAR(3)*PAR(J-1)
-  230 PAR(J+1)=PAR(2)*PAR(J-1)+PAR(3)*PAR(J-2)
-      SUMOLD=SUM
-      SUM=ZERO
-      DO 240 J=1,9
-  240 SUM=SUM+DENEX(J)*PAR(J)
-      IF (DABS(SUM) .GT. DABS(DENMAX)) THEN
-          DENMAX=SUM
-          ISAVE=I
-          TEMPA=SUMOLD
-      ELSE IF (I .EQ. ISAVE+1) THEN
-          TEMPB=SUM
-      END IF
-  250 CONTINUE
-      IF (ISAVE .EQ. 0) TEMPA=SUM
-      IF (ISAVE .EQ. IU) TEMPB=DENOLD
-      STEP=ZERO
-      IF (TEMPA .NE. TEMPB) THEN
-          TEMPA=TEMPA-DENMAX
-          TEMPB=TEMPB-DENMAX
-          STEP=HALF*(TEMPA-TEMPB)/(TEMPA+TEMPB)
-      END IF
-      ANGLE=TEMP*(DFLOAT(ISAVE)+STEP)
-C
-C     Calculate the new parameters of the denominator, the new VLAG vector
-C     and the new D. Then test for convergence.
-C
-      PAR(2)=DCOS(ANGLE)
-      PAR(3)=DSIN(ANGLE)
-      DO 260 J=4,8,2
-      PAR(J)=PAR(2)*PAR(J-2)-PAR(3)*PAR(J-1)
-  260 PAR(J+1)=PAR(2)*PAR(J-1)+PAR(3)*PAR(J-2)
-      BETA=ZERO
-      DENMAX=ZERO
-      DO 270 J=1,9
-      BETA=BETA+DEN(J)*PAR(J)
-  270 DENMAX=DENMAX+DENEX(J)*PAR(J)
-      DO 280 K=1,NDIM
-      VLAG(K)=ZERO
-      DO 280 J=1,5
-  280 VLAG(K)=VLAG(K)+PROD(K,J)*PAR(J)
-      TAU=VLAG(KNEW)
-      DD=ZERO
-      TEMPA=ZERO
-      TEMPB=ZERO
-      DO 290 I=1,N
-      D(I)=PAR(2)*D(I)+PAR(3)*S(I)
-      W(I)=XOPT(I)+D(I)
-      DD=DD+D(I)**2
-      TEMPA=TEMPA+D(I)*W(I)
-  290 TEMPB=TEMPB+W(I)*W(I)
-      IF (ITERC .GE. N) GOTO 340
-      IF (ITERC .GT. 1) DENSAV=DMAX1(DENSAV,DENOLD)
-      IF (DABS(DENMAX) .LE. 1.1D0*DABS(DENSAV)) GOTO 340
-      DENSAV=DENMAX
-C
-C     Set S to half the gradient of the denominator with respect to D.
-C     Then branch for the next iteration.
-C
-      DO 300 I=1,N
-      TEMP=TEMPA*XOPT(I)+TEMPB*D(I)-VLAG(NPT+I)
-  300 S(I)=TAU*BMAT(KNEW,I)+ALPHA*TEMP
-      DO 320 K=1,NPT
-      SUM=ZERO
-      DO 310 J=1,N
-  310 SUM=SUM+XPT(K,J)*W(J)
-      TEMP=(TAU*W(N+K)-ALPHA*VLAG(K))*SUM
-      DO 320 I=1,N
-  320 S(I)=S(I)+TEMP*XPT(K,I)
-      SS=ZERO
-      DS=ZERO
-      DO 330 I=1,N
-      SS=SS+S(I)**2
-  330 DS=DS+D(I)*S(I)
-      SSDEN=DD*SS-DS*DS
-      IF (SSDEN .GE. 1.0D-8*DD*SS) GOTO 70
-C
-C     Set the vector W before the RETURN from the subroutine.
-C
-  340 DO 350 K=1,NDIM
-      W(K)=ZERO
-      DO 350 J=1,5
-  350 W(K)=W(K)+WVEC(K,J)*PAR(J)
-      VLAG(KOPT)=VLAG(KOPT)+ONE
-      RETURN
-      END 
-      SUBROUTINE BIGLAG (N,NPT,XOPT,XPT,BMAT,ZMAT,IDZ,NDIM,KNEW,
-     1  DELTA,D,ALPHA,HCOL,GC,GD,S,W)
-      IMPLICIT REAL*8 (A-H,O-Z)
-      DIMENSION XOPT(*),XPT(NPT,*),BMAT(NDIM,*),ZMAT(NPT,*),D(*),
-     1  HCOL(*),GC(*),GD(*),S(*),W(*)
-C
-C     N is the number of variables.
-C     NPT is the number of interpolation equations.
-C     XOPT is the best interpolation point so far.
-C     XPT contains the coordinates of the current interpolation points.
-C     BMAT provides the last N columns of H.
-C     ZMAT and IDZ give a factorization of the first NPT by NPT submatrix of H.
-C     NDIM is the first dimension of BMAT and has the value NPT+N.
-C     KNEW is the index of the interpolation point that is going to be moved.
-C     DELTA is the current trust region bound.
-C     D will be set to the step from XOPT to the new point.
-C     ALPHA will be set to the KNEW-th diagonal element of the H matrix.
-C     HCOL, GC, GD, S and W will be used for working space.
-C
-C     The step D is calculated in a way that attempts to maximize the modulus
-C     of LFUNC(XOPT+D), subject to the bound ||D|| .LE. DELTA, where LFUNC is
-C     the KNEW-th Lagrange function.
-C
-C     Set some constants.
-C
-      HALF=0.5D0
-      ONE=1.0D0
-      ZERO=0.0D0
-      TWOPI=8.0D0*DATAN(ONE)
-      DELSQ=DELTA*DELTA
-      NPTM=NPT-N-1
-C
-C     Set the first NPT components of HCOL to the leading elements of the
-C     KNEW-th column of H.
-C
-      ITERC=0
-      DO 10 K=1,NPT
-   10 HCOL(K)=ZERO
-      DO 20 J=1,NPTM
-      TEMP=ZMAT(KNEW,J)
-      IF (J .LT. IDZ) TEMP=-TEMP
-      DO 20 K=1,NPT
-   20 HCOL(K)=HCOL(K)+TEMP*ZMAT(K,J)
-      ALPHA=HCOL(KNEW)
-C
-C     Set the unscaled initial direction D. Form the gradient of LFUNC at
-C     XOPT, and multiply D by the second derivative matrix of LFUNC.
-C
-      DD=ZERO
-      DO 30 I=1,N
-      D(I)=XPT(KNEW,I)-XOPT(I)
-      GC(I)=BMAT(KNEW,I)
-      GD(I)=ZERO
-   30 DD=DD+D(I)**2
-      DO 50 K=1,NPT
-      TEMP=ZERO
-      SUM=ZERO
-      DO 40 J=1,N
-      TEMP=TEMP+XPT(K,J)*XOPT(J)
-   40 SUM=SUM+XPT(K,J)*D(J)
-      TEMP=HCOL(K)*TEMP
-      SUM=HCOL(K)*SUM
-      DO 50 I=1,N
-      GC(I)=GC(I)+TEMP*XPT(K,I)
-   50 GD(I)=GD(I)+SUM*XPT(K,I)
-C
-C     Scale D and GD, with a sign change if required. Set S to another
-C     vector in the initial two dimensional subspace.
-C
-      GG=ZERO
-      SP=ZERO
-      DHD=ZERO
-      DO 60 I=1,N
-      GG=GG+GC(I)**2
-      SP=SP+D(I)*GC(I)
-   60 DHD=DHD+D(I)*GD(I)
-      SCALE=DELTA/DSQRT(DD)
-      IF (SP*DHD .LT. ZERO) SCALE=-SCALE
-      TEMP=ZERO
-      IF (SP*SP .GT. 0.99D0*DD*GG) TEMP=ONE
-      TAU=SCALE*(DABS(SP)+HALF*SCALE*DABS(DHD))
-      IF (GG*DELSQ .LT. 0.01D0*TAU*TAU) TEMP=ONE
-      DO 70 I=1,N
-      D(I)=SCALE*D(I)
-      GD(I)=SCALE*GD(I)
-   70 S(I)=GC(I)+TEMP*GD(I)
-C
-C     Begin the iteration by overwriting S with a vector that has the
-C     required length and direction, except that termination occurs if
-C     the given D and S are nearly parallel.
-C
-   80 ITERC=ITERC+1
-      DD=ZERO
-      SP=ZERO
-      SS=ZERO
-      DO 90 I=1,N
-      DD=DD+D(I)**2
-      SP=SP+D(I)*S(I)
-   90 SS=SS+S(I)**2
-      TEMP=DD*SS-SP*SP
-      IF (TEMP .LE. 1.0D-8*DD*SS) GOTO 160
-      DENOM=DSQRT(TEMP)
-      DO 100 I=1,N
-      S(I)=(DD*S(I)-SP*D(I))/DENOM
-  100 W(I)=ZERO
-C
-C     Calculate the coefficients of the objective function on the circle,
-C     beginning with the multiplication of S by the second derivative matrix.
-C
-      DO 120 K=1,NPT
-      SUM=ZERO
-      DO 110 J=1,N
-  110 SUM=SUM+XPT(K,J)*S(J)
-      SUM=HCOL(K)*SUM
-      DO 120 I=1,N
-  120 W(I)=W(I)+SUM*XPT(K,I)
-      CF1=ZERO
-      CF2=ZERO
-      CF3=ZERO
-      CF4=ZERO
-      CF5=ZERO
-      DO 130 I=1,N
-      CF1=CF1+S(I)*W(I)
-      CF2=CF2+D(I)*GC(I)
-      CF3=CF3+S(I)*GC(I)
-      CF4=CF4+D(I)*GD(I)
-  130 CF5=CF5+S(I)*GD(I)
-      CF1=HALF*CF1
-      CF4=HALF*CF4-CF1
-C
-C     Seek the value of the angle that maximizes the modulus of TAU.
-C
-      TAUBEG=CF1+CF2+CF4
-      TAUMAX=TAUBEG
-      TAUOLD=TAUBEG
-      ISAVE=0
-      IU=49
-      TEMP=TWOPI/DFLOAT(IU+1)
-      DO 140 I=1,IU
-      ANGLE=DFLOAT(I)*TEMP
-      CTH=DCOS(ANGLE)
-      STH=DSIN(ANGLE)
-      TAU=CF1+(CF2+CF4*CTH)*CTH+(CF3+CF5*CTH)*STH
-      IF (DABS(TAU) .GT. DABS(TAUMAX)) THEN
-          TAUMAX=TAU
-          ISAVE=I
-          TEMPA=TAUOLD
-      ELSE IF (I .EQ. ISAVE+1) THEN
-          TEMPB=TAU
-      END IF
-  140 TAUOLD=TAU
-      IF (ISAVE .EQ. 0) TEMPA=TAU
-      IF (ISAVE .EQ. IU) TEMPB=TAUBEG
-      STEP=ZERO
-      IF (TEMPA .NE. TEMPB) THEN
-          TEMPA=TEMPA-TAUMAX
-          TEMPB=TEMPB-TAUMAX
-          STEP=HALF*(TEMPA-TEMPB)/(TEMPA+TEMPB)
-      END IF
-      ANGLE=TEMP*(DFLOAT(ISAVE)+STEP)
-C
-C     Calculate the new D and GD. Then test for convergence.
-C
-      CTH=DCOS(ANGLE)
-      STH=DSIN(ANGLE)
-      TAU=CF1+(CF2+CF4*CTH)*CTH+(CF3+CF5*CTH)*STH
-      DO 150 I=1,N
-      D(I)=CTH*D(I)+STH*S(I)
-      GD(I)=CTH*GD(I)+STH*W(I)
-  150 S(I)=GC(I)+GD(I)
-      IF (DABS(TAU) .LE. 1.1D0*DABS(TAUBEG)) GOTO 160
-      IF (ITERC .LT. N) GOTO 80
-  160 RETURN
-      END 
-      FUNCTION NEWUOA (N,NPT,X,RHOBEG,RHOEND,IPRINT,MAXFUN,W,IWF,
-     1  CALFUN)
-      IMPLICIT REAL*8 (A-H,O-Z)
-      DIMENSION X(*),W(*),IWF(*)
-      EXTERNAL CALFUN
-      real*8 NEWUOB, NEWUOA
-C
-C     This subroutine seeks the least value of a function of many variables,
-C     by a trust region method that forms quadratic models by interpolation.
-C     There can be some freedom in the interpolation conditions, which is
-C     taken up by minimizing the Frobenius norm of the change to the second
-C     derivative of the quadratic model, beginning with a zero matrix. The
-C     arguments of the subroutine are as follows.
-C
-C     N must be set to the number of variables and must be at least two.
-C     NPT is the number of interpolation conditions. Its value must be in the
-C       interval [N+2,(N+1)(N+2)/2].
-C     Initial values of the variables must be set in X(1),X(2),...,X(N). They
-C       will be changed to the values that give the least calculated F.
-C     RHOBEG and RHOEND must be set to the initial and final values of a trust
-C       region radius, so both must be positive with RHOEND<=RHOBEG. Typically
-C       RHOBEG should be about one tenth of the greatest expected change to a
-C       variable, and RHOEND should indicate the accuracy that is required in
-C       the final values of the variables.
-C     The value of IPRINT should be set to 0, 1, 2 or 3, which controls the
-C       amount of printing. Specifically, there is no output if IPRINT=0 and
-C       there is output only at the return if IPRINT=1. Otherwise, each new
-C       value of RHO is printed, with the best vector of variables so far and
-C       the corresponding value of the objective function. Further, each new
-C       value of F with its variables are output if IPRINT=3.
-C     MAXFUN must be set to an upper bound on the number of calls of CALFUN.
-C     The array W will be used for working space. Its length must be at least
-C     (NPT+13)*(NPT+N)+3*N*(N+3)/2.
-C
-C     SUBROUTINE CALFUN (N,X,F) must be provided by the user. It must set F to
-C     the value of the objective function for the variables X(1),X(2),...,X(N).
-C
-C     Partition the working space array, so that different parts of it can be
-C     treated separately by the subroutine that performs the main calculation.
-C
-      NP=N+1
-      NPTM=NPT-NP
-      IF (NPT .LT. N+2 .OR. NPT .GT. ((N+2)*NP)/2) THEN
-          PRINT 10
-   10     FORMAT (/4X,'Return from NEWUOA because NPT is not in',
-     1      ' the required interval')
-          GO TO 20
-      END IF
-      NDIM=NPT+N
-      IXB=1
-      IXO=IXB+N
-      IXN=IXO+N
-      IXP=IXN+N
-      IFV=IXP+N*NPT
-      IGQ=IFV+NPT
-      IHQ=IGQ+N
-      IPQ=IHQ+(N*NP)/2
-      IBMAT=IPQ+NPT
-      IZMAT=IBMAT+NDIM*N
-      ID=IZMAT+NPT*NPTM
-      IVL=ID+N
-      IW=IVL+NDIM
-C
-C     The above settings provide a partition of W for subroutine NEWUOB.
-C     The partition requires the first NPT*(NPT+N)+5*N*(N+3)/2 elements of
-C     W plus the space that is needed by the last array of NEWUOB.
-C
-      NEWUOA= NEWUOB (N,NPT,X,RHOBEG,RHOEND,IPRINT,MAXFUN,W(IXB),
-     1  W(IXO),W(IXN),W(IXP),W(IFV),W(IGQ),W(IHQ),W(IPQ),W(IBMAT),
-     2  W(IZMAT),NDIM,W(ID),W(IVL),W(IW),
-     3  IWF, CALFUN)
-   20 RETURN
-      END 
-
-
-
-
-
-
-      FUNCTION NEWUOB (N,NPT,X,RHOBEG,RHOEND,IPRINT,MAXFUN,XBASE,
-     1  XOPT,XNEW,XPT,FVAL,GQ,HQ,PQ,BMAT,ZMAT,NDIM,D,VLAG,W,IWF,CALFUN)
-      IMPLICIT REAL*8 (A-H,O-Z)
-      DIMENSION X(*),XBASE(*),XOPT(*),XNEW(*),XPT(NPT,*),FVAL(*),
-     1  GQ(*),HQ(*),PQ(*),BMAT(NDIM,*),ZMAT(NPT,*),D(*),VLAG(*),W(*),
-     2  IWF(*)
-      EXTERNAL CALFUN
-      REAL*8 NEWUOB
-C
-C     The arguments N, NPT, X, RHOBEG, RHOEND, IPRINT and MAXFUN are identical
-C       to the corresponding arguments in SUBROUTINE NEWUOA.
-C     XBASE will hold a shift of origin that should reduce the contributions
-C       from rounding errors to values of the model and Lagrange functions.
-C     XOPT will be set to the displacement from XBASE of the vector of
-C       variables that provides the least calculated F so far.
-C     XNEW will be set to the displacement from XBASE of the vector of
-C       variables for the current calculation of F.
-C     XPT will contain the interpolation point coordinates relative to XBASE.
-C     FVAL will hold the values of F at the interpolation points.
-C     GQ will hold the gradient of the quadratic model at XBASE.
-C     HQ will hold the explicit second derivatives of the quadratic model.
-C     PQ will contain the parameters of the implicit second derivatives of
-C       the quadratic model.
-C     BMAT will hold the last N columns of H.
-C     ZMAT will hold the factorization of the leading NPT by NPT submatrix of
-C       H, this factorization being ZMAT times Diag(DZ) times ZMAT^T, where
-C       the elements of DZ are plus or minus one, as specified by IDZ.
-C     NDIM is the first dimension of BMAT and has the value NPT+N.
-C     D is reserved for trial steps from XOPT.
-C     VLAG will contain the values of the Lagrange functions at a new point X.
-C       They are part of a product that requires VLAG to be of length NDIM.
-C     The array W will be used for working space. Its length must be at least
-C       10*NDIM = 10*(NPT+N).
-C
-C     Set some constants.
-C
-      HALF=0.5D0
-      ONE=1.0D0
-      TENTH=0.1D0
-      ZERO=0.0D0
-      NP=N+1
-      NH=(N*NP)/2
-      NPTM=NPT-NP
-      NFTEST=MAX0(MAXFUN,1)
-C
-C     Set the initial elements of XPT, BMAT, HQ, PQ and ZMAT to zero.
-C
-      DO 20 J=1,N
-      XBASE(J)=X(J)
-      DO 10 K=1,NPT
-   10 XPT(K,J)=ZERO
-      DO 20 I=1,NDIM
-   20 BMAT(I,J)=ZERO
-      DO 30 IH=1,NH
-   30 HQ(IH)=ZERO
-      DO 40 K=1,NPT
-      PQ(K)=ZERO
-      DO 40 J=1,NPTM
-   40 ZMAT(K,J)=ZERO
-C
-C     Begin the initialization procedure. NF becomes one more than the number
-C     of function values so far. The coordinates of the displacement of the
-C     next initial interpolation point from XBASE are set in XPT(NF,.).
-C
-      RHOSQ=RHOBEG*RHOBEG
-      RECIP=ONE/RHOSQ
-      RECIQ=DSQRT(HALF)/RHOSQ
-      NF=0
-   50 NFM=NF
-      NFMM=NF-N
-      NF=NF+1
-      IF (NFM .LE. 2*N) THEN
-          IF (NFM .GE. 1 .AND. NFM .LE. N) THEN
-              XPT(NF,NFM)=RHOBEG
-          ELSE IF (NFM .GT. N) THEN
-              XPT(NF,NFMM)=-RHOBEG
-          END IF
-      ELSE
-          ITEMP=(NFMM-1)/N
-          JPT=NFM-ITEMP*N-N
-          IPT=JPT+ITEMP
-          IF (IPT .GT. N) THEN
-              ITEMP=JPT
-              JPT=IPT-N
-              IPT=ITEMP
-          END IF
-          XIPT=RHOBEG
-          IF (FVAL(IPT+NP) .LT. FVAL(IPT+1)) XIPT=-XIPT
-          XJPT=RHOBEG
-          IF (FVAL(JPT+NP) .LT. FVAL(JPT+1)) XJPT=-XJPT
-          XPT(NF,IPT)=XIPT
-          XPT(NF,JPT)=XJPT
-      END IF
-C
-C     Calculate the next value of F, label 70 being reached immediately
-C     after this calculation. The least function value so far and its index
-C     are required.
-C
-      DO 60 J=1,N
-   60 X(J)=XPT(NF,J)+XBASE(J)
-      GOTO 310
-   70 FVAL(NF)=F
-      IF (NF .EQ. 1) THEN
-          FBEG=F
-          FOPT=F
-          KOPT=1
-      ELSE IF (F .LT. FOPT) THEN
-          FOPT=F
-          KOPT=NF
-      END IF
-C
-C     Set the nonzero initial elements of BMAT and the quadratic model in
-C     the cases when NF is at most 2*N+1.
-C
-      IF (NFM .LE. 2*N) THEN
-          IF (NFM .GE. 1 .AND. NFM .LE. N) THEN
-              GQ(NFM)=(F-FBEG)/RHOBEG
-              IF (NPT .LT. NF+N) THEN
-                  BMAT(1,NFM)=-ONE/RHOBEG
-                  BMAT(NF,NFM)=ONE/RHOBEG
-                  BMAT(NPT+NFM,NFM)=-HALF*RHOSQ
-              END IF
-          ELSE IF (NFM .GT. N) THEN
-              BMAT(NF-N,NFMM)=HALF/RHOBEG
-              BMAT(NF,NFMM)=-HALF/RHOBEG
-              ZMAT(1,NFMM)=-RECIQ-RECIQ
-              ZMAT(NF-N,NFMM)=RECIQ
-              ZMAT(NF,NFMM)=RECIQ
-              IH=(NFMM*(NFMM+1))/2
-              TEMP=(FBEG-F)/RHOBEG
-              HQ(IH)=(GQ(NFMM)-TEMP)/RHOBEG
-              GQ(NFMM)=HALF*(GQ(NFMM)+TEMP)
-          END IF
-C
-C     Set the off-diagonal second derivatives of the Lagrange functions and
-C     the initial quadratic model.
-C
-      ELSE
-          IH=(IPT*(IPT-1))/2+JPT
-          IF (XIPT .LT. ZERO) IPT=IPT+N
-          IF (XJPT .LT. ZERO) JPT=JPT+N
-          ZMAT(1,NFMM)=RECIP
-          ZMAT(NF,NFMM)=RECIP
-          ZMAT(IPT+1,NFMM)=-RECIP
-          ZMAT(JPT+1,NFMM)=-RECIP
-          HQ(IH)=(FBEG-FVAL(IPT+1)-FVAL(JPT+1)+F)/(XIPT*XJPT)
-      END IF
-      IF (NF .LT. NPT) GOTO 50
-C
-C     Begin the iterative procedure, because the initial model is complete.
-C
-      RHO=RHOBEG
-      DELTA=RHO
-      IDZ=1
-      DIFFA=ZERO
-      DIFFB=ZERO
-      ITEST=0
-      XOPTSQ=ZERO
-      DO 80 I=1,N
-      XOPT(I)=XPT(KOPT,I)
-   80 XOPTSQ=XOPTSQ+XOPT(I)**2
-   90 NFSAV=NF
-C
-C     Generate the next trust region step and test its length. Set KNEW
-C     to -1 if the purpose of the next F will be to improve the model.
-C
-  100 KNEW=0
-      CALL TRSAPP (N,NPT,XOPT,XPT,GQ,HQ,PQ,DELTA,D,W,W(NP),
-     1  W(NP+N),W(NP+2*N),CRVMIN)
-      DSQ=ZERO
-      DO 110 I=1,N
-  110 DSQ=DSQ+D(I)**2
-      DNORM=DMIN1(DELTA,DSQRT(DSQ))
-      IF (DNORM .LT. HALF*RHO) THEN
-          KNEW=-1
-          DELTA=TENTH*DELTA
-          RATIO=-1.0D0
-          IF (DELTA .LE. 1.5D0*RHO) DELTA=RHO
-          IF (NF .LE. NFSAV+2) GOTO 460
-          TEMP=0.125D0*CRVMIN*RHO*RHO
-          IF (TEMP .LE. DMAX1(DIFFA,DIFFB,DIFFC)) GOTO 460
-          GOTO 490
-      END IF
-C
-C     Shift XBASE if XOPT may be too far from XBASE. First make the changes
-C     to BMAT that do not depend on ZMAT.
-C
-  120 IF (DSQ .LE. 1.0D-3*XOPTSQ) THEN
-          TEMPQ=0.25D0*XOPTSQ
-          DO 140 K=1,NPT
-          SUM=ZERO
-          DO 130 I=1,N
-  130     SUM=SUM+XPT(K,I)*XOPT(I)
-          TEMP=PQ(K)*SUM
-          SUM=SUM-HALF*XOPTSQ
-          W(NPT+K)=SUM
-          DO 140 I=1,N
-          GQ(I)=GQ(I)+TEMP*XPT(K,I)
-          XPT(K,I)=XPT(K,I)-HALF*XOPT(I)
-          VLAG(I)=BMAT(K,I)
-          W(I)=SUM*XPT(K,I)+TEMPQ*XOPT(I)
-          IP=NPT+I
-          DO 140 J=1,I
-  140     BMAT(IP,J)=BMAT(IP,J)+VLAG(I)*W(J)+W(I)*VLAG(J)
-C
-C     Then the revisions of BMAT that depend on ZMAT are calculated.
-C
-          DO 180 K=1,NPTM
-          SUMZ=ZERO
-          DO 150 I=1,NPT
-          SUMZ=SUMZ+ZMAT(I,K)
-  150     W(I)=W(NPT+I)*ZMAT(I,K)
-          DO 170 J=1,N
-          SUM=TEMPQ*SUMZ*XOPT(J)
-          DO 160 I=1,NPT
-  160     SUM=SUM+W(I)*XPT(I,J)
-          VLAG(J)=SUM
-          IF (K .LT. IDZ) SUM=-SUM
-          DO 170 I=1,NPT
-  170     BMAT(I,J)=BMAT(I,J)+SUM*ZMAT(I,K)
-          DO 180 I=1,N
-          IP=I+NPT
-          TEMP=VLAG(I)
-          IF (K .LT. IDZ) TEMP=-TEMP
-          DO 180 J=1,I
-  180     BMAT(IP,J)=BMAT(IP,J)+TEMP*VLAG(J)
-C
-C     The following instructions complete the shift of XBASE, including
-C     the changes to the parameters of the quadratic model.
-C
-          IH=0
-          DO 200 J=1,N
-          W(J)=ZERO
-          DO 190 K=1,NPT
-          W(J)=W(J)+PQ(K)*XPT(K,J)
-  190     XPT(K,J)=XPT(K,J)-HALF*XOPT(J)
-          DO 200 I=1,J
-          IH=IH+1
-          IF (I .LT. J) GQ(J)=GQ(J)+HQ(IH)*XOPT(I)
-          GQ(I)=GQ(I)+HQ(IH)*XOPT(J)
-          HQ(IH)=HQ(IH)+W(I)*XOPT(J)+XOPT(I)*W(J)
-  200     BMAT(NPT+I,J)=BMAT(NPT+J,I)
-          DO 210 J=1,N
-          XBASE(J)=XBASE(J)+XOPT(J)
-  210     XOPT(J)=ZERO
-          XOPTSQ=ZERO
-      END IF
-C
-C     Pick the model step if KNEW is positive. A different choice of D
-C     may be made later, if the choice of D by BIGLAG causes substantial
-C     cancellation in DENOM.
-C
-      IF (KNEW .GT. 0) THEN
-          CALL BIGLAG (N,NPT,XOPT,XPT,BMAT,ZMAT,IDZ,NDIM,KNEW,DSTEP,
-     1      D,ALPHA,VLAG,VLAG(NPT+1),W,W(NP),W(NP+N))
-      END IF
-C
-C     Calculate VLAG and BETA for the current choice of D. The first NPT
-C     components of W_check will be held in W.
-C
-      DO 230 K=1,NPT
-      SUMA=ZERO
-      SUMB=ZERO
-      SUM=ZERO
-      DO 220 J=1,N
-      SUMA=SUMA+XPT(K,J)*D(J)
-      SUMB=SUMB+XPT(K,J)*XOPT(J)
-  220 SUM=SUM+BMAT(K,J)*D(J)
-      W(K)=SUMA*(HALF*SUMA+SUMB)
-  230 VLAG(K)=SUM
-      BETA=ZERO
-      DO 250 K=1,NPTM
-      SUM=ZERO
-      DO 240 I=1,NPT
-  240 SUM=SUM+ZMAT(I,K)*W(I)
-      IF (K .LT. IDZ) THEN
-          BETA=BETA+SUM*SUM
-          SUM=-SUM
-      ELSE
-          BETA=BETA-SUM*SUM
-      END IF
-      DO 250 I=1,NPT
-  250 VLAG(I)=VLAG(I)+SUM*ZMAT(I,K)
-      BSUM=ZERO
-      DX=ZERO
-      DO 280 J=1,N
-      SUM=ZERO
-      DO 260 I=1,NPT
-  260 SUM=SUM+W(I)*BMAT(I,J)
-      BSUM=BSUM+SUM*D(J)
-      JP=NPT+J
-      DO 270 K=1,N
-  270 SUM=SUM+BMAT(JP,K)*D(K)
-      VLAG(JP)=SUM
-      BSUM=BSUM+SUM*D(J)
-  280 DX=DX+D(J)*XOPT(J)
-      BETA=DX*DX+DSQ*(XOPTSQ+DX+DX+HALF*DSQ)+BETA-BSUM
-      VLAG(KOPT)=VLAG(KOPT)+ONE
-C
-C     If KNEW is positive and if the cancellation in DENOM is unacceptable,
-C     then BIGDEN calculates an alternative model step, XNEW being used for
-C     working space.
-C
-      IF (KNEW .GT. 0) THEN
-          TEMP=ONE+ALPHA*BETA/VLAG(KNEW)**2
-          IF (DABS(TEMP) .LE. 0.8D0) THEN
-              CALL BIGDEN (N,NPT,XOPT,XPT,BMAT,ZMAT,IDZ,NDIM,KOPT,
-     1          KNEW,D,W,VLAG,BETA,XNEW,W(NDIM+1),W(6*NDIM+1))
-          END IF
-      END IF
-C
-C     Calculate the next value of the objective function.
-C
-  290 DO 300 I=1,N
-      XNEW(I)=XOPT(I)+D(I)
-  300 X(I)=XBASE(I)+XNEW(I)
-      NF=NF+1
-  310 IF (NF .GT. NFTEST) THEN
-          NF=NF-1
-          IF (IPRINT .GT. 0) PRINT 320
-  320     FORMAT (/4X,'Return from NEWUOA because CALFUN has been',
-     1      ' called MAXFUN times.')
-          GOTO 530
-      END IF
-      CALL CALFUN (N,X,F,IWF)
-      IF (IPRINT .EQ. 3) THEN
-          PRINT 330, NF,F,(X(I),I=1,N)
-  330      FORMAT (/4X,'Function number',I6,'    F =',1PD18.10,
-     1       '    The corresponding X is:'/(2X,5D15.6))
-      END IF
-      IF (NF .LE. NPT) GOTO 70
-      IF (KNEW .EQ. -1) GOTO 530
-C
-C     Use the quadratic model to predict the change in F due to the step D,
-C     and set DIFF to the error of this prediction.
-C
-      VQUAD=ZERO
-      IH=0
-      DO 340 J=1,N
-      VQUAD=VQUAD+D(J)*GQ(J)
-      DO 340 I=1,J
-      IH=IH+1
-      TEMP=D(I)*XNEW(J)+D(J)*XOPT(I)
-      IF (I .EQ. J) TEMP=HALF*TEMP
-  340 VQUAD=VQUAD+TEMP*HQ(IH)
-      DO 350 K=1,NPT
-  350 VQUAD=VQUAD+PQ(K)*W(K)
-      DIFF=F-FOPT-VQUAD
-      DIFFC=DIFFB
-      DIFFB=DIFFA
-      DIFFA=DABS(DIFF)
-      IF (DNORM .GT. RHO) NFSAV=NF
-C
-C     Update FOPT and XOPT if the new F is the least value of the objective
-C     function so far. The branch when KNEW is positive occurs if D is not
-C     a trust region step.
-C
-      FSAVE=FOPT
-      IF (F .LT. FOPT) THEN
-          FOPT=F
-          XOPTSQ=ZERO
-          DO 360 I=1,N
-          XOPT(I)=XNEW(I)
-  360     XOPTSQ=XOPTSQ+XOPT(I)**2
-      END IF
-      KSAVE=KNEW
-      IF (KNEW .GT. 0) GOTO 410
-C
-C     Pick the next value of DELTA after a trust region step.
-C
-      IF (VQUAD .GE. ZERO) THEN
-          IF (IPRINT .GT. 0) PRINT 370
-  370     FORMAT (/4X,'Return from NEWUOA because a trust',
-     1      ' region step has failed to reduce Q.')
-          GOTO 530
-      END IF
-      RATIO=(F-FSAVE)/VQUAD
-      IF (RATIO .LE. TENTH) THEN
-          DELTA=HALF*DNORM
-      ELSE IF (RATIO. LE. 0.7D0) THEN
-          DELTA=DMAX1(HALF*DELTA,DNORM)
-      ELSE
-          DELTA=DMAX1(HALF*DELTA,DNORM+DNORM)
-      END IF
-      IF (DELTA .LE. 1.5D0*RHO) DELTA=RHO
-C
-C     Set KNEW to the index of the next interpolation point to be deleted.
-C
-      RHOSQ=DMAX1(TENTH*DELTA,RHO)**2
-      KTEMP=0
-      DETRAT=ZERO
-      IF (F .GE. FSAVE) THEN
-          KTEMP=KOPT
-          DETRAT=ONE
-      END IF
-      DO 400 K=1,NPT
-      HDIAG=ZERO
-      DO 380 J=1,NPTM
-      TEMP=ONE
-      IF (J .LT. IDZ) TEMP=-ONE
-  380 HDIAG=HDIAG+TEMP*ZMAT(K,J)**2
-      TEMP=DABS(BETA*HDIAG+VLAG(K)**2)
-      DISTSQ=ZERO
-      DO 390 J=1,N
-  390 DISTSQ=DISTSQ+(XPT(K,J)-XOPT(J))**2
-      IF (DISTSQ .GT. RHOSQ) TEMP=TEMP*(DISTSQ/RHOSQ)**3
-      IF (TEMP .GT. DETRAT .AND. K .NE. KTEMP) THEN
-          DETRAT=TEMP
-          KNEW=K
-      END IF
-  400 CONTINUE
-      IF (KNEW .EQ. 0) GOTO 460
-C
-C     Update BMAT, ZMAT and IDZ, so that the KNEW-th interpolation point
-C     can be moved. Begin the updating of the quadratic model, starting
-C     with the explicit second derivative term.
-C
-  410 CALL UPDATE (N,NPT,BMAT,ZMAT,IDZ,NDIM,VLAG,BETA,KNEW,W)
-      FVAL(KNEW)=F
-      IH=0
-      DO 420 I=1,N
-      TEMP=PQ(KNEW)*XPT(KNEW,I)
-      DO 420 J=1,I
-      IH=IH+1
-  420 HQ(IH)=HQ(IH)+TEMP*XPT(KNEW,J)
-      PQ(KNEW)=ZERO
-C
-C     Update the other second derivative parameters, and then the gradient
-C     vector of the model. Also include the new interpolation point.
-C
-      DO 440 J=1,NPTM
-      TEMP=DIFF*ZMAT(KNEW,J)
-      IF (J .LT. IDZ) TEMP=-TEMP
-      DO 440 K=1,NPT
-  440 PQ(K)=PQ(K)+TEMP*ZMAT(K,J)
-      GQSQ=ZERO
-      DO 450 I=1,N
-      GQ(I)=GQ(I)+DIFF*BMAT(KNEW,I)
-      GQSQ=GQSQ+GQ(I)**2
-  450 XPT(KNEW,I)=XNEW(I)
-C
-C     If a trust region step makes a small change to the objective function,
-C     then calculate the gradient of the least Frobenius norm interpolant at
-C     XBASE, and store it in W, using VLAG for a vector of right hand sides.
-C
-      IF (KSAVE .EQ. 0 .AND. DELTA .EQ. RHO) THEN
-          IF (DABS(RATIO) .GT. 1.0D-2) THEN
-              ITEST=0
-          ELSE
-              DO 700 K=1,NPT
-  700         VLAG(K)=FVAL(K)-FVAL(KOPT)
-              GISQ=ZERO
-              DO 720 I=1,N
-              SUM=ZERO
-              DO 710 K=1,NPT
-  710         SUM=SUM+BMAT(K,I)*VLAG(K)
-              GISQ=GISQ+SUM*SUM
-  720         W(I)=SUM
-C
-C     Test whether to replace the new quadratic model by the least Frobenius
-C     norm interpolant, making the replacement if the test is satisfied.
-C
-              ITEST=ITEST+1
-              IF (GQSQ .LT. 1.0D2*GISQ) ITEST=0
-              IF (ITEST .GE. 3) THEN
-                  DO 730 I=1,N
-  730             GQ(I)=W(I)
-                  DO 740 IH=1,NH
-  740             HQ(IH)=ZERO
-                  DO 760 J=1,NPTM
-                  W(J)=ZERO
-                  DO 750 K=1,NPT
-  750             W(J)=W(J)+VLAG(K)*ZMAT(K,J)
-  760             IF (J .LT. IDZ) W(J)=-W(J)
-                  DO 770 K=1,NPT
-                  PQ(K)=ZERO
-                  DO 770 J=1,NPTM
-  770             PQ(K)=PQ(K)+ZMAT(K,J)*W(J)
-                  ITEST=0
-              END IF
-          END IF
-      END IF
-      IF (F .LT. FSAVE) KOPT=KNEW
-C
-C     If a trust region step has provided a sufficient decrease in F, then
-C     branch for another trust region calculation. The case KSAVE>0 occurs
-C     when the new function value was calculated by a model step.
-C
-      IF (F .LE. FSAVE+TENTH*VQUAD) GOTO 100
-      IF (KSAVE .GT. 0) GOTO 100
-C
-C     Alternatively, find out if the interpolation points are close enough
-C     to the best point so far.
-C
-      KNEW=0
-  460 DISTSQ=4.0D0*DELTA*DELTA
-      DO 480 K=1,NPT
-      SUM=ZERO
-      DO 470 J=1,N
-  470 SUM=SUM+(XPT(K,J)-XOPT(J))**2
-      IF (SUM .GT. DISTSQ) THEN
-          KNEW=K
-          DISTSQ=SUM
-      END IF
-  480 CONTINUE
-C
-C     If KNEW is positive, then set DSTEP, and branch back for the next
-C     iteration, which will generate a "model step".
-C
-      IF (KNEW .GT. 0) THEN
-          DSTEP=DMAX1(DMIN1(TENTH*DSQRT(DISTSQ),HALF*DELTA),RHO)
-          DSQ=DSTEP*DSTEP
-          GOTO 120
-      END IF
-      IF (RATIO .GT. ZERO) GOTO 100
-      IF (DMAX1(DELTA,DNORM) .GT. RHO) GOTO 100
-C
-C     The calculations with the current value of RHO are complete. Pick the
-C     next values of RHO and DELTA.
-C
-  490 IF (RHO .GT. RHOEND) THEN
-          DELTA=HALF*RHO
-          RATIO=RHO/RHOEND
-          IF (RATIO .LE. 16.0D0) THEN
-              RHO=RHOEND
-          ELSE IF (RATIO .LE. 250.0D0) THEN
-              RHO=DSQRT(RATIO)*RHOEND
-          ELSE
-              RHO=TENTH*RHO
-          END IF
-          DELTA=DMAX1(DELTA,RHO)
-          IF (IPRINT .GE. 2) THEN
-              IF (IPRINT .GE. 3) PRINT 500
-  500         FORMAT (5X)
-              PRINT 510, RHO,NF
-  510         FORMAT (/4X,'New RHO =',1PD11.4,5X,'Number of',
-     1          ' function values =',I6)
-              PRINT 520, FOPT,(XBASE(I)+XOPT(I),I=1,N)
-  520         FORMAT (4X,'Least value of F =',1PD23.15,9X,
-     1          'The corresponding X is:'/(2X,5D15.6))
-          END IF
-          GOTO 90
-      END IF
-C
-C     Return from the calculation, after another Newton-Raphson step, if
-C     it is too short to have been tried before.
-C
-      IF (KNEW .EQ. -1) GOTO 290
-  530 IF (FOPT .LE. F) THEN
-          DO 540 I=1,N
-  540     X(I)=XBASE(I)+XOPT(I)
-          F=FOPT
-      END IF
-      IF (IPRINT .GE. 1) THEN
-          PRINT 550, NF
-  550     FORMAT (/4X,'At the return from NEWUOA',5X,
-     1      'Number of function values =',I6)
-          PRINT 520, F,(X(I),I=1,N)
-      END IF
-      NEWUOB =F
-      RETURN 
-      END 
-      SUBROUTINE TRSAPP (N,NPT,XOPT,XPT,GQ,HQ,PQ,DELTA,STEP,
-     1  D,G,HD,HS,CRVMIN)
-      IMPLICIT REAL*8 (A-H,O-Z)
-      DIMENSION XOPT(*),XPT(NPT,*),GQ(*),HQ(*),PQ(*),STEP(*),
-     1  D(*),G(*),HD(*),HS(*)
-C
-C     N is the number of variables of a quadratic objective function, Q say.
-C     The arguments NPT, XOPT, XPT, GQ, HQ and PQ have their usual meanings,
-C       in order to define the current quadratic model Q.
-C     DELTA is the trust region radius, and has to be positive.
-C     STEP will be set to the calculated trial step.
-C     The arrays D, G, HD and HS will be used for working space.
-C     CRVMIN will be set to the least curvature of H along the conjugate
-C       directions that occur, except that it is set to zero if STEP goes
-C       all the way to the trust region boundary.
-C
-C     The calculation of STEP begins with the truncated conjugate gradient
-C     method. If the boundary of the trust region is reached, then further
-C     changes to STEP may be made, each one being in the 2D space spanned
-C     by the current STEP and the corresponding gradient of Q. Thus STEP
-C     should provide a substantial reduction to Q within the trust region.
-C
-C     Initialization, which includes setting HD to H times XOPT.
-C
-      HALF=0.5D0
-      ZERO=0.0D0
-      TWOPI=8.0D0*DATAN(1.0D0)
-      DELSQ=DELTA*DELTA
-      ITERC=0
-      ITERMAX=N
-      ITERSW=ITERMAX
-      DO 10 I=1,N
-   10 D(I)=XOPT(I)
-      GOTO 170
-C
-C     Prepare for the first line search.
-C
-   20 QRED=ZERO
-      DD=ZERO
-      DO 30 I=1,N
-      STEP(I)=ZERO
-      HS(I)=ZERO
-      G(I)=GQ(I)+HD(I)
-      D(I)=-G(I)
-   30 DD=DD+D(I)**2
-      CRVMIN=ZERO
-      IF (DD .EQ. ZERO) GOTO 160
-      DS=ZERO
-      SS=ZERO
-      GG=DD
-      GGBEG=GG
-C
-C     Calculate the step to the trust region boundary and the product HD.
-C
-   40 ITERC=ITERC+1
-      TEMP=DELSQ-SS
-      BSTEP=TEMP/(DS+DSQRT(DS*DS+DD*TEMP))
-      GOTO 170
-   50 DHD=ZERO
-      DO 60 J=1,N
-   60 DHD=DHD+D(J)*HD(J)
-C
-C     Update CRVMIN and set the step-length ALPHA.
-C
-      ALPHA=BSTEP
-      IF (DHD .GT. ZERO) THEN
-          TEMP=DHD/DD
-          IF (ITERC .EQ. 1) CRVMIN=TEMP
-          CRVMIN=DMIN1(CRVMIN,TEMP)
-          ALPHA=DMIN1(ALPHA,GG/DHD)
-      END IF
-      QADD=ALPHA*(GG-HALF*ALPHA*DHD)
-      QRED=QRED+QADD
-C
-C     Update STEP and HS.
-C
-      GGSAV=GG
-      GG=ZERO
-      DO 70 I=1,N
-      STEP(I)=STEP(I)+ALPHA*D(I)
-      HS(I)=HS(I)+ALPHA*HD(I)
-   70 GG=GG+(G(I)+HS(I))**2
-C
-C     Begin another conjugate direction iteration if required.
-C
-      IF (ALPHA .LT. BSTEP) THEN
-          IF (QADD .LE. 0.01D0*QRED) GOTO 160
-          IF (GG .LE. 1.0D-4*GGBEG) GOTO 160
-          IF (ITERC .EQ. ITERMAX) GOTO 160
-          TEMP=GG/GGSAV
-          DD=ZERO
-          DS=ZERO
-          SS=ZERO
-          DO 80 I=1,N
-          D(I)=TEMP*D(I)-G(I)-HS(I)
-          DD=DD+D(I)**2
-          DS=DS+D(I)*STEP(I)
-   80     SS=SS+STEP(I)**2
-          IF (DS .LE. ZERO) GOTO 160
-          IF (SS .LT. DELSQ) GOTO 40
-      END IF
-      CRVMIN=ZERO
-      ITERSW=ITERC
-C
-C     Test whether an alternative iteration is required.
-C
-   90 IF (GG .LE. 1.0D-4*GGBEG) GOTO 160
-      SG=ZERO
-      SHS=ZERO
-      DO 100 I=1,N
-      SG=SG+STEP(I)*G(I)
-  100 SHS=SHS+STEP(I)*HS(I)
-      SGK=SG+SHS
-      ANGTEST=SGK/DSQRT(GG*DELSQ)
-      IF (ANGTEST .LE. -0.99D0) GOTO 160
-C
-C     Begin the alternative iteration by calculating D and HD and some
-C     scalar products.
-C
-      ITERC=ITERC+1
-      TEMP=DSQRT(DELSQ*GG-SGK*SGK)
-      TEMPA=DELSQ/TEMP
-      TEMPB=SGK/TEMP
-      DO 110 I=1,N
-  110 D(I)=TEMPA*(G(I)+HS(I))-TEMPB*STEP(I)
-      GOTO 170
-  120 DG=ZERO
-      DHD=ZERO
-      DHS=ZERO
-      DO 130 I=1,N
-      DG=DG+D(I)*G(I)
-      DHD=DHD+HD(I)*D(I)
-  130 DHS=DHS+HD(I)*STEP(I)
-C
-C     Seek the value of the angle that minimizes Q.
-C
-      CF=HALF*(SHS-DHD)
-      QBEG=SG+CF
-      QSAV=QBEG
-      QMIN=QBEG
-      ISAVE=0
-      IU=49
-      TEMP=TWOPI/DFLOAT(IU+1)
-      DO 140 I=1,IU
-      ANGLE=DFLOAT(I)*TEMP
-      CTH=DCOS(ANGLE)
-      STH=DSIN(ANGLE)
-      QNEW=(SG+CF*CTH)*CTH+(DG+DHS*CTH)*STH
-      IF (QNEW .LT. QMIN) THEN
-          QMIN=QNEW
-          ISAVE=I
-          TEMPA=QSAV
-      ELSE IF (I .EQ. ISAVE+1) THEN
-          TEMPB=QNEW
-      END IF
-  140 QSAV=QNEW
-      IF (ISAVE .EQ. ZERO) TEMPA=QNEW
-      IF (ISAVE .EQ. IU) TEMPB=QBEG
-      ANGLE=ZERO
-      IF (TEMPA .NE. TEMPB) THEN
-          TEMPA=TEMPA-QMIN
-          TEMPB=TEMPB-QMIN
-          ANGLE=HALF*(TEMPA-TEMPB)/(TEMPA+TEMPB)
-      END IF
-      ANGLE=TEMP*(DFLOAT(ISAVE)+ANGLE)
-C
-C     Calculate the new STEP and HS. Then test for convergence.
-C
-      CTH=DCOS(ANGLE)
-      STH=DSIN(ANGLE)
-      REDUC=QBEG-(SG+CF*CTH)*CTH-(DG+DHS*CTH)*STH
-      GG=ZERO
-      DO 150 I=1,N
-      STEP(I)=CTH*STEP(I)+STH*D(I)
-      HS(I)=CTH*HS(I)+STH*HD(I)
-  150 GG=GG+(G(I)+HS(I))**2
-      QRED=QRED+REDUC
-      RATIO=REDUC/QRED
-      IF (ITERC .LT. ITERMAX .AND. RATIO .GT. 0.01D0) GOTO 90
-  160 RETURN
-C
-C     The following instructions act as a subroutine for setting the vector
-C     HD to the vector D multiplied by the second derivative matrix of Q.
-C     They are called from three different places, which are distinguished
-C     by the value of ITERC.
-C
-  170 DO 180 I=1,N
-  180 HD(I)=ZERO
-      DO 200 K=1,NPT
-      TEMP=ZERO
-      DO 190 J=1,N
-  190 TEMP=TEMP+XPT(K,J)*D(J)
-      TEMP=TEMP*PQ(K)
-      DO 200 I=1,N
-  200 HD(I)=HD(I)+TEMP*XPT(K,I)
-      IH=0
-      DO 210 J=1,N
-      DO 210 I=1,J
-      IH=IH+1
-      IF (I .LT. J) HD(J)=HD(J)+HQ(IH)*D(I)
-  210 HD(I)=HD(I)+HQ(IH)*D(J)
-      IF (ITERC .EQ. 0) GOTO 20
-      IF (ITERC .LE. ITERSW) GOTO 50
-      GOTO 120
-      END
-
-      SUBROUTINE UPDATE (N,NPT,BMAT,ZMAT,IDZ,NDIM,VLAG,BETA,KNEW,W)
-      IMPLICIT REAL*8 (A-H,O-Z)
-      DIMENSION BMAT(NDIM,*),ZMAT(NPT,*),VLAG(*),W(*)
-C
-C     The arrays BMAT and ZMAT with IDZ are updated, in order to shift the
-C     interpolation point that has index KNEW. On entry, VLAG contains the
-C     components of the vector Theta*Wcheck+e_b of the updating formula
-C     (6.11), and BETA holds the value of the parameter that has this name.
-C     The vector W is used for working space.
-C
-C     Set some constants.
-C
-      ONE=1.0D0
-      ZERO=0.0D0
-      NPTM=NPT-N-1
-C
-C     Apply the rotations that put zeros in the KNEW-th row of ZMAT.
-C
-      JL=1
-      DO 20 J=2,NPTM
-      IF (J .EQ. IDZ) THEN
-          JL=IDZ
-      ELSE IF (ZMAT(KNEW,J) .NE. ZERO) THEN
-          TEMP=DSQRT(ZMAT(KNEW,JL)**2+ZMAT(KNEW,J)**2)
-          TEMPA=ZMAT(KNEW,JL)/TEMP
-          TEMPB=ZMAT(KNEW,J)/TEMP
-          DO 10 I=1,NPT
-          TEMP=TEMPA*ZMAT(I,JL)+TEMPB*ZMAT(I,J)
-          ZMAT(I,J)=TEMPA*ZMAT(I,J)-TEMPB*ZMAT(I,JL)
-   10     ZMAT(I,JL)=TEMP
-          ZMAT(KNEW,J)=ZERO
-      END IF
-   20 CONTINUE
-C
-C     Put the first NPT components of the KNEW-th column of HLAG into W,
-C     and calculate the parameters of the updating formula.
-C
-      TEMPA=ZMAT(KNEW,1)
-      IF (IDZ .GE. 2) TEMPA=-TEMPA
-      IF (JL .GT. 1) TEMPB=ZMAT(KNEW,JL)
-      DO 30 I=1,NPT
-      W(I)=TEMPA*ZMAT(I,1)
-      IF (JL .GT. 1) W(I)=W(I)+TEMPB*ZMAT(I,JL)
-   30 CONTINUE
-      ALPHA=W(KNEW)
-      TAU=VLAG(KNEW)
-      TAUSQ=TAU*TAU
-      DENOM=ALPHA*BETA+TAUSQ
-      VLAG(KNEW)=VLAG(KNEW)-ONE
-C
-C     Complete the updating of ZMAT when there is only one nonzero element
-C     in the KNEW-th row of the new matrix ZMAT, but, if IFLAG is set to one,
-C     then the first column of ZMAT will be exchanged with another one later.
-C
-      IFLAG=0
-      IF (JL .EQ. 1) THEN
-          TEMP=DSQRT(DABS(DENOM))
-          TEMPB=TEMPA/TEMP
-          TEMPA=TAU/TEMP
-          DO 40 I=1,NPT
-   40     ZMAT(I,1)=TEMPA*ZMAT(I,1)-TEMPB*VLAG(I)
-          IF (IDZ .EQ. 1 .AND. TEMP .LT. ZERO) IDZ=2
-          IF (IDZ .GE. 2 .AND. TEMP .GE. ZERO) IFLAG=1
-      ELSE
-C
-C     Complete the updating of ZMAT in the alternative case.
-C
-          JA=1
-          IF (BETA .GE. ZERO) JA=JL
-          JB=JL+1-JA
-          TEMP=ZMAT(KNEW,JB)/DENOM
-          TEMPA=TEMP*BETA
-          TEMPB=TEMP*TAU
-          TEMP=ZMAT(KNEW,JA)
-          SCALA=ONE/DSQRT(DABS(BETA)*TEMP*TEMP+TAUSQ)
-          SCALB=SCALA*DSQRT(DABS(DENOM))
-          DO 50 I=1,NPT
-          ZMAT(I,JA)=SCALA*(TAU*ZMAT(I,JA)-TEMP*VLAG(I))
-   50     ZMAT(I,JB)=SCALB*(ZMAT(I,JB)-TEMPA*W(I)-TEMPB*VLAG(I))
-          IF (DENOM .LE. ZERO) THEN
-              IF (BETA .LT. ZERO) IDZ=IDZ+1
-              IF (BETA .GE. ZERO) IFLAG=1
-          END IF
-      END IF
-C
-C     IDZ is reduced in the following case, and usually the first column
-C     of ZMAT is exchanged with a later one.
-C
-      IF (IFLAG .EQ. 1) THEN
-          IDZ=IDZ-1
-          DO 60 I=1,NPT
-          TEMP=ZMAT(I,1)
-          ZMAT(I,1)=ZMAT(I,IDZ)
-   60     ZMAT(I,IDZ)=TEMP
-      END IF
-C
-C     Finally, update the matrix BMAT.
-C
-      DO 70 J=1,N
-      JP=NPT+J
-      W(JP)=BMAT(KNEW,J)
-      TEMPA=(ALPHA*VLAG(JP)-TAU*W(JP))/DENOM
-      TEMPB=(-BETA*W(JP)-TAU*VLAG(JP))/DENOM
-      DO 70 I=1,JP
-      BMAT(I,J)=BMAT(I,J)+TEMPA*VLAG(I)+TEMPB*W(I)
-      IF (I .GT. NPT) BMAT(JP,I-NPT)=BMAT(I,J)
-   70 CONTINUE
-      RETURN
-      END 
+C  version modif by F. HECHT
+C ---------------------------
+C The code in fortran is totally free, and the interface is under LGPL 
+C http://www.inrialpes.fr/bipop/people/guilbert/newuoa/newuoa.pdf 
+C  original source :
+C http://www.inrialpees.fr/bipop/people/guilbert/newuoa/newuoa.tar.gz
+C --------------------
+      SUBROUTINE BIGDEN (N,NPT,XOPT,XPT,BMAT,ZMAT,IDZ,NDIM,KOPT,
+     1  KNEW,D,W,VLAG,BETA,S,WVEC,PROD)
+      IMPLICIT REAL*8 (A-H,O-Z)
+      DIMENSION XOPT(*),XPT(NPT,*),BMAT(NDIM,*),ZMAT(NPT,*),D(*),
+     1  W(*),VLAG(*),S(*),WVEC(NDIM,*),PROD(NDIM,*)
+      DIMENSION DEN(9),DENEX(9),PAR(9)
+C
+C     N is the number of variables.
+C     NPT is the number of interpolation equations.
+C     XOPT is the best interpolation point so far.
+C     XPT contains the coordinates of the current interpolation points.
+C     BMAT provides the last N columns of H.
+C     ZMAT and IDZ give a factorization of the first NPT by NPT submatrix of H.
+C     NDIM is the first dimension of BMAT and has the value NPT+N.
+C     KOPT is the index of the optimal interpolation point.
+C     KNEW is the index of the interpolation point that is going to be moved.
+C     D will be set to the step from XOPT to the new point, and on entry it
+C       should be the D that was calculated by the last call of BIGLAG. The
+C       length of the initial D provides a trust region bound on the final D.
+C     W will be set to Wcheck for the final choice of D.
+C     VLAG will be set to Theta*Wcheck+e_b for the final choice of D.
+C     BETA will be set to the value that will occur in the updating formula
+C       when the KNEW-th interpolation point is moved to its new position.
+C     S, WVEC, PROD and the private arrays DEN, DENEX and PAR will be used
+C       for working space.
+C
+C     D is calculated in a way that should provide a denominator with a large
+C     modulus in the updating formula when the KNEW-th interpolation point is
+C     shifted to the new position XOPT+D.
+C
+C     Set some constants.
+C
+      HALF=0.5D0
+      ONE=1.0D0
+      QUART=0.25D0
+      TWO=2.0D0
+      ZERO=0.0D0
+      TWOPI=8.0D0*DATAN(ONE)
+      NPTM=NPT-N-1
+C
+C     Store the first NPT elements of the KNEW-th column of H in W(N+1)
+C     to W(N+NPT).
+C
+      DO 10 K=1,NPT
+   10 W(N+K)=ZERO
+      DO 20 J=1,NPTM
+      TEMP=ZMAT(KNEW,J)
+      IF (J .LT. IDZ) TEMP=-TEMP
+      DO 20 K=1,NPT
+   20 W(N+K)=W(N+K)+TEMP*ZMAT(K,J)
+      ALPHA=W(N+KNEW)
+C
+C     The initial search direction D is taken from the last call of BIGLAG,
+C     and the initial S is set below, usually to the direction from X_OPT
+C     to X_KNEW, but a different direction to an interpolation point may
+C     be chosen, in order to prevent S from being nearly parallel to D.
+C
+      DD=ZERO
+      DS=ZERO
+      SS=ZERO
+      XOPTSQ=ZERO
+      DO 30 I=1,N
+      DD=DD+D(I)**2
+      S(I)=XPT(KNEW,I)-XOPT(I)
+      DS=DS+D(I)*S(I)
+      SS=SS+S(I)**2
+   30 XOPTSQ=XOPTSQ+XOPT(I)**2
+      IF (DS*DS .GT. 0.99D0*DD*SS) THEN
+          KSAV=KNEW
+          DTEST=DS*DS/SS
+          DO 50 K=1,NPT
+          IF (K .NE. KOPT) THEN
+              DSTEMP=ZERO
+              SSTEMP=ZERO
+              DO 40 I=1,N
+              DIFF=XPT(K,I)-XOPT(I)
+              DSTEMP=DSTEMP+D(I)*DIFF
+   40         SSTEMP=SSTEMP+DIFF*DIFF
+              IF (DSTEMP*DSTEMP/SSTEMP .LT. DTEST) THEN
+                  KSAV=K
+                  DTEST=DSTEMP*DSTEMP/SSTEMP
+                  DS=DSTEMP
+                  SS=SSTEMP
+              END IF
+          END IF
+   50     CONTINUE
+          DO 60 I=1,N
+   60     S(I)=XPT(KSAV,I)-XOPT(I)
+      END IF
+      SSDEN=DD*SS-DS*DS
+      ITERC=0
+      DENSAV=ZERO
+C
+C     Begin the iteration by overwriting S with a vector that has the
+C     required length and direction.
+C
+   70 ITERC=ITERC+1
+      TEMP=ONE/DSQRT(SSDEN)
+      XOPTD=ZERO
+      XOPTS=ZERO
+      DO 80 I=1,N
+      S(I)=TEMP*(DD*S(I)-DS*D(I))
+      XOPTD=XOPTD+XOPT(I)*D(I)
+   80 XOPTS=XOPTS+XOPT(I)*S(I)
+C
+C     Set the coefficients of the first two terms of BETA.
+C
+      TEMPA=HALF*XOPTD*XOPTD
+      TEMPB=HALF*XOPTS*XOPTS
+      DEN(1)=DD*(XOPTSQ+HALF*DD)+TEMPA+TEMPB
+      DEN(2)=TWO*XOPTD*DD
+      DEN(3)=TWO*XOPTS*DD
+      DEN(4)=TEMPA-TEMPB
+      DEN(5)=XOPTD*XOPTS
+      DO 90 I=6,9
+   90 DEN(I)=ZERO
+C
+C     Put the coefficients of Wcheck in WVEC.
+C
+      DO 110 K=1,NPT
+      TEMPA=ZERO
+      TEMPB=ZERO
+      TEMPC=ZERO
+      DO 100 I=1,N
+      TEMPA=TEMPA+XPT(K,I)*D(I)
+      TEMPB=TEMPB+XPT(K,I)*S(I)
+  100 TEMPC=TEMPC+XPT(K,I)*XOPT(I)
+      WVEC(K,1)=QUART*(TEMPA*TEMPA+TEMPB*TEMPB)
+      WVEC(K,2)=TEMPA*TEMPC
+      WVEC(K,3)=TEMPB*TEMPC
+      WVEC(K,4)=QUART*(TEMPA*TEMPA-TEMPB*TEMPB)
+  110 WVEC(K,5)=HALF*TEMPA*TEMPB
+      DO 120 I=1,N
+      IP=I+NPT
+      WVEC(IP,1)=ZERO
+      WVEC(IP,2)=D(I)
+      WVEC(IP,3)=S(I)
+      WVEC(IP,4)=ZERO
+  120 WVEC(IP,5)=ZERO
+C
+C     Put the coefficents of THETA*Wcheck in PROD.
+C
+      DO 190 JC=1,5
+      NW=NPT
+      IF (JC .EQ. 2 .OR. JC .EQ. 3) NW=NDIM
+      DO 130 K=1,NPT
+  130 PROD(K,JC)=ZERO
+      DO 150 J=1,NPTM
+      SUM=ZERO
+      DO 140 K=1,NPT
+  140 SUM=SUM+ZMAT(K,J)*WVEC(K,JC)
+      IF (J .LT. IDZ) SUM=-SUM
+      DO 150 K=1,NPT
+  150 PROD(K,JC)=PROD(K,JC)+SUM*ZMAT(K,J)
+      IF (NW .EQ. NDIM) THEN
+          DO 170 K=1,NPT
+          SUM=ZERO
+          DO 160 J=1,N
+  160     SUM=SUM+BMAT(K,J)*WVEC(NPT+J,JC)
+  170     PROD(K,JC)=PROD(K,JC)+SUM
+      END IF
+      DO 190 J=1,N
+      SUM=ZERO
+      DO 180 I=1,NW
+  180 SUM=SUM+BMAT(I,J)*WVEC(I,JC)
+  190 PROD(NPT+J,JC)=SUM
+C
+C     Include in DEN the part of BETA that depends on THETA.
+C
+      DO 210 K=1,NDIM
+      SUM=ZERO
+      DO 200 I=1,5
+      PAR(I)=HALF*PROD(K,I)*WVEC(K,I)
+  200 SUM=SUM+PAR(I)
+      DEN(1)=DEN(1)-PAR(1)-SUM
+      TEMPA=PROD(K,1)*WVEC(K,2)+PROD(K,2)*WVEC(K,1)
+      TEMPB=PROD(K,2)*WVEC(K,4)+PROD(K,4)*WVEC(K,2)
+      TEMPC=PROD(K,3)*WVEC(K,5)+PROD(K,5)*WVEC(K,3)
+      DEN(2)=DEN(2)-TEMPA-HALF*(TEMPB+TEMPC)
+      DEN(6)=DEN(6)-HALF*(TEMPB-TEMPC)
+      TEMPA=PROD(K,1)*WVEC(K,3)+PROD(K,3)*WVEC(K,1)
+      TEMPB=PROD(K,2)*WVEC(K,5)+PROD(K,5)*WVEC(K,2)
+      TEMPC=PROD(K,3)*WVEC(K,4)+PROD(K,4)*WVEC(K,3)
+      DEN(3)=DEN(3)-TEMPA-HALF*(TEMPB-TEMPC)
+      DEN(7)=DEN(7)-HALF*(TEMPB+TEMPC)
+      TEMPA=PROD(K,1)*WVEC(K,4)+PROD(K,4)*WVEC(K,1)
+      DEN(4)=DEN(4)-TEMPA-PAR(2)+PAR(3)
+      TEMPA=PROD(K,1)*WVEC(K,5)+PROD(K,5)*WVEC(K,1)
+      TEMPB=PROD(K,2)*WVEC(K,3)+PROD(K,3)*WVEC(K,2)
+      DEN(5)=DEN(5)-TEMPA-HALF*TEMPB
+      DEN(8)=DEN(8)-PAR(4)+PAR(5)
+      TEMPA=PROD(K,4)*WVEC(K,5)+PROD(K,5)*WVEC(K,4)
+  210 DEN(9)=DEN(9)-HALF*TEMPA
+C
+C     Extend DEN so that it holds all the coefficients of DENOM.
+C
+      SUM=ZERO
+      DO 220 I=1,5
+      PAR(I)=HALF*PROD(KNEW,I)**2
+  220 SUM=SUM+PAR(I)
+      DENEX(1)=ALPHA*DEN(1)+PAR(1)+SUM
+      TEMPA=TWO*PROD(KNEW,1)*PROD(KNEW,2)
+      TEMPB=PROD(KNEW,2)*PROD(KNEW,4)
+      TEMPC=PROD(KNEW,3)*PROD(KNEW,5)
+      DENEX(2)=ALPHA*DEN(2)+TEMPA+TEMPB+TEMPC
+      DENEX(6)=ALPHA*DEN(6)+TEMPB-TEMPC
+      TEMPA=TWO*PROD(KNEW,1)*PROD(KNEW,3)
+      TEMPB=PROD(KNEW,2)*PROD(KNEW,5)
+      TEMPC=PROD(KNEW,3)*PROD(KNEW,4)
+      DENEX(3)=ALPHA*DEN(3)+TEMPA+TEMPB-TEMPC
+      DENEX(7)=ALPHA*DEN(7)+TEMPB+TEMPC
+      TEMPA=TWO*PROD(KNEW,1)*PROD(KNEW,4)
+      DENEX(4)=ALPHA*DEN(4)+TEMPA+PAR(2)-PAR(3)
+      TEMPA=TWO*PROD(KNEW,1)*PROD(KNEW,5)
+      DENEX(5)=ALPHA*DEN(5)+TEMPA+PROD(KNEW,2)*PROD(KNEW,3)
+      DENEX(8)=ALPHA*DEN(8)+PAR(4)-PAR(5)
+      DENEX(9)=ALPHA*DEN(9)+PROD(KNEW,4)*PROD(KNEW,5)
+C
+C     Seek the value of the angle that maximizes the modulus of DENOM.
+C
+      SUM=DENEX(1)+DENEX(2)+DENEX(4)+DENEX(6)+DENEX(8)
+      DENOLD=SUM
+      DENMAX=SUM
+      ISAVE=0
+      IU=49
+      TEMP=TWOPI/DFLOAT(IU+1)
+      PAR(1)=ONE
+      DO 250 I=1,IU
+      ANGLE=DFLOAT(I)*TEMP
+      PAR(2)=DCOS(ANGLE)
+      PAR(3)=DSIN(ANGLE)
+      DO 230 J=4,8,2
+      PAR(J)=PAR(2)*PAR(J-2)-PAR(3)*PAR(J-1)
+  230 PAR(J+1)=PAR(2)*PAR(J-1)+PAR(3)*PAR(J-2)
+      SUMOLD=SUM
+      SUM=ZERO
+      DO 240 J=1,9
+  240 SUM=SUM+DENEX(J)*PAR(J)
+      IF (DABS(SUM) .GT. DABS(DENMAX)) THEN
+          DENMAX=SUM
+          ISAVE=I
+          TEMPA=SUMOLD
+      ELSE IF (I .EQ. ISAVE+1) THEN
+          TEMPB=SUM
+      END IF
+  250 CONTINUE
+      IF (ISAVE .EQ. 0) TEMPA=SUM
+      IF (ISAVE .EQ. IU) TEMPB=DENOLD
+      STEP=ZERO
+      IF (TEMPA .NE. TEMPB) THEN
+          TEMPA=TEMPA-DENMAX
+          TEMPB=TEMPB-DENMAX
+          STEP=HALF*(TEMPA-TEMPB)/(TEMPA+TEMPB)
+      END IF
+      ANGLE=TEMP*(DFLOAT(ISAVE)+STEP)
+C
+C     Calculate the new parameters of the denominator, the new VLAG vector
+C     and the new D. Then test for convergence.
+C
+      PAR(2)=DCOS(ANGLE)
+      PAR(3)=DSIN(ANGLE)
+      DO 260 J=4,8,2
+      PAR(J)=PAR(2)*PAR(J-2)-PAR(3)*PAR(J-1)
+  260 PAR(J+1)=PAR(2)*PAR(J-1)+PAR(3)*PAR(J-2)
+      BETA=ZERO
+      DENMAX=ZERO
+      DO 270 J=1,9
+      BETA=BETA+DEN(J)*PAR(J)
+  270 DENMAX=DENMAX+DENEX(J)*PAR(J)
+      DO 280 K=1,NDIM
+      VLAG(K)=ZERO
+      DO 280 J=1,5
+  280 VLAG(K)=VLAG(K)+PROD(K,J)*PAR(J)
+      TAU=VLAG(KNEW)
+      DD=ZERO
+      TEMPA=ZERO
+      TEMPB=ZERO
+      DO 290 I=1,N
+      D(I)=PAR(2)*D(I)+PAR(3)*S(I)
+      W(I)=XOPT(I)+D(I)
+      DD=DD+D(I)**2
+      TEMPA=TEMPA+D(I)*W(I)
+  290 TEMPB=TEMPB+W(I)*W(I)
+      IF (ITERC .GE. N) GOTO 340
+      IF (ITERC .GT. 1) DENSAV=DMAX1(DENSAV,DENOLD)
+      IF (DABS(DENMAX) .LE. 1.1D0*DABS(DENSAV)) GOTO 340
+      DENSAV=DENMAX
+C
+C     Set S to half the gradient of the denominator with respect to D.
+C     Then branch for the next iteration.
+C
+      DO 300 I=1,N
+      TEMP=TEMPA*XOPT(I)+TEMPB*D(I)-VLAG(NPT+I)
+  300 S(I)=TAU*BMAT(KNEW,I)+ALPHA*TEMP
+      DO 320 K=1,NPT
+      SUM=ZERO
+      DO 310 J=1,N
+  310 SUM=SUM+XPT(K,J)*W(J)
+      TEMP=(TAU*W(N+K)-ALPHA*VLAG(K))*SUM
+      DO 320 I=1,N
+  320 S(I)=S(I)+TEMP*XPT(K,I)
+      SS=ZERO
+      DS=ZERO
+      DO 330 I=1,N
+      SS=SS+S(I)**2
+  330 DS=DS+D(I)*S(I)
+      SSDEN=DD*SS-DS*DS
+      IF (SSDEN .GE. 1.0D-8*DD*SS) GOTO 70
+C
+C     Set the vector W before the RETURN from the subroutine.
+C
+  340 DO 350 K=1,NDIM
+      W(K)=ZERO
+      DO 350 J=1,5
+  350 W(K)=W(K)+WVEC(K,J)*PAR(J)
+      VLAG(KOPT)=VLAG(KOPT)+ONE
+      RETURN
+      END 
+      SUBROUTINE BIGLAG (N,NPT,XOPT,XPT,BMAT,ZMAT,IDZ,NDIM,KNEW,
+     1  DELTA,D,ALPHA,HCOL,GC,GD,S,W)
+      IMPLICIT REAL*8 (A-H,O-Z)
+      DIMENSION XOPT(*),XPT(NPT,*),BMAT(NDIM,*),ZMAT(NPT,*),D(*),
+     1  HCOL(*),GC(*),GD(*),S(*),W(*)
+C
+C     N is the number of variables.
+C     NPT is the number of interpolation equations.
+C     XOPT is the best interpolation point so far.
+C     XPT contains the coordinates of the current interpolation points.
+C     BMAT provides the last N columns of H.
+C     ZMAT and IDZ give a factorization of the first NPT by NPT submatrix of H.
+C     NDIM is the first dimension of BMAT and has the value NPT+N.
+C     KNEW is the index of the interpolation point that is going to be moved.
+C     DELTA is the current trust region bound.
+C     D will be set to the step from XOPT to the new point.
+C     ALPHA will be set to the KNEW-th diagonal element of the H matrix.
+C     HCOL, GC, GD, S and W will be used for working space.
+C
+C     The step D is calculated in a way that attempts to maximize the modulus
+C     of LFUNC(XOPT+D), subject to the bound ||D|| .LE. DELTA, where LFUNC is
+C     the KNEW-th Lagrange function.
+C
+C     Set some constants.
+C
+      HALF=0.5D0
+      ONE=1.0D0
+      ZERO=0.0D0
+      TWOPI=8.0D0*DATAN(ONE)
+      DELSQ=DELTA*DELTA
+      NPTM=NPT-N-1
+C
+C     Set the first NPT components of HCOL to the leading elements of the
+C     KNEW-th column of H.
+C
+      ITERC=0
+      DO 10 K=1,NPT
+   10 HCOL(K)=ZERO
+      DO 20 J=1,NPTM
+      TEMP=ZMAT(KNEW,J)
+      IF (J .LT. IDZ) TEMP=-TEMP
+      DO 20 K=1,NPT
+   20 HCOL(K)=HCOL(K)+TEMP*ZMAT(K,J)
+      ALPHA=HCOL(KNEW)
+C
+C     Set the unscaled initial direction D. Form the gradient of LFUNC at
+C     XOPT, and multiply D by the second derivative matrix of LFUNC.
+C
+      DD=ZERO
+      DO 30 I=1,N
+      D(I)=XPT(KNEW,I)-XOPT(I)
+      GC(I)=BMAT(KNEW,I)
+      GD(I)=ZERO
+   30 DD=DD+D(I)**2
+      DO 50 K=1,NPT
+      TEMP=ZERO
+      SUM=ZERO
+      DO 40 J=1,N
+      TEMP=TEMP+XPT(K,J)*XOPT(J)
+   40 SUM=SUM+XPT(K,J)*D(J)
+      TEMP=HCOL(K)*TEMP
+      SUM=HCOL(K)*SUM
+      DO 50 I=1,N
+      GC(I)=GC(I)+TEMP*XPT(K,I)
+   50 GD(I)=GD(I)+SUM*XPT(K,I)
+C
+C     Scale D and GD, with a sign change if required. Set S to another
+C     vector in the initial two dimensional subspace.
+C
+      GG=ZERO
+      SP=ZERO
+      DHD=ZERO
+      DO 60 I=1,N
+      GG=GG+GC(I)**2
+      SP=SP+D(I)*GC(I)
+   60 DHD=DHD+D(I)*GD(I)
+      SCALE=DELTA/DSQRT(DD)
+      IF (SP*DHD .LT. ZERO) SCALE=-SCALE
+      TEMP=ZERO
+      IF (SP*SP .GT. 0.99D0*DD*GG) TEMP=ONE
+      TAU=SCALE*(DABS(SP)+HALF*SCALE*DABS(DHD))
+      IF (GG*DELSQ .LT. 0.01D0*TAU*TAU) TEMP=ONE
+      DO 70 I=1,N
+      D(I)=SCALE*D(I)
+      GD(I)=SCALE*GD(I)
+   70 S(I)=GC(I)+TEMP*GD(I)
+C
+C     Begin the iteration by overwriting S with a vector that has the
+C     required length and direction, except that termination occurs if
+C     the given D and S are nearly parallel.
+C
+   80 ITERC=ITERC+1
+      DD=ZERO
+      SP=ZERO
+      SS=ZERO
+      DO 90 I=1,N
+      DD=DD+D(I)**2
+      SP=SP+D(I)*S(I)
+   90 SS=SS+S(I)**2
+      TEMP=DD*SS-SP*SP
+      IF (TEMP .LE. 1.0D-8*DD*SS) GOTO 160
+      DENOM=DSQRT(TEMP)
+      DO 100 I=1,N
+      S(I)=(DD*S(I)-SP*D(I))/DENOM
+  100 W(I)=ZERO
+C
+C     Calculate the coefficients of the objective function on the circle,
+C     beginning with the multiplication of S by the second derivative matrix.
+C
+      DO 120 K=1,NPT
+      SUM=ZERO
+      DO 110 J=1,N
+  110 SUM=SUM+XPT(K,J)*S(J)
+      SUM=HCOL(K)*SUM
+      DO 120 I=1,N
+  120 W(I)=W(I)+SUM*XPT(K,I)
+      CF1=ZERO
+      CF2=ZERO
+      CF3=ZERO
+      CF4=ZERO
+      CF5=ZERO
+      DO 130 I=1,N
+      CF1=CF1+S(I)*W(I)
+      CF2=CF2+D(I)*GC(I)
+      CF3=CF3+S(I)*GC(I)
+      CF4=CF4+D(I)*GD(I)
+  130 CF5=CF5+S(I)*GD(I)
+      CF1=HALF*CF1
+      CF4=HALF*CF4-CF1
+C
+C     Seek the value of the angle that maximizes the modulus of TAU.
+C
+      TAUBEG=CF1+CF2+CF4
+      TAUMAX=TAUBEG
+      TAUOLD=TAUBEG
+      ISAVE=0
+      IU=49
+      TEMP=TWOPI/DFLOAT(IU+1)
+      DO 140 I=1,IU
+      ANGLE=DFLOAT(I)*TEMP
+      CTH=DCOS(ANGLE)
+      STH=DSIN(ANGLE)
+      TAU=CF1+(CF2+CF4*CTH)*CTH+(CF3+CF5*CTH)*STH
+      IF (DABS(TAU) .GT. DABS(TAUMAX)) THEN
+          TAUMAX=TAU
+          ISAVE=I
+          TEMPA=TAUOLD
+      ELSE IF (I .EQ. ISAVE+1) THEN
+          TEMPB=TAU
+      END IF
+  140 TAUOLD=TAU
+      IF (ISAVE .EQ. 0) TEMPA=TAU
+      IF (ISAVE .EQ. IU) TEMPB=TAUBEG
+      STEP=ZERO
+      IF (TEMPA .NE. TEMPB) THEN
+          TEMPA=TEMPA-TAUMAX
+          TEMPB=TEMPB-TAUMAX
+          STEP=HALF*(TEMPA-TEMPB)/(TEMPA+TEMPB)
+      END IF
+      ANGLE=TEMP*(DFLOAT(ISAVE)+STEP)
+C
+C     Calculate the new D and GD. Then test for convergence.
+C
+      CTH=DCOS(ANGLE)
+      STH=DSIN(ANGLE)
+      TAU=CF1+(CF2+CF4*CTH)*CTH+(CF3+CF5*CTH)*STH
+      DO 150 I=1,N
+      D(I)=CTH*D(I)+STH*S(I)
+      GD(I)=CTH*GD(I)+STH*W(I)
+  150 S(I)=GC(I)+GD(I)
+      IF (DABS(TAU) .LE. 1.1D0*DABS(TAUBEG)) GOTO 160
+      IF (ITERC .LT. N) GOTO 80
+  160 RETURN
+      END 
+      FUNCTION NEWUOA (N,NPT,X,RHOBEG,RHOEND,IPRINT,MAXFUN,W,IWF,
+     1  CALFUN)
+      IMPLICIT REAL*8 (A-H,O-Z)
+      DIMENSION X(*),W(*),IWF(*)
+      EXTERNAL CALFUN
+      real*8 NEWUOB, NEWUOA
+C
+C     This subroutine seeks the least value of a function of many variables,
+C     by a trust region method that forms quadratic models by interpolation.
+C     There can be some freedom in the interpolation conditions, which is
+C     taken up by minimizing the Frobenius norm of the change to the second
+C     derivative of the quadratic model, beginning with a zero matrix. The
+C     arguments of the subroutine are as follows.
+C
+C     N must be set to the number of variables and must be at least two.
+C     NPT is the number of interpolation conditions. Its value must be in the
+C       interval [N+2,(N+1)(N+2)/2].
+C     Initial values of the variables must be set in X(1),X(2),...,X(N). They
+C       will be changed to the values that give the least calculated F.
+C     RHOBEG and RHOEND must be set to the initial and final values of a trust
+C       region radius, so both must be positive with RHOEND<=RHOBEG. Typically
+C       RHOBEG should be about one tenth of the greatest expected change to a
+C       variable, and RHOEND should indicate the accuracy that is required in
+C       the final values of the variables.
+C     The value of IPRINT should be set to 0, 1, 2 or 3, which controls the
+C       amount of printing. Specifically, there is no output if IPRINT=0 and
+C       there is output only at the return if IPRINT=1. Otherwise, each new
+C       value of RHO is printed, with the best vector of variables so far and
+C       the corresponding value of the objective function. Further, each new
+C       value of F with its variables are output if IPRINT=3.
+C     MAXFUN must be set to an upper bound on the number of calls of CALFUN.
+C     The array W will be used for working space. Its length must be at least
+C     (NPT+13)*(NPT+N)+3*N*(N+3)/2.
+C
+C     SUBROUTINE CALFUN (N,X,F) must be provided by the user. It must set F to
+C     the value of the objective function for the variables X(1),X(2),...,X(N).
+C
+C     Partition the working space array, so that different parts of it can be
+C     treated separately by the subroutine that performs the main calculation.
+C
+      NP=N+1
+      NPTM=NPT-NP
+      IF (NPT .LT. N+2 .OR. NPT .GT. ((N+2)*NP)/2) THEN
+          PRINT 10
+   10     FORMAT (/4X,'Return from NEWUOA because NPT is not in',
+     1      ' the required interval')
+          GO TO 20
+      END IF
+      NDIM=NPT+N
+      IXB=1
+      IXO=IXB+N
+      IXN=IXO+N
+      IXP=IXN+N
+      IFV=IXP+N*NPT
+      IGQ=IFV+NPT
+      IHQ=IGQ+N
+      IPQ=IHQ+(N*NP)/2
+      IBMAT=IPQ+NPT
+      IZMAT=IBMAT+NDIM*N
+      ID=IZMAT+NPT*NPTM
+      IVL=ID+N
+      IW=IVL+NDIM
+C
+C     The above settings provide a partition of W for subroutine NEWUOB.
+C     The partition requires the first NPT*(NPT+N)+5*N*(N+3)/2 elements of
+C     W plus the space that is needed by the last array of NEWUOB.
+C
+      NEWUOA= NEWUOB (N,NPT,X,RHOBEG,RHOEND,IPRINT,MAXFUN,W(IXB),
+     1  W(IXO),W(IXN),W(IXP),W(IFV),W(IGQ),W(IHQ),W(IPQ),W(IBMAT),
+     2  W(IZMAT),NDIM,W(ID),W(IVL),W(IW),
+     3  IWF, CALFUN)
+   20 RETURN
+      END 
+
+
+
+
+
+
+      FUNCTION NEWUOB (N,NPT,X,RHOBEG,RHOEND,IPRINT,MAXFUN,XBASE,
+     1  XOPT,XNEW,XPT,FVAL,GQ,HQ,PQ,BMAT,ZMAT,NDIM,D,VLAG,W,IWF,CALFUN)
+      IMPLICIT REAL*8 (A-H,O-Z)
+      DIMENSION X(*),XBASE(*),XOPT(*),XNEW(*),XPT(NPT,*),FVAL(*),
+     1  GQ(*),HQ(*),PQ(*),BMAT(NDIM,*),ZMAT(NPT,*),D(*),VLAG(*),W(*),
+     2  IWF(*)
+      EXTERNAL CALFUN
+      REAL*8 NEWUOB
+C
+C     The arguments N, NPT, X, RHOBEG, RHOEND, IPRINT and MAXFUN are identical
+C       to the corresponding arguments in SUBROUTINE NEWUOA.
+C     XBASE will hold a shift of origin that should reduce the contributions
+C       from rounding errors to values of the model and Lagrange functions.
+C     XOPT will be set to the displacement from XBASE of the vector of
+C       variables that provides the least calculated F so far.
+C     XNEW will be set to the displacement from XBASE of the vector of
+C       variables for the current calculation of F.
+C     XPT will contain the interpolation point coordinates relative to XBASE.
+C     FVAL will hold the values of F at the interpolation points.
+C     GQ will hold the gradient of the quadratic model at XBASE.
+C     HQ will hold the explicit second derivatives of the quadratic model.
+C     PQ will contain the parameters of the implicit second derivatives of
+C       the quadratic model.
+C     BMAT will hold the last N columns of H.
+C     ZMAT will hold the factorization of the leading NPT by NPT submatrix of
+C       H, this factorization being ZMAT times Diag(DZ) times ZMAT^T, where
+C       the elements of DZ are plus or minus one, as specified by IDZ.
+C     NDIM is the first dimension of BMAT and has the value NPT+N.
+C     D is reserved for trial steps from XOPT.
+C     VLAG will contain the values of the Lagrange functions at a new point X.
+C       They are part of a product that requires VLAG to be of length NDIM.
+C     The array W will be used for working space. Its length must be at least
+C       10*NDIM = 10*(NPT+N).
+C
+C     Set some constants.
+C
+      HALF=0.5D0
+      ONE=1.0D0
+      TENTH=0.1D0
+      ZERO=0.0D0
+      NP=N+1
+      NH=(N*NP)/2
+      NPTM=NPT-NP
+      NFTEST=MAX0(MAXFUN,1)
+C
+C     Set the initial elements of XPT, BMAT, HQ, PQ and ZMAT to zero.
+C
+      DO 20 J=1,N
+      XBASE(J)=X(J)
+      DO 10 K=1,NPT
+   10 XPT(K,J)=ZERO
+      DO 20 I=1,NDIM
+   20 BMAT(I,J)=ZERO
+      DO 30 IH=1,NH
+   30 HQ(IH)=ZERO
+      DO 40 K=1,NPT
+      PQ(K)=ZERO
+      DO 40 J=1,NPTM
+   40 ZMAT(K,J)=ZERO
+C
+C     Begin the initialization procedure. NF becomes one more than the number
+C     of function values so far. The coordinates of the displacement of the
+C     next initial interpolation point from XBASE are set in XPT(NF,.).
+C
+      RHOSQ=RHOBEG*RHOBEG
+      RECIP=ONE/RHOSQ
+      RECIQ=DSQRT(HALF)/RHOSQ
+      NF=0
+   50 NFM=NF
+      NFMM=NF-N
+      NF=NF+1
+      IF (NFM .LE. 2*N) THEN
+          IF (NFM .GE. 1 .AND. NFM .LE. N) THEN
+              XPT(NF,NFM)=RHOBEG
+          ELSE IF (NFM .GT. N) THEN
+              XPT(NF,NFMM)=-RHOBEG
+          END IF
+      ELSE
+          ITEMP=(NFMM-1)/N
+          JPT=NFM-ITEMP*N-N
+          IPT=JPT+ITEMP
+          IF (IPT .GT. N) THEN
+              ITEMP=JPT
+              JPT=IPT-N
+              IPT=ITEMP
+          END IF
+          XIPT=RHOBEG
+          IF (FVAL(IPT+NP) .LT. FVAL(IPT+1)) XIPT=-XIPT
+          XJPT=RHOBEG
+          IF (FVAL(JPT+NP) .LT. FVAL(JPT+1)) XJPT=-XJPT
+          XPT(NF,IPT)=XIPT
+          XPT(NF,JPT)=XJPT
+      END IF
+C
+C     Calculate the next value of F, label 70 being reached immediately
+C     after this calculation. The least function value so far and its index
+C     are required.
+C
+      DO 60 J=1,N
+   60 X(J)=XPT(NF,J)+XBASE(J)
+      GOTO 310
+   70 FVAL(NF)=F
+      IF (NF .EQ. 1) THEN
+          FBEG=F
+          FOPT=F
+          KOPT=1
+      ELSE IF (F .LT. FOPT) THEN
+          FOPT=F
+          KOPT=NF
+      END IF
+C
+C     Set the nonzero initial elements of BMAT and the quadratic model in
+C     the cases when NF is at most 2*N+1.
+C
+      IF (NFM .LE. 2*N) THEN
+          IF (NFM .GE. 1 .AND. NFM .LE. N) THEN
+              GQ(NFM)=(F-FBEG)/RHOBEG
+              IF (NPT .LT. NF+N) THEN
+                  BMAT(1,NFM)=-ONE/RHOBEG
+                  BMAT(NF,NFM)=ONE/RHOBEG
+                  BMAT(NPT+NFM,NFM)=-HALF*RHOSQ
+              END IF
+          ELSE IF (NFM .GT. N) THEN
+              BMAT(NF-N,NFMM)=HALF/RHOBEG
+              BMAT(NF,NFMM)=-HALF/RHOBEG
+              ZMAT(1,NFMM)=-RECIQ-RECIQ
+              ZMAT(NF-N,NFMM)=RECIQ
+              ZMAT(NF,NFMM)=RECIQ
+              IH=(NFMM*(NFMM+1))/2
+              TEMP=(FBEG-F)/RHOBEG
+              HQ(IH)=(GQ(NFMM)-TEMP)/RHOBEG
+              GQ(NFMM)=HALF*(GQ(NFMM)+TEMP)
+          END IF
+C
+C     Set the off-diagonal second derivatives of the Lagrange functions and
+C     the initial quadratic model.
+C
+      ELSE
+          IH=(IPT*(IPT-1))/2+JPT
+          IF (XIPT .LT. ZERO) IPT=IPT+N
+          IF (XJPT .LT. ZERO) JPT=JPT+N
+          ZMAT(1,NFMM)=RECIP
+          ZMAT(NF,NFMM)=RECIP
+          ZMAT(IPT+1,NFMM)=-RECIP
+          ZMAT(JPT+1,NFMM)=-RECIP
+          HQ(IH)=(FBEG-FVAL(IPT+1)-FVAL(JPT+1)+F)/(XIPT*XJPT)
+      END IF
+      IF (NF .LT. NPT) GOTO 50
+C
+C     Begin the iterative procedure, because the initial model is complete.
+C
+      RHO=RHOBEG
+      DELTA=RHO
+      IDZ=1
+      DIFFA=ZERO
+      DIFFB=ZERO
+      ITEST=0
+      XOPTSQ=ZERO
+      DO 80 I=1,N
+      XOPT(I)=XPT(KOPT,I)
+   80 XOPTSQ=XOPTSQ+XOPT(I)**2
+   90 NFSAV=NF
+C
+C     Generate the next trust region step and test its length. Set KNEW
+C     to -1 if the purpose of the next F will be to improve the model.
+C
+  100 KNEW=0
+      CALL TRSAPP (N,NPT,XOPT,XPT,GQ,HQ,PQ,DELTA,D,W,W(NP),
+     1  W(NP+N),W(NP+2*N),CRVMIN)
+      DSQ=ZERO
+      DO 110 I=1,N
+  110 DSQ=DSQ+D(I)**2
+      DNORM=DMIN1(DELTA,DSQRT(DSQ))
+      IF (DNORM .LT. HALF*RHO) THEN
+          KNEW=-1
+          DELTA=TENTH*DELTA
+          RATIO=-1.0D0
+          IF (DELTA .LE. 1.5D0*RHO) DELTA=RHO
+          IF (NF .LE. NFSAV+2) GOTO 460
+          TEMP=0.125D0*CRVMIN*RHO*RHO
+          IF (TEMP .LE. DMAX1(DIFFA,DIFFB,DIFFC)) GOTO 460
+          GOTO 490
+      END IF
+C
+C     Shift XBASE if XOPT may be too far from XBASE. First make the changes
+C     to BMAT that do not depend on ZMAT.
+C
+  120 IF (DSQ .LE. 1.0D-3*XOPTSQ) THEN
+          TEMPQ=0.25D0*XOPTSQ
+          DO 140 K=1,NPT
+          SUM=ZERO
+          DO 130 I=1,N
+  130     SUM=SUM+XPT(K,I)*XOPT(I)
+          TEMP=PQ(K)*SUM
+          SUM=SUM-HALF*XOPTSQ
+          W(NPT+K)=SUM
+          DO 140 I=1,N
+          GQ(I)=GQ(I)+TEMP*XPT(K,I)
+          XPT(K,I)=XPT(K,I)-HALF*XOPT(I)
+          VLAG(I)=BMAT(K,I)
+          W(I)=SUM*XPT(K,I)+TEMPQ*XOPT(I)
+          IP=NPT+I
+          DO 140 J=1,I
+  140     BMAT(IP,J)=BMAT(IP,J)+VLAG(I)*W(J)+W(I)*VLAG(J)
+C
+C     Then the revisions of BMAT that depend on ZMAT are calculated.
+C
+          DO 180 K=1,NPTM
+          SUMZ=ZERO
+          DO 150 I=1,NPT
+          SUMZ=SUMZ+ZMAT(I,K)
+  150     W(I)=W(NPT+I)*ZMAT(I,K)
+          DO 170 J=1,N
+          SUM=TEMPQ*SUMZ*XOPT(J)
+          DO 160 I=1,NPT
+  160     SUM=SUM+W(I)*XPT(I,J)
+          VLAG(J)=SUM
+          IF (K .LT. IDZ) SUM=-SUM
+          DO 170 I=1,NPT
+  170     BMAT(I,J)=BMAT(I,J)+SUM*ZMAT(I,K)
+          DO 180 I=1,N
+          IP=I+NPT
+          TEMP=VLAG(I)
+          IF (K .LT. IDZ) TEMP=-TEMP
+          DO 180 J=1,I
+  180     BMAT(IP,J)=BMAT(IP,J)+TEMP*VLAG(J)
+C
+C     The following instructions complete the shift of XBASE, including
+C     the changes to the parameters of the quadratic model.
+C
+          IH=0
+          DO 200 J=1,N
+          W(J)=ZERO
+          DO 190 K=1,NPT
+          W(J)=W(J)+PQ(K)*XPT(K,J)
+  190     XPT(K,J)=XPT(K,J)-HALF*XOPT(J)
+          DO 200 I=1,J
+          IH=IH+1
+          IF (I .LT. J) GQ(J)=GQ(J)+HQ(IH)*XOPT(I)
+          GQ(I)=GQ(I)+HQ(IH)*XOPT(J)
+          HQ(IH)=HQ(IH)+W(I)*XOPT(J)+XOPT(I)*W(J)
+  200     BMAT(NPT+I,J)=BMAT(NPT+J,I)
+          DO 210 J=1,N
+          XBASE(J)=XBASE(J)+XOPT(J)
+  210     XOPT(J)=ZERO
+          XOPTSQ=ZERO
+      END IF
+C
+C     Pick the model step if KNEW is positive. A different choice of D
+C     may be made later, if the choice of D by BIGLAG causes substantial
+C     cancellation in DENOM.
+C
+      IF (KNEW .GT. 0) THEN
+          CALL BIGLAG (N,NPT,XOPT,XPT,BMAT,ZMAT,IDZ,NDIM,KNEW,DSTEP,
+     1      D,ALPHA,VLAG,VLAG(NPT+1),W,W(NP),W(NP+N))
+      END IF
+C
+C     Calculate VLAG and BETA for the current choice of D. The first NPT
+C     components of W_check will be held in W.
+C
+      DO 230 K=1,NPT
+      SUMA=ZERO
+      SUMB=ZERO
+      SUM=ZERO
+      DO 220 J=1,N
+      SUMA=SUMA+XPT(K,J)*D(J)
+      SUMB=SUMB+XPT(K,J)*XOPT(J)
+  220 SUM=SUM+BMAT(K,J)*D(J)
+      W(K)=SUMA*(HALF*SUMA+SUMB)
+  230 VLAG(K)=SUM
+      BETA=ZERO
+      DO 250 K=1,NPTM
+      SUM=ZERO
+      DO 240 I=1,NPT
+  240 SUM=SUM+ZMAT(I,K)*W(I)
+      IF (K .LT. IDZ) THEN
+          BETA=BETA+SUM*SUM
+          SUM=-SUM
+      ELSE
+          BETA=BETA-SUM*SUM
+      END IF
+      DO 250 I=1,NPT
+  250 VLAG(I)=VLAG(I)+SUM*ZMAT(I,K)
+      BSUM=ZERO
+      DX=ZERO
+      DO 280 J=1,N
+      SUM=ZERO
+      DO 260 I=1,NPT
+  260 SUM=SUM+W(I)*BMAT(I,J)
+      BSUM=BSUM+SUM*D(J)
+      JP=NPT+J
+      DO 270 K=1,N
+  270 SUM=SUM+BMAT(JP,K)*D(K)
+      VLAG(JP)=SUM
+      BSUM=BSUM+SUM*D(J)
+  280 DX=DX+D(J)*XOPT(J)
+      BETA=DX*DX+DSQ*(XOPTSQ+DX+DX+HALF*DSQ)+BETA-BSUM
+      VLAG(KOPT)=VLAG(KOPT)+ONE
+C
+C     If KNEW is positive and if the cancellation in DENOM is unacceptable,
+C     then BIGDEN calculates an alternative model step, XNEW being used for
+C     working space.
+C
+      IF (KNEW .GT. 0) THEN
+          TEMP=ONE+ALPHA*BETA/VLAG(KNEW)**2
+          IF (DABS(TEMP) .LE. 0.8D0) THEN
+              CALL BIGDEN (N,NPT,XOPT,XPT,BMAT,ZMAT,IDZ,NDIM,KOPT,
+     1          KNEW,D,W,VLAG,BETA,XNEW,W(NDIM+1),W(6*NDIM+1))
+          END IF
+      END IF
+C
+C     Calculate the next value of the objective function.
+C
+  290 DO 300 I=1,N
+      XNEW(I)=XOPT(I)+D(I)
+  300 X(I)=XBASE(I)+XNEW(I)
+      NF=NF+1
+  310 IF (NF .GT. NFTEST) THEN
+          NF=NF-1
+          IF (IPRINT .GT. 0) PRINT 320
+  320     FORMAT (/4X,'Return from NEWUOA because CALFUN has been',
+     1      ' called MAXFUN times.')
+          GOTO 530
+      END IF
+      CALL CALFUN (N,X,F,IWF)
+      IF (IPRINT .EQ. 3) THEN
+          PRINT 330, NF,F,(X(I),I=1,N)
+  330      FORMAT (/4X,'Function number',I6,'    F =',1PD18.10,
+     1       '    The corresponding X is:'/(2X,5D15.6))
+      END IF
+      IF (NF .LE. NPT) GOTO 70
+      IF (KNEW .EQ. -1) GOTO 530
+C
+C     Use the quadratic model to predict the change in F due to the step D,
+C     and set DIFF to the error of this prediction.
+C
+      VQUAD=ZERO
+      IH=0
+      DO 340 J=1,N
+      VQUAD=VQUAD+D(J)*GQ(J)
+      DO 340 I=1,J
+      IH=IH+1
+      TEMP=D(I)*XNEW(J)+D(J)*XOPT(I)
+      IF (I .EQ. J) TEMP=HALF*TEMP
+  340 VQUAD=VQUAD+TEMP*HQ(IH)
+      DO 350 K=1,NPT
+  350 VQUAD=VQUAD+PQ(K)*W(K)
+      DIFF=F-FOPT-VQUAD
+      DIFFC=DIFFB
+      DIFFB=DIFFA
+      DIFFA=DABS(DIFF)
+      IF (DNORM .GT. RHO) NFSAV=NF
+C
+C     Update FOPT and XOPT if the new F is the least value of the objective
+C     function so far. The branch when KNEW is positive occurs if D is not
+C     a trust region step.
+C
+      FSAVE=FOPT
+      IF (F .LT. FOPT) THEN
+          FOPT=F
+          XOPTSQ=ZERO
+          DO 360 I=1,N
+          XOPT(I)=XNEW(I)
+  360     XOPTSQ=XOPTSQ+XOPT(I)**2
+      END IF
+      KSAVE=KNEW
+      IF (KNEW .GT. 0) GOTO 410
+C
+C     Pick the next value of DELTA after a trust region step.
+C
+      IF (VQUAD .GE. ZERO) THEN
+          IF (IPRINT .GT. 0) PRINT 370
+  370     FORMAT (/4X,'Return from NEWUOA because a trust',
+     1      ' region step has failed to reduce Q.')
+          GOTO 530
+      END IF
+      RATIO=(F-FSAVE)/VQUAD
+      IF (RATIO .LE. TENTH) THEN
+          DELTA=HALF*DNORM
+      ELSE IF (RATIO. LE. 0.7D0) THEN
+          DELTA=DMAX1(HALF*DELTA,DNORM)
+      ELSE
+          DELTA=DMAX1(HALF*DELTA,DNORM+DNORM)
+      END IF
+      IF (DELTA .LE. 1.5D0*RHO) DELTA=RHO
+C
+C     Set KNEW to the index of the next interpolation point to be deleted.
+C
+      RHOSQ=DMAX1(TENTH*DELTA,RHO)**2
+      KTEMP=0
+      DETRAT=ZERO
+      IF (F .GE. FSAVE) THEN
+          KTEMP=KOPT
+          DETRAT=ONE
+      END IF
+      DO 400 K=1,NPT
+      HDIAG=ZERO
+      DO 380 J=1,NPTM
+      TEMP=ONE
+      IF (J .LT. IDZ) TEMP=-ONE
+  380 HDIAG=HDIAG+TEMP*ZMAT(K,J)**2
+      TEMP=DABS(BETA*HDIAG+VLAG(K)**2)
+      DISTSQ=ZERO
+      DO 390 J=1,N
+  390 DISTSQ=DISTSQ+(XPT(K,J)-XOPT(J))**2
+      IF (DISTSQ .GT. RHOSQ) TEMP=TEMP*(DISTSQ/RHOSQ)**3
+      IF (TEMP .GT. DETRAT .AND. K .NE. KTEMP) THEN
+          DETRAT=TEMP
+          KNEW=K
+      END IF
+  400 CONTINUE
+      IF (KNEW .EQ. 0) GOTO 460
+C
+C     Update BMAT, ZMAT and IDZ, so that the KNEW-th interpolation point
+C     can be moved. Begin the updating of the quadratic model, starting
+C     with the explicit second derivative term.
+C
+  410 CALL UPDATE (N,NPT,BMAT,ZMAT,IDZ,NDIM,VLAG,BETA,KNEW,W)
+      FVAL(KNEW)=F
+      IH=0
+      DO 420 I=1,N
+      TEMP=PQ(KNEW)*XPT(KNEW,I)
+      DO 420 J=1,I
+      IH=IH+1
+  420 HQ(IH)=HQ(IH)+TEMP*XPT(KNEW,J)
+      PQ(KNEW)=ZERO
+C
+C     Update the other second derivative parameters, and then the gradient
+C     vector of the model. Also include the new interpolation point.
+C
+      DO 440 J=1,NPTM
+      TEMP=DIFF*ZMAT(KNEW,J)
+      IF (J .LT. IDZ) TEMP=-TEMP
+      DO 440 K=1,NPT
+  440 PQ(K)=PQ(K)+TEMP*ZMAT(K,J)
+      GQSQ=ZERO
+      DO 450 I=1,N
+      GQ(I)=GQ(I)+DIFF*BMAT(KNEW,I)
+      GQSQ=GQSQ+GQ(I)**2
+  450 XPT(KNEW,I)=XNEW(I)
+C
+C     If a trust region step makes a small change to the objective function,
+C     then calculate the gradient of the least Frobenius norm interpolant at
+C     XBASE, and store it in W, using VLAG for a vector of right hand sides.
+C
+      IF (KSAVE .EQ. 0 .AND. DELTA .EQ. RHO) THEN
+          IF (DABS(RATIO) .GT. 1.0D-2) THEN
+              ITEST=0
+          ELSE
+              DO 700 K=1,NPT
+  700         VLAG(K)=FVAL(K)-FVAL(KOPT)
+              GISQ=ZERO
+              DO 720 I=1,N
+              SUM=ZERO
+              DO 710 K=1,NPT
+  710         SUM=SUM+BMAT(K,I)*VLAG(K)
+              GISQ=GISQ+SUM*SUM
+  720         W(I)=SUM
+C
+C     Test whether to replace the new quadratic model by the least Frobenius
+C     norm interpolant, making the replacement if the test is satisfied.
+C
+              ITEST=ITEST+1
+              IF (GQSQ .LT. 1.0D2*GISQ) ITEST=0
+              IF (ITEST .GE. 3) THEN
+                  DO 730 I=1,N
+  730             GQ(I)=W(I)
+                  DO 740 IH=1,NH
+  740             HQ(IH)=ZERO
+                  DO 760 J=1,NPTM
+                  W(J)=ZERO
+                  DO 750 K=1,NPT
+  750             W(J)=W(J)+VLAG(K)*ZMAT(K,J)
+  760             IF (J .LT. IDZ) W(J)=-W(J)
+                  DO 770 K=1,NPT
+                  PQ(K)=ZERO
+                  DO 770 J=1,NPTM
+  770             PQ(K)=PQ(K)+ZMAT(K,J)*W(J)
+                  ITEST=0
+              END IF
+          END IF
+      END IF
+      IF (F .LT. FSAVE) KOPT=KNEW
+C
+C     If a trust region step has provided a sufficient decrease in F, then
+C     branch for another trust region calculation. The case KSAVE>0 occurs
+C     when the new function value was calculated by a model step.
+C
+      IF (F .LE. FSAVE+TENTH*VQUAD) GOTO 100
+      IF (KSAVE .GT. 0) GOTO 100
+C
+C     Alternatively, find out if the interpolation points are close enough
+C     to the best point so far.
+C
+      KNEW=0
+  460 DISTSQ=4.0D0*DELTA*DELTA
+      DO 480 K=1,NPT
+      SUM=ZERO
+      DO 470 J=1,N
+  470 SUM=SUM+(XPT(K,J)-XOPT(J))**2
+      IF (SUM .GT. DISTSQ) THEN
+          KNEW=K
+          DISTSQ=SUM
+      END IF
+  480 CONTINUE
+C
+C     If KNEW is positive, then set DSTEP, and branch back for the next
+C     iteration, which will generate a "model step".
+C
+      IF (KNEW .GT. 0) THEN
+          DSTEP=DMAX1(DMIN1(TENTH*DSQRT(DISTSQ),HALF*DELTA),RHO)
+          DSQ=DSTEP*DSTEP
+          GOTO 120
+      END IF
+      IF (RATIO .GT. ZERO) GOTO 100
+      IF (DMAX1(DELTA,DNORM) .GT. RHO) GOTO 100
+C
+C     The calculations with the current value of RHO are complete. Pick the
+C     next values of RHO and DELTA.
+C
+  490 IF (RHO .GT. RHOEND) THEN
+          DELTA=HALF*RHO
+          RATIO=RHO/RHOEND
+          IF (RATIO .LE. 16.0D0) THEN
+              RHO=RHOEND
+          ELSE IF (RATIO .LE. 250.0D0) THEN
+              RHO=DSQRT(RATIO)*RHOEND
+          ELSE
+              RHO=TENTH*RHO
+          END IF
+          DELTA=DMAX1(DELTA,RHO)
+          IF (IPRINT .GE. 2) THEN
+              IF (IPRINT .GE. 3) PRINT 500
+  500         FORMAT (5X)
+              PRINT 510, RHO,NF
+  510         FORMAT (/4X,'New RHO =',1PD11.4,5X,'Number of',
+     1          ' function values =',I6)
+              PRINT 520, FOPT,(XBASE(I)+XOPT(I),I=1,N)
+  520         FORMAT (4X,'Least value of F =',1PD23.15,9X,
+     1          'The corresponding X is:'/(2X,5D15.6))
+          END IF
+          GOTO 90
+      END IF
+C
+C     Return from the calculation, after another Newton-Raphson step, if
+C     it is too short to have been tried before.
+C
+      IF (KNEW .EQ. -1) GOTO 290
+  530 IF (FOPT .LE. F) THEN
+          DO 540 I=1,N
+  540     X(I)=XBASE(I)+XOPT(I)
+          F=FOPT
+      END IF
+      IF (IPRINT .GE. 1) THEN
+          PRINT 550, NF
+  550     FORMAT (/4X,'At the return from NEWUOA',5X,
+     1      'Number of function values =',I6)
+          PRINT 520, F,(X(I),I=1,N)
+      END IF
+      NEWUOB =F
+      RETURN 
+      END 
+      SUBROUTINE TRSAPP (N,NPT,XOPT,XPT,GQ,HQ,PQ,DELTA,STEP,
+     1  D,G,HD,HS,CRVMIN)
+      IMPLICIT REAL*8 (A-H,O-Z)
+      DIMENSION XOPT(*),XPT(NPT,*),GQ(*),HQ(*),PQ(*),STEP(*),
+     1  D(*),G(*),HD(*),HS(*)
+C
+C     N is the number of variables of a quadratic objective function, Q say.
+C     The arguments NPT, XOPT, XPT, GQ, HQ and PQ have their usual meanings,
+C       in order to define the current quadratic model Q.
+C     DELTA is the trust region radius, and has to be positive.
+C     STEP will be set to the calculated trial step.
+C     The arrays D, G, HD and HS will be used for working space.
+C     CRVMIN will be set to the least curvature of H along the conjugate
+C       directions that occur, except that it is set to zero if STEP goes
+C       all the way to the trust region boundary.
+C
+C     The calculation of STEP begins with the truncated conjugate gradient
+C     method. If the boundary of the trust region is reached, then further
+C     changes to STEP may be made, each one being in the 2D space spanned
+C     by the current STEP and the corresponding gradient of Q. Thus STEP
+C     should provide a substantial reduction to Q within the trust region.
+C
+C     Initialization, which includes setting HD to H times XOPT.
+C
+      HALF=0.5D0
+      ZERO=0.0D0
+      TWOPI=8.0D0*DATAN(1.0D0)
+      DELSQ=DELTA*DELTA
+      ITERC=0
+      ITERMAX=N
+      ITERSW=ITERMAX
+      DO 10 I=1,N
+   10 D(I)=XOPT(I)
+      GOTO 170
+C
+C     Prepare for the first line search.
+C
+   20 QRED=ZERO
+      DD=ZERO
+      DO 30 I=1,N
+      STEP(I)=ZERO
+      HS(I)=ZERO
+      G(I)=GQ(I)+HD(I)
+      D(I)=-G(I)
+   30 DD=DD+D(I)**2
+      CRVMIN=ZERO
+      IF (DD .EQ. ZERO) GOTO 160
+      DS=ZERO
+      SS=ZERO
+      GG=DD
+      GGBEG=GG
+C
+C     Calculate the step to the trust region boundary and the product HD.
+C
+   40 ITERC=ITERC+1
+      TEMP=DELSQ-SS
+      BSTEP=TEMP/(DS+DSQRT(DS*DS+DD*TEMP))
+      GOTO 170
+   50 DHD=ZERO
+      DO 60 J=1,N
+   60 DHD=DHD+D(J)*HD(J)
+C
+C     Update CRVMIN and set the step-length ALPHA.
+C
+      ALPHA=BSTEP
+      IF (DHD .GT. ZERO) THEN
+          TEMP=DHD/DD
+          IF (ITERC .EQ. 1) CRVMIN=TEMP
+          CRVMIN=DMIN1(CRVMIN,TEMP)
+          ALPHA=DMIN1(ALPHA,GG/DHD)
+      END IF
+      QADD=ALPHA*(GG-HALF*ALPHA*DHD)
+      QRED=QRED+QADD
+C
+C     Update STEP and HS.
+C
+      GGSAV=GG
+      GG=ZERO
+      DO 70 I=1,N
+      STEP(I)=STEP(I)+ALPHA*D(I)
+      HS(I)=HS(I)+ALPHA*HD(I)
+   70 GG=GG+(G(I)+HS(I))**2
+C
+C     Begin another conjugate direction iteration if required.
+C
+      IF (ALPHA .LT. BSTEP) THEN
+          IF (QADD .LE. 0.01D0*QRED) GOTO 160
+          IF (GG .LE. 1.0D-4*GGBEG) GOTO 160
+          IF (ITERC .EQ. ITERMAX) GOTO 160
+          TEMP=GG/GGSAV
+          DD=ZERO
+          DS=ZERO
+          SS=ZERO
+          DO 80 I=1,N
+          D(I)=TEMP*D(I)-G(I)-HS(I)
+          DD=DD+D(I)**2
+          DS=DS+D(I)*STEP(I)
+   80     SS=SS+STEP(I)**2
+          IF (DS .LE. ZERO) GOTO 160
+          IF (SS .LT. DELSQ) GOTO 40
+      END IF
+      CRVMIN=ZERO
+      ITERSW=ITERC
+C
+C     Test whether an alternative iteration is required.
+C
+   90 IF (GG .LE. 1.0D-4*GGBEG) GOTO 160
+      SG=ZERO
+      SHS=ZERO
+      DO 100 I=1,N
+      SG=SG+STEP(I)*G(I)
+  100 SHS=SHS+STEP(I)*HS(I)
+      SGK=SG+SHS
+      ANGTEST=SGK/DSQRT(GG*DELSQ)
+      IF (ANGTEST .LE. -0.99D0) GOTO 160
+C
+C     Begin the alternative iteration by calculating D and HD and some
+C     scalar products.
+C
+      ITERC=ITERC+1
+      TEMP=DSQRT(DELSQ*GG-SGK*SGK)
+      TEMPA=DELSQ/TEMP
+      TEMPB=SGK/TEMP
+      DO 110 I=1,N
+  110 D(I)=TEMPA*(G(I)+HS(I))-TEMPB*STEP(I)
+      GOTO 170
+  120 DG=ZERO
+      DHD=ZERO
+      DHS=ZERO
+      DO 130 I=1,N
+      DG=DG+D(I)*G(I)
+      DHD=DHD+HD(I)*D(I)
+  130 DHS=DHS+HD(I)*STEP(I)
+C
+C     Seek the value of the angle that minimizes Q.
+C
+      CF=HALF*(SHS-DHD)
+      QBEG=SG+CF
+      QSAV=QBEG
+      QMIN=QBEG
+      ISAVE=0
+      IU=49
+      TEMP=TWOPI/DFLOAT(IU+1)
+      DO 140 I=1,IU
+      ANGLE=DFLOAT(I)*TEMP
+      CTH=DCOS(ANGLE)
+      STH=DSIN(ANGLE)
+      QNEW=(SG+CF*CTH)*CTH+(DG+DHS*CTH)*STH
+      IF (QNEW .LT. QMIN) THEN
+          QMIN=QNEW
+          ISAVE=I
+          TEMPA=QSAV
+      ELSE IF (I .EQ. ISAVE+1) THEN
+          TEMPB=QNEW
+      END IF
+  140 QSAV=QNEW
+      IF (ISAVE .EQ. ZERO) TEMPA=QNEW
+      IF (ISAVE .EQ. IU) TEMPB=QBEG
+      ANGLE=ZERO
+      IF (TEMPA .NE. TEMPB) THEN
+          TEMPA=TEMPA-QMIN
+          TEMPB=TEMPB-QMIN
+          ANGLE=HALF*(TEMPA-TEMPB)/(TEMPA+TEMPB)
+      END IF
+      ANGLE=TEMP*(DFLOAT(ISAVE)+ANGLE)
+C
+C     Calculate the new STEP and HS. Then test for convergence.
+C
+      CTH=DCOS(ANGLE)
+      STH=DSIN(ANGLE)
+      REDUC=QBEG-(SG+CF*CTH)*CTH-(DG+DHS*CTH)*STH
+      GG=ZERO
+      DO 150 I=1,N
+      STEP(I)=CTH*STEP(I)+STH*D(I)
+      HS(I)=CTH*HS(I)+STH*HD(I)
+  150 GG=GG+(G(I)+HS(I))**2
+      QRED=QRED+REDUC
+      RATIO=REDUC/QRED
+      IF (ITERC .LT. ITERMAX .AND. RATIO .GT. 0.01D0) GOTO 90
+  160 RETURN
+C
+C     The following instructions act as a subroutine for setting the vector
+C     HD to the vector D multiplied by the second derivative matrix of Q.
+C     They are called from three different places, which are distinguished
+C     by the value of ITERC.
+C
+  170 DO 180 I=1,N
+  180 HD(I)=ZERO
+      DO 200 K=1,NPT
+      TEMP=ZERO
+      DO 190 J=1,N
+  190 TEMP=TEMP+XPT(K,J)*D(J)
+      TEMP=TEMP*PQ(K)
+      DO 200 I=1,N
+  200 HD(I)=HD(I)+TEMP*XPT(K,I)
+      IH=0
+      DO 210 J=1,N
+      DO 210 I=1,J
+      IH=IH+1
+      IF (I .LT. J) HD(J)=HD(J)+HQ(IH)*D(I)
+  210 HD(I)=HD(I)+HQ(IH)*D(J)
+      IF (ITERC .EQ. 0) GOTO 20
+      IF (ITERC .LE. ITERSW) GOTO 50
+      GOTO 120
+      END
+
+      SUBROUTINE UPDATE (N,NPT,BMAT,ZMAT,IDZ,NDIM,VLAG,BETA,KNEW,W)
+      IMPLICIT REAL*8 (A-H,O-Z)
+      DIMENSION BMAT(NDIM,*),ZMAT(NPT,*),VLAG(*),W(*)
+C
+C     The arrays BMAT and ZMAT with IDZ are updated, in order to shift the
+C     interpolation point that has index KNEW. On entry, VLAG contains the
+C     components of the vector Theta*Wcheck+e_b of the updating formula
+C     (6.11), and BETA holds the value of the parameter that has this name.
+C     The vector W is used for working space.
+C
+C     Set some constants.
+C
+      ONE=1.0D0
+      ZERO=0.0D0
+      NPTM=NPT-N-1
+C
+C     Apply the rotations that put zeros in the KNEW-th row of ZMAT.
+C
+      JL=1
+      DO 20 J=2,NPTM
+      IF (J .EQ. IDZ) THEN
+          JL=IDZ
+      ELSE IF (ZMAT(KNEW,J) .NE. ZERO) THEN
+          TEMP=DSQRT(ZMAT(KNEW,JL)**2+ZMAT(KNEW,J)**2)
+          TEMPA=ZMAT(KNEW,JL)/TEMP
+          TEMPB=ZMAT(KNEW,J)/TEMP
+          DO 10 I=1,NPT
+          TEMP=TEMPA*ZMAT(I,JL)+TEMPB*ZMAT(I,J)
+          ZMAT(I,J)=TEMPA*ZMAT(I,J)-TEMPB*ZMAT(I,JL)
+   10     ZMAT(I,JL)=TEMP
+          ZMAT(KNEW,J)=ZERO
+      END IF
+   20 CONTINUE
+C
+C     Put the first NPT components of the KNEW-th column of HLAG into W,
+C     and calculate the parameters of the updating formula.
+C
+      TEMPA=ZMAT(KNEW,1)
+      IF (IDZ .GE. 2) TEMPA=-TEMPA
+      IF (JL .GT. 1) TEMPB=ZMAT(KNEW,JL)
+      DO 30 I=1,NPT
+      W(I)=TEMPA*ZMAT(I,1)
+      IF (JL .GT. 1) W(I)=W(I)+TEMPB*ZMAT(I,JL)
+   30 CONTINUE
+      ALPHA=W(KNEW)
+      TAU=VLAG(KNEW)
+      TAUSQ=TAU*TAU
+      DENOM=ALPHA*BETA+TAUSQ
+      VLAG(KNEW)=VLAG(KNEW)-ONE
+C
+C     Complete the updating of ZMAT when there is only one nonzero element
+C     in the KNEW-th row of the new matrix ZMAT, but, if IFLAG is set to one,
+C     then the first column of ZMAT will be exchanged with another one later.
+C
+      IFLAG=0
+      IF (JL .EQ. 1) THEN
+          TEMP=DSQRT(DABS(DENOM))
+          TEMPB=TEMPA/TEMP
+          TEMPA=TAU/TEMP
+          DO 40 I=1,NPT
+   40     ZMAT(I,1)=TEMPA*ZMAT(I,1)-TEMPB*VLAG(I)
+          IF (IDZ .EQ. 1 .AND. TEMP .LT. ZERO) IDZ=2
+          IF (IDZ .GE. 2 .AND. TEMP .GE. ZERO) IFLAG=1
+      ELSE
+C
+C     Complete the updating of ZMAT in the alternative case.
+C
+          JA=1
+          IF (BETA .GE. ZERO) JA=JL
+          JB=JL+1-JA
+          TEMP=ZMAT(KNEW,JB)/DENOM
+          TEMPA=TEMP*BETA
+          TEMPB=TEMP*TAU
+          TEMP=ZMAT(KNEW,JA)
+          SCALA=ONE/DSQRT(DABS(BETA)*TEMP*TEMP+TAUSQ)
+          SCALB=SCALA*DSQRT(DABS(DENOM))
+          DO 50 I=1,NPT
+          ZMAT(I,JA)=SCALA*(TAU*ZMAT(I,JA)-TEMP*VLAG(I))
+   50     ZMAT(I,JB)=SCALB*(ZMAT(I,JB)-TEMPA*W(I)-TEMPB*VLAG(I))
+          IF (DENOM .LE. ZERO) THEN
+              IF (BETA .LT. ZERO) IDZ=IDZ+1
+              IF (BETA .GE. ZERO) IFLAG=1
+          END IF
+      END IF
+C
+C     IDZ is reduced in the following case, and usually the first column
+C     of ZMAT is exchanged with a later one.
+C
+      IF (IFLAG .EQ. 1) THEN
+          IDZ=IDZ-1
+          DO 60 I=1,NPT
+          TEMP=ZMAT(I,1)
+          ZMAT(I,1)=ZMAT(I,IDZ)
+   60     ZMAT(I,IDZ)=TEMP
+      END IF
+C
+C     Finally, update the matrix BMAT.
+C
+      DO 70 J=1,N
+      JP=NPT+J
+      W(JP)=BMAT(KNEW,J)
+      TEMPA=(ALPHA*VLAG(JP)-TAU*W(JP))/DENOM
+      TEMPB=(-BETA*W(JP)-TAU*VLAG(JP))/DENOM
+      DO 70 I=1,JP
+      BMAT(I,J)=BMAT(I,J)+TEMPA*VLAG(I)+TEMPB*W(I)
+      IF (I .GT. NPT) BMAT(JP,I-NPT)=BMAT(I,J)
+   70 CONTINUE
+      RETURN
+      END 
diff --git a/examples++-load/provadxw.edp b/examples++-load/provadxw.edp
index fc73d4c..5d67803 100644
--- a/examples++-load/provadxw.edp
+++ b/examples++-load/provadxw.edp
@@ -1,14 +1,14 @@
 // test of DxWriter  from Sala Lorenzo.
-load "DxWriter"
-mesh Th=square(5,5);
-DxWriter ff("pippo");
-Dxaddmesh(ff, Th);
-Dxaddtimeseries(ff, "Vx",Th);
-fespace Vh(Th, P1);
-real t=1.0;
-Vh vx=x*y*t;
-Dxaddsol2ts(ff,"Vx",t, vx);
-t=2.0;
-vx=x*y*t;
-Dxaddsol2ts(ff,"Vx",t, vx);
+load "DxWriter"
+mesh Th=square(5,5);
+DxWriter ff("pippo");
+Dxaddmesh(ff, Th);
+Dxaddtimeseries(ff, "Vx",Th);
+fespace Vh(Th, P1);
+real t=1.0;
+Vh vx=x*y*t;
+Dxaddsol2ts(ff,"Vx",t, vx);
+t=2.0;
+vx=x*y*t;
+Dxaddsol2ts(ff,"Vx",t, vx);
 cout<<"Hello";
\ No newline at end of file
diff --git a/examples++-load/schwarz-nm.edp b/examples++-load/schwarz-nm.edp
index 91b757e..1c8a46d 100644
--- a/examples++-load/schwarz-nm.edp
+++ b/examples++-load/schwarz-nm.edp
@@ -134,6 +134,9 @@ cout << sun[].max << " " << sun[].min<< endl;
 // verification of the partition of the unite.
 assert( 1.-1e-9 <= sun[].min  && 1.+1e-9 >= sun[].max);  
 
+// FFCS: reference value for regression tests
+Vh ref;
+
 int nitermax=1000;
 {
   Vh un=0;
@@ -166,4 +169,5 @@ int nitermax=1000;
         plot(au,dim=3,wait=0,cmm=" iter  "+iter,fill=1 );
     }
   plot(un,wait=1,dim=3,fill=1);
+  ref=un;
 }
diff --git a/examples++-load/scotch.cpp b/examples++-load/scotch.cpp
index 2ad217a..561bd60 100644
--- a/examples++-load/scotch.cpp
+++ b/examples++-load/scotch.cpp
@@ -53,8 +53,9 @@ class SCOTCH_Op : public E_F0mps {
         AnyType operator()(Stack stack) const;
 };
 
+// FFCS - keywords/dumptable is not able to scan class names if they contain spaces, even in template arguments
 template<class T, class V>
-basicAC_F0::name_and_type SCOTCH_Op<T, V>::name_param[] = {
+basicAC_F0::name_and_type SCOTCH_Op<T,V>::name_param[] = {
     {"weight", &typeid(KN<long>*)}
 };
 
diff --git a/examples++-load/test-ElementMixte.edp b/examples++-load/test-ElementMixte.edp
index a792319..8158240 100644
--- a/examples++-load/test-ElementMixte.edp
+++ b/examples++-load/test-ElementMixte.edp
@@ -135,6 +135,9 @@ for(int i=0;i<P3h.ndof;++i)
 
  }
 
+// FFCS - reference value
+real ref;
+
 {
 assert(err==0);
 
@@ -205,6 +208,9 @@ for( int i=0;i<Wh1.ndof;++i)
   V(w)=V(u);
   w1[][i]-=1;
   assert( w1[].linfty < 1e-10);
+
+  // FFCS reference value
+  ref=w1[].linfty;
 }
 
 cout << " End  Check  ***********" << RTname <<  " Ok .... \n"; 
diff --git a/examples++-load/testFE-PkEdge.edp b/examples++-load/testFE-PkEdge.edp
index a0c3bbe..09d5e4f 100644
--- a/examples++-load/testFE-PkEdge.edp
+++ b/examples++-load/testFE-PkEdge.edp
@@ -7,6 +7,8 @@ mesh Th=square(1,1,[10*(x+y/3),10*(y-x/3)]);
 real x1=0.7,y1=0.9, h=1e-7;
 int it1=Th(x1,y1).nuTriangle; 
 
+// FFCS: store reference value
+real regtest;
 
  macro Check(PkEdge)
 { 
@@ -50,7 +52,7 @@ int it1=Th(x1,y1).nuTriangle;
       */
       
     } 
-  
+  regtest=a1'*a1;
 }  //EOM
 
 Check(P1edge)
diff --git a/examples++-load/tetgenholeregion.edp b/examples++-load/tetgenholeregion.edp
deleted file mode 100755
index c0ba0dc..0000000
--- a/examples++-load/tetgenholeregion.edp
+++ /dev/null
@@ -1,86 +0,0 @@
-// file tetgenholeregion.edp
-load "msh3"
-load "tetgen"
-verbosity=2;
-
-// Test 1
-
-mesh Th=square(10,20,[x*pi-pi/2,2*y*pi]);  //  $]\frac{-pi}{2},\frac{-pi}{2}[\times]0,2\pi[ $
-//  a parametrization of a sphere 
-func f1 =cos(x)*cos(y);
-func f2 =cos(x)*sin(y);
-func f3 = sin(x);
-//  partiel derivative of the parametrization DF
-func f1x=sin(x)*cos(y);   
-func f1y=-cos(x)*sin(y);
-func f2x=-sin(x)*sin(y);
-func f2y=cos(x)*cos(y);
-func f3x=cos(x);
-func f3y=0;
-// $  M = DF^t DF $
-func m11=f1x^2+f2x^2+f3x^2;
-func m21=f1x*f1y+f2x*f2y+f3x*f3y;
-func m22=f1y^2+f2y^2+f3y^2;
-
-func perio=[[4,y],[2,y],[1,x],[3,x]];  
-real hh=0.1;
-real vv= 1/square(hh);
-verbosity=2;
-Th=adaptmesh(Th,m11*vv,m21*vv,m22*vv,IsMetric=1,periodic=perio);
-Th=adaptmesh(Th,m11*vv,m21*vv,m22*vv,IsMetric=1,periodic=perio);
-plot(Th,wait=1);
-
-verbosity=2;
-
-// construction of the surface of spheres
-real Rmin  = 1.;
-func f1min = Rmin*f1;
-func f2min = Rmin*f2;
-func f3min = Rmin*f3;
-
-cout << "=====================" << endl;
-cout << "=====================" << endl;
-mesh3 Th3sph=movemesh23(Th,transfo=[f1min,f2min,f3min],orientation=-1);
-cout << "=====================" << endl;
-cout << "=====================" << endl;
-savemesh(Th3sph,"sphereR1.mesh");
-real Rmax  = 2.;
-func f1max = Rmax*f1;
-func f2max = Rmax*f2;
-func f3max = Rmax*f3;
-cout << "=====================" << endl;
-cout << "=====================" << endl;
-mesh3 Th3sph2=movemesh23(Th,transfo=[f1max,f2max,f3max],orientation=1);
-cout << "=====================" << endl;
-cout << "=====================" << endl;
-savemesh(Th3sph2,"sphereR2.mesh");
-cout << "addition" << endl;
-mesh3 Th3=Th3sph+Th3sph2;
-savemesh(Th3,"sphereAdd.mesh");
-
-
-real[int] domain2 = [1.5,0.,0.,145,0.001,0.5,0.,0.,18,0.01];
-cout << "==============================" << endl;
-cout << " tetgen call without hole " << endl;
-cout << "==============================" << endl;
-mesh3 Th3fin=tetg(Th3,switch="paAAYYCCV",nbofregions=2,regionlist=domain2);
-cout << "=============================" << endl;
-cout << "finish: tetgen call without hole" << endl;
-cout << "=============================" << endl;
-savemesh(Th3fin,"spherewithtworegion.mesh"); 
-
-
-real[int] hole = [0.,0.,0.];
-real[int] domain = [1.5,0.,0.,53,0.001];
-cout << "=============================" << endl;
-cout << "  tetgen call with hole   " << endl;
-cout << "=============================" << endl;
-mesh3 Th3finhole=tetg(Th3,switch="paAAYCCV",nbofholes=1,holelist=hole,nbofregions=1,regionlist=domain);
-cout << "=============================" << endl;
-cout << "finish: tetgen call with hole   " << endl;
-cout << "=============================" << endl;
-savemesh(Th3finhole,"spherewithahole.mesh"); 
-
-
-
-
diff --git a/examples++-load/ttestio.edp b/examples++-load/ttestio.edp
index 3ad2323..a6870c0 100644
--- a/examples++-load/ttestio.edp
+++ b/examples++-load/ttestio.edp
@@ -32,7 +32,8 @@ try {
 Th3=readmesh3("spherewithtworegion.mesh"); // This .mesh file is obtaing with tetgenholeregion.edp
 }
 catch (...) {
-  include "../examples++-3d/tetgenholeregion.edp"
+  // FFCS - path to example scripts are changed, so this needs to be in the local directory to be common to FF and FFCS
+  include "tetgenholeregion.edp"
 }
 fespace Vh3(Th3,P1);     // P1 FE space
 func gg2=x+y;
diff --git a/examples++-mpi/._DDM-Schwarz-Lame-2d.edp b/examples++-mpi/._DDM-Schwarz-Lame-2d.edp
new file mode 100644
index 0000000..f7a8f68
Binary files /dev/null and b/examples++-mpi/._DDM-Schwarz-Lame-2d.edp differ
diff --git a/examples++-mpi/._DDM-Schwarz-Lap-2dd.edp b/examples++-mpi/._DDM-Schwarz-Lap-2dd.edp
new file mode 100644
index 0000000..f7a8f68
Binary files /dev/null and b/examples++-mpi/._DDM-Schwarz-Lap-2dd.edp differ
diff --git a/examples++-mpi/._DDM-Schwarz-Stokes-2d.edp b/examples++-mpi/._DDM-Schwarz-Stokes-2d.edp
new file mode 100644
index 0000000..f7a8f68
Binary files /dev/null and b/examples++-mpi/._DDM-Schwarz-Stokes-2d.edp differ
diff --git a/examples++-mpi/._chaleur3D-mumps.edp b/examples++-mpi/._chaleur3D-mumps.edp
new file mode 100644
index 0000000..f7a8f68
Binary files /dev/null and b/examples++-mpi/._chaleur3D-mumps.edp differ
diff --git a/examples++-mpi/._dmatrix.hpp b/examples++-mpi/._dmatrix.hpp
new file mode 100755
index 0000000..e63f378
Binary files /dev/null and b/examples++-mpi/._dmatrix.hpp differ
diff --git a/examples++-mpi/MUMPS.cpp b/examples++-mpi/MUMPS.cpp
index 2da31ab..13a542a 100755
--- a/examples++-mpi/MUMPS.cpp
+++ b/examples++-mpi/MUMPS.cpp
@@ -30,6 +30,13 @@
 #include "rgraph.hpp"
 #include "AFunction.hpp"
 
+// FFCS - 23/4/13 - instanciate some global symbols which are not found by default in MS MPI Fortran libraries
+#ifdef WIN32
+__declspec(dllexport) int toto;
+MPI_Fint* _imp__MPI_F_STATUS_IGNORE;
+MPI_Fint* _imp__MPI_F_STATUSES_IGNORE;
+#endif
+
 #include "MatriceCreuse.hpp"
 
 #include "dmatrix.hpp"
diff --git a/examples++-mpi/MUMPS_FreeFem.cpp b/examples++-mpi/MUMPS_FreeFem.cpp
index 90c2385..7534a0a 100644
--- a/examples++-mpi/MUMPS_FreeFem.cpp
+++ b/examples++-mpi/MUMPS_FreeFem.cpp
@@ -7,7 +7,7 @@
 // AUTHOR   : Jacques Morice
 // E-MAIL   : jacques.morice at ann.jussieu.fr
 //
-//ff-c++-LIBRARY-dep:  mumps parmetis ptscotch  scalapack blas  mpifc  fc  pthread 
+//ff-c++-LIBRARY-dep: mumps parmetis ptscotch scalapack blas mpifc fc mpi pthread 
 //ff-c++-cpp-dep: 
 
 /* 
@@ -36,6 +36,13 @@
 #include  <iostream>
 using namespace std;
 
+// FFCS - 23/4/13 - instanciate some global symbols which are not found by default in MS MPI Fortran libraries
+#ifdef WIN32
+__declspec(dllexport) int toto;
+MPI_Fint* _imp__MPI_F_STATUS_IGNORE;
+MPI_Fint* _imp__MPI_F_STATUSES_IGNORE;
+#endif
+
 #include "rgraph.hpp"
 #include "error.hpp"
 #include "AFunction.hpp"
diff --git a/examples++-mpi/Makefile.am b/examples++-mpi/Makefile.am
index 2767d5f..5e104f3 100644
--- a/examples++-mpi/Makefile.am
+++ b/examples++-mpi/Makefile.am
@@ -1,9 +1,9 @@
 # $Id$
 TESTS=DDM-Schwarz-Lame-2d.edp DDM-Schwarz-Lame-3d.edp DDM-Schwarz-Lap-2dd.edp DDM-Schwarz-Lap-3d.edp DDM-Schwarz-Stokes-2d.edp LaplaceRT-3d-matrix-mumps.edp MPICGLap.edp MPIGMRES2D.edp MPIGMRES3D.edp MUMPS.edp NSI3d-carac-mumps.edp NSI3d-carac.edp Stokes-v1-matrix-mumps.edp Stokes-v1-matrix-superludist.edp Stokes-v2-matrix-mumps.edp Stokes-v3-matrix-mumps.edp VG.edp beam-3d-matrix-superludist.edp cavityNewtow-MUMPS.edp chaleur3D-hips.edp chaleur3D-mumps.edp chaleur3D-superludist.edp cmae [...]
-XFAILS_TESTS=$(TESTS)
+XFAIL_TESTS=$(TESTS)
 
 LOG_DRIVER=$(SHELL) $(top_srcdir)/test-driver-ff
-TESTS_ENVIRONMENT=TEST_FFPP=$(TEST_FFPPMPI) FLAGS_FFPP="-np 4" SKIP=$(SKIP_TESTS_MPI)
+TESTS_ENVIRONMENT=TEST_FFPP=$(TEST_FFPPMPI) FLAGS_FFPP="-np 4 -nw" SKIP=$(SKIP_TESTS_MPI)
 
 LIST_IDP= AddLayer2d.idp		DDM-Schwarz-macro.idp	MPIGMRESmacro.idp	getARGV.idp \
 AddLayer3d.idp		DDM-funcs-v2.idp	MPIplot.idp		mortar-msh.idp Heat3d.idp
@@ -27,19 +27,34 @@ ffmumps_fileparam.txt		ffpastix_iparm_dparm.txt	ffsuperlu_dist_fileparam.txt \
 MUMPS.cpp   \
 MUMPS.edp  dmatrix.hpp              
 
+# FFCS - list modified to disable some downloaded tools depending on the platform (see
+# [[file:../../../configure.ac::tools_problems_all_platforms]] for reasons why some tools may be
+# deactivated).
 
-LIST_COMPILE=MUMPS_FreeFem.$(DYLIB_SUFFIX) hips_FreeFem.$(DYLIB_SUFFIX) \
- interfacepastix.$(DYLIB_SUFFIX) \
-complex_SuperLU_DIST_FreeFem.$(DYLIB_SUFFIX) real_SuperLU_DIST_FreeFem.$(DYLIB_SUFFIX) \
-complex_pastix_FreeFem.$(DYLIB_SUFFIX) real_pastix_FreeFem.$(DYLIB_SUFFIX) \
-dSuperLU_DIST.$(DYLIB_SUFFIX) MPICG.$(DYLIB_SUFFIX) parms_FreeFem.$(DYLIB_SUFFIX) \
-mpi-cmaes.$(DYLIB_SUFFIX) MUMPS.$(DYLIB_SUFFIX)  
+LIST_COMPILE=@FFCS_DYLIB_mumps@ @FFCS_DYLIB_hips@ @FFCS_DYLIB_superludist@ @FFCS_DYLIB_pastix@ MPICG.$(DYLIB_SUFFIX)	\
+ at FFCS_DYLIB_parms@ mpi-cmaes.$(DYLIB_SUFFIX)
 
-all-local:$(LIST_COMPILE) freefem++.pref
+if FFCS_MPIOK
+
+# FFCS - do not set loadpath to be able to run an external version of FF on the examples in this directory with
+# [[../../mkffref]]
+
+all-local:$(LIST_COMPILE)
+	@echo Warning missing mpi plugin: `for i in $(LIST_COMPILE); do if test ! -s $i ; then j=1; echo "$i," ;fi; done`
 	echo "finish compile load mpi solver !"
+else
+all-local:
+endif
 
 .cpp.$(DYLIB_SUFFIX): ../examples++-load/ff-c++ ../examples++-load/WHERE_LIBRARY-download
-	- ../examples++-load/ff-c++ -auto  $< 
+#	FFCS needs an error exit code to make sure that all libraries are correctly compiled
+#
+#	FFCS on Windows inserts all MPI options (include, lib, ...) in the $MPICXX compiler script, instead of "$CXX $MPI_xxx",
+#	but it needs '-mpi' to do that
+#
+###	-../examples++-load/ff-c++ -auto  $< 
+	../examples++-load/ff-c++ -auto -mpi $<
+
 install-exec-local:: 
 	$(mkinstalldirs) -m 755 $(DESTDIR)$(ff_prefix_dir)/lib
 	$(mkinstalldirs) -m 755 $(DESTDIR)$(ff_prefix_dir)/include
@@ -49,6 +64,13 @@ install-exec-local::
 	$(INSTALL)  -m 555  $(LIST_IDP)  $(DESTDIR)$(ff_prefix_dir)/idp
 
 
-freefem++.pref:
+freefem++.pref:Makefile
 	echo loadpath = \"../examples++-load/\" >freefem++.pref
+	echo includepath = \"../examples++-3d/\" >>freefem++.pref
+	echo includepath += \"../examples++-tutorial/\" >>freefem++.pref
 	echo loadpath += \"./\" >>freefem++.pref
+
+# FFCS - cleaning is useful sometimes
+clean-local::
+	-rm *.$(DYLIB_SUFFIX)
+	-rm *.$(OBJEXT)
diff --git a/examples++-mpi/Makefile.in b/examples++-mpi/Makefile.in
index 4fb6e3e..8cef3d4 100644
--- a/examples++-mpi/Makefile.in
+++ b/examples++-mpi/Makefile.in
@@ -54,7 +54,8 @@ 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)/acmacros.m4 \
-	$(top_srcdir)/acoptim.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/acoptim.m4 $(top_srcdir)/acmpi.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -327,11 +328,47 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EIGENOBJ = @EIGENOBJ@
+ENABLE_FFCS = @ENABLE_FFCS@
 EPSTOPDF = @EPSTOPDF@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+FFCS_COMPILE_fflapack = @FFCS_COMPILE_fflapack@
+FFCS_COMPILE_gsl = @FFCS_COMPILE_gsl@
+FFCS_COMPILE_hips = @FFCS_COMPILE_hips@
+FFCS_COMPILE_hypre = @FFCS_COMPILE_hypre@
+FFCS_COMPILE_ipopt = @FFCS_COMPILE_ipopt@
+FFCS_COMPILE_lapack = @FFCS_COMPILE_lapack@
+FFCS_COMPILE_mmg3d = @FFCS_COMPILE_mmg3d@
+FFCS_COMPILE_mshmet = @FFCS_COMPILE_mshmet@
+FFCS_COMPILE_mumps = @FFCS_COMPILE_mumps@
+FFCS_COMPILE_mumps_seq = @FFCS_COMPILE_mumps_seq@
+FFCS_COMPILE_pardiso = @FFCS_COMPILE_pardiso@
+FFCS_COMPILE_parms = @FFCS_COMPILE_parms@
+FFCS_COMPILE_pastix = @FFCS_COMPILE_pastix@
+FFCS_COMPILE_pipe = @FFCS_COMPILE_pipe@
+FFCS_COMPILE_scotch = @FFCS_COMPILE_scotch@
+FFCS_COMPILE_superludist = @FFCS_COMPILE_superludist@
+FFCS_COMPILE_yams = @FFCS_COMPILE_yams@
+FFCS_DYLIB_fflapack = @FFCS_DYLIB_fflapack@
+FFCS_DYLIB_gsl = @FFCS_DYLIB_gsl@
+FFCS_DYLIB_hips = @FFCS_DYLIB_hips@
+FFCS_DYLIB_hypre = @FFCS_DYLIB_hypre@
+FFCS_DYLIB_ipopt = @FFCS_DYLIB_ipopt@
+FFCS_DYLIB_lapack = @FFCS_DYLIB_lapack@
+FFCS_DYLIB_mmg3d = @FFCS_DYLIB_mmg3d@
+FFCS_DYLIB_mshmet = @FFCS_DYLIB_mshmet@
+FFCS_DYLIB_mumps = @FFCS_DYLIB_mumps@
+FFCS_DYLIB_mumps_seq = @FFCS_DYLIB_mumps_seq@
+FFCS_DYLIB_pardiso = @FFCS_DYLIB_pardiso@
+FFCS_DYLIB_parms = @FFCS_DYLIB_parms@
+FFCS_DYLIB_pastix = @FFCS_DYLIB_pastix@
+FFCS_DYLIB_pipe = @FFCS_DYLIB_pipe@
+FFCS_DYLIB_scotch = @FFCS_DYLIB_scotch@
+FFCS_DYLIB_superludist = @FFCS_DYLIB_superludist@
+FFCS_DYLIB_yams = @FFCS_DYLIB_yams@
+FFCS_MAKEFLAGS = @FFCS_MAKEFLAGS@
 FFGLUTNAME = @FFGLUTNAME@
 FFGLUTPROG = @FFGLUTPROG@
 FFLAGS = @FFLAGS@
@@ -501,8 +538,9 @@ top_srcdir = @top_srcdir@
 
 # $Id$
 TESTS = DDM-Schwarz-Lame-2d.edp DDM-Schwarz-Lame-3d.edp DDM-Schwarz-Lap-2dd.edp DDM-Schwarz-Lap-3d.edp DDM-Schwarz-Stokes-2d.edp LaplaceRT-3d-matrix-mumps.edp MPICGLap.edp MPIGMRES2D.edp MPIGMRES3D.edp MUMPS.edp NSI3d-carac-mumps.edp NSI3d-carac.edp Stokes-v1-matrix-mumps.edp Stokes-v1-matrix-superludist.edp Stokes-v2-matrix-mumps.edp Stokes-v3-matrix-mumps.edp VG.edp beam-3d-matrix-superludist.edp cavityNewtow-MUMPS.edp chaleur3D-hips.edp chaleur3D-mumps.edp chaleur3D-superludist.edp cm [...]
+XFAIL_TESTS = $(TESTS)
 LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-ff
-TESTS_ENVIRONMENT = TEST_FFPP=$(TEST_FFPPMPI) FLAGS_FFPP="-np 4" SKIP=$(SKIP_TESTS_MPI)
+TESTS_ENVIRONMENT = TEST_FFPP=$(TEST_FFPPMPI) FLAGS_FFPP="-np 4 -nw" SKIP=$(SKIP_TESTS_MPI)
 LIST_IDP = AddLayer2d.idp		DDM-Schwarz-macro.idp	MPIGMRESmacro.idp	getARGV.idp \
 AddLayer3d.idp		DDM-funcs-v2.idp	MPIplot.idp		mortar-msh.idp Heat3d.idp
 
@@ -525,12 +563,12 @@ ffmumps_fileparam.txt		ffpastix_iparm_dparm.txt	ffsuperlu_dist_fileparam.txt \
 MUMPS.cpp   \
 MUMPS.edp  dmatrix.hpp              
 
-LIST_COMPILE = MUMPS_FreeFem.$(DYLIB_SUFFIX) hips_FreeFem.$(DYLIB_SUFFIX) \
- interfacepastix.$(DYLIB_SUFFIX) \
-complex_SuperLU_DIST_FreeFem.$(DYLIB_SUFFIX) real_SuperLU_DIST_FreeFem.$(DYLIB_SUFFIX) \
-complex_pastix_FreeFem.$(DYLIB_SUFFIX) real_pastix_FreeFem.$(DYLIB_SUFFIX) \
-dSuperLU_DIST.$(DYLIB_SUFFIX) MPICG.$(DYLIB_SUFFIX) parms_FreeFem.$(DYLIB_SUFFIX) \
-mpi-cmaes.$(DYLIB_SUFFIX) MUMPS.$(DYLIB_SUFFIX)  
+
+# FFCS - list modified to disable some downloaded tools depending on the platform (see
+# [[file:../../../configure.ac::tools_problems_all_platforms]] for reasons why some tools may be
+# deactivated).
+LIST_COMPILE = @FFCS_DYLIB_mumps@ @FFCS_DYLIB_hips@ @FFCS_DYLIB_superludist@ @FFCS_DYLIB_pastix@ MPICG.$(DYLIB_SUFFIX)	\
+ at FFCS_DYLIB_parms@ mpi-cmaes.$(DYLIB_SUFFIX)
 
 all: all-am
 
@@ -995,7 +1033,7 @@ maintainer-clean-generic:
 	@echo "it deletes files that may require special tools to rebuild."
 clean: clean-am
 
-clean-am: clean-generic mostlyclean-am
+clean-am: clean-generic clean-local mostlyclean-am
 
 distclean: distclean-am
 	-rm -f Makefile
@@ -1062,7 +1100,7 @@ uninstall-am:
 .MAKE: check-am install-am install-strip
 
 .PHONY: all all-am all-local check check-TESTS check-am clean \
-	clean-generic cscopelist-am ctags-am distclean \
+	clean-generic clean-local cscopelist-am ctags-am distclean \
 	distclean-generic distdir dvi dvi-am html html-am info info-am \
 	install install-am install-data install-data-am install-dvi \
 	install-dvi-am install-exec install-exec-am install-exec-local \
@@ -1074,11 +1112,23 @@ uninstall-am:
 	tags-am uninstall uninstall-am
 
 
-all-local:$(LIST_COMPILE) freefem++.pref
-	echo "finish compile load mpi solver !"
+# FFCS - do not set loadpath to be able to run an external version of FF on the examples in this directory with
+# [[../../mkffref]]
+
+ at FFCS_MPIOK_TRUE@all-local:$(LIST_COMPILE)
+ at FFCS_MPIOK_TRUE@	@echo Warning missing mpi plugin: `for i in $(LIST_COMPILE); do if test ! -s $i ; then j=1; echo "$i," ;fi; done`
+ at FFCS_MPIOK_TRUE@	echo "finish compile load mpi solver !"
+ at FFCS_MPIOK_FALSE@all-local:
 
 .cpp.$(DYLIB_SUFFIX): ../examples++-load/ff-c++ ../examples++-load/WHERE_LIBRARY-download
-	- ../examples++-load/ff-c++ -auto  $< 
+#	FFCS needs an error exit code to make sure that all libraries are correctly compiled
+#
+#	FFCS on Windows inserts all MPI options (include, lib, ...) in the $MPICXX compiler script, instead of "$CXX $MPI_xxx",
+#	but it needs '-mpi' to do that
+#
+###	-../examples++-load/ff-c++ -auto  $< 
+	../examples++-load/ff-c++ -auto -mpi $<
+
 install-exec-local:: 
 	$(mkinstalldirs) -m 755 $(DESTDIR)$(ff_prefix_dir)/lib
 	$(mkinstalldirs) -m 755 $(DESTDIR)$(ff_prefix_dir)/include
@@ -1087,10 +1137,17 @@ install-exec-local::
 	 if [ -f $$i ] ; then 	$(INSTALL)  -m 555 $$i $(DESTDIR)$(ff_prefix_dir)/lib; fi; done
 	$(INSTALL)  -m 555  $(LIST_IDP)  $(DESTDIR)$(ff_prefix_dir)/idp
 
-freefem++.pref:
+freefem++.pref:Makefile
 	echo loadpath = \"../examples++-load/\" >freefem++.pref
+	echo includepath = \"../examples++-3d/\" >>freefem++.pref
+	echo includepath += \"../examples++-tutorial/\" >>freefem++.pref
 	echo loadpath += \"./\" >>freefem++.pref
 
+# FFCS - cleaning is useful sometimes
+clean-local::
+	-rm *.$(DYLIB_SUFFIX)
+	-rm *.$(OBJEXT)
+
 # 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.
 .NOEXPORT:
diff --git a/examples++-mpi/NSI3d-carac.edp b/examples++-mpi/NSI3d-carac.edp
index d388491..c84d0d6 100644
--- a/examples++-mpi/NSI3d-carac.edp
+++ b/examples++-mpi/NSI3d-carac.edp
@@ -1 +1 @@
-cout << "\n\n empty file remove NSI3d-carac.edp\n\n" << endl;
\ No newline at end of file
+cout << "\n\n empty file remove NSI3d-carac.edp\n\n" << endl;
diff --git a/examples++-mpi/Stokes-v1-matrix-mumps.edp b/examples++-mpi/Stokes-v1-matrix-mumps.edp
index c7aa200..111528b 100644
--- a/examples++-mpi/Stokes-v1-matrix-mumps.edp
+++ b/examples++-mpi/Stokes-v1-matrix-mumps.edp
@@ -77,6 +77,5 @@ cout << " solve                   " <<  time3 << endl;
 cout << "                          ------------" << endl;
 cout << " all                     " <<  timeI << endl;
 cout << "============= CPU TIME ============" << endl;
-if(mpirank==0 && pplot) 
-  medit("UV2 PV2",Th,[u1,u2,u3],p);
+if(mpirank==0 && pplot) medit("UV2 PV2",Th,[u1,u2,u3],p);
 
diff --git a/examples++-mpi/Stokes-v1-matrix-pastix.edp b/examples++-mpi/Stokes-v1-matrix-pastix.edp
index 5e3b990..092c55a 100644
--- a/examples++-mpi/Stokes-v1-matrix-pastix.edp
+++ b/examples++-mpi/Stokes-v1-matrix-pastix.edp
@@ -65,6 +65,5 @@ cout << "                          ------------" << endl;
 cout << " all                     " <<  timeI << endl;
 cout << "============= CPU TIME ============" << endl;
 
-if(mpirank==0) 
-medit("UV2 PV2",Th,[u1,u2,u3],p);
+//if(mpirank==0) medit("UV2 PV2",Th,[u1,u2,u3],p);
 
diff --git a/examples++-mpi/Stokes-v1-matrix-superludist.edp b/examples++-mpi/Stokes-v1-matrix-superludist.edp
index 726ab38..883701b 100644
--- a/examples++-mpi/Stokes-v1-matrix-superludist.edp
+++ b/examples++-mpi/Stokes-v1-matrix-superludist.edp
@@ -62,6 +62,5 @@ cout << " solve                   " <<  time3 << endl;
 cout << "                          ------------" << endl;
 cout << " all                     " <<  timeI << endl;
 cout << "============= CPU TIME ============" << endl;
-if(mpirank==0)
-medit("UV2 PV2",Th,[u1,u2,u3],p);
+//if(mpirank==0)medit("UV2 PV2",Th,[u1,u2,u3],p);
 
diff --git a/examples++-mpi/Stokes-v2-matrix-mumps.edp b/examples++-mpi/Stokes-v2-matrix-mumps.edp
index 7450551..f8bc820 100644
--- a/examples++-mpi/Stokes-v2-matrix-mumps.edp
+++ b/examples++-mpi/Stokes-v2-matrix-mumps.edp
@@ -100,5 +100,5 @@ cout << "                          ------------" << endl;
 cout << " all                     " <<  timeI << endl;
 cout << "============= CPU TIME ============" << endl;
 
-if(mpirank==0) medit("UV2 PV2",Th,[u1,u2,u3],p);
+//if(mpirank==0) medit("UV2 PV2",Th,[u1,u2,u3],p);
 
diff --git a/examples++-mpi/Stokes-v2-matrix-pastix.edp b/examples++-mpi/Stokes-v2-matrix-pastix.edp
index 5c5d17d..5c24a7e 100644
--- a/examples++-mpi/Stokes-v2-matrix-pastix.edp
+++ b/examples++-mpi/Stokes-v2-matrix-pastix.edp
@@ -100,5 +100,5 @@ cout << "                          ------------" << endl;
 cout << " all                     " <<  timeI << endl;
 cout << "============= CPU TIME ============" << endl;
 
-if(mpirank==0) medit("UV2 PV2",Th,[u1,u2,u3],p);
+//if(mpirank==0) medit("UV2 PV2",Th,[u1,u2,u3],p);
 
diff --git a/examples++-mpi/Stokes-v2-matrix-superludist.edp b/examples++-mpi/Stokes-v2-matrix-superludist.edp
index ccd9cbc..61279dc 100644
--- a/examples++-mpi/Stokes-v2-matrix-superludist.edp
+++ b/examples++-mpi/Stokes-v2-matrix-superludist.edp
@@ -99,5 +99,5 @@ cout << "                          ------------" << endl;
 cout << " all                     " <<  timeI << endl;
 cout << "============= CPU TIME ============" << endl;
 
-if(mpirank==0) medit("UV2 PV2",Th,[u1,u2,u3],p);
+//if(mpirank==0) medit("UV2 PV2",Th,[u1,u2,u3],p);
 
diff --git a/examples++-mpi/Stokes-v3-matrix-mumps.edp b/examples++-mpi/Stokes-v3-matrix-mumps.edp
index 483dcf3..c12918b 100644
--- a/examples++-mpi/Stokes-v3-matrix-mumps.edp
+++ b/examples++-mpi/Stokes-v3-matrix-mumps.edp
@@ -22,7 +22,7 @@ Th=change(Th,fregion= min(mpisize-1,int(nuTriangle* ccc+1e-10)));
 if(mpirank==0)
 for(int i=0;i<=mpisize;++i)
 	 cout<< " Volume region  " <<  i << " " << int3d(Th,i)(1.) << endl;
-if(mpirank==0) medit("c10x10x10",Th);
+//if(mpirank==0) medit("c10x10x10",Th);
 fespace VVh(Th,[P2,P2,P2,P1]);
 fespace UUh(Th,[P2,P2,P2]);
 fespace Uh(Th,P2);
@@ -118,5 +118,5 @@ cout << "                          ------------" << endl;
 cout << " all                     " <<  timeI << endl;
 cout << "============= CPU TIME ============" << endl;
 
-if(mpirank==0) medit("UV2 PV2",Th,[u1,u2,u3],p);
+//if(mpirank==0) medit("UV2 PV2",Th,[u1,u2,u3],p);
 
diff --git a/examples++-mpi/Stokes-v3-matrix-pastix.edp b/examples++-mpi/Stokes-v3-matrix-pastix.edp
index 30f34c2..435731e 100644
--- a/examples++-mpi/Stokes-v3-matrix-pastix.edp
+++ b/examples++-mpi/Stokes-v3-matrix-pastix.edp
@@ -113,5 +113,7 @@ cout << "                          ------------" << endl;
 cout << " all                     " <<  timeI << endl;
 cout << "============= CPU TIME ============" << endl;
 
-if(mpirank==0) medit("UV2 PV2",Th,[u1,u2,u3],p);
+//if(mpirank==0) medit("UV2 PV2",Th,[u1,u2,u3],p);
 
+// FFCS: testing 3d plots
+plot(Th,[u1,u2,u3],p);
diff --git a/examples++-mpi/Stokes-v3-matrix-superludist.edp b/examples++-mpi/Stokes-v3-matrix-superludist.edp
index d24d1d8..7a4bffc 100644
--- a/examples++-mpi/Stokes-v3-matrix-superludist.edp
+++ b/examples++-mpi/Stokes-v3-matrix-superludist.edp
@@ -112,5 +112,5 @@ cout << "                          ------------" << endl;
 cout << " all                     " <<  timeI << endl;
 cout << "============= CPU TIME ============" << endl;
 
-if(mpirank==0) medit("UV2 PV2",Th,[u1,u2,u3],p);
+//if(mpirank==0) medit("UV2 PV2",Th,[u1,u2,u3],p);
 
diff --git a/examples++-mpi/chaleur3D-mumps.edp b/examples++-mpi/chaleur3D-mumps.edp
index 6139452..eb0cb37 100644
--- a/examples++-mpi/chaleur3D-mumps.edp
+++ b/examples++-mpi/chaleur3D-mumps.edp
@@ -1,4 +1,4 @@
-// NBPROC 1
+// NBPROC 4
 //ff-mpirun -np 4 chaleur3D-mumps.edp -glut ffglut -n 20 -op 1  -dt 0.01 -niter 10
 load "MUMPS_FreeFem"
 real ttgv=1e10;
diff --git a/examples++-mpi/complex_SuperLU_DIST_FreeFem.cpp b/examples++-mpi/complex_SuperLU_DIST_FreeFem.cpp
index ef51128..ef7e49c 100644
--- a/examples++-mpi/complex_SuperLU_DIST_FreeFem.cpp
+++ b/examples++-mpi/complex_SuperLU_DIST_FreeFem.cpp
@@ -1,5 +1,6 @@
 //   for automatic  compilation with ff-c++
-//ff-c++-LIBRARY-dep: superlu_dist  blas parmetis metis mpi fc
+// FFCS - 23/5/12 - remove metis dependency because it interfers with identically-named libmetis.a from parmetis
+//ff-c++-LIBRARY-dep: superlu_dist  blas parmetis mpi fc
 //ff-c++-cpp-dep: 
 // ORIG-DATE: 02/2009
 // -*- Mode : c++ -*-
@@ -38,6 +39,10 @@
   /bin/sh ff-mpic++ zSuperLU_DIST.cpp -I/Users/morice/librairie/SuperLU_DIST_2.3/SRC/ -L/Users/morice/librairie/openmpi/lib/ -lmpi -lopen-pal -lopen-rte -L/Users/morice/librairie/PATCHVECLIB/ -lwrapperdotblas -framework veclib -L/Users/morice/librairie/ParMetis-3.1/ -lparmetis -lmetis -L/Users/morice/librairie/SuperLU_DIST_2.3/lib/ -lsuperlu_dist_2.3
 
 */
+
+// FFCS - required to define __int64 for MSMPI
+#include <stdint.h>
+
 #include <mpi.h>
 #include  <iostream>
 using namespace std;
@@ -274,6 +279,7 @@ public:
 	    // dallocateA_dist(n, nnz, &a, &asub, &xa);
 	    // dCompRow_to_CompCol_dist(m,n,nnz,arow,asubrow,xarow,&a,&asub,&xa);
 	    
+	    // FFCS - "this->" required by g++ 4.7
 	    this->CompRow_to_CompCol_dist(m,n,nnz,AA.a,AA.cl,AA.lg,&a,&asub,&xa);
 	  
 	    /* Broadcast matrix A to the other PEs. */
@@ -295,6 +301,7 @@ public:
 	    MPI_Bcast( &nnz, 1,   mpi_int_t,  0, grid.comm );
 	    
 	    /* Allocate storage for compressed column representation. */
+	    // FFCS - "this->" required by g++ 4.7
 	    zallocateA_dist(n, nnz, this->dc(&a), &asub, &xa);
 	    
 	    MPI_Bcast( a, nnz, SuperLU_MPI_DOUBLE_COMPLEX, 0, grid.comm );
@@ -306,6 +313,7 @@ public:
 	  Dtype_t R_SLU = SuperLUmpiDISTDriver<R>::R_SLU_T(); 
 	  
 	  cout << "Debut: Create_CompCol_Matrix_dist" <<endl;
+	  // FFCS - "this->" required by g++ 4.7
 	  this->Create_CompCol_Matrix_dist(&A, m, n, nnz, a, asub, xa, SLU_NC, R_SLU, SLU_GE);      
 	  cout << "Fin: Create_CompCol_Matrix_dist" <<endl;
 	  /* creation of pseudo solution + second member */
@@ -411,6 +419,7 @@ public:
 	     MPI_Bcast( &nnz, 1,   mpi_int_t,  0, grid.comm );
 	     
 	     /* Allocate storage for compressed column representation. */
+	     // FFCS - "this->" required by g++ 4.7
 	     zallocateA_dist(n, nnz, this->dc(&a), &asub, &xa);
 	     
 	     MPI_Bcast( a, nnz, SuperLU_MPI_DOUBLE_COMPLEX, 0, grid.comm );
@@ -433,6 +442,7 @@ public:
 	   fst_row = iam * m_loc_fst;
 	   
 	   nnz_loc = xa[fst_row+m_loc]-xa[fst_row];
+	   // FFCS - "this->" required by g++ 4.7
 	   zallocateA_dist(m_loc, nnz_loc, this->dc(&aloc), &asubloc, &xaloc);
 	   
 	   //xaloc = (int_t*) intMalloc_dist(m_loc+1);
@@ -461,6 +471,7 @@ public:
 	   Dtype_t R_SLU = SuperLUmpiDISTDriver<R>::R_SLU_T(); 
 	   
 	   if(verbosity) cout << "Debut: Create_CompRowCol_Matrix_dist" <<endl;
+	   // FFCS - "this->" required by g++ 4.7
 	   if(verbosity) this->Create_CompRowLoc_Matrix_dist(&A, m, n, nnz_loc, m_loc, fst_row, aloc, asubloc, xaloc, SLU_NR_loc, R_SLU, SLU_GE);
 	   
 	   cout << "Fin: Create_CompRowCol_Matrix_dist" <<endl;
@@ -794,6 +805,8 @@ bool SetDefault()
     //DefSparseSolver<double>::solver =SparseMatSolver_R;
     DefSparseSolver<Complex>::solver =SparseMatSolver_C;
     TypeSolveMat::defaultvalue =TypeSolveMat::SparseSolver;
+
+    return false;
 }
 
 bool SetSuperLUmpi()
@@ -803,6 +816,8 @@ bool SetSuperLUmpi()
     //DefSparseSolver<double>::solver  =BuildSolverSuperLUmpi;
     DefSparseSolver<Complex>::solver =BuildSolverSuperLUmpi;    
     TypeSolveMat::defaultvalue  = TypeSolveMatdefaultvalue;
+
+    return false;
 }
 
 
diff --git a/examples++-mpi/complex_pastix_FreeFem.cpp b/examples++-mpi/complex_pastix_FreeFem.cpp
index 09e55d4..537509c 100644
--- a/examples++-mpi/complex_pastix_FreeFem.cpp
+++ b/examples++-mpi/complex_pastix_FreeFem.cpp
@@ -653,6 +653,7 @@ bool SetDefault()
     //DefSparseSolver<double>::solver =SparseMatSolver_R;
     DefSparseSolver<Complex>::solver =SparseMatSolver_C;
     TypeSolveMat::defaultvalue =TypeSolveMat::SparseSolver;
+    return false;
 }
 
 bool Setpastixmpi()
@@ -662,6 +663,7 @@ bool Setpastixmpi()
     //DefSparseSolver<double>::solver  =BuildSolverpastix_complex_mpi;
     DefSparseSolver<Complex>::solver =BuildSolverpastix_complex_mpi;    
     TypeSolveMat::defaultvalue  = TypeSolveMatdefaultvalue;
+    return false;
 }
 
 
diff --git a/examples++-mpi/dSuperLU_DIST.cpp b/examples++-mpi/dSuperLU_DIST.cpp
index 0f0a7cf..557e079 100644
--- a/examples++-mpi/dSuperLU_DIST.cpp
+++ b/examples++-mpi/dSuperLU_DIST.cpp
@@ -186,6 +186,7 @@ public:
     if(mpicommw)
       superlu_gridinit(*mpicommw, nprow, npcol, &grid);
     else
+      // FFCS - MPI::COMM_WORLD is not accepted on mingw64+MSMPI?
       superlu_gridinit(MPI_COMM_WORLD, nprow, npcol, &grid);
     
     /* Bail out if I do not belong in the grid. */
@@ -248,6 +249,7 @@ public:
 	  Dtype_t R_SLU = SuperLUmpiDISTDriver<R>::R_SLU_T(); 
 	  
 	  cout << "Debut: Create_CompCol_Matrix_dist" <<endl;
+	  // FFCS - "this->" required by g++ 4.7
 	  this->Create_CompCol_Matrix_dist(&A, m, n, nnz, a, asub, xa, SLU_NC, R_SLU, SLU_GE);      
 	  cout << "Fin: Create_CompCol_Matrix_dist" <<endl;
 	  /* creation of pseudo solution + second member */
@@ -700,6 +702,8 @@ bool SetDefault()
     DefSparseSolver<double>::solver =SparseMatSolver_R;
     //DefSparseSolver<Complex>::solver =SparseMatSolver_C;
     TypeSolveMat::defaultvalue =TypeSolveMat::SparseSolver;
+
+    return false;
 }
 
 bool SetSuperLUmpi()
@@ -709,6 +713,8 @@ bool SetSuperLUmpi()
     DefSparseSolver<double>::solver  =BuildSolverSuperLUmpi;
     //DefSparseSolver<Complex>::solver =BuildSolverSuperLUmpi;    
     TypeSolveMat::defaultvalue  = TypeSolveMatdefaultvalue;
+
+    return false;
 }
 
 
diff --git a/examples++-mpi/essai-com.edp b/examples++-mpi/essai-com.edp
index eadeba7..bb62e50 100644
--- a/examples++-mpi/essai-com.edp
+++ b/examples++-mpi/essai-com.edp
@@ -35,4 +35,4 @@ cout << " mpirank = " << " A =  " <<  A << endl;
 cout << " " <<  norm(A(1,1) - 2-1i) << endl;
 
 int[int] procs=[1,4,8];
-mpiGroup group(procs);
\ No newline at end of file
+mpiGroup group(procs);
diff --git a/examples++-mpi/hypre_FreeFem.cpp b/examples++-mpi/hypre_FreeFem.cpp
index 5946d1e..5f98092 100644
--- a/examples++-mpi/hypre_FreeFem.cpp
+++ b/examples++-mpi/hypre_FreeFem.cpp
@@ -32,6 +32,10 @@
  ref:ANR-07-CIS7-002-01 
  */
 
+// FFCS: add requirement for MPI
+//ff-c++-LIBRARY-dep: hypre mpi
+//ff-c++-cpp-dep: 
+
 // add F.Hecht ...  oct 2010 
 #define HYPRE_TIMING
 // .. end add
diff --git a/examples++-mpi/interfacepastix.cpp b/examples++-mpi/interfacepastix.cpp
index 282c4aa..49fb626 100644
--- a/examples++-mpi/interfacepastix.cpp
+++ b/examples++-mpi/interfacepastix.cpp
@@ -516,6 +516,7 @@ bool SetDefault()
     DefSparseSolver<double>::solver =SparseMatSolver_R;
     //DefSparseSolver<Complex>::solver =SparseMatSolver_C;
     TypeSolveMat::defaultvalue =TypeSolveMat::SparseSolver;
+    return false;
 }
 
 bool Setpastixmpi()
@@ -525,6 +526,7 @@ bool Setpastixmpi()
     DefSparseSolver<double>::solver  =BuildSolverpastixmpi;
     //DefSparseSolver<Complex>::solver =BuildSolverpastixmpi;    
     TypeSolveMat::defaultvalue  = TypeSolveMatdefaultvalue;
+    return false;
 }
 
 
diff --git a/examples++-mpi/parms_FreeFem.cpp b/examples++-mpi/parms_FreeFem.cpp
index 6713d5b..7d7140f 100644
--- a/examples++-mpi/parms_FreeFem.cpp
+++ b/examples++-mpi/parms_FreeFem.cpp
@@ -7,7 +7,8 @@
 // AUTHOR   : Guy Atenekeng
 // E-MAIL   : Guy_Antoine_Atenekeng_Kahou at lri.fr
 //
-//ff-c++-LIBRARY-dep: metis parms  blas mpifc fc
+// FFCS - need reference to MPI to have the proper include for mpi.h on MacOS10.8
+//ff-c++-LIBRARY-dep: metis parms  blas mpifc mpi fc
 //ff-c++-cpp-dep: 
 
 /* 
@@ -473,11 +474,12 @@ public:
 	/*Differents preconditionners use*/
 	 meth[0]=(char *)malloc(sizeof(char)*9); strcpy(meth[0],"add_ilu0"); meth[1]=(char *)malloc(sizeof(char)*9); strcpy(meth[1],"add_ilut"); 
 	 meth[2]=(char *)malloc(sizeof(char)*9); strcpy(meth[2],"add_iluk"); meth[3]=(char *)malloc(sizeof(char)*9); strcpy(meth[3],"add_arms");
-	 meth[4]=(char *)malloc(sizeof(char)*9); strcpy(meth[4],"lsch_ilu0"); meth[5]=(char *)malloc(sizeof(char)*9); strcpy(meth[5],"lsch_ilut");  
-	 meth[6]=(char *)malloc(sizeof(char)*9); strcpy(meth[6],"lsch_iluk"); meth[7]=(char *)malloc(sizeof(char)*9); strcpy(meth[7],"lsch_arms"); 	
-	 meth[8]=(char *)malloc(sizeof(char)*9); strcpy(meth[8],"rsch_ilu0"); meth[9]=(char *)malloc(sizeof(char)*9); strcpy(meth[9],"rsch_ilut");
-         meth[10]=(char *)malloc(sizeof(char)*9); strcpy(meth[10],"rsch_iluk"); meth[11]=(char *)malloc(sizeof(char)*9); strcpy(meth[11],"rsch_arms");
-	 meth[12]=(char *)malloc(sizeof(char)*9); strcpy(meth[12],"sch_gilu0"); meth[13]=(char *)malloc(sizeof(char)*9); strcpy(meth[13],"sch_sgs");
+	 // FFCS - fixed "buffer overflow" warning by JHunt
+	 meth[4]=(char *)malloc(sizeof(char)*10); strcpy(meth[4],"lsch_ilu0"); meth[5]=(char *)malloc(sizeof(char)*10); strcpy(meth[5],"lsch_ilut");  
+	 meth[6]=(char *)malloc(sizeof(char)*10); strcpy(meth[6],"lsch_iluk"); meth[7]=(char *)malloc(sizeof(char)*10); strcpy(meth[7],"lsch_arms"); 	
+	 meth[8]=(char *)malloc(sizeof(char)*10); strcpy(meth[8],"rsch_ilu0"); meth[9]=(char *)malloc(sizeof(char)*10); strcpy(meth[9],"rsch_ilut");
+         meth[10]=(char *)malloc(sizeof(char)*10); strcpy(meth[10],"rsch_iluk"); meth[11]=(char *)malloc(sizeof(char)*10); strcpy(meth[11],"rsch_arms");
+	 meth[12]=(char *)malloc(sizeof(char)*10); strcpy(meth[12],"sch_gilu0"); meth[13]=(char *)malloc(sizeof(char)*8); strcpy(meth[13],"sch_sgs");
 	/*storage format of the matrix*/
          char pcrM[4];
 	strcpy(pcrM,"csr");
diff --git a/examples++-mpi/real_SuperLU_DIST_FreeFem.cpp b/examples++-mpi/real_SuperLU_DIST_FreeFem.cpp
index 7a21ec5..f99daa3 100644
--- a/examples++-mpi/real_SuperLU_DIST_FreeFem.cpp
+++ b/examples++-mpi/real_SuperLU_DIST_FreeFem.cpp
@@ -290,6 +290,7 @@ public:
 	  Dtype_t R_SLU = SuperLUmpiDISTDriver<R>::R_SLU_T(); 
 	  if(verbosity>6)
 	  cout << "Debut: Create_CompCol_Matrix_dist" <<endl;
+	  // FFCS - "this->" required by g++ 4.7
 	  this->Create_CompCol_Matrix_dist(&A, m, n, nnz, a, asub, xa, SLU_NC, R_SLU, SLU_GE); 
 	  if(verbosity>6)
 	  cout << "Fin: Create_CompCol_Matrix_dist" <<endl;
@@ -775,6 +776,8 @@ bool SetDefault()
     DefSparseSolver<double>::solver =SparseMatSolver_R;
     //DefSparseSolver<Complex>::solver =SparseMatSolver_C;
     TypeSolveMat::defaultvalue =TypeSolveMat::SparseSolver;
+
+    return false;
 }
 
 bool SetSuperLUmpi()
@@ -784,6 +787,8 @@ bool SetSuperLUmpi()
     DefSparseSolver<double>::solver  =BuildSolverSuperLUmpi;
     //DefSparseSolver<Complex>::solver =BuildSolverSuperLUmpi;    
     TypeSolveMat::defaultvalue  = TypeSolveMatdefaultvalue;
+
+    return false;
 }
 
 
diff --git a/examples++-mpi/real_pastix_FreeFem.cpp b/examples++-mpi/real_pastix_FreeFem.cpp
index 67374a1..967db35 100644
--- a/examples++-mpi/real_pastix_FreeFem.cpp
+++ b/examples++-mpi/real_pastix_FreeFem.cpp
@@ -685,6 +685,7 @@ bool SetDefault()
     DefSparseSolver<double>::solver =SparseMatSolver_R;
     //DefSparseSolver<Complex>::solver =SparseMatSolver_C;
     TypeSolveMat::defaultvalue =TypeSolveMat::SparseSolver;
+    return false;
 }
 
 bool Setpastixmpi()
@@ -694,6 +695,7 @@ bool Setpastixmpi()
     DefSparseSolver<double>::solver  =BuildSolverpastix_real_mpi;
     //DefSparseSolver<Complex>::solver =BuildSolverpastix_real_mpi;    
     TypeSolveMat::defaultvalue  = TypeSolveMatdefaultvalue;
+    return false;
 }
 
 
diff --git a/examples++-mpi/testsolver_MUMPS.edp b/examples++-mpi/testsolver_MUMPS.edp
index f6fdeec..b79ac18 100644
--- a/examples++-mpi/testsolver_MUMPS.edp
+++ b/examples++-mpi/testsolver_MUMPS.edp
@@ -53,6 +53,9 @@ broadcast(processor(0),ICNTL);
     }
 }
 
+// FFCS - reference value for regression tests
+real regtest;
+
 // Read parameter of MUMPS solver in file ffmumps_fileparam.txt
 
 {
@@ -79,6 +82,7 @@ matrix A =
     di = xx-x;
     if(mpirank==0){	
     cout << "x-xx="<< endl; cout << "Linf "<< di.linfty << " L2 " << di.l2 << endl;
+    regtest=di.l2;
     }
 }
 
diff --git a/examples++-mpi/testsolver_SuperLU_DIST.edp b/examples++-mpi/testsolver_SuperLU_DIST.edp
index 62df1db..63ee388 100644
--- a/examples++-mpi/testsolver_SuperLU_DIST.edp
+++ b/examples++-mpi/testsolver_SuperLU_DIST.edp
@@ -4,6 +4,10 @@ assert(mpisize>=2);
 int[int] procs=[0,1];
 mpiGroup gpr(procs);
 mpiComm comm(gpr);
+
+// FFCS - reference value for regression tests
+real regtest;
+
 if ( bool(comm))
   {
     /////////////////////////////
@@ -106,6 +110,7 @@ if ( bool(comm))
 	cout << "xx= " << xx << endl;	
 	di=(xx-x);
 	cout << "error " << sqrt( abs(di'*di) ) << endl;//'));
+	regtest=di.l2;
       }
 
     
diff --git a/examples++-mpi/testsolver_dsuperlu_dist.edp b/examples++-mpi/testsolver_dsuperlu_dist.edp
index cbbeacd..e0e3ea0 100644
--- a/examples++-mpi/testsolver_dsuperlu_dist.edp
+++ b/examples++-mpi/testsolver_dsuperlu_dist.edp
@@ -1,5 +1,8 @@
 load "dSuperLU_DIST"
 
+// FFCS - reference value for regressions tests
+real regtest;
+
 // read parameter for superlu from file
 verbosity=2;
 {
@@ -53,6 +56,7 @@ matrix A =
     di = xx-x;
     if(mpirank==0){	
     cout << "x-xx="<< endl; cout << "Linf "<< di.linfty << " L2 " << di.l2 << endl;
+    regtest=di.l2;
     }
 }
 
diff --git a/examples++-other/Makefile.in b/examples++-other/Makefile.in
index 9ca4149..1840ccd 100644
--- a/examples++-other/Makefile.in
+++ b/examples++-other/Makefile.in
@@ -54,7 +54,8 @@ 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)/acmacros.m4 \
-	$(top_srcdir)/acoptim.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/acoptim.m4 $(top_srcdir)/acmpi.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -327,11 +328,47 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EIGENOBJ = @EIGENOBJ@
+ENABLE_FFCS = @ENABLE_FFCS@
 EPSTOPDF = @EPSTOPDF@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+FFCS_COMPILE_fflapack = @FFCS_COMPILE_fflapack@
+FFCS_COMPILE_gsl = @FFCS_COMPILE_gsl@
+FFCS_COMPILE_hips = @FFCS_COMPILE_hips@
+FFCS_COMPILE_hypre = @FFCS_COMPILE_hypre@
+FFCS_COMPILE_ipopt = @FFCS_COMPILE_ipopt@
+FFCS_COMPILE_lapack = @FFCS_COMPILE_lapack@
+FFCS_COMPILE_mmg3d = @FFCS_COMPILE_mmg3d@
+FFCS_COMPILE_mshmet = @FFCS_COMPILE_mshmet@
+FFCS_COMPILE_mumps = @FFCS_COMPILE_mumps@
+FFCS_COMPILE_mumps_seq = @FFCS_COMPILE_mumps_seq@
+FFCS_COMPILE_pardiso = @FFCS_COMPILE_pardiso@
+FFCS_COMPILE_parms = @FFCS_COMPILE_parms@
+FFCS_COMPILE_pastix = @FFCS_COMPILE_pastix@
+FFCS_COMPILE_pipe = @FFCS_COMPILE_pipe@
+FFCS_COMPILE_scotch = @FFCS_COMPILE_scotch@
+FFCS_COMPILE_superludist = @FFCS_COMPILE_superludist@
+FFCS_COMPILE_yams = @FFCS_COMPILE_yams@
+FFCS_DYLIB_fflapack = @FFCS_DYLIB_fflapack@
+FFCS_DYLIB_gsl = @FFCS_DYLIB_gsl@
+FFCS_DYLIB_hips = @FFCS_DYLIB_hips@
+FFCS_DYLIB_hypre = @FFCS_DYLIB_hypre@
+FFCS_DYLIB_ipopt = @FFCS_DYLIB_ipopt@
+FFCS_DYLIB_lapack = @FFCS_DYLIB_lapack@
+FFCS_DYLIB_mmg3d = @FFCS_DYLIB_mmg3d@
+FFCS_DYLIB_mshmet = @FFCS_DYLIB_mshmet@
+FFCS_DYLIB_mumps = @FFCS_DYLIB_mumps@
+FFCS_DYLIB_mumps_seq = @FFCS_DYLIB_mumps_seq@
+FFCS_DYLIB_pardiso = @FFCS_DYLIB_pardiso@
+FFCS_DYLIB_parms = @FFCS_DYLIB_parms@
+FFCS_DYLIB_pastix = @FFCS_DYLIB_pastix@
+FFCS_DYLIB_pipe = @FFCS_DYLIB_pipe@
+FFCS_DYLIB_scotch = @FFCS_DYLIB_scotch@
+FFCS_DYLIB_superludist = @FFCS_DYLIB_superludist@
+FFCS_DYLIB_yams = @FFCS_DYLIB_yams@
+FFCS_MAKEFLAGS = @FFCS_MAKEFLAGS@
 FFGLUTNAME = @FFGLUTNAME@
 FFGLUTPROG = @FFGLUTPROG@
 FFLAGS = @FFLAGS@
diff --git a/examples++-other/lap3-cpu.edp b/examples++-other/lap3-cpu.edp
index 52d7974..2fad915 100644
--- a/examples++-other/lap3-cpu.edp
+++ b/examples++-other/lap3-cpu.edp
@@ -53,6 +53,10 @@ uh=0;
 cpu=clock() ;
 laplaceCrout; // solve the problem plot(uh); // to see the result
 cout << "-- lap Crout    " << nn << "x" << nn << "  : " <<  -cpu+clock() << " s,  max =" << uh[].max << endl;
+
+// FFCS: reference value for regression tests
+real regtest=uh[].max;
+
 uh=0;
 
 if(HaveUMFPACK){
diff --git a/examples++-tutorial/._BEM-C.edp b/examples++-tutorial/._BEM-C.edp
new file mode 100644
index 0000000..f7a8f68
Binary files /dev/null and b/examples++-tutorial/._BEM-C.edp differ
diff --git a/examples++-tutorial/._LapDG2.edp b/examples++-tutorial/._LapDG2.edp
new file mode 100644
index 0000000..f7a8f68
Binary files /dev/null and b/examples++-tutorial/._LapDG2.edp differ
diff --git a/examples++-tutorial/._LaplaceRT.edp b/examples++-tutorial/._LaplaceRT.edp
new file mode 100644
index 0000000..f7a8f68
Binary files /dev/null and b/examples++-tutorial/._LaplaceRT.edp differ
diff --git a/examples++-tutorial/._fluidStruct.edp b/examples++-tutorial/._fluidStruct.edp
new file mode 100644
index 0000000..f7a8f68
Binary files /dev/null and b/examples++-tutorial/._fluidStruct.edp differ
diff --git a/examples++-tutorial/._fluidStructAdapt.edp b/examples++-tutorial/._fluidStructAdapt.edp
new file mode 100644
index 0000000..f7a8f68
Binary files /dev/null and b/examples++-tutorial/._fluidStructAdapt.edp differ
diff --git a/examples++-tutorial/._gnuplot.edp b/examples++-tutorial/._gnuplot.edp
new file mode 100644
index 0000000..f7a8f68
Binary files /dev/null and b/examples++-tutorial/._gnuplot.edp differ
diff --git a/examples++-tutorial/._regtests.m4 b/examples++-tutorial/._regtests.m4
new file mode 100644
index 0000000..6729259
Binary files /dev/null and b/examples++-tutorial/._regtests.m4 differ
diff --git a/examples++-tutorial/._sphere.edp b/examples++-tutorial/._sphere.edp
new file mode 100644
index 0000000..f7a8f68
Binary files /dev/null and b/examples++-tutorial/._sphere.edp differ
diff --git a/examples++-tutorial/Laplace-RHS-Dirac.edp b/examples++-tutorial/Laplace-RHS-Dirac.edp
index 4939843..5596a6b 100644
--- a/examples++-tutorial/Laplace-RHS-Dirac.edp
+++ b/examples++-tutorial/Laplace-RHS-Dirac.edp
@@ -5,6 +5,10 @@
  real[int] cdelta=[1.,2.];//  coef    delta_i
   mesh Th=square(10,10);
   verbosity=0;
+
+// Reference value for FFCS regression tests
+real ref;
+
  for(int iter=0;iter < 13;iter++)
  {
 
@@ -29,4 +33,6 @@
   plot(uh,wait=1,dim=3,fill=1);
   Th=adaptmesh(Th,uh,nbvx=100000,err= 0.01*1.15^-iter);
   
+  // Reference value for FFCS regression tests
+  ref=uh[]'*uh[];//'
   }
\ No newline at end of file
diff --git a/examples++-tutorial/Laplace.cpp b/examples++-tutorial/Laplace.cpp
new file mode 100644
index 0000000..56f7f15
--- /dev/null
+++ b/examples++-tutorial/Laplace.cpp
@@ -0,0 +1,59 @@
+/*!
+ * \file 
+ * 
+ * \brief C++ version of Laplace.edp test script
+ * 
+ * 
+ * \author Written by Antoine Le Hyaric
+ * \author Laboratoire Jacques-Louis Lions
+ * \author Université Pierre et Marie Curie-Paris6, UMR 7598, Paris, F-75005 France
+ * \author http://www.ljll.math.upmc.fr/lehyaric
+ * 
+ * \copyright This file is part of Freefem++
+ * 
+ * \copyright Freefem++ is free software; you can redistribute 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.
+ * 
+ * \copyright Freefem++ is distributed in the hope that it will be useful,
+ * 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.
+ * 
+ * \copyright You should have received a copy of the GNU Lesser General Public
+ * License along with Freefem++; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * 
+ * headeralh brief="C++ version of Laplace.edp test script" cpp default=0 dox freefem upmc written
+ */
+
+// [[file:~/ff/loc/src/fflib/ffapi.hpp::API]]
+#include "../src/fflib/ffapi.hpp"
+
+int main(int argc,char *argv[]){
+
+  // ffapi mention is required for Doxygen to distinguish ffapi::mesh and ::mesh
+  ffapi::mesh Th=ffapi::square(10,10);
+
+  fespace Vh(Th,P1);     // P1 FE space
+  Vh uh,vh;              // unkown and test function. 
+  func f=1;                 //  right hand side function 
+  func g=0;                 //  boundary condition function
+ 
+  problem laplace(uh,vh,solver=GMRES,tgv=1e5) =                    //  definion of  the problem 
+    int2d(Th)( dx(uh)*dx(vh) + dy(uh)*dy(vh) ) //  bilinear form
+    - int2d(Th)( f*vh )                          //  linear form
+    + on(1,2,3,4,uh=g) ;                      //  boundary condition form
+
+  laplace; // solve the problem plot(uh); // to see the result
+  plot(uh,ps="Laplace.eps",value=true);
+}
+
+/*!
+ * Local Variables:
+ * mode:c++
+ * ispell-local-dictionary:"british"
+ * coding:utf-8
+ * End:
+ */
diff --git a/examples++-tutorial/Makefile.am b/examples++-tutorial/Makefile.am
index db36d35..5a3e292 100644
--- a/examples++-tutorial/Makefile.am
+++ b/examples++-tutorial/Makefile.am
@@ -1,7 +1,7 @@
 # $Id$
 
 all-local: all.edp regtests.edp  freefem++.pref
-TESTS=adapt.edp adaptindicatorP1.edp adaptindicatorP2.edp algo.edp array.edp a_tutorial.edp beam.edp  calculus.edp cavity.edp convect2.edp convect-apt.edp convect.edp dumptable.edp ex-vf.edp FE.edp fluidStructAdapt.edp fluidStruct.edp freeboundary.edp freeboundary-weak.edp LapDG2.edp Laplace.edp LaplaceP1bis.edp LaplaceP1.edp LaplaceP1P2h.edp LaplaceRT.edp mesh.edp movemesh.edp nolinear-elas.edp NSUzawaCahouetChabart.edp onde.edp periodic4.edp Periodic.edp plot.edp readmesh.edp region.ed [...]
+TESTS=adapt.edp adaptindicatorP1.edp adaptindicatorP2.edp algo.edp array.edp a_tutorial.edp beam.edp  calculus.edp cavity.edp convect2.edp convect-apt.edp convect.edp dumptable.edp ex-vf.edp FE.edp fluidStructAdapt.edp fluidStruct.edp freeboundary.edp freeboundary-weak.edp LapDG2.edp Laplace.edp LaplaceP1bis.edp LaplaceP1.edp LaplaceP1P2h.edp LaplaceRT.edp mesh.edp movemesh.edp nolinear-elas.edp NSUzawaCahouetChabart.edp onde.edp periodic4.edp Periodic.edp plot.edp readmesh.edp region.ed [...]
 LOG_DRIVER=$(SHELL) $(top_srcdir)/test-driver-ff
 TESTS_ENVIRONMENT=TEST_FFPP=$(TEST_FFPP) FLAGS_FFPP=-nw
 
@@ -32,6 +32,12 @@ freefem++.pref:
 	echo loadpath = \"../examples++-load/\" >freefem++.pref
 	echo loadpath += \"./\" >>freefem++.pref
 
+# FreeFem API tests
+# -----------------
+
+EXTRA_PROGRAMS=Laplace
+Laplace_SOURCES=Laplace.cpp
+
 # To check the scripts against their reference values
 regtests.edp: regtests.m4 ../regtests.m4
 	m4 -DASSERT regtests.m4 > regtests.edp
diff --git a/examples++-tutorial/Makefile.in b/examples++-tutorial/Makefile.in
index d0e9249..2099066 100644
--- a/examples++-tutorial/Makefile.in
+++ b/examples++-tutorial/Makefile.in
@@ -51,18 +51,24 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
+EXTRA_PROGRAMS = Laplace$(EXEEXT)
 subdir = examples++-tutorial
 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
-	$(top_srcdir)/mkinstalldirs $(top_srcdir)/test-driver
+	$(top_srcdir)/mkinstalldirs $(top_srcdir)/depcomp \
+	$(top_srcdir)/test-driver
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/acmacros.m4 \
-	$(top_srcdir)/acoptim.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/acoptim.m4 $(top_srcdir)/acmpi.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
+am_Laplace_OBJECTS = Laplace.$(OBJEXT)
+Laplace_OBJECTS = $(am_Laplace_OBJECTS)
+Laplace_LDADD = $(LDADD)
 AM_V_P = $(am__v_P_ at AM_V@)
 am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
 am__v_P_0 = false
@@ -75,14 +81,49 @@ AM_V_at = $(am__v_at_ at AM_V@)
 am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
 am__v_at_0 = @
 am__v_at_1 = 
-SOURCES =
-DIST_SOURCES =
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
+	-o $@
+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 = $(Laplace_SOURCES)
+DIST_SOURCES = $(Laplace_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
 am__tty_colors_dummy = \
   mgn= red= grn= lgn= blu= brg= std=; \
   am__color_tests=no
@@ -329,11 +370,47 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EIGENOBJ = @EIGENOBJ@
+ENABLE_FFCS = @ENABLE_FFCS@
 EPSTOPDF = @EPSTOPDF@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+FFCS_COMPILE_fflapack = @FFCS_COMPILE_fflapack@
+FFCS_COMPILE_gsl = @FFCS_COMPILE_gsl@
+FFCS_COMPILE_hips = @FFCS_COMPILE_hips@
+FFCS_COMPILE_hypre = @FFCS_COMPILE_hypre@
+FFCS_COMPILE_ipopt = @FFCS_COMPILE_ipopt@
+FFCS_COMPILE_lapack = @FFCS_COMPILE_lapack@
+FFCS_COMPILE_mmg3d = @FFCS_COMPILE_mmg3d@
+FFCS_COMPILE_mshmet = @FFCS_COMPILE_mshmet@
+FFCS_COMPILE_mumps = @FFCS_COMPILE_mumps@
+FFCS_COMPILE_mumps_seq = @FFCS_COMPILE_mumps_seq@
+FFCS_COMPILE_pardiso = @FFCS_COMPILE_pardiso@
+FFCS_COMPILE_parms = @FFCS_COMPILE_parms@
+FFCS_COMPILE_pastix = @FFCS_COMPILE_pastix@
+FFCS_COMPILE_pipe = @FFCS_COMPILE_pipe@
+FFCS_COMPILE_scotch = @FFCS_COMPILE_scotch@
+FFCS_COMPILE_superludist = @FFCS_COMPILE_superludist@
+FFCS_COMPILE_yams = @FFCS_COMPILE_yams@
+FFCS_DYLIB_fflapack = @FFCS_DYLIB_fflapack@
+FFCS_DYLIB_gsl = @FFCS_DYLIB_gsl@
+FFCS_DYLIB_hips = @FFCS_DYLIB_hips@
+FFCS_DYLIB_hypre = @FFCS_DYLIB_hypre@
+FFCS_DYLIB_ipopt = @FFCS_DYLIB_ipopt@
+FFCS_DYLIB_lapack = @FFCS_DYLIB_lapack@
+FFCS_DYLIB_mmg3d = @FFCS_DYLIB_mmg3d@
+FFCS_DYLIB_mshmet = @FFCS_DYLIB_mshmet@
+FFCS_DYLIB_mumps = @FFCS_DYLIB_mumps@
+FFCS_DYLIB_mumps_seq = @FFCS_DYLIB_mumps_seq@
+FFCS_DYLIB_pardiso = @FFCS_DYLIB_pardiso@
+FFCS_DYLIB_parms = @FFCS_DYLIB_parms@
+FFCS_DYLIB_pastix = @FFCS_DYLIB_pastix@
+FFCS_DYLIB_pipe = @FFCS_DYLIB_pipe@
+FFCS_DYLIB_scotch = @FFCS_DYLIB_scotch@
+FFCS_DYLIB_superludist = @FFCS_DYLIB_superludist@
+FFCS_DYLIB_yams = @FFCS_DYLIB_yams@
+FFCS_MAKEFLAGS = @FFCS_MAKEFLAGS@
 FFGLUTNAME = @FFGLUTNAME@
 FFGLUTPROG = @FFGLUTPROG@
 FFLAGS = @FFLAGS@
@@ -500,15 +577,16 @@ target_alias = @target_alias@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-TESTS = adapt.edp adaptindicatorP1.edp adaptindicatorP2.edp algo.edp array.edp a_tutorial.edp beam.edp  calculus.edp cavity.edp convect2.edp convect-apt.edp convect.edp dumptable.edp ex-vf.edp FE.edp fluidStructAdapt.edp fluidStruct.edp freeboundary.edp freeboundary-weak.edp LapDG2.edp Laplace.edp LaplaceP1bis.edp LaplaceP1.edp LaplaceP1P2h.edp LaplaceRT.edp mesh.edp movemesh.edp nolinear-elas.edp NSUzawaCahouetChabart.edp onde.edp periodic4.edp Periodic.edp plot.edp readmesh.edp region. [...]
+TESTS = adapt.edp adaptindicatorP1.edp adaptindicatorP2.edp algo.edp array.edp a_tutorial.edp beam.edp  calculus.edp cavity.edp convect2.edp convect-apt.edp convect.edp dumptable.edp ex-vf.edp FE.edp fluidStructAdapt.edp fluidStruct.edp freeboundary.edp freeboundary-weak.edp LapDG2.edp Laplace.edp LaplaceP1bis.edp LaplaceP1.edp LaplaceP1P2h.edp LaplaceRT.edp mesh.edp movemesh.edp nolinear-elas.edp NSUzawaCahouetChabart.edp onde.edp periodic4.edp Periodic.edp plot.edp readmesh.edp region. [...]
 LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-ff
 TESTS_ENVIRONMENT = TEST_FFPP=$(TEST_FFPP) FLAGS_FFPP=-nw
 LIST_IDP = *.idp
 EXTRA_DIST = *.edp *.idp aile.msh xyf all.edp regtests.edp regtests.m4 ref.edp
+Laplace_SOURCES = Laplace.cpp
 all: all-am
 
 .SUFFIXES:
-.SUFFIXES: .log .test .test$(EXEEXT) .trs
+.SUFFIXES: .cpp .log .o .obj .test .test$(EXEEXT) .trs
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
 	@for dep in $?; do \
 	  case '$(am__configure_deps)' in \
@@ -539,12 +617,83 @@ $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
 $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
 	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 $(am__aclocal_m4_deps):
-tags TAGS:
+Laplace$(EXEEXT): $(Laplace_OBJECTS) $(Laplace_DEPENDENCIES) $(EXTRA_Laplace_DEPENDENCIES) 
+	@rm -f Laplace$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(Laplace_OBJECTS) $(Laplace_LDADD) $(LIBS)
 
-ctags CTAGS:
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
 
-cscope cscopelist:
+distclean-compile:
+	-rm -f *.tab.c
 
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/Laplace.Po at am__quote@
+
+.cpp.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
 # Recover from deleted '.trs' file; this should ensure that
 # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
@@ -988,6 +1137,13 @@ tablefunction.edp.log: tablefunction.edp
 	--log-file $$b.log --trs-file $$b.trs \
 	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
+intlevelset.edp.log: intlevelset.edp
+	@p='intlevelset.edp'; \
+	b='intlevelset.edp'; \
+	$(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) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
 .test.log:
 	@p='$<'; \
 	$(am__set_b); \
@@ -1076,8 +1232,10 @@ clean: clean-am
 clean-am: clean-generic mostlyclean-am
 
 distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
 	-rm -f Makefile
-distclean-am: clean-am distclean-generic
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
 
 dvi: dvi-am
 
@@ -1120,12 +1278,13 @@ install-ps-am:
 installcheck-am:
 
 maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
 mostlyclean: mostlyclean-am
 
-mostlyclean-am: mostlyclean-generic
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
 
 pdf: pdf-am
 
@@ -1139,17 +1298,18 @@ uninstall-am:
 
 .MAKE: check-am install-am install-strip
 
-.PHONY: all all-am all-local check check-TESTS check-am clean \
-	clean-generic cscopelist-am ctags-am distclean \
-	distclean-generic distdir dvi dvi-am html html-am info info-am \
-	install install-am install-data install-data-am install-dvi \
+.PHONY: CTAGS GTAGS TAGS all all-am all-local check check-TESTS \
+	check-am clean clean-generic cscopelist-am ctags ctags-am \
+	distclean distclean-compile distclean-generic distclean-tags \
+	distdir dvi dvi-am html html-am info info-am install \
+	install-am install-data install-data-am install-dvi \
 	install-dvi-am install-exec install-exec-am install-exec-local \
 	install-html install-html-am install-info install-info-am \
 	install-man install-pdf install-pdf-am install-ps \
 	install-ps-am install-strip installcheck installcheck-am \
 	installdirs maintainer-clean maintainer-clean-generic \
-	mostlyclean mostlyclean-generic pdf pdf-am ps ps-am recheck \
-	tags-am uninstall uninstall-am
+	mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \
+	ps ps-am recheck tags tags-am uninstall uninstall-am
 
 
 all-local: all.edp regtests.edp  freefem++.pref
diff --git a/examples++-tutorial/NS-BackwardStep.edp b/examples++-tutorial/NS-BackwardStep.edp
index d6c327a..87f7e54 100644
--- a/examples++-tutorial/NS-BackwardStep.edp
+++ b/examples++-tutorial/NS-BackwardStep.edp
@@ -10,6 +10,10 @@
      K.Morgan, J.Périaux and F.Thomasset, Analysis of laminar flow over a backward facing step, Vol9 of Notes on Num. Fluid Mech., Vieweg, 1984. 
     
 */
+
+// FFCS regression test value
+real regtest;
+
 real[int] Reynold=[50,150,300,400,500];
 real[int] HH=[1.5,1]; 
 real[int,int] reattachP=[ [ 2.8, 2 ], [ 5.16, 3.7 ]] ;  // reattachP[irey,cas]  
@@ -159,6 +163,9 @@ for(int krey=0;krey<Reynold.n;++krey)
     plot(coef=0.2,cmm="H="+H+", rey="+re+" [u1,u2] et p  ",p,[uu1,uu2],wait=0,nbiso=20,bb=zoom);//,ps="Upstep-"+H+"-"+re
     plot(coef=0.2,cmm="H="+H+", rey="+re+" [u1,u2] et p  ",p,[uu1,uu2],wait=0,nbiso=20,bb=zoom);//,ps="Upstep-"+H+"-"+re+".ps");  
     plot(coef=0.2,cmm="H="+H+", rey="+re+" [u1,u2] et p  ",psi,bb=zoom,viso=psiviso);//,ps="psi-step-"+H+"-"+re+".ps");  
+
+    // FFCS regression test value
+    regtest=uu1[]'*uu1[];//'
      }
 }
 assert(nerr==0); 
\ No newline at end of file
diff --git a/examples++-tutorial/Newton.edp b/examples++-tutorial/Newton.edp
index c07126d..c925abd 100644
--- a/examples++-tutorial/Newton.edp
+++ b/examples++-tutorial/Newton.edp
@@ -1,3 +1,6 @@
+// FFCS: making a numerical value visible for regression tests
+real regtest;
+
 { // ---  a real non linear test ---
 mesh Th=square(10,10);  // mesh definition of $\Omega$
 Th = adaptmesh(Th,0.05,IsMetric=1,splitpbedge=1);
@@ -48,7 +51,7 @@ int iter=0;
     dfalpha = df( alpha ) ; // optimization
     ddfalpha = 2*ddf(alpha ) ; // optimization
     v[]= vdJ(0,Vh);
-    real res= v[]'*v[];
+    real res= v[]'*v[]; //'
     cout << i <<  " residu^2 = " <<  res  << endl;
     matrix H;
     if( res< 1e-12) break;
@@ -57,10 +60,11 @@ int iter=0;
     u[] -= w[];
     plot (u,wait=0,cmm="solution with Newton Raphson");
 
+    // FFCS: regression tests
+    regtest=u[]'*u[]; //'
    }
 
 load "medit" load "msh3"  
     mesh3 Th3= movemesh23(Th,transfo=[x,y,u*1.5]);
     medit("N",Th3);
 }
-
diff --git a/examples++-tutorial/a_tutorial.edp b/examples++-tutorial/a_tutorial.edp
index 939dcf2..224b559 100644
--- a/examples++-tutorial/a_tutorial.edp
+++ b/examples++-tutorial/a_tutorial.edp
@@ -35,4 +35,4 @@ err =u-(1-x^2-y^2)/4;
 plot(err,value=true,wait=true);
 cout << "error L2=" << sqrt(int2d(disk)( (u-(1-x^2-y^2)/4) ^2) )<< endl;
 cout << "error H10=" << sqrt(  int2d(disk)((dx(u)+x/2)^2) 
-                             + int2d(disk)((dy(u)+y/2)^2))<< endl;
\ No newline at end of file
+                             + int2d(disk)((dy(u)+y/2)^2))<< endl;
diff --git a/examples++-tutorial/array.edp b/examples++-tutorial/array.edp
index f7d8715..70c6b4f 100644
--- a/examples++-tutorial/array.edp
+++ b/examples++-tutorial/array.edp
@@ -317,7 +317,7 @@ d = ( a ? b : c ); // for i = 0, n-1  : d[i] = a[i] ? b[i] : c[i] ,
 cout << " d = ( a ? b : c )  is " << d << endl;
 d = ( a ? 1 : c );// for i = 0, n-1: d[i] = a[i] ? 1 : c[i] ,   (v2.23-1)
 d = ( a ? b : 0 );// for i = 0, n-1: d[i] = a[i] ? b[i] : 0 ,   (v2.23-1)
-d = ( a ? 1 : 0 );// for i = 0, n-1: d[i] = a[i] ? 0 : 1 ,     \hfill�(v2.23-1)
+d = ( a ? 1 : 0 );// for i = 0, n-1: d[i] = a[i] ? 0 : 1 ,     \hfill(v2.23-1)
  tab.sort ; //  sort the array tab  (version 2.18) 
 cout << " tab (after sort) "  << tab << endl;
 int[int] ii(0:d.n-1); // set array ii to 0,1, ..., d.n-1
@@ -326,6 +326,7 @@ sort(d,ii); // sort array d and ii in parallele
 cout << " d " << d << "\n ii = " << ii << endl;
 
 }
+
 //  version 3.8-1
 for(int i=0;i<ARGV.n;++i)
   {
@@ -345,4 +346,5 @@ cout << wh.n << endl;
 cout << vh.n <<endl;
 vh.resize(20);
 cout << vh.n <<endl;
-}
\ No newline at end of file
+}
+
diff --git a/examples++-tutorial/calculus.edp b/examples++-tutorial/calculus.edp
index 9823d43..6a1a490 100644
--- a/examples++-tutorial/calculus.edp
+++ b/examples++-tutorial/calculus.edp
@@ -51,4 +51,4 @@ cout << " i   = " << i << "\n";
  real a =  x == 0 ? x : -1;
  real b =  x != 0 ? x : -1;
  cout << " a = " << a << " b = " << b << endl; 
- }
\ No newline at end of file
+ }
diff --git a/examples++-tutorial/freeboundary-weak.edp b/examples++-tutorial/freeboundary-weak.edp
index 0c52f50..6b53e61 100755
--- a/examples++-tutorial/freeboundary-weak.edp
+++ b/examples++-tutorial/freeboundary-weak.edp
@@ -1,5 +1,5 @@
 //  
-//   calcul d'une zone saturation en eau (nappe phr�atique)
+//   calcul d'une zone saturation en eau (nappe phreatique)
 //
 verbosity=1;
 real weak=1;
@@ -7,7 +7,7 @@ string com= "  avec du/dn ";
 if(weak) com = " avec du/du = residu  ";
 real L=10;        // longueur du domaine					   	
 real Q=0.02;      // flux entrant
-real K=0.5;	      //permeabilit�	
+real K=0.5;	      //permeabilite	
 
 real  erradap=0.001;
 real  coef=1;
diff --git a/examples++-tutorial/glumesh.edp b/examples++-tutorial/glumesh.edp
index 04cafaa..8ffc62e 100644
--- a/examples++-tutorial/glumesh.edp
+++ b/examples++-tutorial/glumesh.edp
@@ -17,6 +17,9 @@ Vh u,v;
 solve P(u,v)=int2d(Th)(Grad(u)'*Grad(v))-int2d(Th)(v)+on(1,3,u=0);
 plot(u,wait=1);
 
+// FFCS: for regression tests
+real regtest;
+
 {
 // ---------------
 real R=50.*sqrt(2.); //  theta = 
@@ -38,4 +41,5 @@ plot(Th,th1,th2,th3,wait=1);
 
 plot(Th4,wait=1);
 Th=Th4;
+regtest=Th.nv;
 }
diff --git a/examples++-tutorial/intlevelset.edp b/examples++-tutorial/intlevelset.edp
new file mode 100644
index 0000000..94f4d2a
--- /dev/null
+++ b/examples++-tutorial/intlevelset.edp
@@ -0,0 +1,30 @@
+int err=0;
+mesh Th=square(50,50,[3*x-1.5,3*y-1.5]);
+func r = sqrt(x*x +y*y);
+// wrong ...
+real lc ;
+verbosity=10;
+lc = int1d(Th,levelset=r-1.)(1.) ; 
+cout << " len of the level set = " <<  lc  << " =  2pi " << 2*pi ;
+cout << ", Ok = " << (abs(lc-2*pi) < 1e-1) << endl; 
+if( abs(lc-2*pi) > 1e-1) err++;
+fespace Vh(Th,P1);
+// test linear and bilinear ... 
+varf vl(u,v) = int1d(Th,levelset=r-1.)(v) + int1d(Th,levelset=r-1.)(u*v);
+real[int] vv=vl(0,Vh);
+
+cout << " len of the level set (varf linear ) = " <<  (lc=vv.sum)  << "=  2pi " << 2*pi ;
+cout  << ", Ok = " << (abs(lc-2*pi) < 1e-1) << endl;
+if( abs(lc-2*pi) > 1e-1) err++; 
+real[int]  one(Vh.ndof); 
+one=1.;
+// sorry not implemented to day ... FH..
+//matrix VV=vl(Vh,Vh); // no build of matrix with levelset ... sorry not implemented to day ... FH..
+//vv = VV*one;
+//cout << " len of the level set (varf bilinear ) = " <<  (lc=vv.sum)  << "=  2pi " << 2*pi;
+//cout << ", Ok = " << (abs(lc-2*pi) < 1e-1) << endl;; 
+//if( abs(lc-2*pi) > 1e-1) err++;
+
+cout << " Nb err " << err << endl;
+assert(err==0);
+
diff --git a/examples++-tutorial/readmesh.edp b/examples++-tutorial/io.edp
similarity index 100%
copy from examples++-tutorial/readmesh.edp
copy to examples++-tutorial/io.edp
diff --git a/examples++-tutorial/medit.edp b/examples++-tutorial/medit.edp
index bc7408c..14e54bc 100644
--- a/examples++-tutorial/medit.edp
+++ b/examples++-tutorial/medit.edp
@@ -28,4 +28,5 @@ load "medit" load "msh3"
     medit("mm",Th3);// bug un color of u ... FH 
 }
 
-
+// FFCS: testing 3D plots
+plot(u);
diff --git a/examples++-tutorial/mesh.edp b/examples++-tutorial/mesh.edp
index 97dcc67..87eb49d 100644
--- a/examples++-tutorial/mesh.edp
+++ b/examples++-tutorial/mesh.edp
@@ -1,3 +1,5 @@
+// FFCS: for regression tests
+real regtest;
 {
  // build from bamg geometrie
 
@@ -272,7 +274,8 @@ plot(rh,ps="lshape.eps");
     for (int k=0;k<nbboundaryelement;++k)
       cout << k << " : " <<  Th.be(k)[0] << " " << Th.be(k)[1] << " , label " << Th.be(k).label 
 	   <<  " tria  " << int(Th.be(k).Element) << " " << Th.be(k).whoinElement <<  endl; 
-    
+
+regtest=Th.nv;
 }
 //   test to catch bogus boundary ( just a test)
 {
diff --git a/examples++-tutorial/mortar-DN-4.edp b/examples++-tutorial/mortar-DN-4.edp
index 28aa5d2..8916c95 100644
--- a/examples++-tutorial/mortar-DN-4.edp
+++ b/examples++-tutorial/mortar-DN-4.edp
@@ -213,7 +213,8 @@ verbosity=1;
 
 plot(usd,wait=1,cmm="CG");
 
-
+// FFCS: for regression tests
+real regtest;
 {  
 fespace Vha(Tha,P1);
 Vha vah,uah;
@@ -224,5 +225,6 @@ solve vLapMM([uah],[vah]) =
    ;
 verbosity =3;
 plot(uah,usd,cmm="uah",wait=1); 
+regtest=uah[]'*uah[];
 }
 
diff --git a/examples++-tutorial/readmesh.edp b/examples++-tutorial/readmesh.edp
index 478e419..6f5fb79 100644
--- a/examples++-tutorial/readmesh.edp
+++ b/examples++-tutorial/readmesh.edp
@@ -22,7 +22,32 @@ real xx;
   file << 0.1 ;
   //  file << " " << 0.2 ;
   cout << " where in file " << where << endl;
+  file << " # comment bla bla ...  0.3 \n";
+  file << 0.2 << endl; 
 }
+//  Idea to skip comment in a file ...  start with  # too EOL
+func ifstream skipcomment(ifstream &ff)
+{
+    
+    while(1)
+    {
+    int where = ff.tellg(); // store file position 
+    string comment;
+    ff >> comment; 
+    if ( ! ff.good() ) break; 
+    if( comment(0:0)=="#") {
+         getline(ff,comment);
+         cout << " -- #" << comment << endl;
+    }
+    else {
+        ff.seekg(where); //restore file position 
+        break;        
+    }    
+    }
+    return ff;
+}
+
+
 {
   ifstream file("f.txt");
   cout << " where " << file.seekg << endl; 
@@ -30,6 +55,8 @@ real xx;
   file >> xx;
   cout <<  " xx = " << xx << " good ? " << file.good() << endl;
   assert(xx==0.1);
+  skipcomment(file) >> xx;
+  assert(xx==0.2);
   file.seekg(0);
   cout << " where " << file.tellg() << " " << file.good() << endl; 
   file >> g[] ;
diff --git a/examples++-tutorial/saverestore.edp b/examples++-tutorial/saverestore.edp
index af21799..4a09608 100644
--- a/examples++-tutorial/saverestore.edp
+++ b/examples++-tutorial/saverestore.edp
@@ -14,6 +14,7 @@ Vh u=f;
 
 f <<u[];
 }
+real regtest;//FFCS regression test value
 {
 mesh Th=readmesh("Th.msh"); // il y a un changement de numerotation des traingle ou??
 // mesh Th("Th.msh"); // oK ..
@@ -26,4 +27,5 @@ e[] = u[] -v[];
 cout << e[].max << " " << e[].min << endl;
 plot(e,wait=1,value=1);
 assert(e[].max-e[].min < 1e-6);
+regtest=e[].max-e[].min;
 }
diff --git a/examples++-tutorial/schwarz-no-overlap.edp b/examples++-tutorial/schwarz-no-overlap.edp
index fc0fbad..2b9313c 100644
--- a/examples++-tutorial/schwarz-no-overlap.edp
+++ b/examples++-tutorial/schwarz-no-overlap.edp
@@ -33,7 +33,9 @@ for ( i=0 ;i< 20; i++)
    pb;
    lambda = lambda - (u-U)/2;
 //  if (i==0)
-  plot(U,u,wait=true,ps="schwarz-no-u"+i+".eps");
+
+    // FFCS: add 3d view
+  plot(U,u,wait=true,ps="schwarz-no-u"+i+".eps",dim=3,fill=1);
 };
 
 plot(U,u,ps="schwarz-no-u.eps");
diff --git a/examples++-tutorial/sparse-cmatrix.edp b/examples++-tutorial/sparse-cmatrix.edp
index b9d2968..c91f3a8 100644
--- a/examples++-tutorial/sparse-cmatrix.edp
+++ b/examples++-tutorial/sparse-cmatrix.edp
@@ -150,4 +150,4 @@ plot(xxr, wait=1);
 
 
 
-}
\ No newline at end of file
+}
diff --git a/examples++-tutorial/thermic-fast.edp b/examples++-tutorial/thermic-fast.edp
index 9c5d7d3..c0aec16 100755
--- a/examples++-tutorial/thermic-fast.edp
+++ b/examples++-tutorial/thermic-fast.edp
@@ -1,45 +1,45 @@
-// file thermal-fast.edp    same problem than thermal.edp
-
-func fu0 =10+90*x/6;
-func k = 1.8*(y<0.5)+0.2;
-real ue = 25. , alpha=0.25, T=5, dt=0.1 ;
-
-mesh Th=square(30,5,[6*x,y]);
-fespace Vh(Th,P1);
-
-Vh u0=fu0,u=u0;
-
-varf vthermic (u,v)= int2d(Th)(u*v/dt + k*(dx(u) * dx(v) + dy(u) * dy(v)))  
-  +  int1d(Th,1,3)(alpha*u*v)
-  + on(2,4,u=1); 
-
-varf vthermic0(u,v) =   int1d(Th,1,3)(alpha*ue*v);
-
-varf vMass (u,v)= int2d(Th)( u*v/dt)  + on(2,4,u=1);
-
-real tgv = 1e30;
-matrix A= vthermic(Vh,Vh,tgv=tgv,solver=CG);
-matrix M= vMass(Vh,Vh);
-
-
-real[int]  b0  = vthermic0(0,Vh); // constant part of the RHS 
+// file thermal-fast.edp    same problem than thermal.edp
+
+func fu0 =10+90*x/6;
+func k = 1.8*(y<0.5)+0.2;
+real ue = 25. , alpha=0.25, T=5, dt=0.1 ;
+
+mesh Th=square(30,5,[6*x,y]);
+fespace Vh(Th,P1);
+
+Vh u0=fu0,u=u0;
+
+varf vthermic (u,v)= int2d(Th)(u*v/dt + k*(dx(u) * dx(v) + dy(u) * dy(v)))  
+  +  int1d(Th,1,3)(alpha*u*v)
+  + on(2,4,u=1); 
+
+varf vthermic0(u,v) =   int1d(Th,1,3)(alpha*ue*v);
+
+varf vMass (u,v)= int2d(Th)( u*v/dt)  + on(2,4,u=1);
+
+real tgv = 1e30;
+matrix A= vthermic(Vh,Vh,tgv=tgv,solver=CG);
+matrix M= vMass(Vh,Vh);
+
+
+real[int]  b0  = vthermic0(0,Vh); // constant part of the RHS 
 real[int]  bcn = vthermic(0,Vh); //  tgv on Dirichlet boundary  node  ( !=0 )
-// we have for the node $i$ : $i\in \Gamma_{24}  \quad \Leftrightarrow \quad bcn[i] \ne 0 $ 
-real[int]  bcl=tgv*u0[]; //  the Dirichlet boundary condition part 
-
-
-ofstream ff("thermic.dat");
-for(real t=0;t<T;t+=dt){
-    real[int] b = b0 ; // for  the  RHS
+// we have for the node $i$ : $i\in \Gamma_{24}  \quad \Leftrightarrow \quad bcn[i] \ne 0 $ 
+real[int]  bcl=tgv*u0[]; //  the Dirichlet boundary condition part 
+
+
+ofstream ff("thermic.dat");
+for(real t=0;t<T;t+=dt){
+    real[int] b = b0 ; // for  the  RHS
     b += M*u[]; //  add the the time dependant part
-    // to lock boundary 2,4 part:
-    b = bcn ? bcl  : b ; // do $\forall i$:  b[i] =  bcn[i] ? bcl[i] : b[i]  ;      
-    u[] = A^-1*b;    
-    ff<< t << " " << u(3,0.5) <<endl;
-    plot(u);
-}
+    // to lock boundary 2,4 part:
+    b = bcn ? bcl  : b ; // do $\forall i$:  b[i] =  bcn[i] ? bcl[i] : b[i]  ;      
+    u[] = A^-1*b;    
+    ff<< t << " " << u(3,0.5) <<endl;
+    plot(u);
+}
 for(int i=0;i<20;i++) 
-  cout<<dy(u)(6.0*i/20.0,0.9)<<endl;
-plot(u,fill=true,wait=1,ps="thermic.eps");
-
-
+  cout<<dy(u)(6.0*i/20.0,0.9)<<endl;
+plot(u,fill=true,wait=1,ps="thermic.eps");
+
+
diff --git a/examples++/._FE-medit.edp b/examples++/._FE-medit.edp
new file mode 100644
index 0000000..f7a8f68
Binary files /dev/null and b/examples++/._FE-medit.edp differ
diff --git a/examples++/._aaa-adp.edp b/examples++/._aaa-adp.edp
new file mode 100644
index 0000000..f7a8f68
Binary files /dev/null and b/examples++/._aaa-adp.edp differ
diff --git a/examples++/._bilap.edp b/examples++/._bilap.edp
new file mode 100644
index 0000000..f7a8f68
Binary files /dev/null and b/examples++/._bilap.edp differ
diff --git a/examples++/._testadp.edp b/examples++/._testadp.edp
new file mode 100644
index 0000000..f7a8f68
Binary files /dev/null and b/examples++/._testadp.edp differ
diff --git a/examples++/Makefile.am b/examples++/Makefile.am
index ce740e3..41df5d4 100644
--- a/examples++/Makefile.am
+++ b/examples++/Makefile.am
@@ -1,6 +1,6 @@
 # $Id$
 
-all-local: all.edp regtests.edp
+all-local: all.edp regtests.edp freefem++.pref
 
 TESTS=aadaptation.edp aalapacien.edp aalaplace-nc.edp aamove.edp aaRT.edp arrayoFVh.edp bilap.edp D2.edp demo1.edp demo.edp funct.edp lapacienprecon.edp lap_mat.edp NSP1P1b.edp NSP1P1.edp NSP1P2.edp parareal.edp Richard.edp teste.edp testFE.edp wafer-heating-laser-axi.edp
 LOG_DRIVER=$(SHELL) $(top_srcdir)/test-driver-ff
@@ -23,6 +23,9 @@ Ref: makeref.edp
 
 makeref.edp: regtests.m4 ../regtests.m4
 	m4 regtests.m4 > makeref.edp
+freefem++.pref:
+	echo loadpath = \"../examples++-load/\" >freefem++.pref
+	echo loadpath += \"./\" >>freefem++.pref
 
 # To check the scripts against their reference values
 regtests.edp: regtests.m4 ../regtests.m4
diff --git a/examples++/Makefile.in b/examples++/Makefile.in
index 47d8546..b4653e6 100644
--- a/examples++/Makefile.in
+++ b/examples++/Makefile.in
@@ -56,7 +56,8 @@ 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)/acmacros.m4 \
-	$(top_srcdir)/acoptim.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/acoptim.m4 $(top_srcdir)/acmpi.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -329,11 +330,47 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EIGENOBJ = @EIGENOBJ@
+ENABLE_FFCS = @ENABLE_FFCS@
 EPSTOPDF = @EPSTOPDF@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+FFCS_COMPILE_fflapack = @FFCS_COMPILE_fflapack@
+FFCS_COMPILE_gsl = @FFCS_COMPILE_gsl@
+FFCS_COMPILE_hips = @FFCS_COMPILE_hips@
+FFCS_COMPILE_hypre = @FFCS_COMPILE_hypre@
+FFCS_COMPILE_ipopt = @FFCS_COMPILE_ipopt@
+FFCS_COMPILE_lapack = @FFCS_COMPILE_lapack@
+FFCS_COMPILE_mmg3d = @FFCS_COMPILE_mmg3d@
+FFCS_COMPILE_mshmet = @FFCS_COMPILE_mshmet@
+FFCS_COMPILE_mumps = @FFCS_COMPILE_mumps@
+FFCS_COMPILE_mumps_seq = @FFCS_COMPILE_mumps_seq@
+FFCS_COMPILE_pardiso = @FFCS_COMPILE_pardiso@
+FFCS_COMPILE_parms = @FFCS_COMPILE_parms@
+FFCS_COMPILE_pastix = @FFCS_COMPILE_pastix@
+FFCS_COMPILE_pipe = @FFCS_COMPILE_pipe@
+FFCS_COMPILE_scotch = @FFCS_COMPILE_scotch@
+FFCS_COMPILE_superludist = @FFCS_COMPILE_superludist@
+FFCS_COMPILE_yams = @FFCS_COMPILE_yams@
+FFCS_DYLIB_fflapack = @FFCS_DYLIB_fflapack@
+FFCS_DYLIB_gsl = @FFCS_DYLIB_gsl@
+FFCS_DYLIB_hips = @FFCS_DYLIB_hips@
+FFCS_DYLIB_hypre = @FFCS_DYLIB_hypre@
+FFCS_DYLIB_ipopt = @FFCS_DYLIB_ipopt@
+FFCS_DYLIB_lapack = @FFCS_DYLIB_lapack@
+FFCS_DYLIB_mmg3d = @FFCS_DYLIB_mmg3d@
+FFCS_DYLIB_mshmet = @FFCS_DYLIB_mshmet@
+FFCS_DYLIB_mumps = @FFCS_DYLIB_mumps@
+FFCS_DYLIB_mumps_seq = @FFCS_DYLIB_mumps_seq@
+FFCS_DYLIB_pardiso = @FFCS_DYLIB_pardiso@
+FFCS_DYLIB_parms = @FFCS_DYLIB_parms@
+FFCS_DYLIB_pastix = @FFCS_DYLIB_pastix@
+FFCS_DYLIB_pipe = @FFCS_DYLIB_pipe@
+FFCS_DYLIB_scotch = @FFCS_DYLIB_scotch@
+FFCS_DYLIB_superludist = @FFCS_DYLIB_superludist@
+FFCS_DYLIB_yams = @FFCS_DYLIB_yams@
+FFCS_MAKEFLAGS = @FFCS_MAKEFLAGS@
 FFGLUTNAME = @FFGLUTNAME@
 FFGLUTPROG = @FFGLUTPROG@
 FFLAGS = @FFLAGS@
@@ -997,7 +1034,7 @@ uninstall-am:
 	uninstall uninstall-am
 
 
-all-local: all.edp regtests.edp
+all-local: all.edp regtests.edp freefem++.pref
 
 all.edp:
 	(echo "NoUseOfWait=true;int verbosityy=verbosity;"; \
@@ -1014,6 +1051,9 @@ Ref: makeref.edp
 
 makeref.edp: regtests.m4 ../regtests.m4
 	m4 regtests.m4 > makeref.edp
+freefem++.pref:
+	echo loadpath = \"../examples++-load/\" >freefem++.pref
+	echo loadpath += \"./\" >>freefem++.pref
 
 # To check the scripts against their reference values
 regtests.edp: regtests.m4 ../regtests.m4
diff --git a/examples++/ccc-adp.edp b/examples++/ccc-adp.edp
index 020cfbc..93b6ece 100644
--- a/examples++/ccc-adp.edp
+++ b/examples++/ccc-adp.edp
@@ -45,4 +45,4 @@ for (int i=0;i<nbiter;i++)
   fff  << i<< " " << err << " " << Th.nt << " " << Th.nv <<  endl;  
 }
 //  for regtest 
-real regvalue=err;
\ No newline at end of file
+real regvalue=err;
diff --git a/examples++/ref.edp b/examples++/ref.edp
index b6467f6..e69de29 100644
--- a/examples++/ref.edp
+++ b/examples++/ref.edp
@@ -1,20 +0,0 @@
-real REFaadaptation=0.000319327;
-real REFaalapacien=1;
-real REFaalaplaceXnc=1713.48;
-real REFaamove=0.0677578;
-real REFaaRT=280.926;
-real REFarrayoFVh=4560.74;
-real REFbilap=33.835;
-real REFD2=1.46879e-23;
-real REFdemo1=1.3417;
-real REFdemo=1.3417;
-real REFfunct=4;
-real REFlapacienprecon=122059;
-real REFlapXmat=85.3776;
-real REFNSP1P1b=0.0461412;
-real REFNSP1P1=0.04912353826;
-real REFNSP1P2=0.0453517;
-real REFparareal=1383.27;
-real REFRichard=95.9029;
-real REFteste=1;
-real REFwaferXheatingXlaserXaxi=285;
diff --git a/examples++/testFE.edp b/examples++/testFE.edp
index de4116c..0456587 100644
--- a/examples++/testFE.edp
+++ b/examples++/testFE.edp
@@ -1,4 +1,4 @@
-
+real regtest;// for FFCS regression tests
 // exact solution is [x*x,y]  -Delta [x*x,y] = [-2,0]
 // This exemple is buggus before version 1.26
 { 
@@ -44,4 +44,5 @@ verbosity = 2;
     real err2= sqrt( int2d(Th)(square(uHx-x*x)+square(uHy-y)));
     cout << " Error in L2 norme " << err2 << endl ;
     assert(err2 < 1e-10);
+    regtest=err2;
 }
diff --git a/freefem++.spec b/freefem++.spec
index 7ea8eeb..75bf19a 100644
--- a/freefem++.spec
+++ b/freefem++.spec
@@ -1,98 +1,98 @@
-Summary: FreeFem++
-Name: freefem++
-Version: 2.8
-Release: 0
-Source: %{name}-%{version}.tar.gz
-Patch:   %{name}-config.patch
-Patch1:   %{name}-gcc4.patch
-%if %{?_with_cadna:1}%{!?_with_cadna:0} 
-Source2: CadnaC_gcc-3.2_Linux_i386.tar.gz
-Patch2:  cadna-gcc4.patch
-%endif
-License: GPL
-Group: Applications/Engineering
-URL: http://www.freefem.org/ff++/
-Packager: Christophe  Trophime <christophe.trophime at grenoble.cnrs.fr>
-Prereq: /sbin/install-info
-Buildroot: %{_tmppath}/%{name}-buildroot
-Requires: arpack, ufsparse
-BuildRequires: arpack-devel, ufsparse-devel
-BuildRequires: fltk >= 1.1
-BuildRequires: fltk >= 1.1
-BuildRequires: gsl >= 1.2
-BuildRequires: rpm >= 4.1
-%if %{?_with_mpi:1}%{!?_with_mpi:0} 
-BuildRequires: lam
-%endif
-%{!?_without_freedesktop:BuildRequires: desktop-file-utils}
-Requires: mesa-libGL >= 6.7.0-9
-Requires: mesa-libGLU >= 6.7.0-9
-Requires: gsl >= 1.2
-Requires: fltk >= 1.1
-Prefix: /usr
-
-%description 
-FreeFem++ is an implementation of a language dedicated to the finite element method. 
-It enables you to solve Partial Differential Equations (PDE) easily.
-
-Problems involving PDE from several branches of physics such as fluid-structure interactions 
-require interpolations of data on several meshes and their manipulation within one program. 
-FreeFem++ includes a fast quadtree-based interpolation algorithm and a language for the manipulation 
-of data on multiple meshes (generated with bamg).
-
-
-
-%prep
-
-%setup -q -n %{name}-%{version}
-%patch -p1 -b .umfpack
-%patch1 -p1 -b .gcc4
-
-%if %{?_with_cadna:1}%{!?_with_cadna:0}
-mkdir -p cadna
-mkdir -p download/cadna
-tar zxvf %{SOURCE2} -C cadna 
-mv cadna/include/cadnafree.h download/cadna
-mv cadna/lib/libcadnafreeC.a download/cadna
-pushd download/cadna/
-ln -sf libcadnafreeC.a libcadnafree.a
-popd
-%patch2 -p1 -b .cadna-gcc4.patch
-%endif
-
-autoreconf -f -i
-
-%build
-%if %{?_with_mpi:1}%{!?_with_mpi:0}
-%configure --with-mpi=lam
-%else
-%configure --without-mpi --with-blas="-L/usr/lib/atlas -lf77blas -lcblas"
-%endif
-make
-
-%install
-rm -rf $RPM_BUILD_ROOT
-
-make install DESTDIR=$RPM_BUILD_ROOT
-
-
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-%files
-%defattr(-,root,root)
-%{_bindir}/FreeFem++
-%{_bindir}/FreeFem++-cs
-%{_bindir}/FreeFem++-nw
-%{_bindir}/FreeFem++-glx
-%{_bindir}/FreeFem++-ide
-%{_bindir}/FreeFem++-server
-%{_bindir}/FreeFem++-client
-%{_bindir}/bamg
-%{_bindir}/cvmsh2
-%{_bindir}/drawbdmesh
-%if %{?_with_mpi:1}%{!?_with_mpi:0}
-%{_bindir}/FreeFem++-mpi
-%endif
-
+Summary: FreeFem++
+Name: freefem++
+Version: 2.8
+Release: 0
+Source: %{name}-%{version}.tar.gz
+Patch:   %{name}-config.patch
+Patch1:   %{name}-gcc4.patch
+%if %{?_with_cadna:1}%{!?_with_cadna:0} 
+Source2: CadnaC_gcc-3.2_Linux_i386.tar.gz
+Patch2:  cadna-gcc4.patch
+%endif
+License: GPL
+Group: Applications/Engineering
+URL: http://www.freefem.org/ff++/
+Packager: Christophe  Trophime <christophe.trophime at grenoble.cnrs.fr>
+Prereq: /sbin/install-info
+Buildroot: %{_tmppath}/%{name}-buildroot
+Requires: arpack, ufsparse
+BuildRequires: arpack-devel, ufsparse-devel
+BuildRequires: fltk >= 1.1
+BuildRequires: fltk >= 1.1
+BuildRequires: gsl >= 1.2
+BuildRequires: rpm >= 4.1
+%if %{?_with_mpi:1}%{!?_with_mpi:0} 
+BuildRequires: lam
+%endif
+%{!?_without_freedesktop:BuildRequires: desktop-file-utils}
+Requires: mesa-libGL >= 6.7.0-9
+Requires: mesa-libGLU >= 6.7.0-9
+Requires: gsl >= 1.2
+Requires: fltk >= 1.1
+Prefix: /usr
+
+%description 
+FreeFem++ is an implementation of a language dedicated to the finite element method. 
+It enables you to solve Partial Differential Equations (PDE) easily.
+
+Problems involving PDE from several branches of physics such as fluid-structure interactions 
+require interpolations of data on several meshes and their manipulation within one program. 
+FreeFem++ includes a fast quadtree-based interpolation algorithm and a language for the manipulation 
+of data on multiple meshes (generated with bamg).
+
+
+
+%prep
+
+%setup -q -n %{name}-%{version}
+%patch -p1 -b .umfpack
+%patch1 -p1 -b .gcc4
+
+%if %{?_with_cadna:1}%{!?_with_cadna:0}
+mkdir -p cadna
+mkdir -p download/cadna
+tar zxvf %{SOURCE2} -C cadna 
+mv cadna/include/cadnafree.h download/cadna
+mv cadna/lib/libcadnafreeC.a download/cadna
+pushd download/cadna/
+ln -sf libcadnafreeC.a libcadnafree.a
+popd
+%patch2 -p1 -b .cadna-gcc4.patch
+%endif
+
+autoreconf -f -i
+
+%build
+%if %{?_with_mpi:1}%{!?_with_mpi:0}
+%configure --with-mpi=lam
+%else
+%configure --without-mpi --with-blas="-L/usr/lib/atlas -lf77blas -lcblas"
+%endif
+make
+
+%install
+rm -rf $RPM_BUILD_ROOT
+
+make install DESTDIR=$RPM_BUILD_ROOT
+
+
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%defattr(-,root,root)
+%{_bindir}/FreeFem++
+%{_bindir}/FreeFem++-cs
+%{_bindir}/FreeFem++-nw
+%{_bindir}/FreeFem++-glx
+%{_bindir}/FreeFem++-ide
+%{_bindir}/FreeFem++-server
+%{_bindir}/FreeFem++-client
+%{_bindir}/bamg
+%{_bindir}/cvmsh2
+%{_bindir}/drawbdmesh
+%if %{?_with_mpi:1}%{!?_with_mpi:0}
+%{_bindir}/FreeFem++-mpi
+%endif
+
diff --git a/src/Algo/Makefile.in b/src/Algo/Makefile.in
index 164296f..a24d1fd 100644
--- a/src/Algo/Makefile.in
+++ b/src/Algo/Makefile.in
@@ -61,7 +61,8 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(top_srcdir)/mkinstalldirs
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/acmacros.m4 \
-	$(top_srcdir)/acoptim.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/acoptim.m4 $(top_srcdir)/acmpi.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -131,11 +132,47 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EIGENOBJ = @EIGENOBJ@
+ENABLE_FFCS = @ENABLE_FFCS@
 EPSTOPDF = @EPSTOPDF@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+FFCS_COMPILE_fflapack = @FFCS_COMPILE_fflapack@
+FFCS_COMPILE_gsl = @FFCS_COMPILE_gsl@
+FFCS_COMPILE_hips = @FFCS_COMPILE_hips@
+FFCS_COMPILE_hypre = @FFCS_COMPILE_hypre@
+FFCS_COMPILE_ipopt = @FFCS_COMPILE_ipopt@
+FFCS_COMPILE_lapack = @FFCS_COMPILE_lapack@
+FFCS_COMPILE_mmg3d = @FFCS_COMPILE_mmg3d@
+FFCS_COMPILE_mshmet = @FFCS_COMPILE_mshmet@
+FFCS_COMPILE_mumps = @FFCS_COMPILE_mumps@
+FFCS_COMPILE_mumps_seq = @FFCS_COMPILE_mumps_seq@
+FFCS_COMPILE_pardiso = @FFCS_COMPILE_pardiso@
+FFCS_COMPILE_parms = @FFCS_COMPILE_parms@
+FFCS_COMPILE_pastix = @FFCS_COMPILE_pastix@
+FFCS_COMPILE_pipe = @FFCS_COMPILE_pipe@
+FFCS_COMPILE_scotch = @FFCS_COMPILE_scotch@
+FFCS_COMPILE_superludist = @FFCS_COMPILE_superludist@
+FFCS_COMPILE_yams = @FFCS_COMPILE_yams@
+FFCS_DYLIB_fflapack = @FFCS_DYLIB_fflapack@
+FFCS_DYLIB_gsl = @FFCS_DYLIB_gsl@
+FFCS_DYLIB_hips = @FFCS_DYLIB_hips@
+FFCS_DYLIB_hypre = @FFCS_DYLIB_hypre@
+FFCS_DYLIB_ipopt = @FFCS_DYLIB_ipopt@
+FFCS_DYLIB_lapack = @FFCS_DYLIB_lapack@
+FFCS_DYLIB_mmg3d = @FFCS_DYLIB_mmg3d@
+FFCS_DYLIB_mshmet = @FFCS_DYLIB_mshmet@
+FFCS_DYLIB_mumps = @FFCS_DYLIB_mumps@
+FFCS_DYLIB_mumps_seq = @FFCS_DYLIB_mumps_seq@
+FFCS_DYLIB_pardiso = @FFCS_DYLIB_pardiso@
+FFCS_DYLIB_parms = @FFCS_DYLIB_parms@
+FFCS_DYLIB_pastix = @FFCS_DYLIB_pastix@
+FFCS_DYLIB_pipe = @FFCS_DYLIB_pipe@
+FFCS_DYLIB_scotch = @FFCS_DYLIB_scotch@
+FFCS_DYLIB_superludist = @FFCS_DYLIB_superludist@
+FFCS_DYLIB_yams = @FFCS_DYLIB_yams@
+FFCS_MAKEFLAGS = @FFCS_MAKEFLAGS@
 FFGLUTNAME = @FFGLUTNAME@
 FFGLUTPROG = @FFGLUTPROG@
 FFLAGS = @FFLAGS@
diff --git a/src/Graphics/._ffglut.cpp b/src/Graphics/._ffglut.cpp
new file mode 100644
index 0000000..63e1130
Binary files /dev/null and b/src/Graphics/._ffglut.cpp differ
diff --git a/src/Graphics/._ffglut.hpp b/src/Graphics/._ffglut.hpp
new file mode 100644
index 0000000..14f037e
Binary files /dev/null and b/src/Graphics/._ffglut.hpp differ
diff --git a/src/Graphics/Makefile.am b/src/Graphics/Makefile.am
index 239fd03..5f0353e 100644
--- a/src/Graphics/Makefile.am
+++ b/src/Graphics/Makefile.am
@@ -3,3 +3,9 @@ macrgraf.cpp Pcrgraph.cpp  rgraph.hpp		\
 sansrgraph.cpp xglrgraf.cpp Xrgraph.cpp DefColor.cpp   \
 getprog-unix.hpp mode_open.hpp ffglut.hpp ff-win32.cpp
 
+# FFCS: no compilation here, so the tags file must be built by hand
+tags:TAGS
+TAGS:
+	etags *.?pp
+clean-local::
+	-rm TAGS
diff --git a/src/Graphics/Makefile.in b/src/Graphics/Makefile.in
index 00f8db4..ed077a8 100644
--- a/src/Graphics/Makefile.in
+++ b/src/Graphics/Makefile.in
@@ -54,7 +54,8 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(top_srcdir)/mkinstalldirs
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/acmacros.m4 \
-	$(top_srcdir)/acoptim.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/acoptim.m4 $(top_srcdir)/acmpi.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -124,11 +125,47 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EIGENOBJ = @EIGENOBJ@
+ENABLE_FFCS = @ENABLE_FFCS@
 EPSTOPDF = @EPSTOPDF@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+FFCS_COMPILE_fflapack = @FFCS_COMPILE_fflapack@
+FFCS_COMPILE_gsl = @FFCS_COMPILE_gsl@
+FFCS_COMPILE_hips = @FFCS_COMPILE_hips@
+FFCS_COMPILE_hypre = @FFCS_COMPILE_hypre@
+FFCS_COMPILE_ipopt = @FFCS_COMPILE_ipopt@
+FFCS_COMPILE_lapack = @FFCS_COMPILE_lapack@
+FFCS_COMPILE_mmg3d = @FFCS_COMPILE_mmg3d@
+FFCS_COMPILE_mshmet = @FFCS_COMPILE_mshmet@
+FFCS_COMPILE_mumps = @FFCS_COMPILE_mumps@
+FFCS_COMPILE_mumps_seq = @FFCS_COMPILE_mumps_seq@
+FFCS_COMPILE_pardiso = @FFCS_COMPILE_pardiso@
+FFCS_COMPILE_parms = @FFCS_COMPILE_parms@
+FFCS_COMPILE_pastix = @FFCS_COMPILE_pastix@
+FFCS_COMPILE_pipe = @FFCS_COMPILE_pipe@
+FFCS_COMPILE_scotch = @FFCS_COMPILE_scotch@
+FFCS_COMPILE_superludist = @FFCS_COMPILE_superludist@
+FFCS_COMPILE_yams = @FFCS_COMPILE_yams@
+FFCS_DYLIB_fflapack = @FFCS_DYLIB_fflapack@
+FFCS_DYLIB_gsl = @FFCS_DYLIB_gsl@
+FFCS_DYLIB_hips = @FFCS_DYLIB_hips@
+FFCS_DYLIB_hypre = @FFCS_DYLIB_hypre@
+FFCS_DYLIB_ipopt = @FFCS_DYLIB_ipopt@
+FFCS_DYLIB_lapack = @FFCS_DYLIB_lapack@
+FFCS_DYLIB_mmg3d = @FFCS_DYLIB_mmg3d@
+FFCS_DYLIB_mshmet = @FFCS_DYLIB_mshmet@
+FFCS_DYLIB_mumps = @FFCS_DYLIB_mumps@
+FFCS_DYLIB_mumps_seq = @FFCS_DYLIB_mumps_seq@
+FFCS_DYLIB_pardiso = @FFCS_DYLIB_pardiso@
+FFCS_DYLIB_parms = @FFCS_DYLIB_parms@
+FFCS_DYLIB_pastix = @FFCS_DYLIB_pastix@
+FFCS_DYLIB_pipe = @FFCS_DYLIB_pipe@
+FFCS_DYLIB_scotch = @FFCS_DYLIB_scotch@
+FFCS_DYLIB_superludist = @FFCS_DYLIB_superludist@
+FFCS_DYLIB_yams = @FFCS_DYLIB_yams@
+FFCS_MAKEFLAGS = @FFCS_MAKEFLAGS@
 FFGLUTNAME = @FFGLUTNAME@
 FFGLUTPROG = @FFGLUTPROG@
 FFLAGS = @FFLAGS@
@@ -406,7 +443,7 @@ maintainer-clean-generic:
 	@echo "it deletes files that may require special tools to rebuild."
 clean: clean-am
 
-clean-am: clean-generic mostlyclean-am
+clean-am: clean-generic clean-local mostlyclean-am
 
 distclean: distclean-am
 	-rm -f Makefile
@@ -472,18 +509,25 @@ uninstall-am:
 
 .MAKE: install-am install-strip
 
-.PHONY: all all-am check check-am clean clean-generic cscopelist-am \
-	ctags-am distclean distclean-generic distdir dvi dvi-am html \
-	html-am info info-am install install-am install-data \
-	install-data-am install-dvi install-dvi-am install-exec \
-	install-exec-am install-html install-html-am install-info \
-	install-info-am install-man install-pdf install-pdf-am \
-	install-ps install-ps-am install-strip installcheck \
-	installcheck-am installdirs maintainer-clean \
+.PHONY: all all-am check check-am clean clean-generic clean-local \
+	cscopelist-am ctags-am distclean distclean-generic distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-man install-pdf \
+	install-pdf-am install-ps install-ps-am install-strip \
+	installcheck installcheck-am installdirs maintainer-clean \
 	maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
 	pdf-am ps ps-am tags-am uninstall uninstall-am
 
 
+# FFCS: no compilation here, so the tags file must be built by hand
+tags:TAGS
+TAGS:
+	etags *.?pp
+clean-local::
+	-rm TAGS
+
 # 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.
 .NOEXPORT:
diff --git a/src/Graphics/ffglut.cpp b/src/Graphics/ffglut.cpp
index feb5792..8a59465 100644
--- a/src/Graphics/ffglut.cpp
+++ b/src/Graphics/ffglut.cpp
@@ -19,6 +19,7 @@ using namespace std;
 #include <list>
 #include <map>
 #include <utility>
+#include <unistd.h>
 
 #include "rgraph.hpp"
 #include "fem.hpp"
@@ -42,6 +43,7 @@ using namespace std;
 
 int debug=1;
 int casemouse=0,keyact=0;
+double gwait=0;//  no wait in second
 #include "ffglut.hpp"
 
 #include "ffthreads.hpp"
@@ -136,7 +138,7 @@ int   ReadOnePlot(FILE *fp)
       assert(nextPlot==0);
       nextPlot = new ThePlot(f,currentPlot,++kread);
 	if(debug>1)	
-      cout << " next is build " << nextPlot<< " wait :" << nextPlot->wait << " -> " << kread <<  endl;
+      cout << " next is build " << nextPlot<< " wait :" << nextPlot->wait << " -> " << kread <<  " gwait = " << gwait << endl;
       assert(nextPlot);
       err=0;
     }
@@ -172,6 +174,9 @@ int SendForNextPlot()
   // every 25/ second..  = 1000/25 = 40 ms
   if(NoMorePlot)
     {
+    if(gwait )
+        {usleep((useconds_t)(1e6*gwait)); Fin(0); }
+
     if((debug > 1)) cout << " send signal For Next plot, skip: No More Plot !  " << endl;
     return 0;
     }
@@ -1111,12 +1116,12 @@ void OneWindow::add(ThePlot *p)
 
 void OneWindow::DefaultView(int state)
 {
-  if(debug>1)  cout << "DefaultView " << state << " " <<keepPV << endl;
+  if(debug>1)  cout << "DefaultView " << state << " " <<keepPV << " theplot " << theplot << endl;
   if(keepPV)
    {
       if(state==0 && init) return;
   }
-  else if(state==2) rapz=-1;
+  else /*if(state==2)*/ rapz0=-1;
     
   if(theplot)
     {
@@ -2470,12 +2475,14 @@ void Display(void)
 	  
       }
 
-    if(!win->theplot || !win->theplot->wait)
+    if(!win->theplot || !win->theplot->wait || gwait )
       SendForNextPlot();
+
     if(!NoMorePlotTilte  &&NoMorePlot)
       {
 	NoMorePlotTilte=true;
 	glutSetWindowTitle("FreeFem++ / Program ended; enter ESC to exit)");
+//          if(gwait) {usleep((useconds_t)(1e6*gwait)); Fin(0); }
       }
 }
 
@@ -2773,13 +2780,17 @@ THREADFUNC(ThreadRead,fd)
 {   
   int err=0;
   assert(nextPlot==0);
-  //  MutexNextPlot.WAIT(); 
+  //  MutexNextPlot.WAIT();
+  if(gwait) usleep((useconds_t) (gwait*1.e6) );
   err=ReadOnePlot((FILE*)fd);
   // MutexNextPlot.Free(); 
   if(debug>1)
     cout << " We Read a plot  : " << kread << " " << nextPlot << " " << err << endl;
   if(err<0)
-    NoMorePlot=true; 
+  {
+    NoMorePlot=true;
+
+   }
   Thread::Exit();
 }
 
@@ -2832,9 +2843,56 @@ static  bool TryNewPlot( void )
         LauchNextRead();
         ret=true;
     }
+    if(gwait &&  NoMorePlot )
+    {usleep((useconds_t)(1e6*gwait)); Fin(0); }
+    
     return ret;    
 }
+const char * Index(const char * p, const char c)
+{
+    int k=0;
+    while(k++<1000000)
+        if(!*p) return 0;
+        else if(  *p==c) return p;
+        else ++p;
+    return 0; 
+}
+const char * rIndex(const char * p, const char c)
+{
+    int k=0;
+    const char *pp=0;
+    while(k++<1000000)
+        if(!*p) break;
+        else if(  *p==c) pp= p;
+        else ++p;
+    return pp; 
+}
+void 	SetDefWin(const char *p,int & iii0,int & jjj0,int & Width,int &Height)
+{
+  // syntax 
+  //   1024x1024+100+100
+  // or
+  //  1024x1024 
+  const char  *bx = p;
+  const char *by = Index(p,'x');
+  const char *ox = Index(p,'+');
+  const char *oy = rIndex(p,'+');
+  if(by ==0) return;
+  Width= atoi(bx);
+  Height= atoi(by+1);
+  if(ox && (ox != oy))
+    {
+      iii0= atoi(ox+1);
+      jjj0=atoi(oy+1);
+    }
+  if(debug>1)
+    cout << "  position = "<< Width << "x" << Height << "+"<< iii0 << "+" << jjj0 << endl;
+  assert(Width >0 &&  Width < 3000);
+  assert(Height >0 &&  Height < 3000);
+  assert(iii0 >0 &&  iii0 < 3000);
+  assert(jjj0 >0 &&  jjj0 < 3000);
 
+}
 int main(int argc,  char** argv)
 {
     glutInit(&argc, argv);
@@ -2845,23 +2903,56 @@ int main(int argc,  char** argv)
 	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_STEREO);
     else  
 	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
-
-    if(argc>2) {
-      if( strcmp(argv[1],"-nv")==0) debug=0;
-      if( strcmp(argv[1],"-v")==0) debug=2,verbosity=2;
-      if( strcmp(argv[1],"-vv")==0) debug=5,verbosity=2;
-      if( strcmp(argv[1],"-vvv")==0) debug=10, verbosity=1000;
-    }
-    if(debug>1)		
-    cout <<  " mode read = " << MODE_READ_BINARY << endl;
-    datafile =0;;
-    if(argc>1 && *argv[argc-1] != '-' ) 
-     {	
+     int i1=1;
+     int Height = 512,Width = 512*3/2, iii0=100,jjj0=100;
+     string titre = "W0/FreeFem++: type return key to proceed (or ? for help on other)";
+     int eerr=0; 
+    if(argc>1) 
+      {
+	if( (i1 < argc) &&strcmp(argv[i1],"-?")==0) i1++,eerr=-1; 
+	if (i1 < argc)
+	  {
+	    if( strcmp(argv[i1],"-nv")==0) i1++,debug=0;
+	    else if( strcmp(argv[i1],"-v")==0) i1++,debug=2,verbosity=2;
+	    else if( strcmp(argv[i1],"-vv")==0) i1++,debug=5,verbosity=2;
+	    else if( strcmp(argv[i1],"-vvv")==0) i1++,debug=10, verbosity=1000;
+	  }
+	  if( (i1+1 < argc) && (strcmp(argv[i1],"-wait")==0)) { i1++; gwait=atof(argv[i1++]); }
+	  if( (i1+1 < argc) && (strcmp(argv[i1],"-g")==0)) { 
+	    i1++; 
+	    SetDefWin(argv[i1++], iii0,jjj0,Width,Height);
+	  }
+	  if( (i1+1 < argc) && (strcmp(argv[i1],"-t")==0)) { 
+	    i1++; 
+	    titre = argv[i1++];
+	  }
+	  if( (i1 -  argc > 1) )
+	    { 
+	      eerr = 1;
+	      cout << " error ming args " << i1 -  argc  << endl; 
+	    }
+      }
+    datafile =0;
+    cout << (argc>i1) << eerr << endl; 
+    if(argc>i1 && (eerr==0))// && *argv[argc-1] != '-' )
+      {	
 	datafile=fopen(argv[argc-1], "r");
 	if(debug >1)
-	cout << " fopen :" << argv[argc-1] << " " <<datafile << endl;
-     }
-
+		cout << " fopen :" << argv[argc-1] << " " <<datafile << endl;
+	if(datafile==0)
+	  eerr=100;
+	
+      }
+    if(eerr)
+      {
+	cerr << " Erreur ffglut  [-nv|-v|-vv|-vvv] [-wait 0.5] [-g 512x300+10+10] [-t title] [file]" << endl; 
+	cerr << " err number " << eerr << endl; 
+	abort();
+      }
+    
+    
+    if(debug>1)		
+    cout <<  " mode read = " << MODE_READ_BINARY << endl;
     if(datafile==0)
 	datafile=stdin;
     if ( !datafile){
@@ -2882,13 +2973,10 @@ int main(int argc,  char** argv)
     cout << "on a lue le premier plot next plot: " << nextPlot << endl;
 
 
-    int Height = 512;
-    int Width = 512*3/2; 
     
     glutInitWindowSize(Width , Height);
-    glutInitWindowPosition(100, 100);
+    glutInitWindowPosition(iii0,jjj0);
 
-    string titre = "W0/FreeFem++: type return key to proceed (or ? for help on other)";
     int iw0=glutCreateWindow(titre.c_str());
     //glutPushWindow();
    // if (fullscreen)
diff --git a/src/Graphics/getprog-unix.hpp b/src/Graphics/getprog-unix.hpp
index 839c032..db87e38 100644
--- a/src/Graphics/getprog-unix.hpp
+++ b/src/Graphics/getprog-unix.hpp
@@ -4,6 +4,14 @@
 #else
 #include <unistd.h>
 #endif
+
+// FFCS: required for chdir() when g++ 4.7 is used
+#include <unistd.h>
+
+// FFCS: redirecting visualization output
+#include "../fflib/ffapi.hpp"
+#include <string>
+
 extern long mpirank;
 extern long verbosity;
 extern FILE *ThePlotStream; //  Add for new plot. FH oct 2008
@@ -70,20 +78,13 @@ int getprog(char* fn,int argc, char **argv)
   const char *progffglut=0;
   const char *fileglut=0;
   bool noffglut=false;
-#ifndef NODEFFFGLUT
-  if(argc)
-    {
-      const char *prog =argv[0];
-      const char *pm= strrchr(argv[0],'-');      
-      if( pm )
-        noffglut = ((strlen(prog)- (pm-prog)) < lsuffix+5);
-      else   noffglut==  false;
-      if(noffglut) { consoleatend=false;  waitatend=false;} 
-      //      cout << " noffglut= " << noffglut << endl;
-      //  suffix ++-glx.exe -> no ffglut
-      // pm = 0= > pas de moins -> freefem++ -> ffglut
-    }
-#endif
+
+  // FFCS - remove the test for noffglut to be able to create pictures
+  // in any situation. Even FreeFem++-mpilang needs to send pictures
+  // (eg when called in a FreeFem++-server situation by EJS)
+
+  noffglut=false;
+
   bool ch2edpdir = false;
   if(argc)
     prognamearg=argv[0];
@@ -175,11 +176,9 @@ if( ch2edpdir && edpfilenamearg)
 	int err=0;
 	if(verbosity>1) 
 	    cout << " chdir '" << dir <<"'"<< endl;
-#if WIN32	
-	err=_chdir(dir);
-#else
+	// FFCS: mingw64 API change
 	err=chdir(dir);
-#endif
+
 	//cout << err << endl;
          if(err) {
 	     cerr << " error : chdir  " << dir << endl;
@@ -196,9 +195,15 @@ if( ch2edpdir && edpfilenamearg)
   
   if(progffglut && mpirank==0)
     {
-      ThePlotStream = popen(progffglut,"w");		   
-      if(verbosity)
-	printf(" EXEC of the plot  : %s\n",progffglut);
+      // FFCS: divert stream to FFCS
+      ThePlotStream = ffapi::ff_popen(progffglut,"w");		   
+
+      // FFCS: just forget the following message because it could be understood as an error during FFCS execution
+      // although ffglut is not used there.
+
+      //if(verbosity)
+      //  printf(" EXEC of the plot  : %s\n",progffglut);
+
       if(!ThePlotStream) { cerr << "  Error popen  "<< progffglut << endl;exit(1);}
       
     }
diff --git a/src/Graphics/sansrgraph.cpp b/src/Graphics/sansrgraph.cpp
index e353cd6..e038b59 100644
--- a/src/Graphics/sansrgraph.cpp
+++ b/src/Graphics/sansrgraph.cpp
@@ -601,7 +601,7 @@ void openPS(const char *filename )
 
   const char *fps (filename?filename:ffff);
 
-  
+
   psfile=fopen(fps,"w");
   if(psfile) {
     psfile_save=psfile;
diff --git a/src/Makefile.in b/src/Makefile.in
index 3328f3c..f6137c5 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -58,7 +58,8 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(top_srcdir)/mkinstalldirs depcomp
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/acmacros.m4 \
-	$(top_srcdir)/acoptim.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/acoptim.m4 $(top_srcdir)/acmpi.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -188,11 +189,47 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EIGENOBJ = @EIGENOBJ@
+ENABLE_FFCS = @ENABLE_FFCS@
 EPSTOPDF = @EPSTOPDF@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+FFCS_COMPILE_fflapack = @FFCS_COMPILE_fflapack@
+FFCS_COMPILE_gsl = @FFCS_COMPILE_gsl@
+FFCS_COMPILE_hips = @FFCS_COMPILE_hips@
+FFCS_COMPILE_hypre = @FFCS_COMPILE_hypre@
+FFCS_COMPILE_ipopt = @FFCS_COMPILE_ipopt@
+FFCS_COMPILE_lapack = @FFCS_COMPILE_lapack@
+FFCS_COMPILE_mmg3d = @FFCS_COMPILE_mmg3d@
+FFCS_COMPILE_mshmet = @FFCS_COMPILE_mshmet@
+FFCS_COMPILE_mumps = @FFCS_COMPILE_mumps@
+FFCS_COMPILE_mumps_seq = @FFCS_COMPILE_mumps_seq@
+FFCS_COMPILE_pardiso = @FFCS_COMPILE_pardiso@
+FFCS_COMPILE_parms = @FFCS_COMPILE_parms@
+FFCS_COMPILE_pastix = @FFCS_COMPILE_pastix@
+FFCS_COMPILE_pipe = @FFCS_COMPILE_pipe@
+FFCS_COMPILE_scotch = @FFCS_COMPILE_scotch@
+FFCS_COMPILE_superludist = @FFCS_COMPILE_superludist@
+FFCS_COMPILE_yams = @FFCS_COMPILE_yams@
+FFCS_DYLIB_fflapack = @FFCS_DYLIB_fflapack@
+FFCS_DYLIB_gsl = @FFCS_DYLIB_gsl@
+FFCS_DYLIB_hips = @FFCS_DYLIB_hips@
+FFCS_DYLIB_hypre = @FFCS_DYLIB_hypre@
+FFCS_DYLIB_ipopt = @FFCS_DYLIB_ipopt@
+FFCS_DYLIB_lapack = @FFCS_DYLIB_lapack@
+FFCS_DYLIB_mmg3d = @FFCS_DYLIB_mmg3d@
+FFCS_DYLIB_mshmet = @FFCS_DYLIB_mshmet@
+FFCS_DYLIB_mumps = @FFCS_DYLIB_mumps@
+FFCS_DYLIB_mumps_seq = @FFCS_DYLIB_mumps_seq@
+FFCS_DYLIB_pardiso = @FFCS_DYLIB_pardiso@
+FFCS_DYLIB_parms = @FFCS_DYLIB_parms@
+FFCS_DYLIB_pastix = @FFCS_DYLIB_pastix@
+FFCS_DYLIB_pipe = @FFCS_DYLIB_pipe@
+FFCS_DYLIB_scotch = @FFCS_DYLIB_scotch@
+FFCS_DYLIB_superludist = @FFCS_DYLIB_superludist@
+FFCS_DYLIB_yams = @FFCS_DYLIB_yams@
+FFCS_MAKEFLAGS = @FFCS_MAKEFLAGS@
 FFGLUTNAME = @FFGLUTNAME@
 FFGLUTPROG = @FFGLUTPROG@
 FFLAGS = @FFLAGS@
diff --git a/src/bamg/Makefile.in b/src/bamg/Makefile.in
index 882cc9d..bfa4ec6 100644
--- a/src/bamg/Makefile.in
+++ b/src/bamg/Makefile.in
@@ -56,7 +56,8 @@ 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)/acmacros.m4 \
-	$(top_srcdir)/acoptim.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/acoptim.m4 $(top_srcdir)/acmpi.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -168,11 +169,47 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EIGENOBJ = @EIGENOBJ@
+ENABLE_FFCS = @ENABLE_FFCS@
 EPSTOPDF = @EPSTOPDF@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+FFCS_COMPILE_fflapack = @FFCS_COMPILE_fflapack@
+FFCS_COMPILE_gsl = @FFCS_COMPILE_gsl@
+FFCS_COMPILE_hips = @FFCS_COMPILE_hips@
+FFCS_COMPILE_hypre = @FFCS_COMPILE_hypre@
+FFCS_COMPILE_ipopt = @FFCS_COMPILE_ipopt@
+FFCS_COMPILE_lapack = @FFCS_COMPILE_lapack@
+FFCS_COMPILE_mmg3d = @FFCS_COMPILE_mmg3d@
+FFCS_COMPILE_mshmet = @FFCS_COMPILE_mshmet@
+FFCS_COMPILE_mumps = @FFCS_COMPILE_mumps@
+FFCS_COMPILE_mumps_seq = @FFCS_COMPILE_mumps_seq@
+FFCS_COMPILE_pardiso = @FFCS_COMPILE_pardiso@
+FFCS_COMPILE_parms = @FFCS_COMPILE_parms@
+FFCS_COMPILE_pastix = @FFCS_COMPILE_pastix@
+FFCS_COMPILE_pipe = @FFCS_COMPILE_pipe@
+FFCS_COMPILE_scotch = @FFCS_COMPILE_scotch@
+FFCS_COMPILE_superludist = @FFCS_COMPILE_superludist@
+FFCS_COMPILE_yams = @FFCS_COMPILE_yams@
+FFCS_DYLIB_fflapack = @FFCS_DYLIB_fflapack@
+FFCS_DYLIB_gsl = @FFCS_DYLIB_gsl@
+FFCS_DYLIB_hips = @FFCS_DYLIB_hips@
+FFCS_DYLIB_hypre = @FFCS_DYLIB_hypre@
+FFCS_DYLIB_ipopt = @FFCS_DYLIB_ipopt@
+FFCS_DYLIB_lapack = @FFCS_DYLIB_lapack@
+FFCS_DYLIB_mmg3d = @FFCS_DYLIB_mmg3d@
+FFCS_DYLIB_mshmet = @FFCS_DYLIB_mshmet@
+FFCS_DYLIB_mumps = @FFCS_DYLIB_mumps@
+FFCS_DYLIB_mumps_seq = @FFCS_DYLIB_mumps_seq@
+FFCS_DYLIB_pardiso = @FFCS_DYLIB_pardiso@
+FFCS_DYLIB_parms = @FFCS_DYLIB_parms@
+FFCS_DYLIB_pastix = @FFCS_DYLIB_pastix@
+FFCS_DYLIB_pipe = @FFCS_DYLIB_pipe@
+FFCS_DYLIB_scotch = @FFCS_DYLIB_scotch@
+FFCS_DYLIB_superludist = @FFCS_DYLIB_superludist@
+FFCS_DYLIB_yams = @FFCS_DYLIB_yams@
+FFCS_MAKEFLAGS = @FFCS_MAKEFLAGS@
 FFGLUTNAME = @FFGLUTNAME@
 FFGLUTPROG = @FFGLUTPROG@
 FFLAGS = @FFLAGS@
diff --git a/src/bamglib/._Mesh2.h b/src/bamglib/._Mesh2.h
new file mode 100644
index 0000000..14f037e
Binary files /dev/null and b/src/bamglib/._Mesh2.h differ
diff --git a/src/bamglib/._MeshGeom.cpp b/src/bamglib/._MeshGeom.cpp
new file mode 100644
index 0000000..63e1130
Binary files /dev/null and b/src/bamglib/._MeshGeom.cpp differ
diff --git a/src/bamglib/Makefile.in b/src/bamglib/Makefile.in
index 50f8e95..820b402 100644
--- a/src/bamglib/Makefile.in
+++ b/src/bamglib/Makefile.in
@@ -61,7 +61,8 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(top_srcdir)/mkinstalldirs
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/acmacros.m4 \
-	$(top_srcdir)/acoptim.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/acoptim.m4 $(top_srcdir)/acmpi.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -131,11 +132,47 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EIGENOBJ = @EIGENOBJ@
+ENABLE_FFCS = @ENABLE_FFCS@
 EPSTOPDF = @EPSTOPDF@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+FFCS_COMPILE_fflapack = @FFCS_COMPILE_fflapack@
+FFCS_COMPILE_gsl = @FFCS_COMPILE_gsl@
+FFCS_COMPILE_hips = @FFCS_COMPILE_hips@
+FFCS_COMPILE_hypre = @FFCS_COMPILE_hypre@
+FFCS_COMPILE_ipopt = @FFCS_COMPILE_ipopt@
+FFCS_COMPILE_lapack = @FFCS_COMPILE_lapack@
+FFCS_COMPILE_mmg3d = @FFCS_COMPILE_mmg3d@
+FFCS_COMPILE_mshmet = @FFCS_COMPILE_mshmet@
+FFCS_COMPILE_mumps = @FFCS_COMPILE_mumps@
+FFCS_COMPILE_mumps_seq = @FFCS_COMPILE_mumps_seq@
+FFCS_COMPILE_pardiso = @FFCS_COMPILE_pardiso@
+FFCS_COMPILE_parms = @FFCS_COMPILE_parms@
+FFCS_COMPILE_pastix = @FFCS_COMPILE_pastix@
+FFCS_COMPILE_pipe = @FFCS_COMPILE_pipe@
+FFCS_COMPILE_scotch = @FFCS_COMPILE_scotch@
+FFCS_COMPILE_superludist = @FFCS_COMPILE_superludist@
+FFCS_COMPILE_yams = @FFCS_COMPILE_yams@
+FFCS_DYLIB_fflapack = @FFCS_DYLIB_fflapack@
+FFCS_DYLIB_gsl = @FFCS_DYLIB_gsl@
+FFCS_DYLIB_hips = @FFCS_DYLIB_hips@
+FFCS_DYLIB_hypre = @FFCS_DYLIB_hypre@
+FFCS_DYLIB_ipopt = @FFCS_DYLIB_ipopt@
+FFCS_DYLIB_lapack = @FFCS_DYLIB_lapack@
+FFCS_DYLIB_mmg3d = @FFCS_DYLIB_mmg3d@
+FFCS_DYLIB_mshmet = @FFCS_DYLIB_mshmet@
+FFCS_DYLIB_mumps = @FFCS_DYLIB_mumps@
+FFCS_DYLIB_mumps_seq = @FFCS_DYLIB_mumps_seq@
+FFCS_DYLIB_pardiso = @FFCS_DYLIB_pardiso@
+FFCS_DYLIB_parms = @FFCS_DYLIB_parms@
+FFCS_DYLIB_pastix = @FFCS_DYLIB_pastix@
+FFCS_DYLIB_pipe = @FFCS_DYLIB_pipe@
+FFCS_DYLIB_scotch = @FFCS_DYLIB_scotch@
+FFCS_DYLIB_superludist = @FFCS_DYLIB_superludist@
+FFCS_DYLIB_yams = @FFCS_DYLIB_yams@
+FFCS_MAKEFLAGS = @FFCS_MAKEFLAGS@
 FFGLUTNAME = @FFGLUTNAME@
 FFGLUTPROG = @FFGLUTPROG@
 FFLAGS = @FFLAGS@
diff --git a/src/bamglib/Mesh2.h b/src/bamglib/Mesh2.h
index 4a7617f..315969a 100644
--- a/src/bamglib/Mesh2.h
+++ b/src/bamglib/Mesh2.h
@@ -1153,11 +1153,12 @@ inline void VertexOnGeom::Set(const VertexOnGeom & rec,const Triangles & Th ,Tri
   *this = rec;  
   mv = ThNew.vertices + Th.Number(mv);
   if (gv)
+  {
     if (abscisse < 0 )
       gv = ThNew.Gh.vertices + Th.Gh.Number(gv);
     else
       ge = ThNew.Gh.edges + Th.Gh.Number(ge);
-  
+  }
 }
 inline Real8 Edge::MetricLength() const
   { 
diff --git a/src/bin-win32/Makefile.am b/src/bin-win32/Makefile.am
index 0ce1387..ed00559 100755
--- a/src/bin-win32/Makefile.am
+++ b/src/bin-win32/Makefile.am
@@ -14,7 +14,7 @@ FF_OBJ0 = CodeAlloc.o AFunction2.o  CheckPtr.o lex.o  global.o environment.o loa
 FF_OBJ_AC = array_complex.o
 FF_OBJ_AR = array_real.o
 FF_OBJ_AL = array_long.o
-FF_OBJ1 = AFunction.o   InitFunct.o strversionnumber.o  mt19937ar.o string_def.o ffapi.o 
+FF_OBJ1 = AFunction.o   InitFunct.o strversionnumber.o  mt19937ar.o string_def.o 
 FF_OBJ2 = BamgFreeFem.o  Drawing.o Element_P2h.o Element_RT.o FESpace.o FQuadTree.o InitFunct.o Mesh2.o MeshDraw.o MeshGeom.o MeshQuad.o MeshRead.o MeshWrite.o Meshio.o Metric.o QuadTree.o QuadratureFormular.o R2.o SetOfE4.o eigenvalue.o fem.o gibbs.o  lgalgo.o lgfem.o lgmat.o lgmesh.o  mshptg.o problem.o DefColor.o lgmesh3.o  P012_2d.o P012_3d.o  FESpacen.o ../libMesh/chrono.o  ../libMesh/libmesh3.o  ../libMesh/memory.o ../libMesh/eigenv.o  ../libMesh/libmesh5.o  Mesh1dn.o Mesh2dn.o Mes [...]
 FF_OBJIDE = FreeFem___cs-cs.o FreeFem___cs-commands.o FreeFem___cs-draw.o FreeFem___cs-strversionnumber.o FreeFem___cs-socket.o FreeFem___cs-threads.o FreeFem___cs-hl_yacc.o FreeFem___cs-hl_lex.o FreeFem___cs-highlight.o FreeFem___cs-spawn.o FreeFem___cs-editor.o FreeFem___cs-server.o    windres.o
 
@@ -27,7 +27,7 @@ FFD_OBJ2 = $(patsubst %.o,../fflib/%.o,$(FF_OBJ2))
 FFD_OBJIDE = $(patsubst %.o,../ide/%.o,$(FF_OBJIDE))
 FFD_OBJLMSH = $(patsubst %.o,../ide/%.o,$(FF_OBJLMSH))
 
-LIBS_FF = libff.dll  
+LIBS_FF = libff.dll FreeFem++-api.dll
 
 
 
@@ -38,7 +38,8 @@ all-local: $(WIN32DLLTARGET)
 win32-dll-target: FreeFem++.exe FreeFem++-nw.exe  bamg.exe cvmsh2.exe  launchff++.exe ff-c++ $(MPIPROG)
 	echo "on a fini"
 
-libff.dll: $(FFD_OBJ0)  $(FFD_OBJ_AR)  $(FFD_OBJ_AC)  $(FFD_OBJ_AL)  $(FFD_OBJ1) $(FFD_OBJ2) ../lglib/lg.tab.o
+libff.dll: $(FFD_OBJ0) $(FFD_OBJ_AR) $(FFD_OBJ_AC) $(FFD_OBJ_AL) $(FFD_OBJ1) $(FFD_OBJ2) ../lglib/lg.tab.o	\
+		FreeFem++-api.dll
 	$(CXX) $(GCCNOCYGWIN)  -shared  -Wl,--enable-auto-import $^  -o $@ $(LDADD2)
 
 
@@ -47,7 +48,7 @@ FreeFem++-nw.exe: ../nw/sansrgraph.o ../nw/parallelempi-empty.o ../lglib/mymain.
 FreeFem++.exe: ../nw/sansrgraph.o    ../nw/parallelempi-empty.o ../lglib/mymain.o $(LIBS_FF)
 	$(CXX)   $(GCCNOCYGWIN) libff.dll $^ -o $@  -lcomdlg32
 FreeFem++-mpi.exe:	../nw/sansrgraph.o ../mpi/parallelempi.o   ../lglib/mymain.o $(LIBS_FF)
-	$(CXX)   $(GCCNOCYGWIN) libff.dll $^ -o $@  -lcomdlg32 $(MPI_LIB)
+	$(MPICXX)   $(GCCNOCYGWIN) libff.dll $^ -o $@  -lcomdlg32 $(MPI_LIB)
 bamg.exe:  libff.dll $(LIBS_FF)
 	$(CXX)   $(GCCNOCYGWIN) ../bamg/bamg.o  -Wl,--enable-auto-import $^ -o $@ 
 cvmsh2.exe:  $(LIBS_FF)
@@ -68,3 +69,10 @@ install-exec-local--win32-dll-target::
 install-exec-local--::
 
 
+# FFCS: create a separate DLL for ffapi so that it can be changed when running FreeFem++ or FFCS
+FreeFem++-api.dll:../nw/ffapi.o
+	$(CXX) $(GCCNOCYGWIN) -shared -Wl,--enable-auto-import $< -o $@
+
+# FFCS: automake does not clean the exes automatically because they are not built automatically.
+clean-local::
+	-rm *.exe
diff --git a/src/bin-win32/Makefile.in b/src/bin-win32/Makefile.in
index fa2f842..4ce39e9 100644
--- a/src/bin-win32/Makefile.in
+++ b/src/bin-win32/Makefile.in
@@ -54,7 +54,8 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(top_srcdir)/mkinstalldirs
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/acmacros.m4 \
-	$(top_srcdir)/acoptim.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/acoptim.m4 $(top_srcdir)/acmpi.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -124,11 +125,47 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EIGENOBJ = @EIGENOBJ@
+ENABLE_FFCS = @ENABLE_FFCS@
 EPSTOPDF = @EPSTOPDF@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+FFCS_COMPILE_fflapack = @FFCS_COMPILE_fflapack@
+FFCS_COMPILE_gsl = @FFCS_COMPILE_gsl@
+FFCS_COMPILE_hips = @FFCS_COMPILE_hips@
+FFCS_COMPILE_hypre = @FFCS_COMPILE_hypre@
+FFCS_COMPILE_ipopt = @FFCS_COMPILE_ipopt@
+FFCS_COMPILE_lapack = @FFCS_COMPILE_lapack@
+FFCS_COMPILE_mmg3d = @FFCS_COMPILE_mmg3d@
+FFCS_COMPILE_mshmet = @FFCS_COMPILE_mshmet@
+FFCS_COMPILE_mumps = @FFCS_COMPILE_mumps@
+FFCS_COMPILE_mumps_seq = @FFCS_COMPILE_mumps_seq@
+FFCS_COMPILE_pardiso = @FFCS_COMPILE_pardiso@
+FFCS_COMPILE_parms = @FFCS_COMPILE_parms@
+FFCS_COMPILE_pastix = @FFCS_COMPILE_pastix@
+FFCS_COMPILE_pipe = @FFCS_COMPILE_pipe@
+FFCS_COMPILE_scotch = @FFCS_COMPILE_scotch@
+FFCS_COMPILE_superludist = @FFCS_COMPILE_superludist@
+FFCS_COMPILE_yams = @FFCS_COMPILE_yams@
+FFCS_DYLIB_fflapack = @FFCS_DYLIB_fflapack@
+FFCS_DYLIB_gsl = @FFCS_DYLIB_gsl@
+FFCS_DYLIB_hips = @FFCS_DYLIB_hips@
+FFCS_DYLIB_hypre = @FFCS_DYLIB_hypre@
+FFCS_DYLIB_ipopt = @FFCS_DYLIB_ipopt@
+FFCS_DYLIB_lapack = @FFCS_DYLIB_lapack@
+FFCS_DYLIB_mmg3d = @FFCS_DYLIB_mmg3d@
+FFCS_DYLIB_mshmet = @FFCS_DYLIB_mshmet@
+FFCS_DYLIB_mumps = @FFCS_DYLIB_mumps@
+FFCS_DYLIB_mumps_seq = @FFCS_DYLIB_mumps_seq@
+FFCS_DYLIB_pardiso = @FFCS_DYLIB_pardiso@
+FFCS_DYLIB_parms = @FFCS_DYLIB_parms@
+FFCS_DYLIB_pastix = @FFCS_DYLIB_pastix@
+FFCS_DYLIB_pipe = @FFCS_DYLIB_pipe@
+FFCS_DYLIB_scotch = @FFCS_DYLIB_scotch@
+FFCS_DYLIB_superludist = @FFCS_DYLIB_superludist@
+FFCS_DYLIB_yams = @FFCS_DYLIB_yams@
+FFCS_MAKEFLAGS = @FFCS_MAKEFLAGS@
 FFGLUTNAME = @FFGLUTNAME@
 FFGLUTPROG = @FFGLUTPROG@
 FFLAGS = @FFLAGS@
@@ -310,7 +347,7 @@ FF_OBJ0 = CodeAlloc.o AFunction2.o  CheckPtr.o lex.o  global.o environment.o loa
 FF_OBJ_AC = array_complex.o
 FF_OBJ_AR = array_real.o
 FF_OBJ_AL = array_long.o
-FF_OBJ1 = AFunction.o   InitFunct.o strversionnumber.o  mt19937ar.o string_def.o ffapi.o 
+FF_OBJ1 = AFunction.o   InitFunct.o strversionnumber.o  mt19937ar.o string_def.o 
 FF_OBJ2 = BamgFreeFem.o  Drawing.o Element_P2h.o Element_RT.o FESpace.o FQuadTree.o InitFunct.o Mesh2.o MeshDraw.o MeshGeom.o MeshQuad.o MeshRead.o MeshWrite.o Meshio.o Metric.o QuadTree.o QuadratureFormular.o R2.o SetOfE4.o eigenvalue.o fem.o gibbs.o  lgalgo.o lgfem.o lgmat.o lgmesh.o  mshptg.o problem.o DefColor.o lgmesh3.o  P012_2d.o P012_3d.o  FESpacen.o ../libMesh/chrono.o  ../libMesh/libmesh3.o  ../libMesh/memory.o ../libMesh/eigenv.o  ../libMesh/libmesh5.o  Mesh1dn.o Mesh2dn.o Mes [...]
 FF_OBJIDE = FreeFem___cs-cs.o FreeFem___cs-commands.o FreeFem___cs-draw.o FreeFem___cs-strversionnumber.o FreeFem___cs-socket.o FreeFem___cs-threads.o FreeFem___cs-hl_yacc.o FreeFem___cs-hl_lex.o FreeFem___cs-highlight.o FreeFem___cs-spawn.o FreeFem___cs-editor.o FreeFem___cs-server.o    windres.o
 FFD_OBJ0 = $(patsubst %.o,../fflib/%.o,$(FF_OBJ0))
@@ -321,7 +358,7 @@ FFD_OBJ1 = $(patsubst %.o,../fflib/%.o,$(FF_OBJ1))
 FFD_OBJ2 = $(patsubst %.o,../fflib/%.o,$(FF_OBJ2))
 FFD_OBJIDE = $(patsubst %.o,../ide/%.o,$(FF_OBJIDE))
 FFD_OBJLMSH = $(patsubst %.o,../ide/%.o,$(FF_OBJLMSH))
-LIBS_FF = libff.dll  
+LIBS_FF = libff.dll FreeFem++-api.dll
 all: all-am
 
 .SUFFIXES:
@@ -428,7 +465,7 @@ maintainer-clean-generic:
 	@echo "it deletes files that may require special tools to rebuild."
 clean: clean-am
 
-clean-am: clean-generic mostlyclean-am
+clean-am: clean-generic clean-local mostlyclean-am
 
 distclean: distclean-am
 	-rm -f Makefile
@@ -495,16 +532,16 @@ uninstall-am:
 .MAKE: install-am install-strip
 
 .PHONY: all all-am all-local check check-am clean clean-generic \
-	cscopelist-am ctags-am distclean distclean-generic distdir dvi \
-	dvi-am html html-am info info-am install install-am \
-	install-data install-data-am install-dvi install-dvi-am \
-	install-exec install-exec-am install-exec-local install-html \
-	install-html-am install-info install-info-am install-man \
-	install-pdf install-pdf-am install-ps install-ps-am \
-	install-strip installcheck installcheck-am installdirs \
-	maintainer-clean maintainer-clean-generic mostlyclean \
-	mostlyclean-generic pdf pdf-am ps ps-am tags-am uninstall \
-	uninstall-am
+	clean-local cscopelist-am ctags-am distclean distclean-generic \
+	distdir dvi dvi-am html html-am info info-am install \
+	install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-exec-local \
+	install-html install-html-am install-info install-info-am \
+	install-man install-pdf install-pdf-am install-ps \
+	install-ps-am install-strip installcheck installcheck-am \
+	installdirs maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags-am \
+	uninstall uninstall-am
 
 
 all-local: $(WIN32DLLTARGET) 
@@ -513,7 +550,8 @@ all-local: $(WIN32DLLTARGET)
 win32-dll-target: FreeFem++.exe FreeFem++-nw.exe  bamg.exe cvmsh2.exe  launchff++.exe ff-c++ $(MPIPROG)
 	echo "on a fini"
 
-libff.dll: $(FFD_OBJ0)  $(FFD_OBJ_AR)  $(FFD_OBJ_AC)  $(FFD_OBJ_AL)  $(FFD_OBJ1) $(FFD_OBJ2) ../lglib/lg.tab.o
+libff.dll: $(FFD_OBJ0) $(FFD_OBJ_AR) $(FFD_OBJ_AC) $(FFD_OBJ_AL) $(FFD_OBJ1) $(FFD_OBJ2) ../lglib/lg.tab.o	\
+		FreeFem++-api.dll
 	$(CXX) $(GCCNOCYGWIN)  -shared  -Wl,--enable-auto-import $^  -o $@ $(LDADD2)
 
 FreeFem++-nw.exe: ../nw/sansrgraph.o ../nw/parallelempi-empty.o ../lglib/mymain.o $(LIBS_FF)
@@ -521,7 +559,7 @@ FreeFem++-nw.exe: ../nw/sansrgraph.o ../nw/parallelempi-empty.o ../lglib/mymain.
 FreeFem++.exe: ../nw/sansrgraph.o    ../nw/parallelempi-empty.o ../lglib/mymain.o $(LIBS_FF)
 	$(CXX)   $(GCCNOCYGWIN) libff.dll $^ -o $@  -lcomdlg32
 FreeFem++-mpi.exe:	../nw/sansrgraph.o ../mpi/parallelempi.o   ../lglib/mymain.o $(LIBS_FF)
-	$(CXX)   $(GCCNOCYGWIN) libff.dll $^ -o $@  -lcomdlg32 $(MPI_LIB)
+	$(MPICXX)   $(GCCNOCYGWIN) libff.dll $^ -o $@  -lcomdlg32 $(MPI_LIB)
 bamg.exe:  libff.dll $(LIBS_FF)
 	$(CXX)   $(GCCNOCYGWIN) ../bamg/bamg.o  -Wl,--enable-auto-import $^ -o $@ 
 cvmsh2.exe:  $(LIBS_FF)
@@ -541,6 +579,14 @@ install-exec-local--win32-dll-target::
 	$(INSTALL_SCRIPT) *.dll   $(DESTDIR)${bindir} 
 install-exec-local--::
 
+# FFCS: create a separate DLL for ffapi so that it can be changed when running FreeFem++ or FFCS
+FreeFem++-api.dll:../nw/ffapi.o
+	$(CXX) $(GCCNOCYGWIN) -shared -Wl,--enable-auto-import $< -o $@
+
+# FFCS: automake does not clean the exes automatically because they are not built automatically.
+clean-local::
+	-rm *.exe
+
 # 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.
 .NOEXPORT:
diff --git a/src/femlib/._CheckPtr.cpp b/src/femlib/._CheckPtr.cpp
new file mode 100644
index 0000000..63e1130
Binary files /dev/null and b/src/femlib/._CheckPtr.cpp differ
diff --git a/src/femlib/._FESpace.cpp b/src/femlib/._FESpace.cpp
new file mode 100644
index 0000000..63e1130
Binary files /dev/null and b/src/femlib/._FESpace.cpp differ
diff --git a/src/femlib/._FESpacen.cpp b/src/femlib/._FESpacen.cpp
new file mode 100644
index 0000000..e9604e8
Binary files /dev/null and b/src/femlib/._FESpacen.cpp differ
diff --git a/src/femlib/._GQuadTree.cpp b/src/femlib/._GQuadTree.cpp
new file mode 100644
index 0000000..e9604e8
Binary files /dev/null and b/src/femlib/._GQuadTree.cpp differ
diff --git a/src/femlib/._GenericMesh.hpp b/src/femlib/._GenericMesh.hpp
new file mode 100644
index 0000000..63e1130
Binary files /dev/null and b/src/femlib/._GenericMesh.hpp differ
diff --git a/src/femlib/._MatriceCreuse.hpp b/src/femlib/._MatriceCreuse.hpp
new file mode 100644
index 0000000..14f037e
Binary files /dev/null and b/src/femlib/._MatriceCreuse.hpp differ
diff --git a/src/femlib/._MatriceCreuse_tpl.hpp b/src/femlib/._MatriceCreuse_tpl.hpp
new file mode 100644
index 0000000..14f037e
Binary files /dev/null and b/src/femlib/._MatriceCreuse_tpl.hpp differ
diff --git a/src/femlib/._MeshPoint.hpp b/src/femlib/._MeshPoint.hpp
new file mode 100644
index 0000000..14f037e
Binary files /dev/null and b/src/femlib/._MeshPoint.hpp differ
diff --git a/src/femlib/._P012_2d.cpp b/src/femlib/._P012_2d.cpp
new file mode 100644
index 0000000..e9604e8
Binary files /dev/null and b/src/femlib/._P012_2d.cpp differ
diff --git a/src/femlib/._PkLagrange.hpp b/src/femlib/._PkLagrange.hpp
new file mode 100644
index 0000000..e9604e8
Binary files /dev/null and b/src/femlib/._PkLagrange.hpp differ
diff --git a/src/femlib/._RNM.hpp b/src/femlib/._RNM.hpp
new file mode 100644
index 0000000..e9604e8
Binary files /dev/null and b/src/femlib/._RNM.hpp differ
diff --git a/src/femlib/._RNM_op.hpp b/src/femlib/._RNM_op.hpp
new file mode 100644
index 0000000..14f037e
Binary files /dev/null and b/src/femlib/._RNM_op.hpp differ
diff --git a/src/femlib/._RNM_opc.hpp b/src/femlib/._RNM_opc.hpp
new file mode 100644
index 0000000..14f037e
Binary files /dev/null and b/src/femlib/._RNM_opc.hpp differ
diff --git a/src/femlib/FQuadTree.cpp b/src/femlib/FQuadTree.cpp
index a933327..eb186dc 100644
--- a/src/femlib/FQuadTree.cpp
+++ b/src/femlib/FQuadTree.cpp
@@ -550,7 +550,7 @@ Vertex *  FQuadTree::NearestVertexWithNormal(const R2 &P)//(long xi,long yj)
 	     NbVerticesSearch++;
 	     I2 i2 =  R2ToI2(v);
 	     // if good sens when try -- 
-	     h0 = h0 = I2(i2,plus).norm();//  NORM(iplus,i2.x,jplus,i2.y);
+	     h0 = I2(i2,plus).norm();//  NORM(iplus,i2.x,jplus,i2.y);
 	     if (h0 <h) 
 	      {
 		   h = h0;
diff --git a/src/femlib/Makefile.in b/src/femlib/Makefile.in
index a2de6d1..0d36ebb 100644
--- a/src/femlib/Makefile.in
+++ b/src/femlib/Makefile.in
@@ -61,7 +61,8 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(top_srcdir)/mkinstalldirs
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/acmacros.m4 \
-	$(top_srcdir)/acoptim.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/acoptim.m4 $(top_srcdir)/acmpi.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -131,11 +132,47 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EIGENOBJ = @EIGENOBJ@
+ENABLE_FFCS = @ENABLE_FFCS@
 EPSTOPDF = @EPSTOPDF@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+FFCS_COMPILE_fflapack = @FFCS_COMPILE_fflapack@
+FFCS_COMPILE_gsl = @FFCS_COMPILE_gsl@
+FFCS_COMPILE_hips = @FFCS_COMPILE_hips@
+FFCS_COMPILE_hypre = @FFCS_COMPILE_hypre@
+FFCS_COMPILE_ipopt = @FFCS_COMPILE_ipopt@
+FFCS_COMPILE_lapack = @FFCS_COMPILE_lapack@
+FFCS_COMPILE_mmg3d = @FFCS_COMPILE_mmg3d@
+FFCS_COMPILE_mshmet = @FFCS_COMPILE_mshmet@
+FFCS_COMPILE_mumps = @FFCS_COMPILE_mumps@
+FFCS_COMPILE_mumps_seq = @FFCS_COMPILE_mumps_seq@
+FFCS_COMPILE_pardiso = @FFCS_COMPILE_pardiso@
+FFCS_COMPILE_parms = @FFCS_COMPILE_parms@
+FFCS_COMPILE_pastix = @FFCS_COMPILE_pastix@
+FFCS_COMPILE_pipe = @FFCS_COMPILE_pipe@
+FFCS_COMPILE_scotch = @FFCS_COMPILE_scotch@
+FFCS_COMPILE_superludist = @FFCS_COMPILE_superludist@
+FFCS_COMPILE_yams = @FFCS_COMPILE_yams@
+FFCS_DYLIB_fflapack = @FFCS_DYLIB_fflapack@
+FFCS_DYLIB_gsl = @FFCS_DYLIB_gsl@
+FFCS_DYLIB_hips = @FFCS_DYLIB_hips@
+FFCS_DYLIB_hypre = @FFCS_DYLIB_hypre@
+FFCS_DYLIB_ipopt = @FFCS_DYLIB_ipopt@
+FFCS_DYLIB_lapack = @FFCS_DYLIB_lapack@
+FFCS_DYLIB_mmg3d = @FFCS_DYLIB_mmg3d@
+FFCS_DYLIB_mshmet = @FFCS_DYLIB_mshmet@
+FFCS_DYLIB_mumps = @FFCS_DYLIB_mumps@
+FFCS_DYLIB_mumps_seq = @FFCS_DYLIB_mumps_seq@
+FFCS_DYLIB_pardiso = @FFCS_DYLIB_pardiso@
+FFCS_DYLIB_parms = @FFCS_DYLIB_parms@
+FFCS_DYLIB_pastix = @FFCS_DYLIB_pastix@
+FFCS_DYLIB_pipe = @FFCS_DYLIB_pipe@
+FFCS_DYLIB_scotch = @FFCS_DYLIB_scotch@
+FFCS_DYLIB_superludist = @FFCS_DYLIB_superludist@
+FFCS_DYLIB_yams = @FFCS_DYLIB_yams@
+FFCS_MAKEFLAGS = @FFCS_MAKEFLAGS@
 FFGLUTNAME = @FFGLUTNAME@
 FFGLUTPROG = @FFGLUTPROG@
 FFLAGS = @FFLAGS@
diff --git a/src/femlib/MatriceCreuse_tpl.hpp b/src/femlib/MatriceCreuse_tpl.hpp
index 5ff06e1..d522165 100644
--- a/src/femlib/MatriceCreuse_tpl.hpp
+++ b/src/femlib/MatriceCreuse_tpl.hpp
@@ -288,28 +288,31 @@ template<class R>
 template<class R>
 bool MatriceProfile<R>::addMatTo(R coef,std::map< pair<int,int>, R> &mij,bool trans,int ii00,int jj00,bool cnj,double threshold)
 {
-   double eps0=max(numeric_limits<double>::min(), threshold);
- if( norm(coef)<eps0) return  L == U ;
- int i,j,kf,k;
-  if(D)
-   for( i=0;i<this->n;i++)
-    if( norm(D[i])>eps0)
-     mij[ij_mat(trans,ii00,jj00,i,i)] += coef*(cnj? conj(D[i]) : D[i]);
-   else
-   for(int i=0;i<this->n;i++) // no dia => identity dai
-     mij[ij_mat(trans,ii00,jj00,i,i)] += coef;
-     
- if (L && pL )    
-   for (kf=pL[0],i=0;  i<this->n;   i++  )  
-     for ( k=kf,kf=pL[i+1], j=i-kf+k;   k<kf; j++,  k++  )
-        if(norm(L[k])>eps0)
-        mij[ij_mat(trans,ii00,jj00,i,j)]= coef*(cnj? conj(L[k]) : L[k]);
- if (U && pU)     
-   for (kf=pU[0],j=0;  j<this->m;  j++)  
-     for (k=kf,kf=pU[j+1], i=j-kf+k;   k<kf; i++,  k++  )
-      if(norm(U[k])>eps0)
-        mij[ij_mat(trans,ii00,jj00,i,j)]= coef*(cnj? conj(U[k]) : U[k]);
- return L == U ; // symetrique               
+    double eps0=max(numeric_limits<double>::min(), threshold);
+    if( norm(coef)<eps0) return  L == U ;
+    int i,j,kf,k;
+    if(D)
+    {
+        for( i=0;i<this->n;i++)
+            if( norm(D[i])>eps0)
+                mij[ij_mat(trans,ii00,jj00,i,i)] += coef*(cnj? conj(D[i]) : D[i]);
+    }
+    else
+    {
+        for(int i=0;i<this->n;i++) // no dia => identity dai
+            mij[ij_mat(trans,ii00,jj00,i,i)] += coef;
+    }
+    if (L && pL )
+        for (kf=pL[0],i=0;  i<this->n;   i++  )
+            for ( k=kf,kf=pL[i+1], j=i-kf+k;   k<kf; j++,  k++  )
+                if(norm(L[k])>eps0)
+                    mij[ij_mat(trans,ii00,jj00,i,j)]= coef*(cnj? conj(L[k]) : L[k]);
+    if (U && pU)
+        for (kf=pU[0],j=0;  j<this->m;  j++)
+            for (k=kf,kf=pU[j+1], i=j-kf+k;   k<kf; i++,  k++  )
+                if(norm(U[k])>eps0)
+                    mij[ij_mat(trans,ii00,jj00,i,j)]= coef*(cnj? conj(U[k]) : U[k]);
+    return L == U ; // symetrique
 }
 template<class R>
 MatriceProfile<R>::MatriceProfile(const int nn,const R *a)
diff --git a/src/fflib/._AFunction.cpp b/src/fflib/._AFunction.cpp
new file mode 100644
index 0000000..14f037e
Binary files /dev/null and b/src/fflib/._AFunction.cpp differ
diff --git a/src/fflib/._Operator.hpp b/src/fflib/._Operator.hpp
new file mode 100644
index 0000000..14f037e
Binary files /dev/null and b/src/fflib/._Operator.hpp differ
diff --git a/src/fflib/._array_long.cpp b/src/fflib/._array_long.cpp
new file mode 100644
index 0000000..e9604e8
Binary files /dev/null and b/src/fflib/._array_long.cpp differ
diff --git a/src/fflib/._array_real.cpp b/src/fflib/._array_real.cpp
new file mode 100644
index 0000000..e9604e8
Binary files /dev/null and b/src/fflib/._array_real.cpp differ
diff --git a/src/fflib/._array_resize.hpp b/src/fflib/._array_resize.hpp
new file mode 100644
index 0000000..14f037e
Binary files /dev/null and b/src/fflib/._array_resize.hpp differ
diff --git a/src/fflib/._array_tlp.hpp b/src/fflib/._array_tlp.hpp
new file mode 100644
index 0000000..14f037e
Binary files /dev/null and b/src/fflib/._array_tlp.hpp differ
diff --git a/src/fflib/._glumesh2D.cpp b/src/fflib/._glumesh2D.cpp
new file mode 100755
index 0000000..e9604e8
Binary files /dev/null and b/src/fflib/._glumesh2D.cpp differ
diff --git a/src/fflib/._lex.cpp b/src/fflib/._lex.cpp
new file mode 100644
index 0000000..e9604e8
Binary files /dev/null and b/src/fflib/._lex.cpp differ
diff --git a/src/fflib/._lgfem.hpp b/src/fflib/._lgfem.hpp
new file mode 100644
index 0000000..14f037e
Binary files /dev/null and b/src/fflib/._lgfem.hpp differ
diff --git a/src/fflib/._lgmesh3.cpp b/src/fflib/._lgmesh3.cpp
new file mode 100644
index 0000000..14f037e
Binary files /dev/null and b/src/fflib/._lgmesh3.cpp differ
diff --git a/src/fflib/._lgsolver.hpp b/src/fflib/._lgsolver.hpp
new file mode 100644
index 0000000..14f037e
Binary files /dev/null and b/src/fflib/._lgsolver.hpp differ
diff --git a/src/fflib/._problem.hpp b/src/fflib/._problem.hpp
new file mode 100644
index 0000000..63e1130
Binary files /dev/null and b/src/fflib/._problem.hpp differ
diff --git a/src/fflib/AFunction.cpp b/src/fflib/AFunction.cpp
index f6f325a..9935379 100644
--- a/src/fflib/AFunction.cpp
+++ b/src/fflib/AFunction.cpp
@@ -1737,121 +1737,123 @@ C_F0  opColumn::code2(const basicAC_F0 &args) const
     if( tb)  teb = dynamic_cast<const TransE_Array*>((Expression) args[1]);
     else eb = dynamic_cast<const E_Array*>((Expression) args[1]);
     
-   // ffassert( ea || tea );
-
+    // ffassert( ea || tea );
+    
     if( (eb || teb) && ( ea || tea ) )
     {
-    const E_Array & a=  ta ? *tea->v : *ea;
-    const E_Array & b=  tb ? *teb->v : *eb;
-    int ma =1;
-    int mb =1;
-    int na=a.size();
-    int nb=b.size();
-    if(na <1 && nb < 1) CompileError(" empty array  [ ...]':[ ...  ]  ");
-    bool mab= b[0].left()==atype<E_Array>();
-    bool maa= a[0].left()==atype<E_Array>();
-    if(maa) {
-	ma= a[0].LeftValue()->nbitem();
-	for (int i=1;i<na;i++)
-	    if( ma != (int) a[i].LeftValue()->nbitem())
-		CompileError(" first matrix with variable number of columm");
+        const E_Array & a=  ta ? *tea->v : *ea;
+        const E_Array & b=  tb ? *teb->v : *eb;
+        int ma =1;
+        int mb =1;
+        int na=a.size();
+        int nb=b.size();
+        if(na <1 && nb < 1) CompileError(" empty array  [ ...]':[ ...  ]  ");
+        bool mab= b[0].left()==atype<E_Array>();
+        bool maa= a[0].left()==atype<E_Array>();
+        if(maa) {
+            ma= a[0].LeftValue()->nbitem();
+            for (int i=1;i<na;i++)
+                if( ma != (int) a[i].LeftValue()->nbitem())
+                    CompileError(" first matrix with variable number of columm");
+            
+        }
+        if(mab) {
+            mb= b[1].LeftValue()->nbitem();
+            for (int i=1;i<nb;i++)
+                if( mb != (int) b[i].LeftValue()->nbitem())
+                    CompileError(" second matrix with variable number of columm");
+        }
+        int na1=na,ma1=ma,nb1=nb,mb1=mb;
+        if(ta) RNM::Exchange(na1,ma1);
+        if(tb) RNM::Exchange(nb1,mb1);
         
-    }
-    if(mab) {
-	mb= b[1].LeftValue()->nbitem();
-	for (int i=1;i<nb;i++)
-	    if( mb != (int) b[i].LeftValue()->nbitem())
-		CompileError(" second matrix with variable number of columm");
-    }
-    int na1=na,ma1=ma,nb1=nb,mb1=mb;
-    if(ta) RNM::Exchange(na1,ma1);
-    if(tb) RNM::Exchange(nb1,mb1);
-    
-    KNM<CC_F0> A(na1,ma1), B(nb1,mb1);
-    if ( (na1!=nb1 ) || (ma1 != mb1) || (na1 * ma1 ==0)  )
-    {
-	cout << "\n   formal  array or matrix : [ .. ] : [ .. ]   " << endl;
-	cout << " first  array :  matrix " << maa << " trans " << ta << " " << na << "x" << ma <<endl;
-	cout << " second array :  matrix " << mab << " trans " << tb << " " << nb << "x" << mb <<endl;
-	CompileError(" no same size  [ ...] : [ ...  ] sorry ");
-    }
-    
-    if(maa)
-	for (int i=0;i<na;++i)
-	{
-	    const E_Array * li=  dynamic_cast<const E_Array *>(a[i].LeftValue());
-	    ffassert(li);
-	    for (int j=0; j<ma;++j)
-		if(!ta)  A(i,j) = (*li)[j];
-		else     A(j,i) = TryConj((*li)[j]);
-	}
-    else
-	for (int i=0;i<na;++i)
-	    if(!ta)  A(i,0) = a[i];
-	    else     A(0,i) = TryConj(a[i]);
-    
-    if(mab)
-	for (int i=0;i<nb;++i)
-	{
-	    const E_Array * li=  dynamic_cast<const E_Array *>(b[i].LeftValue());
-	    ffassert(li);
-	    for (int j=0; j<mb;++j)
-		if(!tb)  B(i,j) = (*li)[j];
-		else     B(j,i) = TryConj((*li)[j]);
-	}
-    else
-	for (int i=0;i<nb;++i)
-	    if(!tb)  B(i,0) = b[i];
-	    else     B(0,i) = TryConj(b[i]);
-    
-    //KNM<CC_F0> C(na1,mb1);
-    CC_F0 s,aibi;
-    
-    for (int i=0;i<na1;++i)
-      for (int j=0;j<ma1;++j)
-	{
-		aibi = C_F0(TheOperators,"*",A(i,j),B(i,j));
-            if( (i==0) && (j==0))
-                s = aibi; 
-            else 
-            s = C_F0(TheOperators,"+",s,aibi);
-	};
- //   if( na1==1 && mb1 ==1)
-	return s;
+        KNM<CC_F0> A(na1,ma1), B(nb1,mb1);
+        if ( (na1!=nb1 ) || (ma1 != mb1) || (na1 * ma1 ==0)  )
+        {
+            cout << "\n   formal  array or matrix : [ .. ] : [ .. ]   " << endl;
+            cout << " first  array :  matrix " << maa << " trans " << ta << " " << na << "x" << ma <<endl;
+            cout << " second array :  matrix " << mab << " trans " << tb << " " << nb << "x" << mb <<endl;
+            CompileError(" no same size  [ ...] : [ ...  ] sorry ");
+        }
+        
+        if(maa)
+            for (int i=0;i<na;++i)
+            {
+                const E_Array * li=  dynamic_cast<const E_Array *>(a[i].LeftValue());
+                ffassert(li);
+                for (int j=0; j<ma;++j)
+                    if(!ta)  A(i,j) = (*li)[j];
+                    else     A(j,i) = TryConj((*li)[j]);
+            }
+        else
+            for (int i=0;i<na;++i)
+                if(!ta)  A(i,0) = a[i];
+                else     A(0,i) = TryConj(a[i]);
+        
+        if(mab)
+            for (int i=0;i<nb;++i)
+            {
+                const E_Array * li=  dynamic_cast<const E_Array *>(b[i].LeftValue());
+                ffassert(li);
+                for (int j=0; j<mb;++j)
+                    if(!tb)  B(i,j) = (*li)[j];
+                    else     B(j,i) = TryConj((*li)[j]);
+            }
+        else
+            for (int i=0;i<nb;++i)
+                if(!tb)  B(i,0) = b[i];
+                else     B(0,i) = TryConj(b[i]);
+        
+        //KNM<CC_F0> C(na1,mb1);
+        CC_F0 s,aibi;
+        
+        for (int i=0;i<na1;++i)
+            for (int j=0;j<ma1;++j)
+            {
+                aibi = C_F0(TheOperators,"*",A(i,j),B(i,j));
+                if( (i==0) && (j==0))
+                    s = aibi; 
+                else 
+                    s = C_F0(TheOperators,"+",s,aibi);
+            };
+        //   if( na1==1 && mb1 ==1)
+        return s;
     }
     else if ( ea || tea )
-    {
-        
+    { // modif 2 /08/  2013  FH .. bug in [ a0,a1,... ]'*b 
+        //  [a0,a1,... ]*b  or [ a0,a1,... ]'*b  => [ a0*b',a1*b',
         const E_Array & a=  ta ? *tea->v : *ea;
         int na=a.size();
         AC_F0  v;
         v = 0; // empty
-	for (int i=0;i<na;++i)
-	    v += C_F0(TheOperators,"*",ta ? TryConj(a[i]) : a[i],args[1]) ;
-	return ta ? C_F0(TheOperators,"\'",C_F0(TheOperators,"[]",v)) :   C_F0(TheOperators,"[]",v);
-    
+        C_F0 b =ta ? TryConj(args[1]) :args[1]; 
+        for (int i=0;i<na;++i)
+        v += C_F0(TheOperators,"*",a[i],b)  ;            
+        return ta ? C_F0(TheOperators,"\'",C_F0(TheOperators,"[]",v)) :   C_F0(TheOperators,"[]",v);
+        
     }
     else if(eb || teb)
-     {
-         const E_Array & b=  tb ? *teb->v : *eb;
-         int nb=b.size();
-         AC_F0  v;
-         v = 0; // empty
-         for (int i=0;i<nb;++i)
-             v += C_F0(TheOperators,"*",args[0],tb ? TryConj(b[i]) : b[i]) ;
-         return tb ? C_F0(TheOperators,"\'",C_F0(TheOperators,"[]",v)) :   C_F0(TheOperators,"[]",v);
-
-     }
+    {  // modif 2 /08/  2013  FH .. bug in a*[ b0,b1,... ]'
+        const E_Array & b=  tb ? *teb->v : *eb;
+        int nb=b.size();
+        C_F0 a =tb ? TryConj(args[0]) :args[0]; 
+        AC_F0  v;
+        v = 0; // empty
+        for (int i=0;i<nb;++i)
+            v += C_F0(TheOperators,"*",a,b[i]) ;
+        return tb ? C_F0(TheOperators,"\'",C_F0(TheOperators,"[]",v)) :   C_F0(TheOperators,"[]",v);
+        
+    }
     else ffassert(0); 
-/*
-    cout << "   formal : array or matrix : [ .. ] : [ .. ]   " << na << "x" << nb << endl;
-    cout << "   formal : array or matrix : [ .. ] : [ .. ]   " <<  endl;
-    cout << " first  array :  matrix " << maa << " trans " << ta << " " << na << "x" << ma <<endl;
-    cout << " second array :  matrix " << mab << " trans " << tb << " " << nb << "x" << mb <<endl;
-    CompileError("  not implemented sorry ..... (FH) to do ???? ");
-   
- */
-     return C_F0();
+    /*
+     cout << "   formal : array or matrix : [ .. ] : [ .. ]   " << na << "x" << nb << endl;
+     cout << "   formal : array or matrix : [ .. ] : [ .. ]   " <<  endl;
+     cout << " first  array :  matrix " << maa << " trans " << ta << " " << na << "x" << ma <<endl;
+     cout << " second array :  matrix " << mab << " trans " << tb << " " << nb << "x" << mb <<endl;
+     CompileError("  not implemented sorry ..... (FH) to do ???? ");
+     
+     */
+    return C_F0();
 }
 
 
diff --git a/src/fflib/AFunction.hpp b/src/fflib/AFunction.hpp
index 27d3f9c..6857e06 100644
--- a/src/fflib/AFunction.hpp
+++ b/src/fflib/AFunction.hpp
@@ -1,3 +1,5 @@
+/// \file
+
 // -*- Mode : c++ -*-
 //
 // SUMMARY  :      
@@ -94,7 +96,10 @@ class C_F0;  //  une instruction  complie time
 class ListOfInst;
 class Polymorphic;
 class OneOperator;
-typedef  E_F0  *  Expression; // 
+
+/// Expression is used as the type of the local list contained in ListOfInst
+typedef  E_F0  *  Expression;
+
 class AC_F0;
 class basicAC_F0;
 typedef complex<double> Complex;
@@ -149,9 +154,7 @@ typedef deque<UnId> ListOfId;
 //#define NEW_TYPE_PtrI(type) map_type[typeid(type*).name()] = new ForEachTypePtr<type*>(Initialize<type>)
 */
 
-
-
-
+/// Doxygen doc
 extern Polymorphic * TheOperators, * TheRightOperators;
 
 //  -------------
@@ -333,6 +336,11 @@ class C_LF2;
 class C_LF1;
 
 //  3 types of function/expression  0,1,2 args  
+
+/// E_F0 is the base class for all expressions built by parsing an EDP script in the grammar of the FreeFem++ language
+/// (see lg.ypp). E_F0 pointers are typed as #Expression, stored as a list in ListOfInst, and evaluated when
+/// CListOfInst::eval() is called (see \ref index).
+
 class E_F0 :public CodeAlloc 
    {
    public:
@@ -376,7 +384,8 @@ class E_F0 :public CodeAlloc
  };  
  
 inline ostream & operator<<(ostream & f,const E_F0 &e) { if(&e) e.dump(f); else f << " --0-- " ;return f;}
-// a  
+
+/// Specialization of E_F0 where MeshIndependent() always returns false instead of true.  
 class E_F0mps : public E_F0 { public:
   virtual bool MeshIndependent() const {return false;} // 
 };
@@ -1360,21 +1369,28 @@ class ListOfInst : public  E_F0mps {
   if(list) delete [] list;list=0;if(linenumber)  delete[] linenumber; linenumber=0;}
 };
 
-class CListOfInst  {  private:
+class CListOfInst{
+private:
   ListOfInst * f;
   const basicForEachType *r;
-  public:
-   void operator=(const CC_F0 &a){
-     f=new ListOfInst();     
-       if( !a.Empty() ) {
-         f->Add(a);
-         r=a.left(); }}
-   CListOfInst & operator+=(const CC_F0 & a);//{ if( !a.Empty()){ f->Add(a);r=a.left();};return *this;} 
-    operator C_F0 () const  { return C_F0(f,r);}
-   void eval(Stack s) {(*f)(s);}
-   int size() const {return f->size();}
-   Expression * ptr() const {return f->ptr();}
-   int * nlines() const { return f->nlines();}
+
+public:
+  void operator=(const CC_F0 &a){
+    f=new ListOfInst();     
+    if( !a.Empty() ) {
+      f->Add(a);
+      r=a.left(); }}
+  CListOfInst & operator+=(const CC_F0 & a);//{ if( !a.Empty()){ f->Add(a);r=a.left();};return *this;} 
+  operator C_F0 () const  { return C_F0(f,r);}
+
+  /// Called by yyparse() to evaluate the complete expression tree when reaching the end of its "start" symbol. It calls
+  /// ListOfInst::operator()() for its private ListOfInst pointer #f.
+
+  void eval(Stack s) {(*f)(s);}
+
+  int size() const {return f->size();}
+  Expression * ptr() const {return f->ptr();}
+  int * nlines() const { return f->nlines();}
 };
 
 
@@ -1384,8 +1400,10 @@ AnyType FIf(Stack s ,E_F0 * test,E_F0 * i1,E_F0 * i2,E_F0 * notuse);
 AnyType TTry(Stack s ,E_F0 * i0,E_F0 * i1,E_F0 * i2,E_F0 * notuse);
 
 
+/// <<Global>> Contains all FreeFem++ language keywords. Definition in [[file:global.cpp::Global]]
 
 extern TableOfIdentifier Global;
+
 void ShowType(ostream & );
 
 template<class T> 
@@ -1885,11 +1903,13 @@ inline  E_F0 * C_F0::LeftValue() const {
 }*/
 
 
-      
+/// Declaration of TypeArray
 aType TypeArray(aType,aType);
-aType TypeTemplate(aType,aType);
 aType TypeArray(aType c,aType b,aType a);
 
+/// Declaration of TypeTemplate
+aType TypeTemplate(aType,aType);
+
 void Init_map_type();
 
 class Block { //
@@ -2339,7 +2359,11 @@ class  Operator_Aritm_If : public OneOperator{
   public:
     AnyType operator()(Stack s)  const 
          {
-          return  SetAny<R>(static_cast<R>( GetAny<bool>((*a)(s)) ? GetAny<B>((*b)(s))  : GetAny<C>((*c)(s))  ));
+             bool ok = GetAny<bool>((*a)(s)) ;
+             R r ;
+             if( ok) r=GetAny<B>((*b)(s)) ;
+             else r =GetAny<C>((*c)(s)) ;
+             return  SetAny<R>(r);// static_cast<R>( ? GetAny<B>((*b)(s))  : GetAny<C>((*c)(s))  ));
           }
     Op(Expression aa,Expression bb,Expression cc) : a(aa),b(bb),c(cc){} 
     bool MeshIndependent() const { return a->MeshIndependent() && b->MeshIndependent() &&b->MeshIndependent() ;}
diff --git a/src/fflib/AFunction2.cpp b/src/fflib/AFunction2.cpp
index 2dc292a..2c1ab66 100644
--- a/src/fflib/AFunction2.cpp
+++ b/src/fflib/AFunction2.cpp
@@ -773,7 +773,7 @@ void ListOfInst::Add(const C_F0 & ins) {
       list[n++] = ins;
       }}
       
-      
+/// Iteratively calls each item in the local array #list of type #Expression
 AnyType ListOfInst::operator()(Stack s) const {     
     AnyType r; 
     double s0=CPUtime(),s1=s0,ss0=s0;
diff --git a/src/fflib/Makefile.am b/src/fflib/Makefile.am
index 0a0f926..820f7bf 100644
--- a/src/fflib/Makefile.am
+++ b/src/fflib/Makefile.am
@@ -4,6 +4,10 @@
 
 noinst_LIBRARIES=libff.a
 
+# FFCS - 28/11/11 - ffapi.cpp cannot be part of libff.a because it
+# needs to be compiled with different options depending on the
+# executable it is included in (eg with/without MPI)
+
 libff_a_SOURCES2=  UMFPack_Solver.cpp \
 AFunction.cpp AFunction2.cpp  \
  array_long.cpp          array_real.cpp        array_complex.cpp \
@@ -43,7 +47,7 @@ endian.hpp \
 ff++.hpp \
 ../Eigen/arpackff.hpp \
 ../femlib/splitsimplex.cpp AFunction_ext.hpp \
-ffapi.hpp ffapi.cpp 
+ffapi.hpp
 
 libff_a_SOURCES=$(libff_a_SOURCES2)  strversionnumber.cpp 
 
diff --git a/src/fflib/Makefile.in b/src/fflib/Makefile.in
index b4c1753..ff59578 100644
--- a/src/fflib/Makefile.in
+++ b/src/fflib/Makefile.in
@@ -59,7 +59,8 @@ 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)/acmacros.m4 \
-	$(top_srcdir)/acoptim.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/acoptim.m4 $(top_srcdir)/acmpi.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -90,7 +91,7 @@ am__objects_1 = UMFPack_Solver.$(OBJEXT) AFunction.$(OBJEXT) \
 	P012_1d.$(OBJEXT) P012_2d.$(OBJEXT) P012_3d.$(OBJEXT) \
 	Mesh1dn.$(OBJEXT) Mesh2dn.$(OBJEXT) Mesh3dn.$(OBJEXT) \
 	GQuadTree.$(OBJEXT) libmesh5.$(OBJEXT) glumesh2D.$(OBJEXT) \
-	splitsimplex.$(OBJEXT) ffapi.$(OBJEXT)
+	splitsimplex.$(OBJEXT)
 am_libff_a_OBJECTS = $(am__objects_1) strversionnumber.$(OBJEXT)
 libff_a_OBJECTS = $(am_libff_a_OBJECTS)
 AM_V_P = $(am__v_P_ at AM_V@)
@@ -207,11 +208,47 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EIGENOBJ = @EIGENOBJ@
+ENABLE_FFCS = @ENABLE_FFCS@
 EPSTOPDF = @EPSTOPDF@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+FFCS_COMPILE_fflapack = @FFCS_COMPILE_fflapack@
+FFCS_COMPILE_gsl = @FFCS_COMPILE_gsl@
+FFCS_COMPILE_hips = @FFCS_COMPILE_hips@
+FFCS_COMPILE_hypre = @FFCS_COMPILE_hypre@
+FFCS_COMPILE_ipopt = @FFCS_COMPILE_ipopt@
+FFCS_COMPILE_lapack = @FFCS_COMPILE_lapack@
+FFCS_COMPILE_mmg3d = @FFCS_COMPILE_mmg3d@
+FFCS_COMPILE_mshmet = @FFCS_COMPILE_mshmet@
+FFCS_COMPILE_mumps = @FFCS_COMPILE_mumps@
+FFCS_COMPILE_mumps_seq = @FFCS_COMPILE_mumps_seq@
+FFCS_COMPILE_pardiso = @FFCS_COMPILE_pardiso@
+FFCS_COMPILE_parms = @FFCS_COMPILE_parms@
+FFCS_COMPILE_pastix = @FFCS_COMPILE_pastix@
+FFCS_COMPILE_pipe = @FFCS_COMPILE_pipe@
+FFCS_COMPILE_scotch = @FFCS_COMPILE_scotch@
+FFCS_COMPILE_superludist = @FFCS_COMPILE_superludist@
+FFCS_COMPILE_yams = @FFCS_COMPILE_yams@
+FFCS_DYLIB_fflapack = @FFCS_DYLIB_fflapack@
+FFCS_DYLIB_gsl = @FFCS_DYLIB_gsl@
+FFCS_DYLIB_hips = @FFCS_DYLIB_hips@
+FFCS_DYLIB_hypre = @FFCS_DYLIB_hypre@
+FFCS_DYLIB_ipopt = @FFCS_DYLIB_ipopt@
+FFCS_DYLIB_lapack = @FFCS_DYLIB_lapack@
+FFCS_DYLIB_mmg3d = @FFCS_DYLIB_mmg3d@
+FFCS_DYLIB_mshmet = @FFCS_DYLIB_mshmet@
+FFCS_DYLIB_mumps = @FFCS_DYLIB_mumps@
+FFCS_DYLIB_mumps_seq = @FFCS_DYLIB_mumps_seq@
+FFCS_DYLIB_pardiso = @FFCS_DYLIB_pardiso@
+FFCS_DYLIB_parms = @FFCS_DYLIB_parms@
+FFCS_DYLIB_pastix = @FFCS_DYLIB_pastix@
+FFCS_DYLIB_pipe = @FFCS_DYLIB_pipe@
+FFCS_DYLIB_scotch = @FFCS_DYLIB_scotch@
+FFCS_DYLIB_superludist = @FFCS_DYLIB_superludist@
+FFCS_DYLIB_yams = @FFCS_DYLIB_yams@
+FFCS_MAKEFLAGS = @FFCS_MAKEFLAGS@
 FFGLUTNAME = @FFGLUTNAME@
 FFGLUTPROG = @FFGLUTPROG@
 FFLAGS = @FFLAGS@
@@ -379,6 +416,10 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 noinst_LIBRARIES = libff.a
+
+# FFCS - 28/11/11 - ffapi.cpp cannot be part of libff.a because it
+# needs to be compiled with different options depending on the
+# executable it is included in (eg with/without MPI)
 libff_a_SOURCES2 = UMFPack_Solver.cpp \
 AFunction.cpp AFunction2.cpp  \
  array_long.cpp          array_real.cpp        array_complex.cpp \
@@ -418,7 +459,7 @@ endian.hpp \
 ff++.hpp \
 ../Eigen/arpackff.hpp \
 ../femlib/splitsimplex.cpp AFunction_ext.hpp \
-ffapi.hpp ffapi.cpp 
+ffapi.hpp
 
 libff_a_SOURCES = $(libff_a_SOURCES2)  strversionnumber.cpp 
 
@@ -520,7 +561,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/eigenvalue.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/environment.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/fem.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ffapi.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gibbs.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/global.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/glumesh2D.Po at am__quote@
diff --git a/src/fflib/PlotStream.hpp b/src/fflib/PlotStream.hpp
index 57534cf..070a260 100644
--- a/src/fflib/PlotStream.hpp
+++ b/src/fflib/PlotStream.hpp
@@ -12,6 +12,9 @@
 #endif
 #include "endian.hpp"
 
+//FFCS visualization stream redirection
+#include "ffapi.hpp"
+
 using  Fem2D::Mesh;
 using  Fem2D::Mesh3;
 namespace Fem2D {
@@ -28,15 +31,19 @@ public:
   PlotStream(FILE *Stream) :TheStream(Stream) { }
   operator bool() const { return TheStream;}
   // datatype mush be < 0 to have no collistion with arg number. 
+  // FFCS: <<PlotStream::datatype>>
     enum datatype { dt_meshes=-1,dt_plots=-2,dt_endplot=-3,dt_meshes3=-10,dt_plots3=-11,dt_endarg=99999,dt_newplot=-5  };
   
-  void SendNewPlot() {  write((long )dt_newplot); set_binary_mode(); }
+  //FFCS:need to send control data to FFCS at least once per plot
+  void SendNewPlot() {  ffapi::newplot();write((long )dt_newplot); set_binary_mode(); }
   void SendEndArgPlot() {write((long )dt_endarg); }
-  void SendEndPlot() { write((long )dt_endplot);fflush(TheStream); set_text_mode() ;}
+  //FFCS:redirect visualization stream
+  void SendEndPlot() { write((long )dt_endplot);ffapi::ff_fflush(TheStream); set_text_mode() ;}
   void SendPlots() { write((long )dt_plots); }
   void SendMeshes() { write((long )dt_meshes);}
   void SendMeshes3() { write((long )dt_meshes3);}
-  void write(const void *data,size_t l) {fwrite(data,1,l,TheStream);}
+  //FFCS: divert stream to FFCS
+  void write(const void *data,size_t l) {ffapi::ff_fwrite(data,1,l,TheStream);}
 
   PlotStream& write(const bool& bb) {bool b=w_endian(bb);write(reinterpret_cast<const void *> (&b),sizeof(bool));return *this;}
   PlotStream& write(const long long& bb) {long long  b=w_endian(bb);write(reinterpret_cast<const void *> (&b),sizeof(long long));return *this;}
@@ -59,15 +66,13 @@ public:
   
   void set_text_mode() 
   {    
-#ifdef WIN32
-        _setmode(fileno(TheStream),O_TEXT);	
-#endif
+  //FFCS:visualization stream redirection
+    ffapi::wintextmode(TheStream);
   }
   void set_binary_mode()
   {    
-#ifdef WIN32
-    _setmode(fileno(TheStream),O_BINARY);	
-#endif
+  //FFCS:visualization stream redirection
+    ffapi::winbinmode(TheStream);
   }
  
   PlotStream & operator << (const bool& b)    { return write(b); }
@@ -112,7 +117,8 @@ public:
 	//	fread(  p++,1,1,TheStream);
 	//       read(data,l);
 }
-  bool good() const {return ferror(TheStream)==0;}
+  //FFCS:visualization stream redirection
+  bool good() const {return ffapi::ff_ferror(TheStream)==0;}
   void GetNewPlot() { get(dt_newplot) ; set_binary_mode();}
   void GetEndArgPlot() {get(dt_endarg); }
   void GetEndPlot() {get(dt_endplot); set_text_mode();}
@@ -129,7 +135,8 @@ public:
     if( tt !=(long) t) 
       cout << " Error Check :  get " << tt << " == wait for  "<< t << endl; 
     ffassert(tt==(long) t);}
-    bool eof() {return feof(TheStream);}
+  //FFCS:visualization stream redirection
+    bool eof() {return ffapi::ff_feof(TheStream);}
   PlotStream& read( bool& b) {read(reinterpret_cast< void *> (&b),sizeof(bool));  b=r_endian(b);return *this;}
   PlotStream& read( long long& b) {read(reinterpret_cast< void *> (&b),sizeof(long long)); b=r_endian(b);return *this;}
   PlotStream& read( long& b) { long long l;
diff --git a/src/fflib/environment.cpp b/src/fflib/environment.cpp
index 4b027eb..80c9a6e 100644
--- a/src/fflib/environment.cpp
+++ b/src/fflib/environment.cpp
@@ -265,7 +265,16 @@ int  readinitfile(const string & file)
 void GetEnvironment()
  {
  char  * ff_verbosity=0,* ff_loadpath=0,* ff_incpath=0,* home=0;
+
+ // FFCS: we must make sure that FFCS does not reuse the same freefem++.pref as FF because some shared libraries must be
+ // recompiled.
+
+#ifdef ENABLE_FFCS
+ string  ffpref="freefem++-cs.pref";
+#else
   string  ffpref="freefem++.pref";
+#endif
+
 #ifdef HAVE_GETENV
   ff_verbosity = getenv("FF_VERBOSITY");
   ff_loadpath = getenv("FF_LOADPATH");
diff --git a/src/fflib/ffapi.cpp b/src/fflib/ffapi.cpp
old mode 100644
new mode 100755
index 12f6093..299bc7c
--- a/src/fflib/ffapi.cpp
+++ b/src/fflib/ffapi.cpp
@@ -29,94 +29,98 @@
 
 // headerfilter
 #include "ffapi.hpp"
-#ifndef FFS
+#ifdef FFLANG
+#include "socket.hpp"
+#include "spawn.hpp"
+#include "buffer.hpp"
+#endif
+#include <iostream>
+#include <cstdio>
+#ifndef FFLANG
 #include <cstdio>
 #endif
-#ifdef FFS
-#include "../src/options.hpp"
+#ifdef FFLANG
+#include "options.hpp"
+#include <stdlib.h>
 #endif
-#ifndef FFS
+#ifndef FFLANG
 #ifdef WIN32
 #include <fcntl.h>
 #endif
 #endif
-#ifndef FFS
+#ifndef FFLANG
 #ifdef PARALLELE
 #include "mpi.h"
 #endif
 #endif
 
-#include <cstdlib>
-
 // FFCS-specific implementations for the FF API
 // --------------------------------------------
 
-/// FFCS defined means that FFCS is being compiled. I am fairly
-/// confident that FFCS will not be defined while compiling the
-/// original FF.
-#ifdef FFS
-#include "../src/socket.hpp"
-#include "../src/buffer.hpp"
-#endif
+/// FFLANG defined means that FFCS is being compiled. I am fairly confident that FFCS will not be defined while
+/// compiling the original FF.
 
-/// Need to choose a non-zero stream number because FF will check it
-/// (as global variable ThePlotStream)
+/// Need to choose a non-zero stream number because FF will check it (as global variable ThePlotStream)
 #define FFAPISTREAM 1
 
-/// if FFCS is around, we need to bufferize all communication to avoid
-/// mixing up CMD_FFG and CMD_STDOUT messages
-#ifdef FFS
+/// if FFCS is around, we need to bufferize all communications to avoid mixing up CMD_FFG and CMD_STDOUT messages
+#ifdef FFLANG
 void bufferwrite(const char *b,const int l){
+  Socket::dialoglock->WAIT(); // need #include "socket.hpp"
 
-  // thank to the buffering, there is only one CMD_FFG tag for multiple
-  // visualization data items.
-  *serversocket<<CMD_FFG;
-  *serversocket<<l;
+  // thank to the buffering, there is only one CMD_FFG tag for multiple visualization data items.
+  onlyffsock()<<CMD_FFG; // need #include "spawn.hpp"
+  onlyffsock()<<l;
 
   // this call contains the socket MAGIC number
-  serversocket->bufferedwrite(static_cast<const char*>(b),l);
+  onlyffsock().bufferedwrite(static_cast<const char*>(b),l);
+
+  Socket::dialoglock->Free();
 }
 
-Buffer buffer(NULL,bufferwrite);
+Buffer buffer(NULL,bufferwrite); // need #include "buffer.hpp"
 #endif
 
 namespace ffapi{
 
-  // Get a pointer to the local cin/cout (which is distinct from
-  // ffcs's stdin/stdout under Windows because each DLL owns separate
-  // cin/cout objects).
+  // Get a pointer to the local cin/cout (which is distinct from ffcs's stdin/stdout under Windows because each DLL owns
+  // separate cin/cout objects).
+
+  // need #include <iostream>
   std::istream *cin(){return &std::cin;}
   std::ostream *cout(){return &std::cout;}
   std::ostream *cerr(){return &std::cerr;}
-  FILE *ffstdout(){return stdout; };
-  FILE *ffstderr(){return stderr;};
-  FILE *ffstdin(){return stdin;};
 
+  // FFCS - ::stdout not accepted under mingw32
+  // need #include <cstdio>
+  FILE *ffstdout(){return stdout;}
+  FILE *ffstderr(){return stderr;}
+  FILE *ffstdin(){return stdin;}
 
-  void newplot(){
-#ifdef FFS
-    assert(serversocket);
-#endif
-  }
+  void newplot(){}
 
   FILE *ff_popen(const char *command, const char *type){
-#ifdef FFS
+#ifdef FFLANG
+
     // this happens right at the begining of FF, so the socket
     // communication must not be started yet (only when actual
     // visualization data needs to be transfered).
+
+    PROGRESS;
     return (FILE*)FFAPISTREAM;
 #else
+
     // need #include <cstdio>
-    popen(command,type);
+    return popen(command,type);
 #endif
   }
 
   int ff_pclose(FILE *stream){
-#ifdef FFS
+#ifdef FFLANG
     // nothing to close in FFCS
     return 0;
 #else
-    pclose(stream);
+    return pclose(stream);
 #endif
   }
 
@@ -127,29 +131,30 @@ namespace ffapi{
     // in the middle of the lines checked by test/compare. So deactivate
     // it by default.
 #ifdef DEBUG_FFAPI
-#ifdef FFS
+#ifdef FFLANG
     printf("debug: ffapi: using TCP sockets\n");
 #else
     printf("debug: ffapi: using an anonymous pipe\n");
-#endif // FFS
+#endif // FFLANG
 #endif // DEBUG_FFAPI
 
-#ifdef FFS
-    // Ask FFCS to analyze the visualization flux header. I could just
-    // skip this stage, but it will be useful to check the coherency
-    // between FFCS and FF when FF evolves in the future.
-    assert(serversocket);
-    *serversocket<<CMD_FFGINIT;
+#ifdef FFLANG
+
+    // Ask FFCS to analyze the visualization flux header. I could just skip this stage, but it will be useful to check
+    // the coherency between FFCS and FF when FF evolves in the future.
+
+    Socket::dialoglock->WAIT();
+    onlyffsock()<<CMD_FFGINIT;
+    Socket::dialoglock->Free();
 #endif
-    ff_fwrite(ptr,size,nmemb,stream);
+    return ff_fwrite(ptr,size,nmemb,stream);
   }
 
   size_t ff_fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream){
-#ifdef FFS
-    // this assert is a way to check that the serversocket pointer
-    // exported from the FFCS shared library is a valid one (which has
-    // not been always true in the case of Windows DLLs).
-    assert(serversocket);
+#ifdef FFLANG
+
+    // if the ffsock pointer is null here, it means that the pointer exported from the FFCS shared library is not a
+    // valid one (this has been the case with Windows DLLs in the past).
 
     // we won't make use of the stream, but make sure that the call from
     // FF is coherent with what we know.
@@ -157,48 +162,57 @@ namespace ffapi{
 
     buffer.write(static_cast<const char*>(ptr),size*nmemb);
 
-    // stops the server flux at one precise point (point value expressed
-    // during a previous crash while reading server data in the client
-    // in visudata.cpp). Use abort() to call the debugger (which can
-    // display the call stack and show where the problematic pipe value
-    // came from).
+    // stops the server flux at one precise point (point value expressed during a previous crash while reading server
+    // data in the client in visudata.cpp). Use abort() to call the debugger (which can display the call stack and show
+    // where the problematic pipe value came from).
 
-    // need #include "../src/options.hpp"
-    if(options->AbortFFGDataAt==buffer.getpoint())abort();
+    // need #include "options.hpp"
+    if(options->AbortFFGraphicsDataAt==buffer.getpoint())abort(); // need #include <stdlib.h>
 
 #else
     fwrite(ptr,size,nmemb,stream);
 #endif
+    return 0;
   }
 
   int ff_fflush(FILE *stream){
-#ifdef FFS
+#ifdef FFLANG
     assert(stream==(FILE*)FFAPISTREAM);
-    assert(serversocket);
 
-    // we need to flush both the buffer and the socket to avoid a
-    // separate callback for flush in the buffer
+    // we need to flush both the buffer and the socket to avoid a separate callback for flush in the buffer
     buffer.flush();
-    serversocket->writeflush();
+
+    // ff_fflush() is used by FF only at the end of a plot, so we can use this location to send a marker for the
+    // sequential java client to deal with one complete plot at a time.
+    Socket::dialoglock->WAIT();
+    onlyffsock()<<CMD_FFGEND;
+    onlyffsock().writeflush();
+    Socket::dialoglock->Free();
+
 #else
     fflush(stream);
 #endif
+    return 0;
   }
 
   int ff_ferror(FILE *stream){
-#ifndef FFS
+#ifndef FFLANG
     return ferror(stream);
+#else
+    return 0;
 #endif
   }
 
   int ff_feof(FILE *stream){
-#ifndef FFS
+#ifndef FFLANG
     return feof(stream);
+#else
+    return 0;
 #endif
   }
 
   void wintextmode(FILE *f){
-#ifndef FFS
+#ifndef FFLANG
 #ifdef WIN32
     // need #include <fcntl.h>
     _setmode(fileno(f),O_TEXT);	
@@ -207,7 +221,7 @@ namespace ffapi{
   }
 
   void winbinmode(FILE *f){
-#ifndef FFS
+#ifndef FFLANG
 #ifdef WIN32
     _setmode(fileno(f),O_BINARY);	
 #endif
@@ -215,9 +229,8 @@ namespace ffapi{
   }
 
   void mpi_init(int &argc, char** &argv){
-    /// only call MPI_Init() if this has not already been done in
-    /// ffcs/src/server.cpp
-#ifndef FFS
+    /// only call MPI_Init() if this has not already been done in ffcs/src/server.cpp
+#ifndef FFLANG
 #ifdef PARALLELE
     // need #include "mpi.h"
     MPI_Init(&argc,&argv);
@@ -226,33 +239,39 @@ namespace ffapi{
   }
 
   void mpi_finalize(){
-#ifndef FFS
+#ifndef FFLANG
 #ifdef PARALLELE
     MPI_Finalize();
 #endif
 #endif
   }
 
-void init()
-{
-  ffapi::fwriteinit ;
-  ffapi::winbinmode ;
-  ffapi::wintextmode ;
-  ffapi::mpi_finalize ;
-  ffapi::cin ;
-  ffapi::cerr ;
-  ffapi::cout ;
-  ffapi::ff_feof ;
-  ffapi::newplot ;
-  ffapi::ff_popen ;
-  ffapi::mpi_init ;
-  ffapi::ff_ferror ;
-  ffapi::ff_fflush ;
-  ffapi::ff_fwrite ;
-  ffapi::ff_pclose ;
-;
+  bool protectedservermode(){
+#ifdef FFLANG
+    return !options->LocalClient;
+#else
+    return false;
+#endif
+  }
 
-}
+  void init(){
+    ffapi::fwriteinit;
+    ffapi::winbinmode;
+    ffapi::wintextmode;
+    ffapi::mpi_finalize;
+    ffapi::cin;
+    ffapi::cerr;
+    ffapi::cout;
+    ffapi::ff_feof;
+    ffapi::newplot;
+    ffapi::ff_popen;
+    ffapi::mpi_init;
+    ffapi::ff_ferror;
+    ffapi::ff_fflush;
+    ffapi::ff_fwrite;
+    ffapi::ff_pclose;
+    ffapi::protectedservermode;
+  }
 }
 
 /// Local Variables:
diff --git a/src/fflib/ffapi.hpp b/src/fflib/ffapi.hpp
old mode 100644
new mode 100755
index f567ccd..90c4cd9
--- a/src/fflib/ffapi.hpp
+++ b/src/fflib/ffapi.hpp
@@ -24,43 +24,56 @@
 /// ======================================================================
 /// headeralh cpp freefem start=21/01/10 upmc
 
-#ifndef FFAPI_HPP
-#define FFAPI_HPP
-
 // Proposed FreeFem++ Application Programming Interface
 // ----------------------------------------------------
 
 // headerfilter
-
+#ifndef FFAPI_HPP
 #include <iostream>
 #include <sstream>
 #include <cstdio>
 using namespace std;
+#endif //FFAPI_HPP
+
+#ifndef FFAPI_HPP
+#define FFAPI_HPP
 
 namespace ffapi{
 
   // Redirecting the FF data stream
   // ------------------------------
 
-  // Getting a pointer to FF stdin and stdout enables extra DLLs to
-  // use standard IO even when they are redirected (eg through FFCS).
+  // Getting a pointer to FF stdin and stdout enables extra DLLs to use standard IO even when they are redirected (eg
+  // through FFCS).
+
   void init(); 
+
+  // need #include <iostream>
+  // need #include <sstream>
+  // need using namespace std;
   std::istream *cin();
   std::ostream *cout();
   std::ostream *cerr();
+
+  // <<mingw32_stdout>> Cannot name these functions identically to the original file pointers under MingW32 (compile
+  // error). Impacts [[file:InitFunct.hpp::LOADINITIO]]. Changed from stdxxx_ptr() to ffstdxxx() according to the way FF
+  // itself was changed.
+
   FILE *ffstdout();
   FILE *ffstderr();
   FILE *ffstdin();
 
-  /// Initiate graphical pipe output. I need a separate function for
-  /// this to warn ffcs to check the corresponding ffglut magic number
+  /// Initiate graphical pipe output. I need a separate function for this to warn ffcs to check the corresponding ffglut
+  /// magic number
+
   size_t fwriteinit(const void *ptr, size_t size, size_t nmemb,FILE *stream);
 
-  /// Indicates the begining of a new plot to avoid sending socket
-  /// control data with each plot item.
+  /// Indicates the begining of a new plot to avoid sending socket control data with each plot item.
+
   void newplot();
 
   /// Redefinition of standard system calls
+
   FILE *ff_popen(const char *command, const char *type);
   int ff_pclose(FILE *stream);
   size_t ff_fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
@@ -71,10 +84,9 @@ namespace ffapi{
   // Windows file mode
   // -----------------
 
-  /// Changing file mode needs to be disabled when the file is a TCP
-  /// socket to FFCS. Since the treatment is different in FF and in
-  /// FFS executables, they have to be stored in a DLL that changes
-  /// between these two programs.
+  /// Changing file mode needs to be disabled when the file is a TCP socket to FFCS. Since the treatment is different in
+  /// FF and in FFLANG executables, they have to be stored in a DLL that changes between these two programs.
+
   void wintextmode(FILE *f);
   void winbinmode(FILE *f);
 
@@ -83,6 +95,14 @@ namespace ffapi{
 
   void mpi_init(int &argc, char **& argv);
   void mpi_finalize();
+
+  // Permanent server control
+  // ------------------------
+
+  /// if true, FF is considered to be accessible from remote anonymous connections and some commands (like shell
+  /// commands) are not allowed.
+
+  bool protectedservermode();
 }
 
 #endif //FFAPI_HPP
diff --git a/src/fflib/ffstack.hpp b/src/fflib/ffstack.hpp
index 7a96e42..bb102ab 100644
--- a/src/fflib/ffstack.hpp
+++ b/src/fflib/ffstack.hpp
@@ -1,3 +1,5 @@
+/// \file
+
 // -*- Mode : c++ -*-
 //
 // SUMMARY  :      
@@ -95,6 +97,7 @@ struct StackType;
 
 //typedef void *Stack;
 
+/// Stack used by CListOfInst::eval()
 typedef StackType & Stack;
 
 struct StackType {
@@ -204,7 +207,8 @@ public:
 	      { 
 		topmemory4tmp=0;// clean the tmp allocation 
 	        if(stackptr.size()>=20 && verbosity>2) 
-	           cout << "\n\t\t ### big?? ptr/lg clean " << stackptr.size() << " ptr's\n ";
+		  //FFCS: nothing on following line for tests/compare
+	           cout << "\n\t\t ### big?? ptr/lg clean " << stackptr.size() << " ptr's\n";
 		
 		for (iterator i=stackptr.end(); i != stackptr.begin();)
 		{
@@ -353,6 +357,8 @@ inline void deleteStack(Stack s)
  }
 #else
 //  a faire ....
+
+/// Called to create a new #Stack used to evaluate a FreeFem++ script in CListOfInst::eval()
 inline Stack newStack(size_t l)
  {
 /*  Stack thestack = new char[l];
diff --git a/src/fflib/global.cpp b/src/fflib/global.cpp
index ce90d91..2d14046 100644
--- a/src/fflib/global.cpp
+++ b/src/fflib/global.cpp
@@ -1,3 +1,5 @@
+/// \file
+
 // -*- Mode : c++ -*-
 //
 // SUMMARY  :      
@@ -67,7 +69,9 @@ Map_type_of_map map_pair_of_type ; //  to store te type
  Polymorphic * TheOperators=0, //=new Polymorphic(), 
              * TheRightOperators=0; //=new Polymorphic();
 
- TableOfIdentifier Global;
+/// <<Global>> Contains all FreeFem++ language keywords. Declaration in [[file:AFunction.hpp::Global]]
+
+TableOfIdentifier Global;
 
  long E_Border::Count =0;
 
diff --git a/src/fflib/lex.hpp b/src/fflib/lex.hpp
index 4562ee2..0733697 100644
--- a/src/fflib/lex.hpp
+++ b/src/fflib/lex.hpp
@@ -1,3 +1,5 @@
+/// \file
+
 // -*- Mode : c++ -*-
 //
 // SUMMARY  :      
diff --git a/src/fflib/lgfem.cpp b/src/fflib/lgfem.cpp
index 0d69c09..44d9c99 100644
--- a/src/fflib/lgfem.cpp
+++ b/src/fflib/lgfem.cpp
@@ -1,3 +1,4 @@
+/// \file
 // -*- Mode : c++ -*-
 //
 // SUMMARY  :      
@@ -2393,7 +2394,7 @@ class Plot :  public E_F0mps { public:
    static basicAC_F0::name_and_type name_param[] ;
 
   // FFCS: added new parameters for VTK graphics
-  static const int n_name_param =41 ;
+  static const int n_name_param =42 ;
    Expression bb[4];
     vector<Expression2> l;
     Expression nargs[n_name_param];
@@ -2546,8 +2547,8 @@ class Plot :  public E_F0mps { public:
   {   "prev", &typeid(bool)}, // keep previou  view point  
   {   "ech", &typeid(double)}, // keep previou  view point 
      
-  // FFCS: more options for VTK graphics (numbers are required for
-  // processing)
+  // FFCS: more options for VTK graphics (numbers are required for processing)
+
   {"ZScale",&typeid(double)}, // #1
   {"WhiteBackground",&typeid(bool)}, // #2
   {"OpaqueBorders",&typeid(bool)}, // #3
@@ -2567,7 +2568,8 @@ class Plot :  public E_F0mps { public:
   {"CameraClippingRange",&typeid(KN_<double>)}, // #17
   {"CutPlaneOrigin",&typeid(KN_<double>)}, // #18
   {"CutPlaneNormal",&typeid(KN_<double>)}, // #19
-  {"WindowIndex",&typeid(long)} // #20
+  {"WindowIndex",&typeid(long)}, // #20
+  {"NbColorTicks",&typeid(long)}, // #21
 
    };
 
@@ -2679,7 +2681,7 @@ struct set_eqvect_fl: public binary_function<KN<K>*,const  FormLinear *,KN<K>*>
  bool all=true; 
  if(dim==2)
  if (verbosity>3) 
-   if (CDomainOfIntegration::int1d==kind) cout << "  -- boundary int border ( nQP: "<< FIE.n << ") ,"  ;
+   if (CDomainOfIntegration::int1d==kind) cout << "  -- boundary int border ( nQP: "<< FIE.n << ") levelset: "<< di->islevelset() << " ,"  ;
    else  if (CDomainOfIntegration::intalledges==kind) cout << "  -- boundary int all edges ( nQP: "<< FIE.n << "),"  ;
    else  if (CDomainOfIntegration::intallVFedges==kind) cout << "  -- boundary int all VF edges nQP: ("<< FIE.n << ")," ;
    else cout << "  --  int    (nQP: "<< FIT.n << " ) in "  ;
@@ -2707,19 +2709,73 @@ struct set_eqvect_fl: public binary_function<KN<K>*,const  FormLinear *,KN<K>*>
      all=false;
    }
  */
+  if(di->islevelset() && (CDomainOfIntegration::int1d!=kind) ) InternalError("So no levelset integration type on no int1d case (10)");
+      
  if(dim==2)
    {
      const Mesh  & Th = * GetAny<pmesh>( (*di->Th)(stack) );
      ffassert(&Th);
      
      if (verbosity >3) 
+     {
        if (all) cout << " all " << endl ;
        else cout << endl;
-     
+     }
      if (kind==CDomainOfIntegration::int1d)
        {
 	 const QuadratureFormular1d & FI = FIE;
-         
+           if(di->islevelset())
+           {
+               double llevelset = 0;
+               double uset = HUGE_VAL;
+               R2 Q[3];
+               KN<double> phi(Th.nv);phi=uset;
+               double f[3];
+               for(int t=0; t< Th.nt;++t)
+               {
+                   double umx=-HUGE_VAL,umn=HUGE_VAL;
+                   for(int i=0;i<3;++i)
+                   {
+                       int j= Th(t,i);
+                       if( phi[j]==uset)
+                       {
+                           MeshPointStack(stack)->setP(&Th,t,i);
+                           phi[j]= di->levelset(stack);//zzzz
+                       }
+                       f[i]=phi[j];
+                       umx = std::max(umx,phi[j]);
+                       umn = std::min(umn,phi[j]);
+                       
+                   }
+                   if( umn <=0 && umx >= 0)
+                   {
+                      
+                       int np= IsoLineK(f,Q,1e-10);
+                       if(np==2)
+                       {
+                           const Triangle & K(Th[t]);
+                           R2 PA(K(Q[0])),PB(K(Q[1]));
+                           R2 NAB(PA,PB);
+                           double  lAB=sqrt((NAB,NAB));
+                           NAB = NAB.perp()/lAB;
+                           llevelset += lAB;
+                           for (int npi=0;npi<FI.n;npi++) // loop on the integration point
+                           {
+                               QuadratureFormular1dPoint pi( FI[npi]);
+                               double sa=pi.x,sb=1.-sa;
+                               R2 Pt(Q[0]*sa+Q[1]*sb ); //
+                               MeshPointStack(stack)->set(Th,K(Pt),Pt,K,-1,NAB,-1);
+                               r += lAB*pi.a*GetAny<R>( (*fonc)(stack));
+                           }
+                       }
+                       
+                   }
+               }
+               if(verbosity > 5) cout << " Lenght level set = " << llevelset << endl;
+               
+           }
+
+        else
 	 for( int e=0;e<Th.neb;e++)
 	   {
 	     if (all || setoflab.find(Th.bedges[e].lab) != setoflab.end())   
@@ -3155,9 +3211,8 @@ AnyType Plot::operator()(Stack s) const  {
 	if (nargs[19]) theplot<< 19L  <= GetAny<bool>((*nargs[19])(s));	
 	if (nargs[20]) theplot<< 20L  <= (echelle=GetAny<double>((*nargs[20])(s)));	
 
-	// FFCS: extra plot options for VTK (indexed from 1 to keep
-	// these lines unchanged even if the number of standard FF
-	// parameters above changes)
+	// FFCS: extra plot options for VTK (indexed from 1 to keep these lines unchanged even if the number of standard
+	// FF parameters above changes) received in [[file:../../../../src/visudata.cpp::receiving_plot_parameters]]
 
 #define VTK_START 20
 #define SEND_VTK_PARAM(index,type)					\
@@ -3185,6 +3240,7 @@ AnyType Plot::operator()(Stack s) const  {
 	SEND_VTK_PARAM(18,KN_<double>); // CutPlaneOrigin
 	SEND_VTK_PARAM(19,KN_<double>); // CutPlaneNormal
 	SEND_VTK_PARAM(20,long); // WindowIndex
+	SEND_VTK_PARAM(21,long); // NbColorTicks
 
 	theplot.SendEndArgPlot();
 	map<const Mesh *,long> mapth;
@@ -4602,6 +4658,8 @@ void  init_lgfem()
  basicForEachType * t_fbilin=atype<const  FormBilinear *>();
  basicForEachType * t_flin=atype<const  FormLinear *>();
  basicForEachType * t_BC=atype<const BC_set *>();
+
+ /// Doxygen doc
  basicForEachType * t_form=atype<const C_args*>();
 
   Dcl_Type<const CDomainOfIntegration *>();
@@ -4751,7 +4809,7 @@ TheOperators->Add("^", new OneBinaryOperatorA_inv<R>());
  
 //  new type  
  zzzfff->Add("R3",atype<R3*>());
- zzzfff->Add("mesh",atype<pmesh*>());
+ zzzfff->Add("mesh",atype<pmesh*>()); // <<mesh_keyword>>
  zzzfff->Add("mesh3",atype<pmesh3*>());
  zzzfff->Add("element",atype<lgElement>());
  zzzfff->Add("vertex",atype<lgVertex>());
@@ -4773,8 +4831,7 @@ TheOperators->Add("^", new OneBinaryOperatorA_inv<R>());
 //    Global.Add("LinearCG","(",new LinearCG<Complex>(1)); //  without right handsize
 //    Global.Add("NLCG","(",new LinearCG<Complex>(-1)); //  without right handsize
    
-    
- zzzfff->AddF("varf",t_form);    //  var. form ~
+ zzzfff->AddF("varf",t_form);    //  var. form ~  <<varf>>
  zzzfff->AddF("solve",t_solve);
  zzzfff->AddF("problem",t_problem);
  
diff --git a/src/fflib/lgfem.hpp b/src/fflib/lgfem.hpp
index 828a708..1a63db0 100644
--- a/src/fflib/lgfem.hpp
+++ b/src/fflib/lgfem.hpp
@@ -464,51 +464,6 @@ int GetPeriodic(Expression  bb, Expression & b,Expression & f);
 int GetPeriodic(Expression  bb, Expression & b,Expression & f1,Expression & f2);
 
 
-/*
-template<class K,int dim>
-class FE  { public:
-
-  const pfes  *pVh; // pointeur sur la variable stockant FESpace;
-  CountPointer<FESpace> Vh; // espace courant 
-  virtual KN<K> *x() {return xx;}
-  KN<K> * xx; // value
-  int componante; 
-  FE(const pfes  *ppVh,int comp=0) :pVh(ppVh), xx(0),Vh(0),componante(comp) {}
-  void destroy() { delete this;}
-  virtual ~FE() { delete xx;}
-  virtual  void operator=( KN<K> *y) { Vh=**pVh; 
-       throwassert((bool) Vh);
-       if (xx) delete xx;xx=y;
-       throwassert( y->N() == Vh->NbOfDF);}
- virtual  FESpace * newVh() { throwassert(*pVh);return **pVh;}
- virtual FE<K> * set()  {return this;};
- operator  FESpace &() {set(); throwassert(Vh); return *Vh;}
-   
-   private:
-     FE(const FE &);
-     void operator= (const FE &); 
-};
-// bof bof pour test 
-/*
-template<class K,int comp>
-class FE_ : public FE<K>{public:
-
-  FE<K>  ** pere;
-  FE_(FE<K> ** p) : FE<K>(0,comp),pere(p) {}
-  operator FE<K>  * () { return new FE<K>(*pere,comp);}
-  void destroy() { delete this;}    
-  FE<K> * set() {throwassert(pere && *pere); xx=(**pere).xx;pVh=(**pere).pVh; Vh =(**pere).Vh;return this; }
-  FESpace * newVh() { return **(**pere).pVh;}
-  virtual ~FE_() { xx=0; }// pour ne pas  detruire les valeurs qui seront detruit quant le pere serat detruit
-  virtual KN<K> *x() {return (**pere).x() ;}
-  
-  void operator=( KN<K> *y) { 
-       **pere=y;
-       set();}
-  
-};
-
-*/
 C_F0 NewFEarray(const char * id,Block *currentblock,C_F0 & fespacetype,CC_F0 init,bool cplx,int dim);
 C_F0 NewFEarray(ListOfId * ids,Block *currentblock,C_F0 & fespacetype,CC_F0 init,bool cplx,int dim);
 C_F0 NewFEvariable(const char * id,Block *currentblock,C_F0 & fespacetype,CC_F0 init,bool cplx,int dim);
diff --git a/src/fflib/lgmat.cpp b/src/fflib/lgmat.cpp
index dd9db16..dfbfc83 100644
--- a/src/fflib/lgmat.cpp
+++ b/src/fflib/lgmat.cpp
@@ -411,7 +411,7 @@ basicAC_F0::name_and_type  SetMatrix_Op<R>::name_param[]= {
 /*
    {   "paramint",&typeid(KN<int>)}, // Add J. Morice 02/09 
    {   "paramdouble",&typeid(KN<double>)},
->>>>>>> 1.42
+
    {   "paramstring",&typeid(string*)},
    {   "permrow",&typeid(KN_<long>)},
    {   "permcol",&typeid(KN_<long>)},
diff --git a/src/fflib/lgmesh.cpp b/src/fflib/lgmesh.cpp
index 449158f..767d9d9 100644
--- a/src/fflib/lgmesh.cpp
+++ b/src/fflib/lgmesh.cpp
@@ -1285,6 +1285,7 @@ Mesh * Carre(int nx,int ny,Expression fx,Expression fy,Stack stack,int flags,KN_
 
 }
 
+/// Creates a square mesh by calling Carre() at script evaluation time
 class MeshCarre2 :   public E_F0mps { public:
     typedef pmesh  Result;
      Expression nx,ny;
@@ -1323,7 +1324,7 @@ class MeshCarre2 :   public E_F0mps { public:
 
 
 
-
+/// Creates a square mesh by calling Carre() at script evaluation time
 class MeshCarre2f :   public E_F0mps { public:
     typedef pmesh  Result;
      Expression nx,ny;
diff --git a/src/fflib/load.cpp b/src/fflib/load.cpp
index 90fcf8c..9478f59 100644
--- a/src/fflib/load.cpp
+++ b/src/fflib/load.cpp
@@ -46,10 +46,21 @@ using namespace std;
 #include <windows.h>
 #endif
 
+#include "ffapi.hpp"
+
 set<string> SetLoadFile;
 
 bool load(string ss)
 {
+
+  // FFCS - do not allow potentially dangerous commands from remote anonymous clients
+
+  if(ffapi::protectedservermode() && (ss=="pipe" || ss=="shell")){
+    cerr<<"library "<<ss<<" not allowed in server environment"<<endl;
+    CompileError("Error load");
+    return 0;
+  }
+
   if(SetLoadFile.find(ss) != SetLoadFile.end())
     { 
       if( (mpirank==0)&& verbosity)
@@ -87,6 +98,12 @@ bool load(string ss)
 #ifdef LOAD  
 	      handle = dlopen (s.c_str(), RTLD_LAZY ); 
 	      if (verbosity>9) cout << " test dlopen(" << s << ")= " << handle <<  endl;
+
+	      // FFCS - 20/9/11 - print explanation for load errors
+	      if(verbosity>9 && !handle){
+		cout<<"load error was: "<<dlerror()<<endl;
+	      }
+
 	      ret= handle !=0;
 	      if (  ret ) 
 		{
diff --git a/src/fflib/problem.cpp b/src/fflib/problem.cpp
index 33fe183..4b5ee27 100644
--- a/src/fflib/problem.cpp
+++ b/src/fflib/problem.cpp
@@ -105,6 +105,101 @@ namespace Fem2D {
     void  Expandsetoflab(Stack stack,const BC_set & bc,set<long> & setoflab);
 // 
 
+int IsoLineK(double *f,R2 *Q,double eps)
+    {
+        int debug=0;
+        R2 P[3]={ R2(0.,0.),R2(1.,0.),R2(0.,1.)};
+        int kv=0,ke=0,e=3;
+        int tv[3],te[3],vk[3],i0[3],i1[3];
+        for(int i=0;i<3;++i)
+        {
+            if( abs(f[i]) <= eps) {
+                e -= tv[kv++]=i;
+                vk[i]=1;
+            }
+            else
+                vk[i]=0;
+        }
+        if(debug) cout << " ** " <<     kv << endl;
+        if(kv>1) //  on 2  vertex on the isoline ....
+        {
+            if(kv==2)
+            {
+                if(f[e] > 0.)
+                {
+                    int j0=(e+1)%3;
+                    int j1=(e+2)%3;
+                    te[ke]=e+3,i0[ke]=j0,i1[ke]=j0,++ke;
+                    te[ke]=e,i0[ke]=j1,i1[ke]=j1,++ke;
+                    // pb d'unicity, need to see the adj triangle ...
+                    //return 10+e ; // edge number + 10
+                }
+                else return 0; // skip edge ...
+                
+            }
+            else return 0; //  const funct...
+        }
+        else // see internal edge ..
+            for(int e=0;e<3;++e)
+            {
+                int j0=(e+1)%3;
+                int j1=(e+2)%3;
+                if( vk[j0]) //  the intial  point on iso line
+                {
+                    if(0. < f[j1])
+                        te[ke]=e,i0[ke]=j0,i1[ke]=j0,++ke;
+                    else
+                        te[ke]=e+3,i0[ke]=j0,i1[ke]=j0,++ke;
+                }
+                else if (vk[j1]); // skip the final point on iso line
+                else if( f[j0] < 0. && 0. < f[j1])  // good  sens
+                    te[ke]=e,i0[ke]=j0,i1[ke]=j1,++ke;
+                else if ( f[j0] > 0. && 0. > f[j1]) // inverse  sens
+                    te[ke]=e+3,i0[ke]=j1,i1[ke]=j0,++ke;
+            }
+        if( ke==2)
+        {
+            // the  K[i1[0]] , Q[0], Q[1] must be direct ...
+            // the  K[i0[1]] , Q[0], Q[1] must be direct ...
+            // Warning   no trivail case ..  make a plot to see
+            //  with is good
+            // the first edge must be
+            
+            if(te[0]<3)  // oriente the line
+            {
+                assert(te[1] >=3);
+                std::swap(te[0],te[1]);
+                std::swap(i0[0],i0[1]);
+                std::swap(i1[0],i1[1]);
+                if(debug) cout << " swap " << endl;
+            }
+            for(int i=0;i<2;++i)
+            {
+                int j0=i0[i],j1=i1[i];
+                if( j0== j1)
+                    Q[i] = P[j0];
+                else
+                    Q[i] = (P[j0]*(f[j1]) -  P[j1]*(f[j0]) ) /(f[j1]-f[j0]);
+                if(debug) cout << i << " " << j0 << " " << j1 << " : "
+                    << Q[i] << "***" << endl;
+            }
+            if(debug)
+            {
+                cout << "i0 " << i0[0] << " " << i0[1] << " " << det(P[i1[0]],Q[0],Q[1]) <<endl;
+                cout << "i1 " << i1[0] << " " << i1[1] << " " << det(P[i0[1]],Q[1],Q[0]) <<endl;
+                cout << "f " << f[0] << " " << f[1] << " " << f[2] << endl;
+                cout << "P " << P[0] << ", " << P[1] << ", " << P[2] << endl;
+                cout << "Q " << Q[0] << ", " << Q[1]  << endl;
+            }
+            if(!vk[i1[0]])
+                assert( det(P[i1[0]],Q[0],Q[1]) > 0);
+            if(!vk[i0[1]])
+                assert( det(P[i0[1]],Q[1],Q[0]) > 0);
+            return 2;
+        }
+        // remark, the left of the line is upper .
+        return 0;
+    }
 
 void Check(const Opera &Op,int N,int  M)
  {
@@ -373,7 +468,11 @@ void Check(const Opera &Op,int N,int  M)
     //const vector<Expression>  & what(di.what);             
     CDomainOfIntegration::typeofkind  kind = di.kind;
     set<int> setoflab;
-    bool all=true; 
+    bool all=true;
+     
+    const Mesh & ThI = Th;//* GetAny<pmesh>( (* di.Th)(stack));
+    bool sameMesh = &ThI == &Vh.Th &&  &ThI == &Uh.Th;
+    
     const QuadratureFormular1d & FIE = di.FIE(stack);
     const QuadratureFormular & FIT = di.FIT(stack);
     bool VF=b->VF();  // finite Volume or discontinous Galerkin
@@ -383,6 +482,9 @@ void Check(const Opera &Op,int N,int  M)
       else  if (CDomainOfIntegration::intalledges==kind) cout << "  -- boundary int all edges ( nQP: "<< FIE.n << "),"  ;
       else  if (CDomainOfIntegration::intallVFedges==kind) cout << "  -- boundary int all VF edges nQP: ("<< FIE.n << ")," ;
       else cout << "  --  int    (nQP: "<< FIT.n << " ) in "  ;
+     //if(di.islevelset()) InternalError("So no levelset integration type on this case (6)");
+     if(di.islevelset() && (CDomainOfIntegration::int1d!=kind) ) InternalError("So no levelset integration type on no int1d case (6)");
+     
     Expandsetoflab(stack,di, setoflab,all);
    /*
     for (size_t i=0;i<what.size();i++)
@@ -472,7 +574,48 @@ void Check(const Opera &Op,int N,int  M)
     
     if (di.kind == CDomainOfIntegration::int1d )
       {
-        for( int e=0;e<Th.neb;e++)
+          if(di.islevelset())
+          {
+              double uset = HUGE_VAL;
+              R2 Q[3];
+              KN<double> phi(ThI.nv);phi=uset;
+              double f[3];
+              for(int t=0; t< ThI.nt;++t)
+              {
+                  double umx=-HUGE_VAL,umn=HUGE_VAL;
+                  for(int i=0;i<3;++i)
+                  {
+                      int j= ThI(t,i);
+                      if( phi[j]==uset)
+                      {
+                          MeshPointStack(stack)->setP(&ThI,t,i);
+                          phi[j]= di.levelset(stack);//zzzz
+                      }
+                      f[i]=phi[j];
+                      umx = std::max(umx,phi[j]);
+                      umn = std::min(umn,phi[j]);
+                      
+                  }
+                  if( umn <=0 && umx >= 0)
+                  {
+                      
+                      int np= IsoLineK(f,Q,1e-10);
+                      if(np==2)
+                      {
+                         /* if ( sameMesh)
+                          {
+                           
+                              Element_rhs<R>(Vh[t],*l->l,buf,stack,*B,FIE,Q[0],Q[1]);
+                          }
+                          else*/ 
+                              InternalError(" No levelSet on Diff mesh :    to day  int1d of Matrix");
+                      }
+                      if(sptrclean) sptrclean=sptr->clean();
+                  }
+              }
+              
+          }
+        else for( int e=0;e<Th.neb;e++)
           {
             if (all || setoflab.find(Th.bedges[e].lab) != setoflab.end())   
               {                  
@@ -566,6 +709,9 @@ void Check(const Opera &Op,int N,int  M)
       else  if (CDomainOfIntegration::intalledges==kind) cout << "  -- boundary int all edges ( nQP: "<< FIT.n << "),"  ;
       else  if (CDomainOfIntegration::intallVFedges==kind) cout << "  -- boundary int all VF edges nQP: ("<< FIE.n << ")," ;
       else cout << "  --  int3d   (nQP: "<< FIV.n << " ) in "  ;
+     if(di.islevelset()) InternalError("Sorry no levelset integration type on this case (7) ");
+     if(di.islevelset() && (CDomainOfIntegration::int2d!=kind) ) InternalError("Sorry no levelset integration type on no int2d case");
+     
    Expandsetoflab(stack,di, setoflab,all);
    /*
     for (size_t i=0;i<what.size();i++)
@@ -1206,6 +1352,9 @@ void Check(const Opera &Op,int N,int  M)
       else  if (CDomainOfIntegration::intalledges==kind) cout << "  -- boundary int all edges ( nQP: "<< FIE.n << "),"  ;
       else  if (CDomainOfIntegration::intallVFedges==kind) cout << "  -- boundary int all VF edges nQP: ("<< FIE.n << ")," ;
       else cout << "  --  int    (nQP: "<< FIT.n << " ) in "  ;
+      if(di.islevelset()) InternalError("Sorry no levelset integration type on this case (1)");
+      if(di.islevelset() && (CDomainOfIntegration::int1d!=kind) ) InternalError("Sorry no levelset integration type on no int1d case");
+      
     /*
     if (verbosity>3) 
       if (CDomainOfIntegration::int1d==kind) cout << "  -- boundary int border  " ;
@@ -1364,6 +1513,8 @@ void Check(const Opera &Op,int N,int  M)
           else  if (CDomainOfIntegration::intallfaces==kind) cout << "  -- boundary int all edges ( nQP: "<< FIT.n << "),"  ;
           //else  if (CDomainOfIntegration::intallVFedges==kind) cout << "  -- boundary int all VF edges nQP: ("<< FIT.n << ")," ;
           else cout << "  --  int    (nQP: "<< FIV.n << " ) in "  ;
+      if(di.islevelset()) InternalError("Sorry no levelset integration type on this case (2)");
+      if(di.islevelset() && (CDomainOfIntegration::int2d!=kind) ) InternalError("Sorry no levelset integration type on no int2d case");
    
       Expandsetoflab(stack,di, setoflab,all);
       /*
@@ -2673,7 +2824,8 @@ void Check(const Opera &Op,int N,int  M)
                   pair<int,int> ii(ll.first);
                   double w_i =  wi(ii.first,ii.second);
                   R c =copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
-                if ( copt && Kv.number<1 <1)
+		  // FFCS - removing what is probably a small glitch
+                if ( copt && Kv.number<1)
                  {
                      R cc  =  GetAny<R>(ll.second.eval(stack));
                      if ( c != cc) { 
@@ -2751,7 +2903,8 @@ void Check(const Opera &Op,int N,int  M)
                   pair<int,int> ii(ll.first);
                   double w_i =  wi(ii.first,ii.second);
                   R c =copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
-                if ( copt && Kv.number<1 <1)
+		  // FFCS - removing what is probably a small glitch
+                if ( copt && Kv.number<1)
                  {
                      R cc  =  GetAny<R>(ll.second.eval(stack));
                      if ( c != cc) { 
@@ -2827,7 +2980,8 @@ void Check(const Opera &Op,int N,int  M)
                     pair<int,int> ii(ll.first);
                     double w_i =  wi(ii.first,ii.second);
                     R c =copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
-                    if ( copt && Kv.number<1 <1)
+		  // FFCS - removing what is probably a small glitch
+                    if ( copt && Kv.number<1)
                     {
                         R cc  =  GetAny<R>(ll.second.eval(stack));
                         if ( c != cc) {
@@ -2951,7 +3105,8 @@ void Check(const Opera &Op,int N,int  M)
 			    else  if (iicase==Code_OtherSide) w_i = ww_i;  // valeur de autre cote
 			    }
 			  R c =copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
-			  if ( copt && Kv.number<1 <1)
+		  // FFCS - removing what is probably a small glitch
+			  if ( copt && Kv.number<1)
 			    {
 				R cc  =  GetAny<R>(ll.second.eval(stack));
 				if ( c != cc) { 
@@ -3045,7 +3200,8 @@ void Check(const Opera &Op,int N,int  M)
                       pair<int,int> ii(ll.first);
                       double w_i =  wi(ii.first,ii.second);
                       R c =copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
-                      if ( copt && Kv.number<1 <1)
+		  // FFCS - removing what is probably a small glitch
+                      if ( copt && Kv.number<1)
                       {
                           R cc  =  GetAny<R>(ll.second.eval(stack));
                           if ( c != cc) { 
@@ -3132,7 +3288,8 @@ void Check(const Opera &Op,int N,int  M)
                   pair<int,int> ii(ll.first);
                   double w_i =  wi(ii.first,ii.second);
                   R c =copt ? *(copt[il]) : GetAny<R>(ll.second.eval(stack));
-                if ( copt && Kv.number<1 <1)
+		  // FFCS - removing what is probably a small glitch
+                if ( copt && Kv.number<1)
                  {
                      R cc  =  GetAny<R>(ll.second.eval(stack));
                      if ( c != cc) { 
@@ -3579,7 +3736,8 @@ template<class R>
       else  if (CDomainOfIntegration::intalledges==kind) cout << "  -- boundary int all edges ( nQP: "<< FIT.n << "),"  ;
       else  if (CDomainOfIntegration::intallVFedges==kind) cout << "  -- boundary int all VF edges nQP: ("<< FIT.n << ")," ;
       else cout << "  --  int    (nQP: "<< FIV.n << " ) in "  ;
-    if(di.islevelset()) InternalError("So no levelset intgeration type on the case");
+    if(di.islevelset()) InternalError("So no levelset integration type on this case (3)");
+    if(di.islevelset() && (CDomainOfIntegration::int1d!=kind) ) InternalError("So no levelset intgeration type on no int1d case");
     /*
     if ( verbosity>3) 
       if (kind==CDomainOfIntegration::int1d) cout << "  -- boundary int border " ;
@@ -3760,101 +3918,6 @@ template<class R>
              
   }
 
-static int IsoLineK(double *f,R2 *Q,double eps)
-    {
-        int debug=0;
-        R2 P[3]={ R2(0.,0.),R2(1.,0.),R2(0.,1.)};
-        int kv=0,ke=0,e=3;
-        int tv[3],te[3],vk[3],i0[3],i1[3];
-        for(int i=0;i<3;++i)
-        {
-            if( abs(f[i]) <= eps) {
-                e -= tv[kv++]=i;
-                vk[i]=1;
-            }
-            else
-                vk[i]=0;
-        }
-        if(debug) cout << " ** " <<     kv << endl;
-        if(kv>1) //  on 2  vertex on the isoline ....
-        {
-            if(kv==2)
-            {
-                if(f[e] > 0.)
-                {
-                    int j0=(e+1)%3;
-                    int j1=(e+2)%3;
-                    te[ke]=e+3,i0[ke]=j0,i1[ke]=j0,++ke;
-                    te[ke]=e,i0[ke]=j1,i1[ke]=j1,++ke;
-                    // pb d'unicity, need to see the adj triangle ...
-                    //return 10+e ; // edge number + 10
-                }
-                else return 0; // skip edge ...
-                
-            }
-            else return 0; //  const funct...
-        }
-        else // see internal edge ..
-            for(int e=0;e<3;++e)
-            {
-                int j0=(e+1)%3;
-                int j1=(e+2)%3;
-                if( vk[j0]) //  the intial  point on iso line
-                {
-                    if(0. < f[j1])
-                        te[ke]=e,i0[ke]=j0,i1[ke]=j0,++ke;
-                    else
-                        te[ke]=e+3,i0[ke]=j0,i1[ke]=j0,++ke;
-                }
-                else if (vk[j1]); // skip the final point on iso line
-                else if( f[j0] < 0. && 0. < f[j1])  // good  sens
-                    te[ke]=e,i0[ke]=j0,i1[ke]=j1,++ke;
-                else if ( f[j0] > 0. && 0. > f[j1]) // inverse  sens
-                    te[ke]=e+3,i0[ke]=j1,i1[ke]=j0,++ke;
-            }
-        if( ke==2)
-        {
-            // the  K[i1[0]] , Q[0], Q[1] must be direct ...
-            // the  K[i0[1]] , Q[0], Q[1] must be direct ...
-            // Warning   no trivail case ..  make a plot to see
-            //  with is good
-            // the first edge must be
-            
-            if(te[0]<3)  // oriente the line
-            {
-                assert(te[1] >=3);
-                std::swap(te[0],te[1]);
-                std::swap(i0[0],i0[1]);
-                std::swap(i1[0],i1[1]);
-                if(debug) cout << " swap " << endl;
-            }
-            for(int i=0;i<2;++i)
-            {
-                int j0=i0[i],j1=i1[i];
-                if( j0== j1)
-                    Q[i] = P[j0];
-                else
-                    Q[i] = (P[j0]*(f[j1]) -  P[j1]*(f[j0]) ) /(f[j1]-f[j0]);
-                if(debug) cout << i << " " << j0 << " " << j1 << " : "
-                    << Q[i] << "***" << endl;
-            }
-            if(debug)
-            {
-                cout << "i0 " << i0[0] << " " << i0[1] << " " << det(P[i1[0]],Q[0],Q[1]) <<endl;
-                cout << "i1 " << i1[0] << " " << i1[1] << " " << det(P[i0[1]],Q[1],Q[0]) <<endl;
-                cout << "f " << f[0] << " " << f[1] << " " << f[2] << endl;
-                cout << "P " << P[0] << ", " << P[1] << ", " << P[2] << endl;
-                cout << "Q " << Q[0] << ", " << Q[1]  << endl;
-            }
-            if(!vk[i1[0]])
-                assert( det(P[i1[0]],Q[0],Q[1]) > 0);
-            if(!vk[i0[1]])
-                assert( det(P[i0[1]],Q[1],Q[0]) > 0);
-            return 2;
-        }
-        // remark, the left of the line is upper .
-        return 0;
-    }
 
 template<class R>
  void AssembleLinearForm(Stack stack,const Mesh & Th,const FESpace & Vh,KN_<R> * B,const  FormLinear * l )
@@ -3901,7 +3964,7 @@ template<class R>
       else cout << "  -- boundary int  " ;
     */
     if(di.islevelset() && ((CDomainOfIntegration::int1d!=kind) ) )
-        InternalError("So no levelset integration  on the case");
+        InternalError("So no levelset integration 1d on the case (4)");
     Expandsetoflab(stack,di, setoflab,all);
     /*
     for (size_t i=0;i<what.size();i++)
@@ -3948,7 +4011,7 @@ template<class R>
       if (all) cout << " all " << endl ;
       else cout << endl;
       if(di.islevelset() && (kind !=CDomainOfIntegration::int1d))
-       InternalError(" Sorry No levelSet integral for is case ..");
+       InternalError(" Sorry No levelSet integral for is case ..(5)");
          
 
     if (kind==CDomainOfIntegration::int1d)
diff --git a/src/fflib/problem.hpp b/src/fflib/problem.hpp
index 1da51cd..fdb47f0 100644
--- a/src/fflib/problem.hpp
+++ b/src/fflib/problem.hpp
@@ -34,9 +34,12 @@ template<class K> class MatriceCreuse;
 namespace  Fem2D {
   template<class K> class SolveGCPrecon;
   template<class K> class SolveGMRESPrecon;
-  template<class K> class SolveGMRESDiag;  
+  template<class K> class SolveGMRESDiag;
+  int IsoLineK(double *f,R2 *Q,double eps);
+  
 }
 
+
 template<class K> class SolveGCDiag; 
 class Plot;
 class v_fes;
@@ -1333,6 +1336,6 @@ TypeVarForm() :
 
  static TypeVarForm *Global;
 }; 
-
+   
 }
 #endif
diff --git a/src/fflib/strversionnumber.cpp b/src/fflib/strversionnumber.cpp
index 7cea1e2..2db57a9 100644
--- a/src/fflib/strversionnumber.cpp
+++ b/src/fflib/strversionnumber.cpp
@@ -18,6 +18,6 @@ string StrVersionNumber(){
 //  buffer.precision(8);
 //  buffer<<VersionNumber();
   static char buffer[100];
-  sprintf(buffer," %9f (date Jeu  6 jui 2013 20:58:44 CEST)",VersionNumber());
-  return buffer; //.str()+" (date Jeu  6 jui 2013 20:58:44 CEST)" ;
+  sprintf(buffer," %9f (date Jeu  5 sep 2013 10:54:38 CEST)",VersionNumber());
+  return buffer; //.str()+" (date Jeu  5 sep 2013 10:54:38 CEST)" ;
 }
diff --git a/src/lglib/Makefile.in b/src/lglib/Makefile.in
index 5880f47..dda237f 100644
--- a/src/lglib/Makefile.in
+++ b/src/lglib/Makefile.in
@@ -59,7 +59,8 @@ 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)/acmacros.m4 \
-	$(top_srcdir)/acoptim.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/acoptim.m4 $(top_srcdir)/acmpi.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -185,11 +186,47 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EIGENOBJ = @EIGENOBJ@
+ENABLE_FFCS = @ENABLE_FFCS@
 EPSTOPDF = @EPSTOPDF@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+FFCS_COMPILE_fflapack = @FFCS_COMPILE_fflapack@
+FFCS_COMPILE_gsl = @FFCS_COMPILE_gsl@
+FFCS_COMPILE_hips = @FFCS_COMPILE_hips@
+FFCS_COMPILE_hypre = @FFCS_COMPILE_hypre@
+FFCS_COMPILE_ipopt = @FFCS_COMPILE_ipopt@
+FFCS_COMPILE_lapack = @FFCS_COMPILE_lapack@
+FFCS_COMPILE_mmg3d = @FFCS_COMPILE_mmg3d@
+FFCS_COMPILE_mshmet = @FFCS_COMPILE_mshmet@
+FFCS_COMPILE_mumps = @FFCS_COMPILE_mumps@
+FFCS_COMPILE_mumps_seq = @FFCS_COMPILE_mumps_seq@
+FFCS_COMPILE_pardiso = @FFCS_COMPILE_pardiso@
+FFCS_COMPILE_parms = @FFCS_COMPILE_parms@
+FFCS_COMPILE_pastix = @FFCS_COMPILE_pastix@
+FFCS_COMPILE_pipe = @FFCS_COMPILE_pipe@
+FFCS_COMPILE_scotch = @FFCS_COMPILE_scotch@
+FFCS_COMPILE_superludist = @FFCS_COMPILE_superludist@
+FFCS_COMPILE_yams = @FFCS_COMPILE_yams@
+FFCS_DYLIB_fflapack = @FFCS_DYLIB_fflapack@
+FFCS_DYLIB_gsl = @FFCS_DYLIB_gsl@
+FFCS_DYLIB_hips = @FFCS_DYLIB_hips@
+FFCS_DYLIB_hypre = @FFCS_DYLIB_hypre@
+FFCS_DYLIB_ipopt = @FFCS_DYLIB_ipopt@
+FFCS_DYLIB_lapack = @FFCS_DYLIB_lapack@
+FFCS_DYLIB_mmg3d = @FFCS_DYLIB_mmg3d@
+FFCS_DYLIB_mshmet = @FFCS_DYLIB_mshmet@
+FFCS_DYLIB_mumps = @FFCS_DYLIB_mumps@
+FFCS_DYLIB_mumps_seq = @FFCS_DYLIB_mumps_seq@
+FFCS_DYLIB_pardiso = @FFCS_DYLIB_pardiso@
+FFCS_DYLIB_parms = @FFCS_DYLIB_parms@
+FFCS_DYLIB_pastix = @FFCS_DYLIB_pastix@
+FFCS_DYLIB_pipe = @FFCS_DYLIB_pipe@
+FFCS_DYLIB_scotch = @FFCS_DYLIB_scotch@
+FFCS_DYLIB_superludist = @FFCS_DYLIB_superludist@
+FFCS_DYLIB_yams = @FFCS_DYLIB_yams@
+FFCS_MAKEFLAGS = @FFCS_MAKEFLAGS@
 FFGLUTNAME = @FFGLUTNAME@
 FFGLUTPROG = @FFGLUTPROG@
 FFLAGS = @FFLAGS@
diff --git a/src/lglib/lg.tab.cpp b/src/lglib/lg.tab.cpp
index 8b31eb7..3866db5 100644
--- a/src/lglib/lg.tab.cpp
+++ b/src/lglib/lg.tab.cpp
@@ -1,24 +1,21 @@
-/* A Bison parser, made by GNU Bison 2.3.  */
+/* A Bison parser, made by GNU Bison 2.7.12-4996.  */
 
-/* Skeleton implementation for Bison's Yacc-like parsers in C
-
-   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
-   Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or modify
+/* Bison implementation for Yacc-like parsers in C
+   
+      Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
+   
+   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 2, or (at your option)
-   any later version.
-
+   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, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 /* As a special exception, you may create a larger work that contains
    part or all of the Bison parser skeleton and distribute that work
@@ -29,7 +26,7 @@
    special exception, which will cause the skeleton and the resulting
    Bison output files to be licensed under the GNU General Public
    License without this special exception.
-
+   
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
@@ -47,7 +44,7 @@
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "2.3"
+#define YYBISON_VERSION "2.7.12-4996"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
@@ -55,133 +52,24 @@
 /* Pure parsers.  */
 #define YYPURE 0
 
-/* Using locations.  */
-#define YYLSP_NEEDED 0
-
-/* Substitute the variable and function names.  */
-#define yyparse lgparse
-#define yylex   lglex
-#define yyerror lgerror
-#define yylval  lglval
-#define yychar  lgchar
-#define yydebug lgdebug
-#define yynerrs lgnerrs
-
-
-/* Tokens.  */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
-   /* Put the tokens into the symbol table, so that GDB and other debuggers
-      know about them.  */
-   enum yytokentype {
-     IF = 258,
-     ELSE = 259,
-     SET = 260,
-     GTGT = 261,
-     LTLT = 262,
-     OR = 263,
-     AND = 264,
-     NE = 265,
-     EQ = 266,
-     GE = 267,
-     LE = 268,
-     DOTSLASH = 269,
-     DOTSTAR = 270,
-     MOINSMOINS = 271,
-     PLUSPLUS = 272,
-     UNARY = 273,
-     LNUM = 274,
-     DNUM = 275,
-     CNUM = 276,
-     ID = 277,
-     FESPACEID = 278,
-     IDPARAM = 279,
-     STRING = 280,
-     ENDOFFILE = 281,
-     INCLUDE = 282,
-     LOAD = 283,
-     BIDON = 284,
-     FOR = 285,
-     WHILE = 286,
-     BREAK = 287,
-     CONTINUE = 288,
-     RETURN = 289,
-     TRY = 290,
-     CATCH = 291,
-     THROW = 292,
-     TYPE = 293,
-     FUNCTION = 294,
-     FESPACE = 295,
-     FESPACE1 = 296,
-     FESPACE3 = 297,
-     PLUSEQ = 298,
-     MOINSEQ = 299,
-     MULEQ = 300,
-     DIVEQ = 301,
-     DOTMULEQ = 302,
-     DOTDIVEQ = 303,
-     ARROW = 304,
-     BORDER = 305,
-     CURVE = 306,
-     SOLVE = 307
-   };
-#endif
-/* Tokens.  */
-#define IF 258
-#define ELSE 259
-#define SET 260
-#define GTGT 261
-#define LTLT 262
-#define OR 263
-#define AND 264
-#define NE 265
-#define EQ 266
-#define GE 267
-#define LE 268
-#define DOTSLASH 269
-#define DOTSTAR 270
-#define MOINSMOINS 271
-#define PLUSPLUS 272
-#define UNARY 273
-#define LNUM 274
-#define DNUM 275
-#define CNUM 276
-#define ID 277
-#define FESPACEID 278
-#define IDPARAM 279
-#define STRING 280
-#define ENDOFFILE 281
-#define INCLUDE 282
-#define LOAD 283
-#define BIDON 284
-#define FOR 285
-#define WHILE 286
-#define BREAK 287
-#define CONTINUE 288
-#define RETURN 289
-#define TRY 290
-#define CATCH 291
-#define THROW 292
-#define TYPE 293
-#define FUNCTION 294
-#define FESPACE 295
-#define FESPACE1 296
-#define FESPACE3 297
-#define PLUSEQ 298
-#define MOINSEQ 299
-#define MULEQ 300
-#define DIVEQ 301
-#define DOTMULEQ 302
-#define DOTDIVEQ 303
-#define ARROW 304
-#define BORDER 305
-#define CURVE 306
-#define SOLVE 307
+/* Push parsers.  */
+#define YYPUSH 0
 
+/* Pull parsers.  */
+#define YYPULL 1
 
 
+/* Substitute the variable and function names.  */
+#define yyparse         lgparse
+#define yylex           lglex
+#define yyerror         lgerror
+#define yylval          lglval
+#define yychar          lgchar
+#define yydebug         lgdebug
+#define yynerrs         lgnerrs
 
 /* Copy the first part of user declarations.  */
+/* Line 371 of yacc.c  */
 #line 1 "lg.ypp"
  
     // -*- Mode : c++ -*-
@@ -305,11 +193,16 @@ void (*initparallele)(int &argc, char **& argv)=0 ;
 void (*init_lgparallele)()=0;
 void (*end_parallele)()=0;
 
+/* Line 371 of yacc.c  */
+#line 198 "lg.tab.cpp"
 
-/* Enabling traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG 1
-#endif
+# ifndef YY_NULL
+#  if defined __cplusplus && 201103L <= __cplusplus
+#   define YY_NULL nullptr
+#  else
+#   define YY_NULL 0
+#  endif
+# endif
 
 /* Enabling verbose error messages.  */
 #ifdef YYERROR_VERBOSE
@@ -319,15 +212,84 @@ void (*end_parallele)()=0;
 # define YYERROR_VERBOSE 0
 #endif
 
-/* Enabling the token table.  */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
+/* In a future release of Bison, this section will be replaced
+   by #include "lg.tab.hpp".  */
+#ifndef YY_LG_LG_TAB_HPP_INCLUDED
+# define YY_LG_LG_TAB_HPP_INCLUDED
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 1
+#endif
+#if YYDEBUG
+extern int lgdebug;
+#endif
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     IF = 258,
+     ELSE = 259,
+     SET = 260,
+     GTGT = 261,
+     LTLT = 262,
+     OR = 263,
+     AND = 264,
+     NE = 265,
+     EQ = 266,
+     GE = 267,
+     LE = 268,
+     DOTSLASH = 269,
+     DOTSTAR = 270,
+     MOINSMOINS = 271,
+     PLUSPLUS = 272,
+     UNARY = 273,
+     LNUM = 274,
+     DNUM = 275,
+     CNUM = 276,
+     ID = 277,
+     FESPACEID = 278,
+     IDPARAM = 279,
+     STRING = 280,
+     ENDOFFILE = 281,
+     INCLUDE = 282,
+     LOAD = 283,
+     BIDON = 284,
+     FOR = 285,
+     WHILE = 286,
+     BREAK = 287,
+     CONTINUE = 288,
+     RETURN = 289,
+     TRY = 290,
+     CATCH = 291,
+     THROW = 292,
+     TYPE = 293,
+     FUNCTION = 294,
+     FESPACE = 295,
+     FESPACE1 = 296,
+     FESPACE3 = 297,
+     PLUSEQ = 298,
+     MOINSEQ = 299,
+     MULEQ = 300,
+     DIVEQ = 301,
+     DOTMULEQ = 302,
+     DOTDIVEQ = 303,
+     ARROW = 304,
+     BORDER = 305,
+     CURVE = 306,
+     SOLVE = 307
+   };
 #endif
 
+
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
+{
+/* Line 387 of yacc.c  */
 #line 124 "lg.ypp"
-{ 
+ 
  double dnum;
  long lnum;
  char * str;
@@ -340,22 +302,38 @@ typedef union YYSTYPE
  Block * block; 
  ListOfId *clist_id;
 /* ListCatch * clist_Catchs;*/
-}
-/* Line 193 of yacc.c.  */
-#line 346 "lg.tab.cpp"
-	YYSTYPE;
+
+
+/* Line 387 of yacc.c  */
+#line 309 "lg.tab.cpp"
+} YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
-# define YYSTYPE_IS_TRIVIAL 1
 #endif
 
+extern YYSTYPE lglval;
 
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int lgparse (void *YYPARSE_PARAM);
+#else
+int lgparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int lgparse (void);
+#else
+int lgparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
 
-/* Copy the second part of user declarations.  */
+#endif /* !YY_LG_LG_TAB_HPP_INCLUDED  */
 
+/* Copy the second part of user declarations.  */
 
-/* Line 216 of yacc.c.  */
-#line 359 "lg.tab.cpp"
+/* Line 390 of yacc.c  */
+#line 337 "lg.tab.cpp"
 
 #ifdef short
 # undef short
@@ -408,36 +386,45 @@ typedef short int yytype_int16;
 # if defined YYENABLE_NLS && YYENABLE_NLS
 #  if ENABLE_NLS
 #   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#   define YY_(Msgid) dgettext ("bison-runtime", Msgid)
 #  endif
 # endif
 # ifndef YY_
-#  define YY_(msgid) msgid
+#  define YY_(Msgid) Msgid
+# endif
+#endif
+
+#ifndef __attribute__
+/* This feature is available in gcc versions 2.5 and later.  */
+# if (! defined __GNUC__ || __GNUC__ < 2 \
+      || (__GNUC__ == 2 && __GNUC_MINOR__ < 5))
+#  define __attribute__(Spec) /* empty */
 # endif
 #endif
 
 /* Suppress unused-variable warnings by "using" E.  */
 #if ! defined lint || defined __GNUC__
-# define YYUSE(e) ((void) (e))
+# define YYUSE(E) ((void) (E))
 #else
-# define YYUSE(e) /* empty */
+# define YYUSE(E) /* empty */
 #endif
 
+
 /* Identity function, used to suppress warnings about constant conditions.  */
 #ifndef lint
-# define YYID(n) (n)
+# define YYID(N) (N)
 #else
 #if (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 static int
-YYID (int i)
+YYID (int yyi)
 #else
 static int
-YYID (i)
-    int i;
+YYID (yyi)
+    int yyi;
 #endif
 {
-  return i;
+  return yyi;
 }
 #endif
 
@@ -458,11 +445,12 @@ YYID (i)
 #    define alloca _alloca
 #   else
 #    define YYSTACK_ALLOC alloca
-#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 #     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#     ifndef _STDLIB_H
-#      define _STDLIB_H 1
+      /* Use EXIT_SUCCESS as a witness for stdlib.h.  */
+#     ifndef EXIT_SUCCESS
+#      define EXIT_SUCCESS 0
 #     endif
 #    endif
 #   endif
@@ -485,24 +473,24 @@ YYID (i)
 #  ifndef YYSTACK_ALLOC_MAXIMUM
 #   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
 #  endif
-#  if (defined __cplusplus && ! defined _STDLIB_H \
+#  if (defined __cplusplus && ! defined EXIT_SUCCESS \
        && ! ((defined YYMALLOC || defined malloc) \
 	     && (defined YYFREE || defined free)))
 #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#   ifndef _STDLIB_H
-#    define _STDLIB_H 1
+#   ifndef EXIT_SUCCESS
+#    define EXIT_SUCCESS 0
 #   endif
 #  endif
 #  ifndef YYMALLOC
 #   define YYMALLOC malloc
-#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+#   if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
 #   endif
 #  endif
 #  ifndef YYFREE
 #   define YYFREE free
-#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+#   if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 void free (void *); /* INFRINGES ON USER NAME SPACE */
 #   endif
@@ -518,9 +506,9 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
 /* A type that is properly aligned for any stack member.  */
 union yyalloc
 {
-  yytype_int16 yyss;
-  YYSTYPE yyvs;
-  };
+  yytype_int16 yyss_alloc;
+  YYSTYPE yyvs_alloc;
+};
 
 /* The size of the maximum gap between one aligned stack and the next.  */
 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
@@ -531,35 +519,19 @@ union yyalloc
      ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
       + YYSTACK_GAP_MAXIMUM)
 
-/* Copy COUNT objects from FROM to TO.  The source and destination do
-   not overlap.  */
-# ifndef YYCOPY
-#  if defined __GNUC__ && 1 < __GNUC__
-#   define YYCOPY(To, From, Count) \
-      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
-#  else
-#   define YYCOPY(To, From, Count)		\
-      do					\
-	{					\
-	  YYSIZE_T yyi;				\
-	  for (yyi = 0; yyi < (Count); yyi++)	\
-	    (To)[yyi] = (From)[yyi];		\
-	}					\
-      while (YYID (0))
-#  endif
-# endif
+# define YYCOPY_NEEDED 1
 
 /* Relocate STACK from its old location to the new one.  The
    local variables YYSIZE and YYSTACKSIZE give the old and new number of
    elements in the stack, and YYPTR gives the new location of the
    stack.  Advance YYPTR to a properly aligned location for the next
    stack.  */
-# define YYSTACK_RELOCATE(Stack)					\
+# define YYSTACK_RELOCATE(Stack_alloc, Stack)				\
     do									\
       {									\
 	YYSIZE_T yynewbytes;						\
-	YYCOPY (&yyptr->Stack, Stack, yysize);				\
-	Stack = &yyptr->Stack;						\
+	YYCOPY (&yyptr->Stack_alloc, Stack, yysize);			\
+	Stack = &yyptr->Stack_alloc;					\
 	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
 	yyptr += yynewbytes / sizeof (*yyptr);				\
       }									\
@@ -567,6 +539,26 @@ union yyalloc
 
 #endif
 
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from SRC to DST.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(Dst, Src, Count) \
+      __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
+#  else
+#   define YYCOPY(Dst, Src, Count)              \
+      do                                        \
+        {                                       \
+          YYSIZE_T yyi;                         \
+          for (yyi = 0; yyi < (Count); yyi++)   \
+            (Dst)[yyi] = (Src)[yyi];            \
+        }                                       \
+      while (YYID (0))
+#  endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  81
 /* YYLAST -- Last index in YYTABLE.  */
@@ -734,30 +726,30 @@ static const yytype_int8 yyrhs[] =
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   257,   257,   299,   302,   303,   306,   307,   308,   309,
-     310,   311,   312,   313,   314,   315,   316,   317,   318,   319,
-     320,   321,   322,   323,   324,   327,   328,   331,   331,   331,
-     331,   333,   334,   335,   337,   344,   345,   346,   347,   348,
-     349,   350,   353,   354,   355,   356,   357,   358,   359,   360,
-     367,   368,   369,   370,   371,   372,   375,   376,   380,   380,
-     380,   381,   382,   387,   388,   390,   391,   393,   394,   398,
-     401,   402,   405,   405,   406,   407,   408,   410,   409,   426,
-     425,   434,   435,   437,   439,   444,   444,   447,   449,   450,
-     451,   452,   453,   454,   455,   456,   460,   461,   462,   463,
-     465,   467,   470,   474,   478,   485,   488,   494,   500,   501,
-     506,   507,   508,   509,   510,   514,   515,   516,   517,   518,
-     519,   520,   521,   526,   527,   528,   529,   533,   534,   535,
-     536,   537,   538,   539,   540,   541,   542,   543,   544,   545,
-     546,   547,   548,   549,   550,   551,   552,   557,   558,   559,
-     560,   564,   565,   566,   567,   568,   569,   570,   571,   572,
-     573,   574,   577,   578,   582,   583,   586,   587,   588,   589,
-     593,   594,   595,   596,   597,   598,   599,   600,   601,   602,
-     603,   604,   605,   606,   607,   608,   609,   610,   611,   620,
-     621
+       0,   257,   257,   301,   304,   305,   310,   311,   312,   313,
+     314,   315,   316,   317,   318,   319,   320,   321,   322,   323,
+     324,   325,   326,   327,   328,   331,   332,   335,   335,   335,
+     335,   339,   340,   341,   343,   350,   351,   352,   353,   354,
+     355,   356,   361,   362,   363,   364,   365,   366,   367,   368,
+     376,   377,   378,   379,   380,   381,   384,   385,   391,   391,
+     391,   392,   393,   398,   399,   401,   402,   404,   405,   411,
+     414,   415,   420,   420,   421,   422,   423,   425,   424,   441,
+     440,   449,   450,   452,   454,   459,   459,   462,   466,   467,
+     468,   469,   470,   471,   472,   473,   477,   478,   479,   480,
+     482,   484,   487,   491,   495,   502,   505,   514,   520,   521,
+     526,   527,   528,   529,   530,   534,   535,   536,   537,   538,
+     539,   540,   541,   546,   547,   548,   549,   553,   554,   555,
+     556,   557,   558,   559,   560,   561,   562,   563,   564,   565,
+     566,   567,   568,   569,   570,   571,   572,   577,   578,   579,
+     580,   584,   585,   586,   587,   588,   589,   590,   591,   592,
+     593,   594,   597,   598,   602,   603,   606,   607,   608,   609,
+     613,   614,   615,   616,   617,   618,   619,   620,   621,   622,
+     623,   624,   625,   626,   627,   628,   629,   630,   631,   640,
+     641
 };
 #endif
 
-#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+#if YYDEBUG || YYERROR_VERBOSE || 0
 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
    First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
 static const char *const yytname[] =
@@ -765,7 +757,7 @@ static const char *const yytname[] =
   "$end", "error", "$undefined", "IF", "ELSE", "','", "'='", "SET",
   "GTGT", "LTLT", "'|'", "OR", "'&'", "AND", "NE", "EQ", "'<'", "'>'",
   "GE", "LE", "'+'", "'-'", "'*'", "'/'", "'%'", "DOTSLASH", "DOTSTAR",
-  "'!'", "MOINSMOINS", "PLUSPLUS", "UNARY", "'^'", "'''", "'_'", "'('",
+  "'!'", "MOINSMOINS", "PLUSPLUS", "UNARY", "'^'", "'\\''", "'_'", "'('",
   "'['", "'.'", "')'", "']'", "LNUM", "DNUM", "CNUM", "ID", "FESPACEID",
   "IDPARAM", "STRING", "ENDOFFILE", "INCLUDE", "LOAD", "BIDON", "FOR",
   "WHILE", "BREAK", "CONTINUE", "RETURN", "TRY", "CATCH", "THROW", "TYPE",
@@ -775,11 +767,11 @@ static const char *const yytname[] =
   "instructions", "list_of_id_args", "list_of_id1", "id", "list_of_dcls",
   "parameters_list", "type_of_dcl", "ID_space", "ID_array_space",
   "fespace123", "fespace", "spaceIDa", "spaceIDb", "spaceIDs",
-  "fespace_def", "fespace_def_list", "declaration", "@1", "@2", "@3",
-  "begin", "end", "for_loop", "while_loop", "declaration_for", "@4", "try",
-  "instruction", "catchs", "bornes", "border_expr", "Expr", "unop",
+  "fespace_def", "fespace_def_list", "declaration", "$@1", "$@2", "$@3",
+  "begin", "end", "for_loop", "while_loop", "declaration_for", "$@4",
+  "try", "instruction", "catchs", "bornes", "border_expr", "Expr", "unop",
   "no_comma_expr", "no_set_expr", "no_ternary_expr", "sub_script_expr",
-  "parameters", "array", "unary_expr", "pow_expr", "primary", 0
+  "parameters", "array", "unary_expr", "pow_expr", "primary", YY_NULL
 };
 #endif
 
@@ -849,8 +841,8 @@ static const yytype_uint8 yyr2[] =
        3
 };
 
-/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
-   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
+   Performed when YYTABLE doesn't specify something else to do.  Zero
    means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 {
@@ -969,8 +961,7 @@ static const yytype_int16 yypgoto[] =
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
    positive, shift that token.  If negative, reduce the rule which
-   number is the opposite.  If zero, do what YYDEFACT says.
-   If YYTABLE_NINF, syntax error.  */
+   number is the opposite.  If YYTABLE_NINF, syntax error.  */
 #define YYTABLE_NINF -31
 static const yytype_int16 yytable[] =
 {
@@ -1082,6 +1073,12 @@ static const yytype_int16 yytable[] =
      115,   116,   117,   118,   119,   120,   121,   122,   123
 };
 
+#define yypact_value_is_default(Yystate) \
+  (!!((Yystate) == (-230)))
+
+#define yytable_value_is_error(Yytable_value) \
+  YYID (0)
+
 static const yytype_int16 yycheck[] =
 {
       33,    39,     7,    24,   132,     8,   235,     5,     5,     5,
@@ -1252,78 +1249,50 @@ static const yytype_uint8 yystos[] =
 
 /* Like YYERROR except do call yyerror.  This remains here temporarily
    to ease the transition to the new meaning of YYERROR, for GCC.
-   Once GCC version 2 has supplanted version 1, this can go.  */
+   Once GCC version 2 has supplanted version 1, this can go.  However,
+   YYFAIL appears to be in use.  Nevertheless, it is formally deprecated
+   in Bison 2.4.2's NEWS entry, where a plan to phase it out is
+   discussed.  */
 
 #define YYFAIL		goto yyerrlab
+#if defined YYFAIL
+  /* This is here to suppress warnings from the GCC cpp's
+     -Wunused-macros.  Normally we don't worry about that warning, but
+     some users do, and we want to make it easy for users to remove
+     YYFAIL uses, which will produce warnings from Bison 2.5.  */
+#endif
 
 #define YYRECOVERING()  (!!yyerrstatus)
 
-#define YYBACKUP(Token, Value)					\
-do								\
-  if (yychar == YYEMPTY && yylen == 1)				\
-    {								\
-      yychar = (Token);						\
-      yylval = (Value);						\
-      yytoken = YYTRANSLATE (yychar);				\
-      YYPOPSTACK (1);						\
-      goto yybackup;						\
-    }								\
-  else								\
-    {								\
+#define YYBACKUP(Token, Value)                                  \
+do                                                              \
+  if (yychar == YYEMPTY)                                        \
+    {                                                           \
+      yychar = (Token);                                         \
+      yylval = (Value);                                         \
+      YYPOPSTACK (yylen);                                       \
+      yystate = *yyssp;                                         \
+      goto yybackup;                                            \
+    }                                                           \
+  else                                                          \
+    {                                                           \
       yyerror (YY_("syntax error: cannot back up")); \
       YYERROR;							\
     }								\
 while (YYID (0))
 
-
+/* Error token number */
 #define YYTERROR	1
 #define YYERRCODE	256
 
 
-/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
-   If N is 0, then set CURRENT to the empty location which ends
-   the previous symbol: RHS[0] (always defined).  */
-
-#define YYRHSLOC(Rhs, K) ((Rhs)[K])
-#ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N)				\
-    do									\
-      if (YYID (N))                                                    \
-	{								\
-	  (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;	\
-	  (Current).first_column = YYRHSLOC (Rhs, 1).first_column;	\
-	  (Current).last_line    = YYRHSLOC (Rhs, N).last_line;		\
-	  (Current).last_column  = YYRHSLOC (Rhs, N).last_column;	\
-	}								\
-      else								\
-	{								\
-	  (Current).first_line   = (Current).last_line   =		\
-	    YYRHSLOC (Rhs, 0).last_line;				\
-	  (Current).first_column = (Current).last_column =		\
-	    YYRHSLOC (Rhs, 0).last_column;				\
-	}								\
-    while (YYID (0))
-#endif
-
-
-/* YY_LOCATION_PRINT -- Print the location on the stream.
-   This macro was not mandated originally: define only if we know
-   we won't break user code: when these are the locations we know.  */
-
+/* This macro is provided for backward compatibility. */
 #ifndef YY_LOCATION_PRINT
-# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
-#  define YY_LOCATION_PRINT(File, Loc)			\
-     fprintf (File, "%d.%d-%d.%d",			\
-	      (Loc).first_line, (Loc).first_column,	\
-	      (Loc).last_line,  (Loc).last_column)
-# else
-#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-# endif
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
 #endif
 
 
 /* YYLEX -- calling `yylex' with the right arguments.  */
-
 #ifdef YYLEX_PARAM
 # define YYLEX yylex (YYLEX_PARAM)
 #else
@@ -1373,6 +1342,8 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep)
     YYSTYPE const * const yyvaluep;
 #endif
 {
+  FILE *yyo = yyoutput;
+  YYUSE (yyo);
   if (!yyvaluep)
     return;
 # ifdef YYPRINT
@@ -1381,11 +1352,7 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep)
 # else
   YYUSE (yyoutput);
 # endif
-  switch (yytype)
-    {
-      default:
-	break;
-    }
+  YYUSE (yytype);
 }
 
 
@@ -1422,17 +1389,20 @@ yy_symbol_print (yyoutput, yytype, yyvaluep)
 #if (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 static void
-yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
 #else
 static void
-yy_stack_print (bottom, top)
-    yytype_int16 *bottom;
-    yytype_int16 *top;
+yy_stack_print (yybottom, yytop)
+    yytype_int16 *yybottom;
+    yytype_int16 *yytop;
 #endif
 {
   YYFPRINTF (stderr, "Stack now");
-  for (; bottom <= top; ++bottom)
-    YYFPRINTF (stderr, " %d", *bottom);
+  for (; yybottom <= yytop; yybottom++)
+    {
+      int yybot = *yybottom;
+      YYFPRINTF (stderr, " %d", yybot);
+    }
   YYFPRINTF (stderr, "\n");
 }
 
@@ -1466,11 +1436,11 @@ yy_reduce_print (yyvsp, yyrule)
   /* The symbols being reduced.  */
   for (yyi = 0; yyi < yynrhs; yyi++)
     {
-      fprintf (stderr, "   $%d = ", yyi + 1);
+      YYFPRINTF (stderr, "   $%d = ", yyi + 1);
       yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
 		       &(yyvsp[(yyi + 1) - (yynrhs)])
 		       		       );
-      fprintf (stderr, "\n");
+      YYFPRINTF (stderr, "\n");
     }
 }
 
@@ -1507,7 +1477,6 @@ int yydebug;
 # define YYMAXDEPTH 10000
 #endif
 
-

 
 #if YYERROR_VERBOSE
 
@@ -1610,115 +1579,145 @@ yytnamerr (char *yyres, const char *yystr)
 }
 # endif
 
-/* Copy into YYRESULT an error message about the unexpected token
-   YYCHAR while in state YYSTATE.  Return the number of bytes copied,
-   including the terminating null byte.  If YYRESULT is null, do not
-   copy anything; just return the number of bytes that would be
-   copied.  As a special case, return 0 if an ordinary "syntax error"
-   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
-   size calculation.  */
-static YYSIZE_T
-yysyntax_error (char *yyresult, int yystate, int yychar)
-{
-  int yyn = yypact[yystate];
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+   about the unexpected token YYTOKEN for the state stack whose top is
+   YYSSP.
 
-  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
-    return 0;
-  else
+   Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is
+   not large enough to hold the message.  In that case, also set
+   *YYMSG_ALLOC to the required number of bytes.  Return 2 if the
+   required number of bytes is too large to store.  */
+static int
+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+                yytype_int16 *yyssp, int yytoken)
+{
+  YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]);
+  YYSIZE_T yysize = yysize0;
+  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+  /* Internationalized format string. */
+  const char *yyformat = YY_NULL;
+  /* Arguments of yyformat. */
+  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+  /* Number of reported tokens (one for the "unexpected", one per
+     "expected"). */
+  int yycount = 0;
+
+  /* There are many possibilities here to consider:
+     - Assume YYFAIL is not used.  It's too flawed to consider.  See
+       <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
+       for details.  YYERROR is fine as it does not invoke this
+       function.
+     - If this state is a consistent state with a default action, then
+       the only way this function was invoked is if the default action
+       is an error action.  In that case, don't check for expected
+       tokens because there are none.
+     - The only way there can be no lookahead present (in yychar) is if
+       this state is a consistent state with a default action.  Thus,
+       detecting the absence of a lookahead is sufficient to determine
+       that there is no unexpected or expected token to report.  In that
+       case, just report a simple "syntax error".
+     - Don't assume there isn't a lookahead just because this state is a
+       consistent state with a default action.  There might have been a
+       previous inconsistent state, consistent state with a non-default
+       action, or user semantic action that manipulated yychar.
+     - Of course, the expected token list depends on states to have
+       correct lookahead information, and it depends on the parser not
+       to perform extra reductions after fetching a lookahead from the
+       scanner and before detecting a syntax error.  Thus, state merging
+       (from LALR or IELR) and default reductions corrupt the expected
+       token list.  However, the list is correct for canonical LR with
+       one exception: it will still contain any token that will not be
+       accepted due to an error action in a later state.
+  */
+  if (yytoken != YYEMPTY)
     {
-      int yytype = YYTRANSLATE (yychar);
-      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
-      YYSIZE_T yysize = yysize0;
-      YYSIZE_T yysize1;
-      int yysize_overflow = 0;
-      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
-      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
-      int yyx;
-
-# if 0
-      /* This is so xgettext sees the translatable formats that are
-	 constructed on the fly.  */
-      YY_("syntax error, unexpected %s");
-      YY_("syntax error, unexpected %s, expecting %s");
-      YY_("syntax error, unexpected %s, expecting %s or %s");
-      YY_("syntax error, unexpected %s, expecting %s or %s or %s");
-      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
-# endif
-      char *yyfmt;
-      char const *yyf;
-      static char const yyunexpected[] = "syntax error, unexpected %s";
-      static char const yyexpecting[] = ", expecting %s";
-      static char const yyor[] = " or %s";
-      char yyformat[sizeof yyunexpected
-		    + sizeof yyexpecting - 1
-		    + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
-		       * (sizeof yyor - 1))];
-      char const *yyprefix = yyexpecting;
-
-      /* Start YYX at -YYN if negative to avoid negative indexes in
-	 YYCHECK.  */
-      int yyxbegin = yyn < 0 ? -yyn : 0;
-
-      /* Stay within bounds of both yycheck and yytname.  */
-      int yychecklim = YYLAST - yyn + 1;
-      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
-      int yycount = 1;
-
-      yyarg[0] = yytname[yytype];
-      yyfmt = yystpcpy (yyformat, yyunexpected);
-
-      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
-	if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
-	  {
-	    if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
-	      {
-		yycount = 1;
-		yysize = yysize0;
-		yyformat[sizeof yyunexpected - 1] = '\0';
-		break;
-	      }
-	    yyarg[yycount++] = yytname[yyx];
-	    yysize1 = yysize + yytnamerr (0, yytname[yyx]);
-	    yysize_overflow |= (yysize1 < yysize);
-	    yysize = yysize1;
-	    yyfmt = yystpcpy (yyfmt, yyprefix);
-	    yyprefix = yyor;
-	  }
+      int yyn = yypact[*yyssp];
+      yyarg[yycount++] = yytname[yytoken];
+      if (!yypact_value_is_default (yyn))
+        {
+          /* Start YYX at -YYN if negative to avoid negative indexes in
+             YYCHECK.  In other words, skip the first -YYN actions for
+             this state because they are default actions.  */
+          int yyxbegin = yyn < 0 ? -yyn : 0;
+          /* Stay within bounds of both yycheck and yytname.  */
+          int yychecklim = YYLAST - yyn + 1;
+          int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+          int yyx;
+
+          for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+            if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
+                && !yytable_value_is_error (yytable[yyx + yyn]))
+              {
+                if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+                  {
+                    yycount = 1;
+                    yysize = yysize0;
+                    break;
+                  }
+                yyarg[yycount++] = yytname[yyx];
+                {
+                  YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]);
+                  if (! (yysize <= yysize1
+                         && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+                    return 2;
+                  yysize = yysize1;
+                }
+              }
+        }
+    }
 
-      yyf = YY_(yyformat);
-      yysize1 = yysize + yystrlen (yyf);
-      yysize_overflow |= (yysize1 < yysize);
-      yysize = yysize1;
+  switch (yycount)
+    {
+# define YYCASE_(N, S)                      \
+      case N:                               \
+        yyformat = S;                       \
+      break
+      YYCASE_(0, YY_("syntax error"));
+      YYCASE_(1, YY_("syntax error, unexpected %s"));
+      YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+      YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+      YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+      YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+# undef YYCASE_
+    }
 
-      if (yysize_overflow)
-	return YYSIZE_MAXIMUM;
+  {
+    YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
+    if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+      return 2;
+    yysize = yysize1;
+  }
 
-      if (yyresult)
-	{
-	  /* Avoid sprintf, as that infringes on the user's name space.
-	     Don't have undefined behavior even if the translation
-	     produced a string with the wrong number of "%s"s.  */
-	  char *yyp = yyresult;
-	  int yyi = 0;
-	  while ((*yyp = *yyf) != '\0')
-	    {
-	      if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
-		{
-		  yyp += yytnamerr (yyp, yyarg[yyi++]);
-		  yyf += 2;
-		}
-	      else
-		{
-		  yyp++;
-		  yyf++;
-		}
-	    }
-	}
-      return yysize;
+  if (*yymsg_alloc < yysize)
+    {
+      *yymsg_alloc = 2 * yysize;
+      if (! (yysize <= *yymsg_alloc
+             && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
+        *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
+      return 1;
     }
+
+  /* Avoid sprintf, as that infringes on the user's name space.
+     Don't have undefined behavior even if the translation
+     produced a string with the wrong number of "%s"s.  */
+  {
+    char *yyp = *yymsg;
+    int yyi = 0;
+    while ((*yyp = *yyformat) != '\0')
+      if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
+        {
+          yyp += yytnamerr (yyp, yyarg[yyi++]);
+          yyformat += 2;
+        }
+      else
+        {
+          yyp++;
+          yyformat++;
+        }
+  }
+  return 0;
 }
 #endif /* YYERROR_VERBOSE */
-

 
 /*-----------------------------------------------.
 | Release the memory associated to this symbol.  |
@@ -1743,44 +1742,31 @@ yydestruct (yymsg, yytype, yyvaluep)
     yymsg = "Deleting";
   YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
 
-  switch (yytype)
-    {
-
-      default:
-	break;
-    }
+  YYUSE (yytype);
 }
-

-
-/* Prevent warnings from -Wmissing-prototypes.  */
 
-#ifdef YYPARSE_PARAM
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void *YYPARSE_PARAM);
-#else
-int yyparse ();
-#endif
-#else /* ! YYPARSE_PARAM */
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void);
-#else
-int yyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
 
 
 
-/* The look-ahead symbol.  */
+/* The lookahead symbol.  */
 int yychar;
 
-/* The semantic value of the look-ahead symbol.  */
-YYSTYPE yylval;
+
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
+/* The semantic value of the lookahead symbol.  */
+YYSTYPE yylval YY_INITIAL_VALUE(yyval_default);
 
 /* Number of syntax errors so far.  */
 int yynerrs;
 
 
-
 /*----------.
 | yyparse.  |
 `----------*/
@@ -1807,14 +1793,37 @@ yyparse ()
 #endif
 #endif
 {
-  
-  int yystate;
+    int yystate;
+    /* Number of tokens to shift before error messages enabled.  */
+    int yyerrstatus;
+
+    /* The stacks and their tools:
+       `yyss': related to states.
+       `yyvs': related to semantic values.
+
+       Refer to the stacks through separate pointers, to allow yyoverflow
+       to reallocate them elsewhere.  */
+
+    /* The state stack.  */
+    yytype_int16 yyssa[YYINITDEPTH];
+    yytype_int16 *yyss;
+    yytype_int16 *yyssp;
+
+    /* The semantic value stack.  */
+    YYSTYPE yyvsa[YYINITDEPTH];
+    YYSTYPE *yyvs;
+    YYSTYPE *yyvsp;
+
+    YYSIZE_T yystacksize;
+
   int yyn;
   int yyresult;
-  /* Number of tokens to shift before error messages enabled.  */
-  int yyerrstatus;
-  /* Look-ahead token as an internal (translated) token number.  */
+  /* Lookahead token as an internal (translated) token number.  */
   int yytoken = 0;
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+
 #if YYERROR_VERBOSE
   /* Buffer for error messages, and its allocated size.  */
   char yymsgbuf[128];
@@ -1822,54 +1831,22 @@ yyparse ()
   YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
 #endif
 
-  /* Three stacks and their tools:
-     `yyss': related to states,
-     `yyvs': related to semantic values,
-     `yyls': related to locations.
-
-     Refer to the stacks thru separate pointers, to allow yyoverflow
-     to reallocate them elsewhere.  */
-
-  /* The state stack.  */
-  yytype_int16 yyssa[YYINITDEPTH];
-  yytype_int16 *yyss = yyssa;
-  yytype_int16 *yyssp;
-
-  /* The semantic value stack.  */
-  YYSTYPE yyvsa[YYINITDEPTH];
-  YYSTYPE *yyvs = yyvsa;
-  YYSTYPE *yyvsp;
-
-
-
 #define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
 
-  YYSIZE_T yystacksize = YYINITDEPTH;
-
-  /* The variables used to return semantic value and location from the
-     action routines.  */
-  YYSTYPE yyval;
-
-
   /* The number of symbols on the RHS of the reduced rule.
      Keep to zero when no symbol should be popped.  */
   int yylen = 0;
 
+  yyssp = yyss = yyssa;
+  yyvsp = yyvs = yyvsa;
+  yystacksize = YYINITDEPTH;
+
   YYDPRINTF ((stderr, "Starting parse\n"));
 
   yystate = 0;
   yyerrstatus = 0;
   yynerrs = 0;
-  yychar = YYEMPTY;		/* Cause a token to be read.  */
-
-  /* Initialize stack pointers.
-     Waste one element of value and location stack
-     so that they stay on the same level as the state stack.
-     The wasted elements are never initialized.  */
-
-  yyssp = yyss;
-  yyvsp = yyvs;
-
+  yychar = YYEMPTY; /* Cause a token to be read.  */
   goto yysetstate;
 
 /*------------------------------------------------------------.
@@ -1896,7 +1873,6 @@ yyparse ()
 	YYSTYPE *yyvs1 = yyvs;
 	yytype_int16 *yyss1 = yyss;
 
-
 	/* Each stack pointer address is followed by the size of the
 	   data in use in that stack, in bytes.  This used to be a
 	   conditional around just the two extra args, but that might
@@ -1904,7 +1880,6 @@ yyparse ()
 	yyoverflow (YY_("memory exhausted"),
 		    &yyss1, yysize * sizeof (*yyssp),
 		    &yyvs1, yysize * sizeof (*yyvsp),
-
 		    &yystacksize);
 
 	yyss = yyss1;
@@ -1927,9 +1902,8 @@ yyparse ()
 	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
 	if (! yyptr)
 	  goto yyexhaustedlab;
-	YYSTACK_RELOCATE (yyss);
-	YYSTACK_RELOCATE (yyvs);
-
+	YYSTACK_RELOCATE (yyss_alloc, yyss);
+	YYSTACK_RELOCATE (yyvs_alloc, yyvs);
 #  undef YYSTACK_RELOCATE
 	if (yyss1 != yyssa)
 	  YYSTACK_FREE (yyss1);
@@ -1940,7 +1914,6 @@ yyparse ()
       yyssp = yyss + yysize - 1;
       yyvsp = yyvs + yysize - 1;
 
-
       YYDPRINTF ((stderr, "Stack size increased to %lu\n",
 		  (unsigned long int) yystacksize));
 
@@ -1950,6 +1923,9 @@ yyparse ()
 
   YYDPRINTF ((stderr, "Entering state %d\n", yystate));
 
+  if (yystate == YYFINAL)
+    YYACCEPT;
+
   goto yybackup;
 
 /*-----------.
@@ -1958,16 +1934,16 @@ yyparse ()
 yybackup:
 
   /* Do appropriate processing given the current state.  Read a
-     look-ahead token if we need one and don't already have one.  */
+     lookahead token if we need one and don't already have one.  */
 
-  /* First try to decide what to do without reference to look-ahead token.  */
+  /* First try to decide what to do without reference to lookahead token.  */
   yyn = yypact[yystate];
-  if (yyn == YYPACT_NINF)
+  if (yypact_value_is_default (yyn))
     goto yydefault;
 
-  /* Not known => get a look-ahead token if don't already have one.  */
+  /* Not known => get a lookahead token if don't already have one.  */
 
-  /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
   if (yychar == YYEMPTY)
     {
       YYDPRINTF ((stderr, "Reading a token: "));
@@ -1993,29 +1969,27 @@ yybackup:
   yyn = yytable[yyn];
   if (yyn <= 0)
     {
-      if (yyn == 0 || yyn == YYTABLE_NINF)
-	goto yyerrlab;
+      if (yytable_value_is_error (yyn))
+        goto yyerrlab;
       yyn = -yyn;
       goto yyreduce;
     }
 
-  if (yyn == YYFINAL)
-    YYACCEPT;
-
   /* Count tokens shifted since error; after three, turn off error
      status.  */
   if (yyerrstatus)
     yyerrstatus--;
 
-  /* Shift the look-ahead token.  */
+  /* Shift the lookahead token.  */
   YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
 
-  /* Discard the shifted token unless it is eof.  */
-  if (yychar != YYEOF)
-    yychar = YYEMPTY;
+  /* Discard the shifted token.  */
+  yychar = YYEMPTY;
 
   yystate = yyn;
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
   *++yyvsp = yylval;
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
 
   goto yynewstate;
 
@@ -2052,10 +2026,12 @@ yyreduce:
   switch (yyn)
     {
         case 2:
+/* Line 1787 of yacc.c  */
 #line 257 "lg.ypp"
     {
 		        const char *  magicffglut="#!ffglutdata3.1\n";// for complex and vector 3d plot 
-                        if(ThePlotStream) fwrite(magicffglut,strlen(magicffglut),1,ThePlotStream);	            
+			//FFCS: divert stream to FFCS
+                        if(ThePlotStream) ffapi::fwriteinit(magicffglut,strlen(magicffglut),1,ThePlotStream);	            
                         size_t sizestack = currentblock->size()+1024 ; //  before close 
                         (yyvsp[(1) - (2)].cinst)+=currentblock->close(currentblock);
                         if(verbosity>2 || mpirank==0) cout << " sizestack + 1024 =" << sizestack << "  ( " << sizestack-1024 <<" )\n" ;   
@@ -2086,357 +2062,426 @@ yyreduce:
                         //debugstack.clear() 
                         } 
                         fingraphique();
-			if(ThePlotStream) {pclose(ThePlotStream); ThePlotStream=0;}
+			//FFCS: divert stream to FFCS
+			if(ThePlotStream) {ffapi::ff_pclose(ThePlotStream); ThePlotStream=0;}
 			UnShowAlloc =1;
                         NbPtr = ShowAlloc("end execution -- ",lg1) - NbPtr;
                         
 			    if (NbPtr) { cout << " ######## We forget of deleting   " << NbPtr 
 			                      << " Nb pointer,   " <<  lg1-lg0 << "Bytes " << " ,  mpirank " << mpirank <<endl;}
-  return 0;;}
+  return 0;}
     break;
 
   case 4:
-#line 302 "lg.ypp"
-    {(yyval.cinst)=(yyvsp[(1) - (1)].cexp);;;;}
+/* Line 1787 of yacc.c  */
+#line 304 "lg.ypp"
+    {(yyval.cinst)=(yyvsp[(1) - (1)].cexp);;;}
     break;
 
   case 5:
-#line 303 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 305 "lg.ypp"
     { (yyval.cinst)= ((yyvsp[(1) - (2)].cinst)+=(yyvsp[(2) - (2)].cexp)) ;}
     break;
 
   case 6:
-#line 306 "lg.ypp"
-    { (yyval.clist_id)=new ListOfId();;}
+/* Line 1787 of yacc.c  */
+#line 310 "lg.ypp"
+    { (yyval.clist_id)=new ListOfId();}
     break;
 
   case 7:
-#line 307 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 311 "lg.ypp"
     { (yyval.clist_id) = new ListOfId(); (yyval.clist_id)->push_back(UnId((yyvsp[(1) - (1)].str)));}
     break;
 
   case 8:
-#line 308 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 312 "lg.ypp"
     { (yyval.clist_id) = new ListOfId(); (yyval.clist_id)->push_back(UnId((yyvsp[(1) - (3)].str),(yyvsp[(3) - (3)].cexp))) ;}
     break;
 
   case 9:
-#line 309 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 313 "lg.ypp"
     { (yyval.clist_id) = new ListOfId(); (yyval.clist_id)->push_back(UnId((yyvsp[(2) - (2)].str),Find((yyvsp[(1) - (2)].str)),atype<FE<double,2> **>()));}
     break;
 
   case 10:
-#line 310 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 314 "lg.ypp"
     { (yyval.clist_id) = new ListOfId(); (yyval.clist_id)->push_back(UnId((yyvsp[(3) - (3)].str),Find((yyvsp[(1) - (3)].str)),atype<FE<double,2> **>(),true));}
     break;
 
   case 11:
-#line 311 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 315 "lg.ypp"
     { (yyval.clist_id) = new ListOfId(); (yyval.clist_id)->push_back(UnId((yyvsp[(2) - (2)].str),Find((yyvsp[(1) - (2)].str)),atype<FE<double,3> **>()));}
     break;
 
   case 12:
-#line 312 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 316 "lg.ypp"
     { (yyval.clist_id) = new ListOfId(); (yyval.clist_id)->push_back(UnId((yyvsp[(3) - (3)].str),Find((yyvsp[(1) - (3)].str)),atype<FE<double,3> **>(),true));}
     break;
 
   case 13:
-#line 313 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 317 "lg.ypp"
     { (yyval.clist_id) = new ListOfId(); (yyval.clist_id)->push_back(UnId((yyvsp[(2) - (2)].str),C_F0(),(yyvsp[(1) - (2)].type)->right())) ;}
     break;
 
   case 14:
-#line 314 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 318 "lg.ypp"
     { (yyval.clist_id) = new ListOfId(); (yyval.clist_id)->push_back(UnId((yyvsp[(3) - (3)].str),C_F0(),(yyvsp[(1) - (3)].type),true)) ;}
     break;
 
   case 15:
-#line 315 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 319 "lg.ypp"
     { (yyval.clist_id) = new ListOfId(); (yyval.clist_id)->push_back(UnId((yyvsp[(2) - (3)].clist_id))) ;}
     break;
 
   case 16:
-#line 316 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 320 "lg.ypp"
     { (yyval.clist_id) = (yyvsp[(1) - (3)].clist_id); (yyval.clist_id)->push_back(UnId((yyvsp[(3) - (3)].str))) ;}
     break;
 
   case 17:
-#line 317 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 321 "lg.ypp"
     { (yyval.clist_id) = (yyvsp[(1) - (5)].clist_id); (yyval.clist_id)->push_back(UnId((yyvsp[(4) - (5)].clist_id))) ;}
     break;
 
   case 18:
-#line 318 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 322 "lg.ypp"
     { (yyval.clist_id) = (yyvsp[(1) - (5)].clist_id); (yyval.clist_id)->push_back(UnId((yyvsp[(3) - (5)].str),(yyvsp[(5) - (5)].cexp))) ;}
     break;
 
   case 19:
-#line 319 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 323 "lg.ypp"
     { (yyval.clist_id) = (yyvsp[(1) - (4)].clist_id); (yyval.clist_id)->push_back(UnId((yyvsp[(4) - (4)].str),Find((yyvsp[(3) - (4)].str)),atype<FE<double,2> **>())) ;}
     break;
 
   case 20:
-#line 320 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 324 "lg.ypp"
     { (yyval.clist_id) = (yyvsp[(1) - (5)].clist_id); (yyval.clist_id)->push_back(UnId((yyvsp[(5) - (5)].str),Find((yyvsp[(3) - (5)].str)),atype<FE<double,2> **>(),true)) ;}
     break;
 
   case 21:
-#line 321 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 325 "lg.ypp"
     { (yyval.clist_id) = (yyvsp[(1) - (4)].clist_id); (yyval.clist_id)->push_back(UnId((yyvsp[(4) - (4)].str),Find((yyvsp[(3) - (4)].str)),atype<FE<double,3> **>())) ;}
     break;
 
   case 22:
-#line 322 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 326 "lg.ypp"
     { (yyval.clist_id) = (yyvsp[(1) - (5)].clist_id); (yyval.clist_id)->push_back(UnId((yyvsp[(5) - (5)].str),Find((yyvsp[(3) - (5)].str)),atype<FE<double,3> **>(),true)) ;}
     break;
 
   case 23:
-#line 323 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 327 "lg.ypp"
     { (yyval.clist_id) = (yyvsp[(1) - (4)].clist_id); (yyval.clist_id)->push_back(UnId((yyvsp[(4) - (4)].str),C_F0(),(yyvsp[(3) - (4)].type)->right())) ;}
     break;
 
   case 24:
-#line 324 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 328 "lg.ypp"
     { (yyval.clist_id) = (yyvsp[(1) - (5)].clist_id); (yyval.clist_id)->push_back(UnId((yyvsp[(5) - (5)].str),C_F0(),(yyvsp[(3) - (5)].type),true)) ;}
     break;
 
   case 25:
-#line 327 "lg.ypp"
-    { (yyval.clist_id) = new ListOfId(); (yyval.clist_id)->push_back(UnId((yyvsp[(1) - (1)].str))); ;}
+/* Line 1787 of yacc.c  */
+#line 331 "lg.ypp"
+    { (yyval.clist_id) = new ListOfId(); (yyval.clist_id)->push_back(UnId((yyvsp[(1) - (1)].str))); }
     break;
 
   case 26:
-#line 328 "lg.ypp"
-    { (yyval.clist_id)=(yyvsp[(1) - (3)].clist_id)  ; (yyval.clist_id)->push_back(UnId((yyvsp[(3) - (3)].str))); ;}
+/* Line 1787 of yacc.c  */
+#line 332 "lg.ypp"
+    { (yyval.clist_id)=(yyvsp[(1) - (3)].clist_id)  ; (yyval.clist_id)->push_back(UnId((yyvsp[(3) - (3)].str))); }
     break;
 
   case 31:
-#line 333 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 339 "lg.ypp"
     {(yyval.cexp)=currentblock->NewVar<LocalVariable>((yyvsp[(1) - (1)].str),dcltype);}
     break;
 
   case 32:
-#line 334 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 340 "lg.ypp"
     {(yyval.cexp)=currentblock->NewVar<LocalVariable>((yyvsp[(1) - (3)].str),dcltype,(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 33:
-#line 335 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 341 "lg.ypp"
     {(yyval.cexp)=currentblock->NewVar<LocalVariable>((yyvsp[(1) - (4)].str),dcltype,(yyvsp[(3) - (4)].args));
                                               (yyvsp[(3) - (4)].args).destroy();}
     break;
 
   case 34:
-#line 337 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 343 "lg.ypp"
     {(yyval.cexp)=C_F0((yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 35:
-#line 344 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 350 "lg.ypp"
     {(yyval.args)=(yyvsp[(1) - (1)].cexp);}
     break;
 
   case 36:
-#line 345 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 351 "lg.ypp"
     {(yyval.args)=Find((yyvsp[(1) - (2)].str));}
     break;
 
   case 37:
-#line 346 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 352 "lg.ypp"
     {(yyval.args)=Find((yyvsp[(1) - (2)].str));}
     break;
 
   case 38:
-#line 347 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 353 "lg.ypp"
     {(yyval.args)=Find((yyvsp[(1) - (2)].str));}
     break;
 
   case 39:
-#line 348 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 354 "lg.ypp"
     { (yyval.args)=make_pair<const char *,const C_F0>((yyvsp[(1) - (3)].str),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 40:
-#line 349 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 355 "lg.ypp"
     { (yyval.args) = ((yyvsp[(1) - (3)].args) += (yyvsp[(3) - (3)].cexp)) ;}
     break;
 
   case 41:
-#line 350 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 356 "lg.ypp"
     { (yyval.args)= ((yyvsp[(1) - (5)].args)+= make_pair<const char *,const C_F0>((yyvsp[(3) - (5)].str),(yyvsp[(5) - (5)].cexp)));}
     break;
 
   case 43:
-#line 354 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 362 "lg.ypp"
     {(yyval.type)=TypeArray((yyvsp[(1) - (4)].type),(yyvsp[(3) - (4)].type));}
     break;
 
   case 44:
-#line 355 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 363 "lg.ypp"
     {(yyval.type)=TypeArray(TypeArray((yyvsp[(1) - (7)].type),(yyvsp[(3) - (7)].type)),(yyvsp[(6) - (7)].type));}
     break;
 
   case 45:
-#line 356 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 364 "lg.ypp"
     {(yyval.type)=TypeArray((yyvsp[(1) - (6)].type),(yyvsp[(3) - (6)].type),(yyvsp[(5) - (6)].type));}
     break;
 
   case 46:
-#line 357 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 365 "lg.ypp"
     {(yyval.type)=TypeArray(TypeArray((yyvsp[(1) - (9)].type),(yyvsp[(3) - (9)].type),(yyvsp[(5) - (9)].type)),(yyvsp[(8) - (9)].type));}
     break;
 
   case 47:
-#line 358 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 366 "lg.ypp"
     {(yyval.type)=TypeTemplate((yyvsp[(1) - (4)].type),(yyvsp[(3) - (4)].type));}
     break;
 
   case 48:
-#line 359 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 367 "lg.ypp"
     {(yyval.type)=TypeArray(TypeTemplate((yyvsp[(1) - (7)].type),(yyvsp[(3) - (7)].type)),(yyvsp[(6) - (7)].type));}
     break;
 
   case 49:
-#line 360 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 368 "lg.ypp"
     {(yyval.type)=TypeArray(TypeTemplate((yyvsp[(1) - (9)].type),(yyvsp[(3) - (9)].type)),(yyvsp[(6) - (9)].type),(yyvsp[(8) - (9)].type));}
     break;
 
   case 50:
-#line 367 "lg.ypp"
-    { (yyval.cexp) =  NewFEvariable((yyvsp[(1) - (1)].str),currentblock,fespacetype,fespacecomplex,fespacedim); ;}
+/* Line 1787 of yacc.c  */
+#line 376 "lg.ypp"
+    { (yyval.cexp) =  NewFEvariable((yyvsp[(1) - (1)].str),currentblock,fespacetype,fespacecomplex,fespacedim); }
     break;
 
   case 51:
-#line 368 "lg.ypp"
-    { (yyval.cexp) =  NewFEarray((yyvsp[(1) - (4)].str),currentblock,fespacetype,(yyvsp[(3) - (4)].cexp),fespacecomplex,fespacedim); ;}
+/* Line 1787 of yacc.c  */
+#line 377 "lg.ypp"
+    { (yyval.cexp) =  NewFEarray((yyvsp[(1) - (4)].str),currentblock,fespacetype,(yyvsp[(3) - (4)].cexp),fespacecomplex,fespacedim); }
     break;
 
   case 52:
-#line 369 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 378 "lg.ypp"
     { (yyval.cexp) =  NewFEvariable((yyvsp[(1) - (3)].str),currentblock,fespacetype,(yyvsp[(3) - (3)].cexp),fespacecomplex,fespacedim) ;}
     break;
 
   case 53:
-#line 370 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 379 "lg.ypp"
     { (yyval.cexp) =  NewFEvariable((yyvsp[(2) - (3)].clist_id),currentblock,fespacetype,fespacecomplex,fespacedim) ;}
     break;
 
   case 54:
-#line 371 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 380 "lg.ypp"
     { (yyval.cexp) =  NewFEarray((yyvsp[(2) - (6)].clist_id),currentblock,fespacetype,(yyvsp[(5) - (6)].cexp),fespacecomplex,fespacedim) ;}
     break;
 
   case 55:
-#line 372 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 381 "lg.ypp"
     { (yyval.cexp) =  NewFEvariable((yyvsp[(2) - (5)].clist_id),currentblock,fespacetype,(yyvsp[(5) - (5)].cexp),fespacecomplex,fespacedim) ;}
     break;
 
   case 56:
-#line 375 "lg.ypp"
-    { (yyval.cexp) =  NewFEarray((yyvsp[(1) - (4)].str),currentblock,fespacetype,(yyvsp[(3) - (4)].cexp),fespacecomplex,fespacedim); ;}
+/* Line 1787 of yacc.c  */
+#line 384 "lg.ypp"
+    { (yyval.cexp) =  NewFEarray((yyvsp[(1) - (4)].str),currentblock,fespacetype,(yyvsp[(3) - (4)].cexp),fespacecomplex,fespacedim); }
     break;
 
   case 57:
-#line 376 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 385 "lg.ypp"
     { (yyval.cexp) =  NewFEarray((yyvsp[(2) - (6)].clist_id),currentblock,fespacetype,(yyvsp[(5) - (6)].cexp),fespacecomplex,fespacedim) ;}
     break;
 
   case 58:
-#line 380 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 391 "lg.ypp"
     { fespacedim=2;}
     break;
 
   case 59:
-#line 380 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 391 "lg.ypp"
     { fespacedim=1;}
     break;
 
   case 60:
-#line 380 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 391 "lg.ypp"
     { fespacedim=3;}
     break;
 
   case 61:
-#line 381 "lg.ypp"
-    {fespacecomplex=false;  fespacetype = Find((yyvsp[(1) - (1)].str));;}
+/* Line 1787 of yacc.c  */
+#line 392 "lg.ypp"
+    {fespacecomplex=false;  fespacetype = Find((yyvsp[(1) - (1)].str));}
     break;
 
   case 62:
-#line 382 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 393 "lg.ypp"
     {
              if ((yyvsp[(3) - (4)].type) != typevarreal && (yyvsp[(3) - (4)].type) != typevarcomplex) lgerror (" type of finite element <real> or <complex>");
              fespacecomplex=((yyvsp[(3) - (4)].type)==typevarcomplex);
-             fespacetype = Find((yyvsp[(1) - (4)].str));;}
+             fespacetype = Find((yyvsp[(1) - (4)].str));}
     break;
 
   case 63:
-#line 387 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 398 "lg.ypp"
     {  (yyval.cexp) = (yyvsp[(1) - (1)].cexp)  ;}
     break;
 
   case 64:
-#line 388 "lg.ypp"
-    { (yyval.cexp)=C_F0((yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));;}
+/* Line 1787 of yacc.c  */
+#line 399 "lg.ypp"
+    { (yyval.cexp)=C_F0((yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 65:
-#line 390 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 401 "lg.ypp"
     {  (yyval.cexp) = (yyvsp[(1) - (1)].cexp)  ;}
     break;
 
   case 66:
-#line 391 "lg.ypp"
-    { (yyval.cexp)=C_F0((yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));;}
+/* Line 1787 of yacc.c  */
+#line 402 "lg.ypp"
+    { (yyval.cexp)=C_F0((yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 67:
-#line 393 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 404 "lg.ypp"
     { (yyval.cexp)=0;  (yyval.cexp) = (yyvsp[(2) - (2)].cexp);}
     break;
 
   case 68:
-#line 394 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 405 "lg.ypp"
     { (yyval.cexp)=0;  (yyval.cexp) = (yyvsp[(5) - (5)].cexp);}
     break;
 
   case 69:
-#line 398 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 411 "lg.ypp"
     {(yyval.cexp)=currentblock->NewVar<LocalVariableFES,size_t>((yyvsp[(1) - (4)].str),typeFESpace((yyvsp[(3) - (4)].args)),(yyvsp[(3) - (4)].args),dimFESpaceImage((yyvsp[(3) - (4)].args)));
-     (yyvsp[(3) - (4)].args).destroy(); ;}
+     (yyvsp[(3) - (4)].args).destroy(); }
     break;
 
   case 71:
-#line 402 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 415 "lg.ypp"
     {(yyval.cexp)=C_F0((yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 72:
-#line 405 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 420 "lg.ypp"
     {dcltype=(yyvsp[(1) - (1)].type);}
     break;
 
   case 73:
-#line 405 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 420 "lg.ypp"
     {(yyval.cexp)=(yyvsp[(3) - (4)].cexp);}
     break;
 
   case 74:
-#line 406 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 421 "lg.ypp"
     {(yyval.cexp)=(yyvsp[(2) - (3)].cexp);}
     break;
 
   case 75:
-#line 407 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 422 "lg.ypp"
     { (yyval.cexp)=(yyvsp[(1) - (2)].cexp);}
     break;
 
   case 76:
-#line 408 "lg.ypp"
-    {(yyval.cexp)=currentblock->NewID((yyvsp[(1) - (5)].type),(yyvsp[(2) - (5)].str),(yyvsp[(4) - (5)].cexp));;}
+/* Line 1787 of yacc.c  */
+#line 423 "lg.ypp"
+    {(yyval.cexp)=currentblock->NewID((yyvsp[(1) - (5)].type),(yyvsp[(2) - (5)].str),(yyvsp[(4) - (5)].cexp));}
     break;
 
   case 77:
-#line 410 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 425 "lg.ypp"
     {   /* use the stack to store the prev return type*/
                       assert(kkembtype+1<nbembtype);
                       rettype[++kkembtype] = (yyvsp[(2) - (6)].type)->right();
@@ -2444,145 +2489,170 @@ yyreduce:
                       (yyvsp[(5) - (6)].routine)=new Routine((yyvsp[(1) - (6)].type),(yyvsp[(2) - (6)].type)->right(),(yyvsp[(3) - (6)].str),(yyvsp[(5) - (6)].clist_id),currentblock);
 		      // routineinblock[kkembtype]->Add($3,"(",$<routine>5); //pas recursif pour l'instanat test  FH 27 dec 2008
                      // cout << " \n after new routine \n " << endl;                      
-                      ;}
+                      }
     break;
 
   case 78:
-#line 419 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 434 "lg.ypp"
     { currentblock=(yyvsp[(5) - (10)].routine)->Set((yyvsp[(9) - (10)].cinst));
                        currentblock->Add((yyvsp[(3) - (10)].str),"(",(yyvsp[(5) - (10)].routine)); //pas recursif pour l'instant test  FH 27 dec 2008
                        kkembtype--;
                        (yyval.cexp)=0;
                     
-                        ;}
+                        }
     break;
 
   case 79:
-#line 426 "lg.ypp"
-    {Block::open(currentblock); (yyvsp[(1) - (5)].type)->SetArgs((yyvsp[(4) - (5)].clist_id));;}
+/* Line 1787 of yacc.c  */
+#line 441 "lg.ypp"
+    {Block::open(currentblock); (yyvsp[(1) - (5)].type)->SetArgs((yyvsp[(4) - (5)].clist_id));}
     break;
 
   case 80:
-#line 428 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 443 "lg.ypp"
     {  (yyval.cinst)=currentblock->close(currentblock);
                          (yyval.cexp)=currentblock->NewID((yyvsp[(1) - (9)].type),(yyvsp[(2) - (9)].str),(yyvsp[(8) - (9)].cexp),*(yyvsp[(4) - (9)].clist_id));
                          delete (yyvsp[(4) - (9)].clist_id); //  FH 23032005
-                         ;}
+                         }
     break;
 
   case 81:
-#line 434 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 449 "lg.ypp"
     {  Block::open(currentblock);}
     break;
 
   case 82:
-#line 435 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 450 "lg.ypp"
     {  (yyval.cexp)=currentblock->close(currentblock);}
     break;
 
   case 83:
-#line 437 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 452 "lg.ypp"
     {ffassert(inloopcount<sizeStackOfLoop);  // modif FH july 2005
-                StackOfLoop[inloopcount++]=currentblock;;}
+                StackOfLoop[inloopcount++]=currentblock;}
     break;
 
   case 84:
-#line 439 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 454 "lg.ypp"
     {ffassert(inloopcount<sizeStackOfLoop);
-                StackOfLoop[inloopcount++]=currentblock;;}
+                StackOfLoop[inloopcount++]=currentblock;}
     break;
 
   case 85:
-#line 444 "lg.ypp"
-    {dcltype=(yyvsp[(1) - (1)].type); Block::open(currentblock);  ;}
+/* Line 1787 of yacc.c  */
+#line 459 "lg.ypp"
+    {dcltype=(yyvsp[(1) - (1)].type); Block::open(currentblock);  }
     break;
 
   case 86:
-#line 445 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 460 "lg.ypp"
     {(yyval.cexp)=(yyvsp[(3) - (3)].cexp);}
     break;
 
   case 87:
-#line 447 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 462 "lg.ypp"
     { Block::open(currentblock) ;}
     break;
 
   case 88:
-#line 449 "lg.ypp"
-    {(yyval.cexp)=0;;}
+/* Line 1787 of yacc.c  */
+#line 466 "lg.ypp"
+    {(yyval.cexp)=0;}
     break;
 
   case 89:
-#line 450 "lg.ypp"
-    {zzzfff->input((yyvsp[(2) - (2)].str));(yyval.cexp)= 0; ;}
+/* Line 1787 of yacc.c  */
+#line 467 "lg.ypp"
+    {zzzfff->input((yyvsp[(2) - (2)].str));(yyval.cexp)= 0; }
     break;
 
   case 90:
-#line 451 "lg.ypp"
-    {load((yyvsp[(2) - (2)].str));(yyval.cexp)= 0; ;}
+/* Line 1787 of yacc.c  */
+#line 468 "lg.ypp"
+    {load((yyvsp[(2) - (2)].str));(yyval.cexp)= 0; }
     break;
 
   case 91:
-#line 452 "lg.ypp"
-    {(yyval.cexp)=Try((yyvsp[(3) - (5)].cinst),(yyvsp[(5) - (5)].cexp),currentblock->close(currentblock));;}
+/* Line 1787 of yacc.c  */
+#line 469 "lg.ypp"
+    {(yyval.cexp)=Try((yyvsp[(3) - (5)].cinst),(yyvsp[(5) - (5)].cexp),currentblock->close(currentblock));}
     break;
 
   case 92:
-#line 453 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 470 "lg.ypp"
     {(yyval.cexp)=(yyvsp[(1) - (2)].cexp);}
     break;
 
   case 93:
-#line 454 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 471 "lg.ypp"
     {(yyval.cexp)=(yyvsp[(1) - (1)].cexp);}
     break;
 
   case 94:
-#line 455 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 472 "lg.ypp"
     {inloopcount--; (yyval.cexp)=For((yyvsp[(3) - (9)].cexp),(yyvsp[(5) - (9)].cexp),(yyvsp[(7) - (9)].cexp),(yyvsp[(9) - (9)].cexp));}
     break;
 
   case 95:
-#line 457 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 474 "lg.ypp"
     {inloopcount--; 
                 (yyval.cexp)=C_F0(For((yyvsp[(3) - (9)].cexp),(yyvsp[(5) - (9)].cexp),(yyvsp[(7) - (9)].cexp),(yyvsp[(9) - (9)].cexp)),currentblock->close(currentblock));}
     break;
 
   case 96:
-#line 460 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 477 "lg.ypp"
     {inloopcount--;(yyval.cexp)=While((yyvsp[(3) - (5)].cexp),(yyvsp[(5) - (5)].cexp));}
     break;
 
   case 97:
-#line 461 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 478 "lg.ypp"
     {(yyval.cexp)=FIf((yyvsp[(3) - (5)].cexp),(yyvsp[(5) - (5)].cexp));}
     break;
 
   case 98:
-#line 462 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 479 "lg.ypp"
     {(yyval.cexp)=FIf((yyvsp[(3) - (7)].cexp),(yyvsp[(5) - (7)].cexp),(yyvsp[(7) - (7)].cexp));}
     break;
 
   case 99:
-#line 463 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 480 "lg.ypp"
     { 
                       (yyval.cexp)=C_F0(new E_block((yyvsp[(2) - (3)].cinst),(yyvsp[(3) - (3)].cexp)),atype<void>()) ;}
     break;
 
   case 100:
-#line 465 "lg.ypp"
-    {
+/* Line 1787 of yacc.c  */
+#line 482 "lg.ypp"
+    { /* <<BORDER_ID>> */
                       (yyval.cexp)=0;currentblock->NewID(atype<const E_Border *>(),(yyvsp[(2) - (3)].str),C_F0(TheOperators,"[border]",(yyvsp[(3) - (3)].args)));}
     break;
 
   case 101:
-#line 467 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 484 "lg.ypp"
     {
                       (yyval.cexp)=0;currentblock->NewID(atype<const E_Border *>(),(yyvsp[(2) - (6)].str),C_F0(TheOperators,"[border]",(yyvsp[(4) - (6)].args)));}
     break;
 
   case 102:
-#line 470 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 487 "lg.ypp"
     {
                     if(inloopcount) 
                       (yyval.cexp)= C_F0(new E_throw(E_exception::e_break),atype<void>()); 
@@ -2590,7 +2660,8 @@ yyreduce:
     break;
 
   case 103:
-#line 474 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 491 "lg.ypp"
     { 
                     if(inloopcount)
                         (yyval.cexp)= C_F0(new E_throw(E_exception::e_continue),atype<void>()) ;
@@ -2598,7 +2669,8 @@ yyreduce:
     break;
 
   case 104:
-#line 478 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 495 "lg.ypp"
     { 
                     if (kkembtype>=0)
                       (yyval.cexp)= C_F0(new E_throw(E_exception::e_return,(rettype[kkembtype]->CastTo((yyvsp[(2) - (3)].cexp))).OnReturn()) ,atype<void>());
@@ -2606,12 +2678,14 @@ yyreduce:
     break;
 
   case 105:
-#line 485 "lg.ypp"
-    {(yyval.cexp) =  (yyvsp[(7) - (7)].cexp); ;}
+/* Line 1787 of yacc.c  */
+#line 502 "lg.ypp"
+    {(yyval.cexp) =  (yyvsp[(7) - (7)].cexp); }
     break;
 
   case 106:
-#line 488 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 505 "lg.ypp"
     { 
    Block::open(currentblock);
    (yyval.args) = currentblock->NewVar<LocalVariable>((yyvsp[(2) - (7)].str),atype<double*>());
@@ -2620,359 +2694,430 @@ yyreduce:
     break;
 
   case 107:
-#line 494 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 514 "lg.ypp"
     {   
    (yyval.args) = ((yyvsp[(1) - (2)].args) += (yyvsp[(2) - (2)].cexp));
    currentblock->close(currentblock);}
     break;
 
   case 109:
-#line 501 "lg.ypp"
-    {(yyval.cexp)=C_F0(TheOperators,(yyvsp[(2) - (3)].oper),(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));;}
+/* Line 1787 of yacc.c  */
+#line 521 "lg.ypp"
+    {(yyval.cexp)=C_F0(TheOperators,(yyvsp[(2) - (3)].oper),(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 116:
-#line 515 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 535 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,(yyvsp[(2) - (3)].oper),(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 117:
-#line 516 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 536 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,"+=",(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 118:
-#line 517 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 537 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,"-=",(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 119:
-#line 518 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 538 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,"*=",(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 120:
-#line 519 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 539 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,"/=",(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 121:
-#line 520 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 540 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,".*=",(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 122:
-#line 521 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 541 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,"./=",(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 124:
-#line 527 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 547 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,"?:",(yyvsp[(1) - (5)].cexp),(yyvsp[(3) - (5)].cexp),(yyvsp[(5) - (5)].cexp));}
     break;
 
   case 125:
-#line 528 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 548 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,"::",(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 126:
-#line 529 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 549 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,"::",(yyvsp[(1) - (5)].cexp),(yyvsp[(3) - (5)].cexp),(yyvsp[(5) - (5)].cexp));}
     break;
 
   case 128:
-#line 534 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 554 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,(yyvsp[(2) - (3)].oper),(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 129:
-#line 535 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 555 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,(yyvsp[(2) - (3)].oper),(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 130:
-#line 536 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 556 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,(yyvsp[(2) - (3)].oper),(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 131:
-#line 537 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 557 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,(yyvsp[(2) - (3)].oper),(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 132:
-#line 538 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 558 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,(yyvsp[(2) - (3)].oper),(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 133:
-#line 539 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 559 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,(yyvsp[(2) - (3)].oper),(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 134:
-#line 540 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 560 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,(yyvsp[(2) - (3)].oper),(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 135:
-#line 541 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 561 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,(yyvsp[(2) - (3)].oper),(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 136:
-#line 542 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 562 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,(yyvsp[(2) - (3)].oper),(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 137:
-#line 543 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 563 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,(yyvsp[(2) - (3)].oper),(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 138:
-#line 544 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 564 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,(yyvsp[(2) - (3)].oper),(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 139:
-#line 545 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 565 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,(yyvsp[(2) - (3)].oper),(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 140:
-#line 546 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 566 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,(yyvsp[(2) - (3)].oper),(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 141:
-#line 547 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 567 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,(yyvsp[(2) - (3)].oper),(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 142:
-#line 548 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 568 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,(yyvsp[(2) - (3)].oper),(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 143:
-#line 549 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 569 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,(yyvsp[(2) - (3)].oper),(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 144:
-#line 550 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 570 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,(yyvsp[(2) - (3)].oper),(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 145:
-#line 551 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 571 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,(yyvsp[(2) - (3)].oper),(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 146:
-#line 552 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 572 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,(yyvsp[(2) - (3)].oper),(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 147:
-#line 557 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 577 "lg.ypp"
     {(yyval.cexp)=(yyvsp[(1) - (1)].cexp);}
     break;
 
   case 148:
-#line 558 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 578 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,":");}
     break;
 
   case 149:
-#line 559 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 579 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,":",(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 150:
-#line 560 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 580 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,":",(yyvsp[(1) - (5)].cexp),(yyvsp[(3) - (5)].cexp),(yyvsp[(5) - (5)].cexp));}
     break;
 
   case 151:
-#line 564 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 584 "lg.ypp"
     {(yyval.args)=0;}
     break;
 
   case 152:
-#line 565 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 585 "lg.ypp"
     {(yyval.args)=Find((yyvsp[(1) - (1)].str));}
     break;
 
   case 153:
-#line 566 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 586 "lg.ypp"
     {(yyval.args)=Find((yyvsp[(1) - (1)].str));}
     break;
 
   case 154:
-#line 567 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 587 "lg.ypp"
     {(yyval.args)=Find((yyvsp[(1) - (1)].str));}
     break;
 
   case 155:
-#line 568 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 588 "lg.ypp"
     { (yyval.args)=make_pair<const char *,const C_F0>((yyvsp[(1) - (3)].str),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 156:
-#line 569 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 589 "lg.ypp"
     {(yyval.args)=(yyvsp[(1) - (1)].cexp);}
     break;
 
   case 157:
-#line 570 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 590 "lg.ypp"
     { (yyval.args) = ((yyvsp[(1) - (3)].args) += Find((yyvsp[(3) - (3)].str))) ;}
     break;
 
   case 158:
-#line 571 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 591 "lg.ypp"
     { (yyval.args) = ((yyvsp[(1) - (3)].args) += Find((yyvsp[(3) - (3)].str))) ;}
     break;
 
   case 159:
-#line 572 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 592 "lg.ypp"
     { (yyval.args) = ((yyvsp[(1) - (3)].args) += Find((yyvsp[(3) - (3)].str))) ;}
     break;
 
   case 160:
-#line 573 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 593 "lg.ypp"
     { (yyval.args) = ((yyvsp[(1) - (3)].args) += (yyvsp[(3) - (3)].cexp)) ;}
     break;
 
   case 161:
-#line 574 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 594 "lg.ypp"
     { (yyval.args)= ((yyvsp[(1) - (5)].args)+= make_pair<const char *,const C_F0>((yyvsp[(3) - (5)].str),(yyvsp[(5) - (5)].cexp))) ;}
     break;
 
   case 162:
-#line 577 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 597 "lg.ypp"
     {(yyval.args)=(yyvsp[(1) - (1)].cexp);}
     break;
 
   case 163:
-#line 578 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 598 "lg.ypp"
     {(yyval.args) = ((yyvsp[(1) - (3)].args) += (yyvsp[(3) - (3)].cexp)) ;}
     break;
 
   case 165:
-#line 583 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 603 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,(yyvsp[(1) - (2)].oper),(yyvsp[(2) - (2)].cexp));}
     break;
 
   case 167:
-#line 587 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 607 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,(yyvsp[(2) - (3)].oper),(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 168:
-#line 588 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 608 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,(yyvsp[(2) - (3)].oper),(yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].cexp));}
     break;
 
   case 169:
-#line 589 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 609 "lg.ypp"
     {(yyval.cexp)=C_F0(TheOperators,(yyvsp[(2) - (2)].oper),(yyvsp[(1) - (2)].cexp));}
     break;
 
   case 170:
-#line 593 "lg.ypp"
-    {(yyval.cexp)=Find((yyvsp[(1) - (1)].str));;}
+/* Line 1787 of yacc.c  */
+#line 613 "lg.ypp"
+    {(yyval.cexp)=Find((yyvsp[(1) - (1)].str));}
     break;
 
   case 171:
-#line 594 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 614 "lg.ypp"
     {(yyval.cexp)= CConstant((yyvsp[(1) - (1)].lnum));}
     break;
 
   case 172:
-#line 595 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 615 "lg.ypp"
     {(yyval.cexp)= CConstant((yyvsp[(1) - (1)].dnum));}
     break;
 
   case 173:
-#line 596 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 616 "lg.ypp"
     {(yyval.cexp)= CConstant(complex<double>(0,(yyvsp[(1) - (1)].dnum)));}
     break;
 
   case 174:
-#line 597 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 617 "lg.ypp"
     {(yyval.cexp)= CConstant<const char *>((yyvsp[(1) - (1)].str));}
     break;
 
   case 175:
-#line 598 "lg.ypp"
-    {(yyval.cexp)=C_F0((yyvsp[(1) - (4)].cexp),(yyvsp[(2) - (4)].oper),(yyvsp[(3) - (4)].args));;}
+/* Line 1787 of yacc.c  */
+#line 618 "lg.ypp"
+    {(yyval.cexp)=C_F0((yyvsp[(1) - (4)].cexp),(yyvsp[(2) - (4)].oper),(yyvsp[(3) - (4)].args));}
     break;
 
   case 176:
-#line 599 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 619 "lg.ypp"
     {(yyval.cexp)=C_F0((yyvsp[(1) - (4)].cexp),(yyvsp[(2) - (4)].oper),(yyvsp[(3) - (4)].cexp));}
     break;
 
   case 177:
-#line 600 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 620 "lg.ypp"
     {(yyval.cexp)=C_F0((yyvsp[(1) - (6)].cexp),(yyvsp[(2) - (6)].oper),(yyvsp[(3) - (6)].cexp),(yyvsp[(5) - (6)].cexp));}
     break;
 
   case 178:
-#line 601 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 621 "lg.ypp"
     {(yyval.cexp)=C_F0((yyvsp[(1) - (3)].cexp),"[]");}
     break;
 
   case 179:
-#line 602 "lg.ypp"
-    { (yyval.cexp)=C_F0((yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].str)) ;;}
+/* Line 1787 of yacc.c  */
+#line 622 "lg.ypp"
+    { (yyval.cexp)=C_F0((yyvsp[(1) - (3)].cexp),(yyvsp[(3) - (3)].str)) ;}
     break;
 
   case 180:
-#line 603 "lg.ypp"
-    { (yyval.cexp)=C_F0(Find((yyvsp[(1) - (3)].str)),(yyvsp[(3) - (3)].str)) ;;}
+/* Line 1787 of yacc.c  */
+#line 623 "lg.ypp"
+    { (yyval.cexp)=C_F0(Find((yyvsp[(1) - (3)].str)),(yyvsp[(3) - (3)].str)) ;}
     break;
 
   case 181:
-#line 604 "lg.ypp"
-    { (yyval.cexp)=C_F0(Find((yyvsp[(1) - (4)].str)),(yyvsp[(2) - (4)].oper),(yyvsp[(3) - (4)].args)) ;;}
+/* Line 1787 of yacc.c  */
+#line 624 "lg.ypp"
+    { (yyval.cexp)=C_F0(Find((yyvsp[(1) - (4)].str)),(yyvsp[(2) - (4)].oper),(yyvsp[(3) - (4)].args)) ;}
     break;
 
   case 182:
-#line 605 "lg.ypp"
-    { (yyval.cexp)=C_F0(Find((yyvsp[(1) - (3)].str)),(yyvsp[(3) - (3)].str)) ;;}
+/* Line 1787 of yacc.c  */
+#line 625 "lg.ypp"
+    { (yyval.cexp)=C_F0(Find((yyvsp[(1) - (3)].str)),(yyvsp[(3) - (3)].str)) ;}
     break;
 
   case 183:
-#line 606 "lg.ypp"
-    { (yyval.cexp)=C_F0(Find((yyvsp[(1) - (4)].str)),(yyvsp[(2) - (4)].oper),(yyvsp[(3) - (4)].args)) ;;}
+/* Line 1787 of yacc.c  */
+#line 626 "lg.ypp"
+    { (yyval.cexp)=C_F0(Find((yyvsp[(1) - (4)].str)),(yyvsp[(2) - (4)].oper),(yyvsp[(3) - (4)].args)) ;}
     break;
 
   case 184:
-#line 607 "lg.ypp"
-    { (yyval.cexp)=C_F0(Find((yyvsp[(1) - (3)].str)),(yyvsp[(3) - (3)].str)) ;;}
+/* Line 1787 of yacc.c  */
+#line 627 "lg.ypp"
+    { (yyval.cexp)=C_F0(Find((yyvsp[(1) - (3)].str)),(yyvsp[(3) - (3)].str)) ;}
     break;
 
   case 185:
-#line 608 "lg.ypp"
-    { (yyval.cexp)=C_F0(Find((yyvsp[(1) - (4)].str)),(yyvsp[(2) - (4)].oper),(yyvsp[(3) - (4)].args)) ;;}
+/* Line 1787 of yacc.c  */
+#line 628 "lg.ypp"
+    { (yyval.cexp)=C_F0(Find((yyvsp[(1) - (4)].str)),(yyvsp[(2) - (4)].oper),(yyvsp[(3) - (4)].args)) ;}
     break;
 
   case 186:
-#line 609 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 629 "lg.ypp"
     {(yyval.cexp)=C_F0(TheRightOperators,(yyvsp[(2) - (2)].oper),(yyvsp[(1) - (2)].cexp));}
     break;
 
   case 187:
-#line 610 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 630 "lg.ypp"
     {(yyval.cexp)=C_F0(TheRightOperators,(yyvsp[(2) - (2)].oper),(yyvsp[(1) - (2)].cexp));}
     break;
 
   case 188:
-#line 611 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 631 "lg.ypp"
     {
              if ((yyvsp[(1) - (4)].type)->right()->CastingFrom((yyvsp[(3) - (4)].cexp).left()) ) 
                 (yyval.cexp)=(yyvsp[(1) - (4)].type)->right()->CastTo((yyvsp[(3) - (4)].cexp))  ;
@@ -2981,24 +3126,37 @@ yyreduce:
                                         (yyvsp[(1) - (4)].type)->right()->name() << endl;
                                 CompileError(" Error in type(exp) "); }
              }
-            ;}
+            }
     break;
 
   case 189:
-#line 620 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 640 "lg.ypp"
     {(yyval.cexp)=(yyvsp[(2) - (3)].cexp);}
     break;
 
   case 190:
-#line 621 "lg.ypp"
+/* Line 1787 of yacc.c  */
+#line 641 "lg.ypp"
     { (yyval.cexp)=C_F0(TheOperators,"[]",(yyvsp[(2) - (3)].args));}
     break;
 
 
-/* Line 1267 of yacc.c.  */
-#line 3000 "lg.tab.cpp"
+/* Line 1787 of yacc.c  */
+#line 3147 "lg.tab.cpp"
       default: break;
     }
+  /* User semantic actions sometimes alter yychar, and that requires
+     that yytoken be updated with the new translation.  We take the
+     approach of translating immediately before every use of yytoken.
+     One alternative is translating here after every semantic action,
+     but that translation would be missed if the semantic action invokes
+     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
+     incorrect destructor might then be invoked immediately.  In the
+     case of YYERROR or YYBACKUP, subsequent parser actions might lead
+     to an incorrect destructor call or verbose syntax error message
+     before the lookahead is translated.  */
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
 
   YYPOPSTACK (yylen);
@@ -3007,7 +3165,6 @@ yyreduce:
 
   *++yyvsp = yyval;
 
-
   /* Now `shift' the result of the reduction.  Determine what state
      that goes to, based on the state we popped back to and the rule
      number reduced by.  */
@@ -3027,6 +3184,10 @@ yyreduce:
 | yyerrlab -- here on detecting error |
 `------------------------------------*/
 yyerrlab:
+  /* Make sure we have latest lookahead translation.  See comments at
+     user semantic actions for why this is necessary.  */
+  yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
+
   /* If not already recovering from an error, report this error.  */
   if (!yyerrstatus)
     {
@@ -3034,37 +3195,36 @@ yyerrlab:
 #if ! YYERROR_VERBOSE
       yyerror (YY_("syntax error"));
 #else
+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
+                                        yyssp, yytoken)
       {
-	YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
-	if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
-	  {
-	    YYSIZE_T yyalloc = 2 * yysize;
-	    if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
-	      yyalloc = YYSTACK_ALLOC_MAXIMUM;
-	    if (yymsg != yymsgbuf)
-	      YYSTACK_FREE (yymsg);
-	    yymsg = (char *) YYSTACK_ALLOC (yyalloc);
-	    if (yymsg)
-	      yymsg_alloc = yyalloc;
-	    else
-	      {
-		yymsg = yymsgbuf;
-		yymsg_alloc = sizeof yymsgbuf;
-	      }
-	  }
-
-	if (0 < yysize && yysize <= yymsg_alloc)
-	  {
-	    (void) yysyntax_error (yymsg, yystate, yychar);
-	    yyerror (yymsg);
-	  }
-	else
-	  {
-	    yyerror (YY_("syntax error"));
-	    if (yysize != 0)
-	      goto yyexhaustedlab;
-	  }
+        char const *yymsgp = YY_("syntax error");
+        int yysyntax_error_status;
+        yysyntax_error_status = YYSYNTAX_ERROR;
+        if (yysyntax_error_status == 0)
+          yymsgp = yymsg;
+        else if (yysyntax_error_status == 1)
+          {
+            if (yymsg != yymsgbuf)
+              YYSTACK_FREE (yymsg);
+            yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
+            if (!yymsg)
+              {
+                yymsg = yymsgbuf;
+                yymsg_alloc = sizeof yymsgbuf;
+                yysyntax_error_status = 2;
+              }
+            else
+              {
+                yysyntax_error_status = YYSYNTAX_ERROR;
+                yymsgp = yymsg;
+              }
+          }
+        yyerror (yymsgp);
+        if (yysyntax_error_status == 2)
+          goto yyexhaustedlab;
       }
+# undef YYSYNTAX_ERROR
 #endif
     }
 
@@ -3072,7 +3232,7 @@ yyerrlab:
 
   if (yyerrstatus == 3)
     {
-      /* If just tried and failed to reuse look-ahead token after an
+      /* If just tried and failed to reuse lookahead token after an
 	 error, discard it.  */
 
       if (yychar <= YYEOF)
@@ -3089,7 +3249,7 @@ yyerrlab:
 	}
     }
 
-  /* Else will try to reuse look-ahead token after shifting the error
+  /* Else will try to reuse lookahead token after shifting the error
      token.  */
   goto yyerrlab1;
 
@@ -3123,7 +3283,7 @@ yyerrlab1:
   for (;;)
     {
       yyn = yypact[yystate];
-      if (yyn != YYPACT_NINF)
+      if (!yypact_value_is_default (yyn))
 	{
 	  yyn += YYTERROR;
 	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
@@ -3146,10 +3306,9 @@ yyerrlab1:
       YY_STACK_PRINT (yyss, yyssp);
     }
 
-  if (yyn == YYFINAL)
-    YYACCEPT;
-
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
   *++yyvsp = yylval;
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
 
 
   /* Shift the error token.  */
@@ -3173,7 +3332,7 @@ yyabortlab:
   yyresult = 1;
   goto yyreturn;
 
-#ifndef yyoverflow
+#if !defined yyoverflow || YYERROR_VERBOSE
 /*-------------------------------------------------.
 | yyexhaustedlab -- memory exhaustion comes here.  |
 `-------------------------------------------------*/
@@ -3184,9 +3343,14 @@ yyexhaustedlab:
 #endif
 
 yyreturn:
-  if (yychar != YYEOF && yychar != YYEMPTY)
-     yydestruct ("Cleanup: discarding lookahead",
-		 yytoken, &yylval);
+  if (yychar != YYEMPTY)
+    {
+      /* Make sure we have latest lookahead translation.  See comments at
+         user semantic actions for why this is necessary.  */
+      yytoken = YYTRANSLATE (yychar);
+      yydestruct ("Cleanup: discarding lookahead",
+                  yytoken, &yylval);
+    }
   /* Do not reclaim the symbols of the rule which action triggered
      this YYABORT or YYACCEPT.  */
   YYPOPSTACK (yylen);
@@ -3210,7 +3374,8 @@ yyreturn:
 }
 
 
-#line 626 "lg.ypp"
+/* Line 2050 of yacc.c  */
+#line 646 "lg.ypp"
  
 
 
@@ -3233,6 +3398,7 @@ void init_algo();
 bool withrgraphique = false;
 //string  StrVersionNumber();
 
+/// Called by mainff() and activates the bison parser by calling yyparse()
 int Compile()
 {
   extern   YYSTYPE *plglval;  // modif FH 
@@ -3301,9 +3467,12 @@ static void SetcppIo()
 #endif
    ios::sync_with_stdio();
 }
+
 // pour l'environement.
 extern const char *  prognamearg;
 extern  bool echo_edp;
+
+/// Called by mymain() and calls Compile() to run the FF language parser
 int mainff (int  argc, char **argv)
 {
     
@@ -3313,7 +3482,12 @@ int mainff (int  argc, char **argv)
 
     int vvold=verbosity; 
     if(mpirank !=0) verbosity=0;
+
+  // ALH - 14/10/8 - This breaks FFCS output redirection
+#ifndef ENABLE_FFCS
   SetcppIo();
+#endif
+
   GetEnvironment();   
     vvold=verbosity; 
     if(mpirank !=0) verbosity=0; 
@@ -3405,13 +3579,23 @@ int mainff (int  argc, char **argv)
 
   //  currentblock->close(currentblock).eval(thestack);
   fingraphique();
-  if(ThePlotStream) {pclose(ThePlotStream); ThePlotStream=0;}  
+  // FFCS: divert stream to FFCS
+  if(ThePlotStream){
+    ffapi::ff_pclose(ThePlotStream);
+    ThePlotStream=0;
+  }
   Destroylex( zzzfff);
   
    // ClearMem();
   return retvalue;
 }
 
-
-
-
+/* FFCS: emacs configuration for this file */
+ 
+/*!
+ * Local Variables:
+ * mode:antlr
+ * ispell-local-dictionary:"british"
+ * coding:utf-8
+ * End:
+ */
diff --git a/src/lglib/lg.tab.hpp b/src/lglib/lg.tab.hpp
index e8f1640..0bb4ebc 100644
--- a/src/lglib/lg.tab.hpp
+++ b/src/lglib/lg.tab.hpp
@@ -1,24 +1,21 @@
-/* A Bison parser, made by GNU Bison 2.3.  */
+/* A Bison parser, made by GNU Bison 2.7.12-4996.  */
 
-/* Skeleton interface for Bison's Yacc-like parsers in C
-
-   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
-   Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or modify
+/* Bison interface for Yacc-like parsers in C
+   
+      Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
+   
+   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 2, or (at your option)
-   any later version.
-
+   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, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 /* As a special exception, you may create a larger work that contains
    part or all of the Bison parser skeleton and distribute that work
@@ -29,10 +26,20 @@
    special exception, which will cause the skeleton and the resulting
    Bison output files to be licensed under the GNU General Public
    License without this special exception.
-
+   
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
+#ifndef YY_LG_LG_TAB_HPP_INCLUDED
+# define YY_LG_LG_TAB_HPP_INCLUDED
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 1
+#endif
+#if YYDEBUG
+extern int lgdebug;
+#endif
+
 /* Tokens.  */
 #ifndef YYTOKENTYPE
 # define YYTOKENTYPE
@@ -91,65 +98,14 @@
      SOLVE = 307
    };
 #endif
-/* Tokens.  */
-#define IF 258
-#define ELSE 259
-#define SET 260
-#define GTGT 261
-#define LTLT 262
-#define OR 263
-#define AND 264
-#define NE 265
-#define EQ 266
-#define GE 267
-#define LE 268
-#define DOTSLASH 269
-#define DOTSTAR 270
-#define MOINSMOINS 271
-#define PLUSPLUS 272
-#define UNARY 273
-#define LNUM 274
-#define DNUM 275
-#define CNUM 276
-#define ID 277
-#define FESPACEID 278
-#define IDPARAM 279
-#define STRING 280
-#define ENDOFFILE 281
-#define INCLUDE 282
-#define LOAD 283
-#define BIDON 284
-#define FOR 285
-#define WHILE 286
-#define BREAK 287
-#define CONTINUE 288
-#define RETURN 289
-#define TRY 290
-#define CATCH 291
-#define THROW 292
-#define TYPE 293
-#define FUNCTION 294
-#define FESPACE 295
-#define FESPACE1 296
-#define FESPACE3 297
-#define PLUSEQ 298
-#define MOINSEQ 299
-#define MULEQ 300
-#define DIVEQ 301
-#define DOTMULEQ 302
-#define DOTDIVEQ 303
-#define ARROW 304
-#define BORDER 305
-#define CURVE 306
-#define SOLVE 307
-
-
 
 
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
+{
+/* Line 2053 of yacc.c  */
 #line 124 "lg.ypp"
-{ 
+ 
  double dnum;
  long lnum;
  char * str;
@@ -162,14 +118,30 @@ typedef union YYSTYPE
  Block * block; 
  ListOfId *clist_id;
 /* ListCatch * clist_Catchs;*/
-}
-/* Line 1529 of yacc.c.  */
-#line 168 "lg.tab.hpp"
-	YYSTYPE;
+
+
+/* Line 2053 of yacc.c  */
+#line 125 "lg.tab.hpp"
+} YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
-# define YYSTYPE_IS_TRIVIAL 1
 #endif
 
 extern YYSTYPE lglval;
 
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int lgparse (void *YYPARSE_PARAM);
+#else
+int lgparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int lgparse (void);
+#else
+int lgparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+#endif /* !YY_LG_LG_TAB_HPP_INCLUDED  */
diff --git a/src/lglib/lg.ypp b/src/lglib/lg.ypp
index 6b8670b..a2dbd69 100644
--- a/src/lglib/lg.ypp
+++ b/src/lglib/lg.ypp
@@ -1,3 +1,5 @@
+/// \file
+
 %{ 
     // -*- Mode : c++ -*-
     //
@@ -256,7 +258,8 @@ void (*end_parallele)()=0;
 
 start:   input ENDOFFILE {
 		        const char *  magicffglut="#!ffglutdata3.1\n";// for complex and vector 3d plot 
-                        if(ThePlotStream) fwrite(magicffglut,strlen(magicffglut),1,ThePlotStream);	            
+			//FFCS: divert stream to FFCS
+                        if(ThePlotStream) ffapi::fwriteinit(magicffglut,strlen(magicffglut),1,ThePlotStream);	            
                         size_t sizestack = currentblock->size()+1024 ; //  before close 
                         $1+=currentblock->close(currentblock);
                         if(verbosity>2 || mpirank==0) cout << " sizestack + 1024 =" << sizestack << "  ( " << sizestack-1024 <<" )\n" ;   
@@ -287,7 +290,8 @@ start:   input ENDOFFILE {
                         //debugstack.clear() 
                         } 
                         fingraphique();
-			if(ThePlotStream) {pclose(ThePlotStream); ThePlotStream=0;}
+			//FFCS: divert stream to FFCS
+			if(ThePlotStream) {ffapi::ff_pclose(ThePlotStream); ThePlotStream=0;}
 			UnShowAlloc =1;
                         NbPtr = ShowAlloc("end execution -- ",lg1) - NbPtr;
                         
@@ -303,6 +307,8 @@ instructions:  instruction   {$$=$1;;;}
         | instructions  instruction   { $$= ($1+=$2) }         
         ;
 
+/* Function arguments list */
+
 list_of_id_args:   { $$=new ListOfId();}
             | id                      { $$ = new ListOfId(); $$->push_back(UnId($1))}
             | id '=' no_comma_expr    { $$ = new ListOfId(); $$->push_back(UnId($1,$3)) }
@@ -330,6 +336,8 @@ list_of_id1:  id                      { $$ = new ListOfId(); $$->push_back(UnId(
          
 id: ID | FESPACE|FESPACE3|FESPACE1; 
 
+/* <<list_of_dcls>> */
+
 list_of_dcls:    ID                         {$$=currentblock->NewVar<LocalVariable>($1,dcltype)}   
               |  ID '='   no_comma_expr     {$$=currentblock->NewVar<LocalVariable>($1,dcltype,$3)}
               |  ID  '(' parameters_list ')' {$$=currentblock->NewVar<LocalVariable>($1,dcltype,$3);
@@ -350,6 +358,8 @@ parameters_list:
 	| parameters_list ',' id '=' no_set_expr { $$= ($1+= make_pair<const char *,const C_F0>($3,$5))}
 ; 
 
+/* <<type_of_dcl>> */
+
 type_of_dcl:   TYPE 
              | TYPE '[' TYPE ']' {$$=TypeArray($1,$3)}
              | TYPE '[' TYPE ']' '[' TYPE ']' {$$=TypeArray(TypeArray($1,$3),$6)} // Add FH mars 2012 
@@ -362,6 +372,7 @@ type_of_dcl:   TYPE
              
 ;
 
+/* <<ID_space>> */
 
 ID_space:
 ID                                  { $$ =  NewFEvariable($1,currentblock,fespacetype,fespacecomplex,fespacedim); }
@@ -377,6 +388,8 @@ ID_array_space:
 
 ;
 
+/* <<fespace>> */
+
 fespace123: FESPACE { fespacedim=2} |FESPACE1 { fespacedim=1} | FESPACE3 { fespacedim=3};
 fespace:  fespace123 {fespacecomplex=false;  fespacetype = Find($1);}
         | fespace123 '<' TYPE '>' {
@@ -394,6 +407,8 @@ spaceIDs :    fespace               spaceIDb    { $$=0;  $$ = $2}
            |  fespace '[' TYPE ']'  spaceIDa    { $$=0;  $$ = $5}
 ;
 
+/* <<fespace_def>> */
+
 fespace_def:
    ID '(' parameters_list ')'  {$$=currentblock->NewVar<LocalVariableFES,size_t>($1,typeFESpace($3),$3,dimFESpaceImage($3));
      $3.destroy(); };
@@ -402,7 +417,9 @@ fespace_def_list:  fespace_def
                  | fespace_def_list ',' fespace_def {$$=C_F0($1,$3)}
 ;
     
-declaration:   type_of_dcl {dcltype=$1} list_of_dcls ';' {$$=$3} 
+/* <<declaration>> */
+
+declaration:   type_of_dcl {dcltype=$1} list_of_dcls ';' {$$=$3} /* see [[list_of_dcls]] */
              | FESPACEID  fespace_def_list    ';' {$$=$2}  
              | spaceIDs ';'{ $$=$1} 
              | FUNCTION ID '=' Expr ';' {$$=currentblock->NewID($1,$2,$4);} 
@@ -446,6 +463,8 @@ declaration_for:
 
 try: TRY { Block::open(currentblock) };
 
+/* <<instruction>> */
+
 instruction:   ';' {$$=0;} 
          | INCLUDE  STRING  {zzzfff->input($2);$$= 0; }
          | LOAD  STRING  {load($2);$$= 0; }
@@ -462,7 +481,7 @@ instruction:   ';' {$$=0;}
          |  IF '(' Expr ')'   instruction  ELSE instruction {$$=FIf($3,$5,$7)}
          |  begin  instructions end { 
                       $$=C_F0(new E_block($2,$3),atype<void>()) }
-         |  BORDER  ID   border_expr {
+         |  BORDER  ID   border_expr { /* <<BORDER_ID>> */
                       $$=0;currentblock->NewID(atype<const E_Border *>(),$2,C_F0(TheOperators,"[border]",$3))} 
          |  BORDER  ID   '['  array ']' ';' {
                       $$=0;currentblock->NewID(atype<const E_Border *>(),$2,C_F0(TheOperators,"[border]",$4))} 
@@ -491,6 +510,9 @@ bornes: '(' ID '=' Expr ',' Expr ')' {
    $$+= $4;
    $$+= $6 }
 ;
+
+/* <<border_expr>> */
+
 border_expr:   bornes instruction {   
    $$ = ($1 += $2);
    currentblock->close(currentblock)} 
@@ -645,6 +667,7 @@ void init_algo();
 bool withrgraphique = false;
 //string  StrVersionNumber();
 
+/// Called by mainff() and activates the bison parser by calling yyparse()
 int Compile()
 {
   extern   YYSTYPE *plglval;  // modif FH 
@@ -713,9 +736,12 @@ static void SetcppIo()
 #endif
    ios::sync_with_stdio();
 }
+
 // pour l'environement.
 extern const char *  prognamearg;
 extern  bool echo_edp;
+
+/// Called by mymain() and calls Compile() to run the FF language parser
 int mainff (int  argc, char **argv)
 {
     
@@ -725,7 +751,12 @@ int mainff (int  argc, char **argv)
 
     int vvold=verbosity; 
     if(mpirank !=0) verbosity=0;
+
+  // ALH - 14/10/8 - This breaks FFCS output redirection
+#ifndef ENABLE_FFCS
   SetcppIo();
+#endif
+
   GetEnvironment();   
     vvold=verbosity; 
     if(mpirank !=0) verbosity=0; 
@@ -817,12 +848,23 @@ int mainff (int  argc, char **argv)
 
   //  currentblock->close(currentblock).eval(thestack);
   fingraphique();
-  if(ThePlotStream) {pclose(ThePlotStream); ThePlotStream=0;}  
+  // FFCS: divert stream to FFCS
+  if(ThePlotStream){
+    ffapi::ff_pclose(ThePlotStream);
+    ThePlotStream=0;
+  }
   Destroylex( zzzfff);
   
    // ClearMem();
   return retvalue;
 }
 
-
-
+/* FFCS: emacs configuration for this file */
+ 
+/*!
+ * Local Variables:
+ * mode:antlr
+ * ispell-local-dictionary:"british"
+ * coding:utf-8
+ * End:
+ */
diff --git a/src/lglib/mymain.cpp b/src/lglib/mymain.cpp
index 0d81853..f7c8a11 100755
--- a/src/lglib/mymain.cpp
+++ b/src/lglib/mymain.cpp
@@ -1,8 +1,11 @@
+/// \file
+
 int mainff (int  argc, char **argv);
 
 
 extern void init_ptr_parallelepmi();
 
+/// called by platform-dependent main() in src/Graphics/sansrgraph.cpp and others.
 int mymain (int  argc, char **argv)
 {
 
diff --git a/src/libMesh/Makefile.in b/src/libMesh/Makefile.in
index c59f323..89c9288 100644
--- a/src/libMesh/Makefile.in
+++ b/src/libMesh/Makefile.in
@@ -62,7 +62,8 @@ 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)/acmacros.m4 \
-	$(top_srcdir)/acoptim.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/acoptim.m4 $(top_srcdir)/acmpi.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -176,11 +177,47 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EIGENOBJ = @EIGENOBJ@
+ENABLE_FFCS = @ENABLE_FFCS@
 EPSTOPDF = @EPSTOPDF@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+FFCS_COMPILE_fflapack = @FFCS_COMPILE_fflapack@
+FFCS_COMPILE_gsl = @FFCS_COMPILE_gsl@
+FFCS_COMPILE_hips = @FFCS_COMPILE_hips@
+FFCS_COMPILE_hypre = @FFCS_COMPILE_hypre@
+FFCS_COMPILE_ipopt = @FFCS_COMPILE_ipopt@
+FFCS_COMPILE_lapack = @FFCS_COMPILE_lapack@
+FFCS_COMPILE_mmg3d = @FFCS_COMPILE_mmg3d@
+FFCS_COMPILE_mshmet = @FFCS_COMPILE_mshmet@
+FFCS_COMPILE_mumps = @FFCS_COMPILE_mumps@
+FFCS_COMPILE_mumps_seq = @FFCS_COMPILE_mumps_seq@
+FFCS_COMPILE_pardiso = @FFCS_COMPILE_pardiso@
+FFCS_COMPILE_parms = @FFCS_COMPILE_parms@
+FFCS_COMPILE_pastix = @FFCS_COMPILE_pastix@
+FFCS_COMPILE_pipe = @FFCS_COMPILE_pipe@
+FFCS_COMPILE_scotch = @FFCS_COMPILE_scotch@
+FFCS_COMPILE_superludist = @FFCS_COMPILE_superludist@
+FFCS_COMPILE_yams = @FFCS_COMPILE_yams@
+FFCS_DYLIB_fflapack = @FFCS_DYLIB_fflapack@
+FFCS_DYLIB_gsl = @FFCS_DYLIB_gsl@
+FFCS_DYLIB_hips = @FFCS_DYLIB_hips@
+FFCS_DYLIB_hypre = @FFCS_DYLIB_hypre@
+FFCS_DYLIB_ipopt = @FFCS_DYLIB_ipopt@
+FFCS_DYLIB_lapack = @FFCS_DYLIB_lapack@
+FFCS_DYLIB_mmg3d = @FFCS_DYLIB_mmg3d@
+FFCS_DYLIB_mshmet = @FFCS_DYLIB_mshmet@
+FFCS_DYLIB_mumps = @FFCS_DYLIB_mumps@
+FFCS_DYLIB_mumps_seq = @FFCS_DYLIB_mumps_seq@
+FFCS_DYLIB_pardiso = @FFCS_DYLIB_pardiso@
+FFCS_DYLIB_parms = @FFCS_DYLIB_parms@
+FFCS_DYLIB_pastix = @FFCS_DYLIB_pastix@
+FFCS_DYLIB_pipe = @FFCS_DYLIB_pipe@
+FFCS_DYLIB_scotch = @FFCS_DYLIB_scotch@
+FFCS_DYLIB_superludist = @FFCS_DYLIB_superludist@
+FFCS_DYLIB_yams = @FFCS_DYLIB_yams@
+FFCS_MAKEFLAGS = @FFCS_MAKEFLAGS@
 FFGLUTNAME = @FFGLUTNAME@
 FFGLUTPROG = @FFGLUTPROG@
 FFLAGS = @FFLAGS@
diff --git a/src/medit/Makefile.am b/src/medit/Makefile.am
index fdfe642..e2637a7 100644
--- a/src/medit/Makefile.am
+++ b/src/medit/Makefile.am
@@ -1,37 +1,39 @@
 # Makefile using Automake + Autoconf
 # ----------------------------------
-# $Id$
+
 CXXLD=$(STATICTOOL) $(CXX)
 
 bin_PROGRAMS=$(MEDITPROG)
+EXTRA_DIST=picking.c 
 EXTRA_PROGRAMS=ffmedit
-ffmedit_SOURCES=  \
-animat.c		cube.c			image.c			listnum.c		mouse.c			persp.c			stream.c		zaldy2.c \
-bbfile.c		dlists.c		inmsh2.c		material.c		normal.c		picking.c		tiles.c \
-camera.c		ellipse.c		inout.c			medit.c			param.c			psfile.c		transform.c \
-cenrad.c		geometry.c		inout_morice.c		menus.c			parsar.c		scene.c			util.c \
-clip.c			gisfil.c		inout_popenbinaire.c	mesh.c			parsop.c		scissor.c		vector.c \
-clipvol.c		hash.c			items.c			mlists.c		particle.c		sftcpy.c		view.c \
-critip.c		ilists.c		keyboard.c		morphing.c		path.c			status.c		zaldy1.c \
-chrono.h	extern.h	image.h		mesh.h \
-eigenv.h	grafic.h	medit.h		sproto.h 
-
-
-LDADD= ../libMesh/libMesh.a $(LIBSGLUT) -lm
+ffmedit_SOURCES= animat.c cube.c image.c listnum.c mouse.c persp.c stream.c zaldy2.c bbfile.c dlists.c inmsh2.c		\
+material.c normal.c tiles.c camera.c ellipse.c inout.c medit.c param.c psfile.c transform.c cenrad.c geometry.c		\
+inout_morice.c menus.c parsar.c scene.c util.c clip.c gisfil.c inout_popenbinaire.c mesh.c parsop.c scissor.c vector.c	\
+clipvol.c hash.c items.c mlists.c particle.c sftcpy.c view.c critip.c ilists.c keyboard.c morphing.c path.c status.c	\
+zaldy1.c chrono.h extern.h image.h mesh.h eigenv.h grafic.h medit.h sproto.h
+
+
+LDADD=picking.$(OBJEXT) ../libMesh/libMesh.a $(LIBSGLUT) -lm
 AM_CPPFLAGS=-I$(srcdir)/../libMesh
 BUILT_SOURCES=compil.date
 compil.date: $(ffmedit_SOURCES)
 	echo "#define COMPIL " '"' `date` '(with ff++ $(VERSION))''"' > compil.date
 #.PHONY: compil.date
-all-local: pinking.no-opt$(MEDITPROG)
+###all-local: pinking.no-opt$(MEDITPROG)
+
+# ALH - during a parallel make, we should make sure that picking.o is not used before being made by a different
+# thread. If I understand things correctly, picking.c should not be compiled with the regular CFLAGS options.
 
-pinking.no-optffmedit$(EXEEXT):picking.c
-	rm picking.$(OBJEXT)
-	$(MAKE) picking.o $(MEDITPROG) CFLAGS="$(CNOFLAGS)"
-	touch pinking.no-optffmedit$(EXEEXT)
-pinking.no-opt:picking.c
-	touch pinking.no-opt
-clean-local:
-	-rm pinking.no-opt pinking.no-optffmedit$(EXEEXT)
+ffmedit_DEPENDENCIES=picking.$(OBJEXT)
+picking.$(OBJEXT):picking.c
+	${CC} -c $< $(CNOFLAGS) -o $@ 
 
+###pinking.no-optffmedit$(EXEEXT):picking.c
+###	rm picking.$(OBJEXT)
+###	$(MAKE) picking.o $(MEDITPROG) CFLAGS="$(CNOFLAGS)"
+###	touch pinking.no-optffmedit$(EXEEXT)
+###pinking.no-opt:picking.c
+###	touch pinking.no-opt
+###clean-local:
+###	-rm pinking.no-opt pinking.no-optffmedit$(EXEEXT)
 
diff --git a/src/medit/Makefile.in b/src/medit/Makefile.in
index 8453602..a891c8f 100644
--- a/src/medit/Makefile.in
+++ b/src/medit/Makefile.in
@@ -14,6 +14,9 @@
 
 @SET_MAKE@
 
+# Makefile using Automake + Autoconf
+# ----------------------------------
+
 VPATH = @srcdir@
 am__make_dryrun = \
   { \
@@ -56,7 +59,8 @@ 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)/acmacros.m4 \
-	$(top_srcdir)/acoptim.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/acoptim.m4 $(top_srcdir)/acmpi.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -69,12 +73,12 @@ am_ffmedit_OBJECTS = animat.$(OBJEXT) cube.$(OBJEXT) image.$(OBJEXT) \
 	listnum.$(OBJEXT) mouse.$(OBJEXT) persp.$(OBJEXT) \
 	stream.$(OBJEXT) zaldy2.$(OBJEXT) bbfile.$(OBJEXT) \
 	dlists.$(OBJEXT) inmsh2.$(OBJEXT) material.$(OBJEXT) \
-	normal.$(OBJEXT) picking.$(OBJEXT) tiles.$(OBJEXT) \
-	camera.$(OBJEXT) ellipse.$(OBJEXT) inout.$(OBJEXT) \
-	medit.$(OBJEXT) param.$(OBJEXT) psfile.$(OBJEXT) \
-	transform.$(OBJEXT) cenrad.$(OBJEXT) geometry.$(OBJEXT) \
-	inout_morice.$(OBJEXT) menus.$(OBJEXT) parsar.$(OBJEXT) \
-	scene.$(OBJEXT) util.$(OBJEXT) clip.$(OBJEXT) gisfil.$(OBJEXT) \
+	normal.$(OBJEXT) tiles.$(OBJEXT) camera.$(OBJEXT) \
+	ellipse.$(OBJEXT) inout.$(OBJEXT) medit.$(OBJEXT) \
+	param.$(OBJEXT) psfile.$(OBJEXT) transform.$(OBJEXT) \
+	cenrad.$(OBJEXT) geometry.$(OBJEXT) inout_morice.$(OBJEXT) \
+	menus.$(OBJEXT) parsar.$(OBJEXT) scene.$(OBJEXT) \
+	util.$(OBJEXT) clip.$(OBJEXT) gisfil.$(OBJEXT) \
 	inout_popenbinaire.$(OBJEXT) mesh.$(OBJEXT) parsop.$(OBJEXT) \
 	scissor.$(OBJEXT) vector.$(OBJEXT) clipvol.$(OBJEXT) \
 	hash.$(OBJEXT) items.$(OBJEXT) mlists.$(OBJEXT) \
@@ -85,7 +89,6 @@ am_ffmedit_OBJECTS = animat.$(OBJEXT) cube.$(OBJEXT) image.$(OBJEXT) \
 ffmedit_OBJECTS = $(am_ffmedit_OBJECTS)
 ffmedit_LDADD = $(LDADD)
 am__DEPENDENCIES_1 =
-ffmedit_DEPENDENCIES = ../libMesh/libMesh.a $(am__DEPENDENCIES_1)
 AM_V_P = $(am__v_P_ at AM_V@)
 am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
 am__v_P_0 = false
@@ -183,11 +186,47 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EIGENOBJ = @EIGENOBJ@
+ENABLE_FFCS = @ENABLE_FFCS@
 EPSTOPDF = @EPSTOPDF@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+FFCS_COMPILE_fflapack = @FFCS_COMPILE_fflapack@
+FFCS_COMPILE_gsl = @FFCS_COMPILE_gsl@
+FFCS_COMPILE_hips = @FFCS_COMPILE_hips@
+FFCS_COMPILE_hypre = @FFCS_COMPILE_hypre@
+FFCS_COMPILE_ipopt = @FFCS_COMPILE_ipopt@
+FFCS_COMPILE_lapack = @FFCS_COMPILE_lapack@
+FFCS_COMPILE_mmg3d = @FFCS_COMPILE_mmg3d@
+FFCS_COMPILE_mshmet = @FFCS_COMPILE_mshmet@
+FFCS_COMPILE_mumps = @FFCS_COMPILE_mumps@
+FFCS_COMPILE_mumps_seq = @FFCS_COMPILE_mumps_seq@
+FFCS_COMPILE_pardiso = @FFCS_COMPILE_pardiso@
+FFCS_COMPILE_parms = @FFCS_COMPILE_parms@
+FFCS_COMPILE_pastix = @FFCS_COMPILE_pastix@
+FFCS_COMPILE_pipe = @FFCS_COMPILE_pipe@
+FFCS_COMPILE_scotch = @FFCS_COMPILE_scotch@
+FFCS_COMPILE_superludist = @FFCS_COMPILE_superludist@
+FFCS_COMPILE_yams = @FFCS_COMPILE_yams@
+FFCS_DYLIB_fflapack = @FFCS_DYLIB_fflapack@
+FFCS_DYLIB_gsl = @FFCS_DYLIB_gsl@
+FFCS_DYLIB_hips = @FFCS_DYLIB_hips@
+FFCS_DYLIB_hypre = @FFCS_DYLIB_hypre@
+FFCS_DYLIB_ipopt = @FFCS_DYLIB_ipopt@
+FFCS_DYLIB_lapack = @FFCS_DYLIB_lapack@
+FFCS_DYLIB_mmg3d = @FFCS_DYLIB_mmg3d@
+FFCS_DYLIB_mshmet = @FFCS_DYLIB_mshmet@
+FFCS_DYLIB_mumps = @FFCS_DYLIB_mumps@
+FFCS_DYLIB_mumps_seq = @FFCS_DYLIB_mumps_seq@
+FFCS_DYLIB_pardiso = @FFCS_DYLIB_pardiso@
+FFCS_DYLIB_parms = @FFCS_DYLIB_parms@
+FFCS_DYLIB_pastix = @FFCS_DYLIB_pastix@
+FFCS_DYLIB_pipe = @FFCS_DYLIB_pipe@
+FFCS_DYLIB_scotch = @FFCS_DYLIB_scotch@
+FFCS_DYLIB_superludist = @FFCS_DYLIB_superludist@
+FFCS_DYLIB_yams = @FFCS_DYLIB_yams@
+FFCS_MAKEFLAGS = @FFCS_MAKEFLAGS@
 FFGLUTNAME = @FFGLUTNAME@
 FFGLUTPROG = @FFGLUTPROG@
 FFLAGS = @FFLAGS@
@@ -354,26 +393,24 @@ target_alias = @target_alias@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-
-# Makefile using Automake + Autoconf
-# ----------------------------------
-# $Id$
 CXXLD = $(STATICTOOL) $(CXX)
 bin_PROGRAMS = $(MEDITPROG)
-ffmedit_SOURCES = \
-animat.c		cube.c			image.c			listnum.c		mouse.c			persp.c			stream.c		zaldy2.c \
-bbfile.c		dlists.c		inmsh2.c		material.c		normal.c		picking.c		tiles.c \
-camera.c		ellipse.c		inout.c			medit.c			param.c			psfile.c		transform.c \
-cenrad.c		geometry.c		inout_morice.c		menus.c			parsar.c		scene.c			util.c \
-clip.c			gisfil.c		inout_popenbinaire.c	mesh.c			parsop.c		scissor.c		vector.c \
-clipvol.c		hash.c			items.c			mlists.c		particle.c		sftcpy.c		view.c \
-critip.c		ilists.c		keyboard.c		morphing.c		path.c			status.c		zaldy1.c \
-chrono.h	extern.h	image.h		mesh.h \
-eigenv.h	grafic.h	medit.h		sproto.h 
-
-LDADD = ../libMesh/libMesh.a $(LIBSGLUT) -lm
+EXTRA_DIST = picking.c 
+ffmedit_SOURCES = animat.c cube.c image.c listnum.c mouse.c persp.c stream.c zaldy2.c bbfile.c dlists.c inmsh2.c		\
+material.c normal.c tiles.c camera.c ellipse.c inout.c medit.c param.c psfile.c transform.c cenrad.c geometry.c		\
+inout_morice.c menus.c parsar.c scene.c util.c clip.c gisfil.c inout_popenbinaire.c mesh.c parsop.c scissor.c vector.c	\
+clipvol.c hash.c items.c mlists.c particle.c sftcpy.c view.c critip.c ilists.c keyboard.c morphing.c path.c status.c	\
+zaldy1.c chrono.h extern.h image.h mesh.h eigenv.h grafic.h medit.h sproto.h
+
+LDADD = picking.$(OBJEXT) ../libMesh/libMesh.a $(LIBSGLUT) -lm
 AM_CPPFLAGS = -I$(srcdir)/../libMesh
 BUILT_SOURCES = compil.date
+#.PHONY: compil.date
+###all-local: pinking.no-opt$(MEDITPROG)
+
+# ALH - during a parallel make, we should make sure that picking.o is not used before being made by a different
+# thread. If I understand things correctly, picking.c should not be compiled with the regular CFLAGS options.
+ffmedit_DEPENDENCIES = picking.$(OBJEXT)
 all: $(BUILT_SOURCES)
 	$(MAKE) $(AM_MAKEFLAGS) all-am
 
@@ -497,7 +534,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/particle.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/path.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/persp.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/picking.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/psfile.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/scene.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/scissor.Po at am__quote@
@@ -611,7 +647,7 @@ distdir: $(DISTFILES)
 check-am: all-am
 check: $(BUILT_SOURCES)
 	$(MAKE) $(AM_MAKEFLAGS) check-am
-all-am: Makefile $(PROGRAMS) all-local
+all-am: Makefile $(PROGRAMS)
 installdirs:
 	for dir in "$(DESTDIR)$(bindir)"; do \
 	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
@@ -650,7 +686,7 @@ maintainer-clean-generic:
 	-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
 clean: clean-am
 
-clean-am: clean-binPROGRAMS clean-generic clean-local mostlyclean-am
+clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
 
 distclean: distclean-am
 	-rm -rf ./$(DEPDIR)
@@ -719,33 +755,33 @@ uninstall-am: uninstall-binPROGRAMS
 
 .MAKE: all check install install-am install-strip
 
-.PHONY: CTAGS GTAGS TAGS all all-am all-local check check-am clean \
-	clean-binPROGRAMS clean-generic clean-local cscopelist-am \
-	ctags ctags-am distclean distclean-compile distclean-generic \
-	distclean-tags distdir dvi dvi-am html html-am info info-am \
-	install install-am install-binPROGRAMS install-data \
-	install-data-am install-dvi install-dvi-am install-exec \
-	install-exec-am install-html install-html-am install-info \
-	install-info-am install-man install-pdf install-pdf-am \
-	install-ps install-ps-am install-strip installcheck \
-	installcheck-am installdirs maintainer-clean \
-	maintainer-clean-generic mostlyclean mostlyclean-compile \
-	mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \
-	uninstall-am uninstall-binPROGRAMS
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \
+	clean-binPROGRAMS clean-generic cscopelist-am ctags ctags-am \
+	distclean distclean-compile distclean-generic distclean-tags \
+	distdir dvi dvi-am html html-am info info-am install \
+	install-am install-binPROGRAMS install-data install-data-am \
+	install-dvi install-dvi-am install-exec install-exec-am \
+	install-html install-html-am install-info install-info-am \
+	install-man install-pdf install-pdf-am install-ps \
+	install-ps-am install-strip installcheck installcheck-am \
+	installdirs maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \
+	ps ps-am tags tags-am uninstall uninstall-am \
+	uninstall-binPROGRAMS
 
 compil.date: $(ffmedit_SOURCES)
 	echo "#define COMPIL " '"' `date` '(with ff++ $(VERSION))''"' > compil.date
-#.PHONY: compil.date
-all-local: pinking.no-opt$(MEDITPROG)
-
-pinking.no-optffmedit$(EXEEXT):picking.c
-	rm picking.$(OBJEXT)
-	$(MAKE) picking.o $(MEDITPROG) CFLAGS="$(CNOFLAGS)"
-	touch pinking.no-optffmedit$(EXEEXT)
-pinking.no-opt:picking.c
-	touch pinking.no-opt
-clean-local:
-	-rm pinking.no-opt pinking.no-optffmedit$(EXEEXT)
+picking.$(OBJEXT):picking.c
+	${CC} -c $< $(CNOFLAGS) -o $@ 
+
+###pinking.no-optffmedit$(EXEEXT):picking.c
+###	rm picking.$(OBJEXT)
+###	$(MAKE) picking.o $(MEDITPROG) CFLAGS="$(CNOFLAGS)"
+###	touch pinking.no-optffmedit$(EXEEXT)
+###pinking.no-opt:picking.c
+###	touch pinking.no-opt
+###clean-local:
+###	-rm pinking.no-opt pinking.no-optffmedit$(EXEEXT)
 
 # 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/mpi/Makefile.am b/src/mpi/Makefile.am
index 7d81a1a..34d05b7 100644
--- a/src/mpi/Makefile.am
+++ b/src/mpi/Makefile.am
@@ -2,7 +2,10 @@
 # ----------------------------------
 # $Id$
 # change FH mars 2010 for sgi mpiu .... 
-#CXX=@MPICXX@
+
+# FFCS - we need to call MPICXX directly because Windows options are too different to be detailed to the FF configuration script.
+
+CXX=@MPICXX@
 
 # To create statically linked executables (see configure.ac)
 CXXLD=$(STATICTOOL) $(CXX)
@@ -14,8 +17,9 @@ EXTRA_PROGRAMS=FreeFem++-mpi
 EXTRA_SCRIPTS=ff-mpirun
 EXTRA_DIST=ff-mpirun.in
 
-FreeFem___mpi_SOURCES=../Graphics/sansrgraph.cpp ../lglib/mymain.cpp   parallelempi.cpp	\
-../lglib/lg.tab.cpp
+# FFCS: visualization stream redirection
+FreeFem___mpi_SOURCES=../Graphics/sansrgraph.cpp ../lglib/mymain.cpp parallelempi.cpp ../lglib/lg.tab.cpp	\
+	../fflib/ffapi.cpp
 FreeFem___mpi_DEPENDENCIES=../fflib/libff.a
 LDADD=../fflib/libff.a @UMFPACKLIBS@ @ARPACKLIBS@ @BLASLIBS@ @MPI_LIB@
 
diff --git a/src/mpi/Makefile.in b/src/mpi/Makefile.in
index aa70518..f82fafc 100644
--- a/src/mpi/Makefile.in
+++ b/src/mpi/Makefile.in
@@ -18,7 +18,8 @@
 # ----------------------------------
 # $Id$
 # change FH mars 2010 for sgi mpiu .... 
-#CXX=@MPICXX@
+
+# FFCS - we need to call MPICXX directly because Windows options are too different to be detailed to the FF configuration script.
 
 
 VPATH = @srcdir@
@@ -63,7 +64,8 @@ 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)/acmacros.m4 \
-	$(top_srcdir)/acoptim.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/acoptim.m4 $(top_srcdir)/acmpi.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -73,7 +75,7 @@ CONFIG_CLEAN_VPATH_FILES =
 am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)"
 PROGRAMS = $(bin_PROGRAMS)
 am_FreeFem___mpi_OBJECTS = sansrgraph.$(OBJEXT) mymain.$(OBJEXT) \
-	parallelempi.$(OBJEXT) lg.tab.$(OBJEXT)
+	parallelempi.$(OBJEXT) lg.tab.$(OBJEXT) ffapi.$(OBJEXT)
 FreeFem___mpi_OBJECTS = $(am_FreeFem___mpi_OBJECTS)
 FreeFem___mpi_LDADD = $(LDADD)
 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
@@ -184,7 +186,7 @@ CFLAGS = @CFLAGS@
 CFLAGSF77 = @CFLAGSF77@
 CNOFLAGS = @CNOFLAGS@
 CPPFLAGS = @CPPFLAGS@
-CXX = @CXX@
+CXX = @MPICXX@
 CXXCPP = @CXXCPP@
 CXXDEPMODE = @CXXDEPMODE@
 CXXFLAGS = @CXXFLAGS@
@@ -205,11 +207,47 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EIGENOBJ = @EIGENOBJ@
+ENABLE_FFCS = @ENABLE_FFCS@
 EPSTOPDF = @EPSTOPDF@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+FFCS_COMPILE_fflapack = @FFCS_COMPILE_fflapack@
+FFCS_COMPILE_gsl = @FFCS_COMPILE_gsl@
+FFCS_COMPILE_hips = @FFCS_COMPILE_hips@
+FFCS_COMPILE_hypre = @FFCS_COMPILE_hypre@
+FFCS_COMPILE_ipopt = @FFCS_COMPILE_ipopt@
+FFCS_COMPILE_lapack = @FFCS_COMPILE_lapack@
+FFCS_COMPILE_mmg3d = @FFCS_COMPILE_mmg3d@
+FFCS_COMPILE_mshmet = @FFCS_COMPILE_mshmet@
+FFCS_COMPILE_mumps = @FFCS_COMPILE_mumps@
+FFCS_COMPILE_mumps_seq = @FFCS_COMPILE_mumps_seq@
+FFCS_COMPILE_pardiso = @FFCS_COMPILE_pardiso@
+FFCS_COMPILE_parms = @FFCS_COMPILE_parms@
+FFCS_COMPILE_pastix = @FFCS_COMPILE_pastix@
+FFCS_COMPILE_pipe = @FFCS_COMPILE_pipe@
+FFCS_COMPILE_scotch = @FFCS_COMPILE_scotch@
+FFCS_COMPILE_superludist = @FFCS_COMPILE_superludist@
+FFCS_COMPILE_yams = @FFCS_COMPILE_yams@
+FFCS_DYLIB_fflapack = @FFCS_DYLIB_fflapack@
+FFCS_DYLIB_gsl = @FFCS_DYLIB_gsl@
+FFCS_DYLIB_hips = @FFCS_DYLIB_hips@
+FFCS_DYLIB_hypre = @FFCS_DYLIB_hypre@
+FFCS_DYLIB_ipopt = @FFCS_DYLIB_ipopt@
+FFCS_DYLIB_lapack = @FFCS_DYLIB_lapack@
+FFCS_DYLIB_mmg3d = @FFCS_DYLIB_mmg3d@
+FFCS_DYLIB_mshmet = @FFCS_DYLIB_mshmet@
+FFCS_DYLIB_mumps = @FFCS_DYLIB_mumps@
+FFCS_DYLIB_mumps_seq = @FFCS_DYLIB_mumps_seq@
+FFCS_DYLIB_pardiso = @FFCS_DYLIB_pardiso@
+FFCS_DYLIB_parms = @FFCS_DYLIB_parms@
+FFCS_DYLIB_pastix = @FFCS_DYLIB_pastix@
+FFCS_DYLIB_pipe = @FFCS_DYLIB_pipe@
+FFCS_DYLIB_scotch = @FFCS_DYLIB_scotch@
+FFCS_DYLIB_superludist = @FFCS_DYLIB_superludist@
+FFCS_DYLIB_yams = @FFCS_DYLIB_yams@
+FFCS_MAKEFLAGS = @FFCS_MAKEFLAGS@
 FFGLUTNAME = @FFGLUTNAME@
 FFGLUTPROG = @FFGLUTPROG@
 FFLAGS = @FFLAGS@
@@ -385,8 +423,10 @@ bin_PROGRAMS = $(MPIPROG)
 bin_SCRIPTS = $(MPISCRIPT)
 EXTRA_SCRIPTS = ff-mpirun
 EXTRA_DIST = ff-mpirun.in
-FreeFem___mpi_SOURCES = ../Graphics/sansrgraph.cpp ../lglib/mymain.cpp   parallelempi.cpp	\
-../lglib/lg.tab.cpp
+
+# FFCS: visualization stream redirection
+FreeFem___mpi_SOURCES = ../Graphics/sansrgraph.cpp ../lglib/mymain.cpp parallelempi.cpp ../lglib/lg.tab.cpp	\
+	../fflib/ffapi.cpp
 
 FreeFem___mpi_DEPENDENCIES = ../fflib/libff.a
 LDADD = ../fflib/libff.a @UMFPACKLIBS@ @ARPACKLIBS@ @BLASLIBS@ @MPI_LIB@
@@ -513,6 +553,7 @@ mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ffapi.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/lg.tab.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mymain.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/parallelempi.Po at am__quote@
@@ -574,6 +615,20 @@ lg.tab.obj: ../lglib/lg.tab.cpp
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o lg.tab.obj `if test -f '../lglib/lg.tab.cpp'; then $(CYGPATH_W) '../lglib/lg.tab.cpp'; else $(CYGPATH_W) '$(srcdir)/../lglib/lg.tab.cpp'; fi`
 
+ffapi.o: ../fflib/ffapi.cpp
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ffapi.o -MD -MP -MF $(DEPDIR)/ffapi.Tpo -c -o ffapi.o `test -f '../fflib/ffapi.cpp' || echo '$(srcdir)/'`../fflib/ffapi.cpp
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/ffapi.Tpo $(DEPDIR)/ffapi.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='../fflib/ffapi.cpp' object='ffapi.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o ffapi.o `test -f '../fflib/ffapi.cpp' || echo '$(srcdir)/'`../fflib/ffapi.cpp
+
+ffapi.obj: ../fflib/ffapi.cpp
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ffapi.obj -MD -MP -MF $(DEPDIR)/ffapi.Tpo -c -o ffapi.obj `if test -f '../fflib/ffapi.cpp'; then $(CYGPATH_W) '../fflib/ffapi.cpp'; else $(CYGPATH_W) '$(srcdir)/../fflib/ffapi.cpp'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/ffapi.Tpo $(DEPDIR)/ffapi.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='../fflib/ffapi.cpp' object='ffapi.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o ffapi.obj `if test -f '../fflib/ffapi.cpp'; then $(CYGPATH_W) '../fflib/ffapi.cpp'; else $(CYGPATH_W) '$(srcdir)/../fflib/ffapi.cpp'; fi`
+
 ID: $(am__tagged_files)
 	$(am__define_uniq_tagged_files); mkid -fID $$unique
 tags: tags-am
diff --git a/src/mpi/ff-mpirun.in b/src/mpi/ff-mpirun.in
index 23a3758..f615e38 100755
--- a/src/mpi/ff-mpirun.in
+++ b/src/mpi/ff-mpirun.in
@@ -14,10 +14,14 @@ j=1;
 #echo $1 ---
 while test -n "$1" ; do
 ((j=$j+1))
-((j1=$j+1))
+#((j1=$j+1))
 #echo --- $1 --  $j1 $j
 case "$1" in
-*.edp) a[$j]="${ffmpi}";a[$j1]="$1";j=j1;;
+"-nw") nw=1;;
+"-win") w=0;;
+*.edp) a[$j]="${ffmpi}";
+if [ "$nw" -eq 1 ]; then ((j=$j+1));a[$j]="-nw"; fi
+((j=$j+1));a[$j]="$1";;
 #if[ ! -f "$1" ]; then echo error file no found "$1"; dry=2; fi;;
 -dry) dry=1;; 
 *)  a[$j]="$1";;
diff --git a/src/mpi/parallelempi.cpp b/src/mpi/parallelempi.cpp
index 5b182d0..420dfd0 100644
--- a/src/mpi/parallelempi.cpp
+++ b/src/mpi/parallelempi.cpp
@@ -40,6 +40,8 @@ using namespace std;
 #include "lgsolver.hpp"
 #include "problem.hpp"
 
+//FFCS redirection
+#include "../fflib/ffapi.hpp"
 
 #undef MPICH_SKIP_MPICXX
 #define  MPICH_SKIP_MPICXX
@@ -2278,7 +2280,8 @@ public:
 // Fin add J. Morice
 void f_initparallele(int &argc, char **& argv)
 {
-  MPI_Init(&argc, &argv);
+  /// FFCS: MPI_Init() needs to be called earlier (in ffcs/src/server.cpp)
+  ffapi::mpi_init(argc,argv);
   
   int mpirank1,mpisize1;
   MPI_Comm_rank(MPI_COMM_WORLD, &mpirank1); /* local */ 
@@ -2289,8 +2292,10 @@ void f_initparallele(int &argc, char **& argv)
   if(verbosity> 2 || (mpirank ==0))
   cout << "initparallele rank " <<  mpirank << " on " << mpisize << endl;
 }
+
 double ffMPI_Wtime() {return MPI_Wtime();}
 double ffMPI_Wtick() {return MPI_Wtick();}
+
 void f_init_lgparallele()
   {
     if(verbosity && mpirank == 0) cout << "parallelempi ";
@@ -2607,7 +2612,9 @@ void f_init_lgparallele()
   }
 void f_end_parallele()
 {
-    MPI_Finalize();
+  /// FFCS: MPI_Finalize() needs to be called later than this (in
+  /// ffcs/src/server.cpp)
+  ffapi::mpi_finalize();
     if(mpirank==0 || verbosity>2) cout << "FreeFem++-mpi finalize correctly .\n" << flush ; 
     else if(verbosity>5)  cout << '.' << endl ;
 }
diff --git a/src/nw/Makefile.am b/src/nw/Makefile.am
index e3844ac..b95021a 100644
--- a/src/nw/Makefile.am
+++ b/src/nw/Makefile.am
@@ -6,15 +6,17 @@
 CXXLD=$(STATICTOOL) $(CXX)
 bin_PROGRAMS=FreeFem++ FreeFem++-nw @FFGLUTPROG@
 EXTRA_PROGRAMS=ffglut
+
+# FFCS:visualization stream redirection
 ffglut_SOURCES=../Graphics/ffglut.cpp ../Graphics/gggg.cpp ../Graphics/ffthreads.cpp \
 ../Graphics/ffthreads.hpp \
 ../femlib/fem.cpp ../femlib/Mesh3dn.cpp ../femlib/Mesh2dn.cpp  ../femlib/Mesh1dn.cpp ../femlib/GQuadTree.cpp  ../femlib/FQuadTree.cpp \
-../femlib/Drawing.cpp ../femlib/mshptg.cpp  
+../femlib/Drawing.cpp ../femlib/mshptg.cpp ../fflib/ffapi.cpp
 
 ffglut_DEPENDENCIES= ../libMesh/libMesh.a
 ffglut_LDADD= ../libMesh/libMesh.a @LIBSGLUT@ @LIBSPTHREAD@ 
-FreeFem___nw_SOURCES=../Graphics/sansrgraph.cpp ../mpi/parallelempi-empty.cpp
-FreeFem___SOURCES=../Graphics/sansrgraph.cpp  ../mpi/parallelempi-empty.cpp 
+FreeFem___nw_SOURCES=../Graphics/sansrgraph.cpp ../mpi/parallelempi-empty.cpp ../fflib/ffapi.cpp
+FreeFem___SOURCES=../Graphics/sansrgraph.cpp  ../mpi/parallelempi-empty.cpp ../fflib/ffapi.cpp
 
 FreeFem___nw_DEPENDENCIES=../fflib/libff.a ../lglib/liblg.a
 FreeFem___DEPENDENCIES=../fflib/libff.a ../lglib/liblg.a
diff --git a/src/nw/Makefile.in b/src/nw/Makefile.in
index 0a488b1..c475f4e 100644
--- a/src/nw/Makefile.in
+++ b/src/nw/Makefile.in
@@ -61,7 +61,8 @@ 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)/acmacros.m4 \
-	$(top_srcdir)/acoptim.m4 $(top_srcdir)/configure.ac
+	$(top_srcdir)/acoptim.m4 $(top_srcdir)/acmpi.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -71,17 +72,18 @@ CONFIG_CLEAN_VPATH_FILES =
 am__installdirs = "$(DESTDIR)$(bindir)"
 PROGRAMS = $(bin_PROGRAMS)
 am_FreeFem___OBJECTS = sansrgraph.$(OBJEXT) \
-	parallelempi-empty.$(OBJEXT)
+	parallelempi-empty.$(OBJEXT) ffapi.$(OBJEXT)
 FreeFem___OBJECTS = $(am_FreeFem___OBJECTS)
 FreeFem___LDADD = $(LDADD)
 am_FreeFem___nw_OBJECTS = sansrgraph.$(OBJEXT) \
-	parallelempi-empty.$(OBJEXT)
+	parallelempi-empty.$(OBJEXT) ffapi.$(OBJEXT)
 FreeFem___nw_OBJECTS = $(am_FreeFem___nw_OBJECTS)
 FreeFem___nw_LDADD = $(LDADD)
 am_ffglut_OBJECTS = ffglut.$(OBJEXT) gggg.$(OBJEXT) \
 	ffthreads.$(OBJEXT) fem.$(OBJEXT) Mesh3dn.$(OBJEXT) \
 	Mesh2dn.$(OBJEXT) Mesh1dn.$(OBJEXT) GQuadTree.$(OBJEXT) \
-	FQuadTree.$(OBJEXT) Drawing.$(OBJEXT) mshptg.$(OBJEXT)
+	FQuadTree.$(OBJEXT) Drawing.$(OBJEXT) mshptg.$(OBJEXT) \
+	ffapi.$(OBJEXT)
 ffglut_OBJECTS = $(am_ffglut_OBJECTS)
 AM_V_P = $(am__v_P_ at AM_V@)
 am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
@@ -198,11 +200,47 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EIGENOBJ = @EIGENOBJ@
+ENABLE_FFCS = @ENABLE_FFCS@
 EPSTOPDF = @EPSTOPDF@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FC = @FC@
 FCFLAGS = @FCFLAGS@
+FFCS_COMPILE_fflapack = @FFCS_COMPILE_fflapack@
+FFCS_COMPILE_gsl = @FFCS_COMPILE_gsl@
+FFCS_COMPILE_hips = @FFCS_COMPILE_hips@
+FFCS_COMPILE_hypre = @FFCS_COMPILE_hypre@
+FFCS_COMPILE_ipopt = @FFCS_COMPILE_ipopt@
+FFCS_COMPILE_lapack = @FFCS_COMPILE_lapack@
+FFCS_COMPILE_mmg3d = @FFCS_COMPILE_mmg3d@
+FFCS_COMPILE_mshmet = @FFCS_COMPILE_mshmet@
+FFCS_COMPILE_mumps = @FFCS_COMPILE_mumps@
+FFCS_COMPILE_mumps_seq = @FFCS_COMPILE_mumps_seq@
+FFCS_COMPILE_pardiso = @FFCS_COMPILE_pardiso@
+FFCS_COMPILE_parms = @FFCS_COMPILE_parms@
+FFCS_COMPILE_pastix = @FFCS_COMPILE_pastix@
+FFCS_COMPILE_pipe = @FFCS_COMPILE_pipe@
+FFCS_COMPILE_scotch = @FFCS_COMPILE_scotch@
+FFCS_COMPILE_superludist = @FFCS_COMPILE_superludist@
+FFCS_COMPILE_yams = @FFCS_COMPILE_yams@
+FFCS_DYLIB_fflapack = @FFCS_DYLIB_fflapack@
+FFCS_DYLIB_gsl = @FFCS_DYLIB_gsl@
+FFCS_DYLIB_hips = @FFCS_DYLIB_hips@
+FFCS_DYLIB_hypre = @FFCS_DYLIB_hypre@
+FFCS_DYLIB_ipopt = @FFCS_DYLIB_ipopt@
+FFCS_DYLIB_lapack = @FFCS_DYLIB_lapack@
+FFCS_DYLIB_mmg3d = @FFCS_DYLIB_mmg3d@
+FFCS_DYLIB_mshmet = @FFCS_DYLIB_mshmet@
+FFCS_DYLIB_mumps = @FFCS_DYLIB_mumps@
+FFCS_DYLIB_mumps_seq = @FFCS_DYLIB_mumps_seq@
+FFCS_DYLIB_pardiso = @FFCS_DYLIB_pardiso@
+FFCS_DYLIB_parms = @FFCS_DYLIB_parms@
+FFCS_DYLIB_pastix = @FFCS_DYLIB_pastix@
+FFCS_DYLIB_pipe = @FFCS_DYLIB_pipe@
+FFCS_DYLIB_scotch = @FFCS_DYLIB_scotch@
+FFCS_DYLIB_superludist = @FFCS_DYLIB_superludist@
+FFCS_DYLIB_yams = @FFCS_DYLIB_yams@
+FFCS_MAKEFLAGS = @FFCS_MAKEFLAGS@
 FFGLUTNAME = @FFGLUTNAME@
 FFGLUTPROG = @FFGLUTPROG@
 FFLAGS = @FFLAGS@
@@ -372,15 +410,17 @@ top_srcdir = @top_srcdir@
 
 # To create statically linked executables (see configure.ac)
 CXXLD = $(STATICTOOL) $(CXX)
+
+# FFCS:visualization stream redirection
 ffglut_SOURCES = ../Graphics/ffglut.cpp ../Graphics/gggg.cpp ../Graphics/ffthreads.cpp \
 ../Graphics/ffthreads.hpp \
 ../femlib/fem.cpp ../femlib/Mesh3dn.cpp ../femlib/Mesh2dn.cpp  ../femlib/Mesh1dn.cpp ../femlib/GQuadTree.cpp  ../femlib/FQuadTree.cpp \
-../femlib/Drawing.cpp ../femlib/mshptg.cpp  
+../femlib/Drawing.cpp ../femlib/mshptg.cpp ../fflib/ffapi.cpp
 
 ffglut_DEPENDENCIES = ../libMesh/libMesh.a
 ffglut_LDADD = ../libMesh/libMesh.a @LIBSGLUT@ @LIBSPTHREAD@ 
-FreeFem___nw_SOURCES = ../Graphics/sansrgraph.cpp ../mpi/parallelempi-empty.cpp
-FreeFem___SOURCES = ../Graphics/sansrgraph.cpp  ../mpi/parallelempi-empty.cpp 
+FreeFem___nw_SOURCES = ../Graphics/sansrgraph.cpp ../mpi/parallelempi-empty.cpp ../fflib/ffapi.cpp
+FreeFem___SOURCES = ../Graphics/sansrgraph.cpp  ../mpi/parallelempi-empty.cpp ../fflib/ffapi.cpp
 FreeFem___nw_DEPENDENCIES = ../fflib/libff.a ../lglib/liblg.a
 FreeFem___DEPENDENCIES = ../fflib/libff.a ../lglib/liblg.a
 LDADD = ../lglib/liblg.a ../fflib/libff.a @UMFPACKLIBS@ @ARPACKLIBS@ @BLASLIBS@
@@ -484,6 +524,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/Mesh2dn.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/Mesh3dn.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/fem.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ffapi.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ffglut.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ffthreads.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gggg.Po at am__quote@
@@ -533,6 +574,20 @@ parallelempi-empty.obj: ../mpi/parallelempi-empty.cpp
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o parallelempi-empty.obj `if test -f '../mpi/parallelempi-empty.cpp'; then $(CYGPATH_W) '../mpi/parallelempi-empty.cpp'; else $(CYGPATH_W) '$(srcdir)/../mpi/parallelempi-empty.cpp'; fi`
 
+ffapi.o: ../fflib/ffapi.cpp
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ffapi.o -MD -MP -MF $(DEPDIR)/ffapi.Tpo -c -o ffapi.o `test -f '../fflib/ffapi.cpp' || echo '$(srcdir)/'`../fflib/ffapi.cpp
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/ffapi.Tpo $(DEPDIR)/ffapi.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='../fflib/ffapi.cpp' object='ffapi.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o ffapi.o `test -f '../fflib/ffapi.cpp' || echo '$(srcdir)/'`../fflib/ffapi.cpp
+
+ffapi.obj: ../fflib/ffapi.cpp
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ffapi.obj -MD -MP -MF $(DEPDIR)/ffapi.Tpo -c -o ffapi.obj `if test -f '../fflib/ffapi.cpp'; then $(CYGPATH_W) '../fflib/ffapi.cpp'; else $(CYGPATH_W) '$(srcdir)/../fflib/ffapi.cpp'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/ffapi.Tpo $(DEPDIR)/ffapi.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='../fflib/ffapi.cpp' object='ffapi.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o ffapi.obj `if test -f '../fflib/ffapi.cpp'; then $(CYGPATH_W) '../fflib/ffapi.cpp'; else $(CYGPATH_W) '$(srcdir)/../fflib/ffapi.cpp'; fi`
+
 ffglut.o: ../Graphics/ffglut.cpp
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ffglut.o -MD -MP -MF $(DEPDIR)/ffglut.Tpo -c -o ffglut.o `test -f '../Graphics/ffglut.cpp' || echo '$(srcdir)/'`../Graphics/ffglut.cpp
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/ffglut.Tpo $(DEPDIR)/ffglut.Po
diff --git a/src/solver/hypre_FreeFem.cpp b/src/solver/hypre_FreeFem.cpp
index 3b9ba3e..921f141 100755
--- a/src/solver/hypre_FreeFem.cpp
+++ b/src/solver/hypre_FreeFem.cpp
@@ -1636,7 +1636,7 @@ public:
 	    if(X_loc!=NULL) free(X_loc);  if(rhs!=NULL) free(rhs); if(xx!=NULL) free(xx);
 	    if(b_loc!=NULL) free(b_loc);  if(row!=NULL) free(row); 
 	    if(iwork1!=NULL) delete [] iwork1; 
-	    if(mapptr!=NULL) delete [] mapptr;
+	    if(mapptr!=NULL) delete [] mapptr;
             }
 	  ~HypreSolver() { 
 	    	if(verbosity){
diff --git a/src/solver/parms_FreeFem.cpp b/src/solver/parms_FreeFem.cpp
index 0ea5df0..32119a5 100755
--- a/src/solver/parms_FreeFem.cpp
+++ b/src/solver/parms_FreeFem.cpp
@@ -412,11 +412,11 @@ int assignprecon( char *precon_str, DistMatrix dm)
 
 
 
-#define minint(a, b)       ( (a) < (b) ? (a) : (b) )
-#define maxint(a, b)       ( (a) > (b) ? (a) : (b) )
-#define max(a, b)       ( (a) > (b) ? (a) : (b) )
-#define min(a, b)   ( a < b ? (a) : (b) )
-#define fabsmin(a, b)   ( fabs(a) < fabs(b) ? (a) : (b) )
+#define minint(a, b)       ( (a) < (b) ? (a) : (b) )
+#define maxint(a, b)       ( (a) > (b) ? (a) : (b) )
+#define max(a, b)       ( (a) > (b) ? (a) : (b) )
+#define min(a, b)   ( a < b ? (a) : (b) )
+#define fabsmin(a, b)   ( fabs(a) < fabs(b) ? (a) : (b) )
 #define fabsmax(a, b)   ( fabs(a) > fabs(b) ? (a) : (b) )
 
 
@@ -471,11 +471,12 @@ public:
 	/*Differents preconditionners use*/
 	 meth[0]=(char *)malloc(sizeof(char)*9); strcpy(meth[0],"add_ilu0"); meth[1]=(char *)malloc(sizeof(char)*9); strcpy(meth[1],"add_ilut"); 
 	 meth[2]=(char *)malloc(sizeof(char)*9); strcpy(meth[2],"add_iluk"); meth[3]=(char *)malloc(sizeof(char)*9); strcpy(meth[3],"add_arms");
-	 meth[4]=(char *)malloc(sizeof(char)*9); strcpy(meth[4],"lsch_ilu0"); meth[5]=(char *)malloc(sizeof(char)*9); strcpy(meth[5],"lsch_ilut");  
-	 meth[6]=(char *)malloc(sizeof(char)*9); strcpy(meth[6],"lsch_iluk"); meth[7]=(char *)malloc(sizeof(char)*9); strcpy(meth[7],"lsch_arms"); 	
-	 meth[8]=(char *)malloc(sizeof(char)*9); strcpy(meth[8],"rsch_ilu0"); meth[9]=(char *)malloc(sizeof(char)*9); strcpy(meth[9],"rsch_ilut");
-         meth[10]=(char *)malloc(sizeof(char)*9); strcpy(meth[10],"rsch_iluk"); meth[11]=(char *)malloc(sizeof(char)*9); strcpy(meth[11],"rsch_arms");
-	 meth[12]=(char *)malloc(sizeof(char)*9); strcpy(meth[12],"sch_gilu0"); meth[13]=(char *)malloc(sizeof(char)*9); strcpy(meth[13],"sch_sgs");
+	 // FFCS - fixed "buffer overflow" warning by JHunt
+	 meth[4]=(char *)malloc(sizeof(char)*10); strcpy(meth[4],"lsch_ilu0"); meth[5]=(char *)malloc(sizeof(char)*10); strcpy(meth[5],"lsch_ilut");  
+	 meth[6]=(char *)malloc(sizeof(char)*10); strcpy(meth[6],"lsch_iluk"); meth[7]=(char *)malloc(sizeof(char)*10); strcpy(meth[7],"lsch_arms"); 	
+	 meth[8]=(char *)malloc(sizeof(char)*10); strcpy(meth[8],"rsch_ilu0"); meth[9]=(char *)malloc(sizeof(char)*10); strcpy(meth[9],"rsch_ilut");
+         meth[10]=(char *)malloc(sizeof(char)*10); strcpy(meth[10],"rsch_iluk"); meth[11]=(char *)malloc(sizeof(char)*10); strcpy(meth[11],"rsch_arms");
+	 meth[12]=(char *)malloc(sizeof(char)*10); strcpy(meth[12],"sch_gilu0"); meth[13]=(char *)malloc(sizeof(char)*8); strcpy(meth[13],"sch_sgs");
 	/*storage format of the matrix*/
          char pcrM[4];
 	strcpy(pcrM,"csr");
@@ -929,8 +930,8 @@ public:
 		 fprintf(stdout, "The 2-NORM OF THE RELATIVE RESIDUAL IS %16.8g\n", res/res1);
 		 
 		
-	 }
-
+	 }
+
   	  double *  xx= (double *)malloc(sizeof(double)*n);
 	 
 	 
@@ -946,7 +947,7 @@ public:
 	   MPI_Gatherv(&(poloc[0]), nloc, MPI_INT, &(perm[0]), iwork, mapptr ,  MPI_INT, 0,comm );
 	   MPI_Bcast(perm,AA.n,MPI_INT,0, comm);
 	   
-	   int *invp=(int *)malloc(sizeof(int)*n);
+	   int *invp=(int *)malloc(sizeof(int)*n);
 	   for(i=0;i<n;i++) invp[perm[i]]=i;
 
 	   if(dm->comm->myproc==0){for(i=0;i<n;i++) x[i]=xx[invp[i]];  } 
diff --git a/test-driver-ff b/test-driver-ff
index 6358d81..e025a4d 100755
--- a/test-driver-ff
+++ b/test-driver-ff
@@ -1,8 +1,8 @@
-#! /bin/sh
+#!/bin/sh
 # test-driver-ff from test-driver - basic testsuite driver script.
 # modif F. Hecht UPMC. 
 
-scriptversion=2013-05-31.20; # UTC
+scriptversion=2013-06-27.18; # UTC
 
 # Copyright (C) 2011-2013 Free Software Foundation, Inc.
 #
@@ -107,7 +107,7 @@ if test $enable_hard_errors = no && test $estatus -eq 99; then
 fi
 
 case $estatus:$expect_failure in
-  0:yes) col=$red res=XPASS recheck=yes gcopy=yes;;
+  0:yes) col=$grn res=PASS recheck=yes gcopy=yes;;
   0:*)   col=$grn res=PASS  recheck=no  gcopy=no;;
   77:*)  col=$blu res=SKIP  recheck=no  gcopy=yes;;
   99:*)  col=$mgn res=ERROR recheck=yes gcopy=yes;;

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



More information about the debian-science-commits mailing list