diff --git a/contrib/arc/highlevel.h b/contrib/arc/highlevel.h
index 8ed6d0ab493de289190a13368d91a1b63af9c6a0..70a497433d43967699f0320e6dfec8fa9ade87a2 100644
--- a/contrib/arc/highlevel.h
+++ b/contrib/arc/highlevel.h
@@ -15,10 +15,12 @@
 #include <vector>
 #include <complex>
 #include <iostream>
+//#include <tr1/memory>
 
 #include "dofManager.h"
 #include "SVector3.h"
 #include "MElement.h"
+#include "MVertex.h"
 
 
 
@@ -31,7 +33,7 @@ template<class T> struct TensorialTraits
   typedef T ValType;
   typedef T GradType[3];
   typedef T HessType[3][3];
-  static const int nb_basis_vectors=1; // par défaut considéré comme un scalaire
+  static const int nb_basis_vectors=1; // par défaut, considéré comme un scalaire
 };
 
 template<> struct TensorialTraits<double>
@@ -56,13 +58,31 @@ template<class T> class Function  // Fonction au sens EF du terme.
                 // renvoie valeur , gradient, hessien, etc...pour un element donné et un point donné
 {
 public:
-  virtual ~Function(){}
-  virtual void GetVal (double uvw[],MElement *e, T& Val)const{};// =0;
-  virtual void GetGrad(double uvw[],MElement *e,typename TensorialTraits<T>::GradType &Grad) const {};//=0;
-  virtual void GetHess(double uvw[],MElement *e,typename TensorialTraits<T>::HessType &Hess)const {};//=0;
+// typedef std::tr1::shared_ptr<Function<T> > FunctionPtr;
+   virtual ~Function(){}
+  virtual void GetVal (double uvw[],MElement *e, T& Val)const=0;
+  virtual void GetGrad(double uvw[],MElement *e,typename TensorialTraits<T>::GradType &Grad) const =0;
+  virtual void GetHess(double uvw[],MElement *e,typename TensorialTraits<T>::HessType &Hess)const =0;
 };
 
-class SpaceBase // renvoie des clefs de dofs
+
+class LagrangeShapeFunction: public Function<double>
+{
+  public:
+  virtual void GetVal(double uvw[],MElement *e, double& Val)
+  {
+//    double s[100];
+//    _e->getShapeFunctions(uvw[0], uvw[1], uvw[2], s);
+
+  }
+};
+
+
+
+
+
+
+class SpaceBase // renvoie des clefs des dofs
 {
 public:
   virtual void getDofs(MElement *e,std::vector<Dof> &vecD)=0;
@@ -73,8 +93,8 @@ template<class T> class Space : public SpaceBase // renvoie des clefs de dofs et
 public: 
   Space(){};
   virtual ~Space(){};
-  virtual void getDofsandSFs(MElement *e,std::vector<std::pair< Dof, Function<T>* > > &vecDFF) {}
-  virtual void getSFs(std::vector<std::pair< Dof, Function<T>* > > &vecDFF){};//=0;
+  virtual void getDofsandSFs(MElement *e,std::vector<std::pair< Dof, Function<T>* > > &vecDFF)=0;
+  virtual void getSFs(std::vector<std::pair< Dof, Function<T>* > > &vecDFF)=0;
 };
 
 
@@ -94,7 +114,10 @@ public:
   SpaceLagrange(int iField):_iField(iField){};
   virtual ~SpaceLagrange(){};
   virtual void getDofsandSFs(MElement *e,std::vector<std::pair< Dof, Function<T>* > > &vecDFF){}
-  virtual void getSFs(std::vector<std::pair< Dof, Function<T>* > > &vecDFF){};//=0;
+  virtual void getSFs(std::vector<std::pair< Dof, Function<T>* > > &vecDFF)
+  {
+    
+  };
   virtual void getDofs(MElement *e,std::vector<Dof> &vecD)
   {
     int ndofs= e->getNumVertices()*TensorialTraits<T>::nb_basis_vectors;
@@ -104,49 +127,36 @@ public:
 };
 
 
