From 960960ea0b8a823712a58475f75bc0fbcdb4a247 Mon Sep 17 00:00:00 2001 From: Matti Pellika <matti.pellikka@tut.fi> Date: Sun, 17 Jan 2010 19:08:31 +0000 Subject: [PATCH] Hex/Quad working. Cleaning. --- Geo/Cell.cpp | 1 - Geo/Cell.h | 2 +- Geo/CellComplex.cpp | 59 ++++++++++++++++++++++++++++++++------------ Geo/CellComplex.h | 10 +++++--- Geo/ChainComplex.cpp | 1 - Geo/Homology.cpp | 18 +------------- Geo/Homology.h | 5 ++-- Parser/Gmsh.y | 2 +- 8 files changed, 54 insertions(+), 44 deletions(-) diff --git a/Geo/Cell.cpp b/Geo/Cell.cpp index 962a53b3ad..fdfb1a6fd4 100755 --- a/Geo/Cell.cpp +++ b/Geo/Cell.cpp @@ -243,7 +243,6 @@ CombinedCell::CombinedCell(Cell* c1, Cell* c2, bool orMatch, bool co) : Cell() { } _index = c1->getIndex(); - //_tag = c1->getTag(); _dim = c1->getDim(); _num = c1->getNum(); _inSubdomain = c1->inSubdomain(); diff --git a/Geo/Cell.h b/Geo/Cell.h index 3fb2439e83..dd5b41bb3b 100644 --- a/Geo/Cell.h +++ b/Geo/Cell.h @@ -169,7 +169,7 @@ class Cell virtual void printOrgCbd(); virtual bool inSubdomain() const { return _inSubdomain; } - //virtual void setInSubdomain(bool subdomain) { _inSubdomain = subdomain; } + virtual void setInSubdomain(bool subdomain) { _inSubdomain = subdomain; } virtual bool onDomainBoundary() const { return _onDomainBoundary; } virtual void setOnDomainBoundary(bool domainboundary) { _onDomainBoundary = domainboundary; } diff --git a/Geo/CellComplex.cpp b/Geo/CellComplex.cpp index cb2b779a5a..cd88192b04 100644 --- a/Geo/CellComplex.cpp +++ b/Geo/CellComplex.cpp @@ -18,9 +18,20 @@ CellComplex::CellComplex( std::vector<GEntity*> domain, std::vector<GEntity*> su _dim = 0; _simplicial = true; - // find boundary entities - find_boundary(domain, subdomain); + _multidim = false; + int dim = 0; + for(int i = 0; i < domain.size(); i++){ + GEntity* entity = domain.at(i); + if(i == 0) dim = entity->dim(); + if(dim != entity->dim()){ + _multidim = true; + Msg::Warning("Domain is not a manifold."); + } + } + // find boundary entities + if(!_multidim) find_boundary(domain, subdomain); + // insert cells into cell complex // subdomain need to be inserted first! insert_cells(true, true); @@ -34,7 +45,6 @@ CellComplex::CellComplex( std::vector<GEntity*> domain, std::vector<GEntity*> su if(getSize(i) > _dim) _dim = i; } - } void CellComplex::find_boundary(std::vector<GEntity*>& domain, std::vector<GEntity*>& subdomain){ @@ -97,8 +107,6 @@ void CellComplex::find_boundary(std::vector<GEntity*>& domain, std::vector<GEnti } void CellComplex::insert_cells(bool subdomain, bool boundary){ - - // works only for simplicial meshes at the moment! std::vector<GEntity*> domain; @@ -134,17 +142,17 @@ void CellComplex::insert_cells(bool subdomain, bool boundary){ else if(type == MSH_QUA_4 || type == MSH_QUA_8 || type == MSH_QUA_9){ cell = new Cell(domain.at(j)->getMeshElement(i), subdomain, boundary); _simplicial = false; - }/* FIXME: reduction doesn't work for these (but should). + } else if(type == MSH_HEX_8 || type == MSH_HEX_27 || type == MSH_HEX_20){ - cell = new CHexahedron(vertices, tag, subdomain, boundary); + cell = new Cell(domain.at(j)->getMeshElement(i), subdomain, boundary); _simplicial = false; - } + }/* FIXME: no getFaceInfo methods for these MElements else if(type == MSH_PRI_6 || type == MSH_PRI_18 || type == MSH_PRI_15){ - cell = new CPrism(vertices, tag, subdomain, boundary); + cell = new Cell(domain.at(j)->getMeshElement(i), subdomain, boundary); _simplicial = false; } else if(type == MSH_PYR_5 || type == MSH_PYR_14 || type == MSH_PYR_13){ - cell = new CPyramid(vertices, tag, subdomain, boundary); + cell = new Cell(domain.at(j)->getMeshElement(i), subdomain, boundary); _simplicial = false; }*/ else Msg::Error("Error: mesh element %d not implemented yet! \n", type); @@ -163,23 +171,31 @@ void CellComplex::insert_cells(bool subdomain, bool boundary){ for(int i = 0; i < cell->getNumFacets(); i++){ cell->getFacetVertices(i, vertices); int type = cell->getTypeForMSH(); - int newtype = 0; //FIXME: add missing boundary cell type relations + //FIXME: high order meshes don't work if(dim == 3){ if(type == MSH_TET_4) newtype = MSH_TRI_3; - else if(type == MSH_TET_10) newtype = MSH_TRI_6; + /*else if(type == MSH_TET_10) newtype = MSH_TRI_6; + else if(type == MSH_TET_20) newtype = MSH_TRI_9;*/ + else if(type == MSH_HEX_8) newtype = MSH_QUA_4; + /*else if(type == MSH_HEX_20) newtype = MSH_QUA_8; + else if(type == MSH_HEX_27) newtype = MSH_QUA_9;*/ } else if(dim == 2){ if(type == MSH_TRI_3 || type == MSH_QUA_4) newtype = MSH_LIN_2; - else if(type == MSH_TRI_6 || type == MSH_QUA_8) newtype = MSH_LIN_3; + /*else if(type == MSH_TRI_6 || type == MSH_QUA_8) newtype = MSH_LIN_3; + else if(type == MSH_TRI_9) newtype = MSH_LIN_4; + else if(type == MSH_QUA_9) newtype = MSH_LIN_3;*/ } else if(dim == 1){ - if(type == MSH_LIN_2 || type == MSH_LIN_3 || type == MSH_LIN_4 || - type == MSH_LIN_5 || type == MSH_LIN_6) newtype = MSH_PNT; + if(type == MSH_LIN_2) newtype = MSH_PNT; + /*else if(type == MSH_LIN_3 || type == MSH_LIN_4 || + type == MSH_LIN_5 || type == MSH_LIN_6) newtype = MSH_PNT;*/ } if(newtype == 0) Msg::Error("Error: mesh element %d not implemented yet! \n", type); + //printf("dim: %d type: %d, newtype: %d, vertices: %d \n", dim, type, newtype, vertices.size()); MElement* element = factory.create(newtype, vertices, 0, cell->getPartition()); Cell* newCell = new Cell(element, subdomain, boundary); newCell->setImmune(cell->getImmune()); @@ -206,7 +222,6 @@ void CellComplex::insert_cells(bool subdomain, bool boundary){ } } } - } CellComplex::~CellComplex(){ @@ -893,6 +908,18 @@ bool CellComplex::hasCell(Cell* cell, bool org){ } } +bool CellComplex::swapSubdomain(){ + if(_multidim) return false; + for(int i = 0; i < 4; i++){ + for(citer cit = firstCell(i); cit != lastCell(i); cit++){ + Cell* cell = *cit; + if(cell->onDomainBoundary() && cell->inSubdomain()) cell->setInSubdomain(false); + else if(cell->onDomainBoundary() && !cell->inSubdomain()) cell->setInSubdomain(true); + } + } + return true; +} + void CellComplex::makeDualComplex(){ std::set<Cell*, Less_Cell> temp = _cells[0]; _cells[0] = _cells[3]; diff --git a/Geo/CellComplex.h b/Geo/CellComplex.h index 49c9ffc072..0179258883 100644 --- a/Geo/CellComplex.h +++ b/Geo/CellComplex.h @@ -59,6 +59,9 @@ class CellComplex // is the cell complex simplicial bool _simplicial; + // does the domain contain entities of different dimensions + bool _multidim; + // 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); @@ -129,10 +132,6 @@ class CellComplex // print the vertices of cells of certain dimension void printComplex(int dim); - // write this cell complex in 2.0 MSH ASCII format - // for debugging only - //int writeComplexMSH(const std::string &name); - // Cell combining for reduction and coreduction int combine(int dim); int cocombine(int dim); @@ -145,6 +144,9 @@ class CellComplex // also check whether all (co)boundary cells of a cell belong to this cell complex bool checkCoherence(); + // make cells on the domain boundary that are not in the subdomain subdomain cells and vice versa + bool swapSubdomain(); + int eulerCharacteristic(){ return getSize(0) - getSize(1) + getSize(2) - getSize(3);} void printEuler(){ printf("Euler characteristic: %d. \n", eulerCharacteristic()); } diff --git a/Geo/ChainComplex.cpp b/Geo/ChainComplex.cpp index 231bee797b..cbfd41bb18 100644 --- a/Geo/ChainComplex.cpp +++ b/Geo/ChainComplex.cpp @@ -602,7 +602,6 @@ int Chain::writeChainMSH(const std::string &name){ void Chain::createPView(){ std::vector<MElement*> elements; - MElementFactory factory; std::map<int, std::vector<double> > data; for(citer cit = _cells.begin(); cit != _cells.end(); cit++){ diff --git a/Geo/Homology.cpp b/Geo/Homology.cpp index fe8850d0db..1a5344f3ea 100644 --- a/Geo/Homology.cpp +++ b/Geo/Homology.cpp @@ -111,7 +111,6 @@ void Homology::findGenerators(std::string fileName){ _cellComplex->getSize(3), _cellComplex->getSize(2), _cellComplex->getSize(1), _cellComplex->getSize(0)); Msg::StatusBar(2, false, "%d V, %d F, %d E, %d N.", _cellComplex->getSize(3), _cellComplex->getSize(2), _cellComplex->getSize(1), _cellComplex->getSize(0)); - //for(int i = 0; i < 4; i++) { printf("Dim %d: \n", i); _cellComplex->printComplex(i); } Msg::Info("Computing homology spaces..."); Msg::StatusBar(1, false, "Computing..."); @@ -190,7 +189,6 @@ void Homology::findDualGenerators(std::string fileName){ Msg::StatusBar(1, false, "Reducing..."); double t1 = Cpu(); int omitted = _cellComplex->coreduceComplex(); - //_cellComplex->emptyTrash(); /* _cellComplex->makeDualComplex(); @@ -203,14 +201,10 @@ void Homology::findDualGenerators(std::string fileName){ _cellComplex->makeDualComplex(); */ - _cellComplex->cocombine(0); _cellComplex->cocombine(1); _cellComplex->cocombine(2); - - //_cellComplex->emptyTrash(); - _cellComplex->checkCoherence(); double t2 = Cpu(); Msg::Info("Cell Complex reduction complete (%g s).", t2 - t1); @@ -220,8 +214,6 @@ void Homology::findDualGenerators(std::string fileName){ _cellComplex->getSize(3), _cellComplex->getSize(2), _cellComplex->getSize(1), _cellComplex->getSize(0)); - //_cellComplex->writeComplexMSH(fileName); - Msg::Info("Computing homology spaces..."); Msg::StatusBar(1, false, "Computing..."); t1 = Cpu(); @@ -360,16 +352,8 @@ void Homology::createPViews(){ bool Homology::writeGeneratorsMSH(std::string fileName, bool binary){ if(!_model->writeMSH(fileName, 2.0, binary)) return false; - /* - for(int i = 0; i < 4; i++){ - for(int j = 0; j < _generators[i].size(); j++){ - Chain* chain = _generators[i].at(j); - if(!chain->writeChainMSH(fileName)) return false; - } - }*/ Msg::Info("Wrote homology computation results to %s.", fileName.c_str()); - Msg::Debug("Wrote homology computation results to %s. \n", fileName.c_str()); - + Msg::Debug("Wrote homology computation results to %s. \n", fileName.c_str()); return true; } diff --git a/Geo/Homology.h b/Geo/Homology.h index fbc47be58c..0443ba40fd 100644 --- a/Geo/Homology.h +++ b/Geo/Homology.h @@ -47,9 +47,8 @@ class Homology void findGenerators(std::string fileName); void findDualGenerators(std::string fileName); void computeBettiNumbers(); - - - //void swapSubdomain() { _cellComplex->swapSubdomain(); } + + bool swapSubdomain() { return _cellComplex->swapSubdomain(); } // Restore the cell complex to its original state before cell reductions void restoreHomology(); diff --git a/Parser/Gmsh.y b/Parser/Gmsh.y index 813628da5e..dd1cf5962c 100644 --- a/Parser/Gmsh.y +++ b/Parser/Gmsh.y @@ -3333,7 +3333,7 @@ Homology : #if defined(HAVE_KBIPACK) Homology* homology = new Homology(GModel::current(), domain, subdomain); - homology->findGenerators(fileName); + homology->findGenerators(fileName); delete homology; #else yymsg(0, "Gmsh needs to be configured with option Kbipack to use homology computation."); -- GitLab