diff --git a/Geo/CellComplex.cpp b/Geo/CellComplex.cpp
index ecf672d2f9e7737156915d9983cf4e5e6290954c..cee51bcecc45f1bbd6d78d0a21ec2d79ca314de7 100644
--- a/Geo/CellComplex.cpp
+++ b/Geo/CellComplex.cpp
@@ -658,6 +658,7 @@ int CellComplex::combine(int dim){
         replaceCells(c1, c2, newCell, (or1 != or2));
         
         cit = firstCell(dim);
+        //cit++;
         count++;
       }
       removeCellQset(s, Qset);
diff --git a/Geo/ChainComplex.cpp b/Geo/ChainComplex.cpp
index 876f9ae76aff53451da2f5872abf42ee7a2a694b..769e610b4d50eaeb334f063c1f2670dcd1569638 100644
--- a/Geo/ChainComplex.cpp
+++ b/Geo/ChainComplex.cpp
@@ -275,16 +275,14 @@ void ChainComplex::Quotient(int dim){
   
   mpz_t elem;
   mpz_init(elem);
-
+    
   for(int i = 1; i <= cols; i++){
     gmp_matrix_get_elem(elem, i, i, normalForm->canonical);
     if(mpz_cmp_si(elem,0) == 0){
       destroy_gmp_normal_form(normalForm);
       return;
     }
-    if(mpz_cmp_si(elem,1) > 0){
-      _torsion[dim].push_back(mpz_get_si(elem));
-    }
+    if(mpz_cmp_si(elem,1) > 0) _torsion[dim].push_back(mpz_get_si(elem));
   }
   
   int rank = cols - _torsion[dim].size();
@@ -437,7 +435,15 @@ std::vector<int> ChainComplex::getCoeffVector(int dim, int chainNumber){
   
 }
 
-Chain::Chain(std::set<Cell*, Less_Cell> cells, std::vector<int> coeffs, CellComplex* cellComplex, std::string name){
+int ChainComplex::getTorsion(int dim, int chainNumber){
+  if(dim < 0 || dim > 4) return 0;
+  if(_Hbasis[dim] == NULL || gmp_matrix_cols(_Hbasis[dim]) < chainNumber) return 0;
+  if(_torsion[dim].empty() || _torsion[dim].size() < chainNumber) return 1;
+  else return _torsion[dim].at(chainNumber-1);
+  
+}
+
+Chain::Chain(std::set<Cell*, Less_Cell> cells, std::vector<int> coeffs, CellComplex* cellComplex, std::string name, int torsion){
   
   int i = 0;
   for(std::set<Cell*, Less_Cell>::iterator cit = cells.begin(); cit != cells.end(); cit++){
@@ -448,9 +454,9 @@ Chain::Chain(std::set<Cell*, Less_Cell> cells, std::vector<int> coeffs, CellComp
     }
     
   }
-  
   _name = name;
   _cellComplex = cellComplex;
+  _torsion = torsion;
   
 }
 
diff --git a/Geo/ChainComplex.h b/Geo/ChainComplex.h
index 558cc50cd5f41253c8b86c5d18bc6ee27c5ee136..f5569a52d502d473d622d59d1c32b4c513eb8250 100644
--- a/Geo/ChainComplex.h
+++ b/Geo/ChainComplex.h
@@ -53,19 +53,19 @@ class ChainComplex{
    CellComplex* _cellComplex;
    
    // set the matrices
-   virtual void setHMatrix(int dim, gmp_matrix* matrix) { if(dim > -1 && dim < 5) _HMatrix[dim] = matrix;}
-   virtual void setKerHMatrix(int dim, gmp_matrix* matrix) { if(dim > -1 && dim < 5)  _kerH[dim] = matrix;}
-   virtual void setCodHMatrix(int dim, gmp_matrix* matrix) { if(dim > -1 && dim < 5)  _codH[dim] = matrix;}
-   virtual void setJMatrix(int dim, gmp_matrix* matrix) { if(dim > -1 && dim < 5)  _JMatrix[dim] = matrix;}
-   virtual void setQMatrix(int dim, gmp_matrix* matrix) { if(dim > -1 && dim < 5)  _QMatrix[dim] = matrix;}
-   virtual void setHbasis(int dim, gmp_matrix* matrix) { if(dim > -1 && dim < 5) _Hbasis[dim] = matrix;}
+   void setHMatrix(int dim, gmp_matrix* matrix) { if(dim > -1 && dim < 5) _HMatrix[dim] = matrix;}
+   void setKerHMatrix(int dim, gmp_matrix* matrix) { if(dim > -1 && dim < 5)  _kerH[dim] = matrix;}
+   void setCodHMatrix(int dim, gmp_matrix* matrix) { if(dim > -1 && dim < 5)  _codH[dim] = matrix;}
+   void setJMatrix(int dim, gmp_matrix* matrix) { if(dim > -1 && dim < 5)  _JMatrix[dim] = matrix;}
+   void setQMatrix(int dim, gmp_matrix* matrix) { if(dim > -1 && dim < 5)  _QMatrix[dim] = matrix;}
+   void setHbasis(int dim, gmp_matrix* matrix) { if(dim > -1 && dim < 5) _Hbasis[dim] = matrix;}
    
    
    
   public:
    
    ChainComplex(CellComplex* cellComplex);
-      
+   
    ChainComplex(){
      for(int i = 0; i < 5; i++){
        _HMatrix[i] = create_gmp_matrix_zero(1,1);
@@ -77,43 +77,44 @@ class ChainComplex{
      }
      _dim = 0;
    }
-   virtual ~ChainComplex(){}
+   ~ChainComplex(){}
    
-   virtual int getDim() { return _dim; }
+   int getDim() { return _dim; }
    
    // get the boundary operator matrix dim->dim-1
-   virtual gmp_matrix* getHMatrix(int dim) { if(dim > -1 && dim < 5) return _HMatrix[dim]; else return NULL;}
-   virtual gmp_matrix* getKerHMatrix(int dim) { if(dim > -1 && dim < 5) return _kerH[dim]; else return NULL;}
-   virtual gmp_matrix* getCodHMatrix(int dim) { if(dim > -1 && dim < 5) return _codH[dim]; else return NULL;}
-   virtual gmp_matrix* getJMatrix(int dim) { if(dim > -1 && dim < 5) return _JMatrix[dim]; else return NULL;}
-   virtual gmp_matrix* getQMatrix(int dim) { if(dim > -1 && dim < 5) return _QMatrix[dim]; else return NULL;}
-   virtual gmp_matrix* getHbasis(int dim) { if(dim > -1 && dim < 5) return _Hbasis[dim]; else return NULL;}
+   gmp_matrix* getHMatrix(int dim) { if(dim > -1 && dim < 5) return _HMatrix[dim]; else return NULL;}
+   gmp_matrix* getKerHMatrix(int dim) { if(dim > -1 && dim < 5) return _kerH[dim]; else return NULL;}
+   gmp_matrix* getCodHMatrix(int dim) { if(dim > -1 && dim < 5) return _codH[dim]; else return NULL;}
+   gmp_matrix* getJMatrix(int dim) { if(dim > -1 && dim < 5) return _JMatrix[dim]; else return NULL;}
+   gmp_matrix* getQMatrix(int dim) { if(dim > -1 && dim < 5) return _QMatrix[dim]; else return NULL;}
+   gmp_matrix* getHbasis(int dim) { if(dim > -1 && dim < 5) return _Hbasis[dim]; else return NULL;}
    
    // Compute basis for kernel and codomain of boundary operator matrix of dimension dim (ie. ker(h_dim) and cod(h_dim) )
-   virtual void KerCod(int dim);
+   void KerCod(int dim);
    // Compute matrix representation J for inclusion relation from dim-cells who are boundary of dim+1-cells 
    // to cycles of dim-cells (ie. j: cod(h_(dim+1)) -> ker(h_dim) )
-   virtual void Inclusion(int lowDim, int highDim);
+   void Inclusion(int lowDim, int highDim);
    // Compute quotient problem for given inclusion relation j to find representatives of homology groups
    // and possible torsion coeffcients
-   virtual void Quotient(int dim);
+   void Quotient(int dim);
    
    // transpose the boundary operator matrices, these are boundary operator matrices for the dual mesh
-   virtual void transposeHMatrices() { for(int i = 0; i < 5; i++) gmp_matrix_transp(_HMatrix[i]); }
-   virtual void transposeHMatrix(int dim) { if(dim > -1 && dim < 5) gmp_matrix_transp(_HMatrix[dim]); }
+   void transposeHMatrices() { for(int i = 0; i < 5; i++) gmp_matrix_transp(_HMatrix[i]); }
+   void transposeHMatrix(int dim) { if(dim > -1 && dim < 5) gmp_matrix_transp(_HMatrix[dim]); }
    
    // Compute bases for the homology groups of this chain complex 
-   virtual void computeHomology(bool dual=false);
+   void computeHomology(bool dual=false);
    
-   virtual std::vector<int> getCoeffVector(int dim, int chainNumber);
-   virtual int getBasisSize(int dim) {  if(dim > -1 && dim < 5) return gmp_matrix_cols(_Hbasis[dim]); else return 0; } 
+   std::vector<int> getCoeffVector(int dim, int chainNumber);
+   int getTorsion(int dim, int chainNumber);
+   int getBasisSize(int dim) {  if(dim > -1 && dim < 5) return gmp_matrix_cols(_Hbasis[dim]); else return 0; } 
    
-   virtual int printMatrix(gmp_matrix* matrix){ 
+   int printMatrix(gmp_matrix* matrix){ 
      printf("%d rows and %d columns\n", gmp_matrix_rows(matrix), gmp_matrix_cols(matrix)); 
      return gmp_matrix_printf(matrix); } 
-     
+   
    // debugging aid
-   virtual void matrixTest();
+   void matrixTest();
 };
 
 // A class representing a chain.
@@ -128,20 +129,24 @@ class Chain{
    // cell complex this chain belongs to
    CellComplex* _cellComplex;
    
+   int _torsion;
+   
   public:
    Chain(){}
-   Chain(std::set<Cell*, Less_Cell> cells, std::vector<int> coeffs, CellComplex* cellComplex, std::string name="Chain");
+   Chain(std::set<Cell*, Less_Cell> cells, std::vector<int> coeffs, CellComplex* cellComplex, std::string name="Chain", int torsion=0);
    ~Chain(){}
    
    // get i:th cell of this chain
-   virtual Cell* getCell(int i) { return _cells.at(i).first; }
+   Cell* getCell(int i) { return _cells.at(i).first; }
    // get coeffcient of i:th cell of this chain
-   virtual int getCoeff(int i) { return _cells.at(i).second; }
+   int getCoeff(int i) { return _cells.at(i).second; }
+   
+   int getTorsion() {return _torsion;}
    
    // number of cells in this chain 
-   virtual int getSize() { return _cells.size(); }
+   int getSize() { return _cells.size(); }
    
-   virtual int getNumCells() {
+   int getNumCells() {
      int count = 0;
      for(std::vector< std::pair <Cell*, int> >::iterator it = _cells.begin(); it != _cells.end(); it++){
        Cell* cell = (*it).first;
@@ -152,13 +157,13 @@ class Chain{
    
    
    // get/set chain name
-   virtual std::string getName() { return _name; }
-   virtual void setName(std::string name) { _name=name; }
+   std::string getName() { return _name; }
+   void setName(std::string name) { _name=name; }
 
    // append this chain to a 2.0 MSH ASCII file as $ElementData
-   virtual int writeChainMSH(const std::string &name);
+   int writeChainMSH(const std::string &name);
    
-   virtual void getData(std::map<int, std::vector<double> >& data);
+   void getData(std::map<int, std::vector<double> >& data);
    
 };
 
diff --git a/Geo/Homology.cpp b/Geo/Homology.cpp
index 7174b65e0f2540f3bc5fa5e847c794931a45e33f..8a7b7b154353a0fe51ac53c624ab41c4775ba035 100644
--- a/Geo/Homology.cpp
+++ b/Geo/Homology.cpp
@@ -8,6 +8,7 @@
 
 #include "Homology.h"
 #include "ChainComplex.h"
+#include "OS.h"
 
 #if defined(HAVE_KBIPACK)
 Homology::Homology(GModel* model, std::vector<int> physicalDomain, std::vector<int> physicalSubdomain){
@@ -15,7 +16,7 @@ Homology::Homology(GModel* model, std::vector<int> physicalDomain, std::vector<i
   _model = model;
   
   Msg::Info("Creating a Cell Complex...");
-  
+  double t1 = Cpu();
   
   std::map<int, std::vector<GEntity*> > groups[4];
   model->getPhysicalGroups(groups);
@@ -60,8 +61,8 @@ Homology::Homology(GModel* model, std::vector<int> physicalDomain, std::vector<i
     Msg::Error("Check the domain & the mesh.");
     return;
   }
-  
-  Msg::Info("Cell Complex complete.");
+  double t2 = Cpu();
+  Msg::Info("Cell Complex complete (%g s).", t2 - t1);
   Msg::Info("%d volumes, %d faces, %d edges and %d vertices.",
             _cellComplex->getSize(3), _cellComplex->getSize(2), _cellComplex->getSize(1), _cellComplex->getSize(0));
   
@@ -71,20 +72,24 @@ Homology::Homology(GModel* model, std::vector<int> physicalDomain, std::vector<i
 void Homology::findGenerators(std::string fileName){
   
   Msg::Info("Reducing Cell Complex...");
+  double t1 = Cpu();
   int omitted = _cellComplex->reduceComplex(true);
   _cellComplex->combine(3);
   _cellComplex->combine(2);
   _cellComplex->combine(1);
-  Msg::Info("Cell Complex reduction complete.");
+  double t2 = Cpu();
+  Msg::Info("Cell Complex reduction complete (%g s).", t2 - t1);
   Msg::Info("%d volumes, %d faces, %d edges and %d vertices.",
             _cellComplex->getSize(3), _cellComplex->getSize(2), _cellComplex->getSize(1), _cellComplex->getSize(0));
 
   _cellComplex->writeComplexMSH(fileName);
   
   Msg::Info("Computing homology groups...");
+  t1 = Cpu();
   ChainComplex* chains = new ChainComplex(_cellComplex);
   chains->computeHomology();
-  Msg::Info("Homology Computation complete.");
+  t2 = Cpu();
+  Msg::Info("Homology Computation complete (%g s).", t2 - t1);
   
   int HRank[4];
   for(int j = 0; j < 4; j++){
@@ -97,9 +102,12 @@ void Homology::findGenerators(std::string fileName){
       convert(j, dimension);
       
       std::string name = dimension + "D Generator " + generator;
-      Chain* chain = new Chain(_cellComplex->getCells(j), chains->getCoeffVector(j,i), _cellComplex, name);
+      Chain* chain = new Chain(_cellComplex->getCells(j), chains->getCoeffVector(j,i), _cellComplex, name, chains->getTorsion(j,i));
       chain->writeChainMSH(fileName);
-      if(chain->getSize() != 0) HRank[j] = HRank[j] + 1;
+      if(chain->getSize() != 0) {
+        HRank[j] = HRank[j] + 1;
+        if(chain->getTorsion() != 1) Msg::Warning("%dD Generator %d has torsion coefficient %d!", j, i, chain->getTorsion());
+      }
       delete chain;
     }
   }
@@ -124,27 +132,31 @@ void Homology::findThickCuts(std::string fileName){
   _cellComplex->removeSubdomain();
   
   Msg::Info("Reducing Cell Complex...");
+  double t1 = Cpu();
   int omitted = _cellComplex->coreduceComplex(true);
   _cellComplex->cocombine(0);
   _cellComplex->cocombine(1);
   _cellComplex->cocombine(2);
-  Msg::Info("Cell Complex reduction complete.");
+  double t2 = Cpu();
+  Msg::Info("Cell Complex reduction complete (%g s).", t2 - t1);
   Msg::Info("%d volumes, %d faces, %d edges and %d vertices.",
             _cellComplex->getSize(3), _cellComplex->getSize(2), _cellComplex->getSize(1), _cellComplex->getSize(0));
  
   _cellComplex->writeComplexMSH(fileName);
   
   Msg::Info("Computing homology groups...");
+  t1 = Cpu();
   ChainComplex* chains = new ChainComplex(_cellComplex);
   chains->transposeHMatrices();
   chains->computeHomology(true);
-  Msg::Info("Homology Computation complete.");
+  t2 = Cpu();
+  Msg::Info("Homology Computation complete (%g s).", t2- t1);
   
   int dim = _cellComplex->getDim();
   
   int HRank[4];
+  for(int i = 0; i < 4; i++) HRank[i] = 0;
   for(int j = 3; j > -1; j--){
-    HRank[j] = 0;
     for(int i = 1; i <= chains->getBasisSize(j); i++){
       
       std::string generator;
@@ -153,9 +165,12 @@ void Homology::findThickCuts(std::string fileName){
       convert(dim-j, dimension);
       
       std::string name = dimension + "D Thick cut " + generator;
-      Chain* chain = new Chain(_cellComplex->getCells(j), chains->getCoeffVector(j,i), _cellComplex, name);
+      Chain* chain = new Chain(_cellComplex->getCells(j), chains->getCoeffVector(j,i), _cellComplex, name, chains->getTorsion(j,i));
       chain->writeChainMSH(fileName);
-      if(chain->getSize() != 0) HRank[j] = HRank[j] + 1;
+      if(chain->getSize() != 0){
+        HRank[dim-j] = HRank[dim-j] + 1;
+        if(chain->getTorsion() != 1) Msg::Warning("%dD Thick cut %d has torsion coefficient %d!", j, i, chain->getTorsion());
+      }
       delete chain;
             
     }