From c2f0b387b6535b1c6fdf462d3ca62c50243c78e9 Mon Sep 17 00:00:00 2001 From: Matti Pellika <matti.pellikka@tut.fi> Date: Fri, 3 Jul 2009 12:17:06 +0000 Subject: [PATCH] Bugfixes. Reverted the possibility to omit generators in multiple dimensions. --- Geo/CellComplex.cpp | 203 ++++++++++++++++++++++++++++----- Geo/ChainComplex.cpp | 1 - Geo/Homology.cpp | 17 ++- Geo/Homology.h | 8 +- Plugin/HomologyComputation.cpp | 1 + 5 files changed, 193 insertions(+), 37 deletions(-) diff --git a/Geo/CellComplex.cpp b/Geo/CellComplex.cpp index bf2ccd4894..ef1e70ab96 100644 --- a/Geo/CellComplex.cpp +++ b/Geo/CellComplex.cpp @@ -6,6 +6,7 @@ // Contributed by Matti Pellikka. #include "CellComplex.h" +#include "OS.h" #if defined(HAVE_KBIPACK) @@ -354,7 +355,6 @@ int CellComplex::reduction(int dim){ removeCell(cbd_c.front()); removeCell(cell); - //removeCell(cbd_c.front()); count++; reduced = true; } @@ -363,9 +363,95 @@ int CellComplex::reduction(int dim){ return count; } +/* +int CellComplex::reduction(Cell* generator){ + + int coreductions = 0; + + std::queue<Cell*> Q; + std::set<Cell*, Less_Cell> Qset; + + Q.push(generator); + Qset.insert(generator); + + + std::list<Cell*> cbd_s; + std::list<Cell*> bd_c; + Cell* s; + int round = 0; + while( !Q.empty() ){ + round++; + //printf("%d ", round); + + s = Q.front(); + Q.pop(); + removeCellQset(s, Qset); - + cbd_s = s->getCoboundary(); + if( cbd_s.size() == 1 && inSameDomain(s, cbd_s.front()) ){ + removeCell(s); + bd_c = bd_s.front()->getBoundary(); + enqueueCells(cbd_c, Q, Qset); + removeCell(cbd_s.front()); + reductions++; + } + else if(cbd_s.empty()){ + bd_c = s->getBoundary(); + enqueueCells(bd_c, Q, Qset); + } + + + } + //printf("Coreduction: %d loops with %d coreductions\n", round, coreductions); + return reductions; +} +*/ +/* +int CellComplex::reduction(int dim){ + if(dim < 1 || dim > 3) return 0; + std::list<Cell*> cbd_c; + std::list<Cell*> bd_c; + int count = 0; + + std::queue<Cell*> Q; + std::set<Cell*, Less_Cell> Qset; + + + for(citer cit = firstCell(dim-1); cit != lastCell(dim-1); cit++){ + + Cell* cell = *cit; + Q.push(cell); + Qset.insert(cell); + + while(Q.size() != 0){ + + Cell* s = Q.front(); + Q.pop(); + cbd_c = s->getCoboundary(); + if( cbd_c.size() == 1 && inSameDomain(s, cbd_c.front()) ){ + + removeCell(cbd_c.front()); + removeCell(s); + count++; + bd_c = cbd_c.front()->getBoundary(); + enqueueCells(bd_c, Q, Qset); + + cit = firstCell(dim-1); + } + + removeCellQset(s, Qset); + + } + } + + return count; +} +*/ + int CellComplex::reduceComplex(int omit){ + + double t1 = Cpu(); + printf("Cell complex before reduction: %d volumes, %d faces, %d edges and %d vertices.\n", getSize(3), getSize(2), getSize(1), getSize(0)); @@ -373,46 +459,49 @@ int CellComplex::reduceComplex(int omit){ for(int i = 3; i > 0; i--) count = count + reduction(i); - + int omitted = 0; if(omit > getDim()) omit = getDim(); - for(int i = 0; i < omit; i++){ - //if(count == 0 && omit > 0){ - + + if(count == 0 && omit > 0){ + + CellComplex::removeSubdomain(); CellComplex::removeSubdomain(); std::set<Cell*, Less_Cell> generatorCells; - - - while (getSize(getDim()-i) != 0){ - citer cit = firstCell(getDim()-i); + + while (getSize(getDim()) != 0){ + + citer cit = firstCell(getDim()); Cell* cell = *cit; generatorCells.insert(cell); removeCell(cell); - - reduction(3); - reduction(2); - reduction(1); + + //makeDualComplex(); + //coreduction(cell); + //makeDualComplex(); + for(int j = 3; j > 0; j--) reduction(j); omitted++; - } - - + } + + for(citer cit = generatorCells.begin(); cit != generatorCells.end(); cit++){ Cell* cell = *cit; cell->clearBoundary(); cell->clearCoboundary(); - _cells[getDim()-i].insert(cell); + _cells[cell->getDim()].insert(cell); } - - + } - printf("Cell complex after reduction: %d volumes, %d faces, %d edges and %d vertices.\n", - getSize(3), getSize(2), getSize(1), getSize(0)); - return omitted; + double t2 = Cpu(); + printf("Cell complex after reduction: %d volumes, %d faces, %d edges and %d vertices (%g s).\n", + getSize(3), getSize(2), getSize(1), getSize(0), t2 - t1); + + return 0; } @@ -453,12 +542,12 @@ int CellComplex::coreduceComplex(int omit){ } int omitted = 0; - //if(count == 0 && omit > 0){ - if(omit > getDim()) omit = getDim(); - for(int i = 0; i < omit; i++){ + if(count == 0 && omit > 0){ + //if(omit > getDim()) omit = getDim(); + //for(int i = 0; i < omit; i++){ std::set<Cell*, Less_Cell> generatorCells; - while (getSize(i) != 0){ - citer cit = firstCell(i); + while (getSize(0) != 0){ + citer cit = firstCell(0); Cell* cell = *cit; generatorCells.insert(cell); removeCell(cell); @@ -471,7 +560,7 @@ int CellComplex::coreduceComplex(int omit){ Cell* cell = *cit; cell->clearBoundary(); cell->clearCoboundary(); - _cells[i].insert(cell); + _cells[0].insert(cell); } } @@ -573,6 +662,7 @@ int CellComplex::cocombine(int dim){ int CellComplex::combine(int dim){ + double t1 = Cpu(); printf("Cell complex before combining: %d volumes, %d faces, %d edges and %d vertices.\n", getSize(3), getSize(2), getSize(1), getSize(0)); @@ -623,14 +713,65 @@ int CellComplex::combine(int dim){ removeCellQset(s, Qset); } + } + double t2 = Cpu(); + printf("Cell complex after combining: %d volumes, %d faces, %d edges and %d vertices (%g s).\n", + getSize(3), getSize(2), getSize(1), getSize(0), t2 - t1); + + + return count; +} + +/* +int CellComplex::combine(int dim){ + double t1 = Cpu(); + printf("Cell complex before combining: %d volumes, %d faces, %d edges and %d vertices.\n", + getSize(3), getSize(2), getSize(1), getSize(0)); + + if(dim < 1 || dim > 3) return 0; + + std::list< std::pair<int, Cell*> > cbd_c; + std::list<Cell*> bd_c; + int count = 0; + bool combined = true; + while(combined){ + combined = false; + for(citer cit = firstCell(dim-1); cit != lastCell(dim-1); cit++){ + Cell* s = *cit; + 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; + + removeCell(s); + + 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-1); + count++; + combined = true; + } + } + } - printf("Cell complex after combining: %d volumes, %d faces, %d edges and %d vertices.\n", - getSize(3), getSize(2), getSize(1), getSize(0)); + double t2 = Cpu(); + printf("Cell complex after combining: %d volumes, %d faces, %d edges and %d vertices (%g s).\n", + getSize(3), getSize(2), getSize(1), getSize(0), t2 - t1); return count; } +*/ void CellComplex::swapSubdomain(){ diff --git a/Geo/ChainComplex.cpp b/Geo/ChainComplex.cpp index 56091c0688..37962355a8 100644 --- a/Geo/ChainComplex.cpp +++ b/Geo/ChainComplex.cpp @@ -384,7 +384,6 @@ void ChainComplex::computeHomology(bool dual){ } - destroy_gmp_matrix(getKerHMatrix(lowDim)); destroy_gmp_matrix(getCodHMatrix(lowDim)); destroy_gmp_matrix(getJMatrix(lowDim)); diff --git a/Geo/Homology.cpp b/Geo/Homology.cpp index 657de3d120..aebc84b249 100644 --- a/Geo/Homology.cpp +++ b/Geo/Homology.cpp @@ -103,7 +103,7 @@ void Homology::findGenerators(std::string fileName){ chains->computeHomology(); t2 = Cpu(); Msg::Info("Homology Computation complete (%g s).", t2 - t1); - + int HRank[4]; for(int j = 0; j < 4; j++){ HRank[j] = 0; @@ -151,14 +151,23 @@ void Homology::findThickCuts(std::string fileName){ Msg::Info("Reducing Cell Complex..."); double t1 = Cpu(); int omitted = _cellComplex->coreduceComplex(_omit); - //for(int i = 0; i < 4; i++) { printf("Dim %d: \n", i); _cellComplex->printComplex(i); } - //_cellComplex->coreduceComplex(false); - //_cellComplex->checkCoherence(); + /* + _cellComplex->makeDualComplex(); + int omitted = _cellComplex->reduceComplex(_omit); + if(getCombine()){ + _cellComplex->combine(3); + _cellComplex->combine(2); + _cellComplex->combine(1); + } + _cellComplex->makeDualComplex(); + */ + if(getCombine()){ _cellComplex->cocombine(0); _cellComplex->cocombine(1); _cellComplex->cocombine(2); } + _cellComplex->checkCoherence(); double t2 = Cpu(); Msg::Info("Cell Complex reduction complete (%g s).", t2 - t1); diff --git a/Geo/Homology.h b/Geo/Homology.h index fd572aeb96..030fd4c1be 100644 --- a/Geo/Homology.h +++ b/Geo/Homology.h @@ -45,13 +45,19 @@ class Homology void swapSubdomain() { _cellComplex->swapSubdomain(); } int getOmit() {return _omit; } - void setOmit(int omit) { + void setOmit(int omit) { + if(omit == 0) _omit = 0; + else _omit = 1; + + /* if(omit > _cellComplex->getDim() || omit < 0) { Msg::Error("Invalid number of dimensions to omit. Must be between 0 - %d.", _cellComplex->getDim()); Msg::Warning("Set to omit 1 dimension."); _omit = 1; } else _omit = omit; + */ + } }; diff --git a/Plugin/HomologyComputation.cpp b/Plugin/HomologyComputation.cpp index 6968bdf1bd..28a2e2f569 100644 --- a/Plugin/HomologyComputation.cpp +++ b/Plugin/HomologyComputation.cpp @@ -22,6 +22,7 @@ StringXNumber HomologyComputationOptions_Number[] = { {GMSH_FULLRC, "Compute generators", NULL, 1.}, {GMSH_FULLRC, "Compute thick cuts", NULL, 0.}, {GMSH_FULLRC, "Omit dimensions", NULL, 1.}, + //{GMSH_FULLRC, "Combine cells", NULL, 1.}, }; StringXString HomologyComputationOptions_String[] = { -- GitLab