diff --git a/Solver/elasticitySolver.cpp b/Solver/elasticitySolver.cpp
index eec404cde3ac0a82aebb9fbd2260110db5fef0e4..35a5c62715a1ebd8e9f0a317e93e4ceb70eda321 100644
--- a/Solver/elasticitySolver.cpp
+++ b/Solver/elasticitySolver.cpp
@@ -14,9 +14,7 @@
 #include "linearSystemGMM.h"
 #include "Numeric.h"
 #include "functionSpace.h"
-#ifdef THIS_FILE_IS_MISSING
 #include "terms.h"
-#endif
 
 #if defined(HAVE_POST)
 #include "PView.h"
@@ -324,6 +322,7 @@ void elasticitySolver::solve()
 
   // solving
   lsys->systemSolve();
+  printf("-- done solving!\n");
 }
 
 
@@ -444,6 +443,7 @@ void MyelasticitySolver::solve()
     }
   }
 
+/*
   // assembling the stifness matrix
   for (unsigned int i = 0; i < elasticFields.size(); i++){
     SElement::setShapeEnrichement(elasticFields[i]._enrichment);
@@ -455,22 +455,15 @@ void MyelasticitySolver::solve()
       El.addToMatrix(*pAssembler, *elasticFields[i].g, *elasticFields[j].g);      
     }
   }
+*/
 
-/*  VectorLagrangeFunctionSpace L1(Dof::createTypeWithTwoInts(0,_tag),VectorLagrangeFunctionSpace::VECTOR_X);
-  VectorLagrangeFunctionSpace L2(Dof::createTypeWithTwoInts(1,_tag),VectorLagrangeFunctionSpace::VECTOR_Y);
-  VectorLagrangeFunctionSpace L3(Dof::createTypeWithTwoInts(2,_tag),VectorLagrangeFunctionSpace::VECTOR_Z);
-  CompositeFunctionSpace<VectorLagrangeFunctionSpace::ValType> P123(L1,L2,L3);*/
-  VectorLagrangeFunctionSpace P123(_tag,VectorLagrangeFunctionSpace::VECTOR_X,VectorLagrangeFunctionSpace::VECTOR_Y);
+  VectorLagrangeFunctionSpace P123(_tag);//,VectorLagrangeFunctionSpace::VECTOR_X,VectorLagrangeFunctionSpace::VECTOR_Y);
 
   for (unsigned int i = 0; i < elasticFields.size(); i++)
   {
-    DummyfemTerm El(pModel);
-//    ElasticTerm<CompositeFunctionSpace<VectorLagrangeFunctionSpace::ValType>,CompositeFunctionSpace<VectorLagrangeFunctionSpace::ValType> > Eterm(P123,elasticFields[i]._E,elasticFields[i]._nu);
-throw;
-#ifdef DEBUG_ME_ELASTIC_TERM_IS_NOT_DEFINE_IT_IS_PROBABLY_IN_TERM_H_BUT_THIS_FILE_IS_NOT_IN_THE_SVN
     ElasticTerm<VectorLagrangeFunctionSpace,VectorLagrangeFunctionSpace> Eterm(P123,elasticFields[i]._E,elasticFields[i]._nu);
-    fullMatrix<double> localMatrix(12,12);
-    std::vector<Dof> R;R.reserve(100);
+    fullMatrix<double> localMatrix;
+    std::vector<Dof> R;
     for ( groupOfElements::elementContainer::const_iterator it = elasticFields[i].g->begin(); it != elasticFields[i].g->end() ; ++it)
     {
       MElement *e = *it;
@@ -480,19 +473,11 @@ throw;
       IntPt *GP;
       e->getIntegrationPoints(integrationOrder, &npts, &GP);
       Eterm.get(e,npts,GP,localMatrix);
-      El.addToMatrix(*pAssembler,localMatrix,R);
+      P123.getKeys(e,R);
+      pAssembler->assemble(R, localMatrix);
     }
-#endif
   }
-
   printf("-- done assembling!\n");
