From 364bf6fcaedadb0f5bea5b26cde04c1441c1dc9a Mon Sep 17 00:00:00 2001
From: Matti Pellika <matti.pellikka@tut.fi>
Date: Fri, 23 Apr 2010 08:15:50 +0000
Subject: [PATCH] Simplified omitting.

---
 Geo/Cell.cpp         |  22 +++++++--
 Geo/Cell.h           |   3 +-
 Geo/CellComplex.cpp  | 108 +++++++++++++++++++++++--------------------
 Geo/CellComplex.h    |  21 ++++-----
 Geo/ChainComplex.cpp |   3 +-
 Geo/Homology.cpp     |  39 +---------------
 6 files changed, 87 insertions(+), 109 deletions(-)

diff --git a/Geo/Cell.cpp b/Geo/Cell.cpp
index cc54acc90f..197594c755 100755
--- a/Geo/Cell.cpp
+++ b/Geo/Cell.cpp
@@ -43,10 +43,10 @@ Cell::~Cell()
   if(_delimage) delete _image; 
 }
 
-bool Cell::findBoundaryCells(std::vector<Cell*>& bdCells)
+bool Cell::findBoundaryElements(std::vector<MElement*>& bdElements)
 {
   if(_combined) return false;
-  bdCells.clear();
+  bdElements.clear();
   MElementFactory factory;
   for(int i = 0; i < getNumFacets(); i++){
     std::vector<MVertex*> vertices;
@@ -69,8 +69,7 @@ bool Cell::findBoundaryCells(std::vector<Cell*>& bdCells)
     }
     MElement* element = factory.create(newtype, vertices, 0, 
 				       _image->getPartition());
-    Cell* cell = new Cell(element);
-    bdCells.push_back(cell);
+    bdElements.push_back(element);
   }
   return true;
 }
@@ -347,4 +346,19 @@ CombinedCell::CombinedCell(Cell* c1, Cell* c2, bool orMatch, bool co) : Cell()
 
 }
 
+CombinedCell::CombinedCell(std::vector<Cell*>& cells) : Cell() 
+{  
+  _num = ++_globalNum;
+  _index = cells.at(0)->getIndex();
+  _subdomain = cells.at(0)->inSubdomain();
+  _combined = true;
+
+  // cells
+  for(unsigned int i = 0; i < cells.size(); i++){
+    Cell* c = cells.at(i);
+    _cells[c] = 1;
+  }
+}
+
+
 #endif
diff --git a/Geo/Cell.h b/Geo/Cell.h
index ae0ed442ca..0239b05a51 100644
--- a/Geo/Cell.h
+++ b/Geo/Cell.h
@@ -100,7 +100,7 @@ class Cell
     else return false; }
 
   // find the cells on the boundary of this cell
-  bool findBoundaryCells(std::vector<Cell*>& bdCells);
+  bool findBoundaryElements(std::vector<MElement*>& bdElements);
   // get boundary cell orientation
   int findBoundaryCellOrientation(Cell* cell);
   
