diff --git a/Geo/Cell.cpp b/Geo/Cell.cpp index 3b7895cbdd6e69e70de950ae538f42119208fb43..d8c773c4f8b7eae18272cf7b1c070907c1082187 100644 --- a/Geo/Cell.cpp +++ b/Geo/Cell.cpp @@ -374,7 +374,18 @@ void Cell::printCell() printf("combined: %d. \n" , isCombined() ); }; -void Cell::restoreCell(){ +void Cell::saveCellBoundary() +{ + for(biter it = firstCoboundary(); it != lastCoboundary(); it++){ + it->second.init(); + } + for(biter it = firstBoundary(); it != lastBoundary(); it++){ + it->second.init(); + } +} + +void Cell::restoreCellBoundary() +{ std::vector<Cell*> toRemove; for(biter it = firstCoboundary(true); it != lastCoboundary(); it++){ it->second.reset(); @@ -473,6 +484,74 @@ bool Cell::hasCoboundary(Cell* cell, bool orig) } } +Cell::biter Cell::firstBoundary(bool orig) +{ + biter it = _bd.begin(); + if(!orig) while(it->second.get() == 0 && it != _bd.end()) it++; + else while(it->second.geto() == 0 && it != _bd.end()) it++; + return it; +} + +Cell::biter Cell::lastBoundary() +{ + return _bd.end(); +} + +Cell::biter Cell::firstCoboundary(bool orig) +{ + biter it = _cbd.begin(); + if(!orig) while(it->second.get() == 0 && it != _cbd.end()) it++; + else while(it->second.geto() == 0 && it != _cbd.end()) it++; + return it; +} + +Cell::biter Cell::lastCoboundary() +{ + return _cbd.end(); +} + +int Cell::getBoundarySize(bool orig) +{ + int size = 0; + for(biter bit = _bd.begin(); bit != _bd.end(); bit++){ + if(!orig && bit->second.get() != 0) size++; + else if(orig && bit->second.geto() != 0) size++; + } + return size; +} + +int Cell::getCoboundarySize(bool orig) +{ + int size = 0; + for(biter bit = _cbd.begin(); bit != _cbd.end(); bit++){ + if(!orig && bit->second.get() != 0) size++; + else if(orig && bit->second.geto() != 0) size++; + } + return size; +} + +void Cell::getBoundary(std::map<Cell*, short int, Less_Cell>& boundary, + bool orig) +{ + boundary.clear(); + for(biter it = firstBoundary(); it != lastBoundary(); it++){ + Cell* cell = it->first; + if(!orig && it->second.get() != 0) boundary[cell] = it->second.get(); + if(orig && it->second.geto() != 0) boundary[cell] = it->second.geto(); + } +} + +void Cell::getCoboundary(std::map<Cell*, short int, Less_Cell>& coboundary, + bool orig) +{ + coboundary.clear(); + for(biter it = firstCoboundary(); it != lastCoboundary(); it++){ + Cell* cell = it->first; + if(!orig && it->second.get() != 0) coboundary[cell] = it->second.get(); + if(orig && it->second.geto() != 0) coboundary[cell] = it->second.geto(); + } +} + void Cell::printBoundary() { for(biter it = firstBoundary(); it != lastBoundary(); it++){ diff --git a/Geo/Cell.h b/Geo/Cell.h index 62d4fd6f8b0da76ec977eb9f5f8b084c00aa56c3..5c999d81c829665303af075ec10c848d9e581281 100644 --- a/Geo/Cell.h +++ b/Geo/Cell.h @@ -22,17 +22,16 @@ public: // Class to save cell boundary orientation information class BdInfo { private: - signed char _ori; - signed char _origOri; + signed char _ori[2]; public: - BdInfo(int ori) { _ori = ori; _origOri = 0; } + BdInfo(int ori) { _ori[0] = ori; _ori[1] = 0; } - int get() const { return _ori; } - void reset() { _ori = _origOri; } - void init() { _origOri = _ori; } - void set(int ori) { _ori = ori; } - int geto() const { return _origOri; } + int get() const { return _ori[0]; } + void reset() { _ori[0] = _ori[1]; } + void init() { _ori[1] = _ori[0]; } + void set(int ori) { _ori[0] = ori; } + int geto() const { return _ori[1]; } }; @@ -100,81 +99,37 @@ class Cell { void increaseGlobalNum() { _globalNum++; } - // restores the cell information to its original state before reduction - void restoreCell(); + // save/restore the original boundary information of the cell + void saveCellBoundary(); + void restoreCellBoundary(); // true if this cell has given vertex virtual bool hasVertex(int vertex) const; // (co)boundary cell iterator typedef std::map<Cell*, BdInfo, Less_Cell>::iterator biter; + // iterators to (first/last (co)boundary cells of this cell // (orig: to original (co)boundary cells of this cell) - biter firstBoundary(bool orig=false){ - biter it = _bd.begin(); - if(!orig) while(it->second.get() == 0 && it != _bd.end()) it++; - else while(it->second.geto() == 0 && it != _bd.end()) it++; - return it; - } - biter lastBoundary(){ return _bd.end(); } - biter firstCoboundary(bool orig=false){ - biter it = _cbd.begin(); - if(!orig) while(it->second.get() == 0 && it != _cbd.end()) it++; - else while(it->second.geto() == 0 && it != _cbd.end()) it++; - return it; - } - biter lastCoboundary(){ return _cbd.end(); } - - int getBoundarySize(bool orig=false) { - int size = 0; - for(biter bit = _bd.begin(); bit != _bd.end(); bit++){ - if(!orig && bit->second.get() != 0) size++; - else if(orig && bit->second.geto() != 0) size++; - } - return size; } - int getCoboundarySize(bool orig=false) { - int size = 0; - for(biter bit = _cbd.begin(); bit != _cbd.end(); bit++){ - if(!orig && bit->second.get() != 0) size++; - else if(orig && bit->second.geto() != 0) size++; - } - return size; } + biter firstBoundary(bool orig=false); + biter lastBoundary(); + biter firstCoboundary(bool orig=false); + biter lastCoboundary(); + + int getBoundarySize(bool orig=false); + int getCoboundarySize(bool orig=false); // get the (orig: original) cell boundary void getBoundary(std::map<Cell*, short int, Less_Cell>& boundary, - bool orig=false){ - boundary.clear(); - for(biter it = firstBoundary(); it != lastBoundary(); it++){ - Cell* cell = it->first; - if(!orig && it->second.get() != 0) boundary[cell] = it->second.get(); - if(orig && it->second.geto() != 0) boundary[cell] = it->second.geto(); - } - } + bool orig=false); void getCoboundary(std::map<Cell*, short int, Less_Cell>& coboundary, - bool orig=false){ - coboundary.clear(); - for(biter it = firstCoboundary(); it != lastCoboundary(); it++){ - Cell* cell = it->first; - if(!orig && it->second.get() != 0) coboundary[cell] = it->second.get(); - if(orig && it->second.geto() != 0) coboundary[cell] = it->second.geto(); - } - } - + bool orig=false); // add (co)boundary cell // (other: reciprocally also add this cell from the other cell's (co)boundary) void addBoundaryCell(int orientation, Cell* cell, bool other); void addCoboundaryCell(int orientation, Cell* cell, bool other); - void saveOriginalBd() { - for(biter it = firstCoboundary(); it != lastCoboundary(); it++){ - it->second.init(); - } - for(biter it = firstBoundary(); it != lastBoundary(); it++){ - it->second.init(); - } - } - // remove (co)boundary cell // (other: reciprocally also revove this cell from the other cell's (co)boundary) void removeBoundaryCell(Cell* cell, bool other); diff --git a/Geo/CellComplex.cpp b/Geo/CellComplex.cpp index 29b31d0bc4e4f8ae3271af1c5a105442d1a52ea6..f08f804863698311127a32b1e386b97ba26ebe7c 100644 --- a/Geo/CellComplex.cpp +++ b/Geo/CellComplex.cpp @@ -44,7 +44,7 @@ CellComplex::CellComplex(GModel* model, Cell* cell = *cit; cell->setNum(++num); cell->increaseGlobalNum(); - cell->saveOriginalBd(); + cell->saveCellBoundary(); } } @@ -316,7 +316,8 @@ int CellComplex::coreduction(Cell* startCell, int omit, Q.pop(); Qset.erase(s); if(s->getBoundarySize() == 1 && - inSameDomain(s, s->firstBoundary()->first)){ + inSameDomain(s, s->firstBoundary()->first) && + abs(s->firstBoundary()->second.get()) < 2){ s->getBoundary(bd_s); removeCell(s); bd_s.begin()->first->getCoboundary(cbd_c); @@ -341,6 +342,9 @@ int CellComplex::reduction(int dim, int omit, { if(dim < 1 || dim > 3) return 0; + int numCells[4]; + for(int i = 0; i < 4; i++) numCells[i] = getSize(i); + int count = 0; bool reduced = true; @@ -353,7 +357,8 @@ int CellComplex::reduction(int dim, int omit, if(cell->getCoboundarySize() == 1 && inSameDomain(cell, cell->firstCoboundary()->first) && !cell->getImmune() && - !cell->firstCoboundary()->first->getImmune()){ + !cell->firstCoboundary()->first->getImmune() && + abs(cell->firstCoboundary()->second.get()) < 2){ cit++; if(dim == omit){ omittedCells.push_back(cell->firstCoboundary()->first); @@ -369,6 +374,9 @@ int CellComplex::reduction(int dim, int omit, } } _reduced = true; + Msg::Debug("Cell complex %d-reduction removed %dv, %df, %de, %dn", dim, + numCells[3]-getSize(3), numCells[2]-getSize(2), + numCells[1]-getSize(1), numCells[0]-getSize(0)); return count; } @@ -377,6 +385,9 @@ int CellComplex::coreduction(int dim, int omit, { if(dim < 1 || dim > 3) return 0; + int numCells[4]; + for(int i = 0; i < 4; i++) numCells[i] = getSize(i); + int count = 0; bool reduced = true; @@ -387,7 +398,8 @@ int CellComplex::coreduction(int dim, int omit, while(cit != lastCell(dim)){ Cell* cell = *cit; if(cell->getBoundarySize() == 1 && - inSameDomain(cell, cell->firstBoundary()->first)) { + inSameDomain(cell, cell->firstBoundary()->first) && + abs(cell->firstBoundary()->second.get()) < 2) { ++cit; if(dim-1 == omit){ omittedCells.push_back(cell->firstBoundary()->first); @@ -403,6 +415,9 @@ int CellComplex::coreduction(int dim, int omit, } } _reduced = true; + Msg::Debug("Cell complex %d-coreduction removed %dv, %df, %de, %dn", dim, + numCells[3]-getSize(3), numCells[2]-getSize(2), + numCells[1]-getSize(1), numCells[0]-getSize(0)); return count; } @@ -428,11 +443,15 @@ int CellComplex::getDomain(Cell* cell, std::string& str) Cell* CellComplex::_omitCell(Cell* cell, bool dual) { + Msg::Debug("Omitting %d-cell from the cell complex", cell->getDim()); removeCell(cell, false); std::vector<Cell*> omittedCells; omittedCells.push_back(cell); int count = 0; + int numCells[4]; + for(int i = 0; i < 4; i++) numCells[i] = getSize(i); + if(!dual) { for(int j = 3; j > 0; j--) count += reduction(j, cell->getDim(), omittedCells); @@ -449,8 +468,10 @@ Cell* CellComplex::_omitCell(Cell* cell, bool dual) std::string domainstr = ""; int domain = getDomain(cell, domainstr); - Msg::Debug("Omitted %d-cell in %s that caused %d reductions", - cell->getDim(), domainstr.c_str(), count); + Msg::Debug("Cell complex %d-omit removed %dv, %df, %de, %dn", + cell->getDim(), + numCells[3]-getSize(3), numCells[2]-getSize(2), + numCells[1]-getSize(1), numCells[0]-getSize(0)); Msg::Debug(" - number of %d-cells left in %s: %d", cell->getDim(), domainstr.c_str(), getNumCells(cell->getDim(), domain)); @@ -460,10 +481,6 @@ Cell* CellComplex::_omitCell(Cell* cell, bool dual) int CellComplex::reduceComplex(int combine, bool omit, bool homseq) { - Msg::Debug("Cell Complex reduction:"); - Msg::Debug(" %d volumes, %d faces, %d edges, and %d vertices", - getSize(3), getSize(2), getSize(1), getSize(0)); - if(!getSize(0)) return 0; double t1 = Cpu(); @@ -510,9 +527,6 @@ int CellComplex::reduceComplex(int combine, bool omit, bool homseq) if(combine > 2) for(int i = 3; i > 0; i--) reduction(i, -1, empty); else if(combine > 1) reduction(0, -1, empty); - Msg::Debug(" %d volumes, %d faces, %d edges, and %d vertices", - getSize(3), getSize(2), getSize(1), getSize(0)); - _reduced = true; return count; } @@ -543,10 +557,6 @@ void CellComplex::removeCells(int dim) 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", - getSize(3), getSize(2), getSize(1), getSize(0)); - if(!getSize(0)) return 0; double t1 = Cpu(); @@ -618,8 +628,6 @@ int CellComplex::coreduceComplex(int combine, bool omit, int heuristic) else if(combine > 1) coreduction(3, -1, empty); coherent(); - Msg::Debug(" %d volumes, %d faces, %d edges, and %d vertices", - getSize(3), getSize(2), getSize(1), getSize(0)); _reduced = true; return count; @@ -682,11 +690,11 @@ std::vector<int> CellComplex::bettiCoreduceComplex() int CellComplex::combine(int dim) { - //Msg::Debug("Cell complex before combining:"); - //Msg::Debug(" %d volumes, %d faces, %d edges, and %d vertices", - // getSize(3), getSize(2), getSize(1), getSize(0)); if(dim < 1 || dim > 3) return 0; + int numCells[4]; + for(int i = 0; i < 4; i++) numCells[i] = getSize(i); + double t1 = Cpu(); std::queue<Cell*> Q; @@ -755,21 +763,20 @@ int CellComplex::combine(int dim) } } - //Msg::Debug("Cell complex after combining:"); - //Msg::Debug(" %d volumes, %d faces, %d edges, and %d vertices", - // getSize(3), getSize(2), getSize(1), getSize(0)); + Msg::Debug("Cell complex %d-combine removed %dv, %df, %de, %dn", dim, + numCells[3]-getSize(3), numCells[2]-getSize(2), + numCells[1]-getSize(1), numCells[0]-getSize(0)); _reduced = true; return count; } int CellComplex::cocombine(int dim) { - //Msg::Debug("Cell complex before cocombining:"); - //Msg::Debug(" %d volumes, %d faces, %d edges, and %d vertices", - //getSize(3), getSize(2), getSize(1), getSize(0)); - if(dim < 0 || dim > 2) return 0; + int numCells[4]; + for(int i = 0; i < 4; i++) numCells[i] = getSize(i); + double t1 = Cpu(); std::queue<Cell*> Q; @@ -839,9 +846,9 @@ int CellComplex::cocombine(int dim) } } - //Msg::Debug("Cell complex after cocombining:"); - //Msg::Debug(" %d volumes, %d faces, %d edges, and %d vertices", - // getSize(3), getSize(2), getSize(1), getSize(0)); + Msg::Debug("Cell complex %d-cocombine removed %dv, %df, %de, %dn", dim, + numCells[3]-getSize(3), numCells[2]-getSize(2), + numCells[1]-getSize(1), numCells[0]-getSize(0)); _reduced = true; return count; } @@ -973,7 +980,7 @@ bool CellComplex::restoreComplex() _cells[i] = _ocells[i]; for(citer cit = firstCell(i); cit != lastCell(i); cit++){ Cell* cell = *cit; - cell->restoreCell(); + cell->restoreCellBoundary(); if(relative()) { if(cell->inSubdomain()) _numSubdomainCells[i] += 1; else _numRelativeCells[i] += 1;