diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp index 089fb42dab7bc2310591edfebecc8305f2c2bce6..9f8f4f3aa38b8dd87704f40938534e6b9d6595dc 100644 --- a/Geo/GModel.cpp +++ b/Geo/GModel.cpp @@ -1889,7 +1889,6 @@ GModel *GModel::buildCutGModel(gLevelset *ls, bool cutElem, bool saveTri) GModel *cutGM = buildCutMesh(this, ls, elements, vertexMap, physicals, cutElem); - for(int i = 0; i < (int)(sizeof(elements) / sizeof(elements[0])); i++) cutGM->_storeElementsInEntities(elements[i]); cutGM->_associateEntityWithMeshVertices(); @@ -1906,7 +1905,6 @@ GModel *GModel::buildCutGModel(gLevelset *ls, bool cutElem, bool saveTri) } } - Msg::Info("Mesh cutting completed (%g s)", Cpu() - t1); return cutGM; diff --git a/Geo/MElementCut.cpp b/Geo/MElementCut.cpp index be041390afd2bfed82bb03918dd4453f7b7179fc..751d9dbc7f2cc55ccf936557f73b59d1174e0fd5 100644 --- a/Geo/MElementCut.cpp +++ b/Geo/MElementCut.cpp @@ -574,7 +574,7 @@ static int getBorderTag(int lsTag, int count, int &maxTag, std::map<int, int> &b { if(borderTags.count(lsTag)) return borderTags[lsTag]; - if(count) { + if(count || lsTag < 0) { int tag = ++maxTag; borderTags[lsTag] = tag; return tag; @@ -689,56 +689,102 @@ static void elementSplitMesh(MElement *e, fullMatrix<double> &verticesLs, } //create level set interface (pt in 1D, line in 2D or face in 3D) - if (splitElem && e->getDim()==2){ + if(splitElem && e->getDim() == 2){ for(int k = 0; k < e->getNumEdges(); k++){ MEdge me = e->getEdge(k); MVertex *v0 = me.getVertex(0); MVertex *v1 = me.getVertex(1); MVertex *v0N = vertexMap[v0->getNum()]; MVertex *v1N = vertexMap[v1->getNum()]; - double val0 = verticesLs(0, v0->getIndex())-eps; - double val1 = verticesLs(0, v1->getIndex())-eps; + double val0 = verticesLs(0, v0->getIndex()) - eps; + double val1 = verticesLs(0, v1->getIndex()) - eps; //printf("splitedge v0= (%g,%g) v1= (%g,%g) val0= %g(%d) val1= %g(%d) nums (%d %d)\n", v0->x(), v0->y(), v1->x(), v1->y(), val0, v0->getIndex(), val1, v1->getIndex(), vertexMap[v0->getNum()]->getIndex(), vertexMap[v1->getNum()]->getIndex()); - if ( (val0*val1 > 0.0 && val0 < 0.0 ) ) { - //printf("split edge \n"); - MLine *lin = new MLine(v0N, v1N); + if(val0*val1 > 0.0 && val0 < 0.0) { getPhysicalTag(-1, gePhysicals, newPhysTags[1]); int c = elements[1].count(gLsTag); int reg = getBorderTag(gLsTag, c, newElemTags[1][0], borderElemTags[0]); - int physTag = (!gePhysicals.size()) ? 0 : getBorderTag(gLsTag, c, newPhysTags[1][0], borderPhysTags[0]); - elements[1][reg].push_back(lin); - if(physTag) assignLsPhysical(GM, reg, 1, physicals, physTag, gLsTag); + int physTag = (!gePhysicals.size()) ? 0 : + getBorderTag(gLsTag, c, newPhysTags[1][0], borderPhysTags[0]); + int i; + for(i = elements[1][reg].size() - 1; i >= 0; i--){ + MElement *el = elements[1][reg][i]; + if((el->getVertex(0) == v0N && el->getVertex(1) == v1N) || + (el->getVertex(0) == v1N && el->getVertex(1) == v0N)) + break; + } + if(i < 0){ + MLine *lin = new MLine(v0N, v1N); + elements[1][reg].push_back(lin); + if(physTag) assignLsPhysical(GM, reg, 1, physicals, physTag, gLsTag); + } + else{ + MElement *el = elements[1][reg][i]; + elements[1][reg].erase(elements[1][reg].begin() + i); + delete el; + } } } } - else if (splitElem && e->getDim()==3){ + else if(splitElem && e->getDim() == 3){ for(int k = 0; k < e->getNumFaces(); k++){ - MFace mf = e->getFace(k); + MFace mf = e->getFace(k); bool sameSign = true; - double val0 = verticesLs(0, mf.getVertex(0)->getIndex()); - for (int j= 1; j< mf.getNumVertices(); j++){ - double valj = verticesLs(0, mf.getVertex(j)->getIndex()); + double val0 = verticesLs(0, mf.getVertex(0)->getIndex()) - eps; + for (int j = 1; j < mf.getNumVertices(); j++){ + double valj = verticesLs(0, mf.getVertex(j)->getIndex()) - eps; if (val0*valj < 0.0){ sameSign = false; break;} } - if (sameSign && val0 < 0.0) { + if(sameSign && val0 < 0.0) { getPhysicalTag(-1, gePhysicals, newPhysTags[2]); - int c = elements[2].count(gLsTag) + elements[3].count(gLsTag) + elements[8].count(gLsTag); + int c = elements[2].count(gLsTag) + elements[3].count(gLsTag) + + elements[8].count(gLsTag); int reg = getBorderTag(gLsTag, c, newElemTags[2][0], borderElemTags[1]); - int physTag = (!gePhysicals.size()) ? 0 : getBorderTag(gLsTag, c, newPhysTags[2][0], borderPhysTags[1]); + int physTag = (!gePhysicals.size()) ? 0 : + getBorderTag(gLsTag, c, newPhysTags[2][0], borderPhysTags[1]); if(mf.getNumVertices() == 3){ - MTriangle *tri = new MTriangle(vertexMap[mf.getVertex(0)->getNum()], - vertexMap[mf.getVertex(1)->getNum()], - vertexMap[mf.getVertex(2)->getNum()]); - elements[2][reg].push_back(tri); + MFace f1 = MFace(vertexMap[mf.getVertex(0)->getNum()], + vertexMap[mf.getVertex(1)->getNum()], + vertexMap[mf.getVertex(2)->getNum()]); + int i = elements[2][reg].size() - 1; + for(; i >= 0; i--){ + MElement *el = elements[2][reg][i]; + MFace f2 = MFace(el->getVertex(0), el->getVertex(1), el->getVertex(2)); + if(f1 == f2) break; + } + if(i < 0){ + MTriangle *tri = new MTriangle(f1.getVertex(0), f1.getVertex(1), f1.getVertex(2)); + elements[2][reg].push_back(tri); + } + else{ + MElement *el = elements[2][reg][i]; + elements[2][reg].erase(elements[2][reg].begin() + i); + delete el; + } } else if(mf.getNumVertices() == 4){ - MQuadrangle *quad = new MQuadrangle(vertexMap[mf.getVertex(0)->getNum()], - vertexMap[mf.getVertex(1)->getNum()], - vertexMap[mf.getVertex(2)->getNum()], - vertexMap[mf.getVertex(3)->getNum()]); - elements[3][reg].push_back(quad); + MFace f1 = MFace(vertexMap[mf.getVertex(0)->getNum()], + vertexMap[mf.getVertex(1)->getNum()], + vertexMap[mf.getVertex(2)->getNum()], + vertexMap[mf.getVertex(3)->getNum()]); + int i; + for(i = elements[3][reg].size() - 1; i >= 0; i--){ + MElement *el = elements[3][reg][i]; + MFace f2 = MFace(el->getVertex(0), el->getVertex(1), + el->getVertex(2), el->getVertex(3)); + if(f1 == f2) break; + } + if(i < 0){ + MQuadrangle *quad = new MQuadrangle(f1.getVertex(0), f1.getVertex(1), + f1.getVertex(2), f1.getVertex(2)); + elements[3][reg].push_back(quad); + } + else{ + MElement *el = elements[3][reg][i]; + elements[3][reg].erase(elements[3][reg].begin() + i); + delete el; + } } - if(physTag) assignLsPhysical(GM, reg, 2, physicals, physTag, gLsTag); + if(physTag) assignLsPhysical(GM, reg, 2, physicals, physTag, gLsTag); } } } @@ -1026,7 +1072,8 @@ static void elementCutMesh(MElement *e, std::vector<gLevelset *> &RPN, int c = elements[2].count(lsTag) + elements[3].count(lsTag) + elements[8].count(lsTag); // the surfaces are cut before the volumes! int reg = getBorderTag(lsTag, c, newElemTags[2][0], borderElemTags[1]); - int physTag = (!gePhysicals.size()) ? 0 : getBorderTag(lsTag, c, newPhysTags[2][0], borderPhysTags[1]); + int physTag = (!gePhysicals.size()) ? 0 : + getBorderTag(lsTag, c, newPhysTags[2][0], borderPhysTags[1]); elements[2][reg].push_back(tri); if(physTag) assignLsPhysical(GM, reg, 2, physicals, physTag, lsTag); @@ -1239,7 +1286,8 @@ static void elementCutMesh(MElement *e, std::vector<gLevelset *> &RPN, int c = elements[1].count(lsTag); // the lines are cut before the surfaces! int reg = getBorderTag(lsTag, c, newElemTags[1][0], borderElemTags[0]); - int physTag = (!gePhysicals.size()) ? 0 : getBorderTag(lsTag, c, newPhysTags[1][0], borderPhysTags[0]); + int physTag = (!gePhysicals.size()) ? 0 : + getBorderTag(lsTag, c, newPhysTags[1][0], borderPhysTags[0]); elements[1][reg].push_back(lin); if(physTag) assignLsPhysical(GM, reg, 1, physicals, physTag, lsTag); @@ -1371,6 +1419,7 @@ GModel *buildCutMesh(GModel *gm, gLevelset *ls, for(unsigned int i = 0; i < gmEntities.size(); i++) { for(unsigned int j = 0; j < gmEntities[i]->getNumMeshVertices(); j++) { MVertex *vi = gmEntities[i]->getMeshVertex(j); + if(vi->getIndex() < 0) continue; if(cutElem){ int k = 0; for(; k < primS; k++) @@ -1461,6 +1510,7 @@ GModel *buildCutMesh(GModel *gm, gLevelset *ls, } for(unsigned int j = 0; j < lsLineRegs.size(); j++){ int nLR = lsLineRegs[j]; + bool havePhys = physicals[1][nLR].size(); while(1){ std::vector<MElement*> conLines; conLines.push_back(elements[1][nLR][0]); @@ -1484,8 +1534,10 @@ GModel *buildCutMesh(GModel *gm, gLevelset *ls, } if(!elements[1][nLR].empty()){ int newReg = ++newElemTags[1][0]; - int newPhys = ++newPhysTags[1][0]; - assignLsPhysical(gm, newReg, 1, physicals, newPhys, lines[lines.size() - 1]->lsTag()); + int newPhys = (!havePhys) ? 0 : ++newPhysTags[1][0]; + if(newPhys) + assignLsPhysical(gm, newReg, 1, physicals, newPhys, + lines[lines.size() - 1]->lsTag()); for(int k = 0; k < conLines.size(); k++) elements[1][newReg].push_back(conLines[k]); } diff --git a/Geo/gmshLevelset.h b/Geo/gmshLevelset.h index 3a46d599b137d3ad9a76cc7135e158e147cba063..38ef8df4430d0c7e60318a31c85d976cc9ddcc0e 100644 --- a/Geo/gmshLevelset.h +++ b/Geo/gmshLevelset.h @@ -127,8 +127,11 @@ protected: double xc, yc, zc, r; public: gLevelsetSphere (const double &x, const double &y, const double &z, const double &R, int tag=1) : gLevelsetPrimitive(tag), xc(x), yc(y), zc(z), r(R) {} - virtual double operator () (const double x, const double y, const double z) const - {return (sqrt((xc - x) * (xc - x) + (yc - y) * (yc - y) + (zc - z) * (zc - z)) - abs(r)) * r / abs(r);} + virtual double operator () (const double x, const double y, const double z) const{ + if(r >= 0.) + return sqrt((xc - x) * (xc - x) + (yc - y) * (yc - y) + (zc - z) * (zc - z)) - r; + return (- r - sqrt((xc - x) * (xc - x) + (yc - y) * (yc - y) + (zc - z) * (zc - z))); + } int type() const {return SPHERE;} }; diff --git a/Mesh/meshGRegionMMG3D.cpp b/Mesh/meshGRegionMMG3D.cpp index 03b7acf633fa78c685067e4629915e076a3518cb..b664d1fb351d145ec5ba07683d043b96790a5fbb 100644 --- a/Mesh/meshGRegionMMG3D.cpp +++ b/Mesh/meshGRegionMMG3D.cpp @@ -277,8 +277,8 @@ void refineMeshMMG(GRegion *gr) gr->deleteVertexArrays(); for (int i=0;i<gr->tetrahedra.size();++i)delete gr->tetrahedra[i]; gr->tetrahedra.clear(); - // for (int i=0;i<gr->mesh_vertices.size();++i)delete gr->mesh_vertices[i]; - // gr->mesh_vertices.clear(); + for (int i=0;i<gr->mesh_vertices.size();++i)delete gr->mesh_vertices[i]; + gr->mesh_vertices.clear(); MMG2gmsh(gr, mmg, mmg2gmsh); freeMMG(mmg, sol);