diff --git a/Numeric/fullMatrix.cpp b/Numeric/fullMatrix.cpp
index 0312dd4b40440f8fa33c684cb537c248deda1126..6b601c9d8a313430edf2ce3e2ecf73e91ccc9592 100644
--- a/Numeric/fullMatrix.cpp
+++ b/Numeric/fullMatrix.cpp
@@ -36,6 +36,18 @@ extern "C" {
                       std::complex<double> *alpha, std::complex<double> *a, int *lda, 
                       std::complex<double> *x, int *incx, std::complex<double> *beta, 
                       std::complex<double> *y, int *incy);
+  void F77NAME(daxpy)(int *n, double *alpha, double *x, int *incx, double *y, int *incy );
+
+
+}
+
+template<> 
+void fullVector<double>::axpy(fullVector<double> &x,double alpha)
+{
+  //  for (int i=0;i<_r;i++) _data[i] += alpha * x._data[i];
+  //  return;
+  int M = _r, INCX = 1, INCY = 1;
+  F77NAME(daxpy)(&M, &alpha, x._data,&INCX, _data, &INCY);
 }
 
 template<> 
diff --git a/Numeric/fullMatrix.h b/Numeric/fullMatrix.h
index 4fe957c33d55f753f0c4718642a56924679b3d8c..da87ddb23f88060bde412b2ac51ecf56f4ee2a81 100644
--- a/Numeric/fullMatrix.h
+++ b/Numeric/fullMatrix.h
@@ -71,6 +71,14 @@ class fullVector
     for(int i = 0; i < _r; ++i) s += _data[i] * other._data[i];
     return s;
   }
