diff --git a/Mesh/BackgroundMesh.cpp b/Mesh/BackgroundMesh.cpp index a1f6f2fa652ae534dd0c23a05827208fb0fc5407..a7a0f011e8b3632c17d93a61342237823cd8ff02 100644 --- a/Mesh/BackgroundMesh.cpp +++ b/Mesh/BackgroundMesh.cpp @@ -43,10 +43,10 @@ SMetric3 buildMetricTangentToCurve(SVector3 &t, double l_t, double l_n) { if (l_t == 0.0) return SMetric3(1.e-22); SVector3 a; - if (t(0) <= t(1) && t(0) <= t(2)){ + if (fabs(t(0)) <= fabs(t(1)) && fabs(t(0)) <= fabs(t(2))){ a = SVector3(1,0,0); } - else if (t(1) <= t(0) && t(1) <= t(2)){ + else if (fabs(t(1)) <= fabs(t(0)) && fabs(t(1)) <= fabs(t(2))){ a = SVector3(0,1,0); } else{ @@ -58,6 +58,7 @@ SMetric3 buildMetricTangentToCurve(SVector3 &t, double l_t, double l_n) c.normalize(); t.normalize(); SMetric3 Metric (1./(l_t*l_t),1./(l_n*l_n),1./(l_n*l_n),t,b,c); + // printf("bmttc %g %g %g %g %g\n",l_t,l_n,Metric(0,0),Metric(0,1),Metric(1,1)); return Metric; } diff --git a/Mesh/Field.cpp b/Mesh/Field.cpp index efb78c8a9eb975a91309f8ba3f4336b8834dfd68..acd71be9d3998923e3aea2c2ae42c2814f457e78 100644 --- a/Mesh/Field.cpp +++ b/Mesh/Field.cpp @@ -1931,7 +1931,7 @@ void BoundaryLayerField::operator() (AttractorField *cc, double dist, const double b = lc_t; const double h = lc_n; double oneOverD2 = .5/(b * b) * - (1. + sqrt (1. + (4. * crv * crv * b * b * b * b / (h * h * beta * beta)))); + (1. + sqrt (1. + (4. * crv * crv * b * b * b * b / (h * h * beta * beta)))); metr = buildMetricTangentToCurve(t1, sqrt(1. / oneOverD2), lc_n); return; } @@ -2013,7 +2013,7 @@ void BoundaryLayerField::operator() (double x, double y, double z, } if (iIntersect) for (unsigned int i = 0; i < hop.size(); i++) - v = intersection_conserve_mostaniso(v, hop[i]); + v = intersection_conserveM1(v, hop[i]); metr = v; } #endif diff --git a/Mesh/meshGEdge.cpp b/Mesh/meshGEdge.cpp index cc99a7c6b2c477e87c62c7ac17eb2ce77a1dd542..7ff2757035e1f5f0db0ad6663b21f41fb0e23089 100644 --- a/Mesh/meshGEdge.cpp +++ b/Mesh/meshGEdge.cpp @@ -369,7 +369,7 @@ void meshGEdge::operator() (GEdge *ge) N = ge->meshAttributes.nbPointsTransfinite; } else{ - if (CTX::instance()->mesh.algo2d == ALGO_2D_BAMG || blf) + if (CTX::instance()->mesh.algo2d == ALGO_2D_BAMG || CTX::instance()->mesh.algo2d == ALGO_2D_PACK_PRLGRMS || blf) a = Integration(ge, t_begin, t_end, F_Lc_aniso, Points, CTX::instance()->mesh.lcIntegrationPrecision); else{ diff --git a/Mesh/meshGFaceDelaunayInsertion.cpp b/Mesh/meshGFaceDelaunayInsertion.cpp index 947e0a333745e8e540f836ddf6de2f068f4c2e5e..223eb34515c706e83c79fe8ac06be43b76b2f804 100644 --- a/Mesh/meshGFaceDelaunayInsertion.cpp +++ b/Mesh/meshGFaceDelaunayInsertion.cpp @@ -274,10 +274,10 @@ int inCircumCircleAniso(GFace *gf, double *p1, double *p2, double *p3, const double a = metric[0]; const double b = metric[1]; const double d = metric[2]; - double d2 = (x[0] - uv[0]) * (x[0] - uv[0]) * a - + (x[1] - uv[1]) * (x[1] - uv[1]) * d - + 2. * (x[0] - uv[0]) * (x[1] - uv[1]) * b; - return d2 < Radius2; + const double d0 = (x[0] - uv[0]); + const double d1 = (x[1] - uv[1]); + const double d3 = d0*d0*a + d1*d1*d + 2.0*d0*d1*b; + return d3 < Radius2; } int inCircumCircleAniso(GFace *gf, MTriangle *base, @@ -292,7 +292,6 @@ int inCircumCircleAniso(GFace *gf, MTriangle *base, (Vs[base->getVertex(0)->getIndex()] + Vs[base->getVertex(1)->getIndex()] + Vs[base->getVertex(2)->getIndex()]) / 3.}; - buildMetric(gf, pa, metric); circumCenterMetric(base, metric, Us, Vs, x, Radius2); @@ -300,11 +299,10 @@ int inCircumCircleAniso(GFace *gf, MTriangle *base, const double b = metric[1]; const double d = metric[2]; - double d2 = (x[0] - uv[0]) * (x[0] - uv[0]) * a - + (x[1] - uv[1]) * (x[1] - uv[1]) * d - + 2. * (x[0] - uv[0]) * (x[1] - uv[1]) * b; - - return d2 < Radius2; + const double d0 = (x[0] - uv[0]); + const double d1 = (x[1] - uv[1]); + const double d3 = d0*d0*a + d1*d1*d + 2.0*d0*d1*b; + return d3 < Radius2; } MTri3::MTri3(MTriangle *t, double lc, SMetric3 *metric, @@ -558,7 +556,7 @@ bool invMapUV(MTriangle *t, double *p, return false; } -double getSurfUV(MTriangle *t, std::vector<double> &Us, std::vector<double> &Vs) +inline double getSurfUV(MTriangle *t, std::vector<double> &Us, std::vector<double> &Vs) { double u1 = Us[t->getVertex(0)->getIndex()]; double v1 = Vs[t->getVertex(0)->getIndex()]; @@ -572,6 +570,7 @@ double getSurfUV(MTriangle *t, std::vector<double> &Us, std::vector<double> &Vs) return s * 0.5; } +double __DT2; bool insertVertexB (std::list<edgeXface> &shell, std::list<MTri3*> &cavity, bool force, GFace *gf, MVertex *v, double *param , MTri3 *t, @@ -585,6 +584,8 @@ bool insertVertexB (std::list<edgeXface> &shell, double *metric, MTri3 **oneNewTriangle) { + if (shell.size() <= 3 || shell.size() != cavity.size() + 2) return false; + std::list<MTri3*> new_cavity; // check that volume is conserved @@ -616,7 +617,7 @@ bool insertVertexB (std::list<edgeXface> &shell, MTri3 *t4; t4 = new MTri3(t, LL,0,&Us,&Vs,gf); - if (oneNewTriangle) *oneNewTriangle = t4; + if (oneNewTriangle) {force = true; *oneNewTriangle = t4;} // double din = t->getInnerRadius(); double d1 = distance(it->v[0],v); @@ -626,7 +627,7 @@ bool insertVertexB (std::list<edgeXface> &shell, // avoid angles that are too obtuse double cosv = ((d1*d1+d2*d2-d3*d3)/(2.*d1*d2)); - if ((d1 < LL * .0025 || d2 < LL * .0025 || cosv < -.9999999) && !force) { + if ((d1 < LL * .5 || d2 < LL * .5 || cosv < -.9) && !force) { onePointIsTooClose = true; } @@ -643,15 +644,16 @@ bool insertVertexB (std::list<edgeXface> &shell, newVolume += ss; ++it; } + - - if (fabs(oldVolume - newVolume) < 1.e-12 * oldVolume && shell.size() > 3 && - !onePointIsTooClose){ + if (fabs(oldVolume - newVolume) < 1.e-12 * oldVolume && !onePointIsTooClose){ connectTris_vector(new_cavity.begin(), new_cavity.end()); - // clock_t t1 = clock(); + // printf("%d %d\n",shell.size(),cavity.size()); + clock_t t1 = clock(); + // 30 % of the time is spent here !!! allTets.insert(newTris, newTris + shell.size()); // clock_t t2 = clock(); - // DT_INSERT_VERTEX += (double)(t2-t1)/CLOCKS_PER_SEC; + __DT2 += (double)(clock()-t1)/CLOCKS_PER_SEC; if (activeTets){ for (std::list<MTri3*>::iterator i = new_cavity.begin(); i != new_cavity.end(); ++i){ int active_edge; @@ -668,7 +670,7 @@ bool insertVertexB (std::list<edgeXface> &shell, // The cavity is NOT star shaped else{ - // printf("(%g %g) %22.15E %22.15E %d %d %d %d %d\n",v->x(),v->y(),oldVolume, newVolume, newVolume,shell.size(), onePointIsTooClose, cavity.size(), new_cavity.size(),allTets.size()); + // printf("(%g %g) %22.15E %22.15E %d %d %d %d %d\n",v->x(),v->y(),oldVolume, newVolume, newVolume,shell.size(), onePointIsTooClose, cavity.size(), new_cavity.size(),allTets.size()); // printf("12.5E 12.5E 12.5E 12.5E 12.5E\n",d1,d2,LL,cosv); ittet = cavity.begin(); @@ -764,7 +766,7 @@ static MTri3* search4Triangle (MTri3 *t, double pt[2], } if (!force)return 0; // FIXME: removing this leads to horrible performance - + N_GLOBAL_SEARCH ++ ; for(std::set<MTri3*,compareTri3Ptr>::iterator itx = AllTris.begin(); itx != AllTris.end();++itx){ @@ -778,6 +780,8 @@ static MTri3* search4Triangle (MTri3 *t, double pt[2], return 0; } +//double __DT1; + static bool insertAPoint(GFace *gf, std::set<MTri3*,compareTri3Ptr>::iterator it, double center[2], double metric[3], std::vector<double> &Us, std::vector<double> &Vs, @@ -806,7 +810,9 @@ static bool insertAPoint(GFace *gf, std::set<MTri3*,compareTri3Ptr>::iterator it // if the point is able to break the bad triangle "worst" if (1){ if (inCircumCircleAniso(gf, worst->tri(), center, metric, Us, Vs)){ + // clock_t t1 = clock(); recurFindCavityAniso(gf, shell, cavity, metric, center, worst, Us, Vs); + // __DT1 += (double) (clock() - t1)/CLOCKS_PER_SEC ; for (std::list<MTri3*>::iterator itc = cavity.begin(); itc != cavity.end(); ++itc){ if (invMapUV((*itc)->tri(), center, Us, Vs, uv, 1.e-8)) { ptin = *itc; @@ -816,14 +822,14 @@ static bool insertAPoint(GFace *gf, std::set<MTri3*,compareTri3Ptr>::iterator it } // else look for it else { - printf("we should never be here !!!\n"); + // printf("cocuou\n"); ptin = search4Triangle (worst, center, Us, Vs, AllTris,uv, oneNewTriangle ? true : false); if (ptin) { recurFindCavityAniso(gf, shell, cavity, metric, center, ptin, Us, Vs); } } } - + // ptin = search4Triangle (worst, center, Us, Vs, AllTris,uv, oneNewTriangle ? true : false); if (ptin) { @@ -853,8 +859,8 @@ static bool insertAPoint(GFace *gf, std::set<MTri3*,compareTri3Ptr>::iterator it if(!p.succeeded() || !insertVertexB (shell, cavity,false, gf, v, center, ptin, AllTris,ActiveTris, vSizes, vSizesBGM,vMetricsBGM, Us, Vs, metric, oneNewTriangle) ) { - // Msg::Debug("Point %g %g cannot be inserted because %d", - // center[0], center[1], p.succeeded() ); + Msg::Debug("Point %g %g cannot be inserted because %d", + center[0], center[1], p.succeeded() ); // printf("Point %g %g cannot be inserted because %d", // center[0], center[1], p.succeeded() ); AllTris.erase(it); @@ -910,6 +916,8 @@ void bowyerWatson(GFace *gf, int MAXPNT) } int ITER = 0; + int NBDELETED = 0; + // double DT1 = 0 , DT2=0, DT3=0; while (1){ // if(ITER % 1== 0){ // char name[245]; @@ -918,14 +926,20 @@ void bowyerWatson(GFace *gf, int MAXPNT) // } MTri3 *worst = *AllTris.begin(); if (worst->isDeleted()){ + // clock_t t1 = clock(); delete worst->tri(); delete worst; AllTris.erase(AllTris.begin()); + NBDELETED ++; + // DT1 += (double) (clock() - t1)/CLOCKS_PER_SEC ; } else{ - if(ITER++ % 5000 == 0) + // clock_t t2 = clock(); + if(ITER++ % 5000 == 0){ Msg::Debug("%7d points created -- Worst tri radius is %8.3f", vSizes.size(), worst->getRadius()); + printf("%d %d %d\n",vSizes.size(), AllTris.size(),NBDELETED); + } double center[2],metric[3],r2; if (worst->getRadius() < /*1.333333/(sqrt(3.0))*/0.5 * sqrt(2.0) || (int)vSizes.size() > MAXPNT) break; @@ -939,10 +953,15 @@ void bowyerWatson(GFace *gf, int MAXPNT) Vs[base->getVertex(2)->getIndex()]) / 3.}; buildMetric(gf, pa, metric); circumCenterMetric(worst->tri(), metric, Us, Vs, center, r2); + // DT2 += (double) (clock() - t2)/CLOCKS_PER_SEC ; + // clock_t t3 = clock() ; insertAPoint(gf, AllTris.begin(), center, metric, Us, Vs, vSizes, vSizesBGM, vMetricsBGM, AllTris); + // DT3 += (double) (clock() - t3)/CLOCKS_PER_SEC ; } } + // printf("%12.5E %12.5E %12.5E %12.5E %12.5E\n",DT1,DT2,DT3,__DT1,__DT2); + printf("%12.5E \n",__DT2); #if defined(HAVE_ANN) { FieldManager *fields = gf->model()->getFields(); @@ -1176,6 +1195,7 @@ void optimalPointFrontalB (GFace *gf, } else { Msg::Debug("--- Non optimal point found -----------"); + // Msg::Info("--- Non optimal point found -----------"); } } @@ -1230,7 +1250,7 @@ void bowyerWatsonFrontal(GFace *gf) worst->getRadius() > LIMIT_){ if(ITER++ % 5000 == 0) Msg::Debug("%7d points created -- Worst tri radius is %8.3f", - vSizes.size(), worst->getRadius()); + gf->mesh_vertices.size(), worst->getRadius()); double newPoint[2], metric[3]; //optimalPointFrontal (gf,worst,active_edge,Us,Vs,vSizes,vSizesBGM,newPoint,metric); optimalPointFrontalB (gf,worst,active_edge,Us,Vs,vSizes,vSizesBGM,newPoint,metric); @@ -1703,7 +1723,7 @@ void bowyerWatsonParallelograms(GFace *gf) buildMetric(gf, newPoint, metric); SMetric3 ANIZO_MESH = metrics[i]; - bool success = insertAPoint(gf, AllTris.begin(), newPoint, metric, Us, Vs, vSizes, + bool success = insertAPoint( gf, AllTris.begin(), newPoint, metric, Us, Vs, vSizes, vSizesBGM, vMetricsBGM, AllTris, 0, oneNewTriangle, &oneNewTriangle); if (!success) oneNewTriangle = 0; // if (!success)printf("success %d %d\n",success,AllTris.size()); diff --git a/Mesh/meshGFaceDelaunayInsertion.h b/Mesh/meshGFaceDelaunayInsertion.h index 003341ca3facfff7454404f2ab1793bf1afaf37d..19ddefc7fd7267ffa31799d3e412915de74850db 100644 --- a/Mesh/meshGFaceDelaunayInsertion.h +++ b/Mesh/meshGFaceDelaunayInsertion.h @@ -49,7 +49,7 @@ class MTri3 static int radiusNorm; // 2 is euclidian norm, -1 is infinite norm bool isDeleted() const { return deleted; } void forceRadius(double r) { circum_radius = r; } - double getRadius() const { return circum_radius; } + inline double getRadius() const { return circum_radius; } MTri3(MTriangle *t, double lc, SMetric3 *m = 0, const std::vector<double> *Us = 0, const std::vector<double> *Vs = 0, GFace *gf = 0); inline MTriangle *tri() const { return base; } diff --git a/Mesh/surfaceFiller.cpp b/Mesh/surfaceFiller.cpp index 8c5d44206412d03a5b97a59ef068496ee6733c04..c531b3d8aeeea05232d222e9c67031bb0685e6ac 100644 --- a/Mesh/surfaceFiller.cpp +++ b/Mesh/surfaceFiller.cpp @@ -17,7 +17,7 @@ #include "BackgroundMesh.h" #include "intersectCurveSurface.h" -static const double FACTOR = .81; +static const double FACTOR = .71; static const int NUMDIR = 3; static const double DIRS [NUMDIR] = {0.0, M_PI/20.,-M_PI/20.}; @@ -163,6 +163,8 @@ bool compute4neighbors (GFace *gf, // the surface metricField = SMetric3(1./(L*L)); } } + + // printf("M = (%g %g %g)\n",metricField(0,0),metricField(1,1),metricField(0,1)); // get the unit normal at that point Pair<SVector3, SVector3> der = gf->firstDer(SPoint2(midpoint[0],midpoint[1])); @@ -220,7 +222,15 @@ bool compute4neighbors (GFace *gf, // the surface 2*E*covar2[1]*covar2[0]+ N*covar2[1]*covar2[1]); - // printf("%12.5E %12.5E %g %g %g %g %g %g %g %g %g %g %g\n",l1,l2,size_1,size_2,size_param_1,size_param_2,M,N,E,s1.x(),s1.y(),s2.x(),s2.y()); + /* printf("%12.5E %12.5E %12.5E %12.5E %12.5E %12.5E %12.5E %12.5E %g %g %g %g %g %g %g %g %g %g %g\n", + M*covar1[0]*covar1[0]+ + 2*E*covar1[1]*covar1[0]+ + N*covar1[1]*covar1[1], + M*covar2[0]*covar2[0]+ + 2*E*covar2[1]*covar2[0]+ + N*covar2[1]*covar2[1] + ,covar1[0],covar1[1],covar2[0],covar2[1],l1,l2,size_1,size_2,size_param_1,size_param_2,M,N,E,s1.x(),s1.y(),s2.x(),s2.y());*/ + // this is the rectangle in the parameter plane. double r1 = 0*1.e-8*(double)rand() / RAND_MAX; double r2 = 0*1.e-8*(double)rand() / RAND_MAX; @@ -270,6 +280,8 @@ bool compute4neighbors (GFace *gf, // the surface void packingOfParallelograms(GFace* gf, std::vector<MVertex*> &packed, std::vector<SMetric3> &metrics){ #if defined(HAVE_RTREE) + // FILE *f = fopen ("parallelograms.pos","w"); + // get all the boundary vertices std::set<MVertex*> bnd_vertices; for(unsigned int i=0;i<gf->getNumMeshElements();i++){ @@ -296,7 +308,9 @@ void packingOfParallelograms(GFace* gf, std::vector<MVertex*> &packed, std::vec vertices.push_back(sp); double _min[2],_max[2]; sp->minmax(_min,_max); - rtree.Insert(_min,_max,sp); + // printf("%g %g .. %g %g\n",_min[0],_min[1],_max[0],_max[1]); + rtree.Insert(_min,_max,sp); + // sp->print(f); } // printf("initially : %d vertices in the domain\n",vertices.size()); @@ -345,8 +359,8 @@ void packingOfParallelograms(GFace* gf, std::vector<MVertex*> &packed, std::vec metrics.push_back(vertices[i]->_meshMetric); SPoint2 midpoint; reparamMeshVertexOnFace(vertices[i]->_v, gf, midpoint); - // fprintf(f,"SP(%22.15E,%22.15E,%g){1};\n",vertices[i]._v->x(),vertices[i]._v->y(),vertices[i]._v->z()); - fprintf(f,"SP(%22.15E,%22.15E,%g){1};\n",midpoint.x(),midpoint.y(),0.0); + fprintf(f,"SP(%22.15E,%22.15E,%g){1};\n",vertices[i]->_v->x(),vertices[i]->_v->y(),vertices[i]->_v->z()); + //fprintf(f,"SP(%22.15E,%22.15E,%g){1};\n",midpoint.x(),midpoint.y(),0.0); } delete vertices[i]; } diff --git a/benchmarks/2d/naca12_2d.geo b/benchmarks/2d/naca12_2d.geo index 90867af8e248e1ab0e7a97fbc1966b938bb0ca9e..dafab665c4533c3d17554c149ec7df4e358488c5 100644 --- a/benchmarks/2d/naca12_2d.geo +++ b/benchmarks/2d/naca12_2d.geo @@ -235,7 +235,8 @@ Field[2].hfar = 1.5; Field[2].hwall_n = 0.001; Field[2].hwall_t = 0.01; Field[2].ratio = 1.3; -Field[2].thickness = .1; +Field[2].thickness = .03; +Field[2].IntersectMetrics = 1; //Background Field = 2; Field[1] = Box;