-template<class T> class Field : public Function<T> // renvoie des valeurs de champ (ff*valeurs dofs), gradient , etc...
+template<class T> class SpaceXfem : public Space<T> //  approximation xfem (spacebase + enrich)
 {
+  int _iEnrich;
+  Space<T> &_SpaceBase;
+  Function<double> &enrich;
+  std::unary_function<MVertex*,bool> &test;
+  Dof getLocalDof(MElement *e, int i) const
+  {
+    int iComp = i / e->getNumVertices();
+    int ithLocalVertex = i % e->getNumVertices();
+    MVertex * v= e->getVertex(ithLocalVertex);
+    if (test(v))
+      return Dof(e->getVertex(ithLocalVertex)->getNum(),
+                Dof::createTypeWithTwoInts(iComp, _iEnrich));
+  } 
 public: 
-  Field(){};
-  virtual ~Field(){};
-};
-
-template<class T1,class T2> class TermBilinear  // terme associe a un "element" / pt de gauss (contribution élémentaire)
-            // typiquement celui ci stoque ce qui doit etre stocke. C'est la base configurable du code
-            // on doit associer cela a un allocateur qui renvoie un pointeur sur ce truc 
-            // Soit tous les elements/pts de gauss ont le meme terme , allocateur unique (pas de stockage aux pts de
-            // gauss par exemple
-            // soit ils ont qqc a stockuer et sont tous distincts
-            // on peut utiliser des membres statiques pour ce qui est constant pour tous les instances
-{
-public:
-  typedef void Stype;
-//  TermBilinear(){};
-  virtual double getTerm(double uvw[],MElement &e,Function<T1> &SF,Function<T2> &TF,Stype* info) {};
-  virtual void Update(double uvw[],MElement &e,Function<T1> &SF,Function<T2> &TF) {};
-// toute fonctios utiles . prevoir un algorithme  ad hoc pour l'appliquer sur ts les pts de gauss ...
-};
-
-
-class TermBilinearMeca : public TermBilinear<double,double>
-{
-public:
-//  typedef Tensor Stype;
-//  TermBilinear(){};
-//  virtual double getTerm(double uvw[],MElement &e,Function<double> &SF,Function<double> &TF,Stype* info) {};
-//  virtual void Update(double uvw[],MElement &e,Function<T1> &SF,Function<T2> &TF) {};
-// toute fonctios utiles . prevoir un algorithme 
+  SpaceXfem(int iEnrich,Space<T>& SpaceBase):_iEnrich(iEnrich), _SpaceBase(SpaceBase){};
+  virtual void getDofsandSFs(MElement *e,std::vector<std::pair< Dof, Function<T>* > > &vecDFF){}
+  virtual void getSFs(std::vector<std::pair< Dof, Function<T>* > > &vecDFF){};
+  virtual void getDofs(MElement *e,std::vector<Dof> &vecD)
+  {
+    _SpaceBase.getDofs(e,vecD);
+  }
 };
 
-
-class TermBilinearMecaNL : public TermBilinearMeca
+template<class T> class Field : public Function<T> // renvoie des valeurs de champ (ff*valeurs dofs), gradient , etc...
 {
-public:
-  typedef Tensor2 Stype;
-//  TermBilinear(){};
-//  virtual double getTerm(double uvw[],MElement &e,Function<double> &SF,Function<double> &TF,Stype* info) {};
-//  virtual void Update(double uvw[],MElement &e,Function<T1> &SF,Function<T2> &TF) {};
-// toute fonctios utiles . prevoir un algorithme 
+public: 
+  Field(){};
+  virtual ~Field(){};
 };
 
 
@@ -156,12 +166,15 @@ class FormBilinearBase
   public: 
   template <class T> void allocate(T *p) {p=new T[10];std::cout << "10" << std::endl;}
   template <class T> void get(T* tab, T *p, int ndx) {p=&tab[ndx];}
+  virtual void getDofs(MElement *e)=0;
+  virtual void getFuncs(MElement *e,const double uvw[3])=0;
+  virtual void getGradFuncs(MElement *e,const double uvw[3])=0;
 };
 
 template <> void FormBilinearBase::allocate(void *p) {p=NULL; std::cout << "null" << std::endl;}
 template <> void FormBilinearBase::get(void *tab,void *p, int ndx) {p=NULL;}
 
-template <class Term> class FormBilinear : public FormBilinearBase
+template <class Term,class SpaceL,class SpaceR> class FormBilinear : public FormBilinearBase
    // Renvoie des matrices élémentaires (ff) 
                   // Accessoirement stocke des pointeurs vers les termes pour chaque element
                   // Doit etre initialisée AVANT toute opération (pour l'allocation)
@@ -171,17 +184,49 @@ template <class Term> class FormBilinear : public FormBilinearBase
 {
 
   typedef typename Term::Stype Stype; // le truc a stocker
+  typedef typename Term::Datamat Datamat; // type elementaire
   Term instance; // une instance du terme. E.g. utile pour toute initialisation (calcul tenseur materiel, etc...)
   Stype *p;
   MElement *e;
   Function<double> *a;
   Function<double> *b;
   double uvw[3];
+  fullMatrix<Datamat> mat;
+  SpaceL *_spacel;
+  SpaceR *_spacer;
+  std::vector<Dof> Dofsl;
+  std::vector<Dof> Dofsr;
+  std::vector<Datamat> Funcl;
+  std::vector<Datamat> Funcr;
+
   public:
+  FormBilinear(SpaceL &sl,SpaceR &sr) {}
+  void getMatrix(fullMatrix<Datamat> *v) {v=&mat;}
   void func(void) { allocate(p);}
-  void func2(void) { instance.getTerm(uvw,*e,*a,*b,p); }
+  void func2(void) { }
+  void getDofs(MElement *e) 
+  {
+    _spacel->getDofs(e,Dofsl);
+    _spacer->getDofs(e,Dofsr);
+  };
+  void getFuncs(MElement *e,const double uvw[3]) {};
+  void getGradFuncs(MElement *e,const double uvw[3]) {};
+  void Init(MElement *e) { getDofs(e);} // called once for each element
+  void Accumulate(MElement *e,const double uvw[3]) // called for every GP
+  {
+//    for (int i)
+//      for (int j) 
+//        mat(i,j)+=instance.getTerm(uvw,*e,*a,*b,NULL,this);
+    instance.Init(e,this); // called once for each GP 
+    if (instance.NeedFuncs()) getFuncs(e,uvw);
+    if (instance.NeedGradFuncs()) getGradFuncs(e,uvw);
+    Datamat result;
+    instance.getTerm(uvw,e,NULL,*a,*b,result); // called for every SF combination (times every GP, times every element)
+  }
 };
 