-  //  for (int i=0;i<pAssembler->sizeOfR();i++){
-    //    printf("%g ",lsys->getFromRightHandSide(i));
-  //  }
-  //  printf("\n");
-
-  // solving
   lsys->systemSolve();
+  printf("-- done solving!\n");
 }
-
-
diff --git a/Solver/elasticityTerm.cpp b/Solver/elasticityTerm.cpp
index 7fd8bbec30707dd574b744fcd6b3c47c64137f2a..e60656d05707d30dcebe3e5694263a36322e68ac 100644
--- a/Solver/elasticityTerm.cpp
+++ b/Solver/elasticityTerm.cpp
@@ -59,19 +59,20 @@ void elasticityTerm::elementMatrix(SElement *se, fullMatrix<double> &m) const
     if (se->getShapeEnrichement() == se->getTestEnrichement()){
       for (int j = 0; j < nbNodes; j++){
 
-        //printf(" GR(j) = %12.5E,%12.5E,%12.5E\n", Grads[j][0],Grads[j][1],Grads[j][2]);
+//        printf(" GR(j) = %12.5E,%12.5E,%12.5E\n", Grads[j][0],Grads[j][1],Grads[j][2]);
 
         BT(j, 0) = B(0, j) = Grads[j][0];
         BT(j, 3) = B(3, j) = Grads[j][1];
-        BT(j, 4) = B(4, j) = Grads[j][2];
+        BT(j, 5) = B(5, j) = Grads[j][2];
 
         BT(j + nbNodes, 1) = B(1, j + nbNodes) = Grads[j][1];
         BT(j + nbNodes, 3) = B(3, j + nbNodes) = Grads[j][0];
-        BT(j + nbNodes, 5) = B(5, j + nbNodes) = Grads[j][2];
+        BT(j + nbNodes, 4) = B(4, j + nbNodes) = Grads[j][2];
 
         BT(j + 2 * nbNodes, 2) = B(2, j + 2 * nbNodes) = Grads[j][2];
-        BT(j + 2 * nbNodes, 4) = B(4, j + 2 * nbNodes) = Grads[j][0];
-        BT(j + 2 * nbNodes, 5) = B(5, j + 2 * nbNodes) = Grads[j][1];
+        BT(j + 2 * nbNodes, 4) = B(4, j + 2 * nbNodes) = Grads[j][1];
+        BT(j + 2 * nbNodes, 5) = B(5, j + 2 * nbNodes) = Grads[j][0];
+        
       }
     }
     else{
@@ -80,15 +81,15 @@ void elasticityTerm::elementMatrix(SElement *se, fullMatrix<double> &m) const
       for (int j = 0; j < nbNodes; j++){
         BT(j, 0) = Grads[j][0]; B(0, j) = GradsT[j][0];
         BT(j, 3) = Grads[j][1]; B(3, j) = GradsT[j][1];
-        BT(j, 4) = Grads[j][2]; B(4, j) = GradsT[j][2];
+        BT(j, 5) = Grads[j][2]; B(5, j) = GradsT[j][2];
 
         BT(j + nbNodes, 1) = Grads[j][1]; B(1, j + nbNodes) = GradsT[j][1];
         BT(j + nbNodes, 3) = Grads[j][0]; B(3, j + nbNodes) = GradsT[j][0];
-        BT(j + nbNodes, 5) = Grads[j][2]; B(5, j + nbNodes) = GradsT[j][2];
+        BT(j + nbNodes, 4) = Grads[j][2]; B(4, j + nbNodes) = GradsT[j][2];
 
         BT(j + 2 * nbNodes, 2) = Grads[j][2]; B(2, j + 2 * nbNodes) = GradsT[j][2];
-        BT(j + 2 * nbNodes, 4) = Grads[j][0]; B(4, j + 2 * nbNodes) = GradsT[j][0];
-        BT(j + 2 * nbNodes, 5) = Grads[j][1]; B(5, j + 2 * nbNodes) = GradsT[j][1];
+        BT(j + 2 * nbNodes, 4) = Grads[j][1]; B(4, j + 2 * nbNodes) = GradsT[j][1];
+        BT(j + 2 * nbNodes, 5) = Grads[j][0]; B(5, j + 2 * nbNodes) = GradsT[j][0];
       }
     }
 
