diff --git a/Solver/TESTCASES/Advection_1.lua b/Solver/TESTCASES/Advection_1.lua
new file mode 100644
index 0000000000000000000000000000000000000000..57198d6827aa0ad2ac6f6a328af2217f63369554
--- /dev/null
+++ b/Solver/TESTCASES/Advection_1.lua
@@ -0,0 +1,69 @@
+model = GModel  ()
+print'*** Loading the geo ***'
+model:load ('square_m.geo')
+-- model:load ('square_p.geo')
+print'*** Loading the mesh ***'
+model:load ('square_m.msh')
+-- model:load('square_p.msh')
+print'*** mesh loaded ***'
+dg = dgSystemOfEquations (model)
+order=3
+dg:setOrder(order)
+print("*** order = " .. order .. " ***")
+print'*** Model set ***'
+
+print("*** set initial condition ***")
+-- initial condition
+function initial_condition( xyz , f )
+  for i=0,xyz:size1()-1 do
+    x = xyz:get(i,0)
+    y = xyz:get(i,1)
+    z = xyz:get(i,2)
+    f:set (i, 0, math.exp(-100*((x+0.2)^2 +(y+0.3)^2)))
+  end
+end
+
+-- conservation law
+-- advection speed
+v=fullMatrix(3,1);
+v:set(0,0,0.01)
+v:set(1,0,0.025)
+v:set(2,0,0)
+--print("*** set advection speed to: v_x=" .. v:get(0,0) ..", v_y=" .. v:get(1,0) .. ", v_z=" .. v:get(2,0) .. "  ***")
+law = dgConservationLawAdvectionDiffusion(functionConstant(v):getName(),'')
+dg:setConservationLaw(law)
+
+print("*** set boundary conditions *** ")
+-- boundary condition
+outside=fullMatrix(1,1)
+outside:set(0,0,0.0)
+bndcondition=law:newOutsideValueBoundary(functionConstant(outside):getName())
+law:addBoundaryCondition('Border',bndcondition)
+
+--dg:setup()
+-- create 2 groups of elements; criterion=maxEdge 
+dg:createGroups("maxEdge")
+-- dg:createGroups("minEdge")
+-- dg:createGroups("elementType")
+
+dg:L2Projection(functionLua(1,'initial_condition',{'XYZ'}):getName())
+
+dg:exportSolution('output/Advection_00000')
+
+dg:computeInvSpectralRadius();
+T=40
+dt=0.1
+
+print("***     default time step (dt)=" .. dt .. ",  Period (T)=" ..T .."    ***")
+
+N=T/dt
+print("***     Number of time steps=" .. N .. "          ***")
+-- main loop
+for i=1,N do
+  norm = dg:multirateRK43(dt)
+    print('iter',i,norm)
+  if (i % 20 == 0) then 
+    dg:exportSolution(string.format("output/Advection_%05d", i)) 
+  end
+end
+print '*** adding the mesh and the model ***'
diff --git a/Solver/TESTCASES/square_m.geo b/Solver/TESTCASES/square_m.geo
new file mode 100644
index 0000000000000000000000000000000000000000..808e014b8ad7fcf76dd04d90ecd05dae1de830eb
--- /dev/null
+++ b/Solver/TESTCASES/square_m.geo
@@ -0,0 +1,15 @@
+Point(1) = {-0.5, -0.5, 0, 0.025};
+Point(2) = {0.5, -0.5, 0, 0.025};
+Point(3) = {0.5, 0.5, 0, 0.125};
+Point(4) = {-0.5, 0.5, 0, 0.125};
+Line(1) = {4, 3};
+Line(2) = {3, 2};
+Line(3) = {2, 1};
+Line(4) = {1, 4};
+Line Loop(5) = {2, 3, 4, 1};
+Plane Surface(6) = {5};
+Physical Line("Border") = {1, 2, 3, 4};
+Physical Surface("Inside") = {6};
+//Mesh.CharacteristicLengthExtendFromBoundary=1;
+//Transfinite Line {1, 2, 4, 3} = 20 Using Progression 1;
+//Transfinite Surface {6};
diff --git a/Solver/TESTCASES/square_p.geo b/Solver/TESTCASES/square_p.geo
new file mode 100644
index 0000000000000000000000000000000000000000..5426e6d6a87cee9ebc13e9739bc9cde356d07f8d
--- /dev/null
+++ b/Solver/TESTCASES/square_p.geo
@@ -0,0 +1,31 @@
+Point(1) = {-0.5, -0.5, 0, .03};
+Point(2) = {0, -0.5, 0, .03};
+Point(3) = {0, 0.5, 0, .03};
+Point(4) = {-0.5, 0.5, 0, .03};
+
+Point(5) = {0.5, -0.5, 0, .03};
+Point(6) = {0.5, 0.5, 0, .03};
+
+Line(1) = {4, 3};
+Line(2) = {3, 2};
+Line(3) = {2, 1};
+Line(4) = {1, 4};
+
+Line(7) = {3, 6};
+Line(8) = {6, 5};
+Line(9) = {5, 2};
+
+Line Loop(5) = {2, 3, 4, 1};
+Line Loop(6) = {8, 9, -2, 7};
+Plane Surface(7) = {5};
+Plane Surface(8) = {6};
+Transfinite Line {4,8} = 20 ;
+Transfinite Line{2}=20;
+Transfinite Surface {7};
+Recombine Surface {7};
+Transfinite Line {3,1,7,9} = 10;
+Transfinite Surface{8};
+
+Physical Line("Border") = {1, 3, 4, 7, 8, 9};
+Physical Surface("Inside1") = {7};
+Physical Surface("Inside2") = {8};
diff --git a/Solver/dgAlgorithm.cpp b/Solver/dgAlgorithm.cpp
index 8035d305338b5cefa2c20b75e02e06c052f66306..fde2d637dbc8dc0cf3db0cadefd615cc32749f70 100644
--- a/Solver/dgAlgorithm.cpp
+++ b/Solver/dgAlgorithm.cpp
@@ -357,9 +357,11 @@ void dgAlgorithm::multirateRungeKutta (const dgConservationLaw &claw,			// conse
 //   double b[4]={1.0/6.0, 1.0/3.0, 1.0/3.0, 1.0/6.0};
 //   double c[4]={0, 1.0/2.0, 1.0/2.0, 1};
    
-
+	 double A[10][10];
+	 double *b;
+	 double *c;
 // Small step RK43
-   double A[10][10]={
+   double A1[10][10]={
 {0,         0,         0,         0,         0,         0,         0,         0,         0,         0},
 {1.0/4.0   ,0,         0,         0,         0,         0,         0,         0,         0,         0},
 {-1.0/12.0, 1.0/3.0,   0,         0,         0,         0,         0,         0,         0,         0},
@@ -371,24 +373,24 @@ void dgAlgorithm::multirateRungeKutta (const dgConservationLaw &claw,			// conse
 {1.0/12.0,  1.0/6.0,   1.0/6.0,   1.0/12.0,  0,         1.0/6.0,   -1.0/6.0,  1.0/2.0,   0,         0},
 {1.0/12.0,  1.0/6.0,   1.0/6.0,   1.0/12.0,  0,         1.0/12.0,  1.0/6.0,   1.0/6.0,   1.0/12.0, 0}
    };
-   double b[10]={1.0/12.0, 1.0/6.0, 1.0/6.0,1.0/12.0,0,1.0/12.0, 1.0/6.0, 1.0/6.0,1.0/12.0,0};
-   double c[10]={0, 1.0/4.0, 1.0/4.0, 1.0/2.0, 1.0/2.0, 1.0/2.0, 3.0/4.0, 3.0/4.0, 1, 1 };
+   double b1[10]={1.0/12.0, 1.0/6.0, 1.0/6.0,1.0/12.0,0,1.0/12.0, 1.0/6.0, 1.0/6.0,1.0/12.0,0};
+   double c1[10]={0, 1.0/4.0, 1.0/4.0, 1.0/2.0, 1.0/2.0, 1.0/2.0, 3.0/4.0, 3.0/4.0, 1, 1 };
 
 // Big step RK43
-//   double A[10][10]={
-//{0,         0,         0,         0,         0,         0,         0,         0,         0,         0},
-//{1.0/4.0 ,  0,         0,         0,         0,         0,         0,         0,         0,         0},
-//{1.0/4.0 ,  0,         0,         0,         0,         0,         0,         0,         0,         0},
-//{1.0/2.0 ,  0,         0,         0,         0,         0,         0,         0,         0,         0},
-//{1.0/2.0 ,  0,         0,         0,         0,         0,         0,         0,         0,         0},
-//{-1.0/6.0,  0,         0,         0,         2.0/3.0,   0,         0,         0,         0,         0},
-//{1.0/12.0,  0,         0,         0,         1.0/6.0,   1.0/2.0,   0,         0,         0,         0},
-//{1.0/12.0,  0,         0,         0,         1.0/6.0,   1.0/2.0,   0,         0,         0,         0},
-//{1.0/3.0 ,  0,         0,         0,         -1.0/3.0,  1,         0,         0,         0,         0},
-//{1.0/3.0 ,  0,         0,         0,         -1.0/3.0,  1,         0,         0,         0,         0},
-//   };
-//   double b[10]={1.0/6.0, 0 , 0 , 0 , 1.0/3.0,1.0/3.0, 0 , 0 , 0 , 1.0/6.0};
-//   double c[10]={0, 1.0/4.0, 1.0/4.0, 1.0/2.0, 1.0/2.0, 1.0/2.0, 3.0/4.0, 3.0/4.0, 1, 1 };
+   double A2[10][10]={
+{0,         0,         0,         0,         0,         0,         0,         0,         0,         0},
+{1.0/4.0 ,  0,         0,         0,         0,         0,         0,         0,         0,         0},
+{1.0/4.0 ,  0,         0,         0,         0,         0,         0,         0,         0,         0},
+{1.0/2.0 ,  0,         0,         0,         0,         0,         0,         0,         0,         0},
+{1.0/2.0 ,  0,         0,         0,         0,         0,         0,         0,         0,         0},
+{-1.0/6.0,  0,         0,         0,         2.0/3.0,   0,         0,         0,         0,         0},
+{1.0/12.0,  0,         0,         0,         1.0/6.0,   1.0/2.0,   0,         0,         0,         0},
+{1.0/12.0,  0,         0,         0,         1.0/6.0,   1.0/2.0,   0,         0,         0,         0},
+{1.0/3.0 ,  0,         0,         0,         -1.0/3.0,  1,         0,         0,         0,         0},
+{1.0/3.0 ,  0,         0,         0,         -1.0/3.0,  1,         0,         0,         0,         0},
+   };
+   double b2[10]={1.0/6.0, 0 , 0 , 0 , 1.0/3.0,1.0/3.0, 0 , 0 , 0 , 1.0/6.0};
+   double c2[10]={0, 1.0/4.0, 1.0/4.0, 1.0/2.0, 1.0/2.0, 1.0/2.0, 3.0/4.0, 3.0/4.0, 1, 1 };
 
 
    // fullMatrix<double> K(sol);
@@ -410,11 +412,25 @@ void dgAlgorithm::multirateRungeKutta (const dgConservationLaw &claw,			// conse
 
    Unp.scale(0.0);
    Unp.axpy(sol);
-
+   // Case of 2 groups: first with big steps, second with small steps	 
    for(int j=0; j<nStages;j++){
      tmp.scale(0.0);
      tmp.axpy(sol);
      for(int k=0;k < groups.getNbElementGroups();k++) {
+		 if (k==0) {
+			 for (int ii=0; ii<10; ii++) {
+				 for (int jj=0; jj<10; jj++) {
+					 A[ii][jj]=A2[ii][jj];
+				 }
+			 }
+		 }
+		 else{
+			 for (int ii=0; ii<10; ii++) {
+				 for (int jj=0; jj<10; jj++) {
+					 A[ii][jj]=A1[ii][jj];
+				 }
+			 }
+		 }
        for(int i=0;i<j;i++){
          if(fabs(A[j][i])>1e-12){
            tmp.getGroupProxy(k).add(K[i]->getGroupProxy(k),h*A[j][i]);
@@ -423,6 +439,15 @@ void dgAlgorithm::multirateRungeKutta (const dgConservationLaw &claw,			// conse
      }
      this->residual(claw,groups,tmp,resd);
      for(int k=0;k < groups.getNbElementGroups(); k++) {
+		 if (k==0) {
+			 b=b2;
+			 c=c2;
+		 }
+		 else{
+			 b=b1;
+			 c=c1;
+		 }
+		 
        dgGroupOfElements *group = groups.getElementGroup(k);
        int nbNodes = group->getNbNodes();
        for(int i=0;i<group->getNbElements();i++) {
@@ -592,7 +617,7 @@ void dgAlgorithm::computeElementaryTimeSteps ( //dofManager &dof, // the DOF man
   // provided dataCache
   dataCacheDouble *maxConvectiveSpeed = claw.newMaxConvectiveSpeed(cacheMap);
   dataCacheDouble *maximumDiffusivity = claw.newMaximumDiffusivity(cacheMap);
-
+	
   const int nbFields = claw.nbFields();
   /* This is an estimate on how lengths changes with p 
      It is merely the smallest distance between gauss 
diff --git a/Solver/dgAlgorithm.h b/Solver/dgAlgorithm.h
index 25a37420ee7a09bad5ae1b97c4ebd9b36546770f..2baaa653050e6bba98074ec8004e68ec108e306a 100644
--- a/Solver/dgAlgorithm.h
+++ b/Solver/dgAlgorithm.h
@@ -51,6 +51,8 @@ class dgAlgorithm {
 					  fullMatrix<double> &solution, // the solution 
 					  std::vector<double> & DT // elementary time steps
 					   );
+  // works only (for the moment) for two groups of elements, small and big step
+  // Uses RK43 from Schlegel (10 stages)	
   void multirateRungeKutta (
 		   const dgConservationLaw &claw,
        dgGroupCollection &groups,
diff --git a/Solver/dgGroupOfElements.cpp b/Solver/dgGroupOfElements.cpp
index e9a3252442bd1b2a70eba3f4d432c522b0b08072..c897f2788733c2a66fb71c4a501602235475f5e5 100644
--- a/Solver/dgGroupOfElements.cpp
+++ b/Solver/dgGroupOfElements.cpp
@@ -700,8 +700,8 @@ void dgGroupCollection::buildGroups(GModel *model, int dim, int order)
       }
     }
   }
-
-
+	
+	
   Msg::Info("%d groups of elements",localElements.size());
   // do a group of elements for every element type in the mesh
   for (std::map<int, std::vector<MElement *> >::iterator it = localElements.begin(); it !=localElements.end() ; ++it){
@@ -838,6 +838,248 @@ void dgGroupCollection::buildGroups(GModel *model, int dim, int order)
   delete []shiftRecv;
 }
 
+
+void dgGroupCollection::buildGroups(GModel *model, int dim, int order,std::string groupType)
+{
+	_model = model;
+	std::map<const std::string,std::set<MVertex*> > boundaryVertices;
+	std::map<const std::string,std::set<MEdge, Less_Edge> > boundaryEdges;
+	std::map<const std::string,std::set<MFace, Less_Face> > boundaryFaces;
+	std::vector<GEntity*> entities;
+	model->getEntities(entities);
+	std::map<int, std::vector<MElement *> >localElements;
+	std::vector<std::map<int, std::vector<MElement *> > >ghostElements(Msg::GetCommSize()); // [partition][elementType]
+	int nlocal=0;
+	int nghosts=0;
+	std::multimap<MElement*, short> &ghostsCells = model->getGhostCells();
+	for(unsigned int i = 0; i < entities.size(); i++){
+		GEntity *entity = entities[i];
+		if(entity->dim() == dim-1){
+			for(unsigned int j = 0; j < entity->physicals.size(); j++){
+				const std::string physicalName = model->getPhysicalName(entity->dim(), entity->physicals[j]);
+				for (int k = 0; k < entity->getNumMeshElements(); k++) {
+					MElement *element = entity->getMeshElement(k);
+					switch(dim) {
+						case 1:
+							boundaryVertices[physicalName].insert( element->getVertex(0) ); 
+							break;
+						case 2:
+							boundaryEdges[physicalName].insert( element->getEdge(0) );
+							break;
+						case 3:
+							boundaryFaces[physicalName].insert( element->getFace(0));
+							break;
+						default :
+							throw;
+					}
+				}
+			}
+		}else if(entity->dim() == dim){
+			double max_edgeM=-1.e22;
+			double max_edgem=1.e22;
+			double min_edgeM=-1.e22;
+			double min_edgem=1.e22;
+			
+			for (int iel=0; iel<entity->getNumMeshElements(); iel++){
+				MElement *el=entity->getMeshElement(iel);
+				if (el->maxEdge()>max_edgeM) {
+					max_edgeM=el->maxEdge();
+				}
+				if (el->maxEdge()<max_edgem) {
+					max_edgem=el->maxEdge();
+				}
+				if (el->minEdge()>min_edgeM) {
+					min_edgeM=el->minEdge();
+				}
+				if (el->minEdge()<min_edgeM) {
+					min_edgem=el->minEdge();
+				}									
+			}
+			//printf("\n a1=%f, a2=%f \n",(min_edgeM+min_edgem)/2.,(max_edgeM+max_edgem)/2.);
+			for (int iel=0; iel<entity->getNumMeshElements(); iel++){
+				MElement *el=entity->getMeshElement(iel);
+				if(el->getPartition()==Msg::GetCommRank()+1 || el->getPartition()==0){
+					
+					if (groupType=="minEdge") {
+							if (el->minEdge()> (min_edgeM+min_edgem)/2.) {
+							 localElements[0].push_back(el);
+							 }
+							 else{
+							 localElements[1].push_back(el);
+							 }
+					}
+					else if(groupType=="maxEdge"){
+							if (el->maxEdge()> (max_edgeM+max_edgem)/2.) {
+							 localElements[0].push_back(el);
+							}
+							else{
+							 localElements[1].push_back(el);
+							}
+						
+					}
+					else{
+							localElements[el->getType()].push_back(el);
+					}
+
+					
+					nlocal++;
+				}else{
+					std::multimap<MElement*, short>::iterator ghost=ghostsCells.lower_bound(el);
+					while(ghost!= ghostsCells.end() && ghost->first==el){
+						if(abs(ghost->second)-1==Msg::GetCommRank()){
+							ghostElements[el->getPartition()-1][el->getType()].push_back(el);
+							nghosts+=1;
+						}
+						ghost++;
+					}
+				}
+			}
+		}
+	}
+	
+	
+	Msg::Info("%d groups of elements",localElements.size());
+	for (int n=0; n<localElements.size(); n++) {
+		printf("\n **** Group %d: %d elements **** \n", n,localElements[n].size());
+	}
+	// do a group of elements for every element type in the mesh
+	for (std::map<int, std::vector<MElement *> >::iterator it = localElements.begin(); it !=localElements.end() ; ++it){
+		_elementGroups.push_back(new dgGroupOfElements(it->second,order));
+	}
+	
+	
+	for (int i=0;i<_elementGroups.size();i++){
+		// create a group of faces on the boundary for every group ef elements
+		switch(dim) {
+			case 1 : {
+				std::map<const std::string, std::set<MVertex*> >::iterator mapIt;
+				for(mapIt=boundaryVertices.begin(); mapIt!=boundaryVertices.end(); mapIt++) {
+					dgGroupOfFaces *gof = new dgGroupOfFaces(*_elementGroups[i],mapIt->first,order,mapIt->second);
+					if (gof->getNbElements())
+						_boundaryGroups.push_back(gof);
+					else
+						delete gof;
+					break;
+				}
+			}
+			case 2 : {
+				std::map<const std::string, std::set<MEdge, Less_Edge> >::iterator mapIt;
+				for(mapIt=boundaryEdges.begin(); mapIt!=boundaryEdges.end(); mapIt++) {
+					dgGroupOfFaces *gof=new dgGroupOfFaces(*_elementGroups[i],mapIt->first,order,mapIt->second);
+					if(gof->getNbElements())
+						_boundaryGroups.push_back(gof);
+					else
+						delete gof;
+				}
+				break;
+			}
+			case 3 : {
+				std::map<const std::string, std::set<MFace, Less_Face> >::iterator mapIt;
+				for(mapIt=boundaryFaces.begin(); mapIt!=boundaryFaces.end(); mapIt++) {
+					dgGroupOfFaces *gof=new dgGroupOfFaces(*_elementGroups[i],mapIt->first,order,mapIt->second);
+					if(gof->getNbElements())
+						_boundaryGroups.push_back(gof);
+					else
+						delete gof;
+				}
+				break;
+			}
+		}
+		// create a group of faces for every face that is common to elements of the same group 
+		_faceGroups.push_back(new dgGroupOfFaces(*_elementGroups[i],order));
+		// create a groupe of d
+		for (int j=i+1;j<_elementGroups.size();j++){
+			dgGroupOfFaces *gof = new dgGroupOfFaces(*_elementGroups[i],*_elementGroups[j],order);
+			if (gof->getNbElements())
+				_faceGroups.push_back(gof);
+			else
+				delete gof;
+		}
+	}
+	//create ghost groups
+	for(int i=0;i<Msg::GetCommSize();i++){
+		for (std::map<int, std::vector<MElement *> >::iterator it = ghostElements[i].begin(); it !=ghostElements[i].end() ; ++it){
+			_ghostGroups.push_back(new dgGroupOfElements(it->second,order,i));
+		}
+	}
+	//create face group for ghostGroups
+	for (int i=0; i<_ghostGroups.size(); i++){
+		for (int j=0;j<_elementGroups.size();j++){
+			dgGroupOfFaces *gof = new dgGroupOfFaces(*_ghostGroups[i],*_elementGroups[j],order);
+			if (gof->getNbElements())
+				_faceGroups.push_back(gof);
+			else
+				delete gof;
+		}
+	}
+	
+	// build the ghosts structure
+	int *nGhostElements = new int[Msg::GetCommSize()];
+	int *nParentElements = new int[Msg::GetCommSize()];
+	for (int i=0;i<Msg::GetCommSize();i++) {
+		nGhostElements[i]=0;
+	}
+	for (size_t i = 0; i< getNbGhostGroups(); i++){
+		dgGroupOfElements *group = getGhostGroup(i);
+		nGhostElements[group->getGhostPartition()] += group->getNbElements();
+	}
+#ifdef HAVE_MPI
+	MPI_Alltoall(nGhostElements,1,MPI_INT,nParentElements,1,MPI_INT,MPI_COMM_WORLD); 
+#else
+	nParentElements[0]=nGhostElements[0];
+#endif
+	int *shiftSend = new int[Msg::GetCommSize()];
+	int *shiftRecv = new int[Msg::GetCommSize()];
+	int *curShiftSend = new int[Msg::GetCommSize()];
+	int totalSend=0,totalRecv=0;
+	for(int i= 0; i<Msg::GetCommSize();i++){
+		shiftSend[i] = (i==0 ? 0 : shiftSend[i-1]+nGhostElements[i-1]);
+		curShiftSend[i] = shiftSend[i];
+		shiftRecv[i] = (i==0 ? 0 : shiftRecv[i-1]+nParentElements[i-1]);
+		totalSend += nGhostElements[i];
+		totalRecv += nParentElements[i];
+	}
+	
+	int *idSend = new int[totalSend];
+	int *idRecv = new int[totalRecv];
+	for (int i = 0; i<getNbGhostGroups(); i++){
+		dgGroupOfElements *group = getGhostGroup(i);
+		int part = group->getGhostPartition();
+		for (int j=0; j< group->getNbElements() ; j++){
+			idSend[curShiftSend[part]++] = group->getElement(j)->getNum();
+		}
+	}
+#ifdef HAVE_MPI
+	MPI_Alltoallv(idSend,nGhostElements,shiftSend,MPI_INT,idRecv,nParentElements,shiftRecv,MPI_INT,MPI_COMM_WORLD);
+#else
+	memcpy(idRecv,idSend,nParentElements[0]*sizeof(int));
+#endif
+	//create a Map elementNum :: group, position in group
+	std::map<int, std::pair<int,int> > elementMap;
+	for(size_t i = 0; i< getNbElementGroups(); i++) {
+		dgGroupOfElements *group = getElementGroup(i);
+		for(int j=0; j< group->getNbElements(); j++){
+			elementMap[group->getElement(j)->getNum()]=std::pair<int,int>(i,j);
+		}
+	}
+	_elementsToSend.resize(Msg::GetCommSize());
+	for(int i = 0; i<Msg::GetCommSize();i++){
+		_elementsToSend[i].resize(nParentElements[i]);
+		for(int j=0;j<nParentElements[i];j++){
+			int num = idRecv[shiftRecv[i]+j];
+			_elementsToSend[i][j]=elementMap[num];
+		}
+	}
+	delete []idRecv;
+	delete []idSend;
+	delete []curShiftSend;
+	delete []shiftSend;
+	delete []shiftRecv;
+}
+
+
+
+
 dgGroupCollection::~dgGroupCollection() {
   for (int i=0; i< _elementGroups.size(); i++)
     delete _elementGroups[i];
diff --git a/Solver/dgGroupOfElements.h b/Solver/dgGroupOfElements.h
index 0b9be6a2d1ac8da1478369df631f5ea7f1b9a657..3452aa31d458ac13bb2b2ba6234999f7c253231e 100644
--- a/Solver/dgGroupOfElements.h
+++ b/Solver/dgGroupOfElements.h
@@ -208,6 +208,7 @@ class dgGroupCollection {
   inline int getImageElementPositionInGroup(int partId, int i) const {return _elementsToSend[partId][i].second;}
 
   void buildGroups (GModel *model,int dimension, int order);
+  void buildGroups (GModel *model,int dimension, int order, std::string groupType);
   ~dgGroupCollection();
 };
 #endif
diff --git a/Solver/dgSlopeLimiter.cpp b/Solver/dgSlopeLimiter.cpp
index 814cb566b262eaaa0bb1f3fd48610e0380192e78..adcdd9355df4d6aeaf6379a1bbf25386ed61766c 100644
--- a/Solver/dgSlopeLimiter.cpp
+++ b/Solver/dgSlopeLimiter.cpp
@@ -14,7 +14,7 @@ bool dgSlopeLimiter::apply ( dgDofContainer &solution, dgGroupCollection &groups
   fullMatrix<double> &solright = solution.getGroupProxy(0); 
   int nbFields =_claw->nbFields();    
   int totNbElems = solution.getNbElements();
-
+	
   // first compute max and min of all fields for all stencils    
   //----------------------------------------------------------   
 
@@ -32,7 +32,7 @@ bool dgSlopeLimiter::apply ( dgDofContainer &solution, dgGroupCollection &groups
     fullMatrix<double> TempL, TempR;
     TempL.setAsProxy(solleft, nbFields*iElementL, nbFields );
     TempR.setAsProxy(solright, nbFields*iElementR, nbFields );    	
-    
+	  
     fSize = TempL.size1(); 
     for (int k=0; k< nbFields; ++k){    
       double AVGL = 0;  
diff --git a/Solver/dgSystemOfEquations.cpp b/Solver/dgSystemOfEquations.cpp
index 68cfdb03a501d71d0c225320fb3e4cd5b52aeab8..29af76404b3f27e5afc402f11c5cb5dd14656ecf 100644
--- a/Solver/dgSystemOfEquations.cpp
+++ b/Solver/dgSystemOfEquations.cpp
@@ -58,6 +58,9 @@ void dgSystemOfEquations::registerBindings(binding *b) {
   cm->setDescription("set the conservation law this system solves");
   cm = cb->addMethod("setup",&dgSystemOfEquations::setup);
   cm->setDescription("allocate and init internal stuff, call this function after setOrder and setLaw and before anything else on this instance");
+  cm = cb->addMethod("createGroups",&dgSystemOfEquations::createGroups);
+  cm->setArgNames("groupType",NULL);
+  cm->setDescription("allocate and init internal stuff, creates groups form criterion groupType");
   cm = cb->addMethod("exportSolution",&dgSystemOfEquations::exportSolution);
   cm->setArgNames("filename",NULL);
   cm->setDescription("Print the solution into a file. This file does not contain the mesh. To visualize the solution in gmsh you have to open the mesh file first.");
@@ -101,6 +104,16 @@ void dgSystemOfEquations::L2Projection (std::string functionName){
   }
 }
 
+// dgSystemOfEquations::setup() + build groups with criterion:
+// - default: elementType
+// - minEdge (based on minimum edges of elements) , for the moment only two groups possible
+// - maxEdge (based on maximum edges of elements) , for the moment only two groups possible
+void dgSystemOfEquations::createGroups(std::string groupType){
+	_groups.buildGroups(_gm,_dimension,_order,groupType);
+	_solution = new dgDofContainer(_groups,_claw->nbFields());
+	_rightHandSide = new dgDofContainer(_groups,_claw->nbFields());
+	}
+	
 // ok, we can setup the groups and create solution vectors
 void dgSystemOfEquations::setup(){
   if (!_claw) throw;
diff --git a/Solver/dgSystemOfEquations.h b/Solver/dgSystemOfEquations.h
index fdb887dc933e4232f9b07dd945654a6c8c44e914..85625e8eea32ed15ae837e997ded85d6f461fe62 100644
--- a/Solver/dgSystemOfEquations.h
+++ b/Solver/dgSystemOfEquations.h
@@ -42,6 +42,7 @@ public:
   void setOrder (int order); // set the polynomial order
   void setConservationLaw (dgConservationLaw *law); // set the conservationLaw
   dgSystemOfEquations(GModel *_gm);
+  void createGroups(std::string groupType); // create groups from criterion: minEdge (2 groups), maxEdge (2 groups), elementType, allocate (same as setup())
   void setup (); // setup the groups and allocate
   void exportSolution (std::string filename); // export the solution
   void limitSolution (); // apply the limiter on the solution