diff --git a/Solver/TESTCASES/Advection.lua b/Solver/TESTCASES/Advection.lua
index d66da7451f3bf76a2f5302b844f596646b47c26e..5d4f9f02047361edb2b3df09038e1a968f7aebbe 100644
--- a/Solver/TESTCASES/Advection.lua
+++ b/Solver/TESTCASES/Advection.lua
@@ -2,7 +2,7 @@ model = GModel  ()
 model:load ('square.geo')
 model:load ('square.msh')
 dg = dgSystemOfEquations (model)
-dg:setOrder(1)
+dg:setOrder(5)
 
 
 -- conservation law
@@ -36,9 +36,9 @@ dg:L2Projection(createFunction.lua(1,'initial_condition','XYZ'))
 dg:exportSolution('output/Advection_00000')
 
 -- main loop
-for i=1,800 do
-  norm = dg:RK44(0.01)
-  if (i % 10 == 0) then 
+for i=1,10000 do
+  norm = dg:RK44(0.001)
+  if (i % 50 == 0) then 
     print('iter',i,norm)
     dg:exportSolution(string.format("output/Advection-%05d", i)) 
   end
diff --git a/Solver/dgAlgorithm.cpp b/Solver/dgAlgorithm.cpp
index 5a15521e0b0d5c0a86cacd82dbd50f0f87ea2c90..718d2cd8f410289624f8f2bc67b8d169099d7423 100644
--- a/Solver/dgAlgorithm.cpp
+++ b/Solver/dgAlgorithm.cpp
@@ -122,7 +122,7 @@ void dgAlgorithm::residualVolume ( //dofManager &dof, // the DOF manager (maybe
 
 void dgAlgorithm::residualInterface ( //dofManager &dof, // the DOF manager (maybe useless here)
 				   const dgConservationLaw &claw,   // the conservation law
-				   const dgGroupOfFaces &group, 
+				   dgGroupOfFaces &group, 
 				   const fullMatrix<double> &solution, // solution !! at faces nodes
 				   fullMatrix<double> &solutionLeft, 
 				   fullMatrix<double> &solutionRight, 
@@ -154,7 +154,8 @@ void dgAlgorithm::residualInterface ( //dofManager &dof, // the DOF manager (may
   dataCacheDouble &normals = cacheMapLeft.provideData("Normals");
   dataCacheElement &cacheElementLeft = cacheMapLeft.getElement();
   dataCacheElement &cacheElementRight = cacheMapRight.getElement();
-  cacheMapLeft.provideData("UVW").set(group.getIntegrationPointsMatrix());
+  dataCacheDouble &uvwLeft = cacheMapLeft.provideData("UVW");
+  dataCacheDouble &uvwRight = cacheMapRight.provideData("UVW");
   dataCacheDouble &solutionQPLeft = cacheMapLeft.provideData("Solution");
   dataCacheDouble &solutionQPRight = cacheMapRight.provideData("Solution");
   dataCacheDouble &gradientSolutionLeft = cacheMapLeft.provideData("GradientSolution");
@@ -185,6 +186,8 @@ void dgAlgorithm::residualInterface ( //dofManager &dof, // the DOF manager (may
     dPsiRightDx.setAsProxy(DPsiLeftDx,iFace*nbNodesRight,nbNodesRight);
     dofsLeft.setAsProxy(solutionLeft, nbFields*group.getElementLeftId(iFace), nbFields);
     dofsRight.setAsProxy(solutionRight, nbFields*group.getElementRightId(iFace), nbFields);
+    uvwLeft.setAsProxy(group.getIntegrationOnElementLeft(iFace));
+    uvwRight.setAsProxy(group.getIntegrationOnElementRight(iFace));
     // proxies for the flux
     normalFluxQP.setAsProxy(NormalFluxQP, iFace*nbFields*2, nbFields*2);
 
@@ -297,7 +300,7 @@ void dgAlgorithm::rungeKutta (const dgConservationLaw &claw,			// conservation l
 
 void dgAlgorithm::residualBoundary ( //dofManager &dof, // the DOF manager (maybe useless here)
 				   const dgConservationLaw &claw,   // the conservation law
-				   const dgGroupOfFaces &group, 
+				   dgGroupOfFaces &group, 
 				   const fullMatrix<double> &solution, // solution !! at faces nodes
 				   fullMatrix<double> &solutionLeft, 
 				   fullMatrix<double> &residual // residual !! at faces nodes
@@ -313,7 +316,7 @@ void dgAlgorithm::residualBoundary ( //dofManager &dof, // the DOF manager (mayb
 
   dataCacheMap cacheMapLeft(group.getNbIntegrationPoints());
   // provided dataCache
-  cacheMapLeft.provideData("UVW").set(group.getIntegrationPointsMatrix());
+  dataCacheDouble &uvw=cacheMapLeft.provideData("UVW");
   dataCacheDouble &solutionQPLeft = cacheMapLeft.provideData("Solution");
   dataCacheDouble &normals = cacheMapLeft.provideData("Normals");
   dataCacheElement &cacheElementLeft = cacheMapLeft.getElement();
@@ -326,6 +329,7 @@ void dgAlgorithm::residualBoundary ( //dofManager &dof, // the DOF manager (mayb
     // ----- 2.3.1 --- provide the data to the cacheMap
     solutionQPLeft.setAsProxy(solutionQP, iFace*nbFields, nbFields);
     normals.setAsProxy(group.getNormals(),iFace*group.getNbIntegrationPoints(),group.getNbIntegrationPoints());
+    uvw.setAsProxy(group.getIntegrationOnElementLeft(iFace));
     cacheElementLeft.set(group.getElementLeft(iFace));
 
     // ----- 2.3.2 --- compute fluxes
diff --git a/Solver/dgAlgorithm.h b/Solver/dgAlgorithm.h
index 566cf906d0c268872dcebe91a3867f6284790bf9..fd9c321490ff310f3c859b259f24ae6de9738332 100644
--- a/Solver/dgAlgorithm.h
+++ b/Solver/dgAlgorithm.h
@@ -19,14 +19,14 @@ class dgAlgorithm {
 			      fullMatrix<double> &residual);
   static void residualInterface ( //dofManager &dof, // the DOF manager (maybe useless here)
 				 const dgConservationLaw &claw,   // the conservation law
-				 const dgGroupOfFaces & group, 
+				 dgGroupOfFaces & group, 
 				 const fullMatrix<double> &solution, // ! at face nodes
 				 fullMatrix<double> &solutionRight,
 				 fullMatrix<double> &solutionLeft,
 				 fullMatrix<double> &residual); // ! at face nodes
   static void residualBoundary ( //dofManager &dof, // the DOF manager (maybe useless here)
 				const dgConservationLaw &claw,   // the conservation law
-				const dgGroupOfFaces &group, 
+				dgGroupOfFaces &group, 
 				const fullMatrix<double> &solution, // solution !! at faces nodes
 				fullMatrix<double> &solutionLeft,
 				fullMatrix<double> &residual // residual !! at faces nodes
diff --git a/Solver/dgConservationLaw.cpp b/Solver/dgConservationLaw.cpp
index d0fd5b45e0880c9e19646c3484d2b48787809e28..e4c7d1cb6d77a306aee59fe0b6c58b0c90e083ab 100644
--- a/Solver/dgConservationLaw.cpp
+++ b/Solver/dgConservationLaw.cpp
@@ -6,7 +6,6 @@ class dgBoundaryConditionOutsideValue : public dgBoundaryCondition {
   class term : public dataCacheDouble {
     dataCacheMap cacheMapRight; // new cacheMap to  pass to the Riemann solver
     dataCacheDouble &solutionRight;
-    dataCacheDouble &solutionLeft;
     dataCacheDouble &outsideValue;
     dataCacheDouble *riemannSolver;
     dgConservationLaw &_claw;
@@ -15,11 +14,11 @@ class dgBoundaryConditionOutsideValue : public dgBoundaryCondition {
       dataCacheDouble(cacheMapLeft.getNbEvaluationPoints(),claw.nbFields()),
       cacheMapRight(cacheMapLeft.getNbEvaluationPoints()),
       solutionRight(cacheMapRight.provideData("Solution")),
-      solutionLeft(cacheMapLeft.get("Solution",this)),
       outsideValue(cacheMapLeft.get(outsideValueFunctionName,this)),
       _claw(claw)
     {
       riemannSolver=_claw.newRiemannSolver(cacheMapLeft,cacheMapRight);
+      riemannSolver->addMeAsDependencyOf(this);
     }
 
     void _eval() {
@@ -43,15 +42,10 @@ class dgBoundaryConditionOutsideValue : public dgBoundaryCondition {
 class dgBoundaryCondition0Flux : public dgBoundaryCondition {
   dgConservationLaw &_claw;
   class term : public dataCacheDouble {
-    dataCacheDouble &UVW;
-    dgConservationLaw &_claw;
     public:
-    term(dgConservationLaw &claw,dataCacheMap &cacheMapLeft): UVW(cacheMapLeft.get("UVW",this)),_claw(claw) {}
+    term(dgConservationLaw &claw,dataCacheMap &cacheMapLeft):
+    dataCacheDouble(cacheMapLeft.getNbEvaluationPoints(),claw.nbFields()) {}
     void _eval() {
-      if(_value.size1()!=UVW().size1()){
-        //adjust sizes
-        _value = fullMatrix<double>(UVW().size1(),_claw.nbFields());
-      }
     }
   };
   public:
diff --git a/Solver/dgConservationLawAdvection.cpp b/Solver/dgConservationLawAdvection.cpp
index ce654004be7002c474f720a3a34b58ca59ccdaf3..b29bdb89ce85ef68b149c071beeff8ff42428cac 100644
--- a/Solver/dgConservationLawAdvection.cpp
+++ b/Solver/dgConservationLawAdvection.cpp
@@ -8,16 +8,14 @@
 class dgConservationLawAdvection : public dgConservationLaw {
   std::string _vFunctionName;
   class advection : public dataCacheDouble {
-    dataCacheDouble &sol, &uvw, &v;
+    dataCacheDouble &sol, &v;
     public:
     advection(std::string vFunctionName, dataCacheMap &cacheMap):
-      uvw(cacheMap.get("UVW",this)),
+      dataCacheDouble(cacheMap.getNbEvaluationPoints(),3),
       sol(cacheMap.get("Solution",this)),
       v(cacheMap.get(vFunctionName,this))
       {};
     void _eval () { 
-      if(_value.size1() != sol().size1())
-        _value=fullMatrix<double>(sol().size1(),3);
       for(int i=0; i< sol().size1(); i++) {
         _value(i,0) = sol(i,0)*v(i,0);
         _value(i,1) = sol(i,0)*v(i,1);
@@ -26,18 +24,16 @@ class dgConservationLawAdvection : public dgConservationLaw {
     }
   };
   class riemann : public dataCacheDouble {
-    dataCacheDouble &uvw, &normals, &solLeft, &solRight,&v;
+    dataCacheDouble &normals, &solLeft, &solRight,&v;
     public:
     riemann(std::string vFunctionName, dataCacheMap &cacheMapLeft, dataCacheMap &cacheMapRight):
-      uvw(cacheMapLeft.get("UVW", this)),
+      dataCacheDouble(cacheMapLeft.getNbEvaluationPoints(),2),
       normals(cacheMapLeft.get("Normals", this)),
       solLeft(cacheMapLeft.get("Solution", this)),
       solRight(cacheMapRight.get("Solution", this)),
       v(cacheMapLeft.get(vFunctionName,this))
       {};
     void _eval () { 
-      if(_value.size1() !=solLeft().size1())
-        _value = fullMatrix<double>(solLeft().size1(),2);
       for(int i=0; i< _value.size1(); i++) {
         double un=v(i,0)*normals(0,i)+v(i,1)*normals(1,i)+v(i,2)*normals(2,i);
         if(un>0){
diff --git a/Solver/dgGroupOfElements.cpp b/Solver/dgGroupOfElements.cpp
index fdeed3c2e28d829eef5f211aa11a0e4e74831737..e3bd1a6fdcc56352243ad6cf4247eee51db38932 100644
--- a/Solver/dgGroupOfElements.cpp
+++ b/Solver/dgGroupOfElements.cpp
@@ -21,24 +21,24 @@ static fullMatrix<double> * dgGetIntegrationRule (MElement *e, int p){
   return m;
 }
 
-static fullMatrix<double> * dgGetFaceIntegrationRuleOnElement (
+static fullMatrix<double> dgGetFaceIntegrationRuleOnElement (
       const polynomialBasis *fsFace,
       const fullMatrix<double> &intgFace,
       const polynomialBasis *fsElement,
-      const std::vector <int> *closure) {
+      const std::vector <int> &closure) {
   int npts=intgFace.size1();
-  fullMatrix<double> *m = new fullMatrix<double> (npts, 4);
+  fullMatrix<double> intgElement(npts, 4);
   double f[256];
   for (int i=0;i<npts;i++){
     fsFace->f(intgFace(i,0),intgFace(i,1),intgFace(i,2),f);
-    for(size_t j=0; j<closure->size();j++){
-      int jNod=(*closure)[j];
+    for(size_t j=0; j<closure.size();j++){
+      int jNod=closure[j];
       for(int k=0;k<fsElement->points.size2();k++)
-        (*m)(i,k) += f[j] * fsElement->points(jNod,k);
-      (*m)(i,3) = intgFace(i,3);
+        intgElement(i,k) += f[j] * fsElement->points(jNod,k);
+      intgElement(i,3) = intgFace(i,3);
     }
   }
-  return m;
+  return intgElement;
 }
 
 
@@ -204,6 +204,10 @@ void dgGroupOfFaces::init(int pOrder) {
   _redistribution = new fullMatrix<double> (_fsFace->coefficients.size1(),_integration->size1());
   _collocation = new fullMatrix<double> (_integration->size1(), _fsFace->coefficients.size1());
   _detJac = new fullMatrix<double> (_integration->size1(), _faces.size());
+  for (size_t i=0; i<_closuresLeft.size(); i++)
+    _integrationPointsLeft.push_back(dgGetFaceIntegrationRuleOnElement(_fsFace,*_integration,_fsLeft,_closuresLeft[i]));
+  for (size_t i=0; i<_closuresRight.size(); i++)
+    _integrationPointsRight.push_back(dgGetFaceIntegrationRuleOnElement(_fsFace,*_integration,_fsRight,_closuresRight[i]));
   double f[256];
   for (int j=0;j<_integration->size1();j++) {
     _fsFace->f((*_integration)(j,0), (*_integration)(j,1), (*_integration)(j,2), f);
@@ -231,11 +235,11 @@ void dgGroupOfFaces::init(int pOrder) {
   int index = 0;
   for (size_t i=0; i<_faces.size();i++){
     const std::vector<int> &closureLeft=getClosureLeft(i);
-    fullMatrix<double> *intLeft=dgGetFaceIntegrationRuleOnElement(_fsFace,*_integration,_fsLeft,&closureLeft);
+    fullMatrix<double> &intLeft=_integrationPointsLeft[_closuresIdLeft[i]];
     double jac[3][3],ijac[3][3];
-    for (int j=0; j<intLeft->size1(); j++){
-      _fsLeft->df((*intLeft)(j,0),(*intLeft)(j,1),(*intLeft)(j,2),g);
-      getElementLeft(i)->getJacobian ((*intLeft)(j,0), (*intLeft)(j,1), (*intLeft)(j,2), jac);
+    for (int j=0; j<intLeft.size1(); j++){
+      _fsLeft->df((intLeft)(j,0),(intLeft)(j,1),(intLeft)(j,2),g);
+      getElementLeft(i)->getJacobian ((intLeft)(j,0), (intLeft)(j,1), (intLeft)(j,2), jac);
       inv3x3(jac,ijac);
       //compute dPsiLeftDxOnQP
       //(iPsi*3+iXYZ,iQP+iFace*NQP);
@@ -264,13 +268,12 @@ void dgGroupOfFaces::init(int pOrder) {
       nz/=norm;
       index++;
     }
-    delete intLeft;
     // there is nothing on the right for boundary groups
     if(_fsRight){
-      fullMatrix<double> *intRight=dgGetFaceIntegrationRuleOnElement(_fsFace,*_integration,_fsRight,&getClosureRight(i));
-      for (int j=0; j<intRight->size1(); j++){
-        _fsRight->df((*intRight)(j,0),(*intRight)(j,1),(*intRight)(j,2),g);
-        getElementRight(i)->getJacobian ((*intRight)(j,0), (*intRight)(j,1), (*intRight)(j,2), jac);
+      fullMatrix<double> &intRight=_integrationPointsLeft[_closuresIdRight[i]];
+      for (int j=0; j<intRight.size1(); j++){
+        _fsRight->df((intRight)(j,0),(intRight)(j,1),(intRight)(j,2),g);
+        getElementRight(i)->getJacobian ((intRight)(j,0), (intRight)(j,1), (intRight)(j,2), jac);
         inv3x3(jac,ijac);
         //compute dPsiRightDxOnQP
         // (iQP*3+iXYZ , iFace*NPsi+iPsi)
@@ -281,7 +284,6 @@ void dgGroupOfFaces::init(int pOrder) {
           (*_dPsiRightDxOnQP)(j*3+2,i*nPsi+iPsi) = g[iPsi][0]*ijac[2][0]+g[iPsi][1]*ijac[2][1]+g[iPsi][2]*ijac[2][2];
         }
       }
-      delete intRight;
     }
   }
 }
diff --git a/Solver/dgGroupOfElements.h b/Solver/dgGroupOfElements.h
index 2836e546e7e5bc8c76787c072525686c61a0ed50..793eb98bf04f9babf9cde73cf9b360f0bf27a2c6 100644
--- a/Solver/dgGroupOfElements.h
+++ b/Solver/dgGroupOfElements.h
@@ -111,6 +111,9 @@ class dgGroupOfFaces {
   std::vector<std::vector<int> > _closuresRight; 
   std::vector<int> _closuresIdLeft; 
   std::vector<int> _closuresIdRight; 
+  // face integration point in the coordinate of the left and right element (one fullMatrix per closure)
+  std::vector<fullMatrix<double> > _integrationPointsLeft;
+  std::vector<fullMatrix<double> > _integrationPointsRight;
   // XYZ gradient of the shape functions of both elements on the integrations points of the face
   // (iQP*3+iXYZ , iFace*NPsi+iPsi)
   fullMatrix<double> *_dPsiLeftDxOnQP;
@@ -134,8 +137,11 @@ public:
   inline MElement* getElementLeft (int i) const {return _groupLeft.getElement(_left[i]);}  
   inline MElement* getElementRight (int i) const {return _groupRight.getElement(_right[i]);}  
   inline MElement* getFace (int iElement) const {return _faces[iElement];}  
-  const std::vector<int> &getClosureLeft(int iFace) const{ return _closuresLeft[_closuresIdLeft[iFace]];}
-  const std::vector<int> &getClosureRight(int iFace) const{ return _closuresRight[_closuresIdRight[iFace]];}
+  inline const std::vector<int> &getClosureLeft(int iFace) const{ return _closuresLeft[_closuresIdLeft[iFace]];}
+  inline const std::vector<int> &getClosureRight(int iFace) const{ return _closuresRight[_closuresIdRight[iFace]];}
+  inline fullMatrix<double> &getIntegrationOnElementLeft(int iFace) { return _integrationPointsLeft[_closuresIdLeft[iFace]];}
+  inline fullMatrix<double> &getIntegrationOnElementRight(int iFace) { return _integrationPointsRight[_closuresIdRight[iFace]];}
+  
   inline fullMatrix<double> &getNormals () const {return *_normals;}
   dgGroupOfFaces (const dgGroupOfElements &elements,int pOrder);
   dgGroupOfFaces (const dgGroupOfElements &elGroup, std::string boundaryTag, int pOrder,std::set<MVertex*> &boundaryVertices);
diff --git a/Solver/function.h b/Solver/function.h
index c9d2b6ba32e553e43486dace44b90504a1296e45..89d775ebc23070aa2820942d150adec34aa40014 100644
--- a/Solver/function.h
+++ b/Solver/function.h
@@ -42,11 +42,11 @@ protected :
       it!=_dependOnMe.end(); it++)
         **it=false;
   }
-  // dataCacheMap is the only one supposed to call this
-  void addMeAsDependencyOf (dataCache *newDep);
   dataCache() : _valid(false) {}
   virtual ~dataCache(){};
 public :
+  // dataCacheMap is the only one supposed to call this
+  void addMeAsDependencyOf (dataCache *newDep);
   inline bool somethingDependOnMe() {
     return !_dependOnMe.empty();
   }
@@ -72,6 +72,13 @@ class dataCacheDouble : public dataCache {
     _value.setAsProxy(mat,cShift,c);
     _valid=true;
   }
+  // take care if you use this you must ensure that the value pointed to are not modified
+  // without further call to setAsProxy because the dependencies won't be invalidate
+  inline void setAsProxy(fullMatrix<double> &mat) {
+    _invalidateDependencies();
+    _value.setAsProxy(mat,0,mat.size2());
+    _valid=true;
+  }
   // this function is needed to be able to pass the _value to functions like gemm or mult
   // but you cannot keep the reference to the _value, you should always use the set function 
   // to modify the _value