+//template <class Term,class SpaceL,class datamat=double> class FormBilinear<Term,SpaceL,SpaceR> : public FormBilinearBase {}; cas symétrique
+
 
 class FormLinear{}; // renvoie des vecteurs élémentaires
               // on devrait pouvoir construire une forme lin à partir d'une forme bilin pour les pb "matrix free"
@@ -198,5 +243,54 @@ void Construct(FormZero &Z,Region &R,Integrator &I);
 void Assemble(FormZero &Z,Region &R,Assembler &A,Integrator &I);
 */
 
+template<class datamat, class T1,class T2> class TermBilinear  // terme associe a un "element" / pt de gauss (contribution élémentaire)
+            // typiquement celui ci stoque ce qui doit etre stocke. C'est la base configurable du code
+            // on doit associer cela a un allocateur qui renvoie un pointeur sur ce truc 
+            // Soit tous les elements/pts de gauss ont le meme terme , allocateur unique (pas de stockage aux pts de
+            // gauss par exemple
+            // soit ils ont qqc a stockuer et sont tous distincts
+            // on peut utiliser des membres statiques pour ce qui est constant pour tous les instances
+{
+public:
+  typedef void Stype;
+  typedef datamat Datamat;
+//  TermBilinear(){};
+  virtual void Init(MElement *e, FormBilinearBase * caller) //called once for every element
+  {
+  }
+  virtual bool NeedGradFuncs(void) { return false ;}// Query if getTerm will use the gradient of the SF
+  virtual bool NeedFuncs(void) { return false ;}// Query if it will need the value of the SF
+
+  virtual void getTerm(const double uvw[],MElement *e,Stype* info, Function<T1> &SF,Function<T2> &TF, datamat &res ) // called for every gauss point
+  {
+  };
+  virtual void Update(const double uvw[],MElement &e,Function<T1> &SF,Function<T2> &TF) {};
+// toute fonctios utiles . prevoir un algorithme  ad hoc pour l'appliquer sur ts les pts de gauss ...
+};
+
+
+class TermBilinearMeca : public TermBilinear<double, double,double>
+{
+public:
+  virtual bool NeedGradFuncs(void) { return true ;}// Query if getTerm will use the gradient of the SF
+//  typedef Tensor Stype;
+//  TermBilinear(){};
+//  virtual double getTerm(double uvw[],MElement &e,Function<double> &SF,Function<double> &TF,Stype* info) {};
+//  virtual void Update(double uvw[],MElement &e,Function<T1> &SF,Function<T2> &TF) {};
+// toute fonctios utiles . prevoir un algorithme 
+};
+
+
+class TermBilinearMecaNL : public TermBilinearMeca
+{
+public:
+  typedef Tensor2 Stype;
+//  TermBilinear(){};
+//  virtual double getTerm(double uvw[],MElement &e,Function<double> &SF,Function<double> &TF,Stype* info) {};
+//  virtual void Update(double uvw[],MElement &e,Function<T1> &SF,Function<T2> &TF) {};
+// toute fonctios utiles . prevoir un algorithme 
+};
+
+
 
 #endif // highlevel_H
diff --git a/contrib/arc/mainElasticity.cpp b/contrib/arc/mainElasticity.cpp
index e39b9fe4118b9e1d338f93d22a1881b111f6991d..99b08ca69a7c04d80e117d95e7f74148c2b2892d 100644
--- a/contrib/arc/mainElasticity.cpp
+++ b/contrib/arc/mainElasticity.cpp
@@ -11,18 +11,17 @@ int main (int argc, char* argv[])
     return -1;
   } 
 
-  
-  FormBilinear<TermBilinearMeca> f;
+  MElement *e;
+  const double uvw[3]={0.,0.,0.};
+  SpaceLagrange<double> L(123);
+  FormBilinear<TermBilinearMeca,SpaceLagrange<double>,SpaceLagrange<double> > f(L,L);
   f.func();
-  f.func2();
+  f.Accumulate(e,uvw);
 
 
-  FormBilinear<TermBilinearMecaNL> fnl;
+  FormBilinear<TermBilinearMecaNL,SpaceLagrange<double>,SpaceLagrange<double> > fnl(L,L);
   fnl.func();
-  fnl.func2();
-  
-  SpaceLagrange<double> L(123);
-
+    
   // globals are still present in Gmsh
   GmshInitialize(argc, argv);