@@ -97,14 +98,6 @@ void elasticityTerm::elementMatrix(SElement *se, fullMatrix<double> &m) const
     m.gemm(BTH, B, weight * detJ, 1.);
   }
   return;
-  for (int i = 0; i < 3 * nbNodes; i++){
-    for (int j = 0; j < 3 * nbNodes; j++){
-      printf("%g ", m(i, j));
-    }
-    printf("\n");
-  }
-    printf("\n");
-    printf("\n");
 }
 
 void elasticityTerm::elementVector(SElement *se, fullVector<double> &m) const
diff --git a/Solver/femTerm.h b/Solver/femTerm.h
index ee759aa75ca90841282cabba8f773b8baff34700..5a16cac81c8059091f52f9eac1c9d860a14d610c 100644
--- a/Solver/femTerm.h
+++ b/Solver/femTerm.h
@@ -101,22 +101,12 @@ class femTerm {
       for (int k = 0; k < nbC; k++)
         C.push_back(getLocalDofC(se, k));
     }
-/*     for (int i = 0; i < nbC; i++) */
-/*       for (int j = 0; j < nbR; j++) */
-/* 	dm.assemble(getLocalDofR(se, i), getLocalDofC(se, j), localMatrix(i,j)); */
-/*     return; */
-    
-    
-//    if (nbR == nbC){
-//      for (int i=0;i<nbR;i++)
-//	if (!(C[i] == R[i]))sym = false;
-//    }
-//    else sym = false;
     if (!sym)
       dm.assemble(R, C, localMatrix);
     else
       dm.assemble(R, localMatrix);
   }
+
   void dirichletNodalBC(int physical, int dim, int comp, int field,
                         const simpleFunction<dataVec> &e,
                         dofManager<dataVec> &dm)
@@ -127,6 +117,7 @@ class femTerm {
     for (unsigned int i = 0; i < v.size(); i++)
       dm.fixVertex(v[i], comp, field, e(v[i]->x(), v[i]->y(), v[i]->z()));
   }
+
   void neumannNodalBC(int physical, int dim, int comp, int field,
                       const simpleFunction<dataVec> &fct,
                       dofManager<dataVec> &dm)
@@ -195,22 +186,6 @@ class DummyfemTerm : public femTerm<double>
   virtual Dof getLocalDofC(SElement *se, int iCol) const {return Dof(0,0);}
   virtual void elementMatrix(SElement *se, fullMatrix<dataMat> &m) const {m.scale(0.);}
   virtual void elementVector(SElement *se, fullVector<dataVec> &m) const {m.scale(0.);}
- public:
-  void addToMatrix(dofManager<dataVec> &dm,
-                   fullMatrix<dataMat> &localMatrix,
-                   std::vector<Dof> R,std::vector<Dof> C) const
-  {
-      dm.assemble(R, C, localMatrix);
-  }
-
-
-  void addToMatrix(dofManager<dataVec> &dm,
-                   fullMatrix<dataMat> &localMatrix,
-                   std::vector<Dof> R) const // symmetric version.
-  {
-      dm.assemble(R, localMatrix);
-  }
-
 };
 
 
diff --git a/Solver/functionSpace.h b/Solver/functionSpace.h
index 3a540f69ec38f24062ee27220896ca1aac28585b..0130c38804694d1f607680646ec7e4302d358556 100644
--- a/Solver/functionSpace.h
+++ b/Solver/functionSpace.h
@@ -5,11 +5,11 @@
 #include "STensor3.h"
 #include <vector>
 #include <iterator>
+#include <iostream>
 #include "Numeric.h"
 #include "MElement.h"
 #include "dofManager.h"
 
