diff --git a/Geo/Cell.cpp b/Geo/Cell.cpp index ea9ccbc8aeef8abf1eebeef578ab86bb866bf8dd..ae9edf9f988dcd1723abbf1e428efc176c8e1ecd 100755 --- a/Geo/Cell.cpp +++ b/Geo/Cell.cpp @@ -6,6 +6,12 @@ // Contributed by Matti Pellikka <matti.pellikka@tut.fi>. #include "Cell.h" +#include "MTriangle.h" +#include "MQuadrangle.h" +#include "MTetrahedron.h" +#include "MPyramid.h" +#include "MHexahedron.h" +#include "MPrism.h" bool Less_Cell::operator()(const Cell* c1, const Cell* c2) const { @@ -23,35 +29,26 @@ bool Less_Cell::operator()(const Cell* c1, const Cell* c2) const return false; } -int Cell::_globalNum = 0; -Cell::Cell(int dim, std::vector<MVertex*>& v) +bool Less_VertexNumIndex::operator()(const std::pair<MVertex*, int> v1, + const std::pair<MVertex*, int> v2) const { - _dim = dim; - _domain = 0; - _combined = false; - _immune = false; - _v = v; - std::sort(_v.begin(), _v.end(), MVertexLessThanNum()); - - _num = 0; - _index = 0; + return (v1.first->getNum() < v2.first->getNum()); } +int Cell::_globalNum = 0; + Cell::Cell(MElement* element, int domain) { _dim = element->getDim(); _domain = domain; _combined = false; _immune = false; + _num = 0; - for(int i = 0; i < element->getNumPrimaryVertices(); i++){ + for(int i = 0; i < element->getNumPrimaryVertices(); i++) _v.push_back(element->getVertex(i)); - } - std::sort(_v.begin(), _v.end(), MVertexLessThanNum()); - - _num = 0; - _index = 0; + _sortVertexIndices(); } Cell::Cell(Cell* parent, int i) @@ -60,144 +57,240 @@ Cell::Cell(Cell* parent, int i) _domain = parent->getDomain(); _combined = false; _immune = false; + _num = 0; parent->findBdElement(i, _v); - std::sort(_v.begin(), _v.end(), MVertexLessThanNum()); + _sortVertexIndices(); +} - _num = 0; - _index = 0; +void Cell::_sortVertexIndices() +{ + std::vector< std::pair<MVertex*, int> > si; + + for(unsigned int i = 0; i < _v.size(); i++) + si.push_back( std::make_pair(_v[i], i) ); + std::sort(si.begin(), si.end(), Less_VertexNumIndex()); + + for(unsigned int i = 0; i < si.size(); i++) + _si.push_back(si[i].second); +} + +inline int Cell::getSortedVertex(int vertex) const +{ + return _v[(int)_si[vertex]]->getNum(); } void Cell::findBdElement(int i, std::vector<MVertex*>& vertices) const { vertices.clear(); - if(_dim == 1){ // i = 0 -> ori = -1, i = 1 -> ori = 1 + switch (_dim) { + case 1: vertices.push_back(_v[i]); - } - else if(_dim == 2){ - if(i == 0){ // ori = 1 - vertices.push_back(_v[0]); - vertices.push_back(_v[1]); - } - else if(i == 1){ // ori = 1 - vertices.push_back(_v[1]); - vertices.push_back(_v[2]); - } - else if(i == 2){ // ori = 1 - vertices.push_back(_v[2]); - vertices.push_back(_v[0]); - } - } - else if(_dim == 3){ - if(i == 0){ - vertices.push_back(_v[0]); - vertices.push_back(_v[2]); - vertices.push_back(_v[1]); - } - else if(i == 1){ - vertices.push_back(_v[0]); - vertices.push_back(_v[1]); - vertices.push_back(_v[3]); - } - else if(i == 2){ - vertices.push_back(_v[0]); - vertices.push_back(_v[3]); - vertices.push_back(_v[2]); + return; + case 2: + switch (getNumVertices()) { + case 3: + for(int j = 0; j < 2; j++) + vertices.push_back(_v[MTriangle::edges_tri(i, j)]); + return; + case 4: + for(int j = 0; j < 2; j++) + vertices.push_back(_v[MQuadrangle::edges_quad(i, j)]); + return; + default: return; } - else if(i == 3){ - vertices.push_back(_v[3]); - vertices.push_back(_v[1]); - vertices.push_back(_v[2]); + case 3: + switch (getNumVertices()) { + case 4: + for(int j = 0; j < 3; j++) + vertices.push_back(_v[MTetrahedron::faces_tetra(i, j)]); + return; + case 5: + if(i < 3) { + for(int j = 0; j < 3; j++) + vertices.push_back(_v[MPyramid::faces_pyramid(i, j)]); + } + else { + vertices.push_back(_v[0]); + vertices.push_back(_v[3]); + vertices.push_back(_v[2]); + vertices.push_back(_v[1]); + } + return; + case 6: + if(i < 2) + for(int j = 0; j < 3; j++) + vertices.push_back(_v[MPrism::faces_prism(i, j)]); + else + for(int j = 0; j < 4; j++) + vertices.push_back(_v[MPrism::faces_prism(i, j)]); + return; + case 8: + for(int j = 0; j < 4; j++) + vertices.push_back(_v[MHexahedron::faces_hexa(i, j)]); + return; + default: return; } + default: return; } } int Cell::getNumBdElements() const { - if(_dim == 0) return 0; - else if(_dim == 1) return 2; - else if(_dim == 2) return 3; - else if(_dim == 3) return 4; - else return 0; + switch (_dim) { + case 0: return 0; + case 1: return 2; + case 2: + switch (getNumVertices()) { + case 3: return 3; + case 4: return 4; + default: return 0; + } + case 3: + switch (getNumVertices()) { + case 4: return 4; + case 5: return 5; + case 6: return 5; + case 8: return 6; + default: return 0; + } + default: return 0; + } } -int Cell::findBdCellOrientation(Cell* cell) const + +int Cell::findBdCellOrientation(Cell* cell, int i) const { std::vector<MVertex*> v; cell->getMeshVertices(v); - if(_dim == 0) return 0; - else if(_dim == 1){ + switch (_dim) { + case 0: return 0; + case 1: if(v[0]->getNum() == _v[0]->getNum()) return -1; else if(v[0]->getNum() == _v[1]->getNum()) return 1; + return 0; + case 2: + switch (getNumVertices()) { + case 3: + if(_v[MTriangle::edges_tri(i, 0)]->getNum() == v[0]->getNum() && + _v[MTriangle::edges_tri(i, 1)]->getNum() == v[1]->getNum()) + return 1; + if(_v[MTriangle::edges_tri(i, 1)]->getNum() == v[0]->getNum() && + _v[MTriangle::edges_tri(i, 0)]->getNum() == v[1]->getNum()) + return -1; + case 4: + if(_v[MQuadrangle::edges_quad(i, 0)]->getNum() == v[0]->getNum() && + _v[MQuadrangle::edges_quad(i, 1)]->getNum() == v[1]->getNum()) + return 1; + if(_v[MQuadrangle::edges_quad(i, 0)]->getNum() == v[1]->getNum() && + _v[MQuadrangle::edges_quad(i, 1)]->getNum() == v[0]->getNum()) + return -1; + default: return 0; + } + case 3: + switch (getNumVertices()) { + case 4: + if(_v[MTetrahedron::faces_tetra(i, 0)]->getNum() == v[0]->getNum() && + _v[MTetrahedron::faces_tetra(i, 1)]->getNum() == v[1]->getNum() && + _v[MTetrahedron::faces_tetra(i, 2)]->getNum() == v[2]->getNum()) + return 1; + if(_v[MTetrahedron::faces_tetra(i, 0)]->getNum() == v[1]->getNum() && + _v[MTetrahedron::faces_tetra(i, 1)]->getNum() == v[2]->getNum() && + _v[MTetrahedron::faces_tetra(i, 2)]->getNum() == v[0]->getNum()) + return 1; + if(_v[MTetrahedron::faces_tetra(i, 0)]->getNum() == v[2]->getNum() && + _v[MTetrahedron::faces_tetra(i, 1)]->getNum() == v[0]->getNum() && + _v[MTetrahedron::faces_tetra(i, 2)]->getNum() == v[1]->getNum()) + return 1; + if(_v[MTetrahedron::faces_tetra(i, 0)]->getNum() == v[0]->getNum() && + _v[MTetrahedron::faces_tetra(i, 1)]->getNum() == v[2]->getNum() && + _v[MTetrahedron::faces_tetra(i, 2)]->getNum() == v[1]->getNum()) + return -1; + if(_v[MTetrahedron::faces_tetra(i, 0)]->getNum() == v[1]->getNum() && + _v[MTetrahedron::faces_tetra(i, 1)]->getNum() == v[0]->getNum() && + _v[MTetrahedron::faces_tetra(i, 2)]->getNum() == v[2]->getNum()) + return -1; + if(_v[MTetrahedron::faces_tetra(i, 0)]->getNum() == v[2]->getNum() && + _v[MTetrahedron::faces_tetra(i, 1)]->getNum() == v[1]->getNum() && + _v[MTetrahedron::faces_tetra(i, 2)]->getNum() == v[0]->getNum()) + return -1; + case 5: return 0; + case 6: return 0; + case 8: + if(_v[MHexahedron::faces_hexa(i, 0)]->getNum() == v[0]->getNum() && + _v[MHexahedron::faces_hexa(i, 1)]->getNum() == v[1]->getNum() && + _v[MHexahedron::faces_hexa(i, 2)]->getNum() == v[2]->getNum() && + _v[MHexahedron::faces_hexa(i, 3)]->getNum() == v[3]->getNum()) + return 1; + if(_v[MHexahedron::faces_hexa(i, 0)]->getNum() == v[1]->getNum() && + _v[MHexahedron::faces_hexa(i, 1)]->getNum() == v[2]->getNum() && + _v[MHexahedron::faces_hexa(i, 2)]->getNum() == v[3]->getNum() && + _v[MHexahedron::faces_hexa(i, 3)]->getNum() == v[0]->getNum()) + return 1; + if(_v[MHexahedron::faces_hexa(i, 0)]->getNum() == v[2]->getNum() && + _v[MHexahedron::faces_hexa(i, 1)]->getNum() == v[3]->getNum() && + _v[MHexahedron::faces_hexa(i, 2)]->getNum() == v[0]->getNum() && + _v[MHexahedron::faces_hexa(i, 3)]->getNum() == v[1]->getNum()) + return 1; + if(_v[MHexahedron::faces_hexa(i, 0)]->getNum() == v[3]->getNum() && + _v[MHexahedron::faces_hexa(i, 1)]->getNum() == v[0]->getNum() && + _v[MHexahedron::faces_hexa(i, 2)]->getNum() == v[1]->getNum() && + _v[MHexahedron::faces_hexa(i, 3)]->getNum() == v[2]->getNum()) + return 1; + if(_v[MHexahedron::faces_hexa(i, 0)]->getNum() == v[0]->getNum() && + _v[MHexahedron::faces_hexa(i, 1)]->getNum() == v[3]->getNum() && + _v[MHexahedron::faces_hexa(i, 2)]->getNum() == v[2]->getNum() && + _v[MHexahedron::faces_hexa(i, 3)]->getNum() == v[1]->getNum()) + return -1; + if(_v[MHexahedron::faces_hexa(i, 0)]->getNum() == v[3]->getNum() && + _v[MHexahedron::faces_hexa(i, 1)]->getNum() == v[2]->getNum() && + _v[MHexahedron::faces_hexa(i, 2)]->getNum() == v[1]->getNum() && + _v[MHexahedron::faces_hexa(i, 3)]->getNum() == v[0]->getNum()) + return -1; + if(_v[MHexahedron::faces_hexa(i, 0)]->getNum() == v[2]->getNum() && + _v[MHexahedron::faces_hexa(i, 1)]->getNum() == v[1]->getNum() && + _v[MHexahedron::faces_hexa(i, 2)]->getNum() == v[0]->getNum() && + _v[MHexahedron::faces_hexa(i, 3)]->getNum() == v[3]->getNum()) + return -1; + if(_v[MHexahedron::faces_hexa(i, 0)]->getNum() == v[1]->getNum() && + _v[MHexahedron::faces_hexa(i, 1)]->getNum() == v[0]->getNum() && + _v[MHexahedron::faces_hexa(i, 2)]->getNum() == v[3]->getNum() && + _v[MHexahedron::faces_hexa(i, 3)]->getNum() == v[2]->getNum()) + return -1; + default: return 0; + } + default: return 0; } - if(_dim == 2){ - if (v[0]->getNum() == _v[0]->getNum() && v[1]->getNum() == _v[1]->getNum() ) return 1; - else if(v[0]->getNum() == _v[1]->getNum() && v[1]->getNum() == _v[0]->getNum() ) return -1; - - else if(v[0]->getNum() == _v[1]->getNum() && v[1]->getNum() == _v[2]->getNum() ) return 1; - else if(v[0]->getNum() == _v[2]->getNum() && v[1]->getNum() == _v[1]->getNum() ) return -1; - - else if(v[0]->getNum() == _v[2]->getNum() && v[1]->getNum() == _v[0]->getNum() ) return 1; - else if(v[0]->getNum() == _v[0]->getNum() && v[1]->getNum() == _v[2]->getNum() ) return -1; - } - else if(_dim == 3) { - if (v[0]->getNum() == _v[0]->getNum() && v[1]->getNum() == _v[2]->getNum() && v[2]->getNum() == _v[1]->getNum() ) return 1; - else if(v[0]->getNum() == _v[0]->getNum() && v[1]->getNum() == _v[1]->getNum() && v[2]->getNum() == _v[2]->getNum()) return -1; - - else if(v[0]->getNum() == _v[2]->getNum() && v[1]->getNum() == _v[1]->getNum() && v[2]->getNum() == _v[0]->getNum()) return 1; - else if(v[0]->getNum() == _v[2]->getNum() && v[1]->getNum() == _v[0]->getNum() && v[2]->getNum() == _v[1]->getNum()) return -1; - - else if(v[0]->getNum() == _v[1]->getNum() && v[1]->getNum() == _v[0]->getNum() && v[2]->getNum() == _v[2]->getNum()) return 1; - else if(v[0]->getNum() == _v[1]->getNum() && v[1]->getNum() == _v[2]->getNum() && v[2]->getNum() == _v[0]->getNum()) return -1; - - - else if(v[0]->getNum() == _v[0]->getNum() && v[1]->getNum() == _v[1]->getNum() && v[2]->getNum() == _v[3]->getNum() ) return 1; - else if(v[0]->getNum() == _v[0]->getNum() && v[1]->getNum() == _v[3]->getNum() && v[2]->getNum() == _v[1]->getNum()) return -1; - - else if(v[0]->getNum() == _v[1]->getNum() && v[1]->getNum() == _v[3]->getNum() && v[2]->getNum() == _v[0]->getNum()) return 1; - else if(v[0]->getNum() == _v[1]->getNum() && v[1]->getNum() == _v[0]->getNum() && v[2]->getNum() == _v[3]->getNum()) return -1; - - else if(v[0]->getNum() == _v[3]->getNum() && v[1]->getNum() == _v[0]->getNum() && v[2]->getNum() == _v[1]->getNum()) return 1; - else if(v[0]->getNum() == _v[3]->getNum() && v[1]->getNum() == _v[1]->getNum() && v[2]->getNum() == _v[0]->getNum()) return -1; - - - else if(v[0]->getNum() == _v[0]->getNum() && v[1]->getNum() == _v[3]->getNum() && v[2]->getNum() == _v[2]->getNum() ) return 1; - else if(v[0]->getNum() == _v[0]->getNum() && v[1]->getNum() == _v[2]->getNum() && v[2]->getNum() == _v[3]->getNum()) return -1; - - else if(v[0]->getNum() == _v[3]->getNum() && v[1]->getNum() == _v[2]->getNum() && v[2]->getNum() == _v[3]->getNum()) return 1; - else if(v[0]->getNum() == _v[3]->getNum() && v[1]->getNum() == _v[3]->getNum() && v[2]->getNum() == _v[2]->getNum()) return -1; - - else if(v[0]->getNum() == _v[2]->getNum() && v[1]->getNum() == _v[0]->getNum() && v[2]->getNum() == _v[3]->getNum()) return 1; - else if(v[0]->getNum() == _v[2]->getNum() && v[1]->getNum() == _v[3]->getNum() && v[2]->getNum() == _v[0]->getNum()) return -1; - - - else if(v[0]->getNum() == _v[3]->getNum() && v[1]->getNum() == _v[1]->getNum() && v[2]->getNum() == _v[2]->getNum() ) return 1; - else if(v[0]->getNum() == _v[3]->getNum() && v[1]->getNum() == _v[2]->getNum() && v[2]->getNum() == _v[1]->getNum()) return -1; - - else if(v[0]->getNum() == _v[1]->getNum() && v[1]->getNum() == _v[2]->getNum() && v[2]->getNum() == _v[3]->getNum()) return 1; - else if(v[0]->getNum() == _v[1]->getNum() && v[1]->getNum() == _v[3]->getNum() && v[2]->getNum() == _v[2]->getNum()) return -1; - - else if(v[0]->getNum() == _v[2]->getNum() && v[1]->getNum() == _v[3]->getNum() && v[2]->getNum() == _v[1]->getNum()) return 1; - else if(v[0]->getNum() == _v[2]->getNum() && v[1]->getNum() == _v[1]->getNum() && v[2]->getNum() == _v[3]->getNum()) return -1; - } - return 0; } int Cell::getTypeMSH() const { - if(_dim == 0) return 15; - else if(_dim == 1) return 1; - else if(_dim == 2) return 2; - else if(_dim == 3) return 4; - else return 0; + switch (_dim) { + case 0: return MSH_PNT; + case 1: return MSH_LIN_2; + case 2: + switch (getNumVertices()) { + case 3: return MSH_TRI_3; + case 4: return MSH_QUA_4; + default: return 0; + } + case 3: + switch (getNumVertices()) { + case 4: return MSH_TET_4; + case 5: return MSH_PYR_5; + case 6: return MSH_PRI_6; + case 8: return MSH_HEX_8; + default: return 0; + } + default: return 0; + } } bool Cell::hasVertex(int vertex) const { - //_vs std::vector<int> v; for(unsigned int i = 0; i < _v.size(); i++) { - v.push_back(_v[i]->getNum()); + v.push_back(_v[(int)_si[i]]->getNum()); } std::vector<int>::const_iterator it = std::find(v.begin(), v.end(), vertex); @@ -219,7 +312,7 @@ void Cell::printCell() printf("%d-cell %d: \n" , getDim(), getNum()); printf("Vertices: "); for(int i = 0; i < this->getNumVertices(); i++){ - printf("%d ", this->getVertex(i)); + printf("%d ", this->getMeshVertex(i)->getNum()); } printf(", in subdomain: %d, ", inSubdomain()); printf("combined: %d. \n" , isCombined() ); @@ -239,7 +332,6 @@ void Cell::restoreCell(){ } for(unsigned int i = 0; i < toRemove.size(); i++) _bd.erase(toRemove[i]); _combined = false; - _index = 0; _immune = false; } @@ -351,7 +443,7 @@ void Cell::printCoboundary(bool orig) } }*/ -CombinedCell::CombinedCell(Cell* c1, Cell* c2, bool orMatch, bool co) : Cell() +CombinedCell::CombinedCell(Cell* c1, Cell* c2, bool orMatch, bool co) { // use "smaller" cell as c2 if(c1->getNumCells() < c2->getNumCells()){ @@ -361,7 +453,6 @@ CombinedCell::CombinedCell(Cell* c1, Cell* c2, bool orMatch, bool co) : Cell() } _num = ++_globalNum; - _index = c1->getIndex(); _domain = c1->getDomain(); _combined = true; _immune = false; @@ -417,12 +508,12 @@ CombinedCell::CombinedCell(Cell* c1, Cell* c2, bool orMatch, bool co) : Cell() } -CombinedCell::CombinedCell(std::vector<Cell*>& cells) : Cell() +CombinedCell::CombinedCell(std::vector<Cell*>& cells) { _num = ++_globalNum; - _index = cells.at(0)->getIndex(); _domain = cells.at(0)->getDomain(); _combined = true; + _immune = false; // cells for(unsigned int i = 0; i < cells.size(); i++){ diff --git a/Geo/Cell.h b/Geo/Cell.h index 7fb65e077b3ef2d99d6eb9f73b6877f352fe556d..da83de9f6ccd25de3868be2250b705c48ae03fec 100644 --- a/Geo/Cell.h +++ b/Geo/Cell.h @@ -19,11 +19,17 @@ public: bool operator()(const Cell* c1, const Cell* c2) const; }; +class Less_VertexNumIndex { +public: + bool operator()(const std::pair<MVertex*, int> v1, + const std::pair<MVertex*, int> v2) const; +}; + // Class to save cell boundary orientation information class BdInfo { private: - short int _ori; - short int _origOri; + signed char _ori; + signed char _origOri; public: BdInfo(int ori) { _ori = ori; _origOri = 0; } @@ -41,15 +47,13 @@ class BdInfo { class Cell { protected: + static int _globalNum; int _num; - // mutable index for each cell (used to create boundary operator matrices) - int _index; - - int _domain; + char _domain; - // whether this cell a combinded cell of elemetary cells + // whether this cell a combinded cell of elementary cells bool _combined; // for some algorithms to omit this cell bool _immune; @@ -60,15 +64,16 @@ class Cell { private: - int _dim; - // sorted vertices of this cell (used for ordering of the cells) + char _dim; std::vector<MVertex*> _v; + // sorted vertices of this cell (used for ordering of the cells) + std::vector<char> _si; - public: + inline void _sortVertexIndices(); - Cell(int dim, std::vector<MVertex*>& v); - Cell() : _num(0), _dim(0), _index(0), _domain(0), _combined(false), _immune(false) {} + public: + Cell() {} Cell(MElement* element, int domain); Cell(Cell* parent, int i); @@ -77,26 +82,21 @@ class Cell { void setNum(int num) { _num = num; }; int getTypeMSH() const; virtual int getDim() const { return _dim; } - bool inSubdomain() const { if(_domain != 0) return true; else return false; } + bool inSubdomain() const { return _domain ? true : false; } void getMeshVertices(std::vector<MVertex*>& v) const { v = _v; } - int getIndex() const { return _index; }; - void setIndex(int index) { _index = index; }; void setImmune(bool immune) { _immune = immune; }; bool getImmune() const { return _immune; }; int getNumSortedVertices() const { return _v.size(); } - int getSortedVertex(int vertex) const { return _v.at(vertex)->getNum(); } + inline int getSortedVertex(int vertex) const; int getNumVertices() const { return _v.size(); } - int getVertex(int vertex) const { return _v.at(vertex)->getNum(); } MVertex* getMeshVertex(int vertex) const { return _v.at(vertex); } - void clearSortedVertices() { _v.clear(); } void findBdElement(int i, std::vector<MVertex*>& vertices) const; int getNumBdElements() const; - int findBdCellOrientation(Cell* cell) const; + int findBdCellOrientation(Cell* cell, int i) const; - void revertGlobalNum() { _globalNum--; } void increaseGlobalNum() { _globalNum++; } // restores the cell information to its original state before reduction diff --git a/Geo/CellComplex.cpp b/Geo/CellComplex.cpp index 109e4a56f99eda5406401ffece4a597a2111222e..dfc6ff9a5defadff219a358da367609c39fa426e 100644 --- a/Geo/CellComplex.cpp +++ b/Geo/CellComplex.cpp @@ -37,11 +37,13 @@ bool CellComplex::_insertCells(std::vector<MElement*>& elements, for(unsigned int i=0; i < elements.size(); i++){ MElement* element = elements.at(i); int type = element->getType(); - if(type != TYPE_PNT && type != TYPE_LIN && - type != TYPE_TRI && type != TYPE_TET) { + if(type == TYPE_PYR || type == TYPE_PRI || + type == TYPE_POLYG || type == TYPE_POLYH) { Msg::Error("Mesh element type %d not implemented in homology solver", type); return false; } + if(type == TYPE_QUA || type == TYPE_HEX) + _simplicial = false; Cell* cell = new Cell(element, domain); bool insert = _cells[cell->getDim()].insert(cell).second; if(!insert) delete cell; @@ -50,8 +52,7 @@ bool CellComplex::_insertCells(std::vector<MElement*>& elements, for (int dim = 3; dim > 0; dim--){ for(citer cit = firstCell(dim); cit != lastCell(dim); cit++){ Cell* cell = *cit; - int numBdElements = cell->getNumBdElements(); - for(int i = 0; i < numBdElements; i++){ + for(int i = 0; i < cell->getNumBdElements(); i++){ Cell* newCell = new Cell(cell, i); std::pair<citer, bool> insert = _cells[newCell->getDim()].insert(newCell); @@ -60,7 +61,7 @@ bool CellComplex::_insertCells(std::vector<MElement*>& elements, newCell = *(insert.first); } if(domain == 0) { - int ori = cell->findBdCellOrientation(newCell); + int ori = cell->findBdCellOrientation(newCell, i); cell->addBoundaryCell( ori, newCell, true); } } diff --git a/Geo/ChainComplex.cpp b/Geo/ChainComplex.cpp index 0da4364848d02e040f5803ecea42ee1389aa33ca..93f4e3237f7ace378b7cafe837846ca80d3abc09 100644 --- a/Geo/ChainComplex.cpp +++ b/Geo/ChainComplex.cpp @@ -34,15 +34,14 @@ ChainComplex::ChainComplex(CellComplex* cellComplex, int domain) for(CellComplex::citer cit = cellComplex->firstCell(dim); cit != cellComplex->lastCell(dim); cit++){ Cell* cell = *cit; - cell->setIndex(0); cols--; if((domain == 0 && !cell->inSubdomain()) || domain == 1 || (domain == 2 && cell->inSubdomain()) ){ cols++; - cell->setIndex(index); - index++; - _cellIndices[dim][cell] = cell->getIndex(); +_cellIndices[dim][cell] = index; + index++; } + else _cellIndices[dim][cell] = 0; } if(dim > 0) rows = lastCols; lastCols = cols; @@ -73,23 +72,24 @@ ChainComplex::ChainComplex(CellComplex* cellComplex, int domain) if((domain == 0 && !bdCell->inSubdomain()) || domain == 1 || (domain == 2 && cell->inSubdomain()) ){ int old_elem = 0; - - if(bdCell->getIndex() > (int)gmp_matrix_rows( _HMatrix[dim]) - || bdCell->getIndex() < 1 - || cell->getIndex() > (int)gmp_matrix_cols( _HMatrix[dim]) - || cell->getIndex() < 1){ + int bdCellIndex = getCellIndex(bdCell); + int cellIndex = getCellIndex(cell); + if(bdCellIndex > (int)gmp_matrix_rows( _HMatrix[dim]) + || bdCellIndex < 1 + || cellIndex > (int)gmp_matrix_cols( _HMatrix[dim]) + || cellIndex < 1){ Msg::Debug("Index out of bound! HMatrix: %d", dim); } else{ - gmp_matrix_get_elem(elem, bdCell->getIndex(), - cell->getIndex(), _HMatrix[dim]); + gmp_matrix_get_elem(elem, bdCellIndex, + cellIndex, _HMatrix[dim]); old_elem = mpz_get_si(elem); mpz_set_si(elem, old_elem + it->second.get()); if( abs((old_elem + it->second.get())) > 1){ //printf("Incidence index: %d, in HMatrix: %d. \n", (old_elem + (*it).second), dim); } - gmp_matrix_set_elem(elem, bdCell->getIndex(), - cell->getIndex(), _HMatrix[dim]); + gmp_matrix_set_elem(elem, bdCellIndex, + cellIndex, _HMatrix[dim]); } } } @@ -746,7 +746,7 @@ void HomologySequence::findIcMaps() cit != _complex->lastCell(i); cit++){ Cell* cell = cit->first; int row = cit->second; - int col = _subcomplex->cellIndex(cell); + int col = _subcomplex->getCellIndex(cell); //printf("row %d, col %d. \n", row, col); if(col != 0) gmp_matrix_set_elem(one, row, col, _Ic_sub[i]); } @@ -761,7 +761,7 @@ void HomologySequence::findIcMaps() cit != _complex->lastCell(i); cit++){ Cell* cell = cit->first; int row = cit->second; - int col = _relcomplex->cellIndex(cell); + int col = _relcomplex->getCellIndex(cell); //printf("row %d, col %d. \n", row, col); if(col != 0) gmp_matrix_set_elem(one, row, col, _Ic_rel[i]); } diff --git a/Geo/ChainComplex.h b/Geo/ChainComplex.h index 03f8b15f9293a821707f55041fa0464f499a180d..45a7b3e9b0a5e1f25d0d457eb51c3e057402fa94 100644 --- a/Geo/ChainComplex.h +++ b/Geo/ChainComplex.h @@ -18,7 +18,7 @@ #include <queue> #include "CellComplex.h" -#if defined(HAVE_GMP) +#if defined(HAVE_GMP) #include "gmp.h" #include "gmp_normal_form.h" #else @@ -30,7 +30,7 @@ class CellComplex; // A class representing a chain complex of a cell complex. // This should only be constructed for a reduced cell complex because of -// dense matrix representations and great computational complexity in +// dense matrix representations and great computational complexity in // its methods. class ChainComplex { @@ -38,12 +38,12 @@ class ChainComplex // boundary operator matrices for this chain complex // h_k: C_k -> C_(k-1) gmp_matrix* _HMatrix[5]; - + // Basis matrices for the kernels and codomains of the boundary operator // matrices gmp_matrix* _kerH[5]; gmp_matrix* _codH[5]; - + // matrix of the mapping B_k -> Z_k gmp_matrix* _JMatrix[5]; // matrix of the mapping H_k -> Z_k @@ -54,68 +54,68 @@ class ChainComplex // torsion coefficients of homology generators // corresponding the columns of _Hbasis std::vector<long int> _torsion[5]; - + int _dim; CellComplex* _cellComplex; - // index to cell map + // index to cell map // matrix indices correspond to these cells in _cellComplex std::map<Cell*, int, Less_Cell> _cellIndices[4]; - + // set the matrices - void setHMatrix(int dim, gmp_matrix* matrix) { + void setHMatrix(int dim, gmp_matrix* matrix) { if(dim > -1 && dim < 5) _HMatrix[dim] = matrix;} - void setKerHMatrix(int dim, gmp_matrix* matrix) { + void setKerHMatrix(int dim, gmp_matrix* matrix) { if(dim > -1 && dim < 5) _kerH[dim] = matrix;} - void setCodHMatrix(int dim, gmp_matrix* matrix) { + void setCodHMatrix(int dim, gmp_matrix* matrix) { if(dim > -1 && dim < 5) _codH[dim] = matrix;} - void setJMatrix(int dim, gmp_matrix* matrix) { + void setJMatrix(int dim, gmp_matrix* matrix) { if(dim > -1 && dim < 5) _JMatrix[dim] = matrix;} - void setQMatrix(int dim, gmp_matrix* matrix) { + void setQMatrix(int dim, gmp_matrix* matrix) { if(dim > -1 && dim < 5) _QMatrix[dim] = matrix;} - void setHbasis(int dim, gmp_matrix* matrix) { + void setHbasis(int dim, gmp_matrix* matrix) { if(dim > -1 && dim < 5) _Hbasis[dim] = matrix;} // get the boundary operator matrix dim->dim-1 - gmp_matrix* getHMatrix(int dim) const { + gmp_matrix* getHMatrix(int dim) const { if(dim > -1 && dim < 5) return _HMatrix[dim]; else return NULL;} - gmp_matrix* getKerHMatrix(int dim) const { + gmp_matrix* getKerHMatrix(int dim) const { if(dim > -1 && dim < 5) return _kerH[dim]; else return NULL;} - gmp_matrix* getCodHMatrix(int dim) const { + gmp_matrix* getCodHMatrix(int dim) const { if(dim > -1 && dim < 5) return _codH[dim]; else return NULL;} - gmp_matrix* getJMatrix(int dim) const { + gmp_matrix* getJMatrix(int dim) const { if(dim > -1 && dim < 5) return _JMatrix[dim]; else return NULL;} - gmp_matrix* getQMatrix(int dim) const { + gmp_matrix* getQMatrix(int dim) const { if(dim > -1 && dim < 5) return _QMatrix[dim]; else return NULL;} - gmp_matrix* getHbasis(int dim) const { + gmp_matrix* getHbasis(int dim) const { if(dim > -1 && dim < 5) return _Hbasis[dim]; else return NULL;} // local deformation tools for chains bool deformChain(std::map<Cell*, int, Less_Cell>& cells, std::pair<Cell*, int> cell, bool bend); bool deform(std::map<Cell*, int, Less_Cell>& cells, - std::map<Cell*, int, Less_Cell>& cellsInChain, + std::map<Cell*, int, Less_Cell>& cellsInChain, std::map<Cell*, int, Less_Cell>& cellsNotInChain); void smoothenChain(std::map<Cell*, int, Less_Cell>& cells); void eraseNullCells(std::map<Cell*, int, Less_Cell>& cells); void deImmuneCells(std::map<Cell*, int, Less_Cell>& cells); - - public: + + public: // domain = 0 : relative chain space // domain = 1 : absolute chain space of all cells in cellComplex // domain = 2 : absolute chain space of cells in subdomain - ChainComplex(CellComplex* cellComplex, int domain=0); + ChainComplex(CellComplex* cellComplex, int domain=0); ~ChainComplex(); - + int getDim() const { return _dim; } - + // 0 : C basis (chains) // 1 : Z basis (cycles) // 2 : B basis (boundaries) // 3 : H basis (homology) // get the bases for various spaces - gmp_matrix* getBasis(int dim, int basis); + gmp_matrix* getBasis(int dim, int basis); gmp_matrix* getBoundaryOp(int dim) { if(dim > -1 && dim < 5) return _HMatrix[dim]; else return NULL;} @@ -123,30 +123,30 @@ class ChainComplex // of dimension dim (ie. ker(h_dim) and cod(h_dim) ) void KerCod(int dim); // compute matrix representation J for inclusion relation from dim-cells - // who are boundary of dim+1-cells to cycles of dim-cells + // who are boundary of dim+1-cells to cycles of dim-cells // (ie. j: cod(h_(dim+1)) -> ker(h_dim) ) void Inclusion(int lowDim, int highDim); // compute quotient problem for given inclusion relation j to find - // representatives of homology group generators and possible + // representatives of homology group generators and possible // torsion coeffcients void Quotient(int dim); - - // transpose the boundary operator matrices, these are boundary operator + + // transpose the boundary operator matrices, these are boundary operator // matrices for the dual mesh - void transposeHMatrices() { + void transposeHMatrices() { for(int i = 0; i < 5; i++) gmp_matrix_transp(_HMatrix[i]); } - void transposeHMatrix(int dim) { + void transposeHMatrix(int dim) { if(dim > -1 && dim < 5) gmp_matrix_transp(_HMatrix[dim]); } - - // Compute bases for the homology groups of this chain complex + + // Compute bases for the homology groups of this chain complex void computeHomology(bool dual=false); - - + + typedef std::map<Cell*, int, Less_Cell>::iterator citer; - citer firstCell(int dim){ return _cellIndices[dim].begin(); } - citer lastCell(int dim){ return _cellIndices[dim].end(); } + citer firstCell(int dim){ return _cellIndices[dim].begin(); } + citer lastCell(int dim){ return _cellIndices[dim].end(); } // get the cell index - int cellIndex(Cell* cell){ + int getCellIndex(Cell* cell){ citer cit = _cellIndices[cell->getDim()].find(cell); if(cit != lastCell(cell->getDim())) return cit->second; else return 0; @@ -158,13 +158,13 @@ class ChainComplex // (deform: with local deformations to make chain smoother and to have // smaller support, deformed chain is homologous to the old one, // only works for chains of the primary chain complex) - void getBasisChain(std::map<Cell*, int, Less_Cell>& chain, + void getBasisChain(std::map<Cell*, int, Less_Cell>& chain, int num, int dim, int basis, bool deform=false); // get rank of a basis int getBasisSize(int dim, int basis); - // homology torsion coefficient for dim-dimensional chain num + // homology torsion coefficient for dim-dimensional chain num int getTorsion(int dim, int num); - + // apply a transformation T to a basis (T should be unimodular) void transformBasis(gmp_matrix* T, int dim, int basis){ if(basis == 3 && _Hbasis[dim] != NULL) { @@ -174,10 +174,10 @@ class ChainComplex //void printBasisChain(std::map<Cell*, int, Less_Cell>& chain); // debugging aid - int printMatrix(gmp_matrix* matrix){ - printf("%d rows and %d columns\n", - (int)gmp_matrix_rows(matrix), (int)gmp_matrix_cols(matrix)); - return gmp_matrix_printf(matrix); } + int printMatrix(gmp_matrix* matrix){ + printf("%d rows and %d columns\n", + (int)gmp_matrix_rows(matrix), (int)gmp_matrix_cols(matrix)); + return gmp_matrix_printf(matrix); } void matrixTest(); }; @@ -191,7 +191,7 @@ class HomologySequence ChainComplex* _subcomplex; ChainComplex* _complex; ChainComplex* _relcomplex; - + gmp_matrix* _Ic_sub[4]; gmp_matrix* _Ic_rel[4]; @@ -199,7 +199,7 @@ class HomologySequence gmp_matrix* _Jh[4]; gmp_matrix* _invIh[4]; gmp_matrix* _invJh[4]; - + gmp_matrix* _Dh[4]; gmp_matrix* _invDh[4]; @@ -213,29 +213,29 @@ class HomologySequence void findInvDhMap(int i); public: - - HomologySequence(ChainComplex* subcomplex, ChainComplex* complex, + + HomologySequence(ChainComplex* subcomplex, ChainComplex* complex, ChainComplex* relcomplex); ~HomologySequence(); // create an inclusion map from domBasis to codBasis // (deletes domBasis, leaves codBasis unaffected) - gmp_matrix* createIncMap(gmp_matrix* domBasis, + gmp_matrix* createIncMap(gmp_matrix* domBasis, gmp_matrix* codBasis); gmp_matrix* removeZeroCols(gmp_matrix* matrix); - void blockHBasis(gmp_matrix* block1T, gmp_matrix* block2T, + void blockHBasis(gmp_matrix* block1T, gmp_matrix* block2T, ChainComplex* complex, int dim); - + int printMatrix(gmp_matrix* matrix){ if(matrix == NULL){ printf("NULL matrix. \n"); return 0; } printf("%d rows and %d columns\n", (int)gmp_matrix_rows(matrix), (int)gmp_matrix_cols(matrix)); - return gmp_matrix_printf(matrix); } - + return gmp_matrix_printf(matrix); } + }; #endif -#endif - +#endif + diff --git a/Geo/Homology.cpp b/Geo/Homology.cpp index d635a22e3b6ba06f97a313dd52db547d8e047113..9596a1715d9b90d05194100b59259ce72c1473f5 100644 --- a/Geo/Homology.cpp +++ b/Geo/Homology.cpp @@ -313,6 +313,9 @@ void Homology::_createPhysicalGroup(std::map<Cell*, int, Less_Cell>& chain, std: MElementFactory factory; int dim = 0; + std::map<Cell*, int, Less_Cell> chain2; + std::string name2 = name + "i"; + typedef std::map<Cell*, int, Less_Cell>::iterator citer; for(citer cit = chain.begin(); cit != chain.end(); cit++){ Cell* cell = cit->first; @@ -335,8 +338,15 @@ void Homology::_createPhysicalGroup(std::map<Cell*, int, Less_Cell>& chain, std: elements.push_back(ecopy); } + //std::vector<double> coeffs (1,1); std::vector<double> coeffs (1,abs(coeff)); data[e->getNum()] = coeffs; + + /*if(abs(coeff) > 1) { + if(coeff < 0) chain2[cell] = coeff+1; + else chain2[cell] = coeff-1; + }*/ + } GModel* m = this->getModel(); @@ -373,6 +383,7 @@ void Homology::_createPhysicalGroup(std::map<Cell*, int, Less_Cell>& chain, std: view->setOptions(opt); #endif } + //if(!chain2.empty()) _createPhysicalGroup(chain2, name2); } bool Homology::writeBasisMSH(bool binary)