diff --git a/Geo/CellComplex.cpp b/Geo/CellComplex.cpp index 9c004e0e0eee30b84b658ecdf7758e09d12a5976..cb8818c06f6735e92453f889b50c7e098daa911a 100644 --- a/Geo/CellComplex.cpp +++ b/Geo/CellComplex.cpp @@ -106,7 +106,7 @@ CellComplex::CellComplex( std::vector<GEntity*> domain, std::vector<GEntity*> su //cell->setTag(tag); tag++; } - //_cells2[i] = _cells[i]; + _ocells[i] = _cells[i]; _betti[i] = 0; if(getSize(i) > _dim) _dim = i; } @@ -116,7 +116,7 @@ CellComplex::CellComplex( std::vector<GEntity*> domain, std::vector<GEntity*> su void CellComplex::insert_cells(bool subdomain, bool boundary){ - // works only for simplcial meshes at the moment! + // works only for simplicial meshes at the moment! std::vector<GEntity*> domain; @@ -200,13 +200,17 @@ void CellComplex::insert_cells(bool subdomain, bool boundary){ if(!subdomain && !boundary){ int ori = cell->kappa(oldCell); oldCell->addCoboundaryCell( ori, cell ); + oldCell->addOrgCbdCell( ori, cell ); cell->addBoundaryCell( ori, oldCell); + cell->addOrgBdCell( ori, oldCell); } } else if(!subdomain && !boundary) { int ori = cell->kappa(newCell); cell->addBoundaryCell( ori, newCell ); + cell->addOrgBdCell( ori, newCell ); newCell->addCoboundaryCell( ori, cell); + newCell->addOrgCbdCell( ori, cell); } } } @@ -215,7 +219,7 @@ void CellComplex::insert_cells(bool subdomain, bool boundary){ } void CellComplex::insertCell(Cell* cell){ - _cells[cell->getDim()].insert(cell); + _ecells.insert(cell); } /* @@ -290,22 +294,22 @@ int OneSimplex::kappa(Cell* tau) const{ void CellComplex::removeCell(Cell* cell, bool other){ - std::list< std::pair< int, Cell*> > coboundary = cell->getOrientedCoboundary(); - std::list< std::pair< int, Cell*> > boundary = cell->getOrientedBoundary(); + std::map<Cell*, int, Less_Cell > coboundary = cell->getOrientedCoboundary(); + std::map<Cell*, int, Less_Cell > boundary = cell->getOrientedBoundary(); //std::list<Cell*> boundary = cell->getBoundary(); //std::list<Cell*> coboundary = cell->getCoboundary(); - for(std::list< std::pair< int, Cell*> >::iterator it = coboundary.begin(); it != coboundary.end(); it++){ + for(std::map<Cell*, int, Less_Cell>::iterator it = coboundary.begin(); it != coboundary.end(); it++){ //for(std::list<Cell*>::iterator it = coboundary.begin(); it != coboundary.end(); it++){ - Cell* cbdCell = (*it).second; + Cell* cbdCell = (*it).first; //Cell* cbdCell = *it; cbdCell->removeBoundaryCell(cell, other); } - for(std::list< std::pair< int, Cell*> >::iterator it = boundary.begin(); it != boundary.end(); it++){ + for(std::map<Cell*, int, Less_Cell>::iterator it = boundary.begin(); it != boundary.end(); it++){ //for(std::list<Cell*>::iterator it = boundary.begin(); it != boundary.end(); it++){ - Cell* bdCell = (*it).second; + Cell* bdCell = (*it).first; //Cell* bdCell = *it; bdCell->removeCoboundaryCell(cell, other); } @@ -673,7 +677,7 @@ int CellComplex::cocombine(int dim){ std::queue<Cell*> Q; std::set<Cell*, Less_Cell> Qset; std::list<Cell*> cbd_c; - std::list< std::pair< int, Cell*> > bd_c; + std::map<Cell*, int, Less_Cell > bd_c; int count = 0; for(citer cit = firstCell(dim); cit != lastCell(dim); cit++){ @@ -687,32 +691,36 @@ int CellComplex::cocombine(int dim){ Q.pop(); bd_c = s->getOrientedBoundary(); + if(s->getBoundarySize() == 2){ - if(s->getBoundarySize() == 2 && !(*(bd_c.front().second) == *(bd_c.back().second)) - && inSameDomain(s, bd_c.front().second) && inSameDomain(s, bd_c.back().second) - && bd_c.front().second->getNumVertices() < getSize(dim) // heuristics for mammoth cell birth control - && bd_c.back().second->getNumVertices() < getSize(dim)){ + std::map<Cell*, int, Less_Cell>::iterator it = bd_c.begin(); + int or1 = (*it).second; + Cell* c1 = (*it).first; + it++; + int or2 = (*it).second; + Cell* c2 = (*it).first; - int or1 = bd_c.front().first; - int or2 = bd_c.back().first; - Cell* c1 = bd_c.front().second; - Cell* c2 = bd_c.back().second; - - removeCell(s); - _trash.push_back(s); - - cbd_c = c1->getCoboundary(); - enqueueCells(cbd_c, Q, Qset); - cbd_c = c2->getCoboundary(); - enqueueCells(cbd_c, Q, Qset); + if(!(*c1 == *c2) + && inSameDomain(s, c1) && inSameDomain(s, c2) + && c1->getNumVertices() < getSize(dim) // heuristics for mammoth cell birth control + && c2->getNumVertices() < getSize(dim)){ + + removeCell(s); + _trash.push_back(s); - CombinedCell* newCell = new CombinedCell(c1, c2, (or1 != or2), true ); - removeCell(c1); - removeCell(c2); - _cells[dim].insert(newCell); + cbd_c = c1->getCoboundary(); + enqueueCells(cbd_c, Q, Qset); + cbd_c = c2->getCoboundary(); + enqueueCells(cbd_c, Q, Qset); - cit = firstCell(dim); - count++; + CombinedCell* newCell = new CombinedCell(c1, c2, (or1 != or2), true ); + removeCell(c1); + removeCell(c2); + _cells[dim].insert(newCell); + + cit = firstCell(dim); + count++; + } } removeCellQset(s, Qset); @@ -735,7 +743,7 @@ int CellComplex::combine(int dim){ std::queue<Cell*> Q; std::set<Cell*, Less_Cell> Qset; - std::list< std::pair<int, Cell*> > cbd_c; + std::map<Cell*, int, Less_Cell> cbd_c; std::list<Cell*> bd_c; int count = 0; @@ -748,33 +756,37 @@ int CellComplex::combine(int dim){ Cell* s = Q.front(); Q.pop(); - cbd_c = s->getOrientedCoboundary(); - - if(s->getCoboundarySize() == 2 && !(*(cbd_c.front().second) == *(cbd_c.back().second)) - && inSameDomain(s, cbd_c.front().second) && inSameDomain(s, cbd_c.back().second) - && cbd_c.front().second->getNumVertices() < getSize(dim) // heuristics for mammoth cell birth control - && cbd_c.back().second->getNumVertices() < getSize(dim)){ - int or1 = cbd_c.front().first; - int or2 = cbd_c.back().first; - Cell* c1 = cbd_c.front().second; - Cell* c2 = cbd_c.back().second; + + if(s->getCoboundarySize() == 2){ + std::map<Cell*, int, Less_Cell>::iterator it = cbd_c.begin(); + int or1 = (*it).second; + Cell* c1 = (*it).first; + it++; + int or2 = (*it).second; + Cell* c2 = (*it).first; + + if(!(*c1 == *c2) + && inSameDomain(s, c1) && inSameDomain(s, c2) + && c1->getNumVertices() < getSize(dim) // heuristics for mammoth cell birth control + && c2->getNumVertices() < getSize(dim)){ + + removeCell(s); + _trash.push_back(s); - removeCell(s); - _trash.push_back(s); - - bd_c = c1->getBoundary(); - enqueueCells(bd_c, Q, Qset); - bd_c = c2->getBoundary(); - enqueueCells(bd_c, Q, Qset); - - CombinedCell* newCell = new CombinedCell(c1, c2, (or1 != or2) ); - removeCell(c1); - removeCell(c2); - std::pair<citer, bool> insertInfo = _cells[dim].insert(newCell); - if(!insertInfo.second) printf("Warning: Combined cell not inserted! \n"); - cit = firstCell(dim); - count++; + bd_c = c1->getBoundary(); + enqueueCells(bd_c, Q, Qset); + bd_c = c2->getBoundary(); + enqueueCells(bd_c, Q, Qset); + + CombinedCell* newCell = new CombinedCell(c1, c2, (or1 != or2) ); + removeCell(c1); + removeCell(c2); + std::pair<citer, bool> insertInfo = _cells[dim].insert(newCell); + if(!insertInfo.second) printf("Warning: Combined cell not inserted! \n"); + cit = firstCell(dim); + count++; + } } removeCellQset(s, Qset); @@ -905,7 +917,8 @@ int CellComplex::writeComplexMSH(const std::string &name){ for(int i = 0; i < _store.size(); i++){ count = count + _store.at(i).size(); } - + count = count + _ecells.size(); + fprintf(fp, "%d\n", count); int partition = 0; @@ -979,6 +992,26 @@ int CellComplex::writeComplexMSH(const std::string &name){ } } + for(citer cit = _ecells.begin(); cit != _ecells.end(); cit++){ + Cell* cell = *cit; + if(cell->inSubdomain()) partition = 3; + else if(cell->onDomainBoundary()) partition = 2; + else partition = 1; + if(cell->getDim() == 0) fprintf(fp, "%d %d %d %d %d %d %d\n", cell->getNum(), 15, 3, 0, 0, partition, cell->getVertex(0)->getNum()); + if(cell->getDim() == 1) fprintf(fp, "%d %d %d %d %d %d %d %d\n", cell->getNum(), 1, 3, 0, 0, partition, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum()); + if(cell->getDim() == 2){ + if(cell->getNumVertices() == 3) fprintf(fp, "%d %d %d %d %d %d %d %d %d\n", cell->getNum(), 2, 3, 0, 0, partition, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum(), cell->getVertex(2)->getNum()); + else if (cell->getNumVertices() == 4) fprintf(fp, "%d %d %d %d %d %d %d %d %d %d\n", cell->getNum(), 3, 3, 0, 0, partition, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum(), cell->getVertex(2)->getNum(), cell->getVertex(3)->getNum()); + } + if(cell->getDim() == 3){ + if(cell->getNumVertices() == 4) fprintf(fp, "%d %d %d %d %d %d %d %d %d %d\n", cell->getNum(), 4, 3, 0, 0, partition, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum(), cell->getVertex(2)->getNum(), cell->getVertex(3)->getNum()); + if(cell->getNumVertices() == 8) fprintf(fp, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", cell->getNum(), 12, 3, 0, 0, partition, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum(), cell->getVertex(2)->getNum(), cell->getVertex(3)->getNum(), cell->getVertex(4)->getNum(), cell->getVertex(5)->getNum(), cell->getVertex(6)->getNum(), cell->getVertex(7)->getNum() ); + if(cell->getNumVertices() == 6) fprintf(fp, "%d %d %d %d %d %d %d %d %d %d %d %d\n", cell->getNum(), 13, 3, 0, 0, partition, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum(), cell->getVertex(2)->getNum(), cell->getVertex(3)->getNum(),cell->getVertex(4)->getNum(), cell->getVertex(5)->getNum()); + if(cell->getNumVertices() == 5) fprintf(fp, "%d %d %d %d %d %d %d %d %d %d %d\n", cell->getNum(), 14, 3, 0, 0, partition, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum(), cell->getVertex(2)->getNum(), cell->getVertex(3)->getNum(), cell->getVertex(4)->getNum()); + } + } + + fprintf(fp, "$EndElements\n"); @@ -1003,10 +1036,10 @@ bool CellComplex::checkCoherence(){ for(int i = 0; i < 4; i++){ for(citer cit = firstCell(i); cit != lastCell(i); cit++){ Cell* cell = *cit; - std::list< std::pair<int, Cell*> > boundary = cell->getOrientedBoundary(); - for(std::list< std::pair<int, Cell* > >::iterator it = boundary.begin(); it != boundary.end(); it++){ - Cell* bdCell = (*it).second; - int ori = (*it).first; + std::map<Cell*, int, Less_Cell> boundary = cell->getOrientedBoundary(); + for(std::map<Cell*, int, Less_Cell>::iterator it = boundary.begin(); it != boundary.end(); it++){ + Cell* bdCell = (*it).first; + int ori = (*it).second; citer cit = _cells[bdCell->getDim()].find(bdCell); if(cit == lastCell(bdCell->getDim())){ printf("Warning! Boundary cell not in cell complex! Boundary removed. \n"); @@ -1026,10 +1059,10 @@ bool CellComplex::checkCoherence(){ } } - std::list< std::pair<int, Cell*> > coboundary = cell->getOrientedCoboundary(); - for(std::list< std::pair<int, Cell* > >::iterator it = coboundary.begin(); it != coboundary.end(); it++){ - Cell* cbdCell = (*it).second; - int ori = (*it).first; + std::map<Cell*, int, Less_Cell> coboundary = cell->getOrientedCoboundary(); + for(std::map<Cell*, int, Less_Cell>::iterator it = coboundary.begin(); it != coboundary.end(); it++){ + Cell* cbdCell = (*it).first; + int ori = (*it).second; citer cit = _cells[cbdCell->getDim()].find(cbdCell); if(cit == lastCell(cbdCell->getDim())){ printf("Warning! Coboundary cell not in cell complex! Coboundary removed. \n"); @@ -1055,4 +1088,24 @@ bool CellComplex::checkCoherence(){ return coherent; } + +bool Less_Cell::operator()(const Cell* c1, const Cell* c2) const { + + //cells with fever vertices first + + if(c1->getNumVertices() != c2->getNumVertices()){ + return (c1->getNumVertices() < c2->getNumVertices()); + } + + + + //"natural number" -like ordering (the number of a vertice corresponds a digit) + + for(int i=0; i < c1->getNumVertices();i++){ + if(c1->getSortedVertex(i) < c2->getSortedVertex(i)) return true; + else if (c1->getSortedVertex(i) > c2->getSortedVertex(i)) return false; + } + + return false; +} #endif diff --git a/Geo/CellComplex.h b/Geo/CellComplex.h index 8d561d861c2843898e51b2b0a2086dd2ad721706..8a647f1c85290c8eff91c868f8a79c2f190920bd 100644 --- a/Geo/CellComplex.h +++ b/Geo/CellComplex.h @@ -32,6 +32,14 @@ #include "GFace.h" #include "GVertex.h" +class Cell; + +// Ordering of the cells +class Less_Cell{ + public: + bool operator()(const Cell* c1, const Cell* c2) const; +}; + // Abstract class representing an elemtary cell of a cell complex. class Cell { @@ -56,12 +64,16 @@ class Cell bool _immune; - // cells on the boundary and on the coboundary of thhis cell - std::list< std::pair<int, Cell*> > _boundary; - std::list< std::pair<int, Cell*> > _coboundary; + // cells on the boundary and on the coboundary of this cell + std::map< Cell*, int, Less_Cell > _boundary; + std::map< Cell*, int, Less_Cell > _coboundary; int _bdSize; int _cbdSize; + // original boundary and coboundary before the reduction of the cell complex + std::map<Cell*, int, Less_Cell > _obd; + std::map<Cell*, int, Less_Cell > _ocbd; + public: Cell(){ _bdSize = 0; @@ -94,24 +106,27 @@ class Cell // true if this cell has given vertex virtual bool hasVertex(int vertex) const = 0; - + + // (co)boundary cell iterator + typedef std::map<Cell*, int, Less_Cell>::iterator biter; + virtual int getBoundarySize() { return _bdSize; } virtual int getCoboundarySize() { return _cbdSize; } - virtual std::list< std::pair<int, Cell*> > getOrientedBoundary() { return _boundary; } + virtual std::map<Cell*, int, Less_Cell > getOrientedBoundary() { return _boundary; } virtual std::list< Cell* > getBoundary() { std::list<Cell*> boundary; - for( std::list< std::pair<int, Cell*> >::iterator it= _boundary.begin();it!= _boundary.end();it++){ - Cell* cell = (*it).second; + for( biter it= _boundary.begin(); it != _boundary.end();it++){ + Cell* cell = (*it).first; boundary.push_back(cell); } return boundary; } - virtual std::list<std::pair<int, Cell*> >getOrientedCoboundary() { return _coboundary; } + virtual std::map<Cell*, int, Less_Cell > getOrientedCoboundary() { return _coboundary; } virtual std::list< Cell* > getCoboundary() { std::list<Cell*> coboundary; - for( std::list< std::pair<int, Cell*> >::iterator it= _coboundary.begin();it!= _coboundary.end();it++){ - Cell* cell = (*it).second; + for( biter it= _coboundary.begin();it!= _coboundary.end();it++){ + Cell* cell = (*it).first; coboundary.push_back(cell); } return coboundary; @@ -119,6 +134,18 @@ class Cell virtual bool addBoundaryCell(int orientation, Cell* cell) { _bdSize++; + biter it = _boundary.find(cell); + if(it != _boundary.end()){ + (*it).second = (*it).second + orientation; + if((*it).second == 0) { + _boundary.erase(it); _bdSize--; + (*it).first->removeCoboundaryCell(this,false); + return false; + } + return true; + } + _boundary.insert( std::make_pair(cell, orientation ) ); + /* for(std::list< std::pair<int, Cell*> >::iterator it = _boundary.begin(); it != _boundary.end(); it++){ Cell* cell2 = (*it).second; if(*cell2 == *cell) { @@ -132,28 +159,36 @@ class Cell } } _boundary.push_back( std::make_pair(orientation, cell ) ); + */ return true; } virtual bool addCoboundaryCell(int orientation, Cell* cell) { _cbdSize++; - for(std::list< std::pair<int, Cell*> >::iterator it = _coboundary.begin(); it != _coboundary.end(); it++){ - Cell* cell2 = (*it).second; - if(*cell2 == *cell) { - (*it).first = (*it).first + orientation; - if((*it).first == 0){ - _coboundary.erase(it); _cbdSize--; - cell2->removeBoundaryCell(this,false); - return false; - } - return true; + biter it = _coboundary.find(cell); + if(it != _coboundary.end()){ + (*it).second = (*it).second + orientation; + if((*it).second == 0) { + _coboundary.erase(it); _cbdSize--; + (*it).first->removeBoundaryCell(this,false); + return false; } + return true; } - _coboundary.push_back( std::make_pair(orientation, cell) ); + _coboundary.insert( std::make_pair(cell, orientation ) ); return true; } virtual int removeBoundaryCell(Cell* cell, bool other=true) { + biter it = _boundary.find(cell); + if(it != _boundary.end()){ + _boundary.erase(it); + if(other) (*it).first->removeCoboundaryCell(this, false); + _bdSize--; + return (*it).second; + } + + /* for(std::list< std::pair<int, Cell*> >::iterator it = _boundary.begin(); it != _boundary.end(); it++){ Cell* cell2 = (*it).second; int ori = (*it).first; @@ -164,35 +199,51 @@ class Cell return ori; } } + */ + return 0; } virtual int removeCoboundaryCell(Cell* cell, bool other=true) { - for(std::list< std::pair<int, Cell*> >::iterator it = _coboundary.begin(); it != _coboundary.end(); it++){ - Cell* cell2 = (*it).second; - int ori = (*it).first; - if(*cell2 == *cell) { - _coboundary.erase(it); - if(other) cell2->removeBoundaryCell(this, false); - _cbdSize--; - return ori; - } + biter it = _coboundary.find(cell); + if(it != _coboundary.end()){ + _coboundary.erase(it); + if(other) (*it).first->removeBoundaryCell(this, false); + _cbdSize--; + return (*it).second; } return 0; } - virtual bool hasBoundary(Cell* cell){ - for(std::list< std::pair<int, Cell*> >::iterator it = _boundary.begin(); it != _boundary.end(); it++){ - Cell* cell2 = (*it).second; - if(*cell2 == *cell) return true; + virtual bool hasBoundary(Cell* cell, bool org=false){ + if(!org){ + /* + for(std::list< std::pair<int, Cell*> >::iterator it = _boundary.begin(); it != _boundary.end(); it++){ + Cell* cell2 = (*it).second; + if(*cell2 == *cell) return true; + } + return false; + */ + biter it = _boundary.find(cell); + if(it != _boundary.end()) return true; + return false; + } + else{ + biter it = _obd.find(cell); + if(it != _obd.end()) return true; + return false; } - return false; } - virtual bool hasCoboundary(Cell* cell){ - for(std::list< std::pair<int, Cell*> >::iterator it = _coboundary.begin(); it != _coboundary.end(); it++){ - Cell* cell2 = (*it).second; - if(*cell2 == *cell) return true; + virtual bool hasCoboundary(Cell* cell, bool org=false){ + if(!org){ + biter it = _coboundary.find(cell); + if(it != _coboundary.end()) return true; + return false; } - return false; + else{ + biter it = _ocbd.find(cell); + if(it != _ocbd.end()) return true; + return false; + } } @@ -200,7 +251,7 @@ class Cell virtual void clearCoboundary() { _coboundary.clear(); } virtual void makeDualCell(){ - std::list< std::pair<int, Cell*> > temp = _boundary; + std::map<Cell*, int, Less_Cell > temp = _boundary; _boundary = _coboundary; _coboundary = temp; _dim = 3-_dim; @@ -208,22 +259,44 @@ class Cell } virtual void printBoundary() { - for(std::list< std::pair<int, Cell*> >::iterator it = _boundary.begin(); it != _boundary.end(); it++){ - printf("Boundary cell orientation: %d ", (*it).first); - Cell* cell2 = (*it).second; + for(biter it = _boundary.begin(); it != _boundary.end(); it++){ + printf("Boundary cell orientation: %d ", (*it).second); + Cell* cell2 = (*it).first; cell2->printCell(); } if(_boundary.empty()) printf("Cell boundary is empty. \n"); } virtual void printCoboundary() { - for(std::list< std::pair<int, Cell*> >::iterator it = _coboundary.begin(); it != _coboundary.end(); it++){ - printf("Coboundary cell orientation: %d, ", (*it).first); - Cell* cell2 = (*it).second; + for(biter it = _coboundary.begin(); it != _coboundary.end(); it++){ + printf("Coboundary cell orientation: %d, ", (*it).second); + Cell* cell2 = (*it).first; cell2->printCell(); if(_coboundary.empty()) printf("Cell coboundary is empty. \n"); } } + virtual void addOrgBdCell(int orientation, Cell* cell) { _obd.insert( std::make_pair(cell, orientation ) ); }; + virtual void addOrgCbdCell(int orientation, Cell* cell) { _ocbd.insert( std::make_pair(cell, orientation ) ); }; + virtual std::map<Cell*, int, Less_Cell > getOrgBd() { return _obd; } + virtual std::map<Cell*, int, Less_Cell > getOrgCbd() { return _ocbd; } + virtual void printOrgBd() { + for(biter it = _obd.begin(); it != _obd.end(); it++){ + printf("Boundary cell orientation: %d ", (*it).second); + Cell* cell2 = (*it).first; + cell2->printCell(); + } + if(_obd.empty()) printf("Cell boundary is empty. \n"); + } + virtual void printOrgCbd() { + for(biter it = _ocbd.begin(); it != _ocbd.end(); it++){ + printf("Coboundary cell orientation: %d, ", (*it).second); + Cell* cell2 = (*it).first; + cell2->printCell(); + if(_ocbd.empty()) printf("Cell coboundary is empty. \n"); + } + } + + virtual bool inSubdomain() const { return _inSubdomain; } @@ -632,8 +705,7 @@ class CPyramid : public Cell, public MPyramid virtual void printCell() const { printf("Cell dimension: %d, Vertices: %d %d %d %d %d, in subdomain: %d \n", getDim(), _v[0]->getNum(), _v[1]->getNum(), _v[2]->getNum(), _v[3]->getNum(), _v[4]->getNum(), _inSubdomain); } }; - - +/* // Ordering for the cells. class Less_Cell{ public: @@ -661,6 +733,7 @@ class Less_Cell{ } }; +*/ class Equal_Cell{ @@ -692,6 +765,7 @@ class Less_MVertex{ } }; +// A cell that is a combination of cells of same dimension class CombinedCell : public Cell{ private: @@ -740,28 +814,32 @@ class CombinedCell : public Cell{ //_boundary = c1->getOrientedBoundary(); - std::list< std::pair<int, Cell*> > c1Boundary = c1->getOrientedBoundary(); - std::list< std::pair<int, Cell*> > c2Boundary = c2->getOrientedBoundary(); + std::map< Cell*, int, Less_Cell > c1Boundary = c1->getOrientedBoundary(); + std::map< Cell*, int, Less_Cell > c2Boundary = c2->getOrientedBoundary(); - for(std::list< std::pair<int, Cell*> >::iterator it = c1Boundary.begin(); it != c1Boundary.end(); it++){ - Cell* cell = (*it).second; - int ori = (*it).first; + for(std::map<Cell*, int, Less_Cell>::iterator it = c1Boundary.begin(); it != c1Boundary.end(); it++){ + Cell* cell = (*it).first; + int ori = (*it).second; cell->removeCoboundaryCell(c1); if(this->addBoundaryCell(ori, cell)) cell->addCoboundaryCell(ori, this); } - for(std::list< std::pair<int, Cell*> >::iterator it = c2Boundary.begin(); it != c2Boundary.end(); it++){ - Cell* cell = (*it).second; - if(!orMatch) (*it).first = -1*(*it).first; - int ori = (*it).first; + for(std::map<Cell*, int, Less_Cell >::iterator it = c2Boundary.begin(); it != c2Boundary.end(); it++){ + Cell* cell = (*it).first; + if(!orMatch) (*it).second = -1*(*it).second; + int ori = (*it).second; cell->removeCoboundaryCell(c2); //if(this->addBoundaryCell(ori, cell)) cell->addCoboundaryCell(ori, this); if(co){ + std::map<Cell*, int, Less_Cell >::iterator it2 = c1Boundary.find(cell); bool old = false; + if(it2 != c1Boundary.end()) old = true; + /* for(std::list< std::pair<int, Cell* > >::iterator it2 = c1Boundary.begin(); it2 != c1Boundary.end(); it2++){ Cell* cell2 = (*it2).second; if(*cell2 == *cell) old = true; } + */ if(!old){ if(this->addBoundaryCell(ori, cell)) cell->addCoboundaryCell(ori, this); } } else{ @@ -770,27 +848,31 @@ class CombinedCell : public Cell{ } //_coboundary = c1->getOrientedCoboundary(); - std::list< std::pair<int, Cell*> > c1Coboundary = c1->getOrientedCoboundary(); - std::list< std::pair<int, Cell*> > c2Coboundary = c2->getOrientedCoboundary(); + std::map<Cell*, int, Less_Cell > c1Coboundary = c1->getOrientedCoboundary(); + std::map<Cell*, int, Less_Cell > c2Coboundary = c2->getOrientedCoboundary(); - for(std::list< std::pair<int, Cell*> >::iterator it = c1Coboundary.begin(); it != c1Coboundary.end(); it++){ - Cell* cell = (*it).second; - int ori = (*it).first; + for(std::map<Cell*, int, Less_Cell>::iterator it = c1Coboundary.begin(); it != c1Coboundary.end(); it++){ + Cell* cell = (*it).first; + int ori = (*it).second; cell->removeBoundaryCell(c1); if(this->addCoboundaryCell(ori, cell)) cell->addBoundaryCell(ori, this); } - for(std::list< std::pair<int, Cell*> >::iterator it = c2Coboundary.begin(); it != c2Coboundary.end(); it++){ - Cell* cell = (*it).second; - if(!orMatch) (*it).first = -1*(*it).first; - int ori = (*it).first; + for(std::map<Cell*, int, Less_Cell>::iterator it = c2Coboundary.begin(); it != c2Coboundary.end(); it++){ + Cell* cell = (*it).first; + if(!orMatch) (*it).second = -1*(*it).second; + int ori = (*it).second; cell->removeBoundaryCell(c2); //if(this->addCoboundaryCell(ori, cell)) cell->addBoundaryCell(ori, this); if(!co){ + std::map<Cell*, int, Less_Cell >::iterator it2 = c1Coboundary.find(cell); bool old = false; + if(it2 != c1Coboundary.end()) old = true; + /* for(std::list< std::pair<int, Cell* > >::iterator it2 = c1Coboundary.begin(); it2 != c1Coboundary.end(); it2++){ Cell* cell2 = (*it2).second; if(*cell2 == *cell) old = true; } + */ if(!old) { if(this->addCoboundaryCell(ori, cell)) cell->addBoundaryCell(ori, this); } } else { @@ -865,8 +947,10 @@ class CellComplex std::list<Cell*> _trash; std::vector< std::set<Cell*, Less_Cell> > _store; + std::set<Cell*, Less_Cell> _ecells; + - //std::set<Cell*, Less_Cell> _originalCells[4]; + std::set<Cell*, Less_Cell> _ocells[4]; // Betti numbers of this cell complex (ranks of homology groups) int _betti[4]; @@ -890,9 +974,9 @@ class CellComplex // remove a cell from this cell complex void removeCell(Cell* cell, bool other=true); + public: void insertCell(Cell* cell); - public: // reduction of this cell complex // removes reduction pairs of cell of dimension dim and dim-1 int reduction(int dim, int omitted=0); @@ -938,22 +1022,23 @@ class CellComplex CellComplex(){} ~CellComplex(){ for(int i = 0; i < 4; i++){ - + /* for(citer cit = _cells[i].begin(); cit != _cells[i].end(); cit++){ Cell* cell = *cit; delete cell; //if(cell->isCombined()) delete cell; } + */ _cells[i].clear(); - /* - for(citer cit = _cells2[i].begin(); cit != _cells2[i].end(); cit++){ + + for(citer cit = _ocells[i].begin(); cit != _ocells[i].end(); cit++){ Cell* cell = *cit; delete cell; } - _cells2[i].clear(); - */ + _ocells[i].clear(); + } - emptyTrash(); + //emptyTrash(); } void emptyTrash(){ @@ -966,20 +1051,32 @@ class CellComplex // get the number of certain dimensional cells int getSize(int dim){ return _cells[dim].size(); } + int getOrgSize(int dim){ return _ocells[dim].size(); } int getDim() {return _dim; } std::set<Cell*, Less_Cell> getCells(int dim){ return _cells[dim]; } - + std::set<Cell*, Less_Cell> getOrgCells(int dim){ return _ocells[dim]; } + // iterators to the first and last cells of certain dimension citer firstCell(int dim) {return _cells[dim].begin(); } citer lastCell(int dim) {return _cells[dim].end(); } - + citer firstOrgCell(int dim) {return _ocells[dim].begin(); } + citer lastOrgCell(int dim) {return _ocells[dim].end(); } + + // true if cell complex has given cell - bool hasCell(Cell* cell){ - citer cit = _cells[cell->getDim()].find(cell); - if( cit == lastCell(cell->getDim()) ) return false; - else return true; + bool hasCell(Cell* cell, bool org=false){ + if(!org){ + citer cit = _cells[cell->getDim()].find(cell); + if( cit == lastCell(cell->getDim()) ) return false; + else return true; + } + else{ + citer cit = _ocells[cell->getDim()].find(cell); + if( cit == lastOrgCell(cell->getDim()) ) return false; + else return true; + } } diff --git a/Geo/ChainComplex.cpp b/Geo/ChainComplex.cpp index 01245f710c510a5b4ceff3391aaafb74316d5815..58a00afadb7bbc4a79a5aeb8fb9146871a90585d 100644 --- a/Geo/ChainComplex.cpp +++ b/Geo/ChainComplex.cpp @@ -6,6 +6,7 @@ // Contributed by Matti Pellikka. #include "ChainComplex.h" +#include "OS.h" #if defined(HAVE_KBIPACK) @@ -71,9 +72,9 @@ ChainComplex::ChainComplex(CellComplex* cellComplex){ for( std::set<Cell*, Less_Cell>::iterator cit = cellComplex->firstCell(dim); cit != cellComplex->lastCell(dim); cit++){ Cell* cell = *cit; if(!cell->inSubdomain()){ - std::list< std::pair<int,Cell*> >bdCell = cell->getOrientedBoundary(); - for(std::list< std::pair<int, Cell*> >::iterator it = bdCell.begin(); it != bdCell.end(); it++){ - Cell* bdCell = (*it).second; + std::map<Cell*, int, Less_Cell> bdCell = cell->getOrientedBoundary(); + for(std::map<Cell*, int, Less_Cell>::iterator it = bdCell.begin(); it != bdCell.end(); it++){ + Cell* bdCell = (*it).first; if(!bdCell->inSubdomain()){ int old_elem = 0; //printf("cell1: %d, cell2: %d \n", bdCell->getIndex(), cell->getIndex()); @@ -84,11 +85,11 @@ ChainComplex::ChainComplex(CellComplex* cellComplex){ else{ gmp_matrix_get_elem(elem, bdCell->getIndex(), cell->getIndex(), _HMatrix[dim]); old_elem = mpz_get_si(elem); - mpz_set_si(elem, old_elem + (*it).first); - if( (old_elem + (*it).first) > 1 || (old_elem + (*it).first) < -1 ){ - printf("Warning: Invalid incidence index: %d! HMatrix: %d.", (old_elem + (*it).first), dim); - printf(" Set to %d. \n", (old_elem + (*it).first) % 2); - mpz_set_si(elem, (old_elem + (*it).first) % 2); + mpz_set_si(elem, old_elem + (*it).second); + if( (old_elem + (*it).second) > 1 || (old_elem + (*it).second) < -1 ){ + printf("Warning: Invalid incidence index: %d! HMatrix: %d.", (old_elem + (*it).second), dim); + printf(" Set to %d. \n", (old_elem + (*it).second) % 2); + mpz_set_si(elem, (old_elem + (*it).second) % 2); } gmp_matrix_set_elem(elem, bdCell->getIndex(), cell->getIndex(), _HMatrix[dim]); } @@ -459,8 +460,17 @@ Chain::Chain(std::set<Cell*, Less_Cell> cells, std::vector<int> coeffs, CellComp int i = 0; for(std::set<Cell*, Less_Cell>::iterator cit = cells.begin(); cit != cells.end(); cit++){ Cell* cell = *cit; + _dim = cell->getDim(); if(!cell->inSubdomain() && (int)coeffs.size() > i){ - if(coeffs.at(i) != 0) _cells.push_back( std::make_pair(cell, coeffs.at(i)) ); + if(coeffs.at(i) != 0){ + std::list< std::pair<int, Cell*> > subCells = cell->getCells(); + for(std::list< std::pair<int, Cell*> >::iterator it = subCells.begin(); it != subCells.end(); it++){ + Cell* subCell = (*it).second; + int coeff = (*it).first; + _cells.insert( std::make_pair(subCell, coeffs.at(i)*coeff)); + } + //_cells.push_back( std::make_pair(cell, coeffs.at(i)) ); + } i++; } @@ -471,8 +481,193 @@ Chain::Chain(std::set<Cell*, Less_Cell> cells, std::vector<int> coeffs, CellComp } -int Chain::writeChainMSH(const std::string &name){ +Cell* Chain::findCommonCbdCell(Cell* c1, Cell* c2, Cell* c3){ + /* + c1->printCell(); + c1->printOrgCbd(); + c2->printOrgCbd(); + c2->printCell(); + printf("------ \n"); + */ + + std::map< Cell*, int, Less_Cell > c1Cbd = c1->getOrgCbd(); + for(std::map< Cell*, int, Less_Cell >::iterator it = c1Cbd.begin(); it != c1Cbd.end(); it++){ + Cell* c1CbdCell = (*it).first; + if(c3 == NULL){ + if(c2->hasCoboundary(c1CbdCell, true)) return c1CbdCell; + } + else{ + if(c2->hasCoboundary(c1CbdCell, true) && c3->hasCoboundary(c1CbdCell, true)) return c1CbdCell; + } + } + + return NULL; + +} + +std::pair<Cell*, int> Chain::findRemainingBoundary(Cell* b, Cell* c1, Cell* c2, Cell* c3){ + std::map<Cell*, int, Less_Cell> bBd = b->getOrgBd(); + for(std::map<Cell*, int, Less_Cell >::iterator it = bBd.begin(); it != bBd.end(); it++){ + Cell* bBdCell = (*it).first; + if(c3 == NULL) { + if( !(*bBdCell == *c1) && !(*bBdCell == *c2)) return *it; + } + else{ + if( !(*bBdCell == *c1) && !(*bBdCell == *c2) && !(*bBdCell == *c3) ) return *it; + } + } + + return std::make_pair(b, 0); +} + +int Chain::findOrientation(Cell* b, Cell* c){ + std::map< Cell*, int, Less_Cell > bBd = b->getOrgBd(); + std::map< Cell*, int, Less_Cell >::iterator it = bBd.find(c); + if(it != bBd.end()) return (*it).second; + return 0; +} + +void Chain::smoothenChain(){ + + int start = getSize(); + double t1 = Cpu(); + + if(getDim() == 1){ + for(citer i = _cells.begin(); i != _cells.end(); i++){ + Cell* c1 = (*i).first; + int c1c = (*i).second; + + for(citer j = _cells.begin(); j != _cells.end(); j++){ + Cell* c2 = (*j).first; + int c2c = (*j).second; + if ( !(*c2 == *c1) && (c1c == 1 || c1c == -1) && (c2c == 1 || c2c == -1)){ + + Cell* b = findCommonCbdCell(c1, c2); + if(b != NULL){ + + std::pair<Cell*, int> c3p = std::make_pair(b, 0); + c3p = findRemainingBoundary(b, c1, c2); + int c1o = findOrientation(b, c1); + int c2o = findOrientation(b, c2); + + int temp1 = c1c - c1o; + int temp2 = c2c - c2o; + + if(c3p.second != 0 && !c3p.first->inSubdomain()) { + + Cell* c3 = c3p.first; + int c3o = c3p.second; + + int c3c = -c3o; + if(temp1 != 0) c3c= c3c*-1; + + this->removeCell(c1, c1c); + this->removeCell(c2, c2c); + this->addCell(c3, c3c); + c1c = (*i).second; + c2c = (*j).second; + + } + } + } + } + } + } + /* + else if(getDim() == 2){ + for(citer i = _cells.begin(); i != _cells.end(); i++){ + Cell* c1 = (*i).first; + int c1c = (*i).second; + + /* + int c1o = 0; + + Cell* c2 = NULL; + int c2c = 0; + int c2o = 0; + + Cell* c3 = NULL; + int c3c = 0; + int c3o = 0; + + std::map<Cell*, int, Less_Cell> c1Cbd c1->getOrgCbd(); + for(citer cit = c1Cbd.begin(); cit != c1Cbd.end(); cit++){ + Cell* c1CbdCell = (*cit).first; + std::map<Cell*, int, Less_Cell> c1CbdBd c1CbdCell->getOrgBd(); + + for(citer cit2 = c1CbdBd.begin(); cit2 != c1CbdBd.end(); cit2++){ + Cell* c1CbdBdCell = (*cit2).first; + int c1CbdBdCellc = (*cit2).first; + int count = 0; + int coeff = getCoeff(c1CbdBdCell); + if(coeff != 0 && !(*c1CbdBdCell == *c1)){ + count++; + if(count == 0) { c2 = coeff; c2o=c1CbdBdCellc; } + if(count == 1) { c3 = coeff; c3o=c1CbdBdCellc; } + if(count == 2) break; + } + } + + } + + + + for(citer j = _cells.begin(); j != _cells.end(); j++){ + Cell* c2 = (*j).first; + int c2c = (*j).second; + + for(citer k = _cells.begin(); k != _cells.end(); k++){ + Cell* c3 = (*k).first; + int c3c = (*k).second; + + if ( !(*c2 == *c1) && !(*c1 == *c3) && !(*c2 == *c3) && (c1c == 1 || c1c == -1) && (c2c == 1 || c2c == -1) && (c3c == 1 || c3c == -1)){ + + Cell* b = findCommonCbdCell(c1, c2, c3); + if(b != NULL){ + + std::pair<Cell*, int> c4p = std::make_pair(b, 0); + c4p = findRemainingBoundary(b, c1, c2, c3); + int c1o = findOrientation(b, c1); + int c2o = findOrientation(b, c2); + int c3o = findOrientation(b, c3); + + int temp1 = c1c - c1o; + int temp2 = c2c - c2o; + int temp3 = c3c - c3o; + + if(c4p.second != 0 && !c4p.first->inSubdomain()) { + + Cell* c4 = c4p.first; + int c4o = c4p.second; + + int c4c = -c4o; + if(temp1 != 0) c4c= c4c*-1; + + this->removeCell(c1, c1c); + this->removeCell(c2, c2c); + this->removeCell(c3, c3c); + this->addCell(c4, c4c); + c1c = (*i).second; + c2c = (*j).second; + c3c = (*k).second; + } + } + } + } + } + + } + }*/ + + eraseNullCells(); + double t2 = Cpu(); + printf("Smoothened a %d-chain from %d cells to %d cells (%g s). \n", getDim(), start, getSize(), t2-t1); + return; +} + +int Chain::writeChainMSH(const std::string &name){ + //_cellComplex->writeComplexMSH(name); if(getSize() == 0) return 0; @@ -483,7 +678,7 @@ int Chain::writeChainMSH(const std::string &name){ printf("Unable to open file."); return 0; } - + fprintf(fp, "\n$ElementData\n"); fprintf(fp, "1 \n"); @@ -493,17 +688,21 @@ int Chain::writeChainMSH(const std::string &name){ fprintf(fp, "4 \n"); fprintf(fp, "0 \n"); fprintf(fp, "1 \n"); - fprintf(fp, "%d \n", getNumCells()); + fprintf(fp, "%d \n", getSize()); fprintf(fp, "0 \n"); - std::list< std::pair<int, Cell*> > cells; - for(int i = 0; i < getSize(); i++){ - Cell* cell = getCell(i); - cells = cell->getCells(); + //std::list< std::pair<int, Cell*> > cells; + for(citer cit = _cells.begin(); cit != _cells.end(); cit++){ + Cell* cell = (*cit).first; + int coeff = (*cit).second; + fprintf(fp, "%d %d \n", cell->getNum(), coeff ); + /* + cells = cell->getCells(); for(std::list< std::pair<int, Cell*> >::iterator it = cells.begin(); it != cells.end(); it++){ Cell* cell2 = (*it).second; - fprintf(fp, "%d %d \n", cell2->getNum(), getCoeff(i)*(*it).first ); + fprintf(fp, "%d %d \n", cell2->getNum(), getCoeff(i)*(*it).first ); } + */ } fprintf(fp, "$EndElementData\n"); @@ -514,13 +713,15 @@ int Chain::writeChainMSH(const std::string &name){ } +/* void Chain::getData(std::map<int, std::vector<double> > & data){ if(getSize() == 0) return; - std::list< std::pair<int, Cell*> > cells; + //std::list< std::pair<int, Cell*> > cells; for(int i = 0; i < getSize(); i++){ Cell* cell = getCell(i); + /* cells = cell->getCells(); for(std::list< std::pair<int, Cell*> >::iterator it = cells.begin(); it != cells.end(); it++){ Cell* cell2 = (*it).second; @@ -531,6 +732,12 @@ void Chain::getData(std::map<int, std::vector<double> > & data){ //printf("%d, %d, \n", cell2->getNum(), (int)coeff.at(0)); } + + std::vector<double> coeff; + coeff.push_back(getCoeff(i)); + std::pair<int, std::vector<double> > dataPair = std::make_pair(cell->getTag(), coeff); + data.insert(dataPair); + } //for(std::map<int, std::vector<double> >::iterator it = data.begin(); it != data.end(); it++){ @@ -539,5 +746,6 @@ void Chain::getData(std::map<int, std::vector<double> > & data){ return; } +*/ #endif diff --git a/Geo/ChainComplex.h b/Geo/ChainComplex.h index c54ed874db0810061003e57343653a80f747914d..d4527bbb98445a4691d20a5663464d398bee1ec6 100644 --- a/Geo/ChainComplex.h +++ b/Geo/ChainComplex.h @@ -133,7 +133,7 @@ class Chain{ private: // cells and their coefficients in this chain - std::vector< std::pair <Cell*, int> > _cells; + std::map< Cell*, int, Less_Cell > _cells; // name of the chain (optional) std::string _name; // cell complex this chain belongs to @@ -141,28 +141,137 @@ class Chain{ int _torsion; + int _dim; + + std::pair<Cell*, int> findRemainingBoundary(Cell* b, Cell* c1, Cell* c2, Cell* c3=NULL); + Cell* findCommonCbdCell(Cell* c1, Cell* c2, Cell* c3=NULL); + int findOrientation(Cell* b, Cell* c); + public: Chain(){} Chain(std::set<Cell*, Less_Cell> cells, std::vector<int> coeffs, CellComplex* cellComplex, std::string name="Chain", int torsion=0); + Chain(Chain* chain){ + _cells = chain->getCells(); + _torsion = chain->getTorsion(); + _name = chain->getName(); + _cellComplex = chain->getCellComplex(); + _dim = chain->getDim(); + } ~Chain(){} + typedef std::map<Cell*, int, Less_Cell>::iterator citer; + // get i:th cell of this chain - 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 - int getCoeff(int i) { return _cells.at(i).second; } + //int getCoeff(int i) { return _cells.at(i).second; } + + + + void removeCell(Cell* cell, int coeff) { + citer it = _cells.find(cell); + if(it != _cells.end()){ + //int coeff2 = (*it).second; + //(*it).second = coeff2 - coeff; + (*it).second = 0; + //printf("removed %d, %d :", cell->getNum(), coeff); cell->printCell(); + //_cells.erase(it); + //if((*it).second == 0) _cells.erase(it); + } + return; + } + void addCell(Cell* cell, int coeff) { + citer it = _cells.find(cell); + /* + if(it != _cells.end()){ + int coeff2 = (*it).second; + (*it).second = coeff2 + coeff; + //if((*it).second == 0) _cells.erase(it); + } + else{*/ + //printf("added %d, %d :", cell->getNum(), coeff); cell->printCell(); + _cells.insert( std::make_pair( cell, coeff)); + //cell->setImmune(true); + //cell->clearBoundary(); + //cell->clearCoboundary(); + //_cellComplex->insertCell(cell); + if(!_cellComplex->hasCell(cell)){ + _cellComplex->insertCell(cell); + } + + //} + return; + } + /* + void insertCells(){ + for(citer cit = _cells.begin(); cit != _cells.end(); cit++){ + Cell* cell = (*cit).first; + std::vector<Cell*> cells; + if(!_cellComplex->hasCell(cell)){ + _cellComplex->insertCell(cell); + } + + } + return; + } + */ + + bool hasCell(Cell* c){ + citer it = _cells.find(c); + if(it != _cells.end() && (*it).second != 0) return true; + return false; + } + Cell* findCell(Cell* c){ + citer it = _cells.find(c); + if(it != _cells.end() && (*it).second != 0) return (*it).first; + return NULL; + } + int getCoeff(Cell* c){ + citer it = _cells.find(c); + if(it != _cells.end()) return (*it).second; + return 0; + } + + + int getTorsion() {return _torsion;} + int getDim() {return _dim;} + CellComplex* getCellComplex() {return _cellComplex;} + std::map<Cell*, int, Less_Cell> getCells() {return _cells;} + + void eraseNullCells(){ + for(citer cit = _cells.begin(); cit != _cells.end(); cit++){ + if( (*cit).second == 0){ + _cells.erase(cit); + ++cit; + } + } + for(citer cit = _cells.begin(); cit != _cells.end(); cit++){ + if( (*cit).second == 0){ + _cells.erase(cit); + cit = _cells.begin(); + } + } + + + return; + } // number of cells in this chain - int getSize() { return _cells.size(); } + int getSize() { + //eraseNullCells(); + return _cells.size(); + } int getNumCells() { - int count = 0; - for(std::vector< std::pair <Cell*, int> >::iterator it = _cells.begin(); it != _cells.end(); it++){ - Cell* cell = (*it).first; - count = count + cell->getNumCells(); - } - return count; + //int count = 0; + //for(std::vector< std::pair <Cell*, int> >::iterator it = _cells.begin(); it != _cells.end(); it++){ + // Cell* cell = (*it).first; + // count = count + cell->getNumCells(); + //} + //return count; + return _cells.size(); } @@ -170,13 +279,16 @@ class Chain{ std::string getName() { return _name; } void setName(std::string name) { _name=name; } - // append this chain to a 2.0 MSH ASCII file as $ElementData - int writeChainMSH(const std::string &name); + void smoothenChain(); - void getData(std::map<int, std::vector<double> >& data); + // append this chain to a 2.1 MSH ASCII file as $ElementData + int writeChainMSH(const std::string &name); + //void getData(std::map<int, std::vector<double> >& data); + }; - + #endif - + #endif + diff --git a/Geo/Homology.cpp b/Geo/Homology.cpp index a81a6b82ca1c012aea9b8dbbe19eb67d62c8a5fe..4a044c4b9938ac18ea1d4f5fdf0e4794a5d7609e 100644 --- a/Geo/Homology.cpp +++ b/Geo/Homology.cpp @@ -84,7 +84,7 @@ void Homology::findGenerators(std::string fileName){ int omitted = _cellComplex->reduceComplex(_omit); //_cellComplex->printEuler(); - _cellComplex->emptyTrash(); + //_cellComplex->emptyTrash(); if(getCombine()){ _cellComplex->combine(3); @@ -96,7 +96,7 @@ void Homology::findGenerators(std::string fileName){ _cellComplex->checkCoherence(); //_cellComplex->printEuler(); - _cellComplex->emptyTrash(); + //_cellComplex->emptyTrash(); double t2 = Cpu(); Msg::Info("Cell Complex reduction complete (%g s).", t2 - t1); @@ -105,7 +105,7 @@ void Homology::findGenerators(std::string fileName){ //for(int i = 0; i < 4; i++) { printf("Dim %d: \n", i); _cellComplex->printComplex(i); } - _cellComplex->writeComplexMSH(fileName); + //_cellComplex->writeComplexMSH(fileName); Msg::Info("Computing homology groups..."); t1 = Cpu(); @@ -113,7 +113,9 @@ void Homology::findGenerators(std::string fileName){ chains->computeHomology(); t2 = Cpu(); Msg::Info("Homology Computation complete (%g s).", t2 - t1); - + + std::vector<Chain*> chainVector; + int HRank[4]; for(int j = 0; j < 4; j++){ HRank[j] = 0; @@ -126,12 +128,20 @@ void Homology::findGenerators(std::string fileName){ std::string name = "H" + dimension + getDomainString() + generator; Chain* chain = new Chain(_cellComplex->getCells(j), chains->getCoeffVector(j,i), _cellComplex, name, chains->getTorsion(j,i)); - chain->writeChainMSH(fileName); + Chain* chain2 = new Chain(chain); + //printf("chain %d \n", i); + t1 = Cpu(); + int start = chain->getSize(); + chain->smoothenChain(); + t2 = Cpu(); + Msg::Info("Smoothened H%d %d from %d cells to %d cells (%g s).", j, i, start, chain->getSize(), t2 - t1); if(chain->getSize() != 0) { HRank[j] = HRank[j] + 1; if(chain->getTorsion() != 1) Msg::Warning("H%d %d has torsion coefficient %d!", j, i, chain->getTorsion()); } - delete chain; + chainVector.push_back(chain); + chainVector.push_back(chain2); + //delete chain; } if(j == _cellComplex->getDim() && _cellComplex->getNumOmitted() > 0){ for(int i = 0; i < _cellComplex->getNumOmitted(); i++){ @@ -140,16 +150,25 @@ void Homology::findGenerators(std::string fileName){ std::string name = "H" + dimension + getDomainString() + generator; std::vector<int> coeffs (_cellComplex->getOmitted(i).size(),1); Chain* chain = new Chain(_cellComplex->getOmitted(i), coeffs, _cellComplex, name, 1); - chain->writeChainMSH(fileName); if(chain->getSize() != 0) HRank[j] = HRank[j] + 1; - delete chain; - + //delete chain; + chainVector.push_back(chain); } } } + _cellComplex->writeComplexMSH(fileName); + for(int i = 0; i < chainVector.size(); i++){ + Chain* chain = chainVector.at(i); + chain->writeChainMSH(fileName); + chainVector.at(i) = NULL; + delete chain; + } + chainVector.clear(); + + Msg::Info("Ranks of homology groups for primal cell complex:"); Msg::Info("H0 = %d", HRank[0]); Msg::Info("H1 = %d", HRank[1]); @@ -177,7 +196,7 @@ void Homology::findDualGenerators(std::string fileName){ Msg::Info("Reducing Cell Complex..."); double t1 = Cpu(); int omitted = _cellComplex->coreduceComplex(_omit); - _cellComplex->emptyTrash(); + //_cellComplex->emptyTrash(); /* _cellComplex->makeDualComplex(); @@ -196,7 +215,7 @@ void Homology::findDualGenerators(std::string fileName){ _cellComplex->cocombine(2); } - _cellComplex->emptyTrash(); + //_cellComplex->emptyTrash(); _cellComplex->checkCoherence(); double t2 = Cpu(); @@ -288,10 +307,10 @@ void Homology::computeBettiNumbers(){ double t2 = Cpu(); Msg::Info("Betti number computation complete (%g s).", t2- t1); - Msg::Info("H0 = %d \n", _cellComplex->getBettiNumber(0)); - Msg::Info("H1 = %d \n", _cellComplex->getBettiNumber(1)); - Msg::Info("H2 = %d \n", _cellComplex->getBettiNumber(2)); - Msg::Info("H3 = %d \n", _cellComplex->getBettiNumber(3)); + Msg::Info("H0 = %d", _cellComplex->getBettiNumber(0)); + Msg::Info("H1 = %d", _cellComplex->getBettiNumber(1)); + Msg::Info("H2 = %d", _cellComplex->getBettiNumber(2)); + Msg::Info("H3 = %d", _cellComplex->getBettiNumber(3)); return; } diff --git a/Geo/Homology.h b/Geo/Homology.h index c1e2e7b077dba11e074ce7d1aebeebe9ef11a825..c6e3a28ffe48029a7a0f7f14cb7f69b9fe78eda5 100644 --- a/Geo/Homology.h +++ b/Geo/Homology.h @@ -30,7 +30,7 @@ class Homology bool _combine; int _omit; - + std::vector<int> _domain; std::vector<int> _subdomain;