-//class STensor3{};
 class SVoid{};
 
 class basisFunction{
@@ -79,7 +79,6 @@ class FunctionSpace {
   virtual int divf(MElement *ele, double u, double v, double w,std::vector<DivType> &divs);
   virtual int curlf(MElement *ele, double u, double v, double w,std::vector<CurlType> &curls);*/
   virtual int getNumKeys(MElement *ele)=0; // if one needs the number of dofs
-  virtual int getKeys(MElement *ele, Dof *keys)=0; // may be faster once the number of dofs is known
   virtual int getKeys(MElement *ele, std::vector<Dof> &keys)=0; 
 };
 
@@ -97,8 +96,6 @@ class ScalarLagrangeFunctionSpace : public FunctionSpace<double>
 
   Dof getLocalDof(MElement *ele, int i) const
   {
-//    int iComp = i / ele->getNumVertices();
-//    int ithLocalVertex = i % ele->getNumVertices();
     return Dof(ele->getVertex(i)->getNum(), _iField);
   }
 
@@ -109,18 +106,18 @@ class ScalarLagrangeFunctionSpace : public FunctionSpace<double>
   {
     int ndofs= ele->getNumVertices();
     int curpos=vals.size();
-    vals.resize(curpos+ndofs);
+    vals.reserve(curpos+ndofs);
     ele->getShapeFunctions(u, v, w, &(vals[curpos]));
   }; 
   virtual int gradf(MElement *ele, double u, double v, double w,std::vector<GradType> &grads)
   {
     int ndofs= ele->getNumVertices();
-//    grads.reserve(grads.size()+ndofs);
+    grads.reserve(grads.size()+ndofs);
     double gradsuvw[256][3];
     ele->getGradShapeFunctions(u, v, w, gradsuvw);
     double jac[3][3];
     double invjac[3][3];
-    const double detJ = ele->getJacobian(u, v, w, jac); // a faire une fois pour toute ??
+    const double detJ = ele->getJacobian(u, v, w, jac); // redondant : on fait cet appel a l'exterieur
     inv3x3(jac, invjac);
     for (int i=0;i<ndofs;++i)
       grads.push_back(GradType(
@@ -130,61 +127,16 @@ class ScalarLagrangeFunctionSpace : public FunctionSpace<double>
                             ));
   };
   virtual int getNumKeys(MElement *ele) {return ele->getNumVertices();}
-  virtual int getKeys(MElement *ele, Dof *keys)
-  {
-      int ndofs= ele->getNumVertices();
-      for (int i=0;i<ndofs;++i)
-        keys[i]=getLocalDof(ele,i);
-  }
+
   virtual int getKeys(MElement *ele, std::vector<Dof> &keys) // appends ...
   {
       int ndofs= ele->getNumVertices();
-//      keys.reserve(keys.size()+ndofs);
+      keys.reserve(keys.size()+ndofs);
       for (int i=0;i<ndofs;++i)
         keys.push_back(getLocalDof(ele,i));
   }
 };
 
