diff --git a/Geo/CellComplex.h b/Geo/CellComplex.h index 742d85a49d1ec20193975a845618e149d9532ca5..79667eee33a96b5ccefa5ba02c78481b161f1a56 100644 --- a/Geo/CellComplex.h +++ b/Geo/CellComplex.h @@ -40,7 +40,7 @@ class Less_Cell{ bool operator()(const Cell* c1, const Cell* c2) const; }; -// Abstract class representing an elemtary cell of a cell complex. +// Abstract class representing an elementary cell of a cell complex. class Cell { protected: @@ -93,6 +93,9 @@ class Cell virtual int getIndex() const { return _index; }; virtual void setIndex(int index) { _index = index; }; virtual int getNum() { return -1; } + virtual int getType() { return -1; } + virtual int getTypeForMSH() { return -1; } + virtual int getPartition() { return -1; } virtual void setImmune(bool immune) { _immune = immune; }; virtual bool getImmune() const { return _immune; }; @@ -354,6 +357,9 @@ class ZeroSimplex : public Simplex, public MPoint int getDim() const { return 0; } int getNum() { return MPoint::getNum(); } + int getType() { return MPoint::getType(); } + int getTypeForMSH() { return MPoint::getTypeForMSH(); } + int getPartition() { return MPoint::getPartition(); } int getNumVertices() const { return 1; } MVertex* getVertex(int vertex) const {return _v[0]; } int getSortedVertex(int vertex) const {return _v[0]->getNum(); } @@ -389,6 +395,9 @@ class OneSimplex : public Simplex, public MLine int getDim() const { return 1; } int getNum() { return MLine::getNum(); } + int getType() { return MLine::getType(); } + int getTypeForMSH() { return MLine::getTypeForMSH(); } + int getPartition() { return MLine::getPartition(); } int getNumVertices() const { return 2; } int getNumFacets() const { return 2; } MVertex* getVertex(int vertex) const {return _v[vertex]; } @@ -435,6 +444,9 @@ class TwoSimplex : public Simplex, public MTriangle int getDim() const { return 2; } int getNum() { return MTriangle::getNum(); } + int getType() { return MTriangle::getType(); } + int getTypeForMSH() { return MTriangle::getTypeForMSH(); } + int getPartition() { return MTriangle::getPartition(); } int getNumVertices() const { return 3; } int getNumFacets() const { return 3; } MVertex* getVertex(int vertex) const {return _v[vertex]; } @@ -480,6 +492,9 @@ class CQuadrangle : public Cell, public MQuadrangle int getDim() const { return 2; } int getNum() { return MQuadrangle::getNum(); } + int getType() { return MQuadrangle::getType(); } + int getTypeForMSH() { return MQuadrangle::getTypeForMSH(); } + int getPartition() { return MQuadrangle::getPartition(); } int getNumVertices() const { return 4; } int getNumFacets() const { return 4; } MVertex* getVertex(int vertex) const {return _v[vertex]; } @@ -527,6 +542,9 @@ class ThreeSimplex : public Simplex, public MTetrahedron int getDim() const { return 3; } int getNum() { return MTetrahedron::getNum(); } + int getType() { return MTetrahedron::getType(); } + int getTypeForMSH() { return MTetrahedron::getTypeForMSH(); } + int getPartition() { return MTetrahedron::getPartition(); } int getNumVertices() const { return 4; } int getNumFacets() const { return 4; } MVertex* getVertex(int vertex) const {return _v[vertex]; } @@ -573,6 +591,9 @@ class CHexahedron : public Cell, public MHexahedron int getDim() const { return 3; } int getNum() { return MHexahedron::getNum(); } + int getType() { return MHexahedron::getType(); } + int getTypeForMSH() { return MHexahedron::getTypeForMSH(); } + int getPartition() { return MHexahedron::getPartition(); } int getNumVertices() const { return 8; } int getNumFacets() const { return 6; } MVertex* getVertex(int vertex) const {return _v[vertex]; } @@ -619,6 +640,9 @@ class CPrism : public Cell, public MPrism int getDim() const { return 3; } int getNum() { return MPrism::getNum(); } + int getType() { return MPrism::getType(); } + int getTypeForMSH() { return MPrism::getTypeForMSH(); } + int getPartition() { return MPrism::getPartition(); } int getNumVertices() const { return 6; } int getNumFacets() const { return 5; } MVertex* getVertex(int vertex) const {return _v[vertex]; } @@ -664,6 +688,9 @@ class CPyramid : public Cell, public MPyramid int getDim() const { return 3; } int getNum() { return MPyramid::getNum(); } + int getType() { return MPyramid::getType(); } + int getTypeForMSH() { return MPyramid::getTypeForMSH(); } + int getPartition() { return MPyramid::getPartition(); } int getNumVertices() const { return 5; } int getNumFacets() const { return 5; } MVertex* getVertex(int vertex) const {return _v[vertex]; } diff --git a/Geo/ChainComplex.cpp b/Geo/ChainComplex.cpp index 85929ec46949a3f8c05391d5e6a67d2a11ff98a0..5f78674b7773fcc301320f2c9ffb698bf8520d7d 100644 --- a/Geo/ChainComplex.cpp +++ b/Geo/ChainComplex.cpp @@ -7,6 +7,7 @@ #include "ChainComplex.h" #include "OS.h" +#include "PView.h" #if defined(HAVE_KBIPACK) @@ -455,7 +456,7 @@ int ChainComplex::getTorsion(int dim, int chainNumber){ } -Chain::Chain(std::set<Cell*, Less_Cell> cells, std::vector<int> coeffs, CellComplex* cellComplex, std::string name, int torsion){ +Chain::Chain(std::set<Cell*, Less_Cell> cells, std::vector<int> coeffs, CellComplex* cellComplex, GModel* model, std::string name, int torsion){ int i = 0; for(std::set<Cell*, Less_Cell>::iterator cit = cells.begin(); cit != cells.end(); cit++){ @@ -478,6 +479,7 @@ Chain::Chain(std::set<Cell*, Less_Cell> cells, std::vector<int> coeffs, CellComp _name = name; _cellComplex = cellComplex; _torsion = torsion; + _model = model; } @@ -821,7 +823,7 @@ void Chain::smoothenChain(){ straightenChain(*cit); } - + eraseNullCells(); double t2 = Cpu(); printf("Smoothened a %d-chain from %d cells to %d cells (%g s).\n", getDim(), start, getSize(), t2-t1); return; @@ -875,39 +877,32 @@ int Chain::writeChainMSH(const std::string &name){ } -/* -void Chain::getData(std::map<int, std::vector<double> > & data){ +void Chain::createPView(){ - if(getSize() == 0) return; + std::vector<MElement*> elements; + MElementFactory factory; + + std::map<int, std::vector<double> > data; - //std::list< std::pair<int, Cell*> > cells; - for(int i = 0; i < getSize(); i++){ - Cell* cell = getCell(i); - /* - cells = cell->getCells(); - for(std::list< std::pair<int, Cell*> >::iterator it = cells.begin(); it != cells.end(); it++){ - Cell* cell2 = (*it).second; - std::vector<double> coeff; - coeff.push_back(getCoeff(i)*(*it).first); - std::pair<int, std::vector<double> > dataPair = std::make_pair(cell2->getTag(), coeff); - data.insert(dataPair); - //printf("%d, %d, \n", cell2->getNum(), (int)coeff.at(0)); - - } - - std::vector<double> coeff; - coeff.push_back(getCoeff(i)); - std::pair<int, std::vector<double> > dataPair = std::make_pair(cell->getTag(), coeff); - data.insert(dataPair); + for(citer cit = _cells.begin(); cit != _cells.end(); cit++){ + Cell* cell = (*cit).first; + int coeff = (*cit).second; + std::vector<MVertex*> v = cell->getVertexVector(); + MElement *e = factory.create(cell->getTypeForMSH(), v, cell->getNum(), cell->getPartition()); + elements.push_back(e); + std::vector<double> coeffs (1,coeff); + data.insert(std::make_pair(e->getNum(), coeffs)); } - //for(std::map<int, std::vector<double> >::iterator it = data.begin(); it != data.end(); it++){ - // printf("%d, %d, \n", (*it).first, (int)(*it).second.at(0)); - //} + std::map<int, std::vector<MElement*> > map; + map.insert(std::make_pair(0, elements)); + _model->storeElementsInEntities(map); + + if(!data.empty()) PView *chain = new PView(getName(), "ElementData", getGModel(), data, 0, 1); - return; + return; } -*/ + #endif diff --git a/Geo/ChainComplex.h b/Geo/ChainComplex.h index 7739b36c37bc9a2f81f4a1f4ebeea8bb7a73da7c..06e85c8569077d5e08fa9cab280adbf8c176979c 100644 --- a/Geo/ChainComplex.h +++ b/Geo/ChainComplex.h @@ -141,6 +141,7 @@ class Chain{ std::string _name; // cell complex this chain belongs to CellComplex* _cellComplex; + GModel* _model; // torsion coefficient int _torsion; @@ -157,13 +158,15 @@ class Chain{ public: Chain(){} - Chain(std::set<Cell*, Less_Cell> cells, std::vector<int> coeffs, CellComplex* cellComplex, std::string name="Chain", int torsion=0); + Chain(std::set<Cell*, Less_Cell> cells, std::vector<int> coeffs, CellComplex* cellComplex, GModel* model, + std::string name="Chain", int torsion=0); Chain(Chain* chain){ _cells = chain->getCells(); _torsion = chain->getTorsion(); _name = chain->getName(); _cellComplex = chain->getCellComplex(); _dim = chain->getDim(); + _model = chain->getGModel(); } ~Chain(){} @@ -175,7 +178,7 @@ class Chain{ //int getCoeff(int i) { return _cells.at(i).second; } - + // remove a cell from this chain void removeCell(Cell* cell) { citer it = _cells.find(cell); if(it != _cells.end()){ @@ -183,6 +186,8 @@ class Chain{ } return; } + + // add a cell to this chain void addCell(Cell* cell, int coeff) { std::pair<citer,bool> insert = _cells.insert( std::make_pair( cell, coeff)); if(!insert.second && (*insert.first).second == 0) (*insert.first).second = coeff; @@ -193,26 +198,12 @@ class Chain{ } return; } - /* - void insertCells(){ - for(citer cit = _cells.begin(); cit != _cells.end(); cit++){ - Cell* cell = (*cit).first; - std::vector<Cell*> cells; - if(!_cellComplex->hasCell(cell)){ - _cellComplex->insertCell(cell); - } - - } - return; - } - */ - + bool hasCell(Cell* c){ citer it = _cells.find(c); if(it != _cells.end() && (*it).second != 0) return true; return false; - } - + } Cell* findCell(Cell* c){ citer it = _cells.find(c); if(it != _cells.end() && (*it).second != 0) return (*it).first; @@ -225,13 +216,13 @@ class Chain{ } - - int getTorsion() {return _torsion;} int getDim() {return _dim;} CellComplex* getCellComplex() {return _cellComplex;} + GModel* getGModel() {return _model;} std::map<Cell*, int, Less_Cell> getCells() {return _cells;} + // erase cells from the chain with zero coefficient void eraseNullCells(){ for(citer cit = _cells.begin(); cit != _cells.end(); cit++){ if( (*cit).second == 0){ @@ -250,6 +241,7 @@ class Chain{ return; } + void deImmuneCells(){ for(citer cit = _cells.begin(); cit != _cells.end(); cit++){ Cell* cell = (*cit).first; @@ -262,29 +254,26 @@ class Chain{ //eraseNullCells(); return _cells.size(); } - int getNumCells() { - //int count = 0; - //for(std::vector< std::pair <Cell*, int> >::iterator it = _cells.begin(); it != _cells.end(); it++){ - // Cell* cell = (*it).first; - // count = count + cell->getNumCells(); - //} - //return count; return _cells.size(); } - // get/set chain name std::string getName() { return _name; } void setName(std::string name) { _name=name; } + // make local deformations to the chain to make it smoother and smaller + // (for primary complex chains only, not for dual chains represented by primary cells (yet).) void smoothenChain(); // append this chain to a 2.1 MSH ASCII file as $ElementData int writeChainMSH(const std::string &name); + + // create a PView of this chain. + // Warning: saving the PView in the GUI changes the numbering of the mesh, + // but NOT the numbering of the post-processing ElementData accordingly! (See Post/PViewDataGModelIO.cpp writeMSH) + void createPView(); - //void getData(std::map<int, std::vector<double> >& data); - }; #endif diff --git a/Geo/GModel.h b/Geo/GModel.h index 7aab300314ef13a9ea3afd663bb68fabf2e9a0f7..fc5f44e668045db87a548bfed469fcbe4da250d2 100644 --- a/Geo/GModel.h +++ b/Geo/GModel.h @@ -442,6 +442,10 @@ class GModel void load(std::string fileName); static void registerBindings(binding *b); + + void storeElementsInEntities(std::map<int, std::vector<MElement*> > &map){ + _storeElementsInEntities(map); + } }; #endif diff --git a/Geo/Homology.cpp b/Geo/Homology.cpp index a4447364402d4521382bea6c46ea0b045a97920b..36c986821104f3f81b6df2df419b7615615c7286 100644 --- a/Geo/Homology.cpp +++ b/Geo/Homology.cpp @@ -9,8 +9,6 @@ #include "Homology.h" #include "ChainComplex.h" #include "OS.h" -#include "PView.h" -#include "PViewDataGModel.h" #if defined(HAVE_KBIPACK) Homology::Homology(GModel* model, std::vector<int> physicalDomain, std::vector<int> physicalSubdomain){ @@ -127,7 +125,7 @@ void Homology::findGenerators(std::string fileName){ convert(i, generator); std::string name = "H" + dimension + getDomainString() + generator; - Chain* chain = new Chain(_cellComplex->getCells(j), chains->getCoeffVector(j,i), _cellComplex, name, chains->getTorsion(j,i)); + Chain* chain = new Chain(_cellComplex->getCells(j), chains->getCoeffVector(j,i), _cellComplex, _model, name, chains->getTorsion(j,i)); //Chain* chain2 = new Chain(chain); //printf("chain %d \n", i); t1 = Cpu(); @@ -149,7 +147,7 @@ void Homology::findGenerators(std::string fileName){ convert(i+1, generator); std::string name = "H" + dimension + getDomainString() + generator; std::vector<int> coeffs (_cellComplex->getOmitted(i).size(),1); - Chain* chain = new Chain(_cellComplex->getOmitted(i), coeffs, _cellComplex, name, 1); + Chain* chain = new Chain(_cellComplex->getOmitted(i), coeffs, _cellComplex, _model, name, 1); if(chain->getSize() != 0) HRank[j] = HRank[j] + 1; //delete chain; chainVector.push_back(chain); @@ -160,9 +158,11 @@ void Homology::findGenerators(std::string fileName){ } _cellComplex->writeComplexMSH(fileName); + //writeHeaderMSH(fileName); for(int i = 0; i < chainVector.size(); i++){ Chain* chain = chainVector.at(i); chain->writeChainMSH(fileName); + chain->createPView(); chainVector.at(i) = NULL; delete chain; } @@ -251,8 +251,9 @@ void Homology::findDualGenerators(std::string fileName){ convert(i, generator); std::string name = "H" + dimension + "*" + getDomainString() + generator; - Chain* chain = new Chain(_cellComplex->getCells(j), chains->getCoeffVector(j,i), _cellComplex, name, chains->getTorsion(j,i)); + Chain* chain = new Chain(_cellComplex->getCells(j), chains->getCoeffVector(j,i), _cellComplex, _model, name, chains->getTorsion(j,i)); chain->writeChainMSH(fileName); + chain->createPView(); if(chain->getSize() != 0){ HRank[dim-j] = HRank[dim-j] + 1; if(chain->getTorsion() != 1) Msg::Warning("H%d* %d has torsion coefficient %d!", dim-j, i, chain->getTorsion()); @@ -268,7 +269,7 @@ void Homology::findDualGenerators(std::string fileName){ convert(i+1, generator); std::string name = "H" + dimension + "*" + getDomainString() + generator; std::vector<int> coeffs (_cellComplex->getOmitted(i).size(),1); - Chain* chain = new Chain(_cellComplex->getOmitted(i), coeffs, _cellComplex, name, 1); + Chain* chain = new Chain(_cellComplex->getOmitted(i), coeffs, _cellComplex, _model, name, 1); chain->writeChainMSH(fileName); if(chain->getSize() != 0) HRank[dim-j] = HRank[dim-j] + 1; delete chain; diff --git a/Geo/Homology.h b/Geo/Homology.h index 8175fc95f22d1fb6bd95325ae78417ac60a833f2..844af0b60836f711cd87b5859ecb5cf3e5dbc6d7 100644 --- a/Geo/Homology.h +++ b/Geo/Homology.h @@ -78,6 +78,17 @@ class Homology return domainString; } + int writeHeaderMSH(const std::string &name){ + FILE *fp = fopen(name.c_str(), "w"); + if(!fp){ + Msg::Error("Unable to open file '%s'", name.c_str()); + printf("Unable to open file."); + return 0; + } + fprintf(fp, "$MeshFormat\n2.1 0 8\n$EndMeshFormat\n"); + fclose(fp); + return 1; + } }; #endif diff --git a/tutorial/t10.geo b/tutorial/t10.geo index af4b553952e783637331c3d18d349bf6302742e2..f15f751a7da5ab99b06586407bfcc174473bb290 100644 --- a/tutorial/t10.geo +++ b/tutorial/t10.geo @@ -128,11 +128,11 @@ Physical Surface(75) = {46, 63, 66, 52, 50, 48, 54, 60, 58, 56}; Mesh 3; // Find generators of relative homology spaces of the domain modulo the four terminals. -// Save the generator chains to t10_homgen_1.msh. +// Save the generator chains to t10_homgen.msh. HomGen("t10_homgen.msh") = {{69}, {70, 71, 72, 73}}; // Find the corresponding cuts. -// Save the cut chains to t10_homcut_1.msh. +// Save the cut chains to t10_homcut.msh. HomCut("t10_homcut.msh") = {{69}, {70, 71, 72, 73}}; // Only find and print the ranks of the relative homology spaces (Betti numbers). @@ -144,14 +144,10 @@ Mesh.Lines = 0; Mesh.Triangles = 0; Mesh.Tetrahedra = 0; -// Show the results as post-processing views -Merge "t10_homgen.msh"; -Merge "t10_homcut.msh"; - // More examples (uncomment): -// HomGen("t10_homgen.msh") = {{69}, {}}; Merge "t10_homgen.msh"; -// HomGen("t10_homgen.msh") = {{69}, {74}}; Merge "t10_homgen.msh"; -// HomGen("t10_homgen.msh") = {{69}, {75}}; Merge "t10_homgen.msh"; +// HomGen("t10_homgen.msh_1") = {{69}, {}}; +// HomGen("t10_homgen.msh_2") = {{69}, {74}}; +// HomGen("t10_homgen.msh_3") = {{69}, {75}};