@@ -208,6 +208,7 @@ class CombinedCell : public Cell{
  public:
   
   CombinedCell(Cell* c1, Cell* c2, bool orMatch, bool co=false);
+  CombinedCell(std::vector<Cell*>& cells);
   ~CombinedCell() {}
 
   int getDim() const { return _cells.begin()->first->getDim(); }
diff --git a/Geo/CellComplex.cpp b/Geo/CellComplex.cpp
index 26162fee1f..b7635c7461 100644
--- a/Geo/CellComplex.cpp
+++ b/Geo/CellComplex.cpp
@@ -28,15 +28,12 @@ CellComplex::CellComplex( std::vector<MElement*>& domainElements,
 
 void CellComplex::panic_exit(){
   for(int i = 0; i < 4; i++){
-    _cells[i].clear();
     for(citer cit = _ocells[i].begin(); cit != _ocells[i].end(); cit++){
       Cell* cell = *cit;
       delete cell;
     }
-    _ocells[i].clear();
   }
   for(unsigned int i = 0; i < _newcells.size(); i++) delete _newcells.at(i);
-  _newcells.clear();
   printf("ERROR: No proper cell complex could be constructed!\n");
 }
 
@@ -57,26 +54,30 @@ bool CellComplex::insert_cells(std::vector<MElement*>& elements,
       printf("ERROR: mesh element %d not implemented! \n", type);
       return false;
     }
+    //Cell* cell = _cellPool.construct(element);
     Cell* cell = new Cell(element);
     cell->setInSubdomain(subdomain);
     std::pair<citer, bool> insertInfo = _cells[cell->getDim()].insert(cell);
-    if(!insertInfo.second) delete cell;  
+    if(!insertInfo.second) delete cell; 
+    //if(!insertInfo.second) _cellPool.free(cell);  
   }
   
   // add lower dimensional cells recursively
   for (int dim = 3; dim > 0; dim--){
     for(citer cit = firstCell(dim); cit != lastCell(dim); cit++){
       Cell* cell = *cit;
-      std::vector<Cell*> bdCells;
-      if(!cell->findBoundaryCells(bdCells)) return false;
-      for(unsigned int i = 0; i < bdCells.size(); i++){
-	Cell* newCell = bdCells.at(i);
+      std::vector<MElement*> bdElements;
+      if(!cell->findBoundaryElements(bdElements)) return false;
+      for(unsigned int i = 0; i < bdElements.size(); i++){
+	//Cell* newCell = _cellPool.construct(bdElements.at(i));
+	Cell* newCell = new Cell(bdElements.at(i));
 	newCell->setInSubdomain(subdomain);
 	newCell->setDeleteImage(true);
 	std::pair<citer, bool> insertInfo = 
 	  _cells[newCell->getDim()].insert(newCell);
 	if(!insertInfo.second){ // the cell was already in the cell complex
 	  delete newCell; 
+	  //_cellPool.free(newCell); 
 	  newCell = *(insertInfo.first); 
 	}
 	if(!subdomain) {
@@ -92,17 +93,12 @@ bool CellComplex::insert_cells(std::vector<MElement*>& elements,
 CellComplex::~CellComplex()
 {
   for(int i = 0; i < 4; i++){
-    _cells[i].clear();
-    
     for(citer cit = _ocells[i].begin(); cit != _ocells[i].end(); cit++){
       Cell* cell = *cit;
       delete cell;
     }
-    _ocells[i].clear();
-    
   }
   for(unsigned int i = 0; i < _newcells.size(); i++) delete _newcells.at(i);
-  _newcells.clear();
 }
 
 void CellComplex::insertCell(Cell* cell)
@@ -119,6 +115,7 @@ void CellComplex::insertCell(Cell* cell)
 
 void CellComplex::removeCell(Cell* cell, bool other)
 {  
+  if(!hasCell(cell)) return;
   std::map<Cell*, int, Less_Cell > coboundary;
   cell->getCoboundary(coboundary);
   std::map<Cell*, int, Less_Cell > boundary; 
@@ -158,7 +155,8 @@ void CellComplex::enqueueCells(std::map<Cell*, int, Less_Cell>& cells,
   }
 }
 
-int CellComplex::coreduction(Cell* startCell, int omitted)
+int CellComplex::coreduction(Cell* startCell, bool omit, 
+			     std::vector<Cell*>& omittedCells)
 {  
   int coreductions = 0;
   
@@ -184,8 +182,8 @@ int CellComplex::coreduction(Cell* startCell, int omitted)
       bd_s.begin()->first->getCoboundary(cbd_c);
       enqueueCells(cbd_c, Q, Qset);
       removeCell(bd_s.begin()->first);
-      if(bd_s.begin()->first->getDim() == 0 && omitted > 0){
-	_store.at(omitted-1).insert(bd_s.begin()->first);
+      if(bd_s.begin()->first->getDim() == 0 && omit){
+	omittedCells.push_back(bd_s.begin()->first);
       }
       coreductions++;
     }
@@ -197,7 +195,8 @@ int CellComplex::coreduction(Cell* startCell, int omitted)
   return coreductions;
 }
 
-int CellComplex::reduction(int dim, int omitted)
+int CellComplex::reduction(int dim, bool omit,
+			   std::vector<Cell*>& omittedCells)
 {
   if(dim < 1 || dim > 3) return 0;
 
@@ -213,9 +212,9 @@ int CellComplex::reduction(int dim, int omitted)
       Cell* cell = *cit;
       if( cell->getCoboundarySize() == 1 
 	  && inSameDomain(cell, cell->firstCoboundary()->first)){
-	++cit;
-	if(dim == getDim() && omitted > 0){
-	  _store.at(omitted-1).insert(cell->firstCoboundary()->first);    
+	cit++;
+	if(dim == getDim() && omit){
+	  omittedCells.push_back(cell->firstCoboundary()->first);    
 	}
 	removeCell(cell->firstCoboundary()->first);
 	removeCell(cell);
@@ -230,7 +229,8 @@ int CellComplex::reduction(int dim, int omitted)
   return count;
 }
 
-int CellComplex::coreduction(int dim, int omitted)
+int CellComplex::coreduction(int dim, bool omit, 
+			     std::vector<Cell*>& omittedCells)
 {
   if(dim < 1 || dim > 3) return 0;
 
@@ -247,8 +247,8 @@ int CellComplex::coreduction(int dim, int omitted)
       if( cell->getBoundarySize() == 1
           && inSameDomain(cell, cell->firstBoundary()->first)){
         ++cit;
-	if(dim-1 == 0 && omitted > 0){
-	  _store.at(omitted-1).insert(cell->firstBoundary()->first);
+	if(dim-1 == 0 && omit){
+	  omittedCells.push_back(cell->firstBoundary()->first);
 	}
         removeCell(cell->firstBoundary()->first);
         removeCell(cell);
@@ -269,25 +269,29 @@ int CellComplex::reduceComplex(bool omit)
 	 getSize(3), getSize(2), getSize(1), getSize(0));
 
   int count = 0;
-  for(int i = 3; i > 0; i--) count = count + reduction(i);
+  std::vector<Cell*> empty;
+  for(int i = 3; i > 0; i--) count = count + reduction(i, false, empty);
 
   if(omit){
-    int omitted = 0;
-    _store.clear();
     
     removeSubdomain();
-    
+    std::vector<Cell*> newCells;
+
     while (getSize(getDim()) != 0){
       
       citer cit = firstCell(getDim());
       Cell* cell = *cit;
-      removeCell(cell, false);
       
-      omitted++;
-      std::set< Cell*, Less_Cell > omittedCells;
-      _store.push_back(omittedCells);
-      _store.at(omitted-1).insert(cell);
-      for(int j = 3; j > 0; j--) reduction(j, omitted);
+      removeCell(cell, false);
+      std::vector<Cell*> omittedCells;
+      omittedCells.push_back(cell);
+
+      for(int j = 3; j > 0; j--) reduction(j, true, omittedCells);
+      CombinedCell* newcell = new CombinedCell(omittedCells);
+      newCells.push_back(newcell);
+    }
+    for(unsigned int i = 0; i < newCells.size(); i++){
+      insertCell(newCells.at(i));
     }
   }
   
@@ -295,9 +299,9 @@ int CellComplex::reduceComplex(bool omit)
        getSize(3), getSize(2), getSize(1), getSize(0));
 
   combine(3);
-  reduction(2);
+  reduction(2, false, empty);
   combine(2);
-  reduction(1);
+  reduction(1, false, empty);
   combine(1);
   
   printf(" %d volumes, %d faces, %d edges and %d vertices. \n",
@@ -325,31 +329,33 @@ int CellComplex::coreduceComplex(bool omit)
   
   int count = 0;
   removeSubdomain();
-  
+  std::vector<Cell*> empty;  
   for(int dim = 0; dim < 4; dim++){
     citer cit = firstCell(dim);
     while(cit != lastCell(dim)){
       Cell* cell = *cit;
-      count = count + coreduction(cell);
+      count = count + coreduction(cell, false, empty);
       if(count != 0) break;
       cit++;
     }
   } 
   
-  int omitted = 0;
   if(omit){
-    _store.clear();
-    
+    std::vector<Cell*> newCells;
     while (getSize(0) != 0){
       citer cit = firstCell(0);
       Cell* cell = *cit;
       
       removeCell(cell, false);
-      std::set< Cell*, Less_Cell > omittedCells;
-      omitted++;
-      _store.push_back(omittedCells);
-      _store.at(omitted-1).insert(cell);
-      coreduction(cell, omitted);
+      std::vector<Cell*> omittedCells;
+      omittedCells.push_back(cell);
+
+      coreduction(cell, true, omittedCells);
+      CombinedCell* newcell = new CombinedCell(omittedCells);
+      newCells.push_back(newcell);
+    }
+    for(unsigned int i = 0; i < newCells.size(); i++){
+      insertCell(newCells.at(i));
     }
   }
 
@@ -357,17 +363,17 @@ int CellComplex::coreduceComplex(bool omit)
 	 getSize(3), getSize(2), getSize(1), getSize(0));
   
   cocombine(0);
-  coreduction(1);
+  coreduction(1, false, empty);
   cocombine(1);
-  coreduction(2);
+  coreduction(2, false, empty);
   cocombine(2);
-  coreduction(3);
+  coreduction(3, false, empty);
   coherent();
 
   printf(" %d volumes, %d faces, %d edges and %d vertices. \n",
 	 getSize(3), getSize(2), getSize(1), getSize(0));
 
-  return omitted;
+  return 0;
 }
 
 int CellComplex::cocombine(int dim)
@@ -464,7 +470,8 @@ int CellComplex::combine(int dim)
           c2->getBoundary(bd_c);
           enqueueCells(bd_c, Q, Qset);
 
-          CombinedCell* newCell = new CombinedCell(c1, c2, (or1 != or2) );
+	  CombinedCell* newCell = new CombinedCell(c1, c2, (or1 != or2));
+          //CombinedCell* newCell = _ccellPool.construct(c1, c2, (or1 != or2));
           removeCell(c1);
           removeCell(c2);
           insertCell(newCell);
@@ -568,7 +575,6 @@ void CellComplex::restoreComplex()
     delete cell;
   }
   _newcells.clear();
-  _store.clear();
 }
 
 void CellComplex::printComplex(int dim)
diff --git a/Geo/CellComplex.h b/Geo/CellComplex.h
index a801d1f928..4fa7f696d0 100644
--- a/Geo/CellComplex.h
+++ b/Geo/CellComplex.h
@@ -21,6 +21,7 @@
 #include "MElement.h"
 #include "ChainComplex.h"
 //#include "GModel.h"
+#include <boost/pool/object_pool.hpp>
 
 class Cell;
 
@@ -30,11 +31,8 @@ class CellComplex
  private:
   // sorted containers of unique cells in this cell complex 
   // one for each dimension
-  std::set<Cell*, Less_Cell>  _cells[4];
-  
-  // temporary store for omitted cells (generators of the highest dimension)
-  std::vector< std::set<Cell*, Less_Cell> > _store;
-  
+  std::set<Cell*, Less_Cell> _cells[4];
+    
   // original cells of this cell complex
   std::set<Cell*, Less_Cell>  _ocells[4];
   
@@ -60,8 +58,9 @@ class CellComplex
   void removeCell(Cell* cell, bool other=true);
   void insertCell(Cell* cell);
   
-  // queued coreduction presented in Mrozek's paper
-  int coreduction(Cell* startCell, int omitted=0);
+  // queued coreduction
+  int coreduction(Cell* startCell, bool omit, 
+		  std::vector<Cell*>& omittedCells);
   
  public: 
   
@@ -106,8 +105,8 @@ class CellComplex
 
   // (co)reduction of this cell complex
   // removes (co)reduction pairs of cell of dimension dim and dim-1
-  int reduction(int dim, int omitted=0);
-  int coreduction(int dim, int omitted=0);  
+  int reduction(int dim, bool omit, std::vector<Cell*>& omittedCells);
+  int coreduction(int dim, bool omit, std::vector<Cell*>& omittedCells);  
     
   // Cell combining for reduction and coreduction
   int combine(int dim);
@@ -129,10 +128,6 @@ class CellComplex
   void printEuler(){ 
     printf("Euler characteristic: %d. \n", eulerCharacteristic()); }
   
-  // get cells omitted by (co)reduction
-  int getNumOmitted() { return _store.size(); }
-  std::set<Cell*, Less_Cell> getOmitted(int i) { return _store.at(i); }  
-
   // restore the cell complex to its original state before (co)reduction
   void restoreComplex();
 
diff --git a/Geo/ChainComplex.cpp b/Geo/ChainComplex.cpp
index 3dcb47e820..261335b077 100644
--- a/Geo/ChainComplex.cpp
+++ b/Geo/ChainComplex.cpp
@@ -96,7 +96,6 @@ ChainComplex::ChainComplex(CellComplex* cellComplex, int domain)
       } 
       mpz_clear(elem); 
     }
-
     _kerH[dim] = NULL;
     _codH[dim] = NULL;
     _JMatrix[dim] = NULL;
@@ -482,7 +481,7 @@ void ChainComplex::getBasisChain(std::map<Cell*, int, Less_Cell>& chain,
   }
   mpz_clear(elem);
   
-  if(deform) smoothenChain(chain);
+  if(deform && (dim == 1 || dim == 2) ) smoothenChain(chain);
 }
 
 int ChainComplex::getBasisSize(int dim, int basis)
diff --git a/Geo/Homology.cpp b/Geo/Homology.cpp
index 9bec179e16..1e20f392c0 100644
--- a/Geo/Homology.cpp
+++ b/Geo/Homology.cpp
@@ -168,23 +168,6 @@ void Homology::findGenerators(CellComplex* cellComplex)
       _generators.push_back(chain->createPGroup());
       delete chain;
     }
-    if(j == cellComplex->getDim() && cellComplex->getNumOmitted() > 0){
-      for(int i = 0; i < cellComplex->getNumOmitted(); i++){
-        std::string generator;
-        convert(i+1, generator);
-        std::string name = "H" + dimension + domainString + generator;
-        std::vector<int> coeffs (cellComplex->getOmitted(i).size(),1);
-        Chain* chain = new Chain(cellComplex->getOmitted(i), coeffs, 
-				 cellComplex, _model, name, 1);
-        if(chain->getSize() == 0){
-	  delete chain;
-	  continue;
-	}
-	HRank[j] = HRank[j] + 1;
-	_generators.push_back(chain->createPGroup());
-	delete chain;
-      }
-    }
   }
   
   if(_fileName != "") writeGeneratorsMSH();
@@ -267,26 +250,6 @@ void Homology::findDualGenerators(CellComplex* cellComplex)
 		     dim-j, i, chain->getTorsion());
       }     
     }
-    
-    if(j == 0 && cellComplex->getNumOmitted() > 0){
-      for(int i = 0; i < cellComplex->getNumOmitted(); i++){
-        std::string generator;
-        convert(i+1, generator);
-        std::string name 
-	  = "H" + dimension + "*" + 
-	  getDomainString(_domain, _subdomain) + generator;
-        std::vector<int> coeffs (cellComplex->getOmitted(i).size(),1);
-        Chain* chain = new Chain(cellComplex->getOmitted(i), coeffs, 
-				 cellComplex, _model, name, 1);
-	if(chain->getSize() == 0) {
-	  delete chain;
-	  continue;
-	}
-	HRank[dim-j] = HRank[dim-j] + 1;
-	_generators.push_back(chain->createPGroup());
-	delete chain;
-      }
-    }
   }
 
   if(_fileName != "") writeGeneratorsMSH();
@@ -313,7 +276,7 @@ void Homology::findHomSequence(){
   Msg::StatusBar(1, false, "Reducing...");
 
   double t1 = Cpu();
-  cellComplex->reduceComplex(false);
+  cellComplex->reduceComplex();
   double t2 = Cpu();
 
   Msg::Info("Cell Complex reduction complete (%g s).", t2 - t1);
-- 
GitLab