diff --git a/Geo/CellComplex.cpp b/Geo/CellComplex.cpp index 892fc24c667f1169656bd9f764d670802775495e..dcbad2b1d6657380c71bfdae3b71848cfdf01071 100644 --- a/Geo/CellComplex.cpp +++ b/Geo/CellComplex.cpp @@ -69,13 +69,12 @@ CellComplex::CellComplex( std::vector<GEntity*> domain, std::vector<GEntity*> su } } } - // insert cells into cell complex // subdomain need to be inserted first! insert_cells(true, true); insert_cells(false, true); insert_cells(false, false); - + // find mesh vertices in the domain for(unsigned int j=0; j < domain.size(); j++) { for(unsigned int i=0; i < domain.at(j)->getNumMeshElements(); i++){ @@ -85,6 +84,7 @@ CellComplex::CellComplex( std::vector<GEntity*> domain, std::vector<GEntity*> su } } } + for(unsigned int j=0; j < subdomain.size(); j++) { for(unsigned int i=0; i < subdomain.at(j)->getNumMeshElements(); i++){ for(int k=0; k < subdomain.at(j)->getMeshElement(i)->getNumVertices(); k++){ @@ -94,7 +94,7 @@ CellComplex::CellComplex( std::vector<GEntity*> domain, std::vector<GEntity*> su } } - + // attach individual tags to cells int tag = 1; for(int i = 0; i < 4; i++){ @@ -120,11 +120,12 @@ void CellComplex::insert_cells(bool subdomain, bool boundary){ else if(boundary) domain = _boundary; else domain = _domain; - std::vector<int> vertices; + std::vector<MVertex*> vertices; int vertex = 0; std::pair<citer, bool> insertInfo; + // add highest dimensional cells for(unsigned int j=0; j < domain.size(); j++) { for(unsigned int i=0; i < domain.at(j)->getNumMeshElements(); i++){ @@ -132,7 +133,7 @@ void CellComplex::insert_cells(bool subdomain, bool boundary){ for(int k=0; k < domain.at(j)->getMeshElement(i)->getNumVertices(); k++){ MVertex* vertex = domain.at(j)->getMeshElement(i)->getVertex(k); - vertices.push_back(vertex->getNum()); + vertices.push_back(vertex); } int dim = domain.at(j)->getMeshElement(i)->getDim(); @@ -141,23 +142,23 @@ void CellComplex::insert_cells(bool subdomain, bool boundary){ if(dim == 3) cell = new ThreeSimplex(vertices, 0, subdomain, boundary); else if(dim == 2) cell = new TwoSimplex(vertices, 0, subdomain, boundary); else if(dim == 1) cell = new OneSimplex(vertices, 0, subdomain, boundary); - else cell = new ZeroSimplex(vertices.at(0), 0, subdomain, boundary); + else cell = new ZeroSimplex(vertices, 0, subdomain, boundary); insertInfo = _cells[dim].insert(cell); if(!insertInfo.second) delete cell; } } - + // add lower dimensional cells recursively for (int dim = 3; dim > 0; dim--){ for(citer cit = firstCell(dim); cit != lastCell(dim); cit++){ Cell* cell = *cit; - std::vector<int> vertices; + std::vector<MVertex*> vertices; for(int i = 0; i < cell->getNumFacets(); i++){ cell->getFacetVertices(i, vertices); Cell* newCell; if(dim == 3) newCell = new TwoSimplex(vertices, 0, subdomain, boundary); else if(dim == 2) newCell = new OneSimplex(vertices, 0, subdomain, boundary); - else if(dim == 1) newCell = new ZeroSimplex(vertices.at(0), 0, subdomain, boundary); + else if(dim == 1) newCell = new ZeroSimplex(vertices, 0, subdomain, boundary); insertInfo = _cells[dim-1].insert(newCell); if(!insertInfo.second){ delete newCell; @@ -186,7 +187,7 @@ void CellComplex::insertCell(Cell* cell){ int Simplex::kappa(Cell* tau) const{ for(int i=0; i < tau->getNumVertices(); i++){ - if( !(this->hasVertex(tau->getVertex(i))) ) return 0; + if( !(this->hasVertex(tau->getVertex(i)->getNum())) ) return 0; } if(this->getDim() - tau->getDim() != 1) return 0; @@ -249,62 +250,6 @@ int OneSimplex::kappa(Cell* tau) const{ } */ -int Quadrangle::kappa(Cell* tau) const{ - for(int i=0; i < tau->getNumVertices(); i++){ - if( !(this->hasVertex(tau->getVertex(i))) ) return 0; - } - - if(tau->getDim() != 1) return 0; - - int value=1; - - std::vector<int> vTau = tau->getVertexVector(); - - for(int i = 0; i < this->getNumFacets(); i++){ - std::vector<int> v; - this->getFacetVertices(i, v); - value = -1; - do { - value = value*-1; - if(v == vTau) return value; - } - while (std::next_permutation(v.begin(), v.end()) ); - } - - return value; -} - -/* -std::set<Cell*, Less_Cell>::iterator CellComplex::findCell(int dim, std::vector<int>& vertices, bool original){ - Cell* cell; - - if(dim == 0) cell = new ZeroSimplex(vertices.at(0)); - else if(dim == 1) cell = new OneSimplex(vertices); - else if(dim == 2) cell = new TwoSimplex(vertices); - else cell = new ThreeSimplex(vertices); - - citer cit; - if(!original) cit = _cells[dim].find(cell); - else cit = _originalCells[dim].find(cell); - - delete cell; - return cit; -} - -std::set<Cell*, Less_Cell>::iterator CellComplex::findCell(int dim, int vertex, int dummy){ - Cell* cell; - if(dim == 0) cell = new ZeroSimplex(vertex); - else if(dim == 1) cell = new OneSimplex(vertex, dummy); - else if(dim == 2) cell = new TwoSimplex(vertex, dummy); - else cell = new ThreeSimplex(vertex, dummy); - - citer cit = _cells[dim].lower_bound(cell); - - delete cell; - return cit; -} -*/ - void CellComplex::removeCell(Cell* cell){ _cells[cell->getDim()].erase(cell); @@ -380,79 +325,6 @@ int CellComplex::coreduction(Cell* generator){ //printf("Coreduction: %d loops with %d coreductions\n", round, coreductions); return coreductions; } -/* -int CellComplex::coreduction(int dim){ - - if(dim < 0 || dim > 2) return 0; - - std::list<Cell*> bd_c; - int count = 0; - - bool coreduced = true; - while (coreduced){ - coreduced = false; - for(citer cit = firstCell(dim+1); cit != lastCell(dim+1); cit++){ - Cell* cell = *cit; - - bd_c = cell->getBoundary(); - if(bd_c.size() == 1 && inSameDomain(cell, bd_c.front()) ){ - removeCell(cell); - removeCell(bd_c.front()); - count++; - coreduced = true; - } - - } - } - - return count; - -} -*/ -/* -int CellComplex::reduction(Cell* generator){ - - int count = 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 = cbd_s.front()->getBoundary(); - enqueueCells(bd_c, Q, Qset); - removeCell(cbd_s.front()); - count++; - } - else if(cbd_s.empty()){ - bd_c = s->getBoundary(); - enqueueCells(bd_c, Q, Qset); - } - - - } - - return count; -} -*/ - int CellComplex::reduction(int dim){ if(dim < 1 || dim > 3) return 0; @@ -483,13 +355,6 @@ void CellComplex::reduceComplex(bool omitHighdim){ printf("Cell complex before reduction: %d volumes, %d faces, %d edges and %d vertices.\n", getSize(3), getSize(2), getSize(1), getSize(0)); - - //reduction(3); - //reduction(2); - //reduction(1); - - - int count = 0; for(int i = 3; i > 0; i--) count = count + reduction(i); @@ -527,45 +392,7 @@ void CellComplex::reduceComplex(bool omitHighdim){ getSize(3), getSize(2), getSize(1), getSize(0)); } -/* -void CellComplex::coreduceComplex(int generatorDim){ - - - std::set<Cell*, Less_Cell> generatorCells[4]; - - printf("Cell complex before coreduction: %d volumes, %d faces, %d edges and %d vertices.\n", - getSize(3), getSize(2), getSize(1), getSize(0)); - for(int i = 0; i < 4; i++){ - while (getSize(i) != 0){ - //if(generatorDim == i || i == generatorDim+1) break; - citer cit = firstCell(i); - Cell* cell = *cit; - while(!cell->inSubdomain() && cit != lastCell(i)){ - cell = *cit; - cit++; - } - if(!cell->inSubdomain()) generatorCells[i].insert(cell); - removeCell(cell); - coreduction(cell); - } - if(generatorDim == i) break; - - } - - for(int i = 0; i < 4; i++){ - for(citer cit = generatorCells[i].begin(); cit != generatorCells[i].end(); cit++){ - Cell* cell = *cit; - _cells[i].insert(cell); - } - } - - printf("Cell complex after coreduction: %d volumes, %d faces, %d edges and %d vertices.\n", - getSize(3), getSize(2), getSize(1), getSize(0)); - - return; -} -*/ void CellComplex::removeSubdomain(){ for(int i = 0; i < 4; i++){ @@ -581,55 +408,7 @@ void CellComplex::removeSubdomain(){ return; } -/* -int CellComplex::coreduction(int dim){ - - int count = 0; - - std::queue<Cell*> Q; - std::set<Cell*, Less_Cell> Qset; - - std::list<Cell*> bd_s; - std::list<Cell*> cbd_c; - - for(citer cit = firstCell(dim); cit != lastCell(dim); cit++){ - - Cell* cell = *cit; - cbd_c = cell->getCoboundary(); - enqueueCells(cbd_c, Q, Qset); - - int round = 0; - while( !Q.empty() ){ - round++; - //printf("%d ", round); - - Cell* s = Q.front(); - Q.pop(); - - bd_s = s->getBoundary(); - - if( bd_s.size() == 1 && inSameDomain(s, bd_s.front()) ){ - removeCell(s); - cbd_c = bd_s.front()->getCoboundary(); - enqueueCells(cbd_c, Q, Qset); - removeCell(bd_s.front()); - cit = firstCell(dim); - count++; - } - else if(bd_s.empty()){ - cbd_c = s->getCoboundary(); - enqueueCells(cbd_c, Q, Qset); - } - - removeCellQset(s, Qset); - - } - - - } - return count; -} -*/ + void CellComplex::coreduceComplex(bool omitLowdim){ printf("Cell complex before coreduction: %d volumes, %d faces, %d edges and %d vertices.\n", @@ -668,24 +447,7 @@ void CellComplex::coreduceComplex(bool omitLowdim){ } - /* - std::set<Cell*, Less_Cell> generatorCells; - - while (getSize(0) != 0){ - citer cit = firstCell(0); - Cell* cell = *cit; - while(!cell->inSubdomain() && cit != lastCell(0)){ - cell = *cit; - cit++; - } - if(!cell->inSubdomain()) generatorCells.insert(cell); - removeCell(cell); - coreduction(cell); - } - */ - - printf("Cell complex after coreduction: %d volumes, %d faces, %d edges and %d vertices.\n", getSize(3), getSize(2), getSize(1), getSize(0)); @@ -694,18 +456,6 @@ void CellComplex::coreduceComplex(bool omitLowdim){ void CellComplex::computeBettiNumbers(){ - /* - removeSubdomain(); - - int count = 0; - for(int dim = 0; dim < 4; dim++){ - citer cit = firstCell(dim); - if(cit != lastCell(dim)){ - Cell* cell = *cit; - count = count + coreduction(cell); - } - } - */ for(int i = 0; i < 4; i++){ printf("Betti number computation process: step %d of 4 \n", i+1); @@ -913,41 +663,6 @@ int CellComplex::combine(int dim){ return count; } -/* -void CellComplex::repairComplex(int i){ - - printf("Cell complex before repair: %d volumes, %d faces, %d edges and %d vertices.\n", - getSize(3), getSize(2), getSize(1), getSize(0)); - - while(i > 0){ - - for(citer cit = firstCell(i); cit != lastCell(i); cit++){ - Cell* cell = *cit; - std::vector<int> vertices = cell->getVertexVector(); - - for(int j=0; j < vertices.size(); j++){ - std::vector<int> bVertices; - - for(int k=0; k < vertices.size(); k++){ - if (k !=j ) bVertices.push_back(vertices.at(k)); - } - citer cit2 = findCell(i-1, bVertices, true); - Cell* cell2 = *cit2; - _cells[i-1].insert(cell2); - - } - } - i--; - - } - - printf("Cell complex after repair: %d volumes, %d faces, %d edges and %d vertices.\n", - getSize(3), getSize(2), getSize(1), getSize(0)); - - return; -} -*/ - void CellComplex::swapSubdomain(){ for(int i = 0; i < 4; i++){ @@ -1021,7 +736,7 @@ int CellComplex::writeComplexMSH(const std::string &name){ if(vertex->inSubdomain()) physical = 3; else if(vertex->onDomainBoundary()) physical = 2; else physical = 1; - fprintf(fp, "%d %d %d %d %d %d %d\n", vertex->getTag(), 15, 3, 0, 0, physical, vertex->getVertex(0)); + fprintf(fp, "%d %d %d %d %d %d %d\n", vertex->getTag(), 15, 3, 0, 0, physical, vertex->getVertex(0)->getNum()); } std::list< std::pair<int, Cell*> > cells; @@ -1033,7 +748,7 @@ int CellComplex::writeComplexMSH(const std::string &name){ cells = edge->getCells(); for(std::list< std::pair<int, Cell*> >::iterator it = cells.begin(); it != cells.end(); it++){ Cell* cell = (*it).second; - fprintf(fp, "%d %d %d %d %d %d %d %d\n", cell->getTag(), 1, 3, 0, 0, physical, cell->getVertex(0), cell->getVertex(1)); + fprintf(fp, "%d %d %d %d %d %d %d %d\n", cell->getTag(), 1, 3, 0, 0, physical, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum()); } } @@ -1045,7 +760,7 @@ int CellComplex::writeComplexMSH(const std::string &name){ cells = face->getCells(); for(std::list< std::pair<int, Cell*> >::iterator it = cells.begin(); it != cells.end(); it++){ Cell* cell = (*it).second; - fprintf(fp, "%d %d %d %d %d %d %d %d %d\n", cell->getTag(), 2, 3, 0, 0, physical, cell->getVertex(0), cell->getVertex(1), cell->getVertex(2)); + fprintf(fp, "%d %d %d %d %d %d %d %d %d\n", cell->getTag(), 2, 3, 0, 0, physical, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum(), cell->getVertex(2)->getNum()); } } for(citer cit = firstCell(3); cit != lastCell(3); cit++) { @@ -1056,7 +771,7 @@ int CellComplex::writeComplexMSH(const std::string &name){ cells = volume->getCells(); for(std::list< std::pair<int, Cell*> >::iterator it = cells.begin(); it != cells.end(); it++){ Cell* cell = (*it).second; - fprintf(fp, "%d %d %d %d %d %d %d %d %d %d\n", cell->getTag(), 4, 3, 0, 0, physical, cell->getVertex(0), cell->getVertex(1), cell->getVertex(2), cell->getVertex(3)); + fprintf(fp, "%d %d %d %d %d %d %d %d %d %d\n", cell->getTag(), 4, 3, 0, 0, physical, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum(), cell->getVertex(2)->getNum(), cell->getVertex(3)->getNum()); } } @@ -1072,20 +787,10 @@ void CellComplex::printComplex(int dim){ for (citer cit = firstCell(dim); cit != lastCell(dim); cit++){ Cell* cell = *cit; for(int i = 0; i < cell->getNumVertices(); i++){ - printf("%d ", cell->getVertex(i)); + printf("%d ", cell->getVertex(i)->getNum()); } printf("\n"); } } - -DualCellComplex::DualCellComplex(CellComplex* cellComplex){ - - for(int i = 0; i < 4; i++){ - _cells[i] = cellComplex->getCells(i); - } - - - -} diff --git a/Geo/CellComplex.h b/Geo/CellComplex.h index 5eec690c5ac830d2c988829a3f7a4257f16a0800..8961d5cbb12c31382953a7362532c1f6fdee195a 100644 --- a/Geo/CellComplex.h +++ b/Geo/CellComplex.h @@ -15,12 +15,18 @@ #include <queue> #include "GmshConfig.h" #include "MElement.h" +#include "MPoint.h" +#include "MLine.h" +#include "MTriangle.h" +#include "MTetrahedron.h" #include "GModel.h" #include "GEntity.h" #include "GRegion.h" #include "GFace.h" #include "GVertex.h" + + // Abstract class representing an elemtary cell of a cell complex. class Cell { @@ -28,11 +34,7 @@ class Cell // cell dimension int _dim; - // maximum number of lower dimensional cells on the boundary of this cell - int _bdMaxSize; - // maximum number of higher dimensional cells on the coboundary of this cell - int _cbdMaxSize; - + // whether this cell belongs to a subdomain // used in relative homology computation bool _inSubdomain; @@ -40,6 +42,7 @@ class Cell // whether this cell belongs to the boundary of a cell complex bool _onDomainBoundary; + // whether this cell a combinded cell of elemetary cells bool _combined; // unique tag for each cell @@ -63,10 +66,10 @@ class Cell // get the number of vertices this cell has - virtual int getNumVertices() const = 0; //{return _vertices.size();} - virtual int getVertex(int vertex) const = 0; //{return _vertices.at(vertex);} + virtual int getNumVertices() const = 0; + virtual MVertex* getVertex(int vertex) const = 0; //{return _vertices.at(vertex);} virtual int getSortedVertex(int vertex) const = 0; - virtual std::vector<int> getVertexVector() const = 0; + virtual std::vector<MVertex*> getVertexVector() const = 0; // returns 1 or -1 if lower dimensional cell tau is on the boundary of this cell // otherwise returns 0 @@ -74,11 +77,8 @@ class Cell virtual int kappa(Cell* tau) const = 0; // true if this cell has given vertex - virtual bool hasVertex(int vertex) const =0; + virtual bool hasVertex(int vertex) const = 0; - virtual unsigned int getBdMaxSize() const { return _bdMaxSize; }; - virtual unsigned int getCbdMaxSize() const { return _cbdMaxSize; }; - virtual int getBoundarySize() { return _boundary.size(); } virtual int getCoboundarySize() { return _coboundary.size(); } @@ -146,13 +146,8 @@ class Cell // print cell vertices virtual void printCell() const = 0; - // return the coordinates of this cell (only used on zero-cells if anywhere) - virtual inline double x() const { return 0; } - virtual inline double y() const { return 0; } - virtual inline double z() const { return 0; } - virtual int getNumFacets() const { return 0; } - virtual void getFacetVertices(const int num, std::vector<int> &v) const {}; + virtual void getFacetVertices(const int num, std::vector<MVertex*> &v) const {}; virtual bool combined() { return _combined; } virtual std::list< std::pair<int, Cell*> > getCells() { std::list< std::pair<int, Cell*> >cells; cells.push_back( std::make_pair(1, this)); return cells; } @@ -202,304 +197,159 @@ class Simplex : public Cell }; // Zero simplex cell type. -class ZeroSimplex : public Simplex +class ZeroSimplex : public Simplex, public MPoint { private: - // number of the vertex - // same as the corresponding vertex in the finite element mesh - int _v; - // coordinates of this zero simplex, if needed - double _x, _y, _z; + public: - ZeroSimplex(int vertex, int tag=0, bool subdomain=false, bool boundary=false, double x=0, double y=0, double z=0) : Simplex(){ - _v = vertex; - _tag = tag; - _dim = 0; - _bdMaxSize = 0; - _cbdMaxSize = 1000; // big number - _x = x; - _y = y; - _z = z; - _inSubdomain = subdomain; - _onDomainBoundary = boundary; - } + ZeroSimplex(std::vector<MVertex*> v, int tag=0, bool subdomain=false, bool boundary=false, int num=0, int part=0) + : MPoint(v, num, part){ + _tag = tag; + _inSubdomain = subdomain; + _onDomainBoundary = boundary; + } ~ZeroSimplex(){} - //int getDim() const { return 0; } + int getDim() const { return 0; } int getNumVertices() const { return 1; } - int getVertex(int vertex) const {return _v; } - int getSortedVertex(int vertex) const {return _v; } - bool hasVertex(int vertex) const {return (_v == vertex); } + MVertex* getVertex(int vertex) const {return _v[0]; } + int getSortedVertex(int vertex) const {return _v[0]->getNum(); } + bool hasVertex(int vertex) const {return (_v[0]->getNum() == vertex); } - std::vector<int> getVertexVector() const { return std::vector<int>(1,_v); } - std::vector<int> getSortedVertexVector() const { return std::vector<int>(1,_v); } + std::vector<MVertex*> getVertexVector() const { std::vector<MVertex*> v; v.push_back(_v[0]); return v; } + std::vector<int> getSortedVertexVector() const { return std::vector<int>(1,_v[0]->getNum()); } - inline double x() const { return _x; } - inline double y() const { return _y; } - inline double z() const { return _z; } - - void printCell() const { printf("Vertices: %d, in subdomain: %d \n", _v, _inSubdomain); } + void printCell() const { printf("Vertices: %d, in subdomain: %d \n", _v[0]->getNum(), _inSubdomain); } }; // One simplex cell type. -class OneSimplex : public Simplex +class OneSimplex : public Simplex, public MLine { private: - // numbers of the vertices of this simplex - // same as the corresponding vertices in the finite element mesh - int _v[2]; int _vs[2]; public: - OneSimplex(std::vector<int> vertices, int tag=0, bool subdomain=false, bool boundary=false) : Simplex(){ - _v[0] = vertices.at(0); - _v[1] = vertices.at(1); - sort(vertices.begin(), vertices.end()); - _vs[0] = vertices.at(0); - _vs[1] = vertices.at(1); - _tag = tag; - _dim = 1; - _bdMaxSize = 2; - _cbdMaxSize = 1000; - _inSubdomain = subdomain; - _onDomainBoundary = boundary; - } - - - - // constructor for the dummy one simplex - // used to find another definite one simplex from the cell complex - // first vertex gives the lower bound from where to look - OneSimplex(int vertex, int dummy){ - _vs[0] = vertex; - _vs[1] = dummy; - } + + OneSimplex(std::vector<MVertex*> v, int tag=0, bool subdomain=false, bool boundary=false, int num=0, int part=0) + : MLine(v, num, part){ + _tag = tag; + _inSubdomain = subdomain; + _onDomainBoundary = boundary; + _vs[0] = v.at(0)->getNum(); + _vs[1] = v.at(1)->getNum(); + std::sort(_vs, _vs+2); + } ~OneSimplex(){} - //int getDim() const { return 1; } + int getDim() const { return 1; } int getNumVertices() const { return 2; } int getNumFacets() const { return 2; } - int getVertex(int vertex) const {return _v[vertex]; } + MVertex* getVertex(int vertex) const {return _v[vertex]; } int getSortedVertex(int vertex) const {return _vs[vertex]; } - bool hasVertex(int vertex) const {return (_v[0] == vertex || _v[1] == vertex); } + bool hasVertex(int vertex) const {return (_v[0]->getNum() == vertex || _v[1]->getNum() == vertex); } - std::vector<int> getVertexVector() const { - return std::vector<int>(_v, _v + sizeof(_v)/sizeof(int) ); } + std::vector<MVertex*> getVertexVector() const { + return std::vector<MVertex*>(_v, _v + sizeof(_v)/sizeof(MVertex*) ); } std::vector<int> getSortedVertexVector() const { return std::vector<int>(_vs, _vs + sizeof(_vs)/sizeof(int) ); } - void getFacetVertices(const int num, std::vector<int> &v) const { + void getFacetVertices(const int num, std::vector<MVertex*> &v) const { v.resize(1); v[0] = _v[num]; } //int kappa(Cell* tau) const; - void printCell() const { printf("Vertices: %d %d, in subdomain: %d \n", _v[0], _v[1], _inSubdomain); } + void printCell() const { printf("Vertices: %d %d, in subdomain: %d \n", _v[0]->getNum(), _v[1]->getNum(), _inSubdomain); } }; // Two simplex cell type. -class TwoSimplex : public Simplex +class TwoSimplex : public Simplex, public MTriangle { private: - // numbers of the vertices of this simplex - // same as the corresponding vertices in the finite element mesh - int _v[3]; + int _vs[3]; - int edges_tri(const int edge, const int vert) const{ - static const int e[3][2] = { - {0, 1}, - {1, 2}, - {2, 0} - }; - return e[edge][vert]; - } - public: - - TwoSimplex(std::vector<int> vertices, int tag=0, bool subdomain=false, bool boundary=false) : Simplex(){ - _v[0] = vertices.at(0); - _v[1] = vertices.at(1); - _v[2] = vertices.at(2); - sort(vertices.begin(), vertices.end()); - _vs[0] = vertices.at(0); - _vs[1] = vertices.at(1); - _vs[2] = vertices.at(2); - _tag = tag; - _dim = 2; - _bdMaxSize = 3; - _cbdMaxSize = 2; - _inSubdomain = subdomain; - _onDomainBoundary = boundary; - } - // constructor for the dummy one simplex - TwoSimplex(int vertex, int dummy){ - _v[0] = vertex; - _v[1] = dummy; - _v[2] = dummy; - } + + TwoSimplex(std::vector<MVertex*> v, int tag=0, bool subdomain=false, bool boundary=false, int num=0, int part=0) + : MTriangle(v, num, part){ + _tag = tag; + _inSubdomain = subdomain; + _onDomainBoundary = boundary; + _vs[0] = v.at(0)->getNum(); + _vs[1] = v.at(1)->getNum(); + _vs[2] = v.at(2)->getNum(); + std::sort(_vs, _vs+3); + } ~TwoSimplex(){} - //int getDim() const { return 2; } + int getDim() const { return 2; } int getNumVertices() const { return 3; } int getNumFacets() const { return 3; } - int getVertex(int vertex) const {return _v[vertex]; } + MVertex* getVertex(int vertex) const {return _v[vertex]; } int getSortedVertex(int vertex) const {return _vs[vertex]; } bool hasVertex(int vertex) const {return - (_v[0] == vertex || _v[1] == vertex || _v[2] == vertex); } - std::vector<int> getVertexVector() const { - return std::vector<int>(_v, _v + sizeof(_v)/sizeof(int) ); } + (_v[0]->getNum() == vertex || _v[1]->getNum() == vertex || _v[2]->getNum() == vertex); } + + std::vector<MVertex*> getVertexVector() const { + return std::vector<MVertex*>(_v, _v + sizeof(_v)/sizeof(MVertex*) ); } std::vector<int> getSortedVertexVector() const { return std::vector<int>(_vs, _vs + sizeof(_vs)/sizeof(int) ); } - void getFacetVertices(const int num, std::vector<int> &v) const { - v.resize(2); - v[0] = _v[edges_tri(num, 0)]; - v[1] = _v[edges_tri(num, 1)]; + void getFacetVertices(const int num, std::vector<MVertex*> &v) const { + MTriangle::getEdgeVertices(num, v); } - void printCell() const { printf("Vertices: %d %d %d, in subdomain: %d\n", _v[0], _v[1], _v[2], _inSubdomain); } + void printCell() const { printf("Vertices: %d %d %d, in subdomain: %d\n", _v[0]->getNum(), _v[1]->getNum(), _v[2]->getNum(), _inSubdomain); } }; // Three simplex cell type. -class ThreeSimplex : public Simplex +class ThreeSimplex : public Simplex, public MTetrahedron { private: - // numbers of the vertices of this simplex - // same as the corresponding vertices in the finite element mesh - int _v[4]; int _vs[4]; - - int faces_tetra(const int face, const int vert) const{ - static const int f[4][3] = { - {0, 2, 1}, - {0, 1, 3}, - {0, 3, 2}, - {3, 1, 2} - }; - return f[face][vert]; - } - + public: - - ThreeSimplex(std::vector<int> vertices, int tag=0, bool subdomain=false, bool boundary=false) : Simplex(){ - _v[0] = vertices.at(0); - _v[1] = vertices.at(1); - _v[2] = vertices.at(2); - _v[3] = vertices.at(3); - sort(vertices.begin(), vertices.end()); - _vs[0] = vertices.at(0); - _vs[1] = vertices.at(1); - _vs[2] = vertices.at(2); - _vs[3] = vertices.at(3); - _tag = tag; - _dim = 3; - _bdMaxSize = 4; - _cbdMaxSize = 0; - _inSubdomain = subdomain; - _onDomainBoundary = boundary; - } - // constructor for the dummy one simplex - ThreeSimplex(int vertex, int dummy){ - _v[0] = vertex; - _v[1] = dummy; - _v[2] = dummy; - _v[3] = dummy; - } + ThreeSimplex(std::vector<MVertex*> v, int tag=0, bool subdomain=false, bool boundary=false, int num=0, int part=0) + : MTetrahedron(v, num, part){ + _tag = tag; + _inSubdomain = subdomain; + _onDomainBoundary = boundary; + _vs[0] = v.at(0)->getNum(); + _vs[1] = v.at(1)->getNum(); + _vs[2] = v.at(2)->getNum(); + _vs[3] = v.at(3)->getNum(); + std::sort(_vs, _vs+4); + } ~ThreeSimplex(){} - //int getDim() const { return 3; } + int getDim() const { return 3; } int getNumVertices() const { return 4; } int getNumFacets() const { return 4; } - int getVertex(int vertex) const {return _v[vertex]; } + MVertex* getVertex(int vertex) const {return _v[vertex]; } int getSortedVertex(int vertex) const {return _vs[vertex]; } bool hasVertex(int vertex) const {return - (_v[0] == vertex || _v[1] == vertex || _v[2] == vertex || _v[3] == vertex); } - std::vector<int> getVertexVector() const { - return std::vector<int>(_v, _v + sizeof(_v)/sizeof(int) ); } + (_v[0]->getNum() == vertex || _v[1]->getNum() == vertex || _v[2]->getNum() == vertex || _v[3]->getNum() == vertex); } + std::vector<MVertex*> getVertexVector() const { + return std::vector<MVertex*>(_v, _v + sizeof(_v)/sizeof(MVertex*) ); } std::vector<int> getSortedVertexVector() const { return std::vector<int>(_vs, _vs + sizeof(_vs)/sizeof(int) ); } - void getFacetVertices(const int num, std::vector<int> &v) const { - v.resize(3); - v[0] = _v[faces_tetra(num, 0)]; - v[1] = _v[faces_tetra(num, 1)]; - v[2] = _v[faces_tetra(num, 2)]; + void getFacetVertices(const int num, std::vector<MVertex*> &v) const { + MTetrahedron::getFaceVertices(num, v); } - virtual void printCell() const { printf("Vertices: %d %d %d %d, in subdomain: %d \n", _v[0], _v[1], _v[2], _v[3], _inSubdomain); } + virtual void printCell() const { printf("Vertices: %d %d %d %d, in subdomain: %d \n", _v[0]->getNum(), _v[1]->getNum(), _v[2]->getNum(), _v[3]->getNum(), _inSubdomain); } }; - -class Quadrangle : public Cell -{ - private: - - int _v[4]; - int _vs[4]; - - int edges_quad(const int edge, const int vert) const{ - static const int e[4][2] = { - {0, 1}, - {1, 2}, - {2, 3}, - {3, 0} - }; - return e[edge][vert]; - } - - public: - - Quadrangle(std::vector<int> vertices, int tag=0, bool subdomain=false, bool boundary=false) : Cell(){ - _v[0] = vertices.at(0); - _v[1] = vertices.at(1); - _v[2] = vertices.at(2); - _v[3] = vertices.at(3); - sort(vertices.begin(), vertices.end()); - _vs[0] = vertices.at(0); - _vs[1] = vertices.at(1); - _vs[2] = vertices.at(2); - _vs[3] = vertices.at(3); - _tag = tag; - _dim = 2; - _bdMaxSize = 4; - _cbdMaxSize = 2; - _inSubdomain = subdomain; - _onDomainBoundary = boundary; - } - ~Quadrangle(){} - - //int getDim() const { return 2; } - int getNumVertices() const { return 4; } - int getNumFacets() const { return 4; } - int getVertex(int vertex) const {return _v[vertex]; } - int getSortedVertex(int vertex) const { return _vs[vertex]; } - int kappa(Cell* tau) const; - - bool hasVertex(int vertex) const {return - (_v[0] == vertex || _v[1] == vertex || _v[2] == vertex || _v[3] == vertex); } - std::vector<int> getVertexVector() const { - return std::vector<int>(_v, _v + sizeof(_v)/sizeof(int) ); } - std::vector<int> getSortedVertexVector() const { - return std::vector<int>(_vs, _vs + sizeof(_vs)/sizeof(int) ); } - - void getFacetVertices(const int num, std::vector<int> &v) const { - v.resize(2); - v[0] = _v[edges_quad(num, 0)]; - v[1] = _v[edges_quad(num, 1)]; - } - -}; - - // Ordering for the cells. class Less_Cell{ public: @@ -519,18 +369,7 @@ class Less_Cell{ if(c1->getSortedVertex(i) < c2->getSortedVertex(i)) return true; else if (c1->getSortedVertex(i) > c2->getSortedVertex(i)) return false; } - - /* - std::vector<int> c1v = c1->getVertexVector(); - std::vector<int> c2v = c2->getVertexVector(); - std::sort(c1v.begin(), c1v.end()); - std::sort(c2v.begin(), c2v.end()); - - for(int i=0; i < c1v.size();i++){ - if(c1v.at(i) < c2v.at(i)) return true; - else if (c1v.at(i) > c2v.at(i)) return false; - } - */ + return false; } }; @@ -563,7 +402,7 @@ class Less_MVertex{ class CombinedCell : public Cell{ private: - std::vector<int> _v; + std::vector<MVertex*> _v; std::vector<int> _vs; std::list< std::pair<int, Cell*> > _cells; @@ -572,18 +411,16 @@ class CombinedCell : public Cell{ CombinedCell(Cell* c1, Cell* c2, bool orMatch, bool co=false) : Cell(){ _tag = c1->getTag(); _dim = c1->getDim(); - _bdMaxSize = 1000000; - _cbdMaxSize = 1000000; _inSubdomain = c1->inSubdomain(); _onDomainBoundary = c1->onDomainBoundary(); _combined = true; _v = c1->getVertexVector(); for(int i = 0; i < c2->getNumVertices(); i++){ - if(!this->hasVertex(c2->getVertex(i))) _v.push_back(c2->getVertex(i)); + if(!this->hasVertex(c2->getVertex(i)->getNum())) _v.push_back(c2->getVertex(i)); } - _vs = _v; + for(int i = 0; i < _v.size(); i++) _vs.push_back(_v.at(i)->getNum()); std::sort(_vs.begin(), _vs.end()); _cells = c1->getCells(); @@ -630,16 +467,16 @@ class CombinedCell : public Cell{ ~CombinedCell(){} int getNumVertices() const { return _v.size(); } - int getVertex(int vertex) const { return _v.at(vertex); } + MVertex* getVertex(int vertex) const { return _v.at(vertex); } int getSortedVertex(int vertex) const { return _vs.at(vertex); } - std::vector<int> getVertexVector() const { return _v; } + std::vector<MVertex*> getVertexVector() const { return _v; } int kappa(Cell* tau) const { return 0; } // true if this cell has given vertex bool hasVertex(int vertex) const { for(int i = 0; i < _v.size(); i++){ - if(_v.at(i) == vertex) return true; + if(_v.at(i)->getNum() == vertex) return true; } return false; } @@ -647,7 +484,7 @@ class CombinedCell : public Cell{ virtual void printCell() const { printf("Vertices: "); for(int i = 0; i < this->getNumVertices(); i++){ - printf("%d ", this->getVertex(i)); + printf("%d ", this->getVertex(i)->getNum()); } printf(", in subdomain: %d\n", _inSubdomain); } @@ -748,10 +585,6 @@ class CellComplex virtual citer firstCell(int dim) {return _cells[dim].begin(); } virtual citer lastCell(int dim) {return _cells[dim].end(); } - // find a cell in this cell complex - //virtual std::set<Cell*, Less_Cell>::iterator findCell(int dim, std::vector<int>& vertices, bool original=false); - //virtual std::set<Cell*, Less_Cell>::iterator findCell(int dim, int vertex, int dummy=0); - // kappa for two cells of this cell complex // implementation will vary depending on cell type virtual inline int kappa(Cell* sigma, Cell* tau) const { return sigma->kappa(tau); } @@ -767,27 +600,17 @@ class CellComplex virtual bool inSameDomain(Cell* c1, Cell* c2) const { return ( (!c1->inSubdomain() && !c2->inSubdomain()) || (c1->inSubdomain() && c2->inSubdomain()) ); } - // coreduction of this cell complex - // removes corection pairs of cells of dimension dim and dim+1 - //virtual int coreduction(int dim); - //virtual int coreduction(); - - // stores removed cells // reduction of this cell complex // removes reduction pairs of cell of dimension dim and dim-1 virtual int reduction(int dim); - //virtual int reduction(Cell* generator); + // useful functions for (co)reduction of cell complex virtual void reduceComplex(bool omitHighdim = false); virtual void coreduceComplex(bool omitlowDim = false); - //virtual void coreduceComplex(int generatorDim); - //virtual void coreduceComplex(); - // queued coreduction presented in Mrozek's paper - // slower, but produces cleaner result virtual int coreduction(Cell* generator); // add every volume, face and edge its missing boundary cells @@ -827,15 +650,4 @@ class CellComplex }; - -class DualCellComplex : public CellComplex -{ - - public: - - DualCellComplex(CellComplex* cellComplex); - ~DualCellComplex(){} - -}; - #endif