From c5ccbdb583302ab28420de57fa5e917191b8bd09 Mon Sep 17 00:00:00 2001 From: Emilie Marchandise <emilie.marchandise@uclouvain.be> Date: Wed, 21 Dec 2011 11:29:19 +0000 Subject: [PATCH] fixed bug meshBamg with compound edges --- Geo/Curvature.cpp | 6 +- Geo/GFaceCompound.cpp | 6 +- Mesh/meshGFace.cpp | 5 - Mesh/meshGFace.h | 5 + Mesh/meshGFaceBamg.cpp | 120 ++++++++++++++---- benchmarks/2d/recombine.geo | 4 +- benchmarks/stl/BifurcationRemeshCurvature.geo | 23 ++++ contrib/bamg/bamg-gmsh.cpp | 3 +- 8 files changed, 130 insertions(+), 42 deletions(-) create mode 100644 benchmarks/stl/BifurcationRemeshCurvature.geo diff --git a/Geo/Curvature.cpp b/Geo/Curvature.cpp index 9a41dee7f4..6266b5aed9 100644 --- a/Geo/Curvature.cpp +++ b/Geo/Curvature.cpp @@ -963,9 +963,9 @@ void Curvature::buildEdgeList() NbEdges += _VertexToEdgeList[i].size(); } - std::cout << "Euler formula:" << std::endl; - std::cout << "Edges + 2 = " << NbEdges + 2 << std::endl; - std::cout << "Elements + Nodes = " << _VertexToInt.size() + _ElementToInt.size() << std::endl; + //std::cout << "Euler formula:" << std::endl; + //std::cout << "Edges + 2 = " << NbEdges + 2 << std::endl; + //std::cout << "Elements + Nodes = " << _VertexToInt.size() + _ElementToInt.size() << std::endl; } diff --git a/Geo/GFaceCompound.cpp b/Geo/GFaceCompound.cpp index 4d33e5f1e2..36bb476cd6 100644 --- a/Geo/GFaceCompound.cpp +++ b/Geo/GFaceCompound.cpp @@ -607,8 +607,8 @@ bool GFaceCompound::parametrize() const if(oct) return paramOK; if(trivial()) return paramOK; - // if (_mapping != RBF) - // coordinates.clear(); + if (_mapping != RBF) + coordinates.clear(); computeNormals(); @@ -1681,7 +1681,7 @@ void GFaceCompound::getTriangle(double u, double v, // } // } - *lt = (GFaceCompoundTriangle*)Octree_Search(uv, oct); + *lt = (GFaceCompoundTriangle*)Octree_Search(uv, oct); // if(!(*lt)) { // for(int i=0;i<nbT;i++){ diff --git a/Mesh/meshGFace.cpp b/Mesh/meshGFace.cpp index ba6203e8c3..a33434abe0 100644 --- a/Mesh/meshGFace.cpp +++ b/Mesh/meshGFace.cpp @@ -433,11 +433,6 @@ void BDS2GMSH(BDS_Mesh *m, GFace *gf, std::map<BDS_Point*, MVertex*> &recoverMap } } -bool meshGenerator(GFace *gf, int RECUR_ITER, - bool repairSelfIntersecting1dMesh, - bool onlyInitialMesh, - bool debug = true, - std::list<GEdge*> *replacement_edges = 0); static void addOrRemove(MVertex *v1, MVertex *v2, std::set<MEdge,Less_Edge> & bedges) { diff --git a/Mesh/meshGFace.h b/Mesh/meshGFace.h index 62fa4a61d0..2cb1d2338a 100644 --- a/Mesh/meshGFace.h +++ b/Mesh/meshGFace.h @@ -54,5 +54,10 @@ int MeshExtrudedSurface(GFace *gf, std::set<std::pair<MVertex*, MVertex*> > *constrainedEdges=0); void partitionAndRemesh(GFaceCompound *gf); bool checkMeshCompound(GFaceCompound *gf, std::list<GEdge*> &edges); +bool meshGenerator(GFace *gf, int RECUR_ITER, + bool repairSelfIntersecting1dMesh, + bool onlyInitialMesh, + bool debug = true, + std::list<GEdge*> *replacement_edges = 0); #endif diff --git a/Mesh/meshGFaceBamg.cpp b/Mesh/meshGFaceBamg.cpp index a4463d3807..caff64c033 100644 --- a/Mesh/meshGFaceBamg.cpp +++ b/Mesh/meshGFaceBamg.cpp @@ -18,6 +18,10 @@ #include <map> #include "BackgroundMesh.h" #include "meshGFaceDelaunayInsertion.h" +#include "Options.h" +#include "meshGFace.h" +#include "GFaceCompound.h" +#include "MElementOctree.h" #if defined(HAVE_BAMG) @@ -69,11 +73,11 @@ static void computeMeshMetricsForBamg(GFace *gf, int numV, void meshGFaceBamg(GFace *gf){ //Replace edges by their compounds - std::list<GEdge*> edges = gf->edges(); - std::set<GEdge*> mySet; - std::list<GEdge*>::iterator it = edges.begin(); - bool hasCompounds = false; - while(it != edges.end()){ + std::list<GEdge*> edges = gf->edges(); + std::set<GEdge*> mySet; + std::list<GEdge*>::iterator it = edges.begin(); + bool hasCompounds = false; + while(it != edges.end()){ if((*it)->getCompound()){ hasCompounds = true; GEdge *gec = (GEdge*)(*it)->getCompound(); @@ -83,22 +87,16 @@ void meshGFaceBamg(GFace *gf){ mySet.insert(*it); } ++it; - } - edges.clear(); - edges.insert(edges.begin(), mySet.begin(), mySet.end()); - std::set<MVertex*> bcVertex; - for (std::list<GEdge*>::iterator it = edges.begin(); it != edges.end(); it++){ + } + edges.clear(); + edges.insert(edges.begin(), mySet.begin(), mySet.end()); + std::set<MVertex*> bcVertex; + for (std::list<GEdge*>::iterator it = edges.begin(); it != edges.end(); it++){ for (unsigned int i = 0; i < (*it)->lines.size(); i++){ bcVertex.insert((*it)->lines[i]->getVertex(0)); bcVertex.insert((*it)->lines[i]->getVertex(1)); } } - //if has compound edges use a frontal mesher to remesh compound surface - if (hasCompounds){ - printf("tris compound = %d \n", gf->triangles.size()); - bowyerWatsonFrontal(gf); - printf("after tris compound = %d \n", gf->triangles.size()); - } //fill mesh data fo bamg (bamgVertices, bamgTriangles, bamgBoundary) std::set<MVertex*> all; @@ -108,13 +106,11 @@ void meshGFaceBamg(GFace *gf){ all.insert(gf->triangles[i]->getVertex(j)); } - //FIXME EMI: how should we define bamgVertices when we have remeshed compound edges not with lines not belonging to triangles of the compound face - int numVertices = all.size()+bcVertex.size(); - Vertex2 *bamgVertices = new Vertex2[numVertices]; + Vertex2 *bamgVertices = new Vertex2[all.size()]; int index = 0; - // for(std::set<MVertex*>::iterator it = all.begin(); it!=all.end(); ++it){ - // if ((*it)->onWhat()->dim() <= 1){ - for(std::set<MVertex*>::iterator it = bcVertex.begin(); it!=bcVertex.end(); ++it){ + for(std::set<MVertex*>::iterator it = all.begin(); it!=all.end(); ++it){ + if ((*it)->onWhat()->dim() <= 1){ + //for(std::set<MVertex*>::iterator it = bcVertex.begin(); it!=bcVertex.end(); ++it){ SPoint2 p; bool success = reparamMeshVertexOnFace(*it, gf, p); bamgVertices[index][0] = p.x(); @@ -122,7 +118,7 @@ void meshGFaceBamg(GFace *gf){ bamgVertices[index].lab = index; recover[index] = *it; (*it)->setIndex(index++); - //} + } } int nbFixedVertices = index; for(std::set<MVertex*>::iterator it = all.begin(); it!=all.end(); ++it){ @@ -136,6 +132,8 @@ void meshGFaceBamg(GFace *gf){ (*it)->setIndex(index++); } } + + std::vector<MElement*> myParamElems; Triangle2 *bamgTriangles = new Triangle2[gf->triangles.size()]; for (unsigned int i = 0; i < gf->triangles.size(); i++){ int nodes [3] = {gf->triangles[i]->getVertex(0)->getIndex(), @@ -147,6 +145,13 @@ void meshGFaceBamg(GFace *gf){ double v1(bamgVertices[nodes[0]][1]); double v2(bamgVertices[nodes[1]][1]); double v3(bamgVertices[nodes[2]][1]); + if (hasCompounds){ + MVertex *vv1 = new MVertex(u1,v1,0.0); + MVertex *vv2 = new MVertex(u2,v2,0.0); + MVertex *vv3 = new MVertex(u3,v3,0.0); + MTriangle *tri = new MTriangle(vv1,vv2,vv3, i); + myParamElems.push_back(tri); + } double sign = (u2-u1)*(v3-v1) - (u3-u1)*(v2-v1); if (sign < 0){ int temp = nodes[0]; @@ -155,7 +160,7 @@ void meshGFaceBamg(GFace *gf){ } bamgTriangles[i].init(bamgVertices, nodes, gf->tag()); } - + int numEdges = 0; for (std::list<GEdge*>::iterator it = edges.begin(); it != edges.end(); ++it){ numEdges += (*it)->lines.size(); @@ -167,7 +172,7 @@ void meshGFaceBamg(GFace *gf){ for (unsigned int i = 0; i < (*it)->lines.size(); ++i){ int nodes [2] = {(*it)->lines[i]->getVertex(0)->getIndex(), (*it)->lines[i]->getVertex(1)->getIndex()}; - bamgBoundary[count].init (bamgVertices, nodes, (*it)->tag()); + bamgBoundary[count].init(bamgVertices, nodes, (*it)->tag()); bamgBoundary[count++].lab = count; } } @@ -175,8 +180,36 @@ void meshGFaceBamg(GFace *gf){ Mesh2 *bamgMesh = new Mesh2 (all.size(), gf->triangles.size(), numEdges, bamgVertices, bamgTriangles, bamgBoundary); + MElementOctree *_octree ; + if (hasCompounds){ + _octree = new MElementOctree(myParamElems); + // //EMI PRINT TRIS + // FILE * fi = fopen("TRIS.pos","w"); + // fprintf(fi, "View \"\"{\n"); + // for( int i =0; i< gf->triangles.size(); i++){ + // int nodes [3] = {gf->triangles[i]->getVertex(0)->getIndex(), + // gf->triangles[i]->getVertex(1)->getIndex(), + // gf->triangles[i]->getVertex(2)->getIndex()}; + // double u1(bamgVertices[nodes[0]][0]); + // double u2(bamgVertices[nodes[1]][0]); + // double u3(bamgVertices[nodes[2]][0]); + // double v1(bamgVertices[nodes[0]][1]); + // double v2(bamgVertices[nodes[1]][1]); + // double v3(bamgVertices[nodes[2]][1]); + // fprintf(fi, "ST(%22.15E,%22.15E,%22.15E,%22.15E,%22.15E,%22.15E,%22.15E," + // "%22.15E,%22.15E){%d,%d,%d};\n", + // u1, v1, 0.0, + // u2, v2, 0.0, + // u3, v3, 0.0, + // i, i, i); + // } + // fprintf(fi,"};\n"); + // fclose(fi); + // //END EMI PRINT TRIS + } + Mesh2 *refinedBamgMesh = 0; - int iterMax = 11; + int iterMax = 1; for (int k= 0; k < iterMax; k++){ int nbVert = bamgMesh->nv; @@ -217,12 +250,42 @@ void meshGFaceBamg(GFace *gf){ Vertex2 &v = refinedBamgMesh->vertices[i]; if (i >= nbFixedVertices){ GPoint gp = gf->point(SPoint2(v[0], v[1])); + // if (gp.x() > 2.){ printf("wrong vertex index=%d %g %g %g (%g %g)\n", i, gp.x(), gp.y(), gp.z(), v[0], v[1]); + // } + //If point not found because compound edges have been remeshed and boundary triangles have changed + //then we call our new octree + if ( !gp.succeeded() && hasCompounds){ + SPoint3 uvw(v[0],v[1], 0.0), UV; + double initialTol = MElement::getTolerance(); + MElement::setTolerance(1.e-2); + MElement *e = _octree->find(v[0],v[1], 0.0, -1); + MElement::setTolerance(initialTol); + if (e){ + e->xyz2uvw(uvw,UV); + double *valX = new double[e->getNumVertices()]; + double *valY = new double[e->getNumVertices()]; + double *valZ = new double[e->getNumVertices()]; + for (int i=0;i<e->getNumVertices();i++){ + int numTri = e->getNum(); + valX[i] = gf->triangles[numTri]->getVertex(0)->x(); + valY[i] = gf->triangles[numTri]->getVertex(0)->y(); + valZ[i] = gf->triangles[numTri]->getVertex(0)->z(); + } + gp.x() = e->interpolate(valX,UV[0],UV[1],UV[2]); + gp.y() = e->interpolate(valY,UV[0],UV[1],UV[2]); + gp.z() = e->interpolate(valZ,UV[0],UV[1],UV[2]); + delete [] valX; + delete [] valY; + delete [] valZ; + } + } MFaceVertex *x = new MFaceVertex(gp.x(), gp.y(), gp.z(), gf, v[0], v[1]); yetAnother[i] = x; gf->mesh_vertices.push_back(x); } else { - yetAnother[i] = recover[i]; + MVertex *v = recover[i]; + yetAnother[i] =v; } } @@ -241,6 +304,9 @@ void meshGFaceBamg(GFace *gf){ } if (refinedBamgMesh) delete refinedBamgMesh; + if ( _octree) delete _octree; + for(std::vector<MElement*>::iterator it = myParamElems.begin(); it != myParamElems.end(); it++) + delete *it; } #else diff --git a/benchmarks/2d/recombine.geo b/benchmarks/2d/recombine.geo index b0afab1e8b..7594af00aa 100644 --- a/benchmarks/2d/recombine.geo +++ b/benchmarks/2d/recombine.geo @@ -1,8 +1,8 @@ lc = 0.03; Point(1) = {0, 0, 0, lc/5}; Point(2) = {.1, 0, 0, lc/5}; -Point(3) = {.1, .3, 0, lc}; -Point(4) = {0, .3, 0, lc}; +Point(3) = {.1, .1, 0, lc}; +Point(4) = {0, .1, 0, lc}; Line(1) = {1,2} ; Line(2) = {3,2} ; Line(3) = {3,4} ; diff --git a/benchmarks/stl/BifurcationRemeshCurvature.geo b/benchmarks/stl/BifurcationRemeshCurvature.geo new file mode 100644 index 0000000000..b70188a8a3 --- /dev/null +++ b/benchmarks/stl/BifurcationRemeshCurvature.geo @@ -0,0 +1,23 @@ +Mesh.Algorithm=7; //1=MeshAdapt, 5=Delaunay, 6=Frontal, 7=BAMG +Mesh.RemeshParametrization=1; //0) harmonic (1) conformal +Mesh.RemeshAlgorithm=1; //(0) nosplit (1) automatic + +Mesh.CharacteristicLengthFactor=0.35; +Mesh.CharacteristicLengthFromCurvature=1; //-clcurv +Mesh.CharacteristicLengthMin = 0.02; //-clmin 0.05 +Mesh.CharacteristicLengthMax = 4.00; //-clmax 4.0 +Mesh.LcIntegrationPrecision=1.e-5; //-epslc1d +Mesh.MinimumCirclePoints=30; //default=7 +Mesh.CharacteristicLengthFromPoints = 0; +Mesh.CharacteristicLengthExtendFromBoundary=0; + +Merge "bifurcation.stl"; + +CreateTopology; + +Compound Surface(20) = {1}; + + +Physical Surface("Wall") = {20}; + + diff --git a/contrib/bamg/bamg-gmsh.cpp b/contrib/bamg/bamg-gmsh.cpp index 999226ceed..4fedb9ab8c 100644 --- a/contrib/bamg/bamg-gmsh.cpp +++ b/contrib/bamg/bamg-gmsh.cpp @@ -419,8 +419,7 @@ Mesh2 *Bamg(Mesh2 *Thh, double * args,double *mm11,double *mm12,double *mm22, bo Triangles &Th(*oTh); // printf("COUCOUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU\n"); - // Th.Write("toto.mesh",bamg::Triangles::AutoMesh); - + //Th.Write("toto.mesh",bamg::Triangles::AutoMesh); bool mtx=true; KN_<double> m11(mm11,Thh->nv); -- GitLab