-/*
-template <class T> class ScalarToAnyFunctionSpace : public FunctionSpace<T> // scalarFS * const vector (avec vecteur non const, peut etre utilise pour xfem directement
-{
-public :
-  typedef typename TensorialTraits<T>::ValType ValType;
-  typedef typename TensorialTraits<T>::GradType GradType;
-  typedef typename TensorialTraits<T>::HessType HessType;
-  typedef typename TensorialTraits<T>::DivType DivType;
-  typedef typename TensorialTraits<T>::CurlType CurlType;
-protected :
-  T multiplier;
-  FunctionSpace<double> *ScalarFS;
-public : 
-  template <class T2> ScalarToAnyFunctionSpace(const T2 &SFS, const T& mult): multiplier(mult),ScalarFS(new T2(SFS)) {}
-  virtual ~ScalarToAnyFunctionSpace() {delete ScalarFS;}
-  virtual int f(MElement *ele, double u, double v, double w, std::vector<ValType> &vals)
-  {
-    std::vector<double> valsd;
-    ScalarFS->f(ele,u,v,w,valsd);
-    int nbdofs=valsd.size();
-    for (int i=0;i<nbdofs;++i) vals.push_back(multiplier*valsd[i]);
-  }
-  
-  virtual int gradf(MElement *ele, double u, double v, double w,std::vector<GradType> &grads)
-  {
-    std::vector<SVector3> gradsd;
-    ScalarFS->gradf(ele,u,v,w,gradsd);
-    int nbdofs=gradsd.size();
-    GradType val;
-    for (int i=0;i<nbdofs;++i)
-    {
-      tensprod(multiplier,gradsd[i],val);
-      grads.push_back(val);
-    }
-  };
-  virtual int getNumKeys(MElement *ele) {return ScalarFS->getNumKeys(ele);}
-  virtual int getKeys(MElement *ele, Dof *keys){ ScalarFS->getKeys(ele,keys);}
-  virtual int getKeys(MElement *ele, std::vector<Dof> &keys) {ScalarFS->getKeys(ele,keys);}
-};
-*/
 
 template <class T> class ScalarToAnyFunctionSpace : public FunctionSpace<T>
 {
@@ -224,6 +176,8 @@ public :
     ScalarFS->f(ele,u,v,w,valsd);
     int nbdofs=valsd.size();
     int nbcomp=comp.size();
+    int curpos=vals.size();
+    vals.reserve(curpos+nbcomp*nbdofs);
     for (int j=0;j<nbcomp;++j)
     {
       for (int i=0;i<nbdofs;++i) vals.push_back(multipliers[j]*valsd[i]);
@@ -236,6 +190,8 @@ public :
     ScalarFS->gradf(ele,u,v,w,gradsd);
     int nbdofs=gradsd.size();
     int nbcomp=comp.size();
+    int curpos=grads.size();
+    grads.reserve(curpos+nbcomp*nbdofs);
     GradType val;
     for (int j=0;j<nbcomp;++j)
     {
@@ -245,47 +201,28 @@ public :
         grads.push_back(val);
       }
     }
-  };
-  virtual int getNumKeys(MElement *ele) {return ScalarFS->getNumKeys(ele)*comp.size();}
-  virtual int getKeys(MElement *ele, Dof *keys)
-  { 
-    int nbcomp=comp.size();
-    int nk=ScalarFS->getNumKeys(ele);
-    Dof *kptr=keys;
-    ScalarFS->getKeys(ele,kptr);
-    kptr+=nk;
-    for (int j=1;j<nbcomp;++j)
-    {
-      for (int i=0;i<nk;++i)
-        kptr[i]=kptr[i-nk];
-      kptr+=nk;
-    }
-    kptr=keys;
-    for (int j=0;j<nbcomp;++j)
-    {
-      for (int i=0;i<nk;++i)
-      {
-        int i1,i2;
-        Dof::getTwoIntsFromType(kptr[i].getType(), i1,i2);
-        kptr[i]=Dof(kptr[i].getEntity(),Dof::createTypeWithTwoInts(comp[j],i2));
-      }
-      kptr+=nk;
-    }
   }
+  
+  virtual int getNumKeys(MElement *ele) {return ScalarFS->getNumKeys(ele)*comp.size();}
+  
   virtual int getKeys(MElement *ele, std::vector<Dof> &keys)
   {
+
     int nk=ScalarFS->getNumKeys(ele);
     std::vector<Dof> bufk;
     bufk.reserve(nk);
     ScalarFS->getKeys(ele,bufk);
+    int nbdofs=bufk.size();
     int nbcomp=comp.size();
+    int curpos=keys.size();
+    keys.reserve(curpos+nbcomp*nbdofs);
     for (int j=0;j<nbcomp;++j)
     {
       for (int i=0;i<nk;++i)
       {
         int i1,i2;
         Dof::getTwoIntsFromType(bufk[i].getType(), i1,i2);
-        keys.push_back(Dof(bufk[i].getEntity(),Dof::createTypeWithTwoInts(comp[j],i2)));
+        keys.push_back(Dof(bufk[i].getEntity(),Dof::createTypeWithTwoInts(comp[j],i1)));
       }
     }
   }
