diff --git a/Geo/CellComplex.cpp b/Geo/CellComplex.cpp
index 74abf563ac22c3cca4abe63f683349a9a1dcce1e..87b9526a47cbaec00c0434ada0d352a253cc783a 100644
--- a/Geo/CellComplex.cpp
+++ b/Geo/CellComplex.cpp
@@ -18,6 +18,8 @@ CellComplex::CellComplex(GModel* model,
   _model(model), _dim(0), _simplicial(true), _saveorig(saveOriginalComplex),
   _relative(false)
 {
+  _smallestCell.second = -1.;
+  _biggestCell.second = -1.;
   _deleteCount = 0;
   _createCount = 0;
   _insertCells(subdomainElements, 1);
@@ -62,8 +64,17 @@ CellComplex::CellComplex(GModel* model,
 bool CellComplex::_insertCells(std::vector<MElement*>& elements,
 			       int domain)
 {
+  std::pair<Cell*, double> smallestElement[4];
+  std::pair<Cell*, double> biggestElement[4];
+  for(int i = 0; i < 4; i++) {
+    smallestElement[i].second = -1.;
+    biggestElement[i].second = -1.;
+  }
+  _dim = 0;
+
   for(unsigned int i=0; i < elements.size(); i++){
     MElement* element = elements.at(i);
+    int dim = element->getDim();
     int type = element->getType();
     if(type == TYPE_PYR || type == TYPE_PRI ||
        type == TYPE_POLYG || type == TYPE_POLYH) {
@@ -77,6 +88,8 @@ bool CellComplex::_insertCells(std::vector<MElement*>& elements,
       delete maybeCell.first;
       continue;
     }
+
+    if(_dim < dim) _dim = dim;
     Cell* cell = maybeCell.first;
     std::pair<citer, bool> insert =
       _cells[cell->getDim()].insert(cell);
@@ -86,7 +99,17 @@ bool CellComplex::_insertCells(std::vector<MElement*>& elements,
       if(domain) cell->setDomain(domain);
     }
     else _createCount++;
+
+    if(domain == 0) {
+      double size = fabs(element->getVolume());
+      if(smallestElement[dim].second < 0. || smallestElement[dim].second > size)
+        smallestElement[dim] = std::make_pair(cell, size);
+      if(biggestElement[dim].second < 0. || biggestElement[dim].second < size)
+        biggestElement[dim] = std::make_pair(cell, size);
+    }
   }
+  _smallestCell = smallestElement[_dim];
+  _biggestCell = biggestElement[_dim];
 
   for (int dim = 3; dim > 0; dim--){
     for(citer cit = firstCell(dim); cit != lastCell(dim); cit++){
@@ -109,6 +132,10 @@ bool CellComplex::_insertCells(std::vector<MElement*>& elements,
 	if(domain == 0) {
 	  int ori = cell->findBdCellOrientation(newCell, i);
 	  cell->addBoundaryCell( ori, newCell, true);
+          if(_smallestCell.first == cell)
+            _smallestCell = std::make_pair(newCell, _smallestCell.second);
+          if(_biggestCell.first == cell)
+            _biggestCell = std::make_pair(newCell, _biggestCell.second);
 	}
       }
     }
@@ -508,7 +535,7 @@ void CellComplex::removeCells(int dim)
   _reduced = true;
 }
 
-int CellComplex::coreduceComplex(int combine, bool omit)
+int CellComplex::coreduceComplex(int combine, bool omit, int heuristic)
 {
   Msg::Debug("Cell Complex coreduction:");
   Msg::Debug(" %d volumes, %d faces, %d edges, and %d vertices",
@@ -537,9 +564,23 @@ int CellComplex::coreduceComplex(int combine, bool omit)
 
     std::vector<Cell*> newCells;
     while (getSize(0) != 0){
+
       citer cit = firstCell(0);
       Cell* cell = *cit;
 
+      if(heuristic == -1 && _smallestCell.second != 0. &&
+         hasCell(_smallestCell.first)) {
+        Msg::Debug("Omitted a cell in the smallest mesh element with volume %g",
+                   _smallestCell.second);
+        cell = _smallestCell.first;
+      }
+      else if(heuristic == 1 && _biggestCell.second != 0. &&
+              hasCell(_biggestCell.first)) {
+        Msg::Debug("Omitted a cell in the biggest mesh element with volume %g",
+                   _biggestCell.second);
+        cell = _biggestCell.first;
+      }
+
       newCells.push_back(_omitCell(cell, true));
     }
     for(unsigned int i = 0; i < newCells.size(); i++){
@@ -599,7 +640,7 @@ int CellComplex::combine(int dim)
            inSameDomain(s, c1) && inSameDomain(s, c2) &&
            c1->getImmune() == c2->getImmune() ) {
 
-          removeCell(s, true, true);
+          removeCell(s, true, false);
 
           c1->getBoundary(bd_c);
           enqueueCells(bd_c, Q, Qset);
@@ -615,10 +656,6 @@ int CellComplex::combine(int dim)
           cit = firstCell(dim);
           count++;
 
-          if(s->isCombined()) {
-            delete s;
-            _deleteCount++;
-          }
           if(c1->isCombined()) {
             delete c1;
             _deleteCount++;
@@ -656,6 +693,7 @@ int CellComplex::cocombine(int dim)
 
   for(citer cit = firstCell(dim); cit != lastCell(dim); cit++){
     Cell* cell = *cit;
+
     cell->getCoboundary(cbd_c);
     enqueueCells(cbd_c, Q, Qset);
 
@@ -674,7 +712,8 @@ int CellComplex::cocombine(int dim)
 
         if(!(*c1 == *c2) && abs(or1) == abs(or2)
            && inSameDomain(s, c1) && inSameDomain(s, c2)){
-	  removeCell(s, true, true);
+
+          removeCell(s, true, false);
 
           c1->getCoboundary(cbd_c);
           enqueueCells(cbd_c, Q, Qset);
@@ -691,10 +730,6 @@ int CellComplex::cocombine(int dim)
           cit = firstCell(dim);
           count++;
 
-          if(s->isCombined()) {
-            delete s;
-            _deleteCount++;
-          }
           if(c1->isCombined()) {
             delete c1;
             _deleteCount++;
diff --git a/Geo/CellComplex.h b/Geo/CellComplex.h
index d8b97eb8b3f788655f97c10faa4e92f08bfd3a83..e75c8c3d65ce4b0ab83605e0e4b2b29d715a1057 100644
--- a/Geo/CellComplex.h
+++ b/Geo/CellComplex.h
@@ -25,6 +25,10 @@ class CellComplex
 {
  private:
 
+
+  std::pair<Cell*, double> _smallestCell;
+  std::pair<Cell*, double> _biggestCell;
+
   GModel* _model;
 
   // sorted containers of unique cells in this cell complex
@@ -158,8 +162,11 @@ class CellComplex
   // (combine = 1 -> with combining)
   // (omit = true -> with highest dimensional cell omitting?)
   // (homseq = true -> homology sequence splitting possible after reduction)
+  // (heuristic =  0 -> no heuristic, let mesh indexing determine
+  //               1 -> omit 0-cell in biggest element
+  //              -1 -> omit 0-cell in smallest element)
   int reduceComplex(int combine=1, bool omit=true, bool homseq=false);
-  int coreduceComplex(int combine=1, bool omit=true);
+  int coreduceComplex(int combine=1, bool omit=true, int heuristic=0);
 
   bool isReduced() const { return _reduced; }
 
diff --git a/Geo/Homology.cpp b/Geo/Homology.cpp
index 19c943ac721d9f0420b7bcf24b399d3895b44c3f..6ec9f1e218e4e7aeff96db8360dfc28ae43d9938 100644
--- a/Geo/Homology.cpp
+++ b/Geo/Homology.cpp
@@ -19,10 +19,11 @@ Homology::Homology(GModel* model,
 		   std::vector<int> physicalSubdomain,
                    std::vector<int> physicalImdomain,
                    bool saveOrig,
-		   int combine, bool omit, bool smoothen) :
+		   int combine, bool omit, bool smoothen, int heuristic) :
   _model(model), _domain(physicalDomain), _subdomain(physicalSubdomain),
   _imdomain(physicalImdomain), _saveOrig(saveOrig),
-  _combine(combine), _omit(omit), _smoothen(smoothen), _cellComplex(NULL)
+  _combine(combine), _omit(omit), _smoothen(smoothen),
+  _heuristic(heuristic), _cellComplex(NULL)
 {
   _fileName = "";
 
@@ -49,6 +50,9 @@ Homology::Homology(GModel* model,
     _cohomologyComputed[i] = false;
     _betti[i] = -1;
   }
+
+  if(abs(_heuristic) > 1) _heuristic = 0;
+
 }
 
 void Homology::_getEntities(const std::vector<int>& physicalGroups,
@@ -257,7 +261,7 @@ void Homology::findCohomologyBasis(std::vector<int> dim)
 
   double t1 = Cpu();
 
-  int omitted = _cellComplex->coreduceComplex(_combine, _omit);
+  int omitted = _cellComplex->coreduceComplex(_combine, _omit, _heuristic);
 
   std::sort(dim.begin(), dim.end());
   if(!dim.empty()  && _combine > 1) {
diff --git a/Geo/Homology.h b/Geo/Homology.h
index 386e6a7e7f122d448a4d6588b1b462079de87a62..99241b0292ff22dddbe0f367bb160a18d4b8f86f 100644
--- a/Geo/Homology.h
+++ b/Geo/Homology.h
@@ -49,6 +49,8 @@ class Homology
   bool _omit;
   // use chain smoothning
   bool _smoothen;
+  // corecution heuristic
+  int _heuristic;
 
   // file name to store the results
   std::string _fileName;
@@ -93,7 +95,8 @@ class Homology
 	   std::vector<int> physicalSubdomain,
            std::vector<int> physicalIm,
            bool saveOrig=true,
-	   int combine=2, bool omit=true, bool smoothen=true);
+	   int combine=2, bool omit=true, bool smoothen=true,
+           int heuristic=1);
   ~Homology();
 
   GModel* getModel() const { return _model; }
diff --git a/Plugin/HomologyComputation.cpp b/Plugin/HomologyComputation.cpp
index e3794c78d4521336fdb3f6daf6368d0b306d2e27..24dbb8e7db03fe3f87d1c334fdd5f45336065661 100644
--- a/Plugin/HomologyComputation.cpp
+++ b/Plugin/HomologyComputation.cpp
@@ -25,7 +25,8 @@ StringXNumber HomologyComputationOptions_Number[] = {
   {GMSH_FULLRC, "CreatePostProcessingViews", NULL, 1.},
   {GMSH_FULLRC, "ReductionOmit", NULL, 1.},
   {GMSH_FULLRC, "ReductionCombine", NULL, 2.},
-  {GMSH_FULLRC, "PostProcessSimplify", NULL, 1.}
+  {GMSH_FULLRC, "PostProcessSimplify", NULL, 1.},
+  {GMSH_FULLRC, "ReductionHeuristic", NULL, 1.}
 };
 
 StringXString HomologyComputationOptions_String[] = {
@@ -111,6 +112,7 @@ PView *GMSH_HomologyComputationPlugin::execute(PView *v)
   bool omit = (bool)HomologyComputationOptions_Number[5].def;
   int combine = (int)HomologyComputationOptions_Number[6].def;
   bool smoothen = (bool)HomologyComputationOptions_Number[7].def;
+  int heuristic = (int)HomologyComputationOptions_Number[8].def;
 
   std::vector<int> domain;
   std::vector<int> subdomain;
@@ -124,7 +126,7 @@ PView *GMSH_HomologyComputationPlugin::execute(PView *v)
   GModel* m = GModel::current();
 
   Homology* homology = new Homology(m, domain, subdomain, imdomain,
-                                    true, combine, omit, smoothen);
+                                    true, combine, omit, smoothen, heuristic);
   homology->setFileName(fileName);
 
   if(hom != 0) homology->findHomologyBasis(dimsave);