diff --git a/Geo/ChainComplex.cpp b/Geo/ChainComplex.cpp index 93f4e3237f7ace378b7cafe837846ca80d3abc09..a77267522e7aff16bd465c3d1d75967f75817624 100644 --- a/Geo/ChainComplex.cpp +++ b/Geo/ChainComplex.cpp @@ -441,12 +441,8 @@ gmp_matrix* ChainComplex::getBasis(int dim, int basis) void ChainComplex::getBasisChain(std::map<Cell*, int, Less_Cell>& chain, int num, int dim, int basis, bool deform) { - gmp_matrix* basisMatrix; - if(basis == 0) basisMatrix = getBasis(dim, 0); - else if(basis == 1) basisMatrix = getBasis(dim, 1); - else if(basis == 2) basisMatrix = getBasis(dim, 2); - else if(basis == 3) basisMatrix = getBasis(dim, 3); - else return; + if(basis < 0 || basis > 3) return; + gmp_matrix* basisMatrix = getBasis(dim, basis); chain.clear(); if(dim < 0 || dim > 4) return; @@ -473,8 +469,8 @@ void ChainComplex::getBasisChain(std::map<Cell*, int, Less_Cell>& chain, std::map<Cell*, int, Less_Cell > subCells; cell->getCells(subCells); for(Cell::citer it = subCells.begin(); it != subCells.end(); it++){ - Cell* subCell = (*it).first; - int coeff = (*it).second; + Cell* subCell = it->first; + int coeff = it->second; chain[subCell] = coeff*elemi*torsion; } } diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp index f17915de01562d9412bbe0f4e5081935998fed21..e21bdffaa58128dab1a09d69490676fe2bb1d4a6 100644 --- a/Geo/GModel.cpp +++ b/Geo/GModel.cpp @@ -984,9 +984,15 @@ void GModel::storeChain(int dim, std::map<int, std::vector<MElement*> > &entityMap, std::map<int, std::map<int, std::string> > &physicalMap) { - // create new discrete entities that have no associated MVertices _storeElementsInEntities(entityMap); _storePhysicalTagsInEntities(dim, physicalMap); + std::map<int, std::vector<MElement*> >::iterator it; + for(it = entityMap.begin(); it != entityMap.end(); it++) { + if(dim == 0) _chainVertices.insert(getVertexByTag(it->first)); + else if(dim == 1) _chainEdges.insert(getEdgeByTag(it->first)); + else if(dim == 2) _chainFaces.insert(getFaceByTag(it->first)); + else if(dim == 3) _chainRegions.insert(getRegionByTag(it->first)); + } } template<class T> @@ -1057,11 +1063,11 @@ void GModel::_storeElementsInEntities(std::map< int, std::vector<MElement* > >& } template<class T> -static void _associateEntityWithElementVertices(GEntity *ge, std::vector<T*> &elements) +static void _associateEntityWithElementVertices(GEntity *ge, std::vector<T*> &elements, bool force=false) { for(unsigned int i = 0; i < elements.size(); i++){ for(int j = 0; j < elements[i]->getNumVertices(); j++){ - if (!elements[i]->getVertex(j)->onWhat() || + if (force || !elements[i]->getVertex(j)->onWhat() || elements[i]->getVertex(j)->onWhat()->dim() > ge->dim()) elements[i]->getVertex(j)->setEntity(ge); } @@ -1137,6 +1143,25 @@ void GModel::_pruneMeshVertexAssociations() entities[i]->mesh_vertices.clear(); } _associateEntityWithMeshVertices(); + // associate mesh vertices primarily with chain entities + for(riter it = _chainRegions.begin(); it != _chainRegions.end(); ++it){ + _associateEntityWithElementVertices(*it, (*it)->tetrahedra, true); + _associateEntityWithElementVertices(*it, (*it)->hexahedra, true); + _associateEntityWithElementVertices(*it, (*it)->prisms, true); + _associateEntityWithElementVertices(*it, (*it)->pyramids, true); + _associateEntityWithElementVertices(*it, (*it)->polyhedra, true); + } + for(fiter it = _chainFaces.begin(); it != _chainFaces.end(); ++it){ + _associateEntityWithElementVertices(*it, (*it)->triangles, true); + _associateEntityWithElementVertices(*it, (*it)->quadrangles, true); + _associateEntityWithElementVertices(*it, (*it)->polygons, true); + } + for(eiter it = _chainEdges.begin(); it != _chainEdges.end(); ++it){ + _associateEntityWithElementVertices(*it, (*it)->lines, true); + } + for(viter it = _chainVertices.begin(); it != _chainVertices.end(); ++it){ + _associateEntityWithElementVertices(*it, (*it)->points, true); + } _storeVerticesInEntities(vertices); } @@ -1739,7 +1764,7 @@ void GModel::createTopologyFromFaces(std::vector<discreteFace*> &discFaces, int for (std::vector<discreteFace*>::iterator it = discFaces.begin(); it != discFaces.end(); it++) (*it)->findEdges(map_edges); - + // return if no boundary edges (torus, sphere, ...) if (map_edges.empty()) return; diff --git a/Geo/GModel.h b/Geo/GModel.h index f19bc97bd12e719e3cf10d4e52e714b252633617..7ab64098818e05519563901e365ba9781af65294 100644 --- a/Geo/GModel.h +++ b/Geo/GModel.h @@ -38,6 +38,10 @@ class GModel private: friend class OCCFactory; std::multimap<std::pair<std::vector<int>, std::vector<int> >, std::string> _homologyRequests; + std::set<GRegion*, GEntityLessThan> _chainRegions; + std::set<GFace*, GEntityLessThan> _chainFaces; + std::set<GEdge*, GEntityLessThan> _chainEdges; + std::set<GVertex*, GEntityLessThan> _chainVertices; protected: // the name of the model @@ -376,12 +380,12 @@ class GModel // mesh the model int mesh(int dimension); - // adapt the mesh anisotropically using metrics that are computed from a set of functions f(x,y,z). + // adapt the mesh anisotropically using metrics that are computed from a set of functions f(x,y,z). // For all algorithms // parameters[1] = lcmin (default : in global gmsh options CTX::instance()->mesh.lcMin) // parameters[2] = lcmax (default : in global gmsh options CTX::instance()->mesh.lcMax) - // niter is the maximum number of iterations - // Available algorithms: + // niter is the maximum number of iterations + // Available algorithms: // 1) Assume that the function is a levelset -> adapt using Coupez technique (technique = 1) // parameters[0] = thickness of the interface (mandatory) // 2) Assume that the function is a physical quantity -> adapt using the Hessian (technique = 2) @@ -397,7 +401,7 @@ class GModel // parameters[4] = thickness of the interface in the negative ls direction (=parameters[0] if not specified) // parameters[3] = the required minimum number of elements to represent a circle - used for curvature-based metric (default: = 15) // 5) Same as 4, except that the transition in band E uses linear interpolation of h, instead of linear interpolation of metric - // The algorithm first generate a mesh if no one is available + // The algorithm first generate a mesh if no one is available // In this first attempt, only the highest dimensional mesh is adapted, which is ok if // we assume that boundaries are already adapted. @@ -487,15 +491,7 @@ class GModel void storeChain(int dim, std::map<int, std::vector<MElement*> > &entityMap, std::map<int, std::map<int, std::string> > &physicalMap); - void storeChain(std::vector<MVertex*> &vertices, int dim, - std::map<int, std::vector<MElement*> > &entityMap, - std::map<int, std::map<int, std::string> > &physicalMap) - { - _storeVerticesInEntities(vertices); - _storeElementsInEntities(entityMap); - _storePhysicalTagsInEntities(dim, physicalMap); - _associateEntityWithMeshVertices(); - } + // request homology computation void addHomologyRequest(const std::string &type, std::vector<int> &domain, std::vector<int> &subdomain); diff --git a/Geo/Homology.cpp b/Geo/Homology.cpp index 9596a1715d9b90d05194100b59259ce72c1473f5..fe390b4e07cc08d9b8f6b79bbf84ef696694098b 100644 --- a/Geo/Homology.cpp +++ b/Geo/Homology.cpp @@ -130,7 +130,6 @@ void Homology::findHomologyBasis(CellComplex* cellComplex) _subdomainEntities); ownComplex = true; } - std::string domainString = _getDomainString(_domain, _subdomain); Msg::StatusBar(2, true, "Reducing cell complex..."); @@ -151,7 +150,7 @@ void Homology::findHomologyBasis(CellComplex* cellComplex) Msg::StatusBar(2, true, "Done computing homology space basis (%g s)", t2 - t1); int dim = cellComplex->getDim(); - + std::string domain = _getDomainString(_domain, _subdomain); int HRank[4]; for(int j = 0; j < 4; j++){ HRank[j] = 0; @@ -162,7 +161,7 @@ void Homology::findHomologyBasis(CellComplex* cellComplex) std::string generator = ""; convert(i, generator); - std::string name = "H" + dimension + domainString + generator; + std::string name = "H" + dimension + domain + generator; std::map<Cell*, int, Less_Cell> chain; chainComplex.getBasisChain(chain, i, j, 3, _smoothen); int torsion = chainComplex.getTorsion(j,i); @@ -181,7 +180,7 @@ void Homology::findHomologyBasis(CellComplex* cellComplex) if(ownComplex) delete cellComplex; - Msg::Info("Ranks of homology spaces:"); + Msg::Info("Ranks of domain %shomology spaces:", domain.c_str()); Msg::Info("H0 = %d", HRank[0]); Msg::Info("H1 = %d", HRank[1]); Msg::Info("H2 = %d", HRank[2]); @@ -221,7 +220,7 @@ void Homology::findCohomologyBasis(CellComplex* cellComplex) Msg::StatusBar(2, true, "Done computing cohomology space basis (%g s)", t2- t1); int dim = cellComplex->getDim(); - + std::string domain = _getDomainString(_domain, _subdomain); int HRank[4]; for(int i = 0; i < 4; i++) HRank[i] = 0; for(int j = 3; j > -1; j--){ @@ -234,7 +233,7 @@ void Homology::findCohomologyBasis(CellComplex* cellComplex) convert(i, generator); std::string name = "H" + dimension + "*" + - _getDomainString(_domain, _subdomain) + generator; + domain + generator; std::map<Cell*, int, Less_Cell> chain; chainComplex.getBasisChain(chain, i, j, 3, _smoothen); int torsion = chainComplex.getTorsion(j,i); @@ -252,7 +251,7 @@ void Homology::findCohomologyBasis(CellComplex* cellComplex) if(ownComplex) delete cellComplex; - Msg::Info("Ranks of cohomology spaces:"); + Msg::Info("Ranks of domain %scohomology spaces:", domain.c_str()); Msg::Info("H0* = %d", HRank[0]); Msg::Info("H1* = %d", HRank[1]); Msg::Info("H2* = %d", HRank[2]); @@ -313,9 +312,6 @@ 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; @@ -338,15 +334,8 @@ 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(); @@ -383,7 +372,6 @@ 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) diff --git a/Geo/Homology.h b/Geo/Homology.h index a781b714a5c0bebf0804f3c58b884c0548a75150..c5dbdc9e51c663939edb175b91271f7c37906411 100644 --- a/Geo/Homology.h +++ b/Geo/Homology.h @@ -52,7 +52,7 @@ class Homology // create a string describing the generator std::string _getDomainString(const std::vector<int>& domain, - const std::vector<int>& subdomain); + const std::vector<int>& subdomain); // remove cells with coefficient 0 int _eraseNullCells(std::map<Cell*, int, Less_Cell>& chain);