@@ -316,7 +253,7 @@ class VectorLagrangeFunctionSpace : public ScalarToAnyFunctionSpace<SVector3>
   {}
   VectorLagrangeFunctionSpace(int id,Along comp1,Along comp2, Along comp3) :
           ScalarToAnyFunctionSpace<SVector3>::ScalarToAnyFunctionSpace(ScalarLagrangeFunctionSpace(id),
-          BasisVectors[comp1],comp3, BasisVectors[comp2],comp2, BasisVectors[comp3],comp3)
+          BasisVectors[comp1],comp1, BasisVectors[comp2],comp2, BasisVectors[comp3],comp3)
   {}
 };
 
@@ -406,10 +343,9 @@ class xFemFunctionSpace : public FunctionSpace<T>
   FunctionSpace<T>* _spacebase;
 //  Function<double>* enrichment;
  public:
-  ValType f(MElement *ele, double u, double v, double w);
-  GradType gradf(MElement *ele, double u, double v, double w);
+  virtual int f(MElement *ele, double u, double v, double w,std::vector<ValType> &vals);
+  virtual int gradf(MElement *ele, double u, double v, double w,std::vector<GradType> &grads);
   int getNumKeys(MElement *ele);
-  void getKeys(MElement *ele, Dof *keys);
   void getKeys(MElement *ele, std::vector<Dof> &keys);
 };
 
@@ -427,10 +363,9 @@ class FilteredFunctionSpace : public FunctionSpace<T>
   F &_filter;
   
  public:
-  ValType f(MElement *ele, double u, double v, double w);
-  GradType gradf(MElement *ele, double u, double v, double w);
+  virtual int f(MElement *ele, double u, double v, double w,std::vector<ValType> &vals);
+  virtual int gradf(MElement *ele, double u, double v, double w,std::vector<GradType> &grads);
   int getNumKeys(MElement *ele);
-  void getKeys(MElement *ele, Dof *keys);
   void getKeys(MElement *ele, std::vector<Dof> &keys);
 };
 
