From 0628eba005681e4e6e89406f5f085dffe83038c9 Mon Sep 17 00:00:00 2001 From: Jean-Francois Remacle <jean-francois.remacle@uclouvain.be> Date: Wed, 10 Oct 2007 08:49:34 +0000 Subject: [PATCH] *** empty log message *** --- Geo/MVertex.h | 7 +- Mesh/BackgroundMesh.cpp | 20 +- Mesh/BackgroundMesh.h | 3 +- Mesh/meshGEdge.cpp | 8 +- Mesh/meshGFace.cpp | 288 ++++++++++++++++------------ Mesh/meshGFaceDelaunayInsertion.cpp | 4 +- benchmarks/2d/Square-Attr2.geo | 2 +- 7 files changed, 198 insertions(+), 134 deletions(-) diff --git a/Geo/MVertex.h b/Geo/MVertex.h index 67311529f7..9406a296fb 100644 --- a/Geo/MVertex.h +++ b/Geo/MVertex.h @@ -117,15 +117,16 @@ class MVertex{ class MEdgeVertex : public MVertex{ protected: - double _u; + double _u, _lc; public : - MEdgeVertex(double x, double y, double z, GEntity *ge, double u) - : MVertex(x, y, z, ge), _u(u) + MEdgeVertex(double x, double y, double z, GEntity *ge, double u, double lc = -1.0) + : MVertex(x, y, z, ge), _u(u),_lc(lc) { } virtual ~MEdgeVertex(){} virtual bool getParameter(int i, double &par) const{ par = _u; return true; } virtual bool setParameter(int i, double par){ _u = par; return true; } + double getLc () const {return _lc;} }; class MFaceVertex : public MVertex{ diff --git a/Mesh/BackgroundMesh.cpp b/Mesh/BackgroundMesh.cpp index 826ccb2b16..321199353e 100644 --- a/Mesh/BackgroundMesh.cpp +++ b/Mesh/BackgroundMesh.cpp @@ -1,4 +1,4 @@ -// $Id: BackgroundMesh.cpp,v 1.25 2007-09-10 04:47:03 geuzaine Exp $ +// $Id: BackgroundMesh.cpp,v 1.26 2007-10-10 08:49:34 remacle Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -183,7 +183,7 @@ double BGM_MeshSize(GEntity *ge, double U, double V, double X, double Y, double double l4 = lc_field.empty() ? MAX_LC : lc_field(X, Y, Z); // use the field unconstrained by other characteristic lengths - if(l4 < MAX_LC && !CTX.mesh.constrained_bgmesh) + if(!lc_field.empty() && !CTX.mesh.constrained_bgmesh) return l4 * CTX.mesh.lc_factor; if(CTX.mesh.lc_from_curvature && ge->dim() < 3) @@ -195,5 +195,21 @@ double BGM_MeshSize(GEntity *ge, double U, double V, double X, double Y, double // printf("l1 = %12.5E l2 = %12.5E l4 = %12.5E\n",l1,l2,l4); double lc = std::min(std::min(std::min(l1, l2), l3), l4); + return lc * CTX.mesh.lc_factor; } + +// we extend the 1d mesh in surfaces if no background mesh exists +// in this case, it is the only way to have something smooth +// we do it also if CTX.mesh.constrained_bgmesh is true; +bool Extend1dMeshIn2dSurfaces () +{ + if ( lc_field.empty()) return true; + if ( CTX.mesh.constrained_bgmesh == true) return true; + return false; +} + +bool Extend2dMeshIn3dVolumes () +{ + return Extend1dMeshIn2dSurfaces (); +} diff --git a/Mesh/BackgroundMesh.h b/Mesh/BackgroundMesh.h index 2d761aceb8..ec7958c8cb 100644 --- a/Mesh/BackgroundMesh.h +++ b/Mesh/BackgroundMesh.h @@ -26,5 +26,6 @@ double BGM_MeshSize(GEntity *ge, double U, double V, double X, double Y, double bool BGMExists(); void BGMAddField(Field *field); void BGMReset(); - +bool Extend1dMeshIn2dSurfaces (); +bool Extend2dMeshIn3dVolumes (); #endif diff --git a/Mesh/meshGEdge.cpp b/Mesh/meshGEdge.cpp index b7887242c0..cccfc7e1f4 100644 --- a/Mesh/meshGEdge.cpp +++ b/Mesh/meshGEdge.cpp @@ -1,4 +1,4 @@ -// $Id: meshGEdge.cpp,v 1.43 2007-09-24 08:14:29 geuzaine Exp $ +// $Id: meshGEdge.cpp,v 1.44 2007-10-10 08:49:34 remacle Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -365,10 +365,12 @@ void meshGEdge::operator() (GEdge *ge) const double d = (double)NUMP * b; if((fabs(P2.p) >= fabs(d)) && (fabs(P1.p) < fabs(d))) { double dt = P2.t - P1.t; + double dlc = P2.lc - P1.lc; double dp = P2.p - P1.p; - double t = P1.t + dt / dp * (d - P1.p); + double t = P1.t + dt / dp * (d - P1.p); + double lc = P1.lc + dlc / dp * (d - P1.p); GPoint V = ge->point(t); - ge->mesh_vertices[NUMP - 1] = new MEdgeVertex(V.x(), V.y(), V.z(), ge, t); + ge->mesh_vertices[NUMP - 1] = new MEdgeVertex(V.x(), V.y(), V.z(), ge, t, lc); NUMP++; } else { diff --git a/Mesh/meshGFace.cpp b/Mesh/meshGFace.cpp index 7dde59d0fb..1b0f5a6c16 100644 --- a/Mesh/meshGFace.cpp +++ b/Mesh/meshGFace.cpp @@ -1,4 +1,4 @@ -// $Id: meshGFace.cpp,v 1.89 2007-09-24 08:14:29 geuzaine Exp $ +// $Id: meshGFace.cpp,v 1.90 2007-10-10 08:49:34 remacle Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -106,7 +106,7 @@ double F_LC_ANALY(double xx, double yy, double zz) double NewGetLc(BDS_Point *p) { - return std::min(p->lc(),p->lcBGM()); + return Extend1dMeshIn2dSurfaces () ? std::min(p->lc(),p->lcBGM()) : p->lcBGM(); } inline double computeEdgeLinearLength(BDS_Point *p1, BDS_Point *p2) @@ -297,6 +297,102 @@ void OptimizeMesh(GFace *gf, BDS_Mesh &m, const int NIT) } } +void swapEdgePass ( GFace *gf, BDS_Mesh &m, int &nb_swap ) +{ + int NN1 = m.edges.size(); + int NN2 = 0; + std::list<BDS_Edge*>::iterator it = m.edges.begin(); + while (1) + { + if (NN2++ >= NN1)break; + // result = -1 => forbid swap because too badly shaped elements + // result = 0 => whatever + // result = 1 => oblige to swap because the quality is greatly improved + if (!(*it)->deleted) + { + int result = edgeSwapTestQuality(*it,5); + if (result >= 0) + if(edgeSwapTestDelaunay(*it,gf) || result > 0) + if (m.swap_edge ( *it , BDS_SwapEdgeTestParametric())) + nb_swap++; + ++it; + } + } +} + +void splitEdgePass ( GFace *gf, BDS_Mesh &m, double MAXE_, int &nb_split) +{ + int NN1 = m.edges.size(); + int NN2 = 0; + std::list<BDS_Edge*>::iterator it = m.edges.begin(); + while (1) + { + if (NN2++ >= NN1)break; + if (!(*it)->deleted) + { + double lone = NewGetLc ( *it,gf); + if ((*it)->numfaces() == 2 && (lone > MAXE_)) + { + const double coord = 0.5; + BDS_Point *mid ; + mid = m.add_point(++m.MAXPOINTNUMBER, + coord * (*it)->p1->u + (1 - coord) * (*it)->p2->u, + coord * (*it)->p1->v + (1 - coord) * (*it)->p2->v,gf); + double l1; + // if (BGMExists()) + mid->lcBGM() = BGM_MeshSize(gf, + (coord * (*it)->p1->u + (1 - coord) * (*it)->p2->u)*m.scalingU, + (coord * (*it)->p1->v + (1 - coord) * (*it)->p2->v)*m.scalingV, + mid->X,mid->Y,mid->Z); + //mid->lc() = 2./ ( 1./(*it)->p1->lc() + 1./(*it)->p2->lc() ); + mid->lc() = 0.5 * ( (*it)->p1->lc() + (*it)->p2->lc() ); + m.split_edge ( *it, mid ); + nb_split++; + } + } + ++it; + } +} + + +void collapseEdgePass ( GFace *gf, BDS_Mesh &m, double MINE_, int MAXNP, int &nb_collaps) +{ + int NN1 = m.edges.size(); + int NN2 = 0; + std::list<BDS_Edge*>::iterator it = m.edges.begin(); + while (1) + { + if (NN2++ >= NN1)break; + double lone = NewGetLc ( *it,gf); + // if (lone < 1.e-10 && computeParametricEdgeLength((*it)->p1,(*it)->p2) > 1.e-5) lone = 2; + + if (!(*it)->deleted && (*it)->numfaces() == 2 && lone < MINE_ ) + { + bool res = false; + if ( (*it)->p1->iD > MAXNP ) + res =m.collapse_edge_parametric ( *it, (*it)->p1); + else if ( (*it)->p2->iD > MAXNP ) + res =m.collapse_edge_parametric ( *it, (*it)->p2); + if (res) + nb_collaps ++; + } + ++it; + } +} + + +void smoothVertexPass ( GFace *gf, BDS_Mesh &m, int &nb_smooth) +{ + std::set<BDS_Point*,PointLessThan>::iterator itp = m.points.begin(); + while (itp != m.points.end()) + { + + if(m.smooth_point_centroid(*itp,gf)) + nb_smooth ++; + ++itp; + } +} + void RefineMesh ( GFace *gf, BDS_Mesh &m , const int NIT) { int IT =0; @@ -305,9 +401,9 @@ void RefineMesh ( GFace *gf, BDS_Mesh &m , const int NIT) int MAXNP = m.MAXPOINTNUMBER; - // computecharacteristic lengths using mesh edge spacing + // computecharacteristic lengths using 1D mesh edge spacing // those lengths will propagate in the 2D mesh. - if (NIT > 0) + if (0 && NIT > 0) { std::set<BDS_Point*,PointLessThan>::iterator itp = m.points.begin(); while (itp != m.points.end()) @@ -320,8 +416,7 @@ void RefineMesh ( GFace *gf, BDS_Mesh &m , const int NIT) if (l<L && (*it)->g && (*it)->g->classif_degree == 1)L=l; ++it; } - if(!CTX.mesh.constrained_bgmesh) - (*itp)->lc() = L; + (*itp)->lc() = L; (*itp)->lcBGM() = L; ++itp; } @@ -329,6 +424,8 @@ void RefineMesh ( GFace *gf, BDS_Mesh &m , const int NIT) double OLDminL=1.E22,OLDmaxL=0; + double t_spl=0, t_sw=0,t_col=0,t_sm=0; + const double MINE_ = 0.7, MAXE_=1.4; while (1) { @@ -342,6 +439,7 @@ void RefineMesh ( GFace *gf, BDS_Mesh &m , const int NIT) // split long edges double minL=1.E22,maxL=0; + int NN1 = m.edges.size(); int NN2 = 0; std::list<BDS_Edge*>::iterator it = m.edges.begin(); @@ -364,116 +462,45 @@ void RefineMesh ( GFace *gf, BDS_Mesh &m , const int NIT) if ((minL > MINE_ && maxL < MAXE_) || IT > (abs(NIT)))break; - NN1 = m.edges.size(); - NN2 = 0; - it = m.edges.begin(); - while (1) - { - if (NN2++ >= NN1)break; - if (!(*it)->deleted) - { - double lone = NewGetLc ( *it,gf); - if ((*it)->numfaces() == 2 && (lone > MAXE_)) - { - const double coord = 0.5; - BDS_Point *mid ; - mid = m.add_point(++m.MAXPOINTNUMBER, - coord * (*it)->p1->u + (1 - coord) * (*it)->p2->u, - coord * (*it)->p1->v + (1 - coord) * (*it)->p2->v,gf); - // if (BGMExists()) - mid->lcBGM() = BGM_MeshSize(gf, - (coord * (*it)->p1->u + (1 - coord) * (*it)->p2->u)*m.scalingU, - (coord * (*it)->p1->v + (1 - coord) * (*it)->p2->v)*m.scalingV, - mid->X,mid->Y,mid->Z); - //mid->lc() = 2./ ( 1./(*it)->p1->lc() + 1./(*it)->p2->lc() ); - mid->lc() = 0.5 * ( (*it)->p1->lc() + (*it)->p2->lc() ); - m.split_edge ( *it, mid ); - nb_split++; - } - } - ++it; - } - - // swap edges that provide a better configuration - - NN2 = 0; - it = m.edges.begin(); - while (1) - { - if (NN2++ >= NN1)break; - // result = -1 => forbid swap because too badly shaped elements - // result = 0 => whatever - // result = 1 => oblige to swap because the quality is greatly improved - if (!(*it)->deleted) - { - int result = edgeSwapTestQuality(*it,5); - if (result >= 0) - if(edgeSwapTestDelaunay(*it,gf) || result > 0) - if (m.swap_edge ( *it , BDS_SwapEdgeTestParametric())) - nb_swap++; - ++it; - } - } - - // collapse short edges - NN1 = m.edges.size(); - NN2 = 0; - it = m.edges.begin(); - while (1) - { - if (NN2++ >= NN1)break; - double lone = NewGetLc ( *it,gf); - // if (lone < 1.e-10 && computeParametricEdgeLength((*it)->p1,(*it)->p2) > 1.e-5) lone = 2; + double maxE = MAXE_;//std::max(MAXE_,maxL / 5); + double minE = MINE_;//std::min(MINE_,minL * 1.2); + clock_t t1 = clock(); + splitEdgePass ( gf, m, maxE, nb_split); + clock_t t2 = clock(); + swapEdgePass ( gf, m, nb_swap); + clock_t t3 = clock(); + collapseEdgePass ( gf, m, minE , MAXNP, nb_collaps); + clock_t t4 = clock(); + swapEdgePass ( gf, m, nb_swap); + clock_t t5 = clock(); + smoothVertexPass ( gf, m, nb_smooth); + clock_t t6 = clock(); + // clean up the mesh - if (!(*it)->deleted && (*it)->numfaces() == 2 && lone < MINE_ ) - { - bool res = false; - if ( (*it)->p1->iD > MAXNP ) - res =m.collapse_edge_parametric ( *it, (*it)->p1); - else if ( (*it)->p2->iD > MAXNP ) - res =m.collapse_edge_parametric ( *it, (*it)->p2); - if (res) - nb_collaps ++; - } - ++it; - } - // swap edges that provide a better configuration - NN1 = m.edges.size(); - NN2 = 0; - it = m.edges.begin(); - while (1) - { - if (NN2++ >= NN1)break; - if (!(*it)->deleted) - { - int result = edgeSwapTestQuality(*it,5); - if (result >= 0) - if(edgeSwapTestDelaunay(*it,gf) || result > 0) - if (m.swap_edge ( *it , BDS_SwapEdgeTestParametric())) - nb_swap++; - ++it; - } - } - // smooth resulting mesh - { - std::set<BDS_Point*,PointLessThan>::iterator itp = m.points.begin(); - while (itp != m.points.end()) - { - - if(m.smooth_point_centroid(*itp,gf)) - nb_smooth ++; - ++itp; - } - } + t_spl += (double)(t2-t1)/CLOCKS_PER_SEC; + t_sw += (double)(t3-t2)/CLOCKS_PER_SEC; + t_sw += (double)(t5-t4)/CLOCKS_PER_SEC; + t_col += (double)(t4-t3)/CLOCKS_PER_SEC; + t_sm += (double)(t6-t5)/CLOCKS_PER_SEC; - // clean up the mesh m.cleanup(); IT++; - Msg(DEBUG1," iter %3d minL %8.3f maxL %8.3f : %6d splits, %6d swaps, %6d collapses, %6d moves",IT,minL,maxL,nb_split,nb_swap,nb_collaps,nb_smooth); + Msg(DEBUG1," iter %3d minL %8.3f/%8.3f maxL %8.3f/%8.3f : %6d splits, %6d swaps, %6d collapses, %6d moves",IT,minL,minE,maxL,maxE,nb_split,nb_swap,nb_collaps,nb_smooth); if (nb_split==0 && nb_collaps == 0)break; } + double t_total = t_spl + t_sw + t_col + t_sm; + Msg(DEBUG1," ---------------------------------------"); + Msg(DEBUG1," CPU Report "); + Msg(DEBUG1," ---------------------------------------"); + Msg(DEBUG1," CPU SWAP %12.5E sec (%3.0f %%)",t_sw,100 * t_sw/t_total); + Msg(DEBUG1," CPU SPLIT %12.5E sec (%3.0f %%) ",t_spl,100 * t_spl/t_total); + Msg(DEBUG1," CPU COLLAPS %12.5E sec (%3.0f %%) ",t_col,100 * t_col/t_total); + Msg(DEBUG1," CPU SMOOTH %12.5E sec (%3.0f %%) ",t_sm,100 * t_sm/t_total); + Msg(DEBUG1," ---------------------------------------"); + Msg(DEBUG1," CPU TOTAL %12.5E sec ",t_total); + Msg(DEBUG1," ---------------------------------------"); } @@ -760,7 +787,21 @@ bool gmsh2DMeshGenerator ( GFace *gf , bool debug = true) V = V_[num]; } - m->add_point ( num, U,V, gf); + BDS_Point *pp = m->add_point ( num, U,V, gf); + + GEntity *ge = here->onWhat(); + if(ge->dim() == 1) + { + double t; + here->getParameter(0,t); + pp->lcBGM() = BGM_MeshSize(ge,t,-12,here->x(),here->y(),here->z()); + } + else + { + MEdgeVertex *eve = (MEdgeVertex*) here; + pp->lcBGM() = eve->getLc(); + } + pp->lc() = pp->lcBGM(); } Msg(DEBUG1,"Meshing of the convex hull (%d points) done",all_vertices.size()); @@ -1189,19 +1230,22 @@ bool buildConsecutiveListOfVertices ( GFace *gf, double U,V; SPoint2 param = coords [i]; U = param.x() / m->scalingU ; - V = param.y() / m->scalingV; - BDS_Point *pp; - pp = m->add_point ( count, U,V,gf ); -// if(ge->dim() == 1) -// { -// double t; -// here->getParameter(0,t); -// pp->lc() = BGM_MeshSize(ge,t,-12,here->x(),here->y(),here->z()); -// } -// else -// { -// pp->lc() = BGM_MeshSize(ge,param.x(),param.y(),here->x(),here->y(),here->z()); -// } + V = param.y() / m->scalingV; + BDS_Point *pp = m->add_point ( count, U,V,gf ); + if(ge->dim() == 1) + { + double t; + here->getParameter(0,t); + pp->lcBGM() = BGM_MeshSize(ge,t,-12,here->x(),here->y(),here->z()); + pp->lc() = pp->lcBGM(); + } + else + { + MEdgeVertex *eve = (MEdgeVertex*) here; + // pp->lc() = BGM_MeshSize(ge,param.x(),param.y(),here->x(),here->y(),here->z()); + pp->lc() = eve->getLc(); + pp->lcBGM() = eve->getLc(); + } m->add_geom (ge->tag(), ge->dim()); BDS_GeomEntity *g = m->get_geom(ge->tag(),ge->dim()); diff --git a/Mesh/meshGFaceDelaunayInsertion.cpp b/Mesh/meshGFaceDelaunayInsertion.cpp index 3d99547357..99b1cadd6c 100644 --- a/Mesh/meshGFaceDelaunayInsertion.cpp +++ b/Mesh/meshGFaceDelaunayInsertion.cpp @@ -1,4 +1,4 @@ -// $Id: meshGFaceDelaunayInsertion.cpp,v 1.5 2007-09-10 13:37:21 remacle Exp $ +// $Id: meshGFaceDelaunayInsertion.cpp,v 1.6 2007-10-10 08:49:34 remacle Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -319,7 +319,7 @@ bool insertVertex (MVertex *v , vSizesBGM [t->getVertex(1)->getNum()]+ vSizesBGM [t->getVertex(2)->getNum()]); - MTri3 *t4 = new MTri3 ( t , std::min(lc,lcBGM)); + MTri3 *t4 = new MTri3 ( t , Extend1dMeshIn2dSurfaces() ? std::min(lc,lcBGM) : lcBGM ); // fprintf(ff,"ST(%g,%g,%g,%g,%g,%g,%g,%g,%g) {0,0,0};\n", // Us [t->getVertex(0)->getNum()], // Vs [t->getVertex(0)->getNum()], diff --git a/benchmarks/2d/Square-Attr2.geo b/benchmarks/2d/Square-Attr2.geo index a69af148a7..9ca3898285 100644 --- a/benchmarks/2d/Square-Attr2.geo +++ b/benchmarks/2d/Square-Attr2.geo @@ -36,4 +36,4 @@ Line(15) = {19,20}; Attractor Line{7,8,9,10,11,12,13,14,15} = {.04,lc/30,lc,1000,7} ; // Argh: //Attractor Line{7,8,9,10,11,12,13,14,15} = {.2,0.002,10} ; -Mesh.Algorithm = 2; +//Mesh.Algorithm = 2; -- GitLab