From ec180db5ca03db44118415a946003c4750748d58 Mon Sep 17 00:00:00 2001 From: Matti Pellika <matti.pellikka@tut.fi> Date: Thu, 11 Jun 2009 12:41:55 +0000 Subject: [PATCH] Bugfixes to cell combining. I can still find examples where it fails. --- Geo/CellComplex.cpp | 65 ++++++++++-------- Geo/CellComplex.h | 122 +++++++++++++++++++++++++-------- Geo/ChainComplex.cpp | 20 ++++-- Geo/ChainComplex.h | 11 ++- Geo/Homology.cpp | 46 ++++++++++--- Geo/Homology.h | 5 ++ Plugin/HomologyComputation.cpp | 24 ++++--- 7 files changed, 213 insertions(+), 80 deletions(-) diff --git a/Geo/CellComplex.cpp b/Geo/CellComplex.cpp index cee51bcecc..d7823ca2fb 100644 --- a/Geo/CellComplex.cpp +++ b/Geo/CellComplex.cpp @@ -105,11 +105,12 @@ CellComplex::CellComplex( std::vector<GEntity*> domain, std::vector<GEntity*> su cell->setTag(tag); tag++; } - //_originalCells[i] = _cells[i]; + _cells2[i] = _cells[i]; _betti[i] = 0; if(getSize(i) > _dim) _dim = i; } + } void CellComplex::insert_cells(bool subdomain, bool boundary){ @@ -254,6 +255,8 @@ int OneSimplex::kappa(Cell* tau) const{ void CellComplex::removeCell(Cell* cell){ + //_trash.insert(cell); + _cells[cell->getDim()].erase(cell); std::list<Cell*> coboundary = cell->getCoboundary(); @@ -269,7 +272,6 @@ void CellComplex::removeCell(Cell* cell){ bdCell->removeCoboundaryCell(cell); } - //_trash.push_back(cell); } @@ -332,7 +334,6 @@ int CellComplex::coreduction(Cell* generator){ int CellComplex::reduction(int dim){ if(dim < 1 || dim > 3) return 0; - std::list<Cell*> cbd_c; int count = 0; @@ -343,7 +344,9 @@ int CellComplex::reduction(int dim){ Cell* cell = *cit; cbd_c = cell->getCoboundary(); if(cbd_c.size() == 1 && inSameDomain(cell, cbd_c.front()) ){ + removeCell(cell); + removeCell(cbd_c.front()); count++; reduced = true; @@ -362,24 +365,33 @@ int CellComplex::reduceComplex(bool omitHighdim){ int count = 0; for(int i = 3; i > 0; i--) count = count + reduction(i); + + int omitted = 0; if(count == 0 && omitHighdim){ - removeSubdomain(); + CellComplex::removeSubdomain(); + CellComplex::removeSubdomain(); std::set<Cell*, Less_Cell> generatorCells; - + while (getSize(getDim()) != 0){ citer cit = firstCell(getDim()); + Cell* cell = *cit; generatorCells.insert(cell); removeCell(cell); + reduction(3); + reduction(2); + reduction(1); + omitted++; + } - + for(citer cit = generatorCells.begin(); cit != generatorCells.end(); cit++){ Cell* cell = *cit; cell->clearBoundary(); @@ -390,7 +402,6 @@ int CellComplex::reduceComplex(bool omitHighdim){ } - printf("Cell complex after reduction: %d volumes, %d faces, %d edges and %d vertices.\n", getSize(3), getSize(2), getSize(1), getSize(0)); @@ -422,7 +433,7 @@ int CellComplex::coreduceComplex(bool omitLowdim){ int count = 0; CellComplex::removeSubdomain(); - + CellComplex::removeSubdomain(); for(int dim = 0; dim < 4; dim++){ citer cit = firstCell(dim); @@ -495,7 +506,7 @@ void CellComplex::computeBettiNumbers(){ void CellComplex::replaceCells(Cell* c1, Cell* c2, Cell* newCell, bool orMatch, bool co){ int dim = c1->getDim(); - + std::list< std::pair<int, Cell*> > coboundary1 = c1->getOrientedCoboundary(); std::list< std::pair<int, Cell*> > coboundary2 = c2->getOrientedCoboundary(); std::list< std::pair<int, Cell*> > boundary1 = c1->getOrientedBoundary(); @@ -506,7 +517,7 @@ void CellComplex::replaceCells(Cell* c1, Cell* c2, Cell* newCell, bool orMatch, Cell* cbdCell = (*it).second; int ori = (*it).first; cbdCell->removeBoundaryCell(c1); - cbdCell->addBoundaryCell(ori, newCell); + cbdCell->addBoundaryCell(ori, newCell, true); } for(std::list< std::pair<int, Cell*> >::iterator it = coboundary2.begin(); it != coboundary2.end(); it++){ Cell* cbdCell = (*it).second; @@ -519,16 +530,16 @@ void CellComplex::replaceCells(Cell* c1, Cell* c2, Cell* newCell, bool orMatch, Cell* cell2 = (*it2).second; if(*cell2 == *cbdCell) old = true; } - if(!old) cbdCell->addBoundaryCell(ori, newCell); + if(!old) cbdCell->addBoundaryCell(ori, newCell, true); } - else cbdCell->addBoundaryCell(ori, newCell); + else cbdCell->addBoundaryCell(ori, newCell, true); } for(std::list< std::pair<int, Cell* > >::iterator it = boundary1.begin(); it != boundary1.end(); it++){ Cell* bdCell = (*it).second; int ori = (*it).first; bdCell->removeCoboundaryCell(c1); - bdCell->addCoboundaryCell(ori, newCell); + bdCell->addCoboundaryCell(ori, newCell, true); } for(std::list< std::pair<int, Cell* > >::iterator it = boundary2.begin(); it != boundary2.end(); it++){ Cell* bdCell = (*it).second; @@ -541,14 +552,16 @@ void CellComplex::replaceCells(Cell* c1, Cell* c2, Cell* newCell, bool orMatch, Cell* cell2 = (*it2).second; if(*cell2 == *bdCell) old = true; } - if(!old) bdCell->addCoboundaryCell(ori, newCell); + if(!old) bdCell->addCoboundaryCell(ori, newCell, true); } - else bdCell->addCoboundaryCell(ori, newCell); + else bdCell->addCoboundaryCell(ori, newCell, true); } _cells[dim].erase(c1); _cells[dim].erase(c2); + //_trash.insert(c1); + //_trash.insert(c2); _cells[dim].insert(newCell); @@ -584,6 +597,8 @@ int CellComplex::cocombine(int dim){ if(bd_c.size() == 2 && !(*(bd_c.front().second) == *(bd_c.back().second)) && inSameDomain(s, bd_c.front().second) && inSameDomain(s, bd_c.back().second) ){ + int or1 = bd_c.front().first; + int or2 = bd_c.back().first; Cell* c1 = bd_c.front().second; Cell* c2 = bd_c.back().second; @@ -591,16 +606,14 @@ int CellComplex::cocombine(int dim){ enqueueCells(cbd_c, Q, Qset); cbd_c = c2->getCoboundary(); enqueueCells(cbd_c, Q, Qset); - - int or1 = bd_c.front().first; - int or2 = bd_c.back().first; - + removeCell(s); CombinedCell* newCell = new CombinedCell(c1, c2, (or1 != or2), true ); replaceCells(c1, c2, newCell, (or1 != or2), true); cit = firstCell(dim); count++; + } removeCellQset(s, Qset); @@ -641,25 +654,23 @@ int CellComplex::combine(int dim){ if(cbd_c.size() == 2 && !(*(cbd_c.front().second) == *(cbd_c.back().second)) && inSameDomain(s, cbd_c.front().second) && inSameDomain(s, cbd_c.back().second) ){ - + int or1 = cbd_c.front().first; + int or2 = cbd_c.back().first; Cell* c1 = cbd_c.front().second; Cell* c2 = cbd_c.back().second; - + bd_c = c1->getBoundary(); enqueueCells(bd_c, Q, Qset); bd_c = c2->getBoundary(); enqueueCells(bd_c, Q, Qset); - - int or1 = cbd_c.front().first; - int or2 = cbd_c.back().first; - + removeCell(s); CombinedCell* newCell = new CombinedCell(c1, c2, (or1 != or2) ); replaceCells(c1, c2, newCell, (or1 != or2)); - cit = firstCell(dim); //cit++; count++; + } removeCellQset(s, Qset); @@ -667,7 +678,7 @@ int CellComplex::combine(int dim){ } printf("Cell complex after combining: %d volumes, %d faces, %d edges and %d vertices.\n", - getSize(3), getSize(2), getSize(1), getSize(0)); + getSize(3), getSize(2), getSize(1), getSize(0)); return count; diff --git a/Geo/CellComplex.h b/Geo/CellComplex.h index 7c217e15ff..4a3e8d5877 100644 --- a/Geo/CellComplex.h +++ b/Geo/CellComplex.h @@ -88,6 +88,7 @@ class Cell for( std::list< std::pair<int, Cell*> >::iterator it= _boundary.begin();it!= _boundary.end();it++){ Cell* cell = (*it).second; boundary.push_back(cell); + if((*it).first == 0) boundary.push_back(cell); } return boundary; } @@ -97,26 +98,50 @@ class Cell for( std::list< std::pair<int, Cell*> >::iterator it= _coboundary.begin();it!= _coboundary.end();it++){ Cell* cell = (*it).second; coboundary.push_back(cell); + if((*it).first == 0) coboundary.push_back(cell); } return coboundary; } - virtual void addBoundaryCell(int orientation, Cell* cell) { _boundary.push_back( std::make_pair(orientation, cell)); } - virtual void addCoboundaryCell(int orientation, Cell* cell) { _coboundary.push_back( std::make_pair(orientation, cell)); } + virtual void addBoundaryCell(int orientation, Cell* cell, bool duplicates=false) { + if(!duplicates){ + for(std::list< std::pair<int, Cell*> >::iterator it = _boundary.begin(); it != _boundary.end(); it++){ + Cell* cell2 = (*it).second; + int ori2 = (*it).first; + if(*cell2 == *cell && !duplicates) return; + } + } + _boundary.push_back( std::make_pair(orientation, cell)); + + } + virtual void addCoboundaryCell(int orientation, Cell* cell, bool duplicates=false) { + if(!duplicates){ + for(std::list< std::pair<int, Cell*> >::iterator it = _coboundary.begin(); it != _coboundary.end(); it++){ + Cell* cell2 = (*it).second; + int ori2 = (*it).first; + if(*cell2 == *cell && !duplicates) return; + } + } + _coboundary.push_back( std::make_pair(orientation, cell)); + } - virtual void removeBoundaryCell(Cell* cell) { + virtual int removeBoundaryCell(Cell* cell) { + int count = 0; for(std::list< std::pair<int, Cell*> >::iterator it = _boundary.begin(); it != _boundary.end(); it++){ Cell* cell2 = (*it).second; - if(*cell2 == *cell) { _boundary.erase(it); break; } + if(*cell2 == *cell) { _boundary.erase(it); count++; it = _boundary.begin(); } } + return count; } - virtual void removeCoboundaryCell(Cell* cell) { + virtual int removeCoboundaryCell(Cell* cell) { + int count = 0; for(std::list< std::pair<int, Cell*> >::iterator it = _coboundary.begin(); it != _coboundary.end(); it++){ Cell* cell2 = (*it).second; - if(*cell2 == *cell) { _coboundary.erase(it); break; } + if(*cell2 == *cell) { _coboundary.erase(it); count++; it = _coboundary.begin(); } } + return count; } - + virtual void clearBoundary() { _boundary.clear(); } virtual void clearCoboundary() { _coboundary.clear(); } @@ -187,6 +212,7 @@ class Simplex : public Cell public: Simplex() : Cell() { _combined = false; + _index = 0; } ~Simplex(){} @@ -413,6 +439,7 @@ class CombinedCell : public Cell{ public: CombinedCell(Cell* c1, Cell* c2, bool orMatch, bool co=false) : Cell(){ + _index = c1->getIndex(); _tag = c1->getTag(); _dim = c1->getDim(); _inSubdomain = c1->inSubdomain(); @@ -518,7 +545,9 @@ class CellComplex // one for each dimension std::set<Cell*, Less_Cell> _cells[4]; - std::vector<Cell*> _trash; + // trashbin for cell pointers removed from cell complex + std::set<Cell*, Less_Cell> _cells2[4]; + std::set<Cell*, Less_Cell> _trash; //std::set<Cell*, Less_Cell> _originalCells[4]; @@ -531,7 +560,7 @@ class CellComplex // iterator for the cells of same dimension typedef std::set<Cell*, Less_Cell>::iterator citer; - protected: + private: // enqueue cells in queue if they are not there already void enqueueCells(std::list<Cell*>& cells, std::queue<Cell*>& Q, std::set<Cell*, Less_Cell>& Qset); @@ -542,6 +571,19 @@ class CellComplex //virtual void insert_cells(bool subdomain, bool boundary); void insert_cells(bool subdomain, bool boundary); + // remove a cell from this cell complex + void removeCell(Cell* cell); + void replaceCells(Cell* c1, Cell* c2, Cell* newCell, bool orMatch, bool co=false); + void insertCell(Cell* cell); + + // reduction of this cell complex + // removes reduction pairs of cell of dimension dim and dim-1 + int reduction(int dim); + + // queued coreduction presented in Mrozek's paper + int coreduction(Cell* generator); + + public: CellComplex( std::vector<GEntity*> domain, std::vector<GEntity*> subdomain, std::set<Cell*, Less_Cell> cells ) { _domain = domain; @@ -578,10 +620,19 @@ class CellComplex CellComplex( std::vector<GEntity*> domain, std::vector<GEntity*> subdomain ); CellComplex(){} ~CellComplex(){ - for(int i = 0; i < _trash.size(); i++){ - Cell* cell = _trash.at(i); - delete cell; + //for(std::set<Cell*, Less_Cell>::iterator it = _trash.begin(); it != _trash.end(); it++){ + // Cell* cell = *it; + // delete cell; + //} + + for(int i = 0; i < 4; i++){ + _cells[i].clear(); + for(citer cit = _cells2[i].begin(); cit != _cells2[i].end(); cit++){ + Cell* cell = *cit; + delete cell; + } } + } @@ -593,36 +644,23 @@ class CellComplex std::set<Cell*, Less_Cell> getCells(int dim){ return _cells[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 firstCell(int dim) {return _cells[dim].begin(); } + citer lastCell(int dim) {return _cells[dim].end(); } // kappa for two cells of this cell complex // implementation will vary depending on cell type inline int kappa(Cell* sigma, Cell* tau) const { return sigma->kappa(tau); } - // remove a cell from this cell complex - void removeCell(Cell* cell); - void replaceCells(Cell* c1, Cell* c2, Cell* newCell, bool orMatch, bool co=false); - - - void insertCell(Cell* cell); // check whether two cells both belong to subdomain or if neither one does bool inSameDomain(Cell* c1, Cell* c2) const { return ( (!c1->inSubdomain() && !c2->inSubdomain()) || (c1->inSubdomain() && c2->inSubdomain()) ); } - - - // reduction of this cell complex - // removes reduction pairs of cell of dimension dim and dim-1 - int reduction(int dim); - + // useful functions for (co)reduction of cell complex int reduceComplex(bool omitHighdim = false); int coreduceComplex(bool omitlowDim = false); - // queued coreduction presented in Mrozek's paper - int coreduction(Cell* generator); // add every volume, face and edge its missing boundary cells // void repairComplex(int i=3); @@ -640,6 +678,13 @@ class CellComplex int combine(int dim); int cocombine(int dim); + void emptyTrash() { + for(std::set<Cell*, Less_Cell>::iterator it = _trash.begin(); it != _trash.end(); it++){ + Cell* cell = *it; + delete cell; + } + } + void computeBettiNumbers(); int getBettiNumber(int i) { if(i > -1 && i < 4) return _betti[i]; else return 0; } @@ -659,6 +704,27 @@ class CellComplex } } + void 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; + for(std::list< std::pair<int, Cell* > >::iterator it = boundary.begin(); it != boundary.end(); it++){ + Cell* bdCell = (*it).second; + citer cit = _cells[bdCell->getDim()].find(bdCell); + if(cit == lastCell(bdCell->getDim())) printf("Warning! Incoherent boundary!"); + } + std::list< std::pair<int, Cell*> > coboundary; + for(std::list< std::pair<int, Cell* > >::iterator it = coboundary.begin(); it != coboundary.end(); it++){ + Cell* cbdCell = (*it).second; + citer cit = _cells[cbdCell->getDim()].find(cbdCell); + if(cit == lastCell(cbdCell->getDim())) printf("Warning! Incoherent coboundary!"); + } + + } + } + } + }; #endif diff --git a/Geo/ChainComplex.cpp b/Geo/ChainComplex.cpp index 769e610b4d..fefc4e1006 100644 --- a/Geo/ChainComplex.cpp +++ b/Geo/ChainComplex.cpp @@ -76,11 +76,21 @@ ChainComplex::ChainComplex(CellComplex* cellComplex){ Cell* bdCell = (*it).second; if(!bdCell->inSubdomain()){ int old_elem = 0; - //printf("kaka1: %d, kaka2: %d \n", bdCell->getIndex(), cell->getIndex()); - 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); - gmp_matrix_set_elem(elem, bdCell->getIndex(), cell->getIndex(), _HMatrix[dim]); + //printf("cell1: %d, cell2: %d \n", bdCell->getIndex(), cell->getIndex()); + if(bdCell->getIndex() > gmp_matrix_rows( _HMatrix[dim]) || bdCell->getIndex() < 1 + || cell->getIndex() > gmp_matrix_cols( _HMatrix[dim]) || cell->getIndex() < 1){ + printf("Warning: Index out of bound! HMatrix: %d. \n", dim); + } + 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. \n", (old_elem + (*it).first), dim); + mpz_set_si(elem, 0); + } + gmp_matrix_set_elem(elem, bdCell->getIndex(), cell->getIndex(), _HMatrix[dim]); + } } } } diff --git a/Geo/ChainComplex.h b/Geo/ChainComplex.h index f5569a52d5..1b41eb7d02 100644 --- a/Geo/ChainComplex.h +++ b/Geo/ChainComplex.h @@ -77,7 +77,16 @@ class ChainComplex{ } _dim = 0; } - ~ChainComplex(){} + ~ChainComplex(){ + for(int i = 0; i < 5; i++){ + destroy_gmp_matrix(_HMatrix[i]); + destroy_gmp_matrix(_kerH[i]); + destroy_gmp_matrix(_codH[i]); + destroy_gmp_matrix(_JMatrix[i]); + destroy_gmp_matrix(_QMatrix[i]); + destroy_gmp_matrix(_Hbasis[i]); + } + } int getDim() { return _dim; } diff --git a/Geo/Homology.cpp b/Geo/Homology.cpp index 8a7b7b1543..18cdc81db9 100644 --- a/Geo/Homology.cpp +++ b/Geo/Homology.cpp @@ -14,6 +14,7 @@ Homology::Homology(GModel* model, std::vector<int> physicalDomain, std::vector<int> physicalSubdomain){ _model = model; + _combine = true; Msg::Info("Creating a Cell Complex..."); double t1 = Cpu(); @@ -74,14 +75,22 @@ 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); + //_cellComplex->checkCoherence(); + if(getCombine()){ + _cellComplex->combine(3); + _cellComplex->reduceComplex(false); + _cellComplex->combine(2); + _cellComplex->reduceComplex(false); + _cellComplex->combine(1); + _cellComplex->reduceComplex(false); + } + //_cellComplex->checkCoherence(); 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..."); @@ -119,29 +128,37 @@ void Homology::findGenerators(std::string fileName){ Msg::Info("H3 = %d", HRank[3]); if(omitted != 0) Msg::Info("Computation of %dD generators was omitted.", _cellComplex->getDim()); - Msg::Info("Wrote results to %s.", fileName.c_str()); delete chains; + printf("H0 = %d \n", HRank[0]); + printf("H1 = %d \n", HRank[1]); + printf("H2 = %d \n", HRank[2]); + printf("H3 = %d \n", HRank[3]); + return; } 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); + //_cellComplex->checkCoherence(); + 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); 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..."); @@ -153,6 +170,8 @@ void Homology::findThickCuts(std::string fileName){ 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; @@ -175,7 +194,7 @@ void Homology::findThickCuts(std::string fileName){ } } - + Msg::Info("Ranks of homology groups for dual cell complex:"); Msg::Info("H0 = %d", HRank[0]); Msg::Info("H1 = %d", HRank[1]); @@ -183,10 +202,15 @@ void Homology::findThickCuts(std::string fileName){ Msg::Info("H3 = %d", HRank[3]); if(omitted != 0) Msg::Info("Computation of %dD thick cuts was omitted.", dim); - Msg::Info("Wrote results to %s.", fileName.c_str()); delete chains; + printf("H0 = %d \n", HRank[0]); + printf("H1 = %d \n", HRank[1]); + printf("H2 = %d \n", HRank[2]); + printf("H3 = %d \n", HRank[3]); + + return; } #endif diff --git a/Geo/Homology.h b/Geo/Homology.h index b5f013653b..e53ca8bd8d 100644 --- a/Geo/Homology.h +++ b/Geo/Homology.h @@ -28,11 +28,16 @@ class Homology CellComplex* _cellComplex; GModel* _model; + bool _combine; + public: Homology(GModel* model, std::vector<int> physicalDomain, std::vector<int> physicalSubdomain); ~Homology(){ delete _cellComplex; } + bool getCombine() { return _combine; } + bool setCombine(bool combine) { _combine = combine; } + void findGenerators(std::string fileName); void findThickCuts(std::string fileName); diff --git a/Plugin/HomologyComputation.cpp b/Plugin/HomologyComputation.cpp index b7d4825630..41d6e8cbfb 100644 --- a/Plugin/HomologyComputation.cpp +++ b/Plugin/HomologyComputation.cpp @@ -15,11 +15,14 @@ #if defined(HAVE_KBIPACK) StringXNumber HomologyComputationOptions_Number[] = { - {GMSH_FULLRC, "Physical group for domain", NULL, 0.}, - {GMSH_FULLRC, "Physical group for subdomain", NULL, 0.}, + {GMSH_FULLRC, "1. Physical group for domain", NULL, 0.}, + {GMSH_FULLRC, "2. Physical group for domain", NULL, 0.}, + {GMSH_FULLRC, "1. Physical group for subdomain", NULL, 0.}, + {GMSH_FULLRC, "2. Physical group for subdomain", NULL, 0.}, {GMSH_FULLRC, "Compute generators", NULL, 1.}, {GMSH_FULLRC, "Compute thick cuts", NULL, 0.}, {GMSH_FULLRC, "Swap subdomain", NULL, 0.}, + {GMSH_FULLRC, "Combine cells", NULL, 1.} }; StringXString HomologyComputationOptions_String[] = { @@ -89,22 +92,27 @@ PView *GMSH_HomologyComputationPlugin::execute(PView *v) std::vector<int> subdomain; domain.push_back((int)HomologyComputationOptions_Number[0].def); - subdomain.push_back((int)HomologyComputationOptions_Number[1].def); + domain.push_back((int)HomologyComputationOptions_Number[1].def); + subdomain.push_back((int)HomologyComputationOptions_Number[2].def); + subdomain.push_back((int)HomologyComputationOptions_Number[3].def); - int gen = (int)HomologyComputationOptions_Number[2].def; - int cuts = (int)HomologyComputationOptions_Number[3].def; - int swap = (int)HomologyComputationOptions_Number[4].def; + int gens = (int)HomologyComputationOptions_Number[4].def; + int cuts = (int)HomologyComputationOptions_Number[5].def; + int swap = (int)HomologyComputationOptions_Number[6].def; + int combine = (int)HomologyComputationOptions_Number[7].def; GModel *m = GModel::current(); Homology* homology = new Homology(m, domain, subdomain); + if(combine == 0) homology->setCombine(false); + if(swap == 1) homology->swapSubdomain(); - if(gen == 1 && cuts != 1) { + if(gens == 1 && cuts != 1) { homology->findGenerators(fileName); GmshMergeFile(fileName); } - else if(cuts == 1 && gen != 1) { + else if(cuts == 1 && gens != 1) { homology->findThickCuts(fileName); GmshMergeFile(fileName); } -- GitLab