+  // y <- y + alpha * x
+  void axpy(fullVector<scalar> &x, scalar alpha=1.)
+#if !defined(HAVE_BLAS)
+  {
+    for (int i=0;i<_r;i++) _data[i] += alpha * x._data[i];
+  }
+#endif
+  ;
   void print(const char *name="") const 
   {
     printf("Printing vector %s:\n", name);
diff --git a/Solver/dgAlgorithm.cpp b/Solver/dgAlgorithm.cpp
index 0203bcf63ad39d616755ab5258b3600845fdc2fd..da3d0ebfa66d2dfd1b5e66fb84f30aec8cc7aa2c 100644
--- a/Solver/dgAlgorithm.cpp
+++ b/Solver/dgAlgorithm.cpp
@@ -1,6 +1,7 @@
 #include <set>
 #include "dgAlgorithm.h"
 #include "dgGroupOfElements.h"
+#include "dgSystemOfEquations.h"
 #include "dgConservationLaw.h"
 #include "GEntity.h"
 #include "MElement.h"
@@ -217,9 +218,9 @@ void dgAlgorithm::residualInterface ( //dofManager &dof, // the DOF manager (may
 }
 
 void dgAlgorithm::multAddInverseMassMatrix ( /*dofManager &dof,*/
-          const dgGroupOfElements & group,
-          fullMatrix<double> &residu,
-          fullMatrix<double> &sol)
+					    const dgGroupOfElements & group,
+					    fullMatrix<double> &residu,
+					    fullMatrix<double> &sol)
 {
   fullMatrix<double> residuEl;
   fullMatrix<double> solEl;
@@ -234,59 +235,72 @@ void dgAlgorithm::multAddInverseMassMatrix ( /*dofManager &dof,*/
 }
 
 
- void dgAlgorithm::rungeKutta (const dgConservationLaw &claw,				// conservation law
-			       std::vector<dgGroupOfElements*> &eGroups,	// group of elements
-			       std::vector<dgGroupOfFaces*> &fGroups,		// group of interfacs
-			       std::vector<dgGroupOfFaces*> &bGroups,		// group of boundaries
-			       double h,									// time-step
-			       std::vector<fullMatrix<double> *> &residu,					
-			       std::vector<fullMatrix<double> *> &sol,					
-			       int orderRK)								// order of RK integrator
+void dgAlgorithm::rungeKutta (const dgConservationLaw &claw,			// conservation law
+			      std::vector<dgGroupOfElements*> &eGroups,	// group of elements
+			      std::vector<dgGroupOfFaces*> &fGroups,		// group of interfacs
+			      std::vector<dgGroupOfFaces*> &bGroups,		// group of boundaries
+			      double h,				        // time-step
+			      dgDofContainer &sol,
+			      dgDofContainer &resd,			       
+			      int orderRK)				        // order of RK integrator
  {
-  // U_{n+1}=U_n+h*(SUM_i a_i*K_i)
-  // K_i=M^(-1)R(U_n+b_i*K_{i-1})
 
-   /*
-     double a[4] = {h/6.0,h/3.0,h/3.0,h/6.0};
-     double b[4] = {0.,h/2.0,h/2.0,h};
-     
-     fullMatrix<double> K(sol);
-     // Current updated solution
-     fullMatrix<double> Unp(sol);
-     fullMatrix<double> residuEl, KEl;
-     fullMatrix<double> iMassEl;
-     
-     int nbNodes = eGroups[0]->getNbNodes();
-     int nbFields = sol.size2()/eGroups[0]->getNbElements(); 
-     
-     for(int j=0; j<orderRK;j++){
-     if(j!=0){
-     K.scale(b[j]);
-     K.add(sol);
-     }
-     this->residual(claw,eGroups,fGroups,bGroups,K,residu);
-     K.scale(0.);
-     for(int i=0;i<eGroups[0]->getNbElements();i++) {
-     residuEl.setAsProxy(residu,i*nbFields,nbFields);
-     KEl.setAsProxy(K,i*nbFields,nbFields);
-     iMassEl.setAsProxy(eGroups[0]->getInverseMassMatrix(),i*nbNodes,nbNodes);
-     iMassEl.mult(residuEl,KEl);
-     }
-     Unp.add(K,a[j]);
+   // U_{n+1}=U_n+h*(SUM_i a_i*K_i)
+   // K_i=M^(-1)R(U_n+b_i*K_{i-1})
+   
+   double a[4] = {h/6.0,h/3.0,h/3.0,h/6.0};
+   double b[4] = {0.,h/2.0,h/2.0,h};
+   
+   // fullMatrix<double> K(sol);
+   // Current updated solution
+   // fullMatrix<double> Unp(sol);
+   fullMatrix<double> residuEl, KEl;
+   fullMatrix<double> iMassEl;
+   
+   int nbFields = claw.nbFields();
+   
+   dgDofContainer K   (eGroups,claw);
+   dgDofContainer Unp (eGroups,claw);
+
+   K._data->scale(0.0);
+   K._data->axpy(*(sol._data));
+   Unp._data->scale(0.0);
+   Unp._data->axpy(*(sol._data));
+
+   for(int j=0; j<orderRK;j++){
+     if(j){
+       K._data->scale(b[j]);
+       K._data->axpy(*(sol._data));
      }
-     sol=Unp;
+     //     printf("iter %d sol size = %d\n",j,sol._dataSize);
+     this->residual(claw,eGroups,fGroups,bGroups,K._dataProxys,resd._dataProxys);
+     K._data->scale(0.);
+     for(int k=0;k < eGroups.size();k++) {
+       int nbNodes = eGroups[k]->getNbNodes();
+       for(int i=0;i<eGroups[k]->getNbElements();i++) {
+	 residuEl.setAsProxy(*(resd._dataProxys[k]),i*nbFields,nbFields);
+	 KEl.setAsProxy(*(K._dataProxys[k]),i*nbFields,nbFields);
+	 iMassEl.setAsProxy(eGroups[k]->getInverseMassMatrix(),i*nbNodes,nbNodes);
+	 iMassEl.mult(residuEl,KEl);
+       }
      }
-
-   */
+     Unp._data->axpy(*(K._data),a[j]);
+   }
+   
+   for (int i=0;i<sol._dataSize;i++){
+     //     printf("tempSol[%d] = %g\n",i,(*tempSol._data)(i));
+     //     memcp
+     (*sol._data)(i)=(*Unp._data)(i);
+   }
  }
 
 void dgAlgorithm::residualBoundary ( //dofManager &dof, // the DOF manager (maybe useless here)
 				   const dgConservationLaw &claw,   // the conservation law
 				   const dgGroupOfFaces &group, 
-           const fullMatrix<double> &solution, // solution !! at faces nodes
-           fullMatrix<double> &solutionLeft, 
-           fullMatrix<double> &residual // residual !! at faces nodes
-           )
+				   const fullMatrix<double> &solution, // solution !! at faces nodes
+				   fullMatrix<double> &solutionLeft, 
+				   fullMatrix<double> &residual // residual !! at faces nodes
+				     )
 { 
   int nbFields = claw.nbFields();
   const dgBoundaryCondition *boundaryCondition = claw.getBoundaryCondition(group.getBoundaryTag());
@@ -409,8 +423,8 @@ void dgAlgorithm::residual( const dgConservationLaw &claw,
     dgGroupOfFaces &faces = *fGroups[i];
     int iGroupLeft = -1, iGroupRight = -1;
     for(size_t j=0;j<eGroups.size() ; j++) {
-      if (eGroups[i] == &faces.getGroupLeft())iGroupLeft = j;
-      if (eGroups[i] == &faces.getGroupRight())iGroupRight= j;
+      if (eGroups[j] == &faces.getGroupLeft())iGroupLeft = j;
+      if (eGroups[j] == &faces.getGroupRight())iGroupRight= j;
     }
     
     fullMatrix<double> solInterface(faces.getNbNodes(),faces.getNbElements()*2*nbFields);
@@ -424,8 +438,8 @@ void dgAlgorithm::residual( const dgConservationLaw &claw,
     dgGroupOfFaces &faces = *bGroups[i];
     int iGroupLeft = -1, iGroupRight = -1;
     for(size_t j=0;j<eGroups.size() ; j++) {
-      if (eGroups[i] == &faces.getGroupLeft())iGroupLeft = j;
-      if (eGroups[i] == &faces.getGroupRight())iGroupRight= j;
+      if (eGroups[j] == &faces.getGroupLeft())iGroupLeft = j;
+      if (eGroups[j] == &faces.getGroupRight())iGroupRight= j;
     }
     fullMatrix<double> solInterface(faces.getNbNodes(),faces.getNbElements()*nbFields);
     fullMatrix<double> residuInterface(faces.getNbNodes(),faces.getNbElements()*nbFields);
diff --git a/Solver/dgAlgorithm.h b/Solver/dgAlgorithm.h
index dfad3132e488ba949dd3a9674a8e4c4e08e69ca1..566cf906d0c268872dcebe91a3867f6284790bf9 100644
--- a/Solver/dgAlgorithm.h
+++ b/Solver/dgAlgorithm.h
@@ -7,6 +7,7 @@ class GModel;
 class dgGroupOfElements;
 class dgGroupOfFaces;
 class dgConservationLaw;
+class dgDofContainer;
 class dgTerm;
 
 class dgAlgorithm {
@@ -44,8 +45,8 @@ class dgAlgorithm {
 		   std::vector<dgGroupOfFaces*> &fGroups,  // group of interfacs
 		   std::vector<dgGroupOfFaces*> &bGroups, // group of boundaries
 		   double h,	
-		   std::vector<fullMatrix<double> *> &residu,
-		   std::vector<fullMatrix<double> *> &sol,
+		   dgDofContainer &residu,
+		   dgDofContainer &sol,
 		   int orderRK=4);
   static void multAddInverseMassMatrix ( /*dofManager &dof,*/
 					const dgGroupOfElements & group,
diff --git a/Solver/dgSystemOfEquations.cpp b/Solver/dgSystemOfEquations.cpp
index 6cc5af311124f95cf17de611f4f7a66a5cb24db8..acaa38827677a29cc3f6f91d85248e3f53f803f3 100644
--- a/Solver/dgSystemOfEquations.cpp
+++ b/Solver/dgSystemOfEquations.cpp
@@ -13,9 +13,7 @@ const char dgSystemOfEquations::className[] = "dgSystemOfEquations";
 // Define the methods we will expose to Lua
 #define _method(class, name) {#name, &class::name}
 Luna<dgSystemOfEquations>::RegType dgSystemOfEquations::methods[] = {
-   _method(dgSystemOfEquations, getRHS),
-   _method(dgSystemOfEquations, computeRHS),
-   _method(dgSystemOfEquations, getSolution),
+   _method(dgSystemOfEquations, RK44),
    _method(dgSystemOfEquations, exportSolution),
    _method(dgSystemOfEquations, setConservationLaw),
    _method(dgSystemOfEquations, setOrder),
@@ -56,6 +54,7 @@ dgSystemOfEquations::dgSystemOfEquations(lua_State *L){
   if (!obj)throw;
   _gm = obj->getGModel();
   _dimension = _gm->getNumRegions() ? 3 : 2;
+  _solution = 0;
 }
 
 // set the conservation law as a string (for now)
@@ -98,8 +97,8 @@ int dgSystemOfEquations::addBoundaryCondition (lua_State *L){
 int dgSystemOfEquations::L2Projection (lua_State *L){
   dgConservationLawL2Projection Law(std::string(luaL_checkstring(L, 1)),*_claw);
   for (int i=0;i<_elementGroups.size();i++){
-    _algo->residualVolume(Law,*_elementGroups[i],*_solutionProxys[i],*_rightHandSideProxys[i]);
-    _algo->multAddInverseMassMatrix(*_elementGroups[i],*_rightHandSideProxys[i],*_solutionProxys[i]);
+    _algo->residualVolume(Law,*_elementGroups[i],*_solution->_dataProxys[i],*_rightHandSide->_dataProxys[i]);
+    _algo->multAddInverseMassMatrix(*_elementGroups[i],*_rightHandSide->_dataProxys[i],*_solution->_dataProxys[i]);
   }
 }
 
@@ -113,60 +112,35 @@ int dgSystemOfEquations::setup(lua_State *L){
 		     _faceGroups,
 		     _boundaryGroups);
   // compute the total size of the soution
-  _dataSize = 0;
-  int nbFields = _claw->nbFields();
-  for (int i=0;i<_elementGroups.size();i++){
-    int nbNodes    = _elementGroups[i]->getNbNodes();
-    int nbElements = _elementGroups[i]->getNbElements();
-    _dataSize += nbNodes*nbFields*nbElements;
-  }
-  // allocate the big vectors
-  _solution      = new double [_dataSize];
-  _rightHandSide = new double [_dataSize];
-  // create proxys for each group
-  int offset = 0;
-  _solutionProxys.resize(_elementGroups.size());
-  _rightHandSideProxys.resize(_elementGroups.size());
-  for (int i=0;i<_elementGroups.size();i++){    
-    int nbNodes    = _elementGroups[i]->getNbNodes();
-    int nbElements = _elementGroups[i]->getNbElements();
-    _solutionProxys[i] = new fullMatrix<double> (&_solution[offset*sizeof(double)],nbNodes, nbFields*nbElements);
-    _rightHandSideProxys[i] = new fullMatrix<double> (&_rightHandSide[offset*sizeof(double)],nbNodes, nbFields*nbElements);
-    offset += nbNodes*nbFields*nbElements;
-  }
+  _solution = new dgDofContainer(_elementGroups,*_claw);
+  _rightHandSide = new dgDofContainer(_elementGroups,*_claw);
+  //  printf("aaaaaaaaaaaaa\n");
 }
 
 
-int dgSystemOfEquations::getSolution(lua_State *L){
-  lua_pushlightuserdata (L, _solution);
-  return 1;
-}
-
-int dgSystemOfEquations::computeRHS(lua_State *L){
-  _algo->residual(*_claw, _elementGroups, _faceGroups, _boundaryGroups, _solutionProxys, _rightHandSideProxys);
-  lua_pushlightuserdata (L, _solution);
-  return 1;
-}
-
-int dgSystemOfEquations::getRHS(lua_State *L){
-  lua_pushlightuserdata (L, _rightHandSide);
+int dgSystemOfEquations::RK44(lua_State *L){
+  double dt = luaL_checknumber(L, 1);
+  _algo->rungeKutta(*_claw, _elementGroups, _faceGroups, _boundaryGroups, dt,  *_solution, *_rightHandSide);
+  double normSolution = _solution->_data->norm();
+  lua_pushnumber (L, normSolution);
   return 1;
 }
 
 int dgSystemOfEquations::exportSolution(lua_State *L){
   std::string outputFile(luaL_checkstring(L, 1));
   export_solution_as_is(outputFile);
+  return 0;
 }
 #endif // HAVE_LUA
 
 dgSystemOfEquations::~dgSystemOfEquations(){
   for (int i=0;i<_elementGroups.size();i++){
-    delete _solutionProxys[i];
-    delete _rightHandSideProxys[i];
     delete _elementGroups[i];
   }
-  delete [] _solution;
-  delete [] _rightHandSide;
+  if (_solution){
+    delete _solution;
+    delete _rightHandSide;
+  }
 }
 
 void dgSystemOfEquations::export_solution_as_is (const std::string &name){
@@ -229,3 +203,31 @@ void dgSystemOfEquations::export_solution_as_is (const std::string &name){
   pv->getData()->writeMSH(name+".msh", false); 
   delete pv;
 }
+
+dgDofContainer::dgDofContainer (std::vector<dgGroupOfElements*> &elementGroups, const dgConservationLaw &claw){
+  _dataSize = 0;
+  int nbFields = claw.nbFields();
+  for (int i=0;i<elementGroups.size();i++){
+    int nbNodes    = elementGroups[i]->getNbNodes();
+    int nbElements = elementGroups[i]->getNbElements();
+    _dataSize += nbNodes*nbFields*nbElements;
+  }
+  // allocate the big vectors
+  _data      = new fullVector<double>(_dataSize);
+  // create proxys for each group
+  int offset = 0;
+  _dataProxys.resize(elementGroups.size());
+  for (int i=0;i<elementGroups.size();i++){    
+    int nbNodes    = elementGroups[i]->getNbNodes();
+    int nbElements = elementGroups[i]->getNbElements();
+    _dataProxys[i] = new fullMatrix<double> (&(*_data)(offset*sizeof(double)),nbNodes, nbFields*nbElements);
+    offset += nbNodes*nbFields*nbElements;
+  }  
+  //  printf("datasize = %d\n",_dataSize);
+}
+
+dgDofContainer::~dgDofContainer (){
+  if (!_dataSize)return;
+  for (int i=0;i<_dataProxys.size();++i) delete _dataProxys[i];
+  delete _data;
+}
diff --git a/Solver/dgSystemOfEquations.h b/Solver/dgSystemOfEquations.h
index 567f37f5b90518b093623538b26bb4131da10b43..45c5108a6a9fe5cc363dba3b7ec0094dbabd993f 100644
--- a/Solver/dgSystemOfEquations.h
+++ b/Solver/dgSystemOfEquations.h
@@ -19,6 +19,18 @@ extern "C" {
 #include "luna.h"
 #endif // HAVE LUA
 
+struct dgDofContainer {
+private:
+  dgDofContainer (const dgDofContainer&);  
+public:
+  int _dataSize; // the full data size i.e. concerning all groups
+  fullVector<double> * _data; // the full data itself
+  std::vector<fullMatrix<double> *> _dataProxys; // proxys 
+  dgDofContainer (std::vector<dgGroupOfElements*> &groups, const dgConservationLaw &claw);
+  ~dgDofContainer ();  
+};
+
+
 class dgSystemOfEquations {
   // the mesh and the model
   GModel *_gm;
@@ -31,13 +43,9 @@ class dgSystemOfEquations {
   int _order;
   // dimension of the problem
   int _dimension;
-  // solution and righ hand sides as a large arrays of doubles
-  int _dataSize;
-  double * _solution;
-  double * _rightHandSide;
-  // proxis of the solution and of the right hand side for each group;
-  std::vector<fullMatrix<double> *> _solutionProxys;
-  std::vector<fullMatrix<double> *> _rightHandSideProxys;
+  // solution and righ hand sides
+  dgDofContainer *_solution;
+  dgDofContainer *_rightHandSide;
   // groups of elements (volume terms)
   std::vector<dgGroupOfElements*> _elementGroups;
   // groups of faces (interface terms)
@@ -51,19 +59,17 @@ public:
   static const char className[];
   static Luna<dgSystemOfEquations>::RegType methods[];
   static void Register(lua_State *L);
-  int computeRHS      (lua_State *L); // get the Right Hand
-  int getRHS      (lua_State *L); // get the Right Hand
-  int getSolution (lua_State *L); // get the Solution
   int exportSolution (lua_State *L); // export the solution
   int setOrder (lua_State *L); // set the polynomial order
   int setConservationLaw (lua_State *L); // set the conservationLaw
   int addBoundaryCondition (lua_State *L); // add a boundary condition : "physical name", "type", [options]
   int setup (lua_State *L); // setup the groups and allocate
   int L2Projection (lua_State *L); // assign the solution to a given function
+  int RK44 (lua_State *L); // assign the solution to a given function
   dgSystemOfEquations(lua_State *L);
 #endif // HAVE LUA
   inline const fullMatrix<double> getSolutionProxy (int iGroup, int iElement){
-    return fullMatrix<double> ( *_solutionProxys [iGroup] ,
+    return fullMatrix<double> ( *_solution->_dataProxys [iGroup] ,
 				iElement * _claw->nbFields(),_claw->nbFields());
   }
   void export_solution_as_is (const std::string &fileName);
diff --git a/contrib/DiscreteIntegration/Integration3D.h b/contrib/DiscreteIntegration/Integration3D.h
index 1d24a0a5c162c32c23bf8491f233d8733efbea87..2665373bb560ec30371424fc0182a9277a690a13 100644
--- a/contrib/DiscreteIntegration/Integration3D.h
+++ b/contrib/DiscreteIntegration/Integration3D.h
@@ -43,11 +43,11 @@ class DI_Point
   DI_Point (double x, double y, double z, const double ls) : x_(x), y_(y), z_(z) {addLs(ls);}
   DI_Point (double x, double y, double z, const DI_Element *e,
             const std::vector<const gLevelset *> &RPNi) : x_(x), y_(y), z_(z) {computeLs(e, RPNi);}
-  DI_Point(const DI_Point &p) : x_(p.x()), y_(p.y()), z_(p.z()) {Ls.clear(); Ls = p.Ls;}
+  //  DI_Point(const DI_Point &p) : x_(p.x()), y_(p.y()), z_(p.z()) {Ls.clear(); Ls = p.Ls;}
   // assignment
   DI_Point & operator=(const DI_Point & rhs);
   // destructor
-  virtual ~DI_Point () {}
+  //  virtual ~DI_Point () {}
   // add a levelset value (adjusted to 0 if ls<ZERO_LS_TOL) into the vector Ls
   void addLs (const double ls);
   // add a levelset value evaluated into the element e