diff --git a/Solver/terms.h b/Solver/terms.h
new file mode 100644
index 0000000000000000000000000000000000000000..df76f2987d57c76aa361ba5060c9b01b056b02d4
--- /dev/null
+++ b/Solver/terms.h
@@ -0,0 +1,227 @@
+//
+// C++ Interface: terms
+//
+// Description: 
+//
+//
+// Author:  <Eric Bechet>, (C) 2009
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+
+#ifndef _TERMS_H_
+#define _TERMS_H_
+
+#include "SVector3.h"
+#include <vector>
+#include <iterator>
+#include "Numeric.h"
+#include "functionSpace.h"
+
+
+// evaluation of a field ???
+template<class T>
+class Field {
+ protected:
+  typedef typename TensorialTraits<T>::ValType ValType;
+  typedef typename TensorialTraits<T>::GradType GradType;
+  dofManager<double> *dm; // 
+/*  typedef typename TensorialTraits<T>::HessType HessType;
+  typedef typename TensorialTraits<T>::DivType DivType;
+  typedef typename TensorialTraits<T>::CurlType CurlType;*/
+ 
+ public:
+  virtual int f(MElement *ele, double u, double v, double w, ValType &val)=0;
+  virtual int gradf(MElement *ele, double u, double v, double w,GradType &grad)=0;
+//  virtual int gradf(MElement *ele, double u, double v, double w,std::vector<GradType> &grads, STensor3 &invjac)=0;// on passe le jacobien que l'on veut ...
+/* virtual int hessf(MElement *ele, double u, double v, double w,std::vector<HessType> &hesss);
+  virtual int divf(MElement *ele, double u, double v, double w,std::vector<DivType> &divs);
+  virtual int curlf(MElement *ele, double u, double v, double w,std::vector<CurlType> &curls);*/
+  virtual int getNumKeys(MElement *ele)=0; // if one needs the number of dofs
+  virtual int getKeys(MElement *ele, Dof *keys)=0; // may be faster once the number of dofs is known
+  virtual int getKeys(MElement *ele, std::vector<Dof> &keys)=0; 
+};
+
+
+
+
+
+
+class Formulation
+{
+  std::vector<FunctionSpace<double>* > scalarfs;
+  std::vector<FunctionSpace<SVector3>* > vectorfs;
+  std::vector<groupOfElements* > groups;
+  std::vector<std::pair<MElement*,std::vector<groupOfElements&> > > links;
+  dofManager<double> *dm; // 
+
+};
+
+class  BilinearTermBase
+{
+ public :  
+  virtual void get(MElement *ele,int npts,IntPt *GP,fullMatrix<double> &m) =0;
+};
+
+template<class S1,class S2> class BilinearTerm : public BilinearTermBase
+{
+ protected :
+  S1& space1;
+  S2& space2;
+ public :
+  BilinearTerm(S1& space1_,S2& space2_) : space1(space1_),space2(space2_) {}
+  virtual void get(MElement *ele,int npts,IntPt *GP,fullMatrix<double> &m) =0;
+};
+
+class  LinearTermBase
+{
+  virtual void get(MElement *ele,int npts,IntPt *GP,fullVector<double> &v) =0;
+};
+
+template<class S1> class LinearTerm : public LinearTermBase
+{
+ public : 
+  virtual void get(MElement *ele,int npts,IntPt *GP,fullMatrix<double> &m) =0;
+};
+
+class  ScalarTermBase
+{
+ public : 
+  virtual void get(MElement *ele,int npts,IntPt *GP,double &v) =0;
+};
+
+class ScalarTerm : public ScalarTermBase
+{
+ public : 
+  virtual void get(MElement *ele,int npts,IntPt *GP,double &v) =0;
+};
+
+
+
+template<class S1,class S2> class ElasticTerm : public BilinearTerm<S1,S2> // non symmetric 
+{
+ protected : 
+  double E,nu;
+  fullMatrix<double> H;/* =
+    { {C11, C12, C12,    0,   0,   0},
+      {C12, C11, C12,    0,   0,   0},
+      {C12, C12, C11,    0,   0,   0},
+      {  0,   0,   0,  C44,   0,   0},
+      {  0,   0,   0,    0, C44,   0},
+      {  0,   0,   0,    0,   0, C44} };*/
+
+ public : 
+  ElasticTerm(S1& space1_,S2& space2_,double E_,double nu_) : BilinearTerm<S1,S2>(space1_,space2_),E(E_),nu(nu_),H(6,6)
+  {
+    double FACT = E / (1 + nu);
+    double C11 = FACT * (1 - nu) / (1 - 2 * nu);
+    double C12 = FACT * nu / (1 - 2 * nu);
+    double C44 = (C11 - C12) / 2;
+    H.scale(0.);
+    for (int i=0;i<3;++i) {H(i,i)=C11;H(i+3,i+3)=C44;}
+    H(1,0)=H(0,1)=H(2,0)=H(0,2)=H(1,2)=H(2,1)=C12;
+  }
+  virtual void get(MElement *ele,int npts,IntPt *GP,fullMatrix<double> &m)
+  {
+    int nbFF1 = BilinearTerm<S1,S2>::space1.getNumKeys(ele);
+    int nbFF2 = BilinearTerm<S1,S2>::space2.getNumKeys(ele);
+    double jac[3][3];
+    fullMatrix<double> B(6, nbFF2);
+    fullMatrix<double> BTH(nbFF2, 6);
+    fullMatrix<double> BT(nbFF1, 6);
+    m.resize(nbFF1, nbFF2);
+    m.setAll(0.);
+    for (int i = 0; i < npts; i++)
+    {
+      const double u = GP[i].pt[0]; const double v = GP[i].pt[1]; const double w = GP[i].pt[2];
+      const double weight = GP[i].weight; const double detJ = ele->getJacobian(u, v, w, jac);
+      std::vector<typename S1::GradType> Grads;// tableau de matrices...
+      std::vector<typename S2::GradType> GradsT;// tableau de matrices...
+      BilinearTerm<S1,S2>::space1.gradf(ele,u, v, w, Grads);
+      BilinearTerm<S1,S2>::space2.gradf(ele,u, v, w, GradsT);
+      for (int j = 0; j < nbFF1; j++)
+      {
+        BT(j, 0) = Grads[j](0,0);
+        BT(j, 1) = Grads[j](1,1);
+        BT(j, 2) = Grads[j](2,2);
+        BT(j, 3) = Grads[j](0,1)+Grads[j](1,0);
+        BT(j, 4) = Grads[j](1,2)+Grads[j](2,1);
+        BT(j, 5) = Grads[j](0,2)+Grads[j](2,0);
+      }
+      for (int j = 0; j < nbFF2; j++)
+      {
+        B(0, j) = GradsT[j](0,0);
+        B(1, j) = GradsT[j](1,1);
+        B(2, j) = GradsT[j](2,2);
+        B(3, j) = GradsT[j](0,1)+GradsT[j](1,0);
+        B(4, j) = GradsT[j](1,2)+GradsT[j](2,1);
+        B(5, j) = GradsT[j](0,2)+GradsT[j](2,0);
+      }
+      BTH.setAll(0.);
+      BTH.gemm(BT, H);
+      m.gemm(BTH, B, weight * detJ, 1.);
+    }
+  }
+}; // class
+
+
+
+template<class S1> class ElasticTerm<S1,S1> : public BilinearTerm<S1,S1> // symmetric
+{
+ protected : 
+  double E,nu;
+  fullMatrix<double> H;/* =
+    { {C11, C12, C12,    0,   0,   0},
+      {C12, C11, C12,    0,   0,   0},
+      {C12, C12, C11,    0,   0,   0},
+      {  0,   0,   0,  C44,   0,   0},
+      {  0,   0,   0,    0, C44,   0},
+      {  0,   0,   0,    0,   0, C44} };*/
+
+ public : 
+  ElasticTerm(S1& space1_,double E_,double nu_) : BilinearTerm<S1,S1>(space1_,space1_),E(E_),nu(nu_),H(6,6)
+  {
+    double FACT = E / (1 + nu);
+    double C11 = FACT * (1 - nu) / (1 - 2 * nu);
+    double C12 = FACT * nu / (1 - 2 * nu);
+    double C44 = (C11 - C12) / 2;
+    H.scale(0.);
+    for (int i=0;i<3;++i) {H(i,i)=C11;H(i+3,i+3)=C44;}
+    H(1,0)=H(0,1)=H(2,0)=H(0,2)=H(1,2)=H(2,1)=C12;
+  }
+  
+  virtual void get(MElement *ele,int npts,IntPt *GP,fullMatrix<double> &m)
+  {
+    int nbFF = BilinearTerm<S1,S1>::space1.getNumKeys(ele);
+    double jac[3][3];
+    fullMatrix<double> B(6, nbFF);
+    fullMatrix<double> BTH(nbFF, 6);
+    fullMatrix<double> BT(nbFF, 6);
+    m.resize(nbFF, nbFF);
+    m.setAll(0.);
+    for (int i = 0; i < npts; i++)
+    {
+      const double u = GP[i].pt[0]; const double v = GP[i].pt[1]; const double w = GP[i].pt[2];
+      const double weight = GP[i].weight; const double detJ = ele->getJacobian(u, v, w, jac);
+      std::vector<typename S1::GradType> Grads;
+      BilinearTerm<S1,S1>::space1.gradf(ele,u, v, w, Grads); // a optimiser ??
+      for (int j = 0; j < nbFF; j++)
+      {
+        BT(j, 0) = B(0, j) = Grads[j](0,0);
+        BT(j, 1) = B(1, j) = Grads[j](1,1);
+        BT(j, 2) = B(2, j) = Grads[j](2,2);
+        BT(j, 3) = B(3, j) = Grads[j](0,1)+Grads[j](1,0);
+        BT(j, 4) = B(4, j) = Grads[j](1,2)+Grads[j](2,1);
+        BT(j, 5) = B(5, j) = Grads[j](0,2)+Grads[j](2,0);
+      }
+      BTH.setAll(0.);
+      BTH.gemm(BT, H);
+      m.gemm(BTH, B, weight * detJ, 1.);
+    }
+  }
+}; // class
+
+
+#endif// _TERMS_H_