From 7fec643d5ec40082bd0a0bb4b5babe06f52da565 Mon Sep 17 00:00:00 2001 From: Algiane Date: Wed, 14 Oct 2020 13:08:50 +0200 Subject: [PATCH 001/170] Remove a char used as int8_t. --- src/common/isosiz.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/isosiz.c b/src/common/isosiz.c index 09d92d548..acb602f3d 100644 --- a/src/common/isosiz.c +++ b/src/common/isosiz.c @@ -370,7 +370,7 @@ int MMG5_gradsizreq_iso(MMG5_pMesh mesh,MMG5_pSol met) { MMG5_pPoint p1,p2; double hgrad,ll,h1,h2,hn,ux,uy; int k,it,ip1,ip2,ipmaster,ipslave,maxit,nup,nu; - unsigned char i,i1,i2; + uint8_t i,i1,i2; if ( abs(mesh->info.imprim) > 5 || mesh->info.ddebug ) { From ce24ecf0631be670bccd753ae023846b211c27ac Mon Sep 17 00:00:00 2001 From: Algiane Date: Wed, 14 Oct 2020 14:58:33 +0200 Subject: [PATCH 002/170] Try to remove arm warnings. --- src/mmg3d/colver_3d.c | 6 ++++++ src/mmgs/anisomovpt_s.c | 24 ++++++++++++++++++++---- src/mmgs/colver_s.c | 15 ++++++++++++++- src/mmgs/mmgs1.c | 22 ++++++++++++++-------- src/mmgs/movpt_s.c | 40 +++++++++++++++++++++++++++++++++------- src/mmgs/split_s.c | 19 +++++++++++++++++-- 6 files changed, 104 insertions(+), 22 deletions(-) diff --git a/src/mmg3d/colver_3d.c b/src/mmg3d/colver_3d.c index fafd3305a..736db7ed6 100644 --- a/src/mmg3d/colver_3d.c +++ b/src/mmg3d/colver_3d.c @@ -388,6 +388,12 @@ int MMG5_chkcol_bdy(MMG5_pMesh mesh,MMG5_pSol met,int k,int8_t iface, p0 = &mesh->point[nump]; assert(p0->tag & MG_BDY); assert(p0->xp); + + /* Remove maybe-uninitialized value warning */ + nprvold[0] = nprvold[1] = nprvold[2] = 0.; + ncurold[0] = ncurold[1] = ncurold[2] = 0.; + nprvnew[0] = nprvnew[1] = nprvnew[2] = 0.; + ncurnew[0] = ncurnew[1] = ncurnew[2] = 0.; #endif ndepmin = ndepplus = 0; diff --git a/src/mmgs/anisomovpt_s.c b/src/mmgs/anisomovpt_s.c index 02bccc4e9..14818a49e 100644 --- a/src/mmgs/anisomovpt_s.c +++ b/src/mmgs/anisomovpt_s.c @@ -55,6 +55,8 @@ int movintpt_ani(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist) { int k,iel,kel,nump,nbeg,nend; int8_t i0,i1,i2,ier; static int warn=0; + static int8_t mmgErr0=0,mmgErr1=0; + step = 0.1; /* Make sure ball of point is closed */ @@ -104,7 +106,7 @@ int movintpt_ani(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist) { } /* At this point : gv = - gradient of V = direction to follow */ - /* Step 3 : locate new point in the ball, and compute its barycentric coordinates */ + /** Step 3 : locate new point in the ball, and compute its barycentric coordinates */ area = lispoi[1]*gv[1] - lispoi[2]*gv[0]; kel = 0; if ( area >= 0.0 ) { @@ -152,13 +154,20 @@ int movintpt_ani(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist) { lambda[2]*= (area); lambda[0] = 1.0 - lambda[1] - lambda[2]; - /* Step 4 : come back to original problem, and compute patch in triangle iel */ + /** Step 4 : come back to original problem, and compute patch in triangle iel */ iel = list[kel] / 3; i0 = list[kel] % 3; pt = &mesh->tria[iel]; ier = MMG5_bezierCP(mesh,pt,&pb,1); - assert(ier); + if ( !ier ) { + if( !mmgErr0 ) { + mmgErr0 = 1; + fprintf(stderr,"\n ## Warning: %s: function MMG5_bezierCP return 0.\n", + __func__); + } + return 0; + } /* Now, for Bezier interpolation, one should identify which of i,i1,i2 is 0,1,2 recall uv[0] = barycentric coord associated to pt->v[1], uv[1] associated to pt->v[2] */ @@ -176,7 +185,14 @@ int movintpt_ani(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist) { } ier = MMGS_bezierInt(&pb,uv,o,no,to); - assert(ier); + if ( !ier ) { + if( !mmgErr1 ) { + mmgErr1 = 1; + fprintf(stderr," ## Warning: %s: function MMGS_bezierInt return 0.\n", + __func__); + } + return 0; + } /* Second test : check whether geometric approximation has not been too much degraded */ ppt0 = &mesh->point[0]; diff --git a/src/mmgs/colver_s.c b/src/mmgs/colver_s.c index 271fe3488..4db898e8c 100644 --- a/src/mmgs/colver_s.c +++ b/src/mmgs/colver_s.c @@ -64,6 +64,18 @@ int chkcol(MMG5_pMesh mesh,MMG5_pSol met,int k,int8_t i,int *list,int8_t typchk) i2 = MMG5_iprv2[i]; ip1 = pt->v[i1]; ip2 = pt->v[i2]; + +#ifndef NDEBUG + /* suppression of maybe-uninitialized value on arm */ + lon = 0.; + n00old[0] = n00old[1] = n00old[2] = 0.; + n0old[0] = n0old[1] = n0old[2] = 0.; + n1old[0] = n1old[1] = n1old[2] = 0.; + n00new[0] = n00new[1] = n00new[2] = 0.; + n0new[0] = n0new[1] = n0new[2] = 0.; + n1new[0] = n1new[1] = n1new[2] = 0.; +#endif + if ( typchk == 2 && met->m ) { lon = MMG5_lenSurfEdg(mesh,met,ip1,ip2,0); if ( !lon ) return 0; @@ -458,7 +470,8 @@ int colver2(MMG5_pMesh mesh,int* list) { int litcol(MMG5_pMesh mesh,int k,int8_t i,double kali) { MMG5_pTria pt,pt0,pt1; MMG5_pPoint p1,p2; - double kal,ps,cosnold,cosnnew,n0old[3],n0new[3],n1old[3],n1new[3],n00old[3],n00new[3]; + double kal,ps,cosnold,cosnnew; + double n0old[3],n0new[3],n1old[3],n1new[3],n00old[3],n00new[3]; int *adja,list[MMGS_LMAX+2],jel,ip2,l,ilist; int8_t i1,i2,j,jj,j2,open; diff --git a/src/mmgs/mmgs1.c b/src/mmgs/mmgs1.c index 171d758cd..c424b0046 100755 --- a/src/mmgs/mmgs1.c +++ b/src/mmgs/mmgs1.c @@ -449,10 +449,14 @@ static int movtri(MMG5_pMesh mesh,MMG5_pSol met,int maxit) { if ( MG_EDG(ppt->tag) ) { ier = movridpt(mesh,met,list,ilist); - if ( ier ) ns++; + if ( ier ) { + ns++; + } } - else + else { ier = movintpt(mesh,met,list,ilist); + } + if ( ier ) { nm++; ppt->flag = base; @@ -747,6 +751,7 @@ static int anaelt(MMG5_pMesh mesh,MMG5_pSol met,int8_t typchk) { it = 1; nc = 0; + j = 0; // To remove maybe-uninitialized warning on arm do { ni = 0; for (k=1; k<=mesh->nt; k++) { @@ -895,11 +900,11 @@ static int anaelt(MMG5_pMesh mesh,MMG5_pSol met,int8_t typchk) { int chkspl(MMG5_pMesh mesh,MMG5_pSol met,int k,int i) { MMG5_pTria pt,pt1; MMG5_pPoint ppt; - MMG5_pxPoint go; + MMG5_pxPoint go; MMG5_Bezier b; - double s,uv[2],o[3],no[3],to[3]; - int *adja,jel,ip,ier; - int8_t i1,i2,j,jj,j2; + double s,uv[2],o[3],no[3],to[3]; + int *adja,jel,ip,ier; + int8_t i1,i2,j,jj,j2; if ( mesh->xp > mesh->xpmax-2 ) return 0; pt = &mesh->tria[k]; @@ -917,7 +922,7 @@ int chkspl(MMG5_pMesh mesh,MMG5_pSol met,int k,int i) { } ier = MMG5_bezierCP(mesh,pt,&b,1); - assert(ier); + assert ( ier ); /* create midedge point */ uv[0] = 0.5; @@ -946,7 +951,8 @@ int chkspl(MMG5_pMesh mesh,MMG5_pSol met,int k,int i) { } s = 0.5; - if ( !intmet(mesh,met,k,i,ip,s) ) return 0; + ier = intmet(mesh,met,k,i,ip,s); + if ( !ier ) return 0; return ip; } diff --git a/src/mmgs/movpt_s.c b/src/mmgs/movpt_s.c index da91a1d4c..c5e797a78 100644 --- a/src/mmgs/movpt_s.c +++ b/src/mmgs/movpt_s.c @@ -37,15 +37,26 @@ #include -/* compute movement of an internal point whose ball is passed */ +/** + * \param mesh pointer toward the mesh structure. + * \param met pointer toward the metric structure. + * \param list pointer toward the ball of the point. + * \param ilist size of the ball. + * + * \return 0 if we can't move the point, 1 if we can. + * + * Move internal point whose volumic is passed. + * + */ int movintpt_iso(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist) { MMG5_pPoint p0,p1,ppt0; MMG5_pTria pt,pt0; MMG5_Bezier b; - double aa,bb,ab,ll,l,mlon,devmean,GV[3],gv[2],cosalpha,sinalpha,r[3][3],*n,lispoi[3*MMGS_LMAX+3]; - double ux,uy,uz,det2d,detloc,step,lambda[3],uv[2],o[3],no[3],to[3],Vold,Vnew,calold,calnew,caltmp; - int ier,iel,ipp,k,kel,npt,ibeg,iend; - int8_t i0,i1,i2; + double aa,bb,ab,ll,l,mlon,devmean,GV[3],gv[2],cosalpha,sinalpha,r[3][3],*n,lispoi[3*MMGS_LMAX+3]; + double ux,uy,uz,det2d,detloc,step,lambda[3],uv[2],o[3],no[3],to[3],Vold,Vnew,calold,calnew,caltmp; + int ier,iel,ipp,k,kel,npt,ibeg,iend; + int8_t i0,i1,i2; + static int8_t mmgErr0=0,mmgErr1=0; step = 0.1; Vold = 0.0; @@ -243,7 +254,14 @@ int movintpt_iso(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist) { pt = &mesh->tria[iel]; ier = MMG5_bezierCP(mesh,pt,&b,1); - assert(ier); + if ( !ier ) { + if( !mmgErr0 ) { + mmgErr0 = 1; + fprintf(stderr,"\n ## Warning: %s: function MMG5_bezierCP return 0.\n", + __func__); + } + return 0; + } /* Now, for Bezier interpolation, one should identify which of i,i1,i2 is 0,1,2 recall uv[0] = barycentric coord associated to pt->v[1], uv[1] associated to pt->v[2] */ @@ -259,8 +277,16 @@ int movintpt_iso(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist) { uv[0] = lambda[2]; uv[1] = lambda[0]; } + ier = MMGS_bezierInt(&b,uv,o,no,to); - assert(ier); + if ( !ier ) { + if( !mmgErr1 ) { + mmgErr1 = 1; + fprintf(stderr," ## Warning: %s: function MMGS_bezierInt return 0.\n", + __func__); + } + return 0; + } /* First test : check whether variance has been decreased */ mlon = 0.0; diff --git a/src/mmgs/split_s.c b/src/mmgs/split_s.c index c3be5ac11..cf3ff6f5e 100644 --- a/src/mmgs/split_s.c +++ b/src/mmgs/split_s.c @@ -225,6 +225,7 @@ int split1b(MMG5_pMesh mesh,int k,int8_t i,int ip) { double uv[2],o[3],no[3],to[3]; int *adja,iel,jel,kel,mel,ier; int8_t i1,i2,j,j1,j2,m; + static int8_t mmgErr0=0,mmgErr1=0; iel = MMGS_newElt(mesh); if ( !iel ) { @@ -251,14 +252,28 @@ int split1b(MMG5_pMesh mesh,int k,int8_t i,int ip) { /* update normal n2 if need be */ if ( jel && pt->tag[i] & MG_GEO ) { ier = MMG5_bezierCP(mesh,&mesh->tria[jel],&b,1); - assert(ier); + if ( !ier ) { + if( !mmgErr0 ) { + mmgErr0 = 1; + fprintf(stderr,"\n ## Warning: %s: function MMG5_bezierCP return 0.\n", + __func__); + } + assert(0); + } uv[0] = 0.5; uv[1] = 0.5; if ( j == 1 ) uv[0] = 0.0; else if ( j == 2 ) uv[1] = 0.0; ier = MMGS_bezierInt(&b,uv,o,no,to); - assert(ier); + if ( !ier ) { + if( !mmgErr1 ) { + mmgErr1 = 1; + fprintf(stderr," ## Warning: %s: function MMGS_bezierInt return 0.\n", + __func__); + } + assert(0); + } go = &mesh->xpoint[ppt->xp]; memcpy(go->n2,no,3*sizeof(double)); } From 1f2e49a5e7bb5e9ec7fc8ebf3f0ff06cb3dc45a2 Mon Sep 17 00:00:00 2001 From: Algiane Date: Wed, 14 Oct 2020 15:20:47 +0200 Subject: [PATCH 003/170] Remove linux warnings. --- src/mmg2d/inout_2d.c | 6 ++---- src/mmgs/inout_s.c | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/mmg2d/inout_2d.c b/src/mmg2d/inout_2d.c index 9f1b65ba5..9b62766fe 100644 --- a/src/mmg2d/inout_2d.c +++ b/src/mmg2d/inout_2d.c @@ -70,8 +70,9 @@ int MMG2D_loadMesh(MMG5_pMesh mesh,const char *filename) { return 0; } } - if ( mesh->info.imprim >= 0 ) + if ( mesh->info.imprim >= 0 ) { fprintf(stdout," %%%% %s OPENED\n",data); + } MMG5_SAFE_FREE(data); if (!bin) { @@ -267,9 +268,6 @@ int MMG2D_loadMesh(MMG5_pMesh mesh,const char *filename) { } - if ( abs(mesh->info.imprim) > 5 ) - fprintf(stdout," -- READING DATA FILE %s\n",data); - if ( !mesh->np ) { fprintf(stdout," ** MISSING DATA : no point\n"); return -1; diff --git a/src/mmgs/inout_s.c b/src/mmgs/inout_s.c index 08f62a8db..3dd5f5cb8 100644 --- a/src/mmgs/inout_s.c +++ b/src/mmgs/inout_s.c @@ -1358,7 +1358,7 @@ int MMGS_loadAllSols(MMG5_pMesh mesh,MMG5_pSol *sol, const char *filename) { long posnp; int iswp,ier,dim; int j,k,ver,bin,np,nsols,*type; - char data[10]; + char data[16]; static char mmgWarn = 0; /** Read the file header */ From a489bac447260e0c13444ab6e0e3a494e6559383 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 20 Oct 2020 11:08:45 +0200 Subject: [PATCH 004/170] Correction of the size of the pile: if the leve-set doesn't contains any tet/tri entirely, the pile may be of size mesh->ne (resp mesh->nt). --- src/mmg2d/mmg2d6.c | 12 ++++++------ src/mmg3d/mmg3d2.c | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/mmg2d/mmg2d6.c b/src/mmg2d/mmg2d6.c index 895f4ac08..f7e76f9dd 100644 --- a/src/mmg2d/mmg2d6.c +++ b/src/mmg2d/mmg2d6.c @@ -596,7 +596,7 @@ int MMG2D_rmc(MMG5_pMesh mesh, MMG5_pSol sol){ pt->flag = base; pile[ipile] = k; ipile++; - if ( ipile >= mesh->nt ) { + if ( ipile > mesh->nt ) { fprintf(stderr,"\n ## Problem in length of pile; function rmc.\n" " Check that the level-set intersect the mesh.\n" " Exit program.\n"); @@ -630,7 +630,7 @@ int MMG2D_rmc(MMG5_pMesh mesh, MMG5_pSol sol){ pt2->flag = base; pile[ipile] = ll; ipile++; - if ( ipile >= mesh->nt ) { + if ( ipile > mesh->nt ) { fprintf(stderr,"\n ## Problem in length of pile; function rmc. Exit program.\n"); return 0; } @@ -645,7 +645,7 @@ int MMG2D_rmc(MMG5_pMesh mesh, MMG5_pSol sol){ pt2->flag = base; pile[ipile] = ll; ipile++; - if ( ipile >= mesh->nt-1 ) { + if ( ipile > mesh->nt ) { fprintf(stderr,"\n ## Problem in length of pile; function rmc. Exit program.\n"); return 0; } @@ -694,7 +694,7 @@ int MMG2D_rmc(MMG5_pMesh mesh, MMG5_pSol sol){ pt->flag = base; pile[ipile] = k; ipile++; - if ( ipile >= mesh->nt -1 ) { + if ( ipile > mesh->nt ) { fprintf(stderr,"\n ## Problem in length of pile; function rmc. Exit program.\n"); return 0; } @@ -724,7 +724,7 @@ int MMG2D_rmc(MMG5_pMesh mesh, MMG5_pSol sol){ pt2->flag = base; pile[ipile] = ll; ipile++; - if ( ipile >= mesh->nt -1 ) { + if ( ipile > mesh->nt ) { fprintf(stderr,"\n ## Problem in length of pile; function rmc. Exit program.\n"); return 0; } @@ -739,7 +739,7 @@ int MMG2D_rmc(MMG5_pMesh mesh, MMG5_pSol sol){ pt2->flag = base; pile[ipile] = ll; ipile++; - if ( ipile >= mesh->nt -1 ) { + if ( ipile > mesh->nt ) { fprintf(stderr,"\n ## Problem in length of pile; function rmc. Exit program.\n"); return 0; } diff --git a/src/mmg3d/mmg3d2.c b/src/mmg3d/mmg3d2.c index 1a889376c..cf61f1f1f 100755 --- a/src/mmg3d/mmg3d2.c +++ b/src/mmg3d/mmg3d2.c @@ -818,7 +818,7 @@ int MMG3D_rmc(MMG5_pMesh mesh, MMG5_pSol sol){ pt->flag = base; pile[ipile] = k; ipile++; - if ( ipile >= mesh->ne ) { + if ( ipile > mesh->ne ) { fprintf(stderr,"\n ## Problem in length of pile; function rmc.\n" " Check that the level-set intersect the mesh.\n" " Exit program.\n"); @@ -850,7 +850,7 @@ int MMG3D_rmc(MMG5_pMesh mesh, MMG5_pSol sol){ pt2->flag = base; pile[ipile] = ll; ipile++; - if ( ipile >= mesh->ne ) { + if ( ipile > mesh->ne ) { fprintf(stderr,"\n ## Problem in length of pile; function rmc. Exit program.\n"); return 0; } @@ -902,7 +902,7 @@ int MMG3D_rmc(MMG5_pMesh mesh, MMG5_pSol sol){ pt->flag = base; pile[ipile] = k; ipile++; - if ( ipile >= mesh->ne ) { + if ( ipile > mesh->ne ) { fprintf(stderr,"\n ## Problem in length of pile; function rmc. Exit program.\n"); return 0; } @@ -931,7 +931,7 @@ int MMG3D_rmc(MMG5_pMesh mesh, MMG5_pSol sol){ pt2->flag = base; pile[ipile] = ll; ipile++; - if ( ipile >= mesh->ne ) { + if ( ipile > mesh->ne ) { fprintf(stderr,"\n ## Problem in length of pile; function rmc. Exit program.\n"); return 0; } From fc8a6c59c16d4975c96aac5337f9e22a7830f8f3 Mon Sep 17 00:00:00 2001 From: Algiane Date: Mon, 26 Oct 2020 16:30:17 +0100 Subject: [PATCH 005/170] Adds the possibility to save Cell data at Medit format (to use Mmg API to convert VTK file). --- src/common/inout.c | 191 +++++++++++++++++++++-- src/common/libmmgtypes.h | 3 +- src/common/mmgcommon.h | 8 +- src/common/vtkparser.cpp | 327 ++++++++++++++++++++++++++------------- src/mmg2d/inout_2d.c | 61 ++++++-- src/mmg3d/inout_3d.c | 67 ++++++-- src/mmgs/inout_s.c | 70 +++++++-- 7 files changed, 562 insertions(+), 165 deletions(-) diff --git a/src/common/inout.c b/src/common/inout.c index 52e7cb049..9df193c4e 100644 --- a/src/common/inout.c +++ b/src/common/inout.c @@ -2309,22 +2309,25 @@ void MMG5_writeDoubleSol3D(MMG5_pMesh mesh,MMG5_pSol sol,FILE *inm,int bin, * \param inm allocatable pointer toward the FILE structure. * \param ver file version (1=simple precision, 2=double). * \param bin 1 if the file is a binary. + * \param bpos cumulative field position for binary Medit format. * \param np number of solutions of each type. * \param dim solution dimension. * \param nsols number of solutions of different types in the file. + * \param entities kind of entity on which the solution applies (Vertex or Tetra) * \param type type of solutions. * \param size size of solutions. * * \return 0 if unable to open the file, 1 if success. * - * Open the "filename" solution file and read the file header. + * Open the "filename" solution file and save the file header and the number and + * type of solutions at vertices (Native solutions for Mmg). * */ int MMG5_saveSolHeader( MMG5_pMesh mesh,const char *filename, - FILE **inm,int ver,int *bin,int np,int dim, - int nsols,int *type,int *size) { + FILE **inm,int ver,int *bin,int *bpos,int np,int dim, + int nsols,int *entities,int *type,int *size) { MMG5_pPoint ppt; - int binch,bpos; + int binch; int k; char *ptr,*data,chaine[MMG5_FILESTR_LGTH]; @@ -2370,7 +2373,7 @@ int MMG5_saveSolHeader( MMG5_pMesh mesh,const char *filename, MMG5_SAFE_FREE(data); /*entete fichier*/ - binch=bpos=0; + binch=(*bpos)=0; if(!*bin) { strcpy(&chaine[0],"MeshVersionFormatted\n"); fprintf(*inm,"%s %d",chaine,ver); @@ -2383,8 +2386,8 @@ int MMG5_saveSolHeader( MMG5_pMesh mesh,const char *filename, fwrite(&binch,MMG5_SW,1,*inm); binch = 3; //Dimension fwrite(&binch,MMG5_SW,1,*inm); - bpos = 20; //Pos - fwrite(&bpos,MMG5_SW,1,*inm); + (*bpos) = 20; //Pos + fwrite(bpos,MMG5_SW,1,*inm); binch = dim; fwrite(&binch,MMG5_SW,1,*inm); } @@ -2395,32 +2398,190 @@ int MMG5_saveSolHeader( MMG5_pMesh mesh,const char *filename, if ( MG_VOK(ppt) ) np++; } + /* Count the number of solutions at vertices */ + int npointSols = 0; + for (k=0; knt; k++) { + pt = &mesh->tria[k]; + if ( MG_EOK(pt) ) { + ++nt; + } + } + + /* Sol at vertices header */ + if(!bin) { + fprintf(inm,"\n\nSolAtTriangles\n"); + fprintf(inm,"%d\n",nt); + fprintf(inm,"%d",nsolsAtTriangles); + for (k=0; kne; k++) { + pt = &mesh->tetra[k]; + if ( MG_EOK(pt) ) { + ++ne; + } + } + + /* Sol at vertices header */ + if(!bin) { + fprintf(inm,"\n\nSolAtTetrahedra\n"); + fprintf(inm,"%d\n",ne); + fprintf(inm,"%d",nsolsAtTetra); + for (k=0; kGetArrayName(k)); - } - } - if ( ncellRef > 1 ) { - printf( " ## Warning:%s: %d reference fields detected (labelled 'medit:ref')." - " Only the first is used, others are ignored.\n",__func__,ncellRef); + // else { + // printf( " ## Warning:%s: %s VTK cell data used" + // " only to assign reference to cells (cell data labelled 'medit:ref')." + // " Cell data ignored.\n",__func__,cd->GetArrayName(k)); + // } } + // if ( ncellRef > 1 ) { + // printf( " ## Warning:%s: %d reference fields detected (labelled 'medit:ref')." + // " Only the first is used, others are ignored.\n",__func__,ncellRef); + // } } // Count the number of field data @@ -214,7 +214,7 @@ int MMG5_count_vtkEntities ( vtkDataSet *dataset, MMG5_pMesh mesh, " Ignored.\n",__func__ ); } - *nsols = npointData - npointRef; + *nsols = npointData + ncellData - npointRef - ncellRef; return 1; } @@ -617,101 +617,230 @@ int MMG5_loadVtkMesh_part2(MMG5_pMesh mesh,MMG5_pSol *sol,vtkDataSet **dataset, if ( nsols ) { auto *pd = (*dataset)->GetPointData(); - assert ( pd ); - int npointData = pd->GetNumberOfArrays(); - assert ( npointData ); + auto *cd = (*dataset)->GetCellData(); - int isol = 0; - for (int k = 0; k < npointData; k++) { - psl = *sol + isol; - psl->ver = mesh->ver; - psl->dim = mesh->dim; - psl->type = 1; - - char *ptr = NULL; - bool metricData = 0; - char chaine[MMG5_FILESTR_LGTH]; - strcpy(chaine,pd->GetArrayName(k)); - - if ( strstr(chaine,"medit:ref" ) ) { - continue; - } - else if ( (ptr = strstr(chaine,":metric")) ) { - *ptr = '\0'; - metricData = 1; - } + if ( pd ) { + int npointData = pd->GetNumberOfArrays(); + + int isol = 0; + for (int k = 0; k < npointData; k++) { + psl = *sol + isol; + psl->ver = mesh->ver; + psl->dim = mesh->dim; + psl->type = 1; + psl->entities = MMG5_Vertex; + + char *ptr = NULL; + bool metricData = 0; + char chaine[MMG5_FILESTR_LGTH]; + strcpy(chaine,pd->GetArrayName(k)); - if ( !MMG5_Set_inputSolName(mesh,psl,chaine) ) { - if ( !mmgWarn1 ) { - mmgWarn1 = 1; - fprintf(stderr,"\n ## Warning: %s: unable to set solution name for" - " at least 1 solution.\n",__func__); + if ( strstr(chaine,"medit:ref" ) ) { + continue; } - } + else if ( (ptr = strstr(chaine,":metric")) ) { + *ptr = '\0'; + metricData = 1; + } + + if ( !MMG5_Set_inputSolName(mesh,psl,chaine) ) { + if ( !mmgWarn1 ) { + mmgWarn1 = 1; + fprintf(stderr,"\n ## Warning: %s: unable to set solution name for" + " at least 1 solution.\n",__func__); + } + } + + auto ar = pd->GetArray(k); + + psl->np = ar->GetNumberOfTuples(); + if ( mesh->np != psl->np ) { + fprintf(stderr," ** MISMATCHES DATA: THE NUMBER OF VERTICES IN " + "THE MESH (%d) DIFFERS FROM THE NUMBER OF VERTICES IN " + "THE SOLUTION (%d) \n",mesh->np,psl->np); + return -1; + } + + int ncp = ar->GetNumberOfComponents(); + + if ( ncp == 1 ) { + psl->size = 1; + psl->type = 1; + } + else if ( ncp == 2 || ncp == 3 ) { + assert ( ncp == mesh->dim ); + psl->size = ncp; + psl->type = 2; + } + else if ( ncp == (mesh->dim * mesh->dim) ) { + if ( metricData ) { + psl->size = (psl->dim*(psl->dim+1))/2; + psl->type = 3; + } + else { + psl->size = ncp; + psl->type = 4; + } + } + else { + fprintf(stderr," ** UNEXPECTED NUMBER OF COMPONENTS (%d). IGNORED \n",ncp); + return -1; + } + + // mem alloc + if ( psl->m ) MMG5_DEL_MEM(mesh,psl->m); + psl->npmax = mesh->npmax; - auto ar = pd->GetArray(k); + MMG5_ADD_MEM(mesh,(psl->size*(psl->npmax+1))*sizeof(double),"initial solution", + fprintf(stderr," Exit program.\n"); + return -1); + MMG5_SAFE_CALLOC(psl->m,psl->size*(psl->npmax+1),double,return 0); - psl->np = ar->GetNumberOfTuples(); - if ( mesh->np != psl->np ) { - fprintf(stderr," ** MISMATCHES DATA: THE NUMBER OF VERTICES IN " - "THE MESH (%d) DIFFERS FROM THE NUMBER OF VERTICES IN " - "THE SOLUTION (%d) \n",mesh->np,psl->np); - return -1; + switch ( psl->type ) { + case ( 1 ): case ( 2 ): + for (k=1; k<=psl->np; k++) { + int iadr = k*psl->size; + ar->GetTuple ( k-1, &psl->m[iadr] ); + } + break; + + case ( 3 ): + // anisotropic sol + double dbuf[9]; + + for (k=1; k<=psl->np; k++) { + ar->GetTuple ( k-1, dbuf ); + int iadr = psl->size*k; + + if ( !metricData ) { + // Non symmetric tensor + if ( psl->dim ==2 ) { + psl->m[iadr] = dbuf[0]; + psl->m[iadr+1] = dbuf[1]; + psl->m[iadr+2] = dbuf[3]; + psl->m[iadr+3] = dbuf[4]; + } + else { + for ( int i=0 ; i<9 ; i++ ) { + psl->m[iadr+i] = dbuf[i]; + } + } + } + else { + // Symmetric tensor + if ( psl->dim ==2 ) { + assert ( dbuf[1] == dbuf[2] ); + + psl->m[iadr] = dbuf[0]; + psl->m[iadr+1] = dbuf[1]; + psl->m[iadr+2] = dbuf[3]; + } + else { + assert ( dbuf[1]==dbuf[3] || dbuf[2]==dbuf[6] || dbuf[5]==dbuf[7] ); + + psl->m[iadr+0] = dbuf[0]; + psl->m[iadr+1] = dbuf[1]; + psl->m[iadr+2] = dbuf[2]; + psl->m[iadr+3] = dbuf[4]; + psl->m[iadr+4] = dbuf[5]; + psl->m[iadr+5] = dbuf[8]; + } + } + } + + break; + default: + fprintf(stderr," ** UNEXPECTED METRIC TYPE (%d). EXIT PROGRAM \n",psl->type); + return -1; + } + + ++isol; } + } - int ncp = ar->GetNumberOfComponents(); + if ( cd ) { + int ncellData = cd->GetNumberOfArrays(); - if ( ncp == 1 ) { - psl->size = 1; + int isol = 0; + for (int k = 0; k < ncellData; k++) { + psl = *sol + isol; + psl->ver = mesh->ver; + psl->dim = mesh->dim; psl->type = 1; - } - else if ( ncp == 2 || ncp == 3 ) { - assert ( ncp == mesh->dim ); - psl->size = ncp; - psl->type = 2; - } - else if ( ncp == (mesh->dim * mesh->dim) ) { - if ( metricData ) { + psl->entities = MMG5_Tetrahedron; + + char *ptr = NULL; + char chaine[MMG5_FILESTR_LGTH]; + strcpy(chaine,pd->GetArrayName(k)); + + if ( strstr(chaine,"medit:ref" ) ) { + continue; + } + + if ( !MMG5_Set_inputSolName(mesh,psl,chaine) ) { + if ( !mmgWarn1 ) { + mmgWarn1 = 1; + fprintf(stderr,"\n ## Warning: %s: unable to set solution name for" + " at least 1 solution.\n",__func__); + } + } + + auto ar = cd->GetArray(k); + + psl->np = ar->GetNumberOfTuples(); + if ( mesh->ne != psl->np ) { + fprintf(stderr," ** MISMATCHES DATA: THE NUMBER OF VERTICES IN " + "THE MESH (%d) DIFFERS FROM THE NUMBER OF VERTICES IN " + "THE SOLUTION (%d) \n",mesh->ne,psl->np); + return -1; + } + + int ncp = ar->GetNumberOfComponents(); + + if ( ncp == 1 ) { + psl->size = 1; + psl->type = 1; + } + else if ( ncp == 2 || ncp == 3 ) { + assert ( ncp == mesh->dim ); + psl->size = ncp; + psl->type = 2; + } + else if ( ncp == (mesh->dim * mesh->dim) ) { psl->size = (psl->dim*(psl->dim+1))/2; psl->type = 3; } else { - psl->size = ncp; - psl->type = 4; + fprintf(stderr," ** UNEXPECTED NUMBER OF COMPONENTS (%d). IGNORED \n",ncp); + return -1; } - } - else { - fprintf(stderr," ** UNEXPECTED NUMBER OF COMPONENTS (%d). IGNORED \n",ncp); - return -1; - } - // mem alloc - if ( psl->m ) MMG5_DEL_MEM(mesh,psl->m); - psl->npmax = mesh->npmax; + // mem alloc + if ( psl->m ) MMG5_DEL_MEM(mesh,psl->m); + psl->npmax = mesh->nemax; - MMG5_ADD_MEM(mesh,(psl->size*(psl->npmax+1))*sizeof(double),"initial solution", - fprintf(stderr," Exit program.\n"); - return -1); - MMG5_SAFE_CALLOC(psl->m,psl->size*(psl->npmax+1),double,return 0); + MMG5_ADD_MEM(mesh,(psl->size*(psl->npmax+1))*sizeof(double),"initial solution", + fprintf(stderr," Exit program.\n"); + return -1); + MMG5_SAFE_CALLOC(psl->m,psl->size*(psl->npmax+1),double,return 0); - switch ( psl->type ) { - case ( 1 ): case ( 2 ): - for (k=1; k<=psl->np; k++) { - int iadr = k*psl->size; - ar->GetTuple ( k-1, &psl->m[iadr] ); - } - break; + switch ( psl->type ) { + case ( 1 ): case ( 2 ): + for (k=1; k<=psl->np; k++) { + int iadr = k*psl->size; + ar->GetTuple ( k-1, &psl->m[iadr] ); + } + break; - case ( 3 ): - // anisotropic sol - double dbuf[9]; + case ( 3 ): + // anisotropic sol + double dbuf[9]; - for (k=1; k<=psl->np; k++) { - ar->GetTuple ( k-1, dbuf ); - int iadr = psl->size*k; + for (k=1; k<=psl->np; k++) { + ar->GetTuple ( k-1, dbuf ); + int iadr = psl->size*k; - if ( !metricData ) { // Non symmetric tensor if ( psl->dim ==2 ) { psl->m[iadr] = dbuf[0]; @@ -725,35 +854,15 @@ int MMG5_loadVtkMesh_part2(MMG5_pMesh mesh,MMG5_pSol *sol,vtkDataSet **dataset, } } } - else { - // Symmetric tensor - if ( psl->dim ==2 ) { - assert ( dbuf[1] == dbuf[2] ); - psl->m[iadr] = dbuf[0]; - psl->m[iadr+1] = dbuf[1]; - psl->m[iadr+2] = dbuf[3]; - } - else { - assert ( dbuf[1]==dbuf[3] || dbuf[2]==dbuf[6] || dbuf[5]==dbuf[7] ); - - psl->m[iadr+0] = dbuf[0]; - psl->m[iadr+1] = dbuf[1]; - psl->m[iadr+2] = dbuf[2]; - psl->m[iadr+3] = dbuf[4]; - psl->m[iadr+4] = dbuf[5]; - psl->m[iadr+5] = dbuf[8]; - } - } + break; + default: + fprintf(stderr," ** UNEXPECTED METRIC TYPE (%d). EXIT PROGRAM \n",psl->type); + return -1; } - break; - default: - fprintf(stderr," ** UNEXPECTED METRIC TYPE (%d). EXIT PROGRAM \n",psl->type); - return -1; + ++isol; } - - ++isol; } } diff --git a/src/mmg2d/inout_2d.c b/src/mmg2d/inout_2d.c index 9b62766fe..7f1eca319 100644 --- a/src/mmg2d/inout_2d.c +++ b/src/mmg2d/inout_2d.c @@ -1478,7 +1478,7 @@ int MMG2D_saveSol(MMG5_pMesh mesh,MMG5_pSol sol,const char *filename) { FILE* inm; MMG5_pPoint ppt; int k,ier; - int binch,bin,dim; + int binch,bin,bpos,dim; if ( !sol->np ) return 1; @@ -1498,8 +1498,9 @@ int MMG2D_saveSol(MMG5_pMesh mesh,MMG5_pSol sol,const char *filename) { dim = 2; } - ier = MMG5_saveSolHeader( mesh,filename,&inm,sol->ver,&bin,mesh->np,dim, - 1,&sol->type,&sol->size); + bpos = 0; + ier = MMG5_saveSolHeader( mesh,filename,&inm,sol->ver,&bin,&bpos,mesh->np,dim, + 1,&sol->entities,&sol->type,&sol->size); if ( ier < 1 ) return ier; @@ -1538,26 +1539,43 @@ int MMG2D_saveAllSols(MMG5_pMesh mesh,MMG5_pSol *sol,const char *filename) { MMG5_pPoint ppt; MMG5_pSol psl; int j,k,ier; - int binch,bin; - int *type,*size; + int binch,bin,bpos,npointSols,ncellSols; + int *type,*size,*entities; if ( !(*sol)[0].np ) return 1; MMG5_SAFE_CALLOC(type,mesh->nsols,int,return 0); MMG5_SAFE_CALLOC(size,mesh->nsols,int,MMG5_SAFE_FREE(type);return 0); + MMG5_SAFE_CALLOC(entities,mesh->nsols,int, + MMG5_SAFE_FREE(type);MMG5_SAFE_FREE(size);return 0); + npointSols = 0; + ncellSols = 0; for (k=0; knsols; ++k ) { (*sol)[k].ver = 2; + + if ( ((*sol)[k].entities==MMG5_Noentity) || ((*sol)[k].entities==MMG5_Vertex) ) { + ++npointSols; + } + else if ( (*sol)[k].entities == MMG5_Triangle ) { + ++ncellSols; + } + else { + printf("\n ## Warning: %s: unexpected entity type for solution %d: %s." + "\n Ignored.\n", + __func__,k,MMG5_Get_entitiesName((*sol)[k].entities)); + } + type[k] = (*sol)[k].type; size[k] = (*sol)[k].size; + entities[k] = (*sol)[k].entities; } - ier = MMG5_saveSolHeader( mesh,filename,&inm,(*sol)[0].ver,&bin,mesh->np, - (*sol)[0].dim,mesh->nsols,type,size); + bpos = 0; + ier = MMG5_saveSolHeader( mesh,filename,&inm,(*sol)[0].ver,&bin,&bpos,mesh->np, + (*sol)[0].dim,mesh->nsols,entities,type,size); - MMG5_SAFE_FREE(type); - MMG5_SAFE_FREE(size); if ( ier < 1 ) return ier; @@ -1567,11 +1585,34 @@ int MMG2D_saveAllSols(MMG5_pMesh mesh,MMG5_pSol *sol,const char *filename) { for ( j=0; jnsols; ++j ) { psl = *sol + j; - MMG2D_writeDoubleSol(psl,inm,bin,k); + + if ( (psl->entities==MMG5_Noentity) || (psl->entities==MMG5_Vertex) ) { + MMG2D_writeDoubleSol(psl,inm,bin,k); + } } fprintf(inm,"\n"); } + MMG5_saveSolAtTrianglesHeader( mesh,inm,(*sol)[0].ver,bin,&bpos,mesh->nsols, + ncellSols,entities,type,size ); + + for (k=1; k<=mesh->nt; k++) { + MMG5_pTria ptt = &mesh->tria[k]; + if ( !MG_EOK(ptt) ) continue; + + for ( j=0; jnsols; ++j ) { + psl = *sol + j; + if ( psl->entities==MMG5_Triangle ) { + MMG2D_writeDoubleSol(psl,inm,bin,k); + } + } + fprintf(inm,"\n"); + } + + MMG5_SAFE_FREE(type); + MMG5_SAFE_FREE(size); + MMG5_SAFE_FREE(entities); + /* End file */ if ( !bin ) { fprintf(inm,"\n\nEnd\n"); diff --git a/src/mmg3d/inout_3d.c b/src/mmg3d/inout_3d.c index c075beb2a..9d68f5525 100644 --- a/src/mmg3d/inout_3d.c +++ b/src/mmg3d/inout_3d.c @@ -2268,7 +2268,7 @@ int MMG3D_loadAllSols(MMG5_pMesh mesh,MMG5_pSol *sol, const char *filename) { int MMG3D_saveSol(MMG5_pMesh mesh,MMG5_pSol met, const char *filename) { FILE* inm; MMG5_pPoint ppt; - int binch,bin,ier,k; + int binch,bpos,bin,ier,k; if ( !met->m ) { fprintf(stderr,"\n ## Warning: %s: no metric data to save.\n",__func__); @@ -2277,8 +2277,9 @@ int MMG3D_saveSol(MMG5_pMesh mesh,MMG5_pSol met, const char *filename) { met->ver = 2; - ier = MMG5_saveSolHeader( mesh,filename,&inm,met->ver,&bin,mesh->np,met->dim, - 1,&met->type,&met->size); + bpos = 0; + ier = MMG5_saveSolHeader( mesh,filename,&inm,met->ver,&bin,&bpos,mesh->np, + met->dim,1,&met->entities,&met->type,&met->size); if ( ier < 1 ) return ier; @@ -2305,8 +2306,9 @@ int MMG3D_saveAllSols(MMG5_pMesh mesh,MMG5_pSol *sol, const char *filename) { MMG5_pSol psl; FILE* inm; MMG5_pPoint ppt; - int binch,bin,ier,k,j; - int *type,*size; + MMG5_pTetra pt; + int binch,bpos,bin,ier,k,j,npointSols,ncellSols; + int *type,*size,*entities; if ( !(*sol)[0].m ) return -1; @@ -2314,16 +2316,31 @@ int MMG3D_saveAllSols(MMG5_pMesh mesh,MMG5_pSol *sol, const char *filename) { MMG5_SAFE_CALLOC(type,mesh->nsols,int,return 0); MMG5_SAFE_CALLOC(size,mesh->nsols,int,MMG5_SAFE_FREE(type);return 0); + MMG5_SAFE_CALLOC(entities,mesh->nsols,int, + MMG5_SAFE_FREE(type);MMG5_SAFE_FREE(size);return 0); + + npointSols = 0; + ncellSols = 0; for (k=0; knsols; ++k ) { - type[k] = (*sol)[k].type; - size[k] = (*sol)[k].size; + if ( ((*sol)[k].entities==MMG5_Noentity) || ((*sol)[k].entities==MMG5_Vertex) ) { + ++npointSols; + } + else if ( (*sol)[k].entities == MMG5_Tetrahedron ) { + ++ncellSols; + } + else { + printf("\n ## Warning: %s: unexpected entity type for solution %d: %s." + "\n Ignored.\n", + __func__,k,MMG5_Get_entitiesName((*sol)[k].entities)); + } + type[k] = (*sol)[k].type; + size[k] = (*sol)[k].size; + entities[k] = (*sol)[k].entities; } - ier = MMG5_saveSolHeader( mesh,filename,&inm,(*sol)[0].ver,&bin,mesh->np, - (*sol)[0].dim,mesh->nsols,type,size); - - MMG5_SAFE_FREE(type); - MMG5_SAFE_FREE(size); + bpos = 0; + ier = MMG5_saveSolHeader( mesh,filename,&inm,(*sol)[0].ver,&bin,&bpos,mesh->np, + (*sol)[0].dim,mesh->nsols,entities,type,size); if ( ier < 1 ) return ier; @@ -2333,11 +2350,35 @@ int MMG3D_saveAllSols(MMG5_pMesh mesh,MMG5_pSol *sol, const char *filename) { for ( j=0; jnsols; ++j ) { psl = *sol+j; - MMG5_writeDoubleSol3D(mesh,psl,inm,bin,k,0); + + if ( (psl->entities==MMG5_Noentity) || (psl->entities==MMG5_Vertex) ) { + MMG5_writeDoubleSol3D(mesh,psl,inm,bin,k,0); + } } fprintf(inm,"\n"); } + MMG5_saveSolAtTetrahedraHeader( mesh,inm,(*sol)[0].ver,bin,&bpos,mesh->nsols, + ncellSols,entities,type,size ); + + for (k=1; k<=mesh->ne; k++) { + pt = &mesh->tetra[k]; + if ( !MG_EOK(pt) ) continue; + + for ( j=0; jnsols; ++j ) { + psl = *sol+j; + if ( psl->entities==MMG5_Tetrahedron ) { + MMG5_writeDoubleSol3D(mesh,psl,inm,bin,k,0); + } + } + fprintf(inm,"\n"); + } + + + MMG5_SAFE_FREE(type); + MMG5_SAFE_FREE(size); + MMG5_SAFE_FREE(entities); + /* End file */ if(!bin) { fprintf(inm,"\n\nEnd\n"); diff --git a/src/mmgs/inout_s.c b/src/mmgs/inout_s.c index 3dd5f5cb8..6b1696b82 100644 --- a/src/mmgs/inout_s.c +++ b/src/mmgs/inout_s.c @@ -1451,7 +1451,7 @@ int MMGS_loadAllSols(MMG5_pMesh mesh,MMG5_pSol *sol, const char *filename) { int MMGS_saveSol(MMG5_pMesh mesh,MMG5_pSol met, const char *filename) { FILE* inm; MMG5_pPoint ppt; - int binch,bin,ier,k; + int binch,bpos,bin,ier,k; if ( !met->m ) { fprintf(stderr,"\n ## Warning: %s: no metric data to save.\n",__func__); @@ -1459,9 +1459,9 @@ int MMGS_saveSol(MMG5_pMesh mesh,MMG5_pSol met, const char *filename) { } met->ver = 2; - - ier = MMG5_saveSolHeader( mesh,filename,&inm,met->ver,&bin,mesh->np,met->dim, - 1,&met->type,&met->size); + bpos = 0; + ier = MMG5_saveSolHeader( mesh,filename,&inm,met->ver,&bin,&bpos,mesh->np,met->dim, + 1,&met->entities,&met->type,&met->size); if ( ier < 1 ) return ier; @@ -1488,39 +1488,79 @@ int MMGS_saveAllSols(MMG5_pMesh mesh,MMG5_pSol *sol, const char *filename) { MMG5_pSol psl; FILE* inm; MMG5_pPoint ppt; - int binch,bin,ier,k,j; - int *type,*size; + int binch,bpos,bin,ier,k,j,npointSols,ncellSols; + int *type,*size,*entities; if ( !(*sol)[0].m ) return -1; (*sol)[0].ver = 2; MMG5_SAFE_CALLOC(type,mesh->nsols,int,return 0); - MMG5_SAFE_CALLOC(size,mesh->nsols,int,return 0); + MMG5_SAFE_CALLOC(size,mesh->nsols,int,MMG5_SAFE_FREE(type);return 0); + MMG5_SAFE_CALLOC(entities,mesh->nsols,int, + MMG5_SAFE_FREE(type);MMG5_SAFE_FREE(size);return 0); + + npointSols = 0; + ncellSols = 0; for (k=0; knsols; ++k ) { + + if ( ((*sol)[k].entities==MMG5_Noentity) || ((*sol)[k].entities==MMG5_Vertex) ) { + ++npointSols; + } + else if ( (*sol)[k].entities == MMG5_Triangle ) { + ++ncellSols; + } + else { + printf("\n ## Warning: %s: unexpected entity type for solution %d: %s." + "\n Ignored.\n", + __func__,k,MMG5_Get_entitiesName((*sol)[k].entities)); + } + type[k] = (*sol)[k].type; size[k] = (*sol)[k].size; + entities[k] = (*sol)[k].entities; } - ier = MMG5_saveSolHeader( mesh,filename,&inm,(*sol)[0].ver,&bin,mesh->np, - (*sol)[0].dim,mesh->nsols,type,size); - - MMG5_SAFE_FREE(type); - MMG5_SAFE_FREE(size); + bpos = 0; + ier = MMG5_saveSolHeader( mesh,filename,&inm,(*sol)[0].ver,&bin,&bpos,mesh->np, + (*sol)[0].dim,mesh->nsols,entities,type,size); if ( ier < 1 ) return ier; for (k=1; k<=mesh->np; k++) { ppt = &mesh->point[k]; - if ( !MG_VOK(ppt) ) continue; + if ( !MG_VOK(ppt) ) continue; + + for ( j=0; jnsols; ++j ) { + psl = *sol + j; + + if ( (psl->entities==MMG5_Noentity) || (psl->entities==MMG5_Vertex) ) { + MMG5_writeDoubleSol3D(mesh,psl,inm,bin,k,0); + } + } + fprintf(inm,"\n"); + } + + MMG5_saveSolAtTrianglesHeader( mesh,inm,(*sol)[0].ver,bin,&bpos,mesh->nsols, + ncellSols,entities,type,size ); + + for (k=1; k<=mesh->nt; k++) { + MMG5_pTria ptt = &mesh->tria[k]; + if ( !MG_EOK(ptt) ) continue; for ( j=0; jnsols; ++j ) { - psl = *sol+j; - MMG5_writeDoubleSol3D(mesh,psl,inm,bin,k,0); + psl = *sol + j; + if ( psl->entities==MMG5_Triangle ) { + MMG5_writeDoubleSol3D(mesh,psl,inm,bin,k,0); + } } fprintf(inm,"\n"); } + MMG5_SAFE_FREE(type); + MMG5_SAFE_FREE(size); + MMG5_SAFE_FREE(entities); + /* End file */ if(!bin) { fprintf(inm,"\n\nEnd\n"); From dba266bdd4487ca378fb5e63d2f8937053fe2be4 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 27 Oct 2020 13:02:51 +0100 Subject: [PATCH 006/170] Remove index error in vtk reader. --- src/common/vtkparser.cpp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/common/vtkparser.cpp b/src/common/vtkparser.cpp index b1c04c781..a938ea44e 100644 --- a/src/common/vtkparser.cpp +++ b/src/common/vtkparser.cpp @@ -615,6 +615,7 @@ int MMG5_loadVtkMesh_part2(MMG5_pMesh mesh,MMG5_pSol *sol,vtkDataSet **dataset, psl->dim = mesh->dim; psl->type = 1; + int isol = 0; if ( nsols ) { auto *pd = (*dataset)->GetPointData(); @@ -623,8 +624,7 @@ int MMG5_loadVtkMesh_part2(MMG5_pMesh mesh,MMG5_pSol *sol,vtkDataSet **dataset, if ( pd ) { int npointData = pd->GetNumberOfArrays(); - int isol = 0; - for (int k = 0; k < npointData; k++) { + for (int j = 0; j < npointData; j++) { psl = *sol + isol; psl->ver = mesh->ver; psl->dim = mesh->dim; @@ -634,7 +634,7 @@ int MMG5_loadVtkMesh_part2(MMG5_pMesh mesh,MMG5_pSol *sol,vtkDataSet **dataset, char *ptr = NULL; bool metricData = 0; char chaine[MMG5_FILESTR_LGTH]; - strcpy(chaine,pd->GetArrayName(k)); + strcpy(chaine,pd->GetArrayName(j)); if ( strstr(chaine,"medit:ref" ) ) { continue; @@ -652,7 +652,7 @@ int MMG5_loadVtkMesh_part2(MMG5_pMesh mesh,MMG5_pSol *sol,vtkDataSet **dataset, } } - auto ar = pd->GetArray(k); + auto ar = pd->GetArray(j); psl->np = ar->GetNumberOfTuples(); if ( mesh->np != psl->np ) { @@ -699,7 +699,7 @@ int MMG5_loadVtkMesh_part2(MMG5_pMesh mesh,MMG5_pSol *sol,vtkDataSet **dataset, switch ( psl->type ) { case ( 1 ): case ( 2 ): - for (k=1; k<=psl->np; k++) { + for (int k=1; k<=psl->np; k++) { int iadr = k*psl->size; ar->GetTuple ( k-1, &psl->m[iadr] ); } @@ -709,7 +709,7 @@ int MMG5_loadVtkMesh_part2(MMG5_pMesh mesh,MMG5_pSol *sol,vtkDataSet **dataset, // anisotropic sol double dbuf[9]; - for (k=1; k<=psl->np; k++) { + for (int k=1; k<=psl->np; k++) { ar->GetTuple ( k-1, dbuf ); int iadr = psl->size*k; @@ -762,8 +762,7 @@ int MMG5_loadVtkMesh_part2(MMG5_pMesh mesh,MMG5_pSol *sol,vtkDataSet **dataset, if ( cd ) { int ncellData = cd->GetNumberOfArrays(); - int isol = 0; - for (int k = 0; k < ncellData; k++) { + for (int j = 0; j < ncellData; j++) { psl = *sol + isol; psl->ver = mesh->ver; psl->dim = mesh->dim; @@ -772,7 +771,7 @@ int MMG5_loadVtkMesh_part2(MMG5_pMesh mesh,MMG5_pSol *sol,vtkDataSet **dataset, char *ptr = NULL; char chaine[MMG5_FILESTR_LGTH]; - strcpy(chaine,pd->GetArrayName(k)); + strcpy(chaine,pd->GetArrayName(j)); if ( strstr(chaine,"medit:ref" ) ) { continue; @@ -786,7 +785,7 @@ int MMG5_loadVtkMesh_part2(MMG5_pMesh mesh,MMG5_pSol *sol,vtkDataSet **dataset, } } - auto ar = cd->GetArray(k); + auto ar = cd->GetArray(j); psl->np = ar->GetNumberOfTuples(); if ( mesh->ne != psl->np ) { @@ -808,7 +807,7 @@ int MMG5_loadVtkMesh_part2(MMG5_pMesh mesh,MMG5_pSol *sol,vtkDataSet **dataset, psl->type = 2; } else if ( ncp == (mesh->dim * mesh->dim) ) { - psl->size = (psl->dim*(psl->dim+1))/2; + psl->size = ncp; psl->type = 3; } else { @@ -827,7 +826,7 @@ int MMG5_loadVtkMesh_part2(MMG5_pMesh mesh,MMG5_pSol *sol,vtkDataSet **dataset, switch ( psl->type ) { case ( 1 ): case ( 2 ): - for (k=1; k<=psl->np; k++) { + for (int k=1; k<=psl->np; k++) { int iadr = k*psl->size; ar->GetTuple ( k-1, &psl->m[iadr] ); } @@ -837,7 +836,7 @@ int MMG5_loadVtkMesh_part2(MMG5_pMesh mesh,MMG5_pSol *sol,vtkDataSet **dataset, // anisotropic sol double dbuf[9]; - for (k=1; k<=psl->np; k++) { + for (int k=1; k<=psl->np; k++) { ar->GetTuple ( k-1, dbuf ); int iadr = psl->size*k; From aacd246766a4d1c3be462f29c11f4a9edb05e376 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 27 Oct 2020 13:56:22 +0100 Subject: [PATCH 007/170] Patch error in the previous commit. --- src/common/vtkparser.cpp | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/common/vtkparser.cpp b/src/common/vtkparser.cpp index a938ea44e..bc976adbc 100644 --- a/src/common/vtkparser.cpp +++ b/src/common/vtkparser.cpp @@ -195,16 +195,7 @@ int MMG5_count_vtkEntities ( vtkDataSet *dataset, MMG5_pMesh mesh, *eltMeditRef = k; ++ncellRef; } - // else { - // printf( " ## Warning:%s: %s VTK cell data used" - // " only to assign reference to cells (cell data labelled 'medit:ref')." - // " Cell data ignored.\n",__func__,cd->GetArrayName(k)); - // } } - // if ( ncellRef > 1 ) { - // printf( " ## Warning:%s: %d reference fields detected (labelled 'medit:ref')." - // " Only the first is used, others are ignored.\n",__func__,ncellRef); - // } } // Count the number of field data @@ -754,7 +745,6 @@ int MMG5_loadVtkMesh_part2(MMG5_pMesh mesh,MMG5_pSol *sol,vtkDataSet **dataset, fprintf(stderr," ** UNEXPECTED METRIC TYPE (%d). EXIT PROGRAM \n",psl->type); return -1; } - ++isol; } } @@ -771,7 +761,7 @@ int MMG5_loadVtkMesh_part2(MMG5_pMesh mesh,MMG5_pSol *sol,vtkDataSet **dataset, char *ptr = NULL; char chaine[MMG5_FILESTR_LGTH]; - strcpy(chaine,pd->GetArrayName(j)); + strcpy(chaine,cd->GetArrayName(j)); if ( strstr(chaine,"medit:ref" ) ) { continue; @@ -789,8 +779,8 @@ int MMG5_loadVtkMesh_part2(MMG5_pMesh mesh,MMG5_pSol *sol,vtkDataSet **dataset, psl->np = ar->GetNumberOfTuples(); if ( mesh->ne != psl->np ) { - fprintf(stderr," ** MISMATCHES DATA: THE NUMBER OF VERTICES IN " - "THE MESH (%d) DIFFERS FROM THE NUMBER OF VERTICES IN " + fprintf(stderr," ** MISMATCHES DATA: THE NUMBER OF ELEMENTS IN " + "THE MESH (%d) DIFFERS FROM THE NUMBER OF CELLS DATA IN " "THE SOLUTION (%d) \n",mesh->ne,psl->np); return -1; } From c38159b27f04c88354f9247a912c337f0b4b2326 Mon Sep 17 00:00:00 2001 From: Algiane Date: Wed, 28 Oct 2020 16:35:33 +0100 Subject: [PATCH 008/170] Add paths suffixes to FindMMG*.cmake files. --- cmake/tools/FindMMG.cmake | 6 ++++-- cmake/tools/FindMMG2D.cmake | 2 +- cmake/tools/FindMMG3D.cmake | 2 +- cmake/tools/FindMMGS.cmake | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/cmake/tools/FindMMG.cmake b/cmake/tools/FindMMG.cmake index e2f8a3572..d4dfb2d66 100644 --- a/cmake/tools/FindMMG.cmake +++ b/cmake/tools/FindMMG.cmake @@ -122,7 +122,8 @@ if(MMG_INCDIR) find_path(MMG_libmmgtypes.h_DIRS NAMES libmmgtypes.h HINTS ${MMG_INCDIR} - PATH_SUFFIXES "mmg2d" "mmgs" "mmg3d") + PATH_SUFFIXES "mmg" "mmg/mmg2d" "mmg/mmgs" "mmg/mmg3d" "mmg2d" + "mmgs" "mmg3d") elseif(MMG_BUILDDIR) set(MMG_libmmgtypes.h_DIRS "MMG_libmmgtypes.h_DIRS-NOTFOUND") find_path(MMG_libmmgtypes.h_DIRS @@ -152,7 +153,8 @@ else() find_path(MMG_libmmgtypes.h_DIRS NAMES libmmgtypes.h HINTS ${_inc_env} - PATH_SUFFIXES "include/mmg" "include/mmg/mmg") + PATH_SUFFIXES "mmg" "mmg/mmg2d" "mmg/mmgs" "mmg/mmg3d" "mmg2d" + "mmgs" "mmg3d") endif() endif() STRING(REGEX REPLACE "(mmg/mmg2d)|(mmg/mmgs)|(mmg/mmg3d)" "" diff --git a/cmake/tools/FindMMG2D.cmake b/cmake/tools/FindMMG2D.cmake index 7cb79b449..67adc47f8 100644 --- a/cmake/tools/FindMMG2D.cmake +++ b/cmake/tools/FindMMG2D.cmake @@ -122,7 +122,7 @@ if(MMG_INCDIR) find_path(MMG2D_libmmgtypes.h_DIRS NAMES libmmgtypes.h HINTS ${MMG_INCDIR} - PATH_SUFFIXES "mmg2d") + PATH_SUFFIXES "mmg/mmg2d" "mmg2d") elseif(MMG_BUILDDIR) set(MMG2D_libmmgtypes.h_DIRS "MMG2D_libmmgtypes.h_DIRS-NOTFOUND") find_path(MMG2D_libmmgtypes.h_DIRS diff --git a/cmake/tools/FindMMG3D.cmake b/cmake/tools/FindMMG3D.cmake index 888fd126d..1f6256b91 100644 --- a/cmake/tools/FindMMG3D.cmake +++ b/cmake/tools/FindMMG3D.cmake @@ -122,7 +122,7 @@ if(MMG_INCDIR) find_path(MMG3D_libmmgtypes.h_DIRS NAMES libmmgtypes.h HINTS ${MMG_INCDIR} - PATH_SUFFIXES "mmg3d") + PATH_SUFFIXES "mmg/mmg3d" "mmg3d") elseif(MMG_BUILDDIR) set(MMG3D_libmmgtypes.h_DIRS "MMG3D_libmmgtypes.h_DIRS-NOTFOUND") find_path(MMG3D_libmmgtypes.h_DIRS diff --git a/cmake/tools/FindMMGS.cmake b/cmake/tools/FindMMGS.cmake index 0062718e9..f8fe09b12 100644 --- a/cmake/tools/FindMMGS.cmake +++ b/cmake/tools/FindMMGS.cmake @@ -122,7 +122,7 @@ if(MMG_INCDIR) find_path(MMGS_libmmgtypes.h_DIRS NAMES libmmgtypes.h HINTS ${MMG_INCDIR} - PATH_SUFFIXES "mmgs") + PATH_SUFFIXES "mmg/mmgs" "mmgs") elseif(MMG_BUILDDIR) set(MMGS_libmmgtypes.h_DIRS "MMGS_libmmgtypes.h_DIRS-NOTFOUND") find_path(MMGS_libmmgtypes.h_DIRS From 1d3278c35fdc7e44ab6d39aae0dea5613c9e3d62 Mon Sep 17 00:00:00 2001 From: Algiane Date: Wed, 28 Oct 2020 19:37:01 +0100 Subject: [PATCH 009/170] Remove a possible NaN creation (when testing a flat element) in cenrad_iso. --- src/mmg3d/cenrad_3d.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/mmg3d/cenrad_3d.c b/src/mmg3d/cenrad_3d.c index e43e762fa..cc13bf6e7 100644 --- a/src/mmg3d/cenrad_3d.c +++ b/src/mmg3d/cenrad_3d.c @@ -55,7 +55,11 @@ int MMG5_cenrad_iso(MMG5_pMesh mesh,double *ct,double *c,double *rad) { uy = c4[1] - c1[1]; uz = c4[2] - c1[2]; - dd = 1.0 / sqrt(ux*ux + uy*uy + uz*uz); + dd = ux*ux + uy*uy + uz*uz; + if ( dd < MMG5_EPSD2 ) return 0; + + dd = 1.0 / sqrt(dd); + n1[0] = ux*dd; n1[1] = uy*dd; n1[2] = uz*dd; @@ -68,7 +72,11 @@ int MMG5_cenrad_iso(MMG5_pMesh mesh,double *ct,double *c,double *rad) { uy = c4[1] - c2[1]; uz = c4[2] - c2[2]; - dd = 1.0 / sqrt(ux*ux + uy*uy + uz*uz); + dd = ux*ux + uy*uy + uz*uz; + if ( dd < MMG5_EPSD2 ) return 0; + + dd = 1.0 / sqrt(dd); + n2[0] = ux*dd; n2[1] = uy*dd; n2[2] = uz*dd; @@ -79,7 +87,11 @@ int MMG5_cenrad_iso(MMG5_pMesh mesh,double *ct,double *c,double *rad) { uy = c4[1] - c3[1]; uz = c4[2] - c3[2]; - dd = 1.0 / sqrt(ux*ux + uy*uy + uz*uz); + dd = ux*ux + uy*uy + uz*uz; + if ( dd < MMG5_EPSD2 ) return 0; + + dd = 1.0 / sqrt(dd); + n3[0] = ux*dd; n3[1] = uy*dd; n3[2] = uz*dd; From 57c941e19fcdee8c992b91239d65dbb66355b697 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 3 Nov 2020 16:40:27 +0100 Subject: [PATCH 010/170] Comment too long nightly test. --- cmake/testing/mmg3d_tests.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/testing/mmg3d_tests.cmake b/cmake/testing/mmg3d_tests.cmake index c9b08b2b1..28ec7769c 100644 --- a/cmake/testing/mmg3d_tests.cmake +++ b/cmake/testing/mmg3d_tests.cmake @@ -92,7 +92,7 @@ IF ( LONG_TESTS ) mmg3d_CubeSkin0.2_Inside0.4 mmg3d_CubeSkin0.0125_Inside0.125 mmg3d_CubeSkin0.0125_Inside0.25 - mmg3d_CubeSkin0.0125_Inside0.5 + # mmg3d_CubeSkin0.0125_Inside0.5 # Check results on various meshes # First: Meshes that we want unrefined mmg3d_Various_unref_Linkrods_met0.2 @@ -144,7 +144,7 @@ IF ( LONG_TESTS ) ${MMG3D_CI_TESTS}/CubeSkin0.2_Inside0.4/CubeSkin0.2 ${MMG3D_CI_TESTS}/CubeSkin0.0125_Inside0.125/CubeSkin0.125 ${MMG3D_CI_TESTS}/CubeSkin0.0125_Inside0.25/CubeSkin0.25 - ${MMG3D_CI_TESTS}/CubeSkin0.0125_Inside0.5/CubeSkin0.5 + # ${MMG3D_CI_TESTS}/CubeSkin0.0125_Inside0.5/CubeSkin0.5 ### Linkrods ${MMG3D_CI_TESTS}/Various_unref_Linkrods_met0.2/linkrods ${MMG3D_CI_TESTS}/Various_unref_Linkrods_met0.2_hausd0.01/linkrods @@ -193,7 +193,7 @@ IF ( LONG_TESTS ) "-v 5" "-v 5" "-v 5" - "-v 5" + # "-v 5" ### Linkrods "-v 5 -hausd 0.1" "-v 5 -hausd 0.01" From 504d4dc4d0109290b60f8ca81084a1a866da867f Mon Sep 17 00:00:00 2001 From: luca Date: Sun, 15 Nov 2020 16:09:50 +0100 Subject: [PATCH 011/170] Patch reallocation of disp->m structure (without changing MMG3D_POINT_REALLOC for now). --- src/mmg3d/mmg3d3.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/mmg3d/mmg3d3.c b/src/mmg3d/mmg3d3.c index b64abdfdf..30628b00b 100644 --- a/src/mmg3d/mmg3d3.c +++ b/src/mmg3d/mmg3d3.c @@ -185,7 +185,28 @@ static int MMG5_spllag(MMG5_pMesh mesh,MMG5_pSol disp,MMG5_pSol met,int itdeg, i if ( !ip ) { /* reallocation of point table */ + int oldnpmax = mesh->npmax; MMG3D_POINT_REALLOC(mesh,met,ip,mesh->gap,*warn=1;break,o,MG_NOTAG,src); + if( disp->m ) { + MMG5_ADD_MEM(mesh,(disp->size*(mesh->npmax-disp->npmax))*sizeof(double), + "larger solution", + MMG5_SAFE_RECALLOC(mesh->point,mesh->npmax+1,oldnpmax+1,MMG5_Point,,); + mesh->memCur -= (mesh->npmax - oldnpmax)*sizeof(MMG5_Point); + mesh->npmax = oldnpmax; + mesh->np = mesh->npmax-1; + mesh->npnil = 0; + break); + MMG5_SAFE_REALLOC(disp->m,disp->size*(disp->npmax+1), + disp->size*(mesh->npmax+1), + double,"larger displacement", + MMG5_SAFE_RECALLOC(mesh->point,mesh->npmax+1,oldnpmax+1,MMG5_Point,,); + mesh->memCur -= (mesh->npmax - oldnpmax)*sizeof(MMG5_Point); + mesh->npmax = oldnpmax; + mesh->np = mesh->npmax-1; + mesh->npnil = 0; + break); + } + disp->npmax = mesh->npmax; } /* Interpolation of metric, if any */ From 73ae8fe7ee9a8781ebd96b55aab13e09b893db7f Mon Sep 17 00:00:00 2001 From: luca Date: Sun, 15 Nov 2020 16:13:10 +0100 Subject: [PATCH 012/170] Fix wrong split on boundary edges referred by a tetra with no faces on the boundary. --- src/mmg3d/mmg3d3.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mmg3d/mmg3d3.c b/src/mmg3d/mmg3d3.c index 30628b00b..4a9ab87a6 100644 --- a/src/mmg3d/mmg3d3.c +++ b/src/mmg3d/mmg3d3.c @@ -133,6 +133,7 @@ static int MMG5_spllag(MMG5_pMesh mesh,MMG5_pSol disp,MMG5_pSol met,int itdeg, i /* Skip the non-internal edges */ if ( pxt && (pxt->tag[i] & MG_BDY) ) continue; + if( (p0->tag & MG_BDY) && (p1->tag & MG_BDY) ) continue; len = (p1->c[0]-p0->c[0])*(p1->c[0]-p0->c[0]) + (p1->c[1]-p0->c[1])*(p1->c[1]-p0->c[1]) From 1a5d610a4ad1b98f84c8b53d672291af937234c1 Mon Sep 17 00:00:00 2001 From: luca Date: Mon, 16 Nov 2020 15:09:04 +0100 Subject: [PATCH 013/170] Comments. --- src/mmg3d/mmg3d3.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mmg3d/mmg3d3.c b/src/mmg3d/mmg3d3.c index 4a9ab87a6..e50bbfd62 100644 --- a/src/mmg3d/mmg3d3.c +++ b/src/mmg3d/mmg3d3.c @@ -133,6 +133,8 @@ static int MMG5_spllag(MMG5_pMesh mesh,MMG5_pSol disp,MMG5_pSol met,int itdeg, i /* Skip the non-internal edges */ if ( pxt && (pxt->tag[i] & MG_BDY) ) continue; + /* Skip boundary edges - WARNING: This also skips edges connecting two + * boundary points. */ if( (p0->tag & MG_BDY) && (p1->tag & MG_BDY) ) continue; len = (p1->c[0]-p0->c[0])*(p1->c[0]-p0->c[0]) From b736949114195205bdd34eb7d1d9d316edc332fa Mon Sep 17 00:00:00 2001 From: luca Date: Mon, 16 Nov 2020 15:11:51 +0100 Subject: [PATCH 014/170] Fix verbosity. --- src/mmg2d/mmg2d9.c | 2 +- src/mmg3d/mmg3d3.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mmg2d/mmg2d9.c b/src/mmg2d/mmg2d9.c index e0e3ab9e8..0b6c4e8f4 100644 --- a/src/mmg2d/mmg2d9.c +++ b/src/mmg2d/mmg2d9.c @@ -698,7 +698,7 @@ int MMG2D_mmg2d9(MMG5_pMesh mesh,MMG5_pSol disp,MMG5_pSol met,int **invalidTrias if ( t == MMG2D_SHORTMAX ) break; } - if ( mesh->info.imprim > 0 && abs(mesh->info.imprim) < 4 ) { + if ( mesh->info.imprim > 1 && abs(mesh->info.imprim) < 4 ) { printf(" ---> Realized displacement: %f\n",tau); } if ( abs(mesh->info.imprim) > 2 && mesh->info.lag ) diff --git a/src/mmg3d/mmg3d3.c b/src/mmg3d/mmg3d3.c index e50bbfd62..33b04db60 100644 --- a/src/mmg3d/mmg3d3.c +++ b/src/mmg3d/mmg3d3.c @@ -773,7 +773,7 @@ int MMG5_mmg3d3(MMG5_pMesh mesh,MMG5_pSol disp,MMG5_pSol met,int **invalidTets) nnnc += nnc; nnns += nns; - if ( (mesh->info.imprim > 0) && (mesh->info.imprim < 4) ) { + if ( (mesh->info.imprim > 1) && (mesh->info.imprim < 4) ) { printf(" ---> Realized displacement: %f\n",tau); } From cdcfe60e3a9fd3587fd70d02840f9041a495f851 Mon Sep 17 00:00:00 2001 From: luca Date: Mon, 16 Nov 2020 15:26:01 +0100 Subject: [PATCH 015/170] Same as in 504d4dc4 for levelset. --- src/mmg3d/mmg3d2.c | 23 +++++++++++++++++++++++ src/mmg3d/mmg3d3.c | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/mmg3d/mmg3d2.c b/src/mmg3d/mmg3d2.c index cf61f1f1f..a498257ba 100755 --- a/src/mmg3d/mmg3d2.c +++ b/src/mmg3d/mmg3d2.c @@ -1124,12 +1124,35 @@ static int MMG3D_cuttet_ls(MMG5_pMesh mesh, MMG5_pSol sol,MMG5_pSol met){ #endif np = MMG3D_newPt(mesh,c,0,src); if ( !np ) { + int oldnpmax = mesh->npmax; MMG3D_POINT_REALLOC(mesh,sol,np,MMG5_GAP, fprintf(stderr,"\n ## Error: %s: unable to" " allocate a new point\n",__func__); MMG5_INCREASE_MEM_MESSAGE(); return 0 ,c,0,src); + if( met ) { + if( met->m ) { + MMG5_ADD_MEM(mesh,(met->size*(mesh->npmax-met->npmax))*sizeof(double), + "larger solution", + MMG5_SAFE_RECALLOC(mesh->point,mesh->npmax+1,oldnpmax+1,MMG5_Point,,); + mesh->memCur -= (mesh->npmax - oldnpmax)*sizeof(MMG5_Point); + mesh->npmax = oldnpmax; + mesh->np = mesh->npmax-1; + mesh->npnil = 0; + return 0); + MMG5_SAFE_REALLOC(met->m,met->size*(met->npmax+1), + met->size*(mesh->npmax+1), + double,"larger solution", + MMG5_SAFE_RECALLOC(mesh->point,mesh->npmax+1,oldnpmax+1,MMG5_Point,,); + mesh->memCur -= (mesh->npmax - oldnpmax)*sizeof(MMG5_Point); + mesh->npmax = oldnpmax; + mesh->np = mesh->npmax-1; + mesh->npnil = 0; + return 0); + } + met->npmax = mesh->npmax; + } } sol->m[np] = mesh->info.ls; /* If user provide a metric, interpolate it at the new point */ diff --git a/src/mmg3d/mmg3d3.c b/src/mmg3d/mmg3d3.c index 33b04db60..31a33da30 100644 --- a/src/mmg3d/mmg3d3.c +++ b/src/mmg3d/mmg3d3.c @@ -192,7 +192,7 @@ static int MMG5_spllag(MMG5_pMesh mesh,MMG5_pSol disp,MMG5_pSol met,int itdeg, i MMG3D_POINT_REALLOC(mesh,met,ip,mesh->gap,*warn=1;break,o,MG_NOTAG,src); if( disp->m ) { MMG5_ADD_MEM(mesh,(disp->size*(mesh->npmax-disp->npmax))*sizeof(double), - "larger solution", + "larger displacement", MMG5_SAFE_RECALLOC(mesh->point,mesh->npmax+1,oldnpmax+1,MMG5_Point,,); mesh->memCur -= (mesh->npmax - oldnpmax)*sizeof(MMG5_Point); mesh->npmax = oldnpmax; From 4cb148ee76c29ac24501917109d87ac03bc8ab22 Mon Sep 17 00:00:00 2001 From: luca Date: Mon, 16 Nov 2020 21:46:23 +0100 Subject: [PATCH 016/170] Fix usage of Scotch in Lagrangian motion 3D: permute displacement field (but remember it is nullified after Lagrangian step). --- src/common/librnbg.c | 37 ++++++++++++++++++++++++++----------- src/mmg3d/libmmg3d.c | 8 ++++---- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/src/common/librnbg.c b/src/common/librnbg.c index e203eb248..803721c85 100644 --- a/src/common/librnbg.c +++ b/src/common/librnbg.c @@ -177,17 +177,32 @@ void MMG5_swapNod(MMG5_pMesh mesh,MMG5_pPoint points, double* sols, /* swap solution fields (for ParMmg) */ if ( field ) { - for ( i=0; insols; ++i ) { - psl = field+i; - assert ( psl && psl->m ); - - pslsiz = psl->size; - addr1 = ind1*pslsiz; - addr2 = ind2*pslsiz; - - memcpy(&soltmp , psl->m + addr2,pslsiz*sizeof(double)); - memcpy(psl->m + addr2, psl->m + addr1,pslsiz*sizeof(double)); - memcpy(psl->m + addr1, &soltmp ,pslsiz*sizeof(double)); + if( mesh->nsols ) { /* swap solution fields (for ParMmg) */ + for ( i=0; insols; ++i ) { + psl = field+i; + assert ( psl && psl->m ); + + pslsiz = psl->size; + addr1 = ind1*pslsiz; + addr2 = ind2*pslsiz; + + memcpy(&soltmp , psl->m + addr2,pslsiz*sizeof(double)); + memcpy(psl->m + addr2, psl->m + addr1,pslsiz*sizeof(double)); + memcpy(psl->m + addr1, &soltmp ,pslsiz*sizeof(double)); + } + } else { /* swap a single displacement field (for Lagrangian motion) */ + psl = field; + assert ( psl ); + + if( psl->m ) { /* it is null after Lagrangian step */ + pslsiz = psl->size; + addr1 = ind1*pslsiz; + addr2 = ind2*pslsiz; + + memcpy(&soltmp , psl->m + addr2,pslsiz*sizeof(double)); + memcpy(psl->m + addr2, psl->m + addr1,pslsiz*sizeof(double)); + memcpy(psl->m + addr1, &soltmp ,pslsiz*sizeof(double)); + } } } diff --git a/src/mmg3d/libmmg3d.c b/src/mmg3d/libmmg3d.c index e1923cf95..9a9ed83ec 100644 --- a/src/mmg3d/libmmg3d.c +++ b/src/mmg3d/libmmg3d.c @@ -1625,7 +1625,7 @@ int MMG3D_mmg3dmov(MMG5_pMesh mesh,MMG5_pSol met, MMG5_pSol disp) { } /* renumerotation if available */ - if ( !MMG5_scotchCall(mesh,met,NULL,NULL) ) + if ( !MMG5_scotchCall(mesh,met,disp,NULL) ) { if ( !MMG5_unscaleMesh(mesh,met,disp) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); MMG5_RETURN_AND_PACK(mesh,met,disp,MMG5_LOWFAILURE); @@ -1674,7 +1674,7 @@ int MMG3D_mmg3dmov(MMG5_pMesh mesh,MMG5_pSol met, MMG5_pSol disp) { } /* renumerotation if available */ - if ( !MMG5_scotchCall(mesh,met,NULL,NULL) ) + if ( !MMG5_scotchCall(mesh,met,disp,NULL) ) { if ( !MMG5_unscaleMesh(mesh,met,disp) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); MMG5_RETURN_AND_PACK(mesh,met,disp,MMG5_LOWFAILURE); @@ -1708,9 +1708,9 @@ int MMG3D_mmg3dmov(MMG5_pMesh mesh,MMG5_pSol met, MMG5_pSol disp) { } /* last renum to give back a good numbering to the user */ - if ( !MMG5_scotchCall(mesh,met,NULL,NULL) ) + if ( !MMG5_scotchCall(mesh,met,disp,NULL) ) { - if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); + if ( !MMG5_unscaleMesh(mesh,met,disp) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); MMG5_RETURN_AND_PACK(mesh,met,disp,MMG5_LOWFAILURE); } From 50d5da2a94dda471b6b269e98d40ee62b888f4da Mon Sep 17 00:00:00 2001 From: Algiane Date: Fri, 20 Nov 2020 11:12:07 +0100 Subject: [PATCH 017/170] Add continuous integration test cases + try to patch errors in nightly tests. --- CMakeLists.txt | 8 ++++---- cmake/modules/mmg3d.cmake | 7 ++++++- cmake/testing/libmmg3d_tests.cmake | 2 ++ cmake/testing/mmg2d_tests.cmake | 7 +++++++ cmake/testing/mmg3d_tests.cmake | 11 +++++++++-- 5 files changed, 28 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 804952911..f80827b56 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -501,7 +501,7 @@ IF( BUILD_TESTING ) ##------- Get the continuous integration tests ----------------------## ##-------------------------------------------------------------------## INCLUDE(cmake/modules/LoadCiTests.cmake) -ENDIF ( ) + ENDIF ( ) ##-------------------------------------------------------------------## ##------- Set the continuous integration options --------------------## @@ -556,17 +556,17 @@ ENDIF ( ) SET(EXECUT_MMG ${EXECUT_MMGS} ${EXECUT_MMG3D}) # Change authorisations for some files... - IF ( EXISTS ${CTEST_OUTPUT_DIR}/LeakCheck_AbnormalEnd7/unreadable.meshb) + IF ( EXISTS ${CTEST_OUTPUT_DIR}/LeakCheck_AbnormalEnd7/unwrittable.meshb) FILE(REMOVE ${CTEST_OUTPUT_DIR}/LeakCheck_AbnormalEnd7/unwrittable.meshb) ENDIF() FILE(COPY ${MMG_CI_TESTS}/LeakCheck_AbnormalEnd7/dout.mesh - DESTINATION ${CTEST_OUTPUT_DIR}/AbnormalEnd7/unwrittable.meshb) + DESTINATION ${CTEST_OUTPUT_DIR}/LeakCheck_AbnormalEnd7/unwrittable.meshb) IF ( EXISTS ${CTEST_OUTPUT_DIR}/LeakCheck_AbnormalEnd8/unwrittable.sol) FILE(REMOVE ${CTEST_OUTPUT_DIR}/LeakCheck_AbnormalEnd8/unwrittable.sol) ENDIF() FILE(COPY ${MMG_CI_TESTS}/LeakCheck_AbnormalEnd8/dsol.sol - DESTINATION ${CTEST_OUTPUT_DIR}/AbnormalEnd8/unwrittable.sol) + DESTINATION ${CTEST_OUTPUT_DIR}/LeakCheck_AbnormalEnd8/unwrittable.sol) # Add common tests for mmgs/3d appli INCLUDE( ${PROJECT_SOURCE_DIR}/cmake/testing/mmg_tests.cmake ) diff --git a/cmake/modules/mmg3d.cmake b/cmake/modules/mmg3d.cmake index 25ffb7980..88af96cf3 100644 --- a/cmake/modules/mmg3d.cmake +++ b/cmake/modules/mmg3d.cmake @@ -210,6 +210,7 @@ IF ( BUILD_TESTING ) SET(LIBMMG3D_LSANDMETRIC ${EXECUTABLE_OUTPUT_PATH}/libmmg3d_lsAndMetric ) SET(TEST_API3D_EXEC0 ${EXECUTABLE_OUTPUT_PATH}/test_api3d_0) SET(TEST_API3D_DOMSEL ${EXECUTABLE_OUTPUT_PATH}/test_api3d_domain-selection) + SET(TEST_API3D_VTK2MESH ${EXECUTABLE_OUTPUT_PATH}/test_api3d_vtk2mesh) ADD_TEST(NAME libmmg3d_example0_a COMMAND ${LIBMMG3D_EXEC0_a} "${PROJECT_SOURCE_DIR}/libexamples/mmg3d/adaptation_example0/example0_a/cube.mesh" @@ -259,7 +260,11 @@ IF ( BUILD_TESTING ) "${MMG3D_CI_TESTS}/OptLs_plane/p.sol" "${CTEST_OUTPUT_DIR}/test_API3d-domsel-whole.o" "${CTEST_OUTPUT_DIR}/test_API3d-domsel-dom2.o" - ) + ) + ADD_TEST(NAME test_api3d_vtk2mesh COMMAND ${TEST_API3D_VTK2MESH} + "${MMG3D_CI_TESTS}/API_tests/cellsAndNode-data.vtk" + "${CTEST_OUTPUT_DIR}/test_API3d-vtk2mesh.o" + ) IF ( CMAKE_Fortran_COMPILER) SET(LIBMMG3D_EXECFORTRAN_a ${EXECUTABLE_OUTPUT_PATH}/libmmg3d_fortran_a) diff --git a/cmake/testing/libmmg3d_tests.cmake b/cmake/testing/libmmg3d_tests.cmake index ccd59eb57..03fdcbe73 100644 --- a/cmake/testing/libmmg3d_tests.cmake +++ b/cmake/testing/libmmg3d_tests.cmake @@ -37,6 +37,7 @@ SET ( MMG3D_LIB_TESTS libmmg3d_lsAndMetric test_api3d_0 test_api3d_domain-selection + test_api3d_vtk2mesh ) SET ( MMG3D_LIB_TESTS_MAIN_PATH ${PROJECT_SOURCE_DIR}/libexamples/mmg3d/adaptation_example0/example0_a/main.c @@ -49,6 +50,7 @@ SET ( MMG3D_LIB_TESTS_MAIN_PATH ${PROJECT_SOURCE_DIR}/libexamples/mmg3d/IsosurfDiscretization_lsAndMetric/main.c ${MMG3D_CI_TESTS}/API_tests/3d.c ${MMG3D_CI_TESTS}/API_tests/domain-selection.c + ${MMG3D_CI_TESTS}/API_tests/vtk2mesh.c ) IF ( LIBMMG3D_STATIC ) diff --git a/cmake/testing/mmg2d_tests.cmake b/cmake/testing/mmg2d_tests.cmake index e47b8f9f3..5a0ddc1af 100644 --- a/cmake/testing/mmg2d_tests.cmake +++ b/cmake/testing/mmg2d_tests.cmake @@ -506,6 +506,13 @@ ADD_TEST(NAME mmg2d_OptLs_dom_withbub -sol ${MMG2D_CI_TESTS}/LSDiscretization/bub.sol ${CTEST_OUTPUT_DIR}/mmg2d_OptLs_dom-withbub.o.meshb) +# ls + rmc: max pile size bug +ADD_TEST(NAME mmg2d_OptLs_dom_rmcmaxpile + COMMAND ${EXECUT_MMG2D} -v 5 -ls -rmc + ${MMG2D_CI_TESTS}/LSDiscretization/dom + -sol ${MMG2D_CI_TESTS}/LSDiscretization/whole.sol + ${CTEST_OUTPUT_DIR}/mmg2d_OptLs_dom-rmcmaxpile.o.meshb) + ADD_TEST(NAME mmg2d_OptLs_dom_rembub COMMAND ${EXECUT_MMG2D} -v 5 -ls ${MMG2D_CI_TESTS}/LSDiscretization/dom diff --git a/cmake/testing/mmg3d_tests.cmake b/cmake/testing/mmg3d_tests.cmake index 28ec7769c..1df4606ab 100644 --- a/cmake/testing/mmg3d_tests.cmake +++ b/cmake/testing/mmg3d_tests.cmake @@ -91,8 +91,8 @@ IF ( LONG_TESTS ) mmg3d_CubeSkin0.1_Inside0.4 mmg3d_CubeSkin0.2_Inside0.4 mmg3d_CubeSkin0.0125_Inside0.125 - mmg3d_CubeSkin0.0125_Inside0.25 - # mmg3d_CubeSkin0.0125_Inside0.5 + # mmg3d_CubeSkin0.0125_Inside0.25 # too long on OSX + # mmg3d_CubeSkin0.0125_Inside0.5 # too long on all machine # Check results on various meshes # First: Meshes that we want unrefined mmg3d_Various_unref_Linkrods_met0.2 @@ -622,6 +622,13 @@ ADD_TEST(NAME mmg3d_OptLs_plane_withbub -sol ${MMG3D_CI_TESTS}/OptLs_plane/bub.sol ${CTEST_OUTPUT_DIR}/mmg3d_OptLs_plane-withbub.o.meshb) +# ls + rmc: max pile bug +ADD_TEST(NAME mmg3d_OptLs_plane_rmcmaxpile + COMMAND ${EXECUT_MMG3D} -v 5 -ls -rmc + ${MMG3D_CI_TESTS}/OptLs_plane/plane + -sol ${MMG3D_CI_TESTS}/OptLs_plane/whole.sol + ${CTEST_OUTPUT_DIR}/mmg3d_OptLs_plane-rmcmaxpile.o.meshb) + ADD_TEST(NAME mmg3d_OptLs_plane_rembub COMMAND ${EXECUT_MMG3D} -v 5 -ls ${MMG3D_CI_TESTS}/OptLs_plane/plane From f01f2109c111f532325887bb3c006906a83ab6a1 Mon Sep 17 00:00:00 2001 From: Algiane Date: Fri, 20 Nov 2020 11:45:14 +0100 Subject: [PATCH 018/170] Treat the case where we don't link vtk for the new vtk conversion testcase. --- cmake/modules/mmg3d.cmake | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cmake/modules/mmg3d.cmake b/cmake/modules/mmg3d.cmake index 88af96cf3..20e6aab94 100644 --- a/cmake/modules/mmg3d.cmake +++ b/cmake/modules/mmg3d.cmake @@ -266,6 +266,12 @@ IF ( BUILD_TESTING ) "${CTEST_OUTPUT_DIR}/test_API3d-vtk2mesh.o" ) + IF ( NOT VTK_FOUND ) + SET(expr "VTK library not founded") + SET_PROPERTY(TEST test_api3d_vtk2mesh + PROPERTY PASS_REGULAR_EXPRESSION "${expr}") + ENDIF ( ) + IF ( CMAKE_Fortran_COMPILER) SET(LIBMMG3D_EXECFORTRAN_a ${EXECUTABLE_OUTPUT_PATH}/libmmg3d_fortran_a) SET(LIBMMG3D_EXECFORTRAN_b ${EXECUTABLE_OUTPUT_PATH}/libmmg3d_fortran_b) From 4815b62c8d77baf97194275ac05a1d8af9f69885 Mon Sep 17 00:00:00 2001 From: Algiane Date: Fri, 20 Nov 2020 16:21:37 +0100 Subject: [PATCH 019/170] Correction of typo in the path of the AbnormalEnd8 test. --- cmake/testing/mmg_tests.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/testing/mmg_tests.cmake b/cmake/testing/mmg_tests.cmake index 2bbd7cb54..d311e0b9e 100644 --- a/cmake/testing/mmg_tests.cmake +++ b/cmake/testing/mmg_tests.cmake @@ -171,7 +171,7 @@ FOREACH(EXEC ${LISTEXEC_MMG}) ADD_TEST(NAME mmg_LeakCheck_AbnormalEnd8_${SHRT_EXEC} COMMAND ${EXEC} -v 5 ${common_args} ${MMG_CI_TESTS}/LeakCheck_AbnormalEnd8/d - -out ${CTEST_OUTPUT_DIR}/AbnormalEnd8/unwrittable.meshb) + -out ${CTEST_OUTPUT_DIR}/LeakCheck_AbnormalEnd8/unwrittable.meshb) SET(passRegex "\\*\\* UNABLE TO OPEN.*.sol") SET_PROPERTY(TEST mmg_LeakCheck_AbnormalEnd8_${SHRT_EXEC} PROPERTY PASS_REGULAR_EXPRESSION "${passRegex}") From 6a982f787e34ccd37edc07e707745369d26c5eb5 Mon Sep 17 00:00:00 2001 From: Algiane Date: Mon, 23 Nov 2020 12:28:44 +0100 Subject: [PATCH 020/170] Try to patch AbnormalEnd8 test. --- CMakeLists.txt | 14 +++++--------- cmake/testing/mmg_tests.cmake | 4 ++-- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f80827b56..8da26a6f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -555,18 +555,14 @@ IF( BUILD_TESTING ) SET(LISTEXEC_MMG ${LISTEXEC_MMGS} ${LISTEXEC_MMG3D}) SET(EXECUT_MMG ${EXECUT_MMGS} ${EXECUT_MMG3D}) - # Change authorisations for some files... - IF ( EXISTS ${CTEST_OUTPUT_DIR}/LeakCheck_AbnormalEnd7/unwrittable.meshb) - FILE(REMOVE ${CTEST_OUTPUT_DIR}/LeakCheck_AbnormalEnd7/unwrittable.meshb) + # Make some files not openable + IF ( NOT EXISTS ${CTEST_OUTPUT_DIR}/unwrittable7.meshb) + FILE(MAKE_DIRECTORY ${CTEST_OUTPUT_DIR}/unwrittable7.meshb) ENDIF() - FILE(COPY ${MMG_CI_TESTS}/LeakCheck_AbnormalEnd7/dout.mesh - DESTINATION ${CTEST_OUTPUT_DIR}/LeakCheck_AbnormalEnd7/unwrittable.meshb) - IF ( EXISTS ${CTEST_OUTPUT_DIR}/LeakCheck_AbnormalEnd8/unwrittable.sol) - FILE(REMOVE ${CTEST_OUTPUT_DIR}/LeakCheck_AbnormalEnd8/unwrittable.sol) + IF ( NOT EXISTS ${CTEST_OUTPUT_DIR}/unwrittable8.sol) + FILE(MAKE_DIRECTORY ${CTEST_OUTPUT_DIR}/unwrittable8.sol) ENDIF() - FILE(COPY ${MMG_CI_TESTS}/LeakCheck_AbnormalEnd8/dsol.sol - DESTINATION ${CTEST_OUTPUT_DIR}/LeakCheck_AbnormalEnd8/unwrittable.sol) # Add common tests for mmgs/3d appli INCLUDE( ${PROJECT_SOURCE_DIR}/cmake/testing/mmg_tests.cmake ) diff --git a/cmake/testing/mmg_tests.cmake b/cmake/testing/mmg_tests.cmake index d311e0b9e..1bcfbb4c1 100644 --- a/cmake/testing/mmg_tests.cmake +++ b/cmake/testing/mmg_tests.cmake @@ -163,7 +163,7 @@ FOREACH(EXEC ${LISTEXEC_MMG}) ADD_TEST(NAME mmg_LeakCheck_AbnormalEnd7_${SHRT_EXEC} COMMAND ${EXEC} -v 5 ${common_args} ${MMG_CI_TESTS}/LeakCheck_AbnormalEnd7/d - -out ${CTEST_OUTPUT_DIR}/AbnormalEnd7/unwrittable.meshb) + -out ${CTEST_OUTPUT_DIR}/unwrittable7.meshb) SET(passRegex "\\*\\* UNABLE TO OPEN.*") SET_PROPERTY(TEST mmg_LeakCheck_AbnormalEnd7_${SHRT_EXEC} PROPERTY PASS_REGULAR_EXPRESSION "${passRegex}") @@ -171,7 +171,7 @@ FOREACH(EXEC ${LISTEXEC_MMG}) ADD_TEST(NAME mmg_LeakCheck_AbnormalEnd8_${SHRT_EXEC} COMMAND ${EXEC} -v 5 ${common_args} ${MMG_CI_TESTS}/LeakCheck_AbnormalEnd8/d - -out ${CTEST_OUTPUT_DIR}/LeakCheck_AbnormalEnd8/unwrittable.meshb) + -out ${CTEST_OUTPUT_DIR}/unwrittable8.meshb) SET(passRegex "\\*\\* UNABLE TO OPEN.*.sol") SET_PROPERTY(TEST mmg_LeakCheck_AbnormalEnd8_${SHRT_EXEC} PROPERTY PASS_REGULAR_EXPRESSION "${passRegex}") From decddf4bc5d753b89b1131782f0b614ec2897b51 Mon Sep 17 00:00:00 2001 From: Algiane Date: Mon, 23 Nov 2020 12:48:38 +0100 Subject: [PATCH 021/170] Remove unwrittable files if exists. --- CMakeLists.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8da26a6f9..6d115d340 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -556,10 +556,18 @@ IF( BUILD_TESTING ) SET(EXECUT_MMG ${EXECUT_MMGS} ${EXECUT_MMG3D}) # Make some files not openable + IF ( EXISTS ${CTEST_OUTPUT_DIR}/unwrittable7.meshb + AND NOT IS_DIRECTORY ${CTEST_OUTPUT_DIR}/unwrittable7.meshb ) + FILE ( REMOVE ${CTEST_OUTPUT_DIR}/unwrittable7.meshb ) + ENDIF () IF ( NOT EXISTS ${CTEST_OUTPUT_DIR}/unwrittable7.meshb) FILE(MAKE_DIRECTORY ${CTEST_OUTPUT_DIR}/unwrittable7.meshb) ENDIF() + IF ( EXISTS ${CTEST_OUTPUT_DIR}/unwrittable8.sol + AND NOT IS_DIRECTORY ${CTEST_OUTPUT_DIR}/unwrittable8.sol ) + FILE ( REMOVE ${CTEST_OUTPUT_DIR}/unwrittable8.sol ) + ENDIF () IF ( NOT EXISTS ${CTEST_OUTPUT_DIR}/unwrittable8.sol) FILE(MAKE_DIRECTORY ${CTEST_OUTPUT_DIR}/unwrittable8.sol) ENDIF() From f626c1cc375e8b76491b3fa006b1cc94183dfad1 Mon Sep 17 00:00:00 2001 From: Algiane Date: Mon, 23 Nov 2020 14:21:14 +0100 Subject: [PATCH 022/170] Remove overwritting of the CTEST_OUUTPUT_DIR variable in the mmg.cmake modules. --- cmake/modules/mmg.cmake | 3 --- cmake/modules/mmg2d.cmake | 3 --- cmake/modules/mmg3d.cmake | 3 --- cmake/modules/mmgs.cmake | 4 ---- 4 files changed, 13 deletions(-) diff --git a/cmake/modules/mmg.cmake b/cmake/modules/mmg.cmake index b65a16462..470905f4f 100644 --- a/cmake/modules/mmg.cmake +++ b/cmake/modules/mmg.cmake @@ -156,9 +156,6 @@ ENDIF() IF ( BUILD_TESTING ) - SET ( CTEST_OUTPUT_DIR ${PROJECT_BINARY_DIR}/TEST_OUTPUTS ) - FILE ( MAKE_DIRECTORY ${CTEST_OUTPUT_DIR} ) - ##-------------------------------------------------------------------## ##--------------------------- Add tests and configure it ------------## ##-------------------------------------------------------------------## diff --git a/cmake/modules/mmg2d.cmake b/cmake/modules/mmg2d.cmake index a73ad7a32..9e89764f2 100644 --- a/cmake/modules/mmg2d.cmake +++ b/cmake/modules/mmg2d.cmake @@ -168,9 +168,6 @@ IF ( BUILD_TESTING ) # Add runtime that we want to test for mmg2d IF ( MMG2D_CI ) - SET ( CTEST_OUTPUT_DIR ${PROJECT_BINARY_DIR}/TEST_OUTPUTS ) - FILE ( MAKE_DIRECTORY ${CTEST_OUTPUT_DIR} ) - ADD_EXEC_TO_CI_TESTS ( ${PROJECT_NAME}2d EXECUT_MMG2D ) IF ( TEST_LIBMMG2D ) diff --git a/cmake/modules/mmg3d.cmake b/cmake/modules/mmg3d.cmake index 20e6aab94..6c8cb09af 100644 --- a/cmake/modules/mmg3d.cmake +++ b/cmake/modules/mmg3d.cmake @@ -184,9 +184,6 @@ IF ( BUILD_TESTING ) # Add runtime that we want to test for mmg3d IF ( MMG3D_CI ) - SET ( CTEST_OUTPUT_DIR ${PROJECT_BINARY_DIR}/TEST_OUTPUTS ) - FILE ( MAKE_DIRECTORY ${CTEST_OUTPUT_DIR} ) - IF ( LONG_TESTS ) # Run some tests twice with the output of the previous test as input OPTION ( RUN_AGAIN "Enable/Disable second run of some tests" ON ) diff --git a/cmake/modules/mmgs.cmake b/cmake/modules/mmgs.cmake index 418da2898..d89ce4d39 100644 --- a/cmake/modules/mmgs.cmake +++ b/cmake/modules/mmgs.cmake @@ -149,10 +149,6 @@ IF ( BUILD_TESTING ) # Add runtime that we want to test for mmgs IF( MMGS_CI ) - SET ( CTEST_OUTPUT_DIR ${PROJECT_BINARY_DIR}/TEST_OUTPUTS ) - FILE ( MAKE_DIRECTORY ${CTEST_OUTPUT_DIR} ) - - ADD_EXEC_TO_CI_TESTS ( ${PROJECT_NAME}s EXECUT_MMGS ) SET ( LISTEXEC_MMG ${EXECUT_MMGS} ) From c4bddbbc284e3353e1304142a469bd3b040e8d22 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 24 Nov 2020 14:09:01 +0100 Subject: [PATCH 023/170] Move definition of CTEST_OUTPUT_DIR cache variable to avoid unitialization when defining library tests. --- CMakeLists.txt | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d115d340..b616e29a4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -425,6 +425,17 @@ CMAKE_DEPENDENT_OPTION( ############################################################################### SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) +# CTEST_OUTPUT_DIR MUST BE SETTED HERE TO AVOID UNINITIALIZATION FOR LIBRARY +# TESTS DEFS +OPTION ( BUILD_TESTING "Enable/Disable continuous integration" OFF ) + +IF( BUILD_TESTING ) + SET ( CTEST_OUTPUT_DIR ${PROJECT_BINARY_DIR}/TEST_OUTPUTS + CACHE PATH "Path toward the tests outputs" ) + MARK_AS_ADVANCED ( CTEST_OUTPUT_DIR ) + FILE ( MAKE_DIRECTORY ${CTEST_OUTPUT_DIR} ) +ENDIF ( ) + IF ( BUILD_MMG2D ) INCLUDE(cmake/modules/mmg2d.cmake) ENDIF ( ) @@ -473,8 +484,6 @@ ENDIF() ##### ############################################################################### -OPTION ( BUILD_TESTING "Enable/Disable continuous integration" OFF ) - CMAKE_DEPENDENT_OPTION ( ONLY_VERY_SHORT_TESTS "Enable/Disable very short tests" OFF "BUILD_TESTING;NOT LONG_TESTS" OFF ) @@ -490,12 +499,6 @@ CMAKE_DEPENDENT_OPTION ( COVERAGE "Watch code coverage (Linux only)" OFF IF( BUILD_TESTING ) - SET ( CTEST_OUTPUT_DIR ${PROJECT_BINARY_DIR}/TEST_OUTPUTS - CACHE PATH "Path toward the tests outputs" ) - MARK_AS_ADVANCED ( CTEST_OUTPUT_DIR ) - - FILE ( MAKE_DIRECTORY ${CTEST_OUTPUT_DIR} ) - IF ( NOT ONLY_VERY_SHORT_TESTS ) ##-------------------------------------------------------------------## ##------- Get the continuous integration tests ----------------------## From 87a596005e7dd87d68728fb893a17912c1843833 Mon Sep 17 00:00:00 2001 From: Algiane Date: Mon, 30 Nov 2020 09:17:35 +0100 Subject: [PATCH 024/170] Comment sphereIso_0.020-0.015_met test that doesn't pass on windows 4Go. --- cmake/testing/mmg3d_tests.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/testing/mmg3d_tests.cmake b/cmake/testing/mmg3d_tests.cmake index 1df4606ab..f00fd1af3 100644 --- a/cmake/testing/mmg3d_tests.cmake +++ b/cmake/testing/mmg3d_tests.cmake @@ -75,7 +75,7 @@ IF ( LONG_TESTS ) mmg3d_SphereIso_0.25h_met mmg3d_SphereIso_0.125h_met mmg3d_SphereIso_0.020_met - mmg3d_SphereIso_0.020-0.015_met + # mmg3d_SphereIso_0.020-0.015_met # not enough mem on windows 4G mmg3d_SphereAni_0.02 # Check what happend when we unrefine a sphere of size smallh with a # constant metric (2*smallh, 4*smallh and 8*smallh) @@ -129,7 +129,7 @@ IF ( LONG_TESTS ) ${MMG3D_CI_TESTS}/SphereIso_0.25h_met/SphereIso0.5 ${MMG3D_CI_TESTS}/SphereIso_0.125h_met/SphereIso0.5 ${MMG3D_CI_TESTS}/SphereIso_0.020_met/SphereIso0.5 - ${MMG3D_CI_TESTS}/SphereIso_0.020-0.015_met/SphereIso0.020 + # ${MMG3D_CI_TESTS}/SphereIso_0.020-0.015_met/SphereIso0.020 ${MMG3D_CI_TESTS}/SphereAni_0.02/sphere ### ${MMG3D_CI_TESTS}/SphereIso_2smallh_met/SphereIso0.0625 @@ -178,7 +178,7 @@ IF ( LONG_TESTS ) "-v 5 -hausd 0.1" "-v 5 -hausd 0.1" "-v 5 -hausd 0.1" - "-v 5 -hausd 0.1" + # "-v 5 -hausd 0.1" "-v 5" ### "-v 5 -hausd 0.1" From 1e569007726f519bd43296d96b62902d787cac12 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 8 Dec 2020 13:51:08 +0100 Subject: [PATCH 025/170] Remove a possible segfault while we lack of memory in delaunay_3d.c: as TETRA_REALLOC macro deallocate mesh->tetra, we can not access it to delete new elements. --- src/mmg3d/delaunay_3d.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/mmg3d/delaunay_3d.c b/src/mmg3d/delaunay_3d.c index 4e6c44cfb..9788750fa 100644 --- a/src/mmg3d/delaunay_3d.c +++ b/src/mmg3d/delaunay_3d.c @@ -212,10 +212,6 @@ int MMG5_delone(MMG5_pMesh mesh,MMG5_pSol sol,int ip,int *list,int ilist) { MMG3D_TETRA_REALLOC(mesh,ielnum[k],mesh->gap, fprintf(stderr,"\n ## Error: %s: unable to allocate a" " new element.\n",__func__); - for(ll=1 ; lltetra[ielnum[ll]].v[0] = 1; - if ( !MMG3D_delElt(mesh,ielnum[ll]) ) return -1; - } return -1); } } From 2b183d1e0ebfd8127c864b086e45642a5e68e9d1 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 8 Dec 2020 18:39:24 +0100 Subject: [PATCH 026/170] Do not deallocate type variable inside MMG5_chkMetricType as it may be an allocated array but also an integer. --- src/common/inout.c | 7 +++---- src/mmg2d/inout_2d.c | 5 ++++- src/mmg3d/inout_3d.c | 6 +++++- src/mmgs/inout_s.c | 7 ++++++- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/common/inout.c b/src/common/inout.c index 9df193c4e..2966c5293 100644 --- a/src/common/inout.c +++ b/src/common/inout.c @@ -2589,8 +2589,9 @@ int MMG5_saveSolAtTetrahedraHeader( MMG5_pMesh mesh, * \param inm metric file * \return 1 if success, -1 if fail * - * Check if the type of the metric is compatible with the remeshing mode. - * If not, deallocate the type array and close the metric file. + * Check if the type of the metric is compatible with the remeshing mode. If + * not, close the metric file (note that if type is an allocated array, you must + * unallocate it outside). * */ int MMG5_chkMetricType(MMG5_pMesh mesh,int *type, FILE *inm) { @@ -2601,7 +2602,6 @@ int MMG5_chkMetricType(MMG5_pMesh mesh,int *type, FILE *inm) { if ( mesh->info.lag == -1 ) { if ( type[0]!=1 && type[0]!=3) { fprintf(stderr," ** DATA TYPE IGNORED %d \n",type[0]); - MMG5_SAFE_FREE(type); if ( inm ) fclose(inm); return -1; } @@ -2610,7 +2610,6 @@ int MMG5_chkMetricType(MMG5_pMesh mesh,int *type, FILE *inm) { if ( type[0] != 2 ) { fprintf(stderr," ** MISMATCH DATA TYPE FOR LAGRANGIAN MODE %d \n", type[0]); - MMG5_SAFE_FREE(type); if ( inm ) fclose(inm); return -1; } diff --git a/src/mmg2d/inout_2d.c b/src/mmg2d/inout_2d.c index 7f1eca319..f39fce496 100644 --- a/src/mmg2d/inout_2d.c +++ b/src/mmg2d/inout_2d.c @@ -849,7 +849,10 @@ int MMG2D_loadSol(MMG5_pMesh mesh,MMG5_pSol sol,const char *filename) { } ier = MMG5_chkMetricType(mesh,type,inm); - if ( ier <1 ) return ier; + if ( ier < 1 ) { + MMG5_SAFE_FREE(type); + return ier; + } /* Allocate and store the header informations for each solution */ if ( !MMG2D_Set_solSize(mesh,sol,MMG5_Vertex,mesh->np,type[0]) ) { diff --git a/src/mmg3d/inout_3d.c b/src/mmg3d/inout_3d.c index 9d68f5525..af3571954 100644 --- a/src/mmg3d/inout_3d.c +++ b/src/mmg3d/inout_3d.c @@ -2130,7 +2130,11 @@ int MMG3D_loadSol(MMG5_pMesh mesh,MMG5_pSol met, const char *filename) { ier = MMG5_chkMetricType(mesh,type,inm); - if ( ier <1 ) return ier; + if ( ier < 1 ) { + MMG5_SAFE_FREE(type); + return ier; + } + /* Allocate and store the header informations for each solution */ if ( !MMG3D_Set_solSize(mesh,met,MMG5_Vertex,mesh->np,type[0]) ) { fclose(inm); diff --git a/src/mmgs/inout_s.c b/src/mmgs/inout_s.c index 6b1696b82..5b2dc782a 100644 --- a/src/mmgs/inout_s.c +++ b/src/mmgs/inout_s.c @@ -1315,7 +1315,10 @@ int MMGS_loadSol(MMG5_pMesh mesh,MMG5_pSol met,const char* filename) { } ier = MMG5_chkMetricType(mesh,type,inm); - if ( ier <1 ) return ier; + if ( ier < 1 ) { + MMG5_SAFE_FREE(type); + return ier; + } /* Allocate and store the header informations for each solution */ if ( !MMGS_Set_solSize(mesh,met,MMG5_Vertex,mesh->np,type[0]) ) { @@ -1326,6 +1329,8 @@ int MMGS_loadSol(MMG5_pMesh mesh,MMG5_pSol met,const char* filename) { /* For binary file, we read the verson inside the file */ if ( ver ) met->ver = ver; + MMG5_SAFE_FREE(type); + /* Read mesh solutions */ rewind(inm); fseek(inm,posnp,SEEK_SET); From a8109dd9fe418a474a32ecd02769768251e15d46 Mon Sep 17 00:00:00 2001 From: Algiane Date: Wed, 9 Dec 2020 09:30:27 +0100 Subject: [PATCH 027/170] Add a new error message when chkMetricType fail. --- src/common/inout.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/common/inout.c b/src/common/inout.c index 2966c5293..183b2ae4a 100644 --- a/src/common/inout.c +++ b/src/common/inout.c @@ -2602,6 +2602,9 @@ int MMG5_chkMetricType(MMG5_pMesh mesh,int *type, FILE *inm) { if ( mesh->info.lag == -1 ) { if ( type[0]!=1 && type[0]!=3) { fprintf(stderr," ** DATA TYPE IGNORED %d \n",type[0]); + fprintf(stderr," ## Error: %s: if your input file is at a non Medit" + " file format, please ensure that the metric field" + " contains the \":metric\" string.\n",__FILE__); if ( inm ) fclose(inm); return -1; } From 3988bbb0fc9a7e7aab6e080ff7ca260427366ff0 Mon Sep 17 00:00:00 2001 From: luca Date: Fri, 11 Dec 2020 18:05:03 +0100 Subject: [PATCH 028/170] Avoid wrong result when checking non-manifold on no-split boundaries (brute force implementation). --- src/common/mmg2.c | 23 +++++++++++++++++++++++ src/common/mmgcommon.h | 1 + src/mmg3d/mmg3d2.c | 6 +++++- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/common/mmg2.c b/src/common/mmg2.c index 302ac8d9e..d22119437 100644 --- a/src/common/mmg2.c +++ b/src/common/mmg2.c @@ -71,6 +71,29 @@ int MMG5_isSplit(MMG5_pMesh mesh,int ref,int *refint,int *refext) { } +int MMG5_isLevelSet(MMG5_pMesh mesh,int ref0,int ref1) { + MMG5_pMat pm; + int k; + int found0,found1; + + for (k=0; kinfo.nmat; k++) { + pm = &mesh->info.mat[k]; + if( pm->ref == ref0 ) { found0 = MG_NOTAG; break; } + if( pm->rin == ref0 ) { found0 = MG_PLUS; break; } + if( pm->rex == ref0 ) { found0 = MG_MINUS; break; } + } + for (k=0; kinfo.nmat; k++) { + pm = &mesh->info.mat[k]; + if( pm->ref == ref1 ) { found1 = MG_NOTAG; break; } + if( pm->rin == ref1 ) { found1 = MG_PLUS; break; } + if( pm->rex == ref1 ) { found1 = MG_MINUS; break; } + } + + if( (found0+found1) == (MG_MINUS+MG_PLUS) ) return 1; + else return 0; + +} + /** * \param mesh pointer toward the mesh * \param ref final reference for which we are searching the initial one diff --git a/src/common/mmgcommon.h b/src/common/mmgcommon.h index bc56bc8bc..31d60e29e 100644 --- a/src/common/mmgcommon.h +++ b/src/common/mmgcommon.h @@ -725,6 +725,7 @@ int MMG5_updatemetreq_ani(double *n,double dn[2],double vp[2][2]); int MMG5_swapbin(int sbin); float MMG5_swapf(float sbin); double MMG5_swapd(double sbin); +int MMG5_isLevelSet(MMG5_pMesh,int,int); int MMG5_isSplit(MMG5_pMesh ,int ,int *,int *); int MMG5_getIniRef(MMG5_pMesh ,int ); diff --git a/src/mmg3d/mmg3d2.c b/src/mmg3d/mmg3d2.c index a498257ba..fc4603a04 100755 --- a/src/mmg3d/mmg3d2.c +++ b/src/mmg3d/mmg3d2.c @@ -1407,6 +1407,7 @@ int MMG5_chkmaniball(MMG5_pMesh mesh, int start, int8_t ip){ int ref,base,ilist,nump,k,cur,k1,nref; int *adja,list[MMG3D_LMAX+2]; int8_t i,l,j; + int dummyrin,dummyrex; base = ++mesh->base; ilist = 0; @@ -1435,6 +1436,7 @@ int MMG5_chkmaniball(MMG5_pMesh mesh, int start, int8_t ip){ if(!k1) continue; k1 /= 4; pt1 = &mesh->tetra[k1]; + if( !MMG5_isSplit(mesh,pt1->ref,&dummyrin,&dummyrex) ) continue; if( pt1 ->ref != ref ) continue; @@ -1473,6 +1475,8 @@ int MMG5_chkmaniball(MMG5_pMesh mesh, int start, int8_t ip){ k1/=4; pt1 = &mesh->tetra[k1]; + if( !MMG5_isSplit(mesh,pt1->ref,&dummyrin,&dummyrex) ) continue; + if(pt1->flag == base) continue; pt1->flag = base; @@ -1553,7 +1557,7 @@ int MMG5_chkmani(MMG5_pMesh mesh){ if(!adja[i]) continue; iel = adja[i] / 4; pt1 = &mesh->tetra[iel]; - if(pt1->ref == pt->ref) continue; + if( !MMG5_isLevelSet(mesh,pt1->ref,pt->ref) ) continue; for(j=0; j<3; j++){ ip = MMG5_idir[i][j]; From ae102754154d5294f5fde0e262cafcb6040ebf3d Mon Sep 17 00:00:00 2001 From: luca Date: Fri, 11 Dec 2020 18:16:22 +0100 Subject: [PATCH 029/170] isNotSplit function. --- src/common/mmg2.c | 25 +++++++++++++++++++++++++ src/common/mmgcommon.h | 1 + src/mmg3d/mmg3d2.c | 5 ++--- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/common/mmg2.c b/src/common/mmg2.c index d22119437..5579ca23f 100644 --- a/src/common/mmg2.c +++ b/src/common/mmg2.c @@ -71,6 +71,31 @@ int MMG5_isSplit(MMG5_pMesh mesh,int ref,int *refint,int *refext) { } +/** + * \param mesh pointer toward the mesh structure. + * \param ref initial reference. + * \return 1 if entity cannot be split, 0 if can be split. + * + * Identify whether an entity with reference ref should not be split. + * + */ +int MMG5_isNotSplit(MMG5_pMesh mesh,int ref) { + MMG5_pMat pm; + int k; + + /* Split material by default if not in multi-material mode */ + if( !mesh->info.nmat ) return 0; + + for (k=0; kinfo.nmat; k++) { + pm = &mesh->info.mat[k]; + if ( pm->ref == ref ) { + if ( !pm->dospl ) { + return 1; + } else return 0; + } + } +} + int MMG5_isLevelSet(MMG5_pMesh mesh,int ref0,int ref1) { MMG5_pMat pm; int k; diff --git a/src/common/mmgcommon.h b/src/common/mmgcommon.h index 31d60e29e..a2fd7d6cb 100644 --- a/src/common/mmgcommon.h +++ b/src/common/mmgcommon.h @@ -727,6 +727,7 @@ float MMG5_swapf(float sbin); double MMG5_swapd(double sbin); int MMG5_isLevelSet(MMG5_pMesh,int,int); int MMG5_isSplit(MMG5_pMesh ,int ,int *,int *); +int MMG5_isNotSplit(MMG5_pMesh ,int); int MMG5_getIniRef(MMG5_pMesh ,int ); diff --git a/src/mmg3d/mmg3d2.c b/src/mmg3d/mmg3d2.c index fc4603a04..acd5bbcbf 100755 --- a/src/mmg3d/mmg3d2.c +++ b/src/mmg3d/mmg3d2.c @@ -1407,7 +1407,6 @@ int MMG5_chkmaniball(MMG5_pMesh mesh, int start, int8_t ip){ int ref,base,ilist,nump,k,cur,k1,nref; int *adja,list[MMG3D_LMAX+2]; int8_t i,l,j; - int dummyrin,dummyrex; base = ++mesh->base; ilist = 0; @@ -1436,7 +1435,7 @@ int MMG5_chkmaniball(MMG5_pMesh mesh, int start, int8_t ip){ if(!k1) continue; k1 /= 4; pt1 = &mesh->tetra[k1]; - if( !MMG5_isSplit(mesh,pt1->ref,&dummyrin,&dummyrex) ) continue; + if( MMG5_isNotSplit(mesh,pt1->ref) ) continue; if( pt1 ->ref != ref ) continue; @@ -1475,7 +1474,7 @@ int MMG5_chkmaniball(MMG5_pMesh mesh, int start, int8_t ip){ k1/=4; pt1 = &mesh->tetra[k1]; - if( !MMG5_isSplit(mesh,pt1->ref,&dummyrin,&dummyrex) ) continue; + if( MMG5_isNotSplit(mesh,pt1->ref) ) continue; if(pt1->flag == base) continue; pt1->flag = base; From 52db6476ec45064c20acd077c7ec3528584f9f9f Mon Sep 17 00:00:00 2001 From: Pierre Jolivet Date: Sun, 6 Dec 2020 11:46:33 +0100 Subject: [PATCH 030/170] Install missing headers for ParMmg. --- CMakeLists.txt | 3 +++ cmake/modules/mmg.cmake | 8 ++++++++ cmake/modules/mmg3d.cmake | 6 ++++++ scripts/JENKINSFILE.sonarqube | 2 +- 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b616e29a4..71fdf6ddc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -311,6 +311,9 @@ ENDFUNCTION() OPTION(BUILD_SHARED_LIBS "Build shared libraries" OFF) INVERT_BOOL("BUILD_STATIC_LIBS" ${BUILD_SHARED_LIBS}) +IF (${BUILD_STATIC_LIBS} AND NOT CMAKE_POSITION_INDEPENDENT_CODE) + SET(CMAKE_POSITION_INDEPENDENT_CODE ON) +ENDIF() #------------------------------- mmg2d CMAKE_DEPENDENT_OPTION ( LIBMMG2D_STATIC "Compile the mmg2d static library" ${BUILD_STATIC_LIBS} diff --git a/cmake/modules/mmg.cmake b/cmake/modules/mmg.cmake index 470905f4f..c16894ea7 100644 --- a/cmake/modules/mmg.cmake +++ b/cmake/modules/mmg.cmake @@ -52,6 +52,11 @@ LIST(REMOVE_ITEM mmg_library_files ${MMGS_SOURCE_DIR}/mmgs.c ${MMG3D_SOURCE_DIR}/mmg3d.c ${REMOVE_FILE} ) +FILE( + GLOB + mmg_header_files + ${COMMON_SOURCE_DIR}/*.h + ) IF ( VTK_FOUND ) LIST(APPEND mmg_library_files @@ -99,6 +104,9 @@ IF ( LIBMMG_STATIC OR LIBMMG_SHARED ) SET( mmg_headers ${PROJECT_SOURCE_DIR}/src/mmg/libmmg.h ${PROJECT_SOURCE_DIR}/src/mmg/libmmgf.h + ${COMMON_BINARY_DIR}/mmgcmakedefines.h + ${COMMON_BINARY_DIR}/mmgversion.h + ${mmg_header_files} ) SET(MMG2D_INCLUDE ${PROJECT_BINARY_DIR}/include/mmg/mmg2d ) SET(MMGS_INCLUDE ${PROJECT_BINARY_DIR}/include/mmg/mmgs ) diff --git a/cmake/modules/mmg3d.cmake b/cmake/modules/mmg3d.cmake index 6c8cb09af..5f58dc4ac 100644 --- a/cmake/modules/mmg3d.cmake +++ b/cmake/modules/mmg3d.cmake @@ -130,6 +130,8 @@ ENDIF() # mmg3d header files needed for library SET( mmg3d_headers ${MMG3D_SOURCE_DIR}/libmmg3d.h + ${MMG3D_SOURCE_DIR}/mmg3d.h + ${MMG3D_SOURCE_DIR}/inlined_functions_3d.h ${MMG3D_BINARY_DIR}/libmmg3df.h ${COMMON_SOURCE_DIR}/libmmgtypes.h ${COMMON_BINARY_DIR}/libmmgtypesf.h @@ -138,6 +140,10 @@ SET( mmg3d_headers ) IF (NOT WIN32 OR MINGW) LIST(APPEND mmg3d_headers ${COMMON_BINARY_DIR}/git_log_mmg.h ) + IF (LIBMMG_STATIC OR LIBMMG_SHARED) + SET(mmg3d_git_header ${COMMON_BINARY_DIR}/git_log_mmg.h) + INSTALL(FILES ${mmg3d_git_header} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mmg/ COMPONENT headers) + ENDIF() ENDIF() diff --git a/scripts/JENKINSFILE.sonarqube b/scripts/JENKINSFILE.sonarqube index 95cc15cf3..77231e2f4 100644 --- a/scripts/JENKINSFILE.sonarqube +++ b/scripts/JENKINSFILE.sonarqube @@ -12,7 +12,7 @@ node('mmg-sonnar-new') { mkdir -p buildPattern'''+list[i]+''' cd buildPattern'''+list[i]+''' rm -rf * - export CFLAGS="-O0 -g -fPIC --coverage -Wall -Wunused-parameter -Wundef -Wno-long-long -Wsign-compare -Wmissing-prototypes -Wstrict-prototypes -Wcomment -pedantic -fdiagnostics-show-option" + export CFLAGS="-O0 -g --coverage -Wall -Wunused-parameter -Wundef -Wno-long-long -Wsign-compare -Wmissing-prototypes -Wstrict-prototypes -Wcomment -pedantic -fdiagnostics-show-option" export LDFLAGS="--coverage" cmake .. -DCMAKE_BUILD_TYPE=Debug -DPATTERN='''+list[i]+''' -DBUILD_TESTING=ON -DCMAKE_C_FLAGS="$CFLAGS" -DCMAKE_EXE_LINKER_FLAGS="$LDFLAGS" -DCMAKE_INSTALL_PREFIX=$PWD/../install -DBUILD_TESTING=ON -DLONG_TESTS=OFF -DRUN_AGAIN=ON -DLIBMMG2D_STATIC=ON -DLIBMMG3D_STATIC=ON -DLIBMMG_STATIC=ON -DLIBMMG2D_STATIC=ON -DLIBMMGS_STATIC=ON -DTEST_LIBMMG=ON -DTEST_LIBMMG2D=ON -DTEST_LIBMMG3D=ON -DTEST_LIBMMGS=ON -DSCOTCH_DIR=/home/ci/scotch_6.0.6 -DSCOTCH_LIBRARIES=/builds/scotch_6.0.6/lib/libscotch.a -DUSE_SCOTCH=ON -DELAS_DIR=/home/ci/LinearElasticity -DUSE_ELAS=ON make clean From ae943dee5aece3a1d2e2e6335302bea99adc1019 Mon Sep 17 00:00:00 2001 From: luca Date: Mon, 14 Dec 2020 16:44:21 +0100 Subject: [PATCH 031/170] Revert header install to test separately from fpic option. --- cmake/modules/mmg.cmake | 8 -------- cmake/modules/mmg3d.cmake | 6 ------ 2 files changed, 14 deletions(-) diff --git a/cmake/modules/mmg.cmake b/cmake/modules/mmg.cmake index c16894ea7..470905f4f 100644 --- a/cmake/modules/mmg.cmake +++ b/cmake/modules/mmg.cmake @@ -52,11 +52,6 @@ LIST(REMOVE_ITEM mmg_library_files ${MMGS_SOURCE_DIR}/mmgs.c ${MMG3D_SOURCE_DIR}/mmg3d.c ${REMOVE_FILE} ) -FILE( - GLOB - mmg_header_files - ${COMMON_SOURCE_DIR}/*.h - ) IF ( VTK_FOUND ) LIST(APPEND mmg_library_files @@ -104,9 +99,6 @@ IF ( LIBMMG_STATIC OR LIBMMG_SHARED ) SET( mmg_headers ${PROJECT_SOURCE_DIR}/src/mmg/libmmg.h ${PROJECT_SOURCE_DIR}/src/mmg/libmmgf.h - ${COMMON_BINARY_DIR}/mmgcmakedefines.h - ${COMMON_BINARY_DIR}/mmgversion.h - ${mmg_header_files} ) SET(MMG2D_INCLUDE ${PROJECT_BINARY_DIR}/include/mmg/mmg2d ) SET(MMGS_INCLUDE ${PROJECT_BINARY_DIR}/include/mmg/mmgs ) diff --git a/cmake/modules/mmg3d.cmake b/cmake/modules/mmg3d.cmake index 5f58dc4ac..6c8cb09af 100644 --- a/cmake/modules/mmg3d.cmake +++ b/cmake/modules/mmg3d.cmake @@ -130,8 +130,6 @@ ENDIF() # mmg3d header files needed for library SET( mmg3d_headers ${MMG3D_SOURCE_DIR}/libmmg3d.h - ${MMG3D_SOURCE_DIR}/mmg3d.h - ${MMG3D_SOURCE_DIR}/inlined_functions_3d.h ${MMG3D_BINARY_DIR}/libmmg3df.h ${COMMON_SOURCE_DIR}/libmmgtypes.h ${COMMON_BINARY_DIR}/libmmgtypesf.h @@ -140,10 +138,6 @@ SET( mmg3d_headers ) IF (NOT WIN32 OR MINGW) LIST(APPEND mmg3d_headers ${COMMON_BINARY_DIR}/git_log_mmg.h ) - IF (LIBMMG_STATIC OR LIBMMG_SHARED) - SET(mmg3d_git_header ${COMMON_BINARY_DIR}/git_log_mmg.h) - INSTALL(FILES ${mmg3d_git_header} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mmg/ COMPONENT headers) - ENDIF() ENDIF() From 3deec105b1dc18d0c0d975295e7dd0108d5bd97f Mon Sep 17 00:00:00 2001 From: luca Date: Mon, 14 Dec 2020 19:48:36 +0100 Subject: [PATCH 032/170] Try trivial hash for materials table. --- src/common/API_functions.c | 15 ++++ src/common/libmmgtypes.h | 8 ++ src/common/mmg2.c | 162 ++++++++++++++++++++++++++++--------- src/common/mmgcommon.h | 1 + src/mmg2d/libmmg2d_tools.c | 5 ++ 5 files changed, 154 insertions(+), 37 deletions(-) diff --git a/src/common/API_functions.c b/src/common/API_functions.c index 31a039868..7cf2257b4 100644 --- a/src/common/API_functions.c +++ b/src/common/API_functions.c @@ -485,6 +485,13 @@ void MMG5_Free_structures(MMG5_pMesh mesh,MMG5_pSol sol){ if ( mesh->info.npar && mesh->info.par ) MMG5_DEL_MEM(mesh,mesh->info.par); + if ( mesh->info.nmat ) { + if( mesh->info.mat ) + MMG5_DEL_MEM(mesh,mesh->info.mat); + if( mesh->info.invmat.lookup ) + MMG5_DEL_MEM(mesh,mesh->info.invmat.lookup); + } + if ( mesh->info.imprim>5 || mesh->info.ddebug ) { printf(" MEMORY USED AT END (Bytes) %zu\n",mesh->memCur); } @@ -708,5 +715,13 @@ int MMG5_Set_multiMat(MMG5_pMesh mesh,MMG5_pSol sol,int ref, mesh->info.nmati++; + /* Invert the table if all materials have been set */ + if( mesh->info.nmati == mesh->info.nmat ) + if( !MMG5_MultiMat_init(mesh) ) { + fprintf(stderr,"\n ## Error: %s: unable to create lookup table for multiple materials.\n", + __func__); + return 0; + } + return 1; } diff --git a/src/common/libmmgtypes.h b/src/common/libmmgtypes.h index b5d382dad..55d1725b2 100644 --- a/src/common/libmmgtypes.h +++ b/src/common/libmmgtypes.h @@ -467,6 +467,13 @@ typedef struct { } MMG5_Mat; typedef MMG5_Mat * MMG5_pMat; +typedef struct { + int offset; + int size; + int *lookup; +} MMG5_InvMat; +typedef MMG5_InvMat * MMG5_pInvMat; + /** * \struct MMG5_Info * \brief Store input parameters of the run. @@ -500,6 +507,7 @@ typedef struct { uint8_t optim, optimLES, noinsert, noswap, nomove, nosurf, nosizreq; uint8_t metRidTyp; /*!< 0 for a classical storage of the aniso metric at ridge, 1 for the Mmg storage (modified by defsiz) */ MMG5_pMat mat; + MMG5_InvMat invmat; } MMG5_Info; /** diff --git a/src/common/mmg2.c b/src/common/mmg2.c index 5579ca23f..d2df59db4 100644 --- a/src/common/mmg2.c +++ b/src/common/mmg2.c @@ -34,6 +34,106 @@ #include "mmgcommon.h" +static int MMG5_InvMat_key(MMG5_pInvMat pim,int ref) { + return (ref - pim->offset); +} + +static void MMG5_InvMat_set(MMG5_pInvMat pim,MMG5_pMat pm) { + /** Store the dosplit attribute of the parent material */ + pim->lookup[MMG5_InvMat_key(pim,pm->ref)] = pm->dospl; + + /** Store the child material sign with the parent material reference. + * 1) 0 is a legit material reference, so store the parent as 4*(ref+1). + * 2) If a child material has the same reference as the parent, this + * effectively overwrites the result of the previous instruction. + * 3) No different child materials are allowed to have the same reference, + * and this must have already been checked. */ + if( pm->dospl ) { + pim->lookup[MMG5_InvMat_key(pim,pm->rin)] = 4*(pm->ref+1)+MG_MINUS; + pim->lookup[MMG5_InvMat_key(pim,pm->rex)] = 4*(pm->ref+1)+MG_PLUS; + } +} + +static int MMG5_InvMat_getParent(MMG5_pInvMat pim,int ref) { + int key = MMG5_InvMat_key(pim,ref); + /* The parent is stored as 4*(ref+1) */ + return (pim->lookup[key] / 4 - 1); +} + +static int MMG5_InvMat_getTag(MMG5_pInvMat pim,int ref) { + int key = MMG5_InvMat_key(pim,ref); + /* The nosplit/split/plus/minus attribute is stored as the rest of the + * integer division. */ + return (pim->lookup[key] % 4); +} + +static void MMG5_InvMat_print(MMG5_pInvMat pim) { + int ref; + + for( ref = pim->offset; ref < pim->offset + pim->size; ref++ ) { + printf("%d (%d): %d %d\n",ref,MMG5_InvMat_key(pim,ref), + MMG5_InvMat_getParent(pim,ref),MMG5_InvMat_getTag(pim,ref)); + } +} + +int MMG5_MultiMat_init(MMG5_pMesh mesh) { + MMG5_pMat pm; + MMG5_pInvMat pim; + int k; + int refmax,refmin; + + /* Nothing to do if no multi-material option */ + if( !mesh->info.nmat ) return 1; + + /* Error if all the materials have not been set */ + if( mesh->info.nmati < mesh->info.nmat ) { + fprintf(stderr,"\n ## Error: %s: Only %d materials out of %d have been set.\n", + __func__,mesh->info.nmati,mesh->info.nmat); + return 0; + } + + /* Get pointer to the structure */ + pim = &mesh->info.invmat; + + /* Initialize the max and min reference */ + refmax = 0; + refmin = INT_MAX; + + /* Look for the max/min reference */ + for( k = 0; k < mesh->info.nmat; k++ ) { + pm = &mesh->info.mat[k]; + /* Update max and min val for original ref */ + if( pm->ref > refmax ) refmax = pm->ref; + if( pm->ref < refmin ) refmin = pm->ref; + if( !pm->dospl ) continue; + /* Update max and min val with interior ref */ + if( pm->rin > refmax ) refmax = pm->rin; + if( pm->rin < refmin ) refmin = pm->rin; + /* Update max and min val with exterior ref */ + if( pm->rex > refmax ) refmax = pm->rex; + if( pm->rex < refmin ) refmin = pm->rex; + } + + /* Get span of the lookup table */ + pim->offset = refmin; + pim->size = refmax - refmin + 1; + assert( pim->size > 0 ); + + /* Allocate lookup table */ + MMG5_ADD_MEM(mesh,pim->size*sizeof(int),"materials lookup table",return 0); + MMG5_SAFE_CALLOC(pim->lookup,pim->size,int,return 0); + + /* Fill lookup table */ + for( k = 0; k < mesh->info.nmat; k++ ) { + pm = &mesh->info.mat[k]; + MMG5_InvMat_set(pim,pm); + } + + return 1; +} + + + /** * \param mesh pointer toward the mesh structure. * \param ref initial reference. @@ -80,39 +180,28 @@ int MMG5_isSplit(MMG5_pMesh mesh,int ref,int *refint,int *refext) { * */ int MMG5_isNotSplit(MMG5_pMesh mesh,int ref) { - MMG5_pMat pm; - int k; + MMG5_pInvMat pim; + int8_t k; /* Split material by default if not in multi-material mode */ if( !mesh->info.nmat ) return 0; - for (k=0; kinfo.nmat; k++) { - pm = &mesh->info.mat[k]; - if ( pm->ref == ref ) { - if ( !pm->dospl ) { - return 1; - } else return 0; - } - } + /* Look in the table otherwise */ + pim = &mesh->info.invmat; + if( !MMG5_InvMat_getTag(pim,ref) ) + return 0; + else + return 1; + } int MMG5_isLevelSet(MMG5_pMesh mesh,int ref0,int ref1) { - MMG5_pMat pm; - int k; - int found0,found1; + MMG5_pInvMat pim; + int8_t found0,found1; - for (k=0; kinfo.nmat; k++) { - pm = &mesh->info.mat[k]; - if( pm->ref == ref0 ) { found0 = MG_NOTAG; break; } - if( pm->rin == ref0 ) { found0 = MG_PLUS; break; } - if( pm->rex == ref0 ) { found0 = MG_MINUS; break; } - } - for (k=0; kinfo.nmat; k++) { - pm = &mesh->info.mat[k]; - if( pm->ref == ref1 ) { found1 = MG_NOTAG; break; } - if( pm->rin == ref1 ) { found1 = MG_PLUS; break; } - if( pm->rex == ref1 ) { found1 = MG_MINUS; break; } - } + pim = &mesh->info.invmat; + found0 = MMG5_InvMat_getTag(pim,ref0); + found1 = MMG5_InvMat_getTag(pim,ref1); if( (found0+found1) == (MG_MINUS+MG_PLUS) ) return 1; else return 0; @@ -128,19 +217,18 @@ int MMG5_isLevelSet(MMG5_pMesh mesh,int ref0,int ref1) { * */ int MMG5_getIniRef(MMG5_pMesh mesh,int ref) { - MMG5_pMat pm; - int k; + MMG5_pInvMat pim; + int k; - for (k=0; kinfo.nmat; k++) { - pm = &mesh->info.mat[k]; - if ( pm->ref == ref && !pm->dospl ) return pm->ref; - if ( ref == pm->rin || ref == pm->rex ) return pm->ref; - } + /* No materials */ + if( !mesh->info.nmat ) return 0; - if ( k==0 ) { - /* No materials */ - return 0; - } + /* Get parent of material */ + pim = &mesh->info.invmat; + k = MMG5_InvMat_getParent(pim,ref); + + /* The current material is the parent */ + if( k == -1 ) k = ref; - return ref; + return k; } diff --git a/src/common/mmgcommon.h b/src/common/mmgcommon.h index a2fd7d6cb..fb2aba297 100644 --- a/src/common/mmgcommon.h +++ b/src/common/mmgcommon.h @@ -725,6 +725,7 @@ int MMG5_updatemetreq_ani(double *n,double dn[2],double vp[2][2]); int MMG5_swapbin(int sbin); float MMG5_swapf(float sbin); double MMG5_swapd(double sbin); +int MMG5_MultiMat_init(MMG5_pMesh); int MMG5_isLevelSet(MMG5_pMesh,int,int); int MMG5_isSplit(MMG5_pMesh ,int ,int *,int *); int MMG5_isNotSplit(MMG5_pMesh ,int); diff --git a/src/mmg2d/libmmg2d_tools.c b/src/mmg2d/libmmg2d_tools.c index ae53f76ae..1e28e0369 100644 --- a/src/mmg2d/libmmg2d_tools.c +++ b/src/mmg2d/libmmg2d_tools.c @@ -124,6 +124,11 @@ int MMG2D_parsop(MMG5_pMesh mesh,MMG5_pSol met) { pm->dospl = 1; } } + if( !MMG5_MultiMat_init(mesh) ) { + fprintf(stderr," %%%% Error: %s: unable to create lookup table for multiple materials.\n", + __func__); + return 0; + } } } /* Read user-defined local parameters and store them in the structure info->par */ From e69abeb038b517a624aeab471995d6a74cddb810 Mon Sep 17 00:00:00 2001 From: luca Date: Mon, 14 Dec 2020 22:04:03 +0100 Subject: [PATCH 033/170] Change hash so that it can store the index in the lookup table. Less ambiguous name getIniRef -> getStartRef. Put error code in getStartRef. --- src/common/mmg2.c | 118 ++++++++++++++++++++++++++--------------- src/common/mmgcommon.h | 2 +- src/mmg2d/mmg2d6.c | 2 +- src/mmg3d/mmg3d2.c | 2 +- 4 files changed, 78 insertions(+), 46 deletions(-) diff --git a/src/common/mmg2.c b/src/common/mmg2.c index d2df59db4..7f34648eb 100644 --- a/src/common/mmg2.c +++ b/src/common/mmg2.c @@ -38,26 +38,52 @@ static int MMG5_InvMat_key(MMG5_pInvMat pim,int ref) { return (ref - pim->offset); } -static void MMG5_InvMat_set(MMG5_pInvMat pim,MMG5_pMat pm) { +static int MMG5_InvMat_index(MMG5_pInvMat pim,int ref) { + int key = MMG5_InvMat_key(pim,ref); + /* The parent index is stored as 4*(k+1) */ + return (pim->lookup[key] / 4 - 1); +} + +static void MMG5_InvMat_set(MMG5_pMesh mesh,MMG5_pInvMat pim,int k) { + MMG5_pMat pm; + int key; + + /* Get material */ + pm = &mesh->info.mat[k]; + /** Store the dosplit attribute of the parent material */ - pim->lookup[MMG5_InvMat_key(pim,pm->ref)] = pm->dospl; + key = MMG5_InvMat_key(pim,pm->ref); + pim->lookup[key] = 4*(k+1)+pm->dospl; - /** Store the child material sign with the parent material reference. - * 1) 0 is a legit material reference, so store the parent as 4*(ref+1). + /** Store the child material sign with the parent material index (in the + * lookup table). + * 1) 0 is a legit material index, so store the parent as 4*(k+1). * 2) If a child material has the same reference as the parent, this * effectively overwrites the result of the previous instruction. * 3) No different child materials are allowed to have the same reference, * and this must have already been checked. */ if( pm->dospl ) { - pim->lookup[MMG5_InvMat_key(pim,pm->rin)] = 4*(pm->ref+1)+MG_MINUS; - pim->lookup[MMG5_InvMat_key(pim,pm->rex)] = 4*(pm->ref+1)+MG_PLUS; + key = MMG5_InvMat_key(pim,pm->rin); + pim->lookup[key] = 4*(k+1)+MG_MINUS; + key = MMG5_InvMat_key(pim,pm->rex); + pim->lookup[key] = 4*(k+1)+MG_PLUS; } } -static int MMG5_InvMat_getParent(MMG5_pInvMat pim,int ref) { - int key = MMG5_InvMat_key(pim,ref); - /* The parent is stored as 4*(ref+1) */ - return (pim->lookup[key] / 4 - 1); +static int MMG5_InvMat_getParent(MMG5_pMesh mesh,MMG5_pInvMat pim,int ref,int *pref) { + MMG5_pMat pm; + int k; + + /* The parent index */ + k = MMG5_InvMat_index(pim,ref); + + /* Material not found in the table */ + if( k == -1 ) return 0; + + /* Get the material in the lookup table and return the parent reference */ + pm = &mesh->info.mat[k]; + *pref = pm->ref; + return 1; } static int MMG5_InvMat_getTag(MMG5_pInvMat pim,int ref) { @@ -67,12 +93,14 @@ static int MMG5_InvMat_getTag(MMG5_pInvMat pim,int ref) { return (pim->lookup[key] % 4); } -static void MMG5_InvMat_print(MMG5_pInvMat pim) { - int ref; +static void MMG5_InvMat_print(MMG5_pMesh mesh,MMG5_pInvMat pim) { + int ref,pref; + /* Scan all references in the table limits, some may not exist */ for( ref = pim->offset; ref < pim->offset + pim->size; ref++ ) { - printf("%d (%d): %d %d\n",ref,MMG5_InvMat_key(pim,ref), - MMG5_InvMat_getParent(pim,ref),MMG5_InvMat_getTag(pim,ref)); + if( !MMG5_InvMat_getParent(mesh,pim,ref,&pref) ) continue; + printf("%d (%d): %d %d\n",ref,MMG5_InvMat_key(pim,ref),pref, + MMG5_InvMat_getTag(pim,ref)); } } @@ -125,10 +153,10 @@ int MMG5_MultiMat_init(MMG5_pMesh mesh) { /* Fill lookup table */ for( k = 0; k < mesh->info.nmat; k++ ) { - pm = &mesh->info.mat[k]; - MMG5_InvMat_set(pim,pm); + MMG5_InvMat_set(mesh,pim,k); } +// MMG5_InvMat_print(mesh,pim); return 1; } @@ -146,29 +174,31 @@ int MMG5_MultiMat_init(MMG5_pMesh mesh) { * */ int MMG5_isSplit(MMG5_pMesh mesh,int ref,int *refint,int *refext) { + MMG5_pInvMat pim; MMG5_pMat pm; int k; - /* Check in the info->mat table if reference ref is supplied by the user */ - for (k=0; kinfo.nmat; k++) { - pm = &mesh->info.mat[k]; - if ( pm->ref == ref ) { - if ( !pm->dospl ) { - return 0; - } - else { - *refint = pm->rin; - *refext = pm->rex; - return 1; - } - } + /* Default case: split with references MG_MINUS, MG_PLUS */ + if( !mesh->info.nmat ) { + *refint = MG_MINUS; + *refext = MG_PLUS; + return 1; } - /* Default case: split with references MG_MINUS, MG_PLUS */ - *refint = MG_MINUS; - *refext = MG_PLUS; - return 1; + /* Check in the info->mat table if reference ref is supplied by the user */ + pim = &mesh->info.invmat; + k = MMG5_InvMat_index(pim,ref); + assert( k != -1 ); + pm = &mesh->info.mat[k]; + + if ( !pm->dospl ) { + return 0; + } else { + *refint = pm->rin; + *refext = pm->rex; + return 1; + } } /** @@ -213,22 +243,24 @@ int MMG5_isLevelSet(MMG5_pMesh mesh,int ref0,int ref1) { * \param ref final reference for which we are searching the initial one * \return initial reference associated to \a ref if founded, \a ref if not founded. * - * Retrieve the initial domain reference associated to the (split) reference ref. + * Retrieve the starting domain reference associated to the (split) reference ref. * */ -int MMG5_getIniRef(MMG5_pMesh mesh,int ref) { +int MMG5_getStartRef(MMG5_pMesh mesh,int ref,int *pref) { MMG5_pInvMat pim; - int k; - /* No materials */ - if( !mesh->info.nmat ) return 0; + /* No multi-materials nor single material reference preservation */ + if( !mesh->info.nmat ) { + *pref = 0; + return 1; + } /* Get parent of material */ pim = &mesh->info.invmat; - k = MMG5_InvMat_getParent(pim,ref); - /* The current material is the parent */ - if( k == -1 ) k = ref; - - return k; + /* Return 0 if the material does not exist, 1 otherwise */ + if( !MMG5_InvMat_getParent(mesh,pim,ref,pref) ) + return 0; + else + return 1; } diff --git a/src/common/mmgcommon.h b/src/common/mmgcommon.h index fb2aba297..6d8197f2a 100644 --- a/src/common/mmgcommon.h +++ b/src/common/mmgcommon.h @@ -729,7 +729,7 @@ int MMG5_MultiMat_init(MMG5_pMesh); int MMG5_isLevelSet(MMG5_pMesh,int,int); int MMG5_isSplit(MMG5_pMesh ,int ,int *,int *); int MMG5_isNotSplit(MMG5_pMesh ,int); -int MMG5_getIniRef(MMG5_pMesh ,int ); +int MMG5_getStartRef(MMG5_pMesh ,int, int *); /* tools */ diff --git a/src/mmg2d/mmg2d6.c b/src/mmg2d/mmg2d6.c index f7e76f9dd..119bb5c0f 100644 --- a/src/mmg2d/mmg2d6.c +++ b/src/mmg2d/mmg2d6.c @@ -209,7 +209,7 @@ int MMG2D_resetRef(MMG5_pMesh mesh) { for (k=1; k<=mesh->nt; k++) { pt = &mesh->tria[k]; if ( !pt->v[0] ) continue; - ref = MMG5_getIniRef(mesh,pt->ref); + if( !MMG5_getStartRef(mesh,pt->ref,&ref) ) return 0; pt->ref = ref; } diff --git a/src/mmg3d/mmg3d2.c b/src/mmg3d/mmg3d2.c index acd5bbcbf..673740c37 100755 --- a/src/mmg3d/mmg3d2.c +++ b/src/mmg3d/mmg3d2.c @@ -341,7 +341,7 @@ int MMG3D_resetRef(MMG5_pMesh mesh) { if ( !MG_EOK(pt) ) continue; - ref = MMG5_getIniRef(mesh,pt->ref); + if( !MMG5_getStartRef(mesh,pt->ref,&ref) ) return 0; pt->ref = ref; } From 68691325d591a57097eaadea4cdd811d2bf3b1e9 Mon Sep 17 00:00:00 2001 From: luca Date: Thu, 7 Jan 2021 15:54:27 +0100 Subject: [PATCH 034/170] Fix check on discrete levelset in single mat mode. --- src/common/mmg2.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/common/mmg2.c b/src/common/mmg2.c index 7f34648eb..c0d22a3e7 100644 --- a/src/common/mmg2.c +++ b/src/common/mmg2.c @@ -225,17 +225,35 @@ int MMG5_isNotSplit(MMG5_pMesh mesh,int ref) { } +/** + * \param mesh pointer toward the mesh structure. + * \param ref0 reference of the first tetrahedron sharing the face. + * \param ref1 reference of the second tetrahedron sharing the face.. + * \return 1 if face is on the discrete level set, 0 if not. + * + * Identify whether a face is on the discrete level set or not. + * + */ int MMG5_isLevelSet(MMG5_pMesh mesh,int ref0,int ref1) { MMG5_pInvMat pim; int8_t found0,found1; - pim = &mesh->info.invmat; - found0 = MMG5_InvMat_getTag(pim,ref0); - found1 = MMG5_InvMat_getTag(pim,ref1); + /* Check whether multimaterial case or not */ + if( mesh->info.nmat ) { + /* Retrieve levelset information from the lookup table */ + pim = &mesh->info.invmat; + found0 = MMG5_InvMat_getTag(pim,ref0); + found1 = MMG5_InvMat_getTag(pim,ref1); - if( (found0+found1) == (MG_MINUS+MG_PLUS) ) return 1; - else return 0; + if( (found0+found1) == (MG_MINUS+MG_PLUS) ) return 1; + else return 0; + } else { + /* Single material, check references directly */ + if( ( ref0 == MG_MINUS && ref1 == MG_PLUS ) || + ( ref1 == MG_MINUS && ref0 == MG_PLUS ) ) return 1; + else return 0; + } } /** From 5f085bd7038fc2a68e0d3947590734d154e14e9d Mon Sep 17 00:00:00 2001 From: luca Date: Thu, 7 Jan 2021 17:01:43 +0100 Subject: [PATCH 035/170] Extensive documentation for multimaterial initialization. --- src/common/mmg2.c | 82 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 2 deletions(-) diff --git a/src/common/mmg2.c b/src/common/mmg2.c index c0d22a3e7..c58a360d2 100644 --- a/src/common/mmg2.c +++ b/src/common/mmg2.c @@ -104,6 +104,82 @@ static void MMG5_InvMat_print(MMG5_pMesh mesh,MMG5_pInvMat pim) { } } +/** + * \param mesh pointer toward the mesh structure. + * \return 1 if success, 0 if fail. + * + * + * Initialize handling of multimaterial mode. + * + * An indexed table of materials has been provided by the MMG5_Mat datatype in + * the form: + * + * index | dospl | ref | rin | rex + * ------------------------------------------------------- + * 0 | dospl_0 | ref_0 | rin_0 | rex_0 + * ... | ... | ... | ... | + * k | dospl_k | ref_k | rin_k | rex_k + * ... | ... | ... | ... | + * n-1 | dospl_{n-1} | ref_{n-1} | rin_{n-1} | rex_{n-1} + * + * where dospl is the split/preserve character of the material, and rin,rex + * are its child materials (if dospl). Viceversa, ref is the parent material + * for rin,rex. + * + * Here a lookup table for material references is built through trivial hashing + * for all references (both parent and child materials) with the key: + * + * key = ref - ref_min, ref_min = min_{k = 0,n-1} (ref_k, rin_k, rex_k) + * + * For all references, it is important to store + * - the index k of the row in the original table, + * - the character (parent-split, parent-preserve, child-interior, + * child-exterior) of the material. + * + * Since + * dospl = 0 or 1, MG_PLUS = 2, and MG_MINUS = 3 + * + * we can store the character as dospl (for the parent material) or MG_MINUS/ + * MG_PLUS (for the child materials), with its value ranging between 0 and 3. + * + * A convenient entry to store both the index and the character in the lookup + * table is thus: + * + * entry = 4*(index+1) + character + * + * leading to a lookup table in the form (the key ordering is only an example): + * + * key | entry + * ------------------------ + * ... | ... + * ref_k | 4*(k+1)+dospl_k + * ... | ... + * rin_k | 4*(k+1)+MG_MINUS + * ... | ... + * rex_k | 4*(k+1)+MG_PLUS + * ... | ... + * + * where the index and the character of the material can be retrieved as + * + * index = entry / 4 -1 + * character = entry % 4 + * + * + * What if two materials have the same reference? + * - child references should be distinct (the entry in the lookup table would + * be overwritten), + * - a parent material can have itself as child (a positive character would say + * it should be split, the character value would say if it is interior or + * exterior). + * Thus, each of the maps parent->child_in and parent->child_ext is injective, + * but a fixed point is allowed. + * + * Why child materials should be different? + * - because on failure it is necessary to recover the parent references and + * apply them on the tetrahedra to restore the starting materials + * distribution. + * + */ int MMG5_MultiMat_init(MMG5_pMesh mesh) { MMG5_pMat pm; MMG5_pInvMat pim; @@ -259,9 +335,11 @@ int MMG5_isLevelSet(MMG5_pMesh mesh,int ref0,int ref1) { /** * \param mesh pointer toward the mesh * \param ref final reference for which we are searching the initial one - * \return initial reference associated to \a ref if founded, \a ref if not founded. + * \param pref pointer to the reference of the parent material. + * \return 1 if found, 0 otherwise. * - * Retrieve the starting domain reference associated to the (split) reference ref. + * Retrieve the starting domain reference (parent material) associated to the + * split reference ref. * */ int MMG5_getStartRef(MMG5_pMesh mesh,int ref,int *pref) { From 7510c9dc24f8a1ab40e46bc7958b9a4879a6051c Mon Sep 17 00:00:00 2001 From: luca Date: Thu, 7 Jan 2021 17:25:40 +0100 Subject: [PATCH 036/170] Continue documentation. --- src/common/mmg2.c | 79 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 60 insertions(+), 19 deletions(-) diff --git a/src/common/mmg2.c b/src/common/mmg2.c index c58a360d2..52e31e8d5 100644 --- a/src/common/mmg2.c +++ b/src/common/mmg2.c @@ -34,16 +34,37 @@ #include "mmgcommon.h" +/** + * \param pim multimaterials inverse data table. + * \param ref material reference. + * \return the key of the material in the lookup/hash table. + * + * Compute key for the material in the hash table. + */ static int MMG5_InvMat_key(MMG5_pInvMat pim,int ref) { return (ref - pim->offset); } -static int MMG5_InvMat_index(MMG5_pInvMat pim,int ref) { +/** + * \param pim multimaterials inverse data table. + * \param ref material reference. + * \return Index of the material. + * + * Get index of the material from lookup table. + */ +static int MMG5_InvMat_getIndex(MMG5_pInvMat pim,int ref) { int key = MMG5_InvMat_key(pim,ref); /* The parent index is stored as 4*(k+1) */ return (pim->lookup[key] / 4 - 1); } +/** + * \param mesh pointer toward the mesh structure. + * \param pim multimaterials inverse data table. + * \param k index of the material in the input table. + * + * Set materials lookup table entry. + */ static void MMG5_InvMat_set(MMG5_pMesh mesh,MMG5_pInvMat pim,int k) { MMG5_pMat pm; int key; @@ -70,12 +91,22 @@ static void MMG5_InvMat_set(MMG5_pMesh mesh,MMG5_pInvMat pim,int k) { } } +/** + * \param mesh pointer toward the mesh structure. + * \param pim multimaterials inverse data table. + * \param ref material reference. + * \param pref pointer to the parent material reference. + * \return 1 if found, 0 if not found. + * + * Get reference of the parent material in multimaterial mode. + *. + */ static int MMG5_InvMat_getParent(MMG5_pMesh mesh,MMG5_pInvMat pim,int ref,int *pref) { MMG5_pMat pm; int k; /* The parent index */ - k = MMG5_InvMat_index(pim,ref); + k = MMG5_InvMat_getIndex(pim,ref); /* Material not found in the table */ if( k == -1 ) return 0; @@ -86,13 +117,25 @@ static int MMG5_InvMat_getParent(MMG5_pMesh mesh,MMG5_pInvMat pim,int ref,int *p return 1; } -static int MMG5_InvMat_getTag(MMG5_pInvMat pim,int ref) { +/** + * \param mesh pointer toward the mesh structure. + * \param pim multimaterials inverse data table. + * \param ref material reference. + * \return the nosplit/split/plus/minus attribute of the material. + */ +static int MMG5_InvMat_getAttrib(MMG5_pInvMat pim,int ref) { int key = MMG5_InvMat_key(pim,ref); /* The nosplit/split/plus/minus attribute is stored as the rest of the * integer division. */ return (pim->lookup[key] % 4); } +/** + * \param mesh pointer toward the mesh structure. + * \param pim multimaterials inverse data table. + * + * Print materials lookup table. + */ static void MMG5_InvMat_print(MMG5_pMesh mesh,MMG5_pInvMat pim) { int ref,pref; @@ -100,7 +143,7 @@ static void MMG5_InvMat_print(MMG5_pMesh mesh,MMG5_pInvMat pim) { for( ref = pim->offset; ref < pim->offset + pim->size; ref++ ) { if( !MMG5_InvMat_getParent(mesh,pim,ref,&pref) ) continue; printf("%d (%d): %d %d\n",ref,MMG5_InvMat_key(pim,ref),pref, - MMG5_InvMat_getTag(pim,ref)); + MMG5_InvMat_getAttrib(pim,ref)); } } @@ -122,7 +165,7 @@ static void MMG5_InvMat_print(MMG5_pMesh mesh,MMG5_pInvMat pim) { * ... | ... | ... | ... | * n-1 | dospl_{n-1} | ref_{n-1} | rin_{n-1} | rex_{n-1} * - * where dospl is the split/preserve character of the material, and rin,rex + * where dospl is the split/preserve attribute of the material, and rin,rex * are its child materials (if dospl). Viceversa, ref is the parent material * for rin,rex. * @@ -133,19 +176,19 @@ static void MMG5_InvMat_print(MMG5_pMesh mesh,MMG5_pInvMat pim) { * * For all references, it is important to store * - the index k of the row in the original table, - * - the character (parent-split, parent-preserve, child-interior, + * - the characteristic attribute (parent-split, parent-preserve, child-interior, * child-exterior) of the material. * * Since * dospl = 0 or 1, MG_PLUS = 2, and MG_MINUS = 3 * - * we can store the character as dospl (for the parent material) or MG_MINUS/ + * we can store the attribute as dospl (for the parent material) or MG_MINUS/ * MG_PLUS (for the child materials), with its value ranging between 0 and 3. * - * A convenient entry to store both the index and the character in the lookup + * A convenient entry to store both the index and the attribute in the lookup * table is thus: * - * entry = 4*(index+1) + character + * entry = 4*(index+1) + attribute * * leading to a lookup table in the form (the key ordering is only an example): * @@ -159,17 +202,17 @@ static void MMG5_InvMat_print(MMG5_pMesh mesh,MMG5_pInvMat pim) { * rex_k | 4*(k+1)+MG_PLUS * ... | ... * - * where the index and the character of the material can be retrieved as + * where the index and the attribute of the material can be retrieved as * * index = entry / 4 -1 - * character = entry % 4 + * attribute = entry % 4 * * * What if two materials have the same reference? * - child references should be distinct (the entry in the lookup table would * be overwritten), - * - a parent material can have itself as child (a positive character would say - * it should be split, the character value would say if it is interior or + * - a parent material can have itself as child (a positive attribute would say + * it should be split, the attribute value would say if it is interior or * exterior). * Thus, each of the maps parent->child_in and parent->child_ext is injective, * but a fixed point is allowed. @@ -236,8 +279,6 @@ int MMG5_MultiMat_init(MMG5_pMesh mesh) { return 1; } - - /** * \param mesh pointer toward the mesh structure. * \param ref initial reference. @@ -263,7 +304,7 @@ int MMG5_isSplit(MMG5_pMesh mesh,int ref,int *refint,int *refext) { /* Check in the info->mat table if reference ref is supplied by the user */ pim = &mesh->info.invmat; - k = MMG5_InvMat_index(pim,ref); + k = MMG5_InvMat_getIndex(pim,ref); assert( k != -1 ); pm = &mesh->info.mat[k]; @@ -294,7 +335,7 @@ int MMG5_isNotSplit(MMG5_pMesh mesh,int ref) { /* Look in the table otherwise */ pim = &mesh->info.invmat; - if( !MMG5_InvMat_getTag(pim,ref) ) + if( !MMG5_InvMat_getAttrib(pim,ref) ) return 0; else return 1; @@ -318,8 +359,8 @@ int MMG5_isLevelSet(MMG5_pMesh mesh,int ref0,int ref1) { if( mesh->info.nmat ) { /* Retrieve levelset information from the lookup table */ pim = &mesh->info.invmat; - found0 = MMG5_InvMat_getTag(pim,ref0); - found1 = MMG5_InvMat_getTag(pim,ref1); + found0 = MMG5_InvMat_getAttrib(pim,ref0); + found1 = MMG5_InvMat_getAttrib(pim,ref1); if( (found0+found1) == (MG_MINUS+MG_PLUS) ) return 1; else return 0; From f9bf47133abd4a6d1c2898f8f16dc7e6fcb8b1fa Mon Sep 17 00:00:00 2001 From: luca Date: Thu, 7 Jan 2021 17:29:21 +0100 Subject: [PATCH 037/170] Continue documentation and reordering. --- src/common/mmg2.c | 102 +++++++++++++++++++++++----------------------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/src/common/mmg2.c b/src/common/mmg2.c index 52e31e8d5..a2ffac886 100644 --- a/src/common/mmg2.c +++ b/src/common/mmg2.c @@ -45,19 +45,6 @@ static int MMG5_InvMat_key(MMG5_pInvMat pim,int ref) { return (ref - pim->offset); } -/** - * \param pim multimaterials inverse data table. - * \param ref material reference. - * \return Index of the material. - * - * Get index of the material from lookup table. - */ -static int MMG5_InvMat_getIndex(MMG5_pInvMat pim,int ref) { - int key = MMG5_InvMat_key(pim,ref); - /* The parent index is stored as 4*(k+1) */ - return (pim->lookup[key] / 4 - 1); -} - /** * \param mesh pointer toward the mesh structure. * \param pim multimaterials inverse data table. @@ -91,6 +78,32 @@ static void MMG5_InvMat_set(MMG5_pMesh mesh,MMG5_pInvMat pim,int k) { } } +/** + * \param pim multimaterials inverse data table. + * \param ref material reference. + * \return Index of the material. + * + * Get index of the material from lookup table. + */ +static int MMG5_InvMat_getIndex(MMG5_pInvMat pim,int ref) { + int key = MMG5_InvMat_key(pim,ref); + /* The parent index is stored as 4*(k+1) */ + return (pim->lookup[key] / 4 - 1); +} + +/** + * \param mesh pointer toward the mesh structure. + * \param pim multimaterials inverse data table. + * \param ref material reference. + * \return the nosplit/split/plus/minus attribute of the material. + */ +static int MMG5_InvMat_getAttrib(MMG5_pInvMat pim,int ref) { + int key = MMG5_InvMat_key(pim,ref); + /* The nosplit/split/plus/minus attribute is stored as the rest of the + * integer division. */ + return (pim->lookup[key] % 4); +} + /** * \param mesh pointer toward the mesh structure. * \param pim multimaterials inverse data table. @@ -118,16 +131,32 @@ static int MMG5_InvMat_getParent(MMG5_pMesh mesh,MMG5_pInvMat pim,int ref,int *p } /** - * \param mesh pointer toward the mesh structure. - * \param pim multimaterials inverse data table. - * \param ref material reference. - * \return the nosplit/split/plus/minus attribute of the material. + * \param mesh pointer toward the mesh + * \param ref final reference for which we are searching the initial one + * \param pref pointer to the reference of the parent material. + * \return 1 if found, 0 otherwise. + * + * Retrieve the starting domain reference (parent material) associated to the + * split reference ref. Allow the call in non-multimaterial mode. + * */ -static int MMG5_InvMat_getAttrib(MMG5_pInvMat pim,int ref) { - int key = MMG5_InvMat_key(pim,ref); - /* The nosplit/split/plus/minus attribute is stored as the rest of the - * integer division. */ - return (pim->lookup[key] % 4); +int MMG5_getStartRef(MMG5_pMesh mesh,int ref,int *pref) { + MMG5_pInvMat pim; + + /* No multi-materials nor single material reference preservation */ + if( !mesh->info.nmat ) { + *pref = 0; + return 1; + } + + /* Get parent of material */ + pim = &mesh->info.invmat; + + /* Return 0 if the material does not exist, 1 otherwise */ + if( !MMG5_InvMat_getParent(mesh,pim,ref,pref) ) + return 0; + else + return 1; } /** @@ -372,32 +401,3 @@ int MMG5_isLevelSet(MMG5_pMesh mesh,int ref0,int ref1) { else return 0; } } - -/** - * \param mesh pointer toward the mesh - * \param ref final reference for which we are searching the initial one - * \param pref pointer to the reference of the parent material. - * \return 1 if found, 0 otherwise. - * - * Retrieve the starting domain reference (parent material) associated to the - * split reference ref. - * - */ -int MMG5_getStartRef(MMG5_pMesh mesh,int ref,int *pref) { - MMG5_pInvMat pim; - - /* No multi-materials nor single material reference preservation */ - if( !mesh->info.nmat ) { - *pref = 0; - return 1; - } - - /* Get parent of material */ - pim = &mesh->info.invmat; - - /* Return 0 if the material does not exist, 1 otherwise */ - if( !MMG5_InvMat_getParent(mesh,pim,ref,pref) ) - return 0; - else - return 1; -} From 32709d647aacd5d96031dc0d5a69df56df208503 Mon Sep 17 00:00:00 2001 From: luca Date: Thu, 7 Jan 2021 17:55:46 +0100 Subject: [PATCH 038/170] Continue documentation. --- src/common/libmmgtypes.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/common/libmmgtypes.h b/src/common/libmmgtypes.h index 55d1725b2..dc8b6fb15 100644 --- a/src/common/libmmgtypes.h +++ b/src/common/libmmgtypes.h @@ -467,6 +467,10 @@ typedef struct { } MMG5_Mat; typedef MMG5_Mat * MMG5_pMat; +/** + * \struct MMG5_InvMat + * \brief To store lookup table for references in the mesh (useful in LS mode) + */ typedef struct { int offset; int size; From d513648294f22493a59e3e0f862a74c9c9955c14 Mon Sep 17 00:00:00 2001 From: luca Date: Thu, 7 Jan 2021 17:57:03 +0100 Subject: [PATCH 039/170] Same multimaterial initialization in 2D as in 3D. --- src/mmg2d/libmmg2d_tools.c | 44 ++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/src/mmg2d/libmmg2d_tools.c b/src/mmg2d/libmmg2d_tools.c index 1e28e0369..7d01204dd 100644 --- a/src/mmg2d/libmmg2d_tools.c +++ b/src/mmg2d/libmmg2d_tools.c @@ -66,7 +66,7 @@ void MMG2D_setfunc(MMG5_pMesh mesh,MMG5_pSol met) { * */ int MMG2D_parsop(MMG5_pMesh mesh,MMG5_pSol met) { - int ret,ref,i,j,npar; + int ret,ref,i,j,npar,rin,rex,split; float fp1,fp2,fp3; char *ptr,data[256]; FILE *in; @@ -97,36 +97,28 @@ int MMG2D_parsop(MMG5_pMesh mesh,MMG5_pSol met) { /* Read user-defined references for the LS mode */ if ( !strcmp(data,"lsreferences") ) { - ret = fscanf(in,"%d",&mesh->info.nmat); - + ret = fscanf(in,"%d",&npar); if ( !ret ) { - fprintf(stderr," %%%% Wrong format for lsreferences: %d\n",mesh->info.nmat); + fprintf(stderr," %%%% Wrong format for lsreferences: %d\n",npar); return (0); } - if ( mesh->info.nmat ) { - MMG5_ADD_MEM(mesh,(mesh->info.nmat)*sizeof(MMG5_Mat),"multi material params",return 0); - MMG5_SAFE_CALLOC(mesh->info.mat,mesh->info.nmat,MMG5_Mat,return 0); - for (i=0; iinfo.nmat; i++) { - pm = &mesh->info.mat[i]; - MMG_FSCANF(in,"%d",&pm->ref); - fgetpos(in,&position); - MMG_FSCANF(in,"%255s",data); - if ( !strcmp(data,"nosplit") ) { - pm->dospl = 0; - pm->rin = pm->ref; - pm->rex = pm->ref; - } - else { - fsetpos(in,&position); - MMG_FSCANF(in,"%d",&pm->rin); - MMG_FSCANF(in,"%d",&pm->rex); - pm->dospl = 1; - } + if ( !MMG2D_Set_iparameter(mesh,met,MMG2D_IPARAM_numberOfMat,npar) ) { + return 0; + } + for (i=0; iinfo.nmat; i++) { + MMG_FSCANF(in,"%d",&ref); + fgetpos(in,&position); + MMG_FSCANF(in,"%255s",data); + split = MMG5_MMAT_NoSplit; + rin = rex = ref; + if ( strcmp(data,"nosplit") ) { + fsetpos(in,&position); + split = MMG5_MMAT_Split; + MMG_FSCANF(in,"%d",&rin); + MMG_FSCANF(in,"%d",&rex); } - if( !MMG5_MultiMat_init(mesh) ) { - fprintf(stderr," %%%% Error: %s: unable to create lookup table for multiple materials.\n", - __func__); + if ( !MMG2D_Set_multiMat(mesh,met,ref,split,rin,rex) ) { return 0; } } From a9b8d561f58a781847e97e7942b73598c5ba17a9 Mon Sep 17 00:00:00 2001 From: luca Date: Wed, 13 Jan 2021 12:03:23 +0100 Subject: [PATCH 040/170] Fix: noinsert actually blocked all mesh operators in mmg2dls. --- src/mmg2d/libmmg2d.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mmg2d/libmmg2d.c b/src/mmg2d/libmmg2d.c index c12cc5495..2b95390bf 100644 --- a/src/mmg2d/libmmg2d.c +++ b/src/mmg2d/libmmg2d.c @@ -865,7 +865,7 @@ int MMG2D_mmg2dls(MMG5_pMesh mesh,MMG5_pSol sol,MMG5_pSol umet) fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT\n"); } - if ( (!mesh->info.noinsert) && !MMG2D_mmg2d1n(mesh,met) ) { + if ( !MMG2D_mmg2d1n(mesh,met) ) { if ( mettofree ) { MMG5_DEL_MEM(mesh,met->m); MMG5_SAFE_FREE (met); From 27a49f2a6d3b9d51b45c2ec77f22df9374e15f19 Mon Sep 17 00:00:00 2001 From: luca Date: Tue, 19 Jan 2021 19:48:58 +0100 Subject: [PATCH 041/170] Don't put MG_ISO on reconstructed triangles on a material interface (not level set). --- src/mmg3d/hash_3d.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mmg3d/hash_3d.c b/src/mmg3d/hash_3d.c index ebc9fcbe9..38f49c72e 100644 --- a/src/mmg3d/hash_3d.c +++ b/src/mmg3d/hash_3d.c @@ -1303,8 +1303,10 @@ int MMG5_bdryTria(MMG5_pMesh mesh, int ntmesh) { /* Triangle at the interface between two tets is set to the user-defined ref if any, or else to MG_ISO ref */ if ( pxt && pxt->ftag[i] & MG_BDY ) ptt->ref = pxt->ref[i]; + else if( MMG5_isLevelSet(mesh,pt->ref,pt1->ref) ) + ptt->ref = MG_ISO; else - ptt->ref = MG_ISO; + ptt->ref = MG_MIN(pt->ref,pt1->ref); } /* useful only when saving mesh or in ls mode */ else { From 452b4b5cd13de7b8f022c214b706f35228de32a7 Mon Sep 17 00:00:00 2001 From: luca Date: Tue, 2 Feb 2021 19:50:36 +0100 Subject: [PATCH 042/170] Repristinate original distance value in case of failed snap in 2D. --- src/mmg2d/mmg2d6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mmg2d/mmg2d6.c b/src/mmg2d/mmg2d6.c index f7e76f9dd..d9242f84b 100644 --- a/src/mmg2d/mmg2d6.c +++ b/src/mmg2d/mmg2d6.c @@ -330,7 +330,7 @@ int MMG2D_snapval(MMG5_pMesh mesh, MMG5_pSol sol) { p0 = &mesh->point[k]; if ( !MG_VOK(p0) ) continue; if ( fabs(sol->m[k]) < MMG5_EPS ) { - tmp[k] = - 100.0*MMG5_EPS; + tmp[k] = sol->m[k]; p0->flag = 1; sol->m[k] = 0.0; ns++; From 28aa74e4a48f689cb3e0d25b15908e541b60d1ce Mon Sep 17 00:00:00 2001 From: luca Date: Mon, 22 Feb 2021 17:41:15 +0100 Subject: [PATCH 043/170] Ease readability of MMG5_mmgHashTria. --- src/common/hash.c | 17 ++++++----------- src/mmg3d/hash_3d.c | 3 ++- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/common/hash.c b/src/common/hash.c index 32080cf70..d38c3a9c3 100644 --- a/src/common/hash.c +++ b/src/common/hash.c @@ -48,7 +48,7 @@ * */ int MMG5_mmgHashTria(MMG5_pMesh mesh, int *adjt, MMG5_Hash *hash, int chkISO) { - MMG5_pTria pt,pt1; + MMG5_pTria pt,pt1,pt2; MMG5_hedge *ph; int *adja,k,kk,jel,lel,hmax,dup,nmf,ia,ib; int8_t i,i1,i2,j,l; @@ -118,22 +118,17 @@ int MMG5_mmgHashTria(MMG5_pMesh mesh, int *adjt, MMG5_Hash *hash, int chkISO) { } /* non-manifold case */ else if ( adja[i] != 3*jel+j ) { + lel = adjt[3*(jel-1)+1+j]/3; + l = adjt[3*(jel-1)+1+j]%3; + pt2 = &mesh->tria[lel]; if ( chkISO && ( (pt->ref == MG_ISO) || (pt->ref < 0)) ) { - lel = adjt[3*(jel-1)+1+j]/3; - l = adjt[3*(jel-1)+1+j]%3; adjt[3*(lel-1)+1+l] = 0; adja[i] = 3*jel+j; adjt[3*(jel-1)+1+j] = 3*k + i; - (mesh->tria[jel]).tag[j] |= MG_GEO + MG_NOM; - (mesh->tria[lel]).tag[l] |= MG_GEO + MG_NOM; - } - else { - lel = adjt[3*(jel-1)+1+j]/3; - l = adjt[3*(jel-1)+1+j]%3; - (mesh->tria[lel]).tag[l] |= MG_GEO + MG_NOM; - pt1->tag[j] |= MG_GEO + MG_NOM; } pt->tag[i] |= MG_GEO + MG_NOM; + pt1->tag[j] |= MG_GEO + MG_NOM; + pt2->tag[l] |= MG_GEO + MG_NOM; nmf++; ++ph->s; } diff --git a/src/mmg3d/hash_3d.c b/src/mmg3d/hash_3d.c index ebc9fcbe9..96fc9bbf7 100644 --- a/src/mmg3d/hash_3d.c +++ b/src/mmg3d/hash_3d.c @@ -1154,9 +1154,10 @@ int MMG5_hGeom(MMG5_pMesh mesh) { if ( !MMG5_hEdge(mesh,&mesh->htab,pt->v[i1],pt->v[i2],pt->edg[i],pt->tag[i]) ) return 0; } - else if ( k < kk && ( pt->edg[i] || pt->tag[i] ) ) + else if ( k < kk && ( pt->edg[i] || pt->tag[i] ) ) { if ( !MMG5_hEdge(mesh,&mesh->htab,pt->v[i1],pt->v[i2],pt->edg[i],pt->tag[i])) return 0; + } } } /* now check triangles */ From a20c4f265987ed22aa5a6e430bdc2a611f2b4ea8 Mon Sep 17 00:00:00 2001 From: luca Date: Mon, 22 Feb 2021 17:49:23 +0100 Subject: [PATCH 044/170] Modify MMG5_mmgHashTria so that adjacency is not build for parallel triangles; intersections of boundary and interfaces will have either a MG_PARBDYBDY tag (manifold case) or a MG_NOM tag (non-manifold case). --- src/common/hash.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/common/hash.c b/src/common/hash.c index d38c3a9c3..04f509335 100644 --- a/src/common/hash.c +++ b/src/common/hash.c @@ -78,6 +78,10 @@ int MMG5_mmgHashTria(MMG5_pMesh mesh, int *adjt, MMG5_Hash *hash, int chkISO) { pt->base = mesh->base; adja = &adjt[3*(k-1)+1]; for (i=0; i<3; i++) { + + /* Skip parallel edges */ + if( pt->tag[i] & MG_PARBDY ) continue; + i1 = MMG5_inxt2[i]; i2 = MMG5_iprv2[i]; @@ -176,6 +180,47 @@ int MMG5_mmgHashTria(MMG5_pMesh mesh, int *adjt, MMG5_Hash *hash, int chkISO) { } } + /* Now loop on parallel edges in order to add a MG_PARBDYBDY tag on those + * that are found in the hash table and their adjacents (if manifold; in the + * non-manifold case the MG_NOM tag suffices). */ + for (k=1; k<=mesh->nt; k++) { + pt = &mesh->tria[k]; + if ( !MG_EOK(pt) ) continue; + for (i=0; i<3; i++) { + if( !(pt->tag[i] & MG_PARBDY) ) continue; + i1 = MMG5_inxt2[i]; + i2 = MMG5_iprv2[i]; + + /* compute key */ + ia = MG_MIN(pt->v[i1],pt->v[i2]); + ib = MG_MAX(pt->v[i1],pt->v[i2]); + key = (MMG5_KA*ia + MMG5_KB*ib) % hash->siz; + ph = &hash->item[key]; + + if ( ph->a == 0 ) continue; + while( ph->a ) { + if ( ph->a == ia && ph->b == ib ) { + jel = ph->k / 3; + j = ph->k % 3; + pt1 = &mesh->tria[jel]; + pt1->tag[j] |= MG_PARBDYBDY; + /* update adjacent */ + lel = adjt[3*(jel-1)+1+j]/3; + l = adjt[3*(jel-1)+1+j]%3; + if( lel ) { + pt2 = &mesh->tria[lel]; + pt2->tag[l] |= MG_PARBDYBDY; + } + break; + } else if ( !ph->nxt ) { + break; + } else { + ph = &hash->item[ph->nxt]; + } + } + } + } + /* set tag */ for (k=1; k<=mesh->nt; k++) { pt = &mesh->tria[k]; From 764861b032171645d32d471aa20a00ca9152ae6d Mon Sep 17 00:00:00 2001 From: luca Date: Mon, 22 Feb 2021 18:28:36 +0100 Subject: [PATCH 045/170] Skip parallel edges in MMG5_hGeom. --- src/mmg3d/hash_3d.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mmg3d/hash_3d.c b/src/mmg3d/hash_3d.c index 96fc9bbf7..741c6de0e 100644 --- a/src/mmg3d/hash_3d.c +++ b/src/mmg3d/hash_3d.c @@ -1081,6 +1081,7 @@ int MMG5_hGeom(MMG5_pMesh mesh) { for (k=1; k<=mesh->nt; k++) { pt = &mesh->tria[k]; for (i=0; i<3; i++) { + if( pt->tag[i] & MG_PARBDY ) continue; i1 = MMG5_inxt2[i]; i2 = MMG5_iprv2[i]; /* transfer non manifold tag to edges */ @@ -1122,6 +1123,7 @@ int MMG5_hGeom(MMG5_pMesh mesh) { pt = &mesh->tria[k]; adja = &mesh->adjt[3*(k-1)+1]; for (i=0; i<3; i++) { + if( pt->tag[i] & MG_PARBDY ) continue; kk = adja[i] / 3; if ( !kk || pt->tag[i] & MG_NOM ) mesh->na++; @@ -1143,6 +1145,7 @@ int MMG5_hGeom(MMG5_pMesh mesh) { pt = &mesh->tria[k]; adja = &mesh->adjt[3*(k-1)+1]; for (i=0; i<3; i++) { + if( pt->tag[i] & MG_PARBDY ) continue; i1 = MMG5_inxt2[i]; i2 = MMG5_iprv2[i]; kk = adja[i] / 3; @@ -1164,6 +1167,7 @@ int MMG5_hGeom(MMG5_pMesh mesh) { for (k=1; k<=mesh->nt; k++) { pt = &mesh->tria[k]; for (i=0; i<3; i++) { + if( pt->tag[i] & MG_PARBDY ) continue; i1 = MMG5_inxt2[i]; i2 = MMG5_iprv2[i]; MMG5_hGet(&mesh->htab,pt->v[i1],pt->v[i2],&edg,&tag); From 4806dd8697d1f87fa42da230d0c579cf4b418212 Mon Sep 17 00:00:00 2001 From: luca Date: Mon, 22 Feb 2021 18:31:29 +0100 Subject: [PATCH 046/170] Skip parallel edges and their adjacents in MMG5_setadj (MG_GEO tags should not be put since adjacency is not built there). --- src/mmg3d/analys_3d.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mmg3d/analys_3d.c b/src/mmg3d/analys_3d.c index a6c78a4d2..3e7f7789a 100644 --- a/src/mmg3d/analys_3d.c +++ b/src/mmg3d/analys_3d.c @@ -118,6 +118,7 @@ int MMG5_setadj(MMG5_pMesh mesh){ adja = &mesh->adjt[3*(k-1)+1]; for (i=0; i<3; i++) { + if( (pt->tag[i] & MG_PARBDY) || (pt->tag[i] & MG_PARBDYBDY) ) continue; i1 = MMG5_inxt2[i]; i2 = MMG5_iprv2[i]; ip1 = pt->v[i1]; From 23d43c2376c7693a12e07dcd522c7f0749fca88b Mon Sep 17 00:00:00 2001 From: luca Date: Tue, 23 Feb 2021 10:59:22 +0100 Subject: [PATCH 047/170] Fix to consider MG_PARBDYBDY triangles: use MG_BDY tag on intersection of simple interfaces with true boundaries. --- src/common/hash.c | 10 +++++----- src/mmg3d/analys_3d.c | 3 ++- src/mmg3d/hash_3d.c | 8 ++++---- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/common/hash.c b/src/common/hash.c index 04f509335..53ee9086a 100644 --- a/src/common/hash.c +++ b/src/common/hash.c @@ -80,7 +80,7 @@ int MMG5_mmgHashTria(MMG5_pMesh mesh, int *adjt, MMG5_Hash *hash, int chkISO) { for (i=0; i<3; i++) { /* Skip parallel edges */ - if( pt->tag[i] & MG_PARBDY ) continue; + if( (pt->tag[i] & MG_PARBDY) && !(pt->tag[i] & MG_PARBDYBDY) ) continue; i1 = MMG5_inxt2[i]; i2 = MMG5_iprv2[i]; @@ -180,14 +180,14 @@ int MMG5_mmgHashTria(MMG5_pMesh mesh, int *adjt, MMG5_Hash *hash, int chkISO) { } } - /* Now loop on parallel edges in order to add a MG_PARBDYBDY tag on those + /* Now loop on "only" parallel edges in order to add a MG_BDY tag on those * that are found in the hash table and their adjacents (if manifold; in the * non-manifold case the MG_NOM tag suffices). */ for (k=1; k<=mesh->nt; k++) { pt = &mesh->tria[k]; if ( !MG_EOK(pt) ) continue; for (i=0; i<3; i++) { - if( !(pt->tag[i] & MG_PARBDY) ) continue; + if( !(pt->tag[i] & MG_PARBDY) || (pt->tag[i] & MG_PARBDYBDY) ) continue; i1 = MMG5_inxt2[i]; i2 = MMG5_iprv2[i]; @@ -203,13 +203,13 @@ int MMG5_mmgHashTria(MMG5_pMesh mesh, int *adjt, MMG5_Hash *hash, int chkISO) { jel = ph->k / 3; j = ph->k % 3; pt1 = &mesh->tria[jel]; - pt1->tag[j] |= MG_PARBDYBDY; + pt1->tag[j] |= MG_BDY; /* update adjacent */ lel = adjt[3*(jel-1)+1+j]/3; l = adjt[3*(jel-1)+1+j]%3; if( lel ) { pt2 = &mesh->tria[lel]; - pt2->tag[l] |= MG_PARBDYBDY; + pt2->tag[l] |= MG_BDY; } break; } else if ( !ph->nxt ) { diff --git a/src/mmg3d/analys_3d.c b/src/mmg3d/analys_3d.c index 3e7f7789a..f8f1432e1 100644 --- a/src/mmg3d/analys_3d.c +++ b/src/mmg3d/analys_3d.c @@ -118,7 +118,8 @@ int MMG5_setadj(MMG5_pMesh mesh){ adja = &mesh->adjt[3*(k-1)+1]; for (i=0; i<3; i++) { - if( (pt->tag[i] & MG_PARBDY) || (pt->tag[i] & MG_PARBDYBDY) ) continue; + if( ((pt->tag[i] & MG_PARBDY) && !(pt->tag[i] & MG_PARBDYBDY)) || + (pt->tag[i] & MG_BDY) ) continue; i1 = MMG5_inxt2[i]; i2 = MMG5_iprv2[i]; ip1 = pt->v[i1]; diff --git a/src/mmg3d/hash_3d.c b/src/mmg3d/hash_3d.c index 741c6de0e..249dcf29a 100644 --- a/src/mmg3d/hash_3d.c +++ b/src/mmg3d/hash_3d.c @@ -1081,7 +1081,7 @@ int MMG5_hGeom(MMG5_pMesh mesh) { for (k=1; k<=mesh->nt; k++) { pt = &mesh->tria[k]; for (i=0; i<3; i++) { - if( pt->tag[i] & MG_PARBDY ) continue; + if( (pt->tag[i] & MG_PARBDY) && !(pt->tag[i] & MG_PARBDYBDY) ) continue; i1 = MMG5_inxt2[i]; i2 = MMG5_iprv2[i]; /* transfer non manifold tag to edges */ @@ -1123,7 +1123,7 @@ int MMG5_hGeom(MMG5_pMesh mesh) { pt = &mesh->tria[k]; adja = &mesh->adjt[3*(k-1)+1]; for (i=0; i<3; i++) { - if( pt->tag[i] & MG_PARBDY ) continue; + if( (pt->tag[i] & MG_PARBDY) && !(pt->tag[i] & MG_PARBDYBDY) ) continue; kk = adja[i] / 3; if ( !kk || pt->tag[i] & MG_NOM ) mesh->na++; @@ -1145,7 +1145,7 @@ int MMG5_hGeom(MMG5_pMesh mesh) { pt = &mesh->tria[k]; adja = &mesh->adjt[3*(k-1)+1]; for (i=0; i<3; i++) { - if( pt->tag[i] & MG_PARBDY ) continue; + if( (pt->tag[i] & MG_PARBDY) && !(pt->tag[i] & MG_PARBDYBDY) ) continue; i1 = MMG5_inxt2[i]; i2 = MMG5_iprv2[i]; kk = adja[i] / 3; @@ -1167,7 +1167,7 @@ int MMG5_hGeom(MMG5_pMesh mesh) { for (k=1; k<=mesh->nt; k++) { pt = &mesh->tria[k]; for (i=0; i<3; i++) { - if( pt->tag[i] & MG_PARBDY ) continue; + if( (pt->tag[i] & MG_PARBDY) && !(pt->tag[i] & MG_PARBDYBDY) ) continue; i1 = MMG5_inxt2[i]; i2 = MMG5_iprv2[i]; MMG5_hGet(&mesh->htab,pt->v[i1],pt->v[i2],&edg,&tag); From b89426d355f8a75804f84a60a1aaac65dec23a34 Mon Sep 17 00:00:00 2001 From: luca Date: Tue, 23 Feb 2021 17:53:41 +0100 Subject: [PATCH 048/170] Avoid tagging as MG_BDY all edges from input triangles (to test). --- src/mmg3d/hash_3d.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/mmg3d/hash_3d.c b/src/mmg3d/hash_3d.c index 249dcf29a..d4c80e294 100644 --- a/src/mmg3d/hash_3d.c +++ b/src/mmg3d/hash_3d.c @@ -1102,8 +1102,6 @@ int MMG5_hGeom(MMG5_pMesh mesh) { if ( mesh->info.nosurf && (tag & MG_REQ) ) pt->tag[i] &= ~MG_NOSURF; - /* Mark edges as boundary edges */ - pt->tag[i] |= (tag | MG_BDY); MMG5_hTag(&mesh->htab,pt->v[i1],pt->v[i2],edg,pt->tag[i]); } } From f8af817e7873d29f68c60ee432b48c081fe89c5c Mon Sep 17 00:00:00 2001 From: luca Date: Wed, 24 Feb 2021 18:34:11 +0100 Subject: [PATCH 049/170] Update MMG5_setdhd to the new MG_BDY tag usage. --- src/mmg3d/analys_3d.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mmg3d/analys_3d.c b/src/mmg3d/analys_3d.c index f8f1432e1..d9f40071d 100644 --- a/src/mmg3d/analys_3d.c +++ b/src/mmg3d/analys_3d.c @@ -302,7 +302,8 @@ int MMG5_setdhd(MMG5_pMesh mesh) { MMG5_nortri(mesh,pt,n1); adja = &mesh->adjt[3*(k-1)+1]; for (i=0; i<3; i++) { - if ( pt->tag[i] & MG_PARBDY ) continue; + if ( ((pt->tag[i] & MG_PARBDY) && !(pt->tag[i] & MG_PARBDYBDY)) || + (pt->tag[i] & MG_BDY) ) continue; kk = adja[i] / 3; ii = adja[i] % 3; From 1c9539628e63d834ade2f5c350cef1faf5205cab Mon Sep 17 00:00:00 2001 From: luca Date: Mon, 1 Mar 2021 15:50:10 +0100 Subject: [PATCH 050/170] Prevent MMG5_bdryTria from adding a spurious MG_BDY tag when filling missing triangles. --- src/mmg3d/hash_3d.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/mmg3d/hash_3d.c b/src/mmg3d/hash_3d.c index d4c80e294..5998ef3a7 100644 --- a/src/mmg3d/hash_3d.c +++ b/src/mmg3d/hash_3d.c @@ -1204,7 +1204,7 @@ int MMG5_bdryTria(MMG5_pMesh mesh, int ntmesh) { MMG5_pxPrism pxpr; MMG5_Hash hash; int ref,*adja,adj,k,ia,ib,ic,kt, tofree=0,ntinit; - int8_t i; + int8_t i,j; hash.item = NULL; @@ -1293,13 +1293,15 @@ int MMG5_bdryTria(MMG5_pMesh mesh, int ntmesh) { if ( pxt ) { /* useful only when saving mesh or in ls mode */ - if ( pxt->tag[MMG5_iarf[i][0]] ) ptt->tag[0] = pxt->tag[MMG5_iarf[i][0]]; - if ( pxt->tag[MMG5_iarf[i][1]] ) ptt->tag[1] = pxt->tag[MMG5_iarf[i][1]]; - if ( pxt->tag[MMG5_iarf[i][2]] ) ptt->tag[2] = pxt->tag[MMG5_iarf[i][2]]; - - if ( pxt->edg[MMG5_iarf[i][0]] ) ptt->edg[0] = pxt->edg[MMG5_iarf[i][0]]; - if ( pxt->edg[MMG5_iarf[i][1]] ) ptt->edg[1] = pxt->edg[MMG5_iarf[i][1]]; - if ( pxt->edg[MMG5_iarf[i][2]] ) ptt->edg[2] = pxt->edg[MMG5_iarf[i][2]]; + for( j = 0; j < 3; j++ ) { + if ( pxt->tag[MMG5_iarf[i][j]] ) { + ptt->tag[j] = pxt->tag[MMG5_iarf[i][j]]; + /* Remove redundant boundary tag */ + ptt->tag[j] &= ~MG_BDY; + } + if ( pxt->edg[MMG5_iarf[i][j]] ) + ptt->edg[j] = pxt->edg[MMG5_iarf[i][j]]; + } } if ( adj ) { if ( mesh->info.iso ) { From 8c94ec13450509d406cf9d9ddf05f38a54cb19bd Mon Sep 17 00:00:00 2001 From: luca Date: Thu, 11 Mar 2021 16:58:04 +0100 Subject: [PATCH 051/170] Fix indexing in MMG2D_Set/Get_tensorSols functions. --- src/mmg2d/API_functions_2d.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mmg2d/API_functions_2d.c b/src/mmg2d/API_functions_2d.c index d98f80291..898304f5a 100644 --- a/src/mmg2d/API_functions_2d.c +++ b/src/mmg2d/API_functions_2d.c @@ -1628,7 +1628,7 @@ int MMG2D_Set_tensorSols(MMG5_pSol met, double *sols) { for ( k=0; knp; ++k ) { j = 3*k; - m = &met->m[j]; + m = &met->m[j+3]; m[1] = sols[j]; m[2] = sols[j+1]; @@ -1643,7 +1643,7 @@ int MMG2D_Get_tensorSols(MMG5_pSol met, double *sols) { for ( k=0; knp; ++k ) { j = 3*k; - m = &met->m[j]; + m = &met->m[j+3]; sols[j] = m[1]; sols[j+1] = m[2]; From 12ddc3a7caa5301c38ee2794259faf7ac063d6be Mon Sep 17 00:00:00 2001 From: Nicolas Barral Date: Thu, 11 Mar 2021 17:58:38 +0100 Subject: [PATCH 052/170] MMG3D API: fix volume computation --- src/mmg3d/API_functions_3d.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mmg3d/API_functions_3d.c b/src/mmg3d/API_functions_3d.c index 4a7592fe4..5ec10ef58 100644 --- a/src/mmg3d/API_functions_3d.c +++ b/src/mmg3d/API_functions_3d.c @@ -651,7 +651,7 @@ int MMG3D_Set_tetrahedra(MMG5_pMesh mesh, int *tetra, int *refs) { vol = MMG5_orvol(mesh->point,pt->v); - if ( vol <= MMG5_EPSD2 ) { + if ( fabs(vol) <= MMG5_EPSD2 ) { fprintf(stderr,"\n ## Error: %s: tetrahedron %d has volume null.\n", __func__,i); From 02c9262fef976c4333a6ef44f76ba3360716d35f Mon Sep 17 00:00:00 2001 From: Nicolas Barral Date: Thu, 11 Mar 2021 18:30:30 +0100 Subject: [PATCH 053/170] MMG2d API: index error of debutant --- src/mmg2d/API_functions_2d.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mmg2d/API_functions_2d.c b/src/mmg2d/API_functions_2d.c index 898304f5a..7fe38362b 100644 --- a/src/mmg2d/API_functions_2d.c +++ b/src/mmg2d/API_functions_2d.c @@ -1626,13 +1626,13 @@ int MMG2D_Set_tensorSols(MMG5_pSol met, double *sols) { return 0; } - for ( k=0; knp; ++k ) { + for ( k=1; k<=met->np; ++k ) { j = 3*k; - m = &met->m[j+3]; + m = &met->m[j]; - m[1] = sols[j]; - m[2] = sols[j+1]; - m[3] = sols[j+2]; + m[0] = sols[j]; + m[1] = sols[j+1]; + m[2] = sols[j+2]; } return 1; } From 91342c339c1d7176be86bab31f00b50ce854f3f0 Mon Sep 17 00:00:00 2001 From: luca Date: Thu, 11 Mar 2021 18:56:08 +0100 Subject: [PATCH 054/170] Fix (again) indices in MMG2D_Set/Get_tensorSols. --- src/mmg2d/API_functions_2d.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mmg2d/API_functions_2d.c b/src/mmg2d/API_functions_2d.c index 7fe38362b..8ed3eccba 100644 --- a/src/mmg2d/API_functions_2d.c +++ b/src/mmg2d/API_functions_2d.c @@ -1626,9 +1626,9 @@ int MMG2D_Set_tensorSols(MMG5_pSol met, double *sols) { return 0; } - for ( k=1; k<=met->np; ++k ) { + for ( k=0; knp; ++k ) { j = 3*k; - m = &met->m[j]; + m = &met->m[j+3]; m[0] = sols[j]; m[1] = sols[j+1]; @@ -1645,9 +1645,9 @@ int MMG2D_Get_tensorSols(MMG5_pSol met, double *sols) { j = 3*k; m = &met->m[j+3]; - sols[j] = m[1]; - sols[j+1] = m[2]; - sols[j+2] = m[3]; + sols[j] = m[0]; + sols[j+1] = m[1]; + sols[j+2] = m[2]; } return 1; From a263872987061c0441aa97e672ec241d31b2af5f Mon Sep 17 00:00:00 2001 From: luca Date: Mon, 22 Mar 2021 19:14:02 +0100 Subject: [PATCH 055/170] Recognize internal boundaries when traveling the shell of an edge to find non-manifold points (in MMG5_boulenm for MMG3D_nmgeom). --- src/mmg3d/boulep_3d.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mmg3d/boulep_3d.c b/src/mmg3d/boulep_3d.c index de6d0b9f8..fd5edc515 100644 --- a/src/mmg3d/boulep_3d.c +++ b/src/mmg3d/boulep_3d.c @@ -246,7 +246,7 @@ int MMG5_boulenm(MMG5_pMesh mesh,int start,int ip,int iface, iopp = MMG5_ifar[i][1]; piv = pt->v[ipiv]; } - isface = (adja[iopp] == 0); + isface = ((adja[iopp] == 0) || (mesh->tetra[adj].ref != pt->ref)); } while ( adj && (adj != nvstart) && !isface ); } From 026c8e7c10d119c0ca071a9c9a87cf81b2535e0f Mon Sep 17 00:00:00 2001 From: CapucineLegentil Date: Wed, 31 Mar 2021 14:51:01 +0200 Subject: [PATCH 056/170] Add nofem option in mmg2d --- src/mmg2d/API_functions_2d.c | 6 +++++- src/mmg2d/libmmg2d.h | 1 + src/mmg2d/mmg2d.c | 5 +++++ src/mmg2d/mmg2d1.c | 5 +++-- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/mmg2d/API_functions_2d.c b/src/mmg2d/API_functions_2d.c index 8ed3eccba..d34288a54 100644 --- a/src/mmg2d/API_functions_2d.c +++ b/src/mmg2d/API_functions_2d.c @@ -84,6 +84,7 @@ void MMG2D_Init_parameters(MMG5_pMesh mesh) { /* default values for integers */ mesh->info.lag = MMG5_LAG; + mesh->info.setfem = MMG5_FEM; mesh->info.optim = MMG5_OFF; /* [0/1] ,avoid/allow surface modifications */ mesh->info.nosurf = MMG5_OFF; @@ -137,6 +138,9 @@ int MMG2D_Set_iparameter(MMG5_pMesh mesh, MMG5_pSol sol, int iparam, int val){ mesh->info.dhd = MMG5_ANGEDG; } break; + case MMG2D_IPARAM_nofem : + mesh->info.setfem = (val==1)? 0 : 1; + break; case MMG2D_IPARAM_opnbdy : mesh->info.opnbdy = val; break; @@ -235,7 +239,7 @@ int MMG2D_Set_iparameter(MMG5_pMesh mesh, MMG5_pSol sol, int iparam, int val){ return 0; } /* other options */ - mesh->info.setfem = MMG5_OFF; + return 1; } diff --git a/src/mmg2d/libmmg2d.h b/src/mmg2d/libmmg2d.h index a1f29a155..39d8746e6 100644 --- a/src/mmg2d/libmmg2d.h +++ b/src/mmg2d/libmmg2d.h @@ -83,6 +83,7 @@ extern "C" { MMG2D_DPARAM_hgradreq, /*!< [val], Control gradation on required entites (advanced usage) */ MMG2D_DPARAM_ls, /*!< [val], Value of level-set */ MMG2D_DPARAM_rmc, /*!< [-1/val], Remove small connex componants in level-set mode */ + MMG2D_IPARAM_nofem, /*!< [1/0], Generate a non finite element mesh */ }; /*----------------------------- functions header -----------------------------*/ diff --git a/src/mmg2d/mmg2d.c b/src/mmg2d/mmg2d.c index ce5d39c04..e49df4eeb 100644 --- a/src/mmg2d/mmg2d.c +++ b/src/mmg2d/mmg2d.c @@ -54,6 +54,7 @@ static int MMG2D_usage(char *name) { fprintf(stdout,"\n"); + fprintf(stdout,"-nofem do not force Mmg to create a finite element mesh \n"); fprintf(stdout,"-nosurf no surface modifications\n"); /* Common parameters (second section) */ @@ -472,6 +473,10 @@ int parsar(int argc,char *argv[],MMG5_pMesh mesh,MMG5_pSol met,MMG5_pSol sol) { } break; case 'n': + if ( !strcmp(argv[i],"-nofem") ) { + if ( !MMG2D_Set_iparameter(mesh,met,MMG2D_IPARAM_nofem,1) ) + return 0; + } if ( !strcmp(argv[i],"-nreg") ) { if ( !MMG2D_Set_iparameter(mesh,met,MMG2D_IPARAM_nreg,1) ) return 0; diff --git a/src/mmg2d/mmg2d1.c b/src/mmg2d/mmg2d1.c index a6753fa3f..3039163c1 100644 --- a/src/mmg2d/mmg2d1.c +++ b/src/mmg2d/mmg2d1.c @@ -45,8 +45,9 @@ int MMG2D_anatri(MMG5_pMesh mesh,MMG5_pSol met,int8_t typchk) { /* Main routine; intertwine split, collapse and swaps */ do { - if ( typchk == 2 && it == 0 ) mesh->info.fem = 1; - + if ( typchk == 2 && it == 0 ) { +#warning Luca: check consistency with 3D + } if ( !mesh->info.noinsert ) { /* Memory free */ MMG5_DEL_MEM(mesh,mesh->adja); From 2768e06c41a2e4190f0e069b59d6488c5f5f8ee0 Mon Sep 17 00:00:00 2001 From: luca Date: Wed, 31 Mar 2021 16:35:04 +0200 Subject: [PATCH 057/170] Detect material interfaces as boundary when checking non-manifold configurations in 2D. --- src/mmg2d/mmg2d6.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/mmg2d/mmg2d6.c b/src/mmg2d/mmg2d6.c index d9242f84b..f4dfaedf9 100644 --- a/src/mmg2d/mmg2d6.c +++ b/src/mmg2d/mmg2d6.c @@ -248,9 +248,10 @@ int MMG2D_ismaniball(MMG5_pMesh mesh, MMG5_pSol sol, int start, int8_t istart) { v2 = sol->m[ip2]; /* Authorize change of references only provided the boundary reference is MG_ISO */ - if ( pt->ref != refstart && pt->edg[i1] != MG_ISO ) + if ( pt->ref != refstart && pt->edg[i1] != MG_ISO ) { smsgn = 0; - else + k = 0; + } else smsgn = (fabs(v1) < MMG5_EPS) || ( (fabs(v2) > MMG5_EPS) && MG_SMSGN(v1,v2) ) ? 1 : 0; // smsgn = MG_SMSGN(v1,v2) ? 1 : 0; } @@ -276,9 +277,10 @@ int MMG2D_ismaniball(MMG5_pMesh mesh, MMG5_pSol sol, int start, int8_t istart) { v1 = sol->m[ip1]; v2 = sol->m[ip2]; - if ( pt->ref != refstart && pt->edg[i1] != MG_ISO ) + if ( pt->ref != refstart && pt->edg[i1] != MG_ISO ) { smsgn = 0; - else + k = 0; + } else smsgn = (fabs(v2) < MMG5_EPS) || ( (fabs(v1) > MMG5_EPS) && MG_SMSGN(v1,v2) ) ? 1 : 0; // smsgn = MG_SMSGN(v1,v2) ? 1 : 0; } From 4e8b5bedb26f670a671246da19302797386e7bee Mon Sep 17 00:00:00 2001 From: luca Date: Fri, 2 Apr 2021 15:41:13 +0200 Subject: [PATCH 058/170] Skip parallel edges and points when checking singularities on non-manifold edges. --- src/mmg3d/hash_3d.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/mmg3d/hash_3d.c b/src/mmg3d/hash_3d.c index 5998ef3a7..f4401615a 100644 --- a/src/mmg3d/hash_3d.c +++ b/src/mmg3d/hash_3d.c @@ -536,6 +536,10 @@ int MMG5_setEdgeNmTag(MMG5_pMesh mesh, MMG5_Hash *hash) { if ( !MG_EOK(ptt) ) continue; for (l=0; l<3; l++) { + + /* Skip edges at the intersection of a parallel interface */ + if ( ptt->tag[l] & MG_BDY ) continue; + if ( ptt->tag[l] & MG_NOM ) { i1 = MMG5_inxt2[l]; i2 = MMG5_iprv2[l]; @@ -699,6 +703,10 @@ int MMG5_setVertexNmTag(MMG5_pMesh mesh) { for ( i=0; i<4; ++i ) { ppt = &mesh->point[ptet->v[i]]; + + /* Skip parallel points */ + if ( ppt->tag & MG_PARBDY ) continue; + if ( (!MG_VOK(ppt)) || (ppt->flag==mesh->base) ) continue; ppt->flag = mesh->base; From 70bb8abe97192e17c625a2a114eb5c030a503afb Mon Sep 17 00:00:00 2001 From: luca Date: Sat, 10 Apr 2021 17:08:08 +0200 Subject: [PATCH 059/170] If a simply parallel edge is found in the hash table, it is not only an intersection edge (MG_BDY) but also a true boundary edge (MG_PARBDYBDY). --- src/common/hash.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/hash.c b/src/common/hash.c index 53ee9086a..27ef9157c 100644 --- a/src/common/hash.c +++ b/src/common/hash.c @@ -203,13 +203,13 @@ int MMG5_mmgHashTria(MMG5_pMesh mesh, int *adjt, MMG5_Hash *hash, int chkISO) { jel = ph->k / 3; j = ph->k % 3; pt1 = &mesh->tria[jel]; - pt1->tag[j] |= MG_BDY; + pt1->tag[j] |= MG_BDY + MG_PARBDYBDY; /* update adjacent */ lel = adjt[3*(jel-1)+1+j]/3; l = adjt[3*(jel-1)+1+j]%3; if( lel ) { pt2 = &mesh->tria[lel]; - pt2->tag[l] |= MG_BDY; + pt2->tag[l] |= MG_BDY + MG_PARBDYBDY; } break; } else if ( !ph->nxt ) { From 02a4f6d9783eab8024fa8a8960f09b0395c6ecc8 Mon Sep 17 00:00:00 2001 From: luca Date: Thu, 15 Apr 2021 17:42:29 +0200 Subject: [PATCH 060/170] Skip parallel points in MMG5_norver. --- src/mmg3d/analys_3d.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mmg3d/analys_3d.c b/src/mmg3d/analys_3d.c index d9f40071d..4daee5450 100644 --- a/src/mmg3d/analys_3d.c +++ b/src/mmg3d/analys_3d.c @@ -533,7 +533,7 @@ int MMG5_norver(MMG5_pMesh mesh) { ppt->flag = mesh->base; if ( mesh->nc1 ) { if ( ppt->n[0]*ppt->n[0] + ppt->n[1]*ppt->n[1] + ppt->n[2]*ppt->n[2] > 0 ) { - if ( ppt->tag & MG_CRN || ppt->tag & MG_NOM || MG_EDG(ppt->tag) ) { + if ( ppt->tag & MG_PARBDY || ppt->tag & MG_CRN || ppt->tag & MG_NOM || MG_EDG(ppt->tag) ) { ++nnr; continue; } @@ -561,7 +561,7 @@ int MMG5_norver(MMG5_pMesh mesh) { adja = &mesh->adjt[3*(k-1)+1]; for (i=0; i<3; i++) { ppt = &mesh->point[pt->v[i]]; - if ( ppt->tag & MG_CRN || ppt->tag & MG_NOM || ppt->flag == mesh->base ) continue; + if ( ppt->tag & MG_PARBDY || ppt->tag & MG_CRN || ppt->tag & MG_NOM || ppt->flag == mesh->base ) continue; /* C1 point */ if ( !MG_EDG(ppt->tag) ) { From 95e3813af2503b57ed304d961661c371610b0114 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 4 May 2021 15:18:37 +0200 Subject: [PATCH 061/170] Correction of wrong arguments in INCLUDE_DIRECTORIES CMake call. --- CMakeLists.txt | 2 +- cmake/modules/macros.cmake | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a5dfbecf..3c24d0b0b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -457,7 +457,7 @@ ENDIF ( ) IF( SCOTCH_FOUND ) # Include Scotch Dir here to ensure that Mmg doesn't search it's own headers in /usr/local - INCLUDE_DIRECTORIES(PUBLIC ${SCOTCH_INCLUDE_DIRS}) + INCLUDE_DIRECTORIES(${SCOTCH_INCLUDE_DIRS}) ENDIF() IF ( MmgTargetsExported ) diff --git a/cmake/modules/macros.cmake b/cmake/modules/macros.cmake index 05aa2b090..a556b29c1 100644 --- a/cmake/modules/macros.cmake +++ b/cmake/modules/macros.cmake @@ -150,7 +150,7 @@ MACRO ( ADD_AND_INSTALL_LIBRARY ADD_DEPENDENCIES( ${target_name} ${target_dependencies}) IF ( CMAKE_VERSION VERSION_LESS 2.8.12 ) - INCLUDE_DIRECTORIES ( ${target_name} PUBLIC + INCLUDE_DIRECTORIES ( ${COMMON_BINARY_DIR} ${COMMON_SOURCE_DIR} ${PROJECT_BINARY_DIR}/include ${PROJECT_BINARY_DIR}) ELSE ( ) target_include_directories( ${target_name} PUBLIC @@ -170,7 +170,7 @@ MACRO ( ADD_AND_INSTALL_LIBRARY if ( SCOTCH_FOUND ) message(STATUS "[mmg] add include scotch directories ${SCOTCH_INCLUDE_DIRS}") IF ( CMAKE_VERSION VERSION_LESS 2.8.12 ) - INCLUDE_DIRECTORIES ( ${target_name} PUBLIC ${SCOTCH_INCLUDE_DIRS} ) + INCLUDE_DIRECTORIES (${SCOTCH_INCLUDE_DIRS} ) ELSE ( ) target_include_directories( ${target_name} PUBLIC ${SCOTCH_INCLUDE_DIRS} ) endif() @@ -235,7 +235,7 @@ MACRO ( ADD_AND_INSTALL_EXECUTABLE ENDIF ( ) IF ( CMAKE_VERSION VERSION_LESS 2.8.12 ) - INCLUDE_DIRECTORIES ( ${exec_name} PUBLIC + INCLUDE_DIRECTORIES ( ${COMMON_BINARY_DIR} ${COMMON_SOURCE_DIR} ${PROJECT_BINARY_DIR}/include ${PROJECT_BINARY_DIR} ) ELSE ( ) TARGET_INCLUDE_DIRECTORIES ( ${exec_name} PUBLIC @@ -314,7 +314,7 @@ MACRO ( ADD_LIBRARY_TEST target_name main_path target_dependency lib_name ) ADD_DEPENDENCIES( ${target_name} ${target_dependency} ) IF ( CMAKE_VERSION VERSION_LESS 2.8.12 ) - INCLUDE_DIRECTORIES ( ${target_name} PUBLIC ${PROJECT_BINARY_DIR}/include ) + INCLUDE_DIRECTORIES (${PROJECT_BINARY_DIR}/include ) ELSE ( ) TARGET_INCLUDE_DIRECTORIES ( ${target_name} PUBLIC ${PROJECT_BINARY_DIR}/include ) ENDIF ( ) From da471926fcbfe12028bc77dfeecd596e55ac4bc3 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 4 May 2021 15:19:06 +0200 Subject: [PATCH 062/170] Comment compiler warning because it is not supported by MSVC. --- src/mmg2d/mmg2d1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mmg2d/mmg2d1.c b/src/mmg2d/mmg2d1.c index 3039163c1..513a48ed7 100644 --- a/src/mmg2d/mmg2d1.c +++ b/src/mmg2d/mmg2d1.c @@ -46,7 +46,7 @@ int MMG2D_anatri(MMG5_pMesh mesh,MMG5_pSol met,int8_t typchk) { /* Main routine; intertwine split, collapse and swaps */ do { if ( typchk == 2 && it == 0 ) { -#warning Luca: check consistency with 3D +// #warning Luca: check consistency with 3D } if ( !mesh->info.noinsert ) { /* Memory free */ From 59576e5804f2a26de9cd48cbe092c4ee071ecb88 Mon Sep 17 00:00:00 2001 From: luca Date: Tue, 4 May 2021 19:32:00 +0200 Subject: [PATCH 063/170] Explicitly set the DNDEBUG flag in case the user or a parent project overrides it. --- CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c24d0b0b..6639ab253 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -190,6 +190,13 @@ IF ( BUILD_MMG3D OR BUILD_MMGS ) ELSE () SET(BUILD_MMGS3D OFF) ENDIF() + +# Explicitly set the DNDEBUG flag in case the user or a parent project overrides +# it. +if (NOT CMAKE_BUILD_TYPE MATCHES Debug) + add_definitions(-DNDEBUG) +endif() + ############################################################################ ##### ##### Fortran header: libmmgtypesf.h From d708a5880424369a2aee7490a89d5ea42cc19fc0 Mon Sep 17 00:00:00 2001 From: luca Date: Tue, 4 May 2021 19:36:14 +0200 Subject: [PATCH 064/170] Fix typo (thx prj) --- src/common/anisomovpt.c | 2 +- src/common/anisosiz.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/anisomovpt.c b/src/common/anisomovpt.c index 416e9c50f..9b7dcc972 100644 --- a/src/common/anisomovpt.c +++ b/src/common/anisomovpt.c @@ -164,7 +164,7 @@ int MMG5_elementWeight(MMG5_pMesh mesh,MMG5_pSol met, MMG5_pTria pt, density = dens[0]*dens[2] - dens[1]*dens[1]; if ( density <= MMG5_EPSD2 ) { -#ifndef DNDEBUG +#ifndef NDEBUG if ( !mmgErr ) { fprintf(stderr,"\n ## Warning: %s: at least 1 negative or null density.\n", __func__); diff --git a/src/common/anisosiz.c b/src/common/anisosiz.c index 591c7ba04..16bab7ead 100644 --- a/src/common/anisosiz.c +++ b/src/common/anisosiz.c @@ -90,7 +90,7 @@ double MMG5_surf(MMG5_pMesh mesh,double m[3][6],MMG5_pTria ptt) { dens = tJmJ[0][0]*tJmJ[1][1] - tJmJ[1][0]*tJmJ[0][1]; if ( dens <= MMG5_EPSD2 ) { -#ifndef DNDEBUG +#ifndef NDEBUG if ( !mmgErr ) { fprintf(stderr,"\n ## Warning: %s: at least 1 negative or null density.\n", __func__); From d3918a7d23016804dcb44cac0daa5eb1c8c09fd9 Mon Sep 17 00:00:00 2001 From: luca Date: Thu, 6 May 2021 18:57:40 +0200 Subject: [PATCH 065/170] Correct orientation of the new collapsed face (inherited from the collapsing element) based on the references of the newly adjacent elements. --- src/mmg3d/colver_3d.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/mmg3d/colver_3d.c b/src/mmg3d/colver_3d.c index 5341a9e5a..60a3bde96 100644 --- a/src/mmg3d/colver_3d.c +++ b/src/mmg3d/colver_3d.c @@ -1002,6 +1002,15 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in else MG_CLR( pxt1->ori,voyp ); } + /* correct the orientation if the new adjacent has a different + * reference */ + if( qel ) { + if( mesh->tetra[pel].ref > mesh->tetra[qel].ref ) + MG_SET( pxt1->ori,voyp ); + else if( mesh->tetra[pel].ref < mesh->tetra[qel].ref ) + MG_CLR( pxt1->ori,voyp ); + } + #ifndef NDEBUG if ( qel ) { @@ -1120,6 +1129,14 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in else MG_CLR( pxt1->ori,voyq ); } + /* correct the orientation if the new adjacent has a different + * reference */ + if( pel ) { + if( mesh->tetra[qel].ref > mesh->tetra[pel].ref ) + MG_SET( pxt1->ori,voyq ); + else if( mesh->tetra[qel].ref < mesh->tetra[pel].ref ) + MG_CLR( pxt1->ori,voyq ); + } #ifndef NDEBUG if ( pel ) { From 8128e3488b31bdd363f5590c2826fcd6185b8dc0 Mon Sep 17 00:00:00 2001 From: Algiane Date: Fri, 7 May 2021 09:18:32 +0200 Subject: [PATCH 066/170] Clean useless assert after Luca's correction. --- src/mmg3d/colver_3d.c | 26 ++++---------------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/src/mmg3d/colver_3d.c b/src/mmg3d/colver_3d.c index 60a3bde96..2845d192e 100644 --- a/src/mmg3d/colver_3d.c +++ b/src/mmg3d/colver_3d.c @@ -1005,23 +1005,14 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in /* correct the orientation if the new adjacent has a different * reference */ if( qel ) { - if( mesh->tetra[pel].ref > mesh->tetra[qel].ref ) + if( pt1->ref > mesh->tetra[qel].ref ) MG_SET( pxt1->ori,voyp ); - else if( mesh->tetra[pel].ref < mesh->tetra[qel].ref ) + else if( pt1->ref < mesh->tetra[qel].ref ) MG_CLR( pxt1->ori,voyp ); } #ifndef NDEBUG - if ( qel ) { - /* Check that the domain of max ref imposes its orientation */ - if ( pt1->ref < mesh->tetra[qel].ref ) { - assert ( !MG_GET(pxt1->ori,voyp) ); - } - else if ( pt1->ref > mesh->tetra[qel].ref ) { - assert ( MG_GET(pxt1->ori,voyp ) ); - } - } else { /* Check that a non parallel external boundary face has always a good * orientation */ @@ -1132,22 +1123,13 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in /* correct the orientation if the new adjacent has a different * reference */ if( pel ) { - if( mesh->tetra[qel].ref > mesh->tetra[pel].ref ) + if( pt1->ref > mesh->tetra[pel].ref ) MG_SET( pxt1->ori,voyq ); - else if( mesh->tetra[qel].ref < mesh->tetra[pel].ref ) + else if( pt1->ref < mesh->tetra[pel].ref ) MG_CLR( pxt1->ori,voyq ); } #ifndef NDEBUG - if ( pel ) { - /* Check that the domain of max ref imposes its orientation */ - if ( pt1->ref < mesh->tetra[pel].ref ) { - assert ( !MG_GET(pxt1->ori,voyq) ); - } - else if ( pt1->ref > mesh->tetra[pel].ref ) { - assert ( MG_GET(pxt1->ori,voyq ) ); - } - } else { /* Check that a non parallel external boundary face has always a good * orientation */ From dd1941e2a1fea95ab36955b0fd475d7ecf32fb45 Mon Sep 17 00:00:00 2001 From: luca Date: Sat, 15 May 2021 14:30:47 +0200 Subject: [PATCH 067/170] Remove the assumption oof isotropic metric on singolar point which is a slave point for required gradation: It could have an anisotropic metric coming from the intersection with a physical metric. --- src/common/anisosiz.c | 32 +++++++++++++++++++++++--------- src/mmg3d/anisosiz_3d.c | 35 +++++++++++++++++++++++------------ 2 files changed, 46 insertions(+), 21 deletions(-) diff --git a/src/common/anisosiz.c b/src/common/anisosiz.c index 16bab7ead..508a7ea5c 100644 --- a/src/common/anisosiz.c +++ b/src/common/anisosiz.c @@ -1576,18 +1576,32 @@ int MMG5_grad2metSurfreq(MMG5_pMesh mesh, MMG5_pSol met, MMG5_pTria pt, int npma * of the singular points. Thus: * lambda_new = = 0.5 lambda_1 + 0.5 lambda_new = lambda_1 + 0.5 beta. * with beta the smallest variation of the eigenvalues (lambda_new-lambda_1). */ - assert ( fabs(mm2[0]-mm2[3]) < MMG5_EPSOK && fabs(mm2[3]-mm2[5]) < MMG5_EPSOK - && "iso metric?" ); - beta = mu[0] - mm2[0]; + /* This point can have an anisotropic metric if a user-provided metric is + * found. So, compute the eigenvalues. */ + double ll[3],rr[3][3],llmin; + int i; + if( !MMG5_eigenv(1,mm2,ll, rr) ) return 0; + llmin = 0.0; + for( i = 0; i < 3; i++ ) + if( ll[i] < llmin ) llmin = ll[i]; - if ( fabs(beta) < fabs(mm2[0]-mu[1]) ) { - beta = mu[1] - mm2[0]; + + beta = mu[0] - llmin; + + if ( fabs(beta) < fabs(llmin-mu[1]) ) { + beta = mu[1] - llmin; } - mm2[0] += 0.5*beta; - mm2[3] += 0.5*beta; - mm2[5] += 0.5*beta; - assert ( mm2[0]>0. && mm2[3]>0. && mm2[5]>0. ); + ll[0] += 0.5*beta; + ll[1] += 0.5*beta; + ll[2] += 0.5*beta; + assert ( ll[0]>0. && ll[1]>0. && ll[2]>0. ); + mm2[0] = ll[0]*rr[0][0]*rr[0][0] + ll[1]*rr[1][0]*rr[1][0] + ll[2]*rr[2][0]*rr[2][0]; + mm2[1] = ll[0]*rr[0][0]*rr[0][1] + ll[1]*rr[1][0]*rr[1][1] + ll[2]*rr[2][0]*rr[2][1]; + mm2[2] = ll[0]*rr[0][0]*rr[0][2] + ll[1]*rr[1][0]*rr[1][2] + ll[2]*rr[2][0]*rr[2][2]; + mm2[3] = ll[0]*rr[0][1]*rr[0][1] + ll[1]*rr[1][1]*rr[1][1] + ll[2]*rr[2][1]*rr[2][1]; + mm2[4] = ll[0]*rr[0][1]*rr[0][2] + ll[1]*rr[1][1]*rr[1][2] + ll[2]*rr[2][1]*rr[2][2]; + mm2[5] = ll[0]*rr[0][2]*rr[0][2] + ll[1]*rr[1][2]*rr[1][2] + ll[2]*rr[2][2]*rr[2][2]; } else if ( p2->tag & MG_GEO ){ if ( !MMG5_updatemetreq_ani(mtan2,mu,vp) ) { return 0; } diff --git a/src/mmg3d/anisosiz_3d.c b/src/mmg3d/anisosiz_3d.c index 189df9cf7..20e7d8cac 100644 --- a/src/mmg3d/anisosiz_3d.c +++ b/src/mmg3d/anisosiz_3d.c @@ -1810,21 +1810,32 @@ int MMG5_grad2metVolreq(MMG5_pMesh mesh,MMG5_pSol met,MMG5_pTetra pt,int npmaste * of the singular points. Thus: * lambda_new = = 0.5 lambda_1 + 0.5 lambda_new = lambda_1 + 0.5 beta. * with beta the smallest variation of the eigenvalues (lambda_new-lambda_1). */ - assert ( fabs(mm2[0]-mm2[3]) < MMG5_EPSOK && fabs(mm2[3]-mm2[5]) < MMG5_EPSOK - && "iso metric?" ); - beta = mu[0] - mm2[0]; + /* This point can have an anisotropic metric if a user-provided metric is + * found. So, compute the eigenvalues. */ + double ll[3],rr[3][3],llmin; + int i; + if( !MMG5_eigenv(1,mm2,ll, rr) ) return 0; + llmin = 0.0; + for( i = 0; i < 3; i++ ) + if( ll[i] < llmin ) llmin = ll[i]; - if ( fabs(beta) < fabs(mm2[0]-mu[1]) ) { - beta = mu[1] - mm2[0]; - } - if ( fabs(beta) < fabs(mm2[0]-mu[2]) ) { - beta = mu[2] - mm2[0]; - } - mm2[0] += 0.5*beta; - mm2[3] += 0.5*beta; - mm2[5] += 0.5*beta; + beta = mu[0] - llmin; + + if ( fabs(beta) < fabs(llmin-mu[1]) ) { + beta = mu[1] - llmin; + } + ll[0] += 0.5*beta; + ll[1] += 0.5*beta; + ll[2] += 0.5*beta; + assert ( ll[0]>0. && ll[1]>0. && ll[2]>0. ); + mm2[0] = ll[0]*rr[0][0]*rr[0][0] + ll[1]*rr[1][0]*rr[1][0] + ll[2]*rr[2][0]*rr[2][0]; + mm2[1] = ll[0]*rr[0][0]*rr[0][1] + ll[1]*rr[1][0]*rr[1][1] + ll[2]*rr[2][0]*rr[2][1]; + mm2[2] = ll[0]*rr[0][0]*rr[0][2] + ll[1]*rr[1][0]*rr[1][2] + ll[2]*rr[2][0]*rr[2][2]; + mm2[3] = ll[0]*rr[0][1]*rr[0][1] + ll[1]*rr[1][1]*rr[1][1] + ll[2]*rr[2][1]*rr[2][1]; + mm2[4] = ll[0]*rr[0][1]*rr[0][2] + ll[1]*rr[1][1]*rr[1][2] + ll[2]*rr[2][1]*rr[2][2]; + mm2[5] = ll[0]*rr[0][2]*rr[0][2] + ll[1]*rr[1][2]*rr[1][2] + ll[2]*rr[2][2]*rr[2][2]; } else if( p2->tag & MG_GEO ){ From f83179d54d3d4c817838f5b43c038bf4ca47d187 Mon Sep 17 00:00:00 2001 From: luca Date: Mon, 17 May 2021 16:14:36 +0200 Subject: [PATCH 068/170] Fix error. --- src/common/anisosiz.c | 9 ++++++--- src/mmg3d/anisosiz_3d.c | 8 +++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/common/anisosiz.c b/src/common/anisosiz.c index 508a7ea5c..a9e4ffb87 100644 --- a/src/common/anisosiz.c +++ b/src/common/anisosiz.c @@ -1581,10 +1581,13 @@ int MMG5_grad2metSurfreq(MMG5_pMesh mesh, MMG5_pSol met, MMG5_pTria pt, int npma * found. So, compute the eigenvalues. */ double ll[3],rr[3][3],llmin; int i; - if( !MMG5_eigenv(1,mm2,ll, rr) ) return 0; - llmin = 0.0; + if( !MMG5_eigenv(1,mm2,ll, rr) ) { + return 0; + } + llmin = 1.0/MMG5_EPSOK; for( i = 0; i < 3; i++ ) - if( ll[i] < llmin ) llmin = ll[i]; + if( ll[i] < llmin ) + llmin = ll[i]; beta = mu[0] - llmin; diff --git a/src/mmg3d/anisosiz_3d.c b/src/mmg3d/anisosiz_3d.c index 20e7d8cac..633c08288 100644 --- a/src/mmg3d/anisosiz_3d.c +++ b/src/mmg3d/anisosiz_3d.c @@ -1815,10 +1815,12 @@ int MMG5_grad2metVolreq(MMG5_pMesh mesh,MMG5_pSol met,MMG5_pTetra pt,int npmaste * found. So, compute the eigenvalues. */ double ll[3],rr[3][3],llmin; int i; - if( !MMG5_eigenv(1,mm2,ll, rr) ) return 0; - llmin = 0.0; + if( !MMG5_eigenv(1,mm2,ll, rr) ) + return 0; + llmin = 1.0/MMG5_EPSOK; for( i = 0; i < 3; i++ ) - if( ll[i] < llmin ) llmin = ll[i]; + if( ll[i] < llmin ) + llmin = ll[i]; beta = mu[0] - llmin; From cdc1a03e803092e684be5bfcbce808bbccd4ecc8 Mon Sep 17 00:00:00 2001 From: luca Date: Mon, 17 May 2021 16:32:46 +0200 Subject: [PATCH 069/170] Faster initialization. --- src/common/anisosiz.c | 2 +- src/mmg3d/anisosiz_3d.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/anisosiz.c b/src/common/anisosiz.c index a9e4ffb87..9c6db3d80 100644 --- a/src/common/anisosiz.c +++ b/src/common/anisosiz.c @@ -1584,7 +1584,7 @@ int MMG5_grad2metSurfreq(MMG5_pMesh mesh, MMG5_pSol met, MMG5_pTria pt, int npma if( !MMG5_eigenv(1,mm2,ll, rr) ) { return 0; } - llmin = 1.0/MMG5_EPSOK; + llmin = DBL_MAX; for( i = 0; i < 3; i++ ) if( ll[i] < llmin ) llmin = ll[i]; diff --git a/src/mmg3d/anisosiz_3d.c b/src/mmg3d/anisosiz_3d.c index 633c08288..a68b1274d 100644 --- a/src/mmg3d/anisosiz_3d.c +++ b/src/mmg3d/anisosiz_3d.c @@ -1817,7 +1817,7 @@ int MMG5_grad2metVolreq(MMG5_pMesh mesh,MMG5_pSol met,MMG5_pTetra pt,int npmaste int i; if( !MMG5_eigenv(1,mm2,ll, rr) ) return 0; - llmin = 1.0/MMG5_EPSOK; + llmin = DBL_MAX; for( i = 0; i < 3; i++ ) if( ll[i] < llmin ) llmin = ll[i]; From b67a9825f9e93880fccb692ac9f0d71eea5239c6 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 18 May 2021 14:48:48 +0200 Subject: [PATCH 070/170] Test cases migration and cmake script simplification. --- cmake/modules/LoadCiTests.cmake | 404 +++++--------------------------- 1 file changed, 57 insertions(+), 347 deletions(-) diff --git a/cmake/modules/LoadCiTests.cmake b/cmake/modules/LoadCiTests.cmake index f0f50e779..6a00c0ff2 100644 --- a/cmake/modules/LoadCiTests.cmake +++ b/cmake/modules/LoadCiTests.cmake @@ -20,387 +20,97 @@ ## use this copy of the mmg distribution only if you accept them. ## ============================================================================= -SET ( GET_MMG_TESTS "FALSE" ) -SET ( GET_MMG2D_TESTS "FALSE" ) -SET ( GET_MMGS_TESTS "FALSE" ) -SET ( GET_MMG3D_TESTS "FALSE" ) +############################################################################### +##### +##### Download test cases for Mmg code +##### +############################################################################### -# Check if the ci_tests directory exists -IF ( NOT EXISTS ${CI_DIR} ) - - # First download of the tests - MESSAGE("-- Create the continuous integration directory ${CI_DIR}" - " and download the test cases. May be very long...") - FILE(MAKE_DIRECTORY ${CI_DIR}) - - SET ( GET_MMG_TESTS "TRUE" ) - SET ( GET_MMG2D_TESTS "TRUE" ) - SET ( GET_MMGS_TESTS "TRUE" ) - SET ( GET_MMG3D_TESTS "TRUE" ) - -ELSE ( ) +MACRO ( DOWNLOAD_TESTS x ) # Check if the tests are up to date - #--------------> mmg - IF ( EXISTS ${CI_DIR}/mmg.version ) - FILE(MD5 ${CI_DIR}/mmg.version OLD_MMG_MD5) - ELSE ( ) - SET ( OLD_MMG_MD5 "0" ) + SET ( OLD_MMG_MD5 "0" ) + IF ( EXISTS ${CI_DIR}/mmg${x}.version ) + FILE(MD5 ${CI_DIR}/mmg${x}.version OLD_MMG_MD5) ENDIF ( ) - FILE(DOWNLOAD https://drive.google.com/uc?export=download&id=1tSey9RCMDWbjovX9CCHPZUZsiNHD5se_ - ${CI_DIR}/mmg.version + FILE(DOWNLOAD https://static.bordeaux.inria.fr/mmg/mmg${x}.version + ${CI_DIR}/mmg${x}.version STATUS MMG_VERSION_STATUS INACTIVITY_TIMEOUT 5) LIST(GET MMG_VERSION_STATUS 0 MMG_VERSION_STATUS_0) LIST(GET MMG_VERSION_STATUS 1 MMG_VERSION_STATUS_1) + SET ( GET_MMG_TESTS "FALSE" ) IF ( MMG_VERSION_STATUS_0 MATCHES 0) - FILE(MD5 ${CI_DIR}/mmg.version MMG_MD5) + FILE(MD5 ${CI_DIR}/mmg${x}.version MMG_MD5) IF ( NOT (${OLD_MMG_MD5} MATCHES ${MMG_MD5}) ) SET ( GET_MMG_TESTS "TRUE" ) ENDIF () - ELSE( ) - MESSAGE(WARNING "Failed to load a simple text file, download status:" - " ${MMG_VERSION_STATUS_1}. - Try to get it at the following link: - https://drive.google.com/uc?export=download&id=0B3X6EwOEKqHmRktsVkFDTGlfdzQ - then untar it in the ${CI_DIR} directory.") - ENDIF() - - #--------------> mmg2d - IF ( EXISTS ${CI_DIR}/mmg2d.version ) - FILE(MD5 ${CI_DIR}/mmg2d.version OLD_MMG2D_MD5) - ELSE ( ) - SET ( OLD_MMG2D_MD5 "0" ) - ENDIF ( ) - FILE(DOWNLOAD https://drive.google.com/uc?export=download&id=0B3X6EwOEKqHmV3BlUER4M0Z4MGs - ${CI_DIR}/mmg2d.version - STATUS MMG2D_VERSION_STATUS - INACTIVITY_TIMEOUT 5) - LIST(GET MMG2D_VERSION_STATUS 0 MMG2D_VERSION_STATUS_0) - LIST(GET MMG2D_VERSION_STATUS 1 MMG2D_VERSION_STATUS_1) - - IF ( MMG2D_VERSION_STATUS_0 MATCHES 0) - FILE(MD5 ${CI_DIR}/mmg2d.version MMG2D_MD5) - - IF ( NOT (${OLD_MMG2D_MD5} MATCHES ${MMG2D_MD5}) ) - SET ( GET_MMG2D_TESTS "TRUE" ) - ENDIF () ELSE( ) MESSAGE(WARNING "Failed to load a simple text file, download status:" - " ${MMG2D_VERSION_STATUS_1}. - Try to get it at the following link: - https://drive.google.com/uc?export=download&id=0B3X6EwOEKqHmV3BlUER4M0Z4MGs - then untar it in the ${CI_DIR} directory.") - ENDIF() - - #--------------> mmgs - IF ( EXISTS ${CI_DIR}/mmgs.version ) - FILE(MD5 ${CI_DIR}/mmgs.version OLD_MMGS_MD5) - ELSE ( ) - SET ( OLD_MMGS_MD5 "0" ) - ENDIF ( ) - - FILE(DOWNLOAD https://drive.google.com/uc?export=download&id=0B3X6EwOEKqHmSWtGV295a28wU2c - ${CI_DIR}/mmgs.version - STATUS MMGS_VERSION_STATUS - INACTIVITY_TIMEOUT 5) - LIST(GET MMGS_VERSION_STATUS 0 MMGS_VERSION_STATUS_0) - LIST(GET MMGS_VERSION_STATUS 1 MMGS_VERSION_STATUS_1) - - IF ( MMGS_VERSION_STATUS_0 MATCHES 0) - FILE(MD5 ${CI_DIR}/mmgs.version MMGS_MD5) - - IF ( NOT (${OLD_MMGS_MD5} MATCHES ${MMGS_MD5}) ) - SET ( GET_MMGS_TESTS "TRUE" ) - ENDIF () - ELSE( ) - MESSAGE(WARNING "Failed to load a simple text file, download status:" - " ${MMGS_VERSION_STATUS_1}. - Try to get it at the following link: - https://drive.google.com/uc?export=download&id=0B3X6EwOEKqHmSWtGV295a28wU2c - then untar it in the ${CI_DIR} directory.") - ENDIF() - - #--------------> mmg3d - IF ( EXISTS ${CI_DIR}/mmg3d.version ) - FILE(MD5 ${CI_DIR}/mmg3d.version OLD_MMG3D_MD5) - ELSE ( ) - SET ( OLD_MMG3D_MD5 "0" ) - ENDIF ( ) - - FILE(DOWNLOAD https://drive.google.com/uc?export=download&id=0B3X6EwOEKqHmSWtGV295a28wU2c - ${CI_DIR}/mmg3d.version - STATUS MMG3D_VERSION_STATUS - INACTIVITY_TIMEOUT 5) - LIST(GET MMG3D_VERSION_STATUS 0 MMG3D_VERSION_STATUS_0) - LIST(GET MMG3D_VERSION_STATUS 1 MMG3D_VERSION_STATUS_1) - - IF ( MMG3D_VERSION_STATUS_0 MATCHES 0) - FILE(MD5 ${CI_DIR}/mmg3d.version MMG3D_MD5) + " ${MMG_VERSION_STATUS_1}. + Try to get the test cases at the following link: + https://static.bordeaux.inria.fr/mmg/mmg${x}.tgz + Then untar it in ${CI_DIR}/mmg${x}.") - IF (NOT (${OLD_MMG3D_MD5} MATCHES ${MMG3D_MD5})) - SET ( GET_MMG3D_TESTS "TRUE" ) - ENDIF () - ELSE( ) - MESSAGE(WARNING "Failed to load a simple text file, download status:" - " ${MMG3D_VERSION_STATUS_1}. - Try to get it at the following link: - https://drive.google.com/uc?export=download&id=0B3X6EwOEKqHmSWtGV295a28wU2c - then untar it in the ${CI_DIR} directory.") ENDIF() -ENDIF() - -# Download the tests if needed -#--------------> mmg -IF ( GET_MMG_TESTS MATCHES "TRUE" ) - MESSAGE("-- Download the mmg test cases. May be very long...") - - SET(ADDRESS - https://drive.google.com/uc?export=download&id=1Pren7-lwnkG7UTaUimspE-16hlIDLoCc - https://drive.google.com/uc?export=download&id=1CZJM__QvYq_88BcMb3dBtaY2nDRYrcLz - https://drive.google.com/uc?export=download&id=1NZHHeSmMzpiADGfLbTatbVn2bjv0bbVp - ) - - SET(FILENAME - ${CI_DIR}/mmg.tgz.aa - ${CI_DIR}/mmg.tgz.ab - ${CI_DIR}/mmg.tgz.ac - ) - - SET(LOAD_OK 1) - - FOREACH( i RANGE 0 2) - LIST(GET ADDRESS ${i} ADDRESS_i) - LIST(GET FILENAME ${i} FILENAME_i) - - FILE(DOWNLOAD ${ADDRESS_i} - ${FILENAME_i} + # Get tests + IF ( GET_MMG_TESTS MATCHES "TRUE" ) + MESSAGE("-- Mmg${x} test cases download. May take a while...") + FILE(DOWNLOAD https://static.bordeaux.inria.fr/mmg/mmg${x}.tgz + ${CI_DIR}/mmg${x}.tgz SHOW_PROGRESS) - IF ( NOT EXISTS ${FILENAME_i} ) + + IF ( NOT EXISTS ${CI_DIR}/mmg${x}.tgz ) MESSAGE("\n") - MESSAGE(WARNING "Fail to automatically download the mmg3d test cases + MESSAGE(WARNING "Fail to automatically download the mmg${x} test cases. Try to get it at the following link: - ${ADDRESS_i} -then untar it in the ${CI_DIR} directory.") - SET ( LOAD_OK 0 ) - BREAK() - ENDIF() - - ENDFOREACH() - - IF ( ${LOAD_OK} ) - IF ( WIN32 ) - foreach( file_i IN LISTS FILENAME ) - file(TO_NATIVE_PATH ${file_i} file_i_n) - list(APPEND list_fic_s ${file_i_n}) - endforeach() - - EXECUTE_PROCESS( - COMMAND cmd.exe /c type ${list_fic_s} > ${CI_DIR}/mmg.tgz - WORKING_DIRECTORY ${CI_DIR} - # COMMAND_ECHO STDOUT - # RESULT_VARIABLE cmd_output - TIMEOUT 10000 - ) - + https://static.bordeaux.inria.fr/mmg/mmg${x}.tgz +then untar it in the ${CI_DIR}/mmg${x} directory.") + ELSE() EXECUTE_PROCESS( - COMMAND ${CMAKE_COMMAND} -E tar xzf mmg.tgz + COMMAND ${CMAKE_COMMAND} -E tar xzf ${CI_DIR}/mmg${x}.tgz WORKING_DIRECTORY ${CI_DIR} + #RESULT_VARIABLE toto #COMMAND_ECHO STDOUT - #RESULT_VARIABLE cmd_output - TIMEOUT 10000 ) - #MESSAGE ( "cmd_output ${cmd_output}" ) - ELSE() - EXECUTE_PROCESS( - COMMAND cat ${FILENAME} - COMMAND tar -xzf - - WORKING_DIRECTORY ${CI_DIR}/ - TIMEOUT 10000 ) - ENDIF(WIN32) - - IF ( NOT EXISTS ${CI_DIR}/mmg ) - MESSAGE("\n") - MESSAGE(WARNING "Fail to automatically untar the mmg " - "test cases directory (mmg.tgz.*). -Try to untar it by hand in the ${CI_DIR} directory: " - "cat mmg.tgz.* | tar xzvf - ") - ELSE () - FILE(REMOVE ${FILENAME}) - ENDIF() - ENDIF() - -ENDIF() - -#--------------> mmg2d -IF ( GET_MMG2D_TESTS MATCHES "TRUE" ) - MESSAGE("-- Download the mmg2d test cases. May be very long...") - FILE(DOWNLOAD https://drive.google.com/uc?export=download&id=1Lnvh7AldwEXS7WRa1VxsRqI7Xu7CgJNj - ${CI_DIR}/mmg2d.tgz - SHOW_PROGRESS) - IF ( NOT EXISTS ${CI_DIR}/mmg2d.tgz ) - MESSAGE("\n") - MESSAGE(WARNING "Fail to automatically download the mmg2d test cases. -Try to get it at the following link: - https://drive.google.com/uc?export=download&id=1Lnvh7AldwEXS7WRa1VxsRqI7Xu7CgJNj -then untar it in the ${CI_DIR} directory.") - ELSE() - EXECUTE_PROCESS( - COMMAND ${CMAKE_COMMAND} -E tar xzf ${CI_DIR}/mmg2d.tgz - WORKING_DIRECTORY ${CI_DIR} - #RESULT_VARIABLE toto - #COMMAND_ECHO STDOUT - ) - #MESSAGE("${toto}") - IF ( NOT EXISTS ${CI_DIR}/mmg2d ) - MESSAGE("\n") - MESSAGE(WARNING "Fail to automatically untar the mmg2d " - "test cases directory (mmg2d.tgz). + IF ( NOT EXISTS ${CI_DIR}/mmg${x} ) + MESSAGE("\n") + MESSAGE(WARNING "Fail to automatically untar the mmg${x} " + "test cases directory (mmg${x}.tgz). Try to untar it by hand in the ${CI_DIR} directory.") - ELSE() - FILE(REMOVE ${CI_DIR}/mmg2d.tgz) - ENDIF () - - ENDIF () -ENDIF () - -#--------------> mmgs -IF ( GET_MMGS_TESTS MATCHES "TRUE" ) - MESSAGE("-- Download the mmgs test cases. May be very long...") - FILE(DOWNLOAD https://drive.google.com/uc?export=download&id=0B3X6EwOEKqHmcVdZb1EzaTR3ZlU - ${CI_DIR}/mmgs.tgz - #STATUS status - #LOG log - SHOW_PROGRESS) - #MESSAGE(${log}) - IF ( NOT EXISTS ${CI_DIR}/mmgs.tgz ) - MESSAGE("\n") - MESSAGE(WARNING "Fail to automatically download the mmgs test cases. -Try to get it at the following link: - https://drive.google.com/uc?export=download&id=0B3X6EwOEKqHmcVdZb1EzaTR3ZlU -then untar it in the ${CI_DIR} directory.") - ELSE() - EXECUTE_PROCESS( - COMMAND ${CMAKE_COMMAND} -E tar xzf - ${CI_DIR}/mmgs.tgz - WORKING_DIRECTORY ${CI_DIR}/ - ) - IF ( NOT EXISTS ${CI_DIR}/mmgs ) - MESSAGE("\n") - MESSAGE(WARNING "Fail to automatically untar the mmgs " - "test cases directory (mmgs.tgz). -Try to untar it by hand in the ${CI_DIR} directory.") - ELSE() - FILE(REMOVE ${CI_DIR}/mmgs.tgz) - ENDIF () - ENDIF () -ENDIF () - -#--------------> mmg3d -SET(ADDRESS - https://drive.google.com/uc?export=download&id=1WJK8mbFh81QFsDuOUt7kcavJwLO4yatO - https://drive.google.com/uc?export=download&id=1SvznS9n57f1jIVoeFMM7-WVGJUu3OdMz - https://drive.google.com/uc?export=download&id=1wACP1jut6Dz4mTf6uQARW7Koc1Zs_O9H - https://drive.google.com/uc?export=download&id=142BueykwzDGS_Ne_RzJfgMGqQNhzJb6a - https://drive.google.com/uc?export=download&id=1dEXKIApQiEkplI03bgVbThKMKTL4P0M_ - https://drive.google.com/uc?export=download&id=1KA5H7oS9HrtXT3sUpGU78YU7BwRHMVk7 - https://drive.google.com/uc?export=download&id=1duHPrEjdHrb1k9VwoV_-uYw4CPbMN9AM - https://drive.google.com/uc?export=download&id=179k-asjM88ewVumZSQ9eUMWLJRfbQwIz - https://drive.google.com/uc?export=download&id=1yjGvVah-vFNhwsImrHA0Bu5sIo1Fo5wW - https://drive.google.com/uc?export=download&id=1PpQpC0OvJUTieTs0jd_A0Qb5EVP3QfZw - https://drive.google.com/uc?export=download&id=1DbI0CCIYvDX-cPLZehazMV5wmu-K9K4b - https://drive.google.com/uc?export=download&id=1MDALbXmXSpoVaHo4ghU6QpmQhsBP8Pjy - https://drive.google.com/uc?export=download&id=1iil5UBwVgpcErUcKd_wJi_Oguuuyy0HT - ) - -SET(FILENAME - ${CI_DIR}/mmg3d.tgz.aa - ${CI_DIR}/mmg3d.tgz.ab - ${CI_DIR}/mmg3d.tgz.ac - ${CI_DIR}/mmg3d.tgz.ad - ${CI_DIR}/mmg3d.tgz.ae - ${CI_DIR}/mmg3d.tgz.af - ${CI_DIR}/mmg3d.tgz.ag - ${CI_DIR}/mmg3d.tgz.ah - ${CI_DIR}/mmg3d.tgz.ai - ${CI_DIR}/mmg3d.tgz.aj - ${CI_DIR}/mmg3d.tgz.ak - ${CI_DIR}/mmg3d.tgz.al - ${CI_DIR}/mmg3d.tgz.am - ) - + ELSE() + FILE(REMOVE ${CI_DIR}/mmg${x}.tgz) + ENDIF () -IF ( GET_MMG3D_TESTS MATCHES "TRUE" ) - MESSAGE("-- Download the mmg3d test cases. May be very long...") - - SET(LOAD_OK 1) - - FOREACH( i RANGE 0 12) - LIST(GET ADDRESS ${i} ADDRESS_i) - LIST(GET FILENAME ${i} FILENAME_i) - - FILE(DOWNLOAD ${ADDRESS_i} - ${FILENAME_i} - SHOW_PROGRESS) - IF ( NOT EXISTS ${FILENAME_i} ) - MESSAGE("\n") - MESSAGE(WARNING "Fail to automatically download the mmg3d test cases -Try to get it at the following link: - ${ADDRESS_i} -then untar it in the ${CI_DIR} directory.") - SET ( LOAD_OK 0 ) - BREAK() ENDIF() + ENDIF() - ENDFOREACH() +ENDMACRO ( ) - IF ( ${LOAD_OK} ) - IF ( WIN32 ) - set(list_fic_s "") - foreach( file_i IN LISTS FILENAME ) - file(TO_NATIVE_PATH ${file_i} file_i_n) - list(APPEND list_fic_s ${file_i_n}) - endforeach() +############################################################################### +##### +##### Download test cases depending on user options +##### +############################################################################### - EXECUTE_PROCESS( - COMMAND cmd.exe /c type ${list_fic_s} > ${CI_DIR}/mmg3d.tgz - WORKING_DIRECTORY ${CI_DIR} - # COMMAND_ECHO STDOUT - # RESULT_VARIABLE cmd_output - TIMEOUT 10000 - ) +# Check if the ci_tests directory exists +IF ( NOT EXISTS ${CI_DIR} ) - EXECUTE_PROCESS( - COMMAND cmd.exe /c tar xvzf ${CI_DIR}/mmg3d.tgz - WORKING_DIRECTORY ${CI_DIR} - # COMMAND_ECHO STDOUT - # RESULT_VARIABLE cmd_output - TIMEOUT 10000 - ) - #MESSAGE ( "cmd_output ${cmd_output}" ) - ELSE() - EXECUTE_PROCESS( - COMMAND cat ${FILENAME} - COMMAND tar -xzf - - WORKING_DIRECTORY ${CI_DIR}/ - TIMEOUT 10000 - ) - ENDIF(WIN32) + # First download of the tests + MESSAGE("-- Creation of continuous integration directory: ${CI_DIR}") + FILE(MAKE_DIRECTORY ${CI_DIR}) - IF ( NOT EXISTS ${CI_DIR}/mmg3d ) - MESSAGE("\n") - MESSAGE(WARNING "Fail to automatically untar the mmg3d" - "test cases directory (mmg3d.tgz.*). -Try to untar it by hand in the ${CI_DIR} directory: " - "cat mmg3d.tgz.* | tar xzvf - ") - ELSE() - FILE(REMOVE ${FILENAME}) - ENDIF() - ENDIF() +ENDIF ( ) -ENDIF() +# +# Download the tests if needed +##--------------> mmg +DOWNLOAD_TESTS ( "2d" ) +DOWNLOAD_TESTS ( "3d" ) +DOWNLOAD_TESTS ( "s" ) +DOWNLOAD_TESTS ( "" ) From 9201b30babe0f3598514515e7957bb1aeb6dbe2a Mon Sep 17 00:00:00 2001 From: Algiane Date: Thu, 20 May 2021 16:33:41 +0200 Subject: [PATCH 071/170] Add missing test in nofem mode. --- src/mmg2d/bezier_2d.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mmg2d/bezier_2d.c b/src/mmg2d/bezier_2d.c index 73bdc4f79..223c617f1 100644 --- a/src/mmg2d/bezier_2d.c +++ b/src/mmg2d/bezier_2d.c @@ -57,7 +57,8 @@ int MMG2D_chkedg(MMG5_pMesh mesh, int k) { else if ( ll < MMG5_EPSD ) continue; /* Split non geometric edges connecting two parts of the border */ - else if ( !MG_EDG(pt->tag[i]) && p1->tag > MG_NOTAG && p2->tag > MG_NOTAG ) { + else if ( mesh->info.fem && + ( (!MG_EDG(pt->tag[i])) && (p1->tag > MG_NOTAG) && (p2->tag > MG_NOTAG)) ) { MG_SET(pt->flag,i); continue; } From c4a439f3022ec8f9a1446a1bf6f477b935480437 Mon Sep 17 00:00:00 2001 From: Algiane Date: Thu, 20 May 2021 23:21:00 +0200 Subject: [PATCH 072/170] Update sonaqube script. --- scripts/JENKINSFILE.sonarqube | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/scripts/JENKINSFILE.sonarqube b/scripts/JENKINSFILE.sonarqube index 77231e2f4..d3ca67c2c 100644 --- a/scripts/JENKINSFILE.sonarqube +++ b/scripts/JENKINSFILE.sonarqube @@ -1,5 +1,5 @@ node('mmg-sonnar-new') { - def list = ['ON','OFF'] + def list = ['OFF','ON'] stage('GitClone'){ checkout([$class: 'GitSCM', branches: [[name: '*/develop']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[url: 'https://github.com/MmgTools/mmg.git']]]) step([$class: 'LastChangesPublisher', since:'PREVIOUS_REVISION',specificRevision: '', format: 'LINE', matchWordsThreshold: '0.25', matching: 'NONE', matchingMaxComparisons: '1000', showFiles: true, synchronisedScroll: true]) @@ -7,14 +7,13 @@ node('mmg-sonnar-new') { } for ( i=0; i&1 |tee mmg-build.log make install |tee -a mmg-build.log @@ -23,9 +22,9 @@ node('mmg-sonnar-new') { try { stage('Test'+list[i]){ sh '''#!/bin/bash -l - cd buildPattern'''+list[i]+''' + cd buildPattern'''+list[i]+'''useScotch'''+list[i]+''' ctest --no-compress-output -T Test -V || /usr/bin/true - lcov --directory . --capture --output-file mmg-pattern'''+list[i]+'''.lcov + lcov --directory . --capture --output-file mmg-pattern'''+list[i]+'''-use-scotch'''+list[i]+'''.lcov ''' } } catch (Exception err) { @@ -35,9 +34,9 @@ node('mmg-sonnar-new') { stage('Analysis'){ sh '''#!/bin/bash -l - lcov -a buildPatternON/mmg-patternON.lcov -a buildPatternOFF/mmg-patternOFF.lcov -o mmg.lcov + lcov -a buildPatternONuseScotchON/mmg-patternON-use-scotchON.lcov -a buildPatternOFFuseScotchOFF/mmg-patternOFF-use-scotchOFF.lcov -o mmg.lcov python /builds/sonar/lcov-to-cobertura-xml-1.6/lcov_cobertura/lcov_cobertura.py mmg.lcov --output mmg-coverage.xml - export CPPCHECK_INCLUDES="-IbuildPatternON/include -IbuildPatternOFF/include -IbuildPatternON/src/common -IbuildPatternOFF/src/common" + export CPPCHECK_INCLUDES="-IbuildPatternONuseScotchON/include -IbuildPatternOFFuseScotchOFF/include -IbuildPatternONuseScotchON/src/common -IbuildPatternOFFuseScotchOFF/src/common" export SOURCES_TO_ANALYZE="./src" cppcheck -v -f --language=c --platform=unix64 --check-config --enable=all --xml --xml-version=2 --suppress=missingIncludeSystem ${CPPCHECK_INCLUDES} ${SOURCES_TO_ANALYZE} 2> mmg-cppcheck.xml /usr/local/bin/rats -w 3 --xml ${SOURCES_TO_ANALYZE} > mmg-rats.xml @@ -53,11 +52,11 @@ sonar.links.issue=https://github.com/MmgTools/mmg/issues sonar.projectKey=cardamom:mmg:github:develop sonar.projectDescription=open source software for bidimensional and tridimensional remeshing sonar.projectVersion=$version_mmg -sonar.language=c sonar.sources=./src sonar.sourceEncoding=UTF-8 sonar.c.suffixes.sources=.c sonar.c.suffixes.headers=.h +sonar.lang.patterns.c++ : **/*.cxx,**/*.cpp,**/*.hxx,**/*.hpp sonar.c.errorRecoveryEnabled=True sonar.c.includeDirectories=src/common, src/mmg, src/mmg3d, src/mmg2d, src/mmgs, build/src/mmg2d, build/src/mmg3d, build/src/mmgs, build/src/common, build/include, bu\ ild/src From 49005584cf0d8849832133d8aacba9c1c6451961 Mon Sep 17 00:00:00 2001 From: Algiane Date: Wed, 26 May 2021 09:46:23 +0200 Subject: [PATCH 073/170] Patch error in analysis mode: we were trying to save a non existing metric in non Medit file. --- src/common/inout.c | 13 ++++++++++++- src/common/vtkparser.hpp | 15 ++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/common/inout.c b/src/common/inout.c index 183b2ae4a..577a74eab 100644 --- a/src/common/inout.c +++ b/src/common/inout.c @@ -1850,7 +1850,18 @@ int MMG5_saveMshMesh(MMG5_pMesh mesh,MMG5_pSol *sol,const char *filename, } /** Write solution */ - nsols = (metricData==1)? 1 : mesh->nsols; + if ( metricData==1 ) { + if ( sol && *sol && sol[0]->np ) { + nsols = 1; + } + else { + /* In analysis mode (-noinsert -noswap -nomove), metric is not allocated */ + nsols = 0; + } + } + else { + nsols = mesh->nsols; + } for ( isol=0; isolnsols; + int nsols; + + if ( metricData==1 ) { + if ( sol && *sol && sol[0]->np ) { + nsols = 1; + } + else { + /* In analysis mode (-noinsert -noswap -nomove), metric is not allocated */ + nsols = 0; + } + } + else { + nsols = mesh->nsols; + } static int mmgWarn = 0; for ( int isol=0; isol Date: Fri, 28 May 2021 10:23:22 +0200 Subject: [PATCH 074/170] Cmake policy (unquote a variable) --- cmake/modules/macros.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/modules/macros.cmake b/cmake/modules/macros.cmake index a556b29c1..8a013457c 100644 --- a/cmake/modules/macros.cmake +++ b/cmake/modules/macros.cmake @@ -140,7 +140,7 @@ MACRO ( ADD_AND_INSTALL_LIBRARY ADD_LIBRARY ( ${target_name} ${target_type} ${sources} ) ADD_LIBRARY ( Mmg::${target_name} ALIAS ${target_name} ) - IF ( "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" AND ${CMAKE_C_COMPILER_VERSION} VERSION_GREATER 10 ) + IF ( ${CMAKE_C_COMPILER_ID} STREQUAL "Clang" AND ${CMAKE_C_COMPILER_VERSION} VERSION_GREATER 10 ) target_compile_options(${target_name} PRIVATE "-fcommon") ENDIF() From 5d060275db6342ed8a9a72ebc6c96c04eb1907ea Mon Sep 17 00:00:00 2001 From: luca Date: Wed, 2 Jun 2021 09:57:49 +0200 Subject: [PATCH 075/170] Improve doc for triangle adjacency computation. --- src/common/hash.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/common/hash.c b/src/common/hash.c index 27ef9157c..d0b55caea 100644 --- a/src/common/hash.c +++ b/src/common/hash.c @@ -182,7 +182,15 @@ int MMG5_mmgHashTria(MMG5_pMesh mesh, int *adjt, MMG5_Hash *hash, int chkISO) { /* Now loop on "only" parallel edges in order to add a MG_BDY tag on those * that are found in the hash table and their adjacents (if manifold; in the - * non-manifold case the MG_NOM tag suffices). */ + * non-manifold case the MG_NOM tag suffices). + * + * Rationale: + * - put MG_BDY tags on edges that are contact edges between a true + * boundary (!MG_PARBDY || (MG_PARBDY && MG_PARBDYBDY) and a parallel one + * (MG_PARBDY && !MG_PARBDYBDY); + * - add also a MG_PARBDYBDY tag on those edges (as it cannot be inherited + * from any triangle there). + */ for (k=1; k<=mesh->nt; k++) { pt = &mesh->tria[k]; if ( !MG_EOK(pt) ) continue; From bddb1b275b1f991e44687f3ab47930c4594fed64 Mon Sep 17 00:00:00 2001 From: Algiane Date: Thu, 3 Jun 2021 17:15:51 +0200 Subject: [PATCH 076/170] Make writting at Triangle format compatible with triangle default options. --- cmake/testing/mmg2d_tests.cmake | 3 +++ cmake/testing/mmg3d_tests.cmake | 2 ++ src/common/inout.c | 33 +++++++++++++++++++++++++++------ src/common/libmmgcommon.h | 3 ++- src/mmg2d/inout_2d.c | 9 ++++++++- src/mmg2d/libmmg2d.h | 6 +++++- src/mmg3d/inout_3d.c | 2 +- src/mmg3d/libmmg3d.h | 4 ++++ src/mmgs/libmmgs.h | 4 ++++ 9 files changed, 56 insertions(+), 10 deletions(-) diff --git a/cmake/testing/mmg2d_tests.cmake b/cmake/testing/mmg2d_tests.cmake index 5a0ddc1af..798569bfb 100644 --- a/cmake/testing/mmg2d_tests.cmake +++ b/cmake/testing/mmg2d_tests.cmake @@ -312,6 +312,9 @@ IF ( NOT VTK_FOUND ) ENDIF() # Triangle output +# +# Respect the default Tetgen behaviour: saves only boundary edges in +# .edge file. ADD_TEST(NAME mmg2d_Circle-triangle COMMAND ${EXECUT_MMG2D} -v 5 ${MMG2D_CI_TESTS}/Circle/cercle diff --git a/cmake/testing/mmg3d_tests.cmake b/cmake/testing/mmg3d_tests.cmake index f00fd1af3..15a507584 100644 --- a/cmake/testing/mmg3d_tests.cmake +++ b/cmake/testing/mmg3d_tests.cmake @@ -302,6 +302,8 @@ ADD_TEST(NAME mmg3d_ascii_gmsh_3d ) # Tetgen +# Default Tetgen behaviour saves only boundary tria (resp. edges) in +# .face (resp. .edge) file. ADD_TEST ( NAME mmg3d_cube-tetgen COMMAND ${EXECUT_MMG3D} -v 5 ${MMG3D_CI_TESTS}/Cube/cube diff --git a/src/common/inout.c b/src/common/inout.c index 577a74eab..e671d94ad 100644 --- a/src/common/inout.c +++ b/src/common/inout.c @@ -2748,10 +2748,10 @@ int MMG5_saveNode(MMG5_pMesh mesh,const char *filename) { return 1; } -int MMG5_saveEdge(MMG5_pMesh mesh,const char *filename) { +int MMG5_saveEdge(MMG5_pMesh mesh,const char *filename,const char *ext) { FILE* inm; MMG5_pEdge pt; - int k; + int k,polyfile; char *ptr,*data; if ( !mesh->na ) { @@ -2768,15 +2768,15 @@ int MMG5_saveEdge(MMG5_pMesh mesh,const char *filename) { } /* Name of file */ - MMG5_SAFE_CALLOC(data,strlen(filename)+6,char,return 0); + MMG5_SAFE_CALLOC(data,strlen(filename)+strlen(ext),char,return 0); strcpy(data,filename); ptr = strstr(data,".node"); if ( ptr ) { *ptr = '\0'; } - /* Add .node ext */ - strcat(data,".edge"); + /* Add file ext */ + strcat(data,ext); if( !(inm = fopen(data,"wb")) ) { fprintf(stderr," ** UNABLE TO OPEN %s.\n",data); MMG5_SAFE_FREE(data); @@ -2786,8 +2786,23 @@ int MMG5_saveEdge(MMG5_pMesh mesh,const char *filename) { fprintf(stdout," %%%% %s OPENED\n",data); MMG5_SAFE_FREE(data); + /* For .poly file, add header */ + if ( !strcmp(ext,".poly") ) { + polyfile = 1; + } + else { + polyfile = 0; + } + + if ( polyfile ) { + /* Save 0 nodes (saved in a separated .node file), dim, 0 attributes, 1 bdy + * marker */ + fprintf(inm, "0 %d 0 1\n",mesh->dim); + + } + /* Save node number, dim, no attributes, 1 bdy marker */ - fprintf(inm, "%d %d\n\n",mesh->na,1); + fprintf(inm, "%d %d\n",mesh->na,1); for ( k=1; k<=mesh->na; ++k ) { /* Save edge idx */ @@ -2799,6 +2814,12 @@ int MMG5_saveEdge(MMG5_pMesh mesh,const char *filename) { fprintf(inm,"%d %d %d\n",mesh->point[pt->a].tmp,mesh->point[pt->b].tmp,pt->ref); } + + /* For .poly file, add last line: 0 holes */ + if ( polyfile ) { + fprintf(inm, "0 \n"); + } + fprintf(stdout," NUMBER OF EDGES %8d\n",mesh->na); fclose(inm); diff --git a/src/common/libmmgcommon.h b/src/common/libmmgcommon.h index 83477bfa7..58ac775e7 100644 --- a/src/common/libmmgcommon.h +++ b/src/common/libmmgcommon.h @@ -262,12 +262,13 @@ int MMG5_saveNode(MMG5_pMesh mesh,const char *filename); /** * \param mesh pointer toward the mesh structure. * \param filename name of file. + * \param ext file extension (.poly or .edge) * * \return 1 if success, 0 if fail. * * Save edge list at .edge file format (Tetgen/Triangle). */ -int MMG5_saveEdge(MMG5_pMesh mesh,const char *filename); +int MMG5_saveEdge(MMG5_pMesh mesh,const char *filename,const char *ext); #ifdef __cplusplus } diff --git a/src/mmg2d/inout_2d.c b/src/mmg2d/inout_2d.c index f39fce496..1fb55e3b8 100644 --- a/src/mmg2d/inout_2d.c +++ b/src/mmg2d/inout_2d.c @@ -2040,6 +2040,13 @@ int MMG2D_saveNeigh(MMG5_pMesh mesh,const char *filename) { return 1; } +static inline +int MMG2D_saveEdge(MMG5_pMesh mesh,const char *filename) { + + return MMG5_saveEdge(mesh,filename,".poly"); +} + + int MMG2D_saveTetgenMesh(MMG5_pMesh mesh,const char *filename) { if ( !MMG5_saveNode(mesh,filename) ) { @@ -2050,7 +2057,7 @@ int MMG2D_saveTetgenMesh(MMG5_pMesh mesh,const char *filename) { return 0; } - if ( !MMG5_saveEdge(mesh,filename) ) { + if ( !MMG2D_saveEdge(mesh,filename) ) { return 0; } diff --git a/src/mmg2d/libmmg2d.h b/src/mmg2d/libmmg2d.h index 39d8746e6..c39414153 100644 --- a/src/mmg2d/libmmg2d.h +++ b/src/mmg2d/libmmg2d.h @@ -2016,6 +2016,10 @@ int MMG2D_loadVtkMesh_and_allData(MMG5_pMesh mesh,MMG5_pSol *sol,const char *fil * boundary if it is located at the interface of 2 domains with different * references, if it belongs to one triangle only or if it is a singular edge * (ridge or required). + * Append these edges to the list of edge. + * + * \warning reallocate the edge array and append the internal edges. This may + * modify the behaviour of other functions. * * \remark Fortran interface: * > SUBROUTINE MMG2D_GET_NUMBEROFNONBDYEDGES(mesh,nb_edges,retval)\n @@ -2037,7 +2041,7 @@ int MMG2D_loadVtkMesh_and_allData(MMG5_pMesh mesh,MMG5_pSol *sol,const char *fil * * Get extremities \a e0, \a e1 and reference \a ref of the idx^th non boundary * edge (for DG methods for example). An edge is boundary if it is located at - * the interface of 2 domains witch different references, if it belongs to one + * the interface of 2 domains with different references, if it belongs to one * triangle only or if it is a singular edge (ridge or required). * * \remark Fortran interface: diff --git a/src/mmg3d/inout_3d.c b/src/mmg3d/inout_3d.c index af3571954..f644be5a3 100644 --- a/src/mmg3d/inout_3d.c +++ b/src/mmg3d/inout_3d.c @@ -2624,7 +2624,7 @@ int MMG3D_saveTetgenMesh(MMG5_pMesh mesh,const char *filename) { return 0; } - if ( !MMG5_saveEdge(mesh,filename) ) { + if ( !MMG5_saveEdge(mesh,filename,".edge") ) { return 0; } diff --git a/src/mmg3d/libmmg3d.h b/src/mmg3d/libmmg3d.h index 5bf8cb372..dae692c87 100644 --- a/src/mmg3d/libmmg3d.h +++ b/src/mmg3d/libmmg3d.h @@ -2759,6 +2759,10 @@ int MMG3D_switch_metricStorage(MMG5_pMesh mesh, MMG5_pSol met); * A triangle is * boundary if it is located at the interface of 2 domains with different * references or if it belongs to one tetra only. + * Append these triangles to the list of triangles. + * + * \warning reallocate the triangle array and append the internal triangles. + * This may modify the behaviour of other functions. * * \remark Fortran interface: * > SUBROUTINE MMG3D_GET_NUMBEROFNONBDYTRIANGLESS(mesh,nb_tria,retval)\n diff --git a/src/mmgs/libmmgs.h b/src/mmgs/libmmgs.h index 7e5e43a66..39274287b 100644 --- a/src/mmgs/libmmgs.h +++ b/src/mmgs/libmmgs.h @@ -1863,6 +1863,10 @@ void MMGS_setfunc(MMG5_pMesh mesh,MMG5_pSol met); * boundary if it is located at the interface of 2 domains with different * references, if it belongs to one triangle only or if it is a singular edge * (ridge or required). + * Append these edges to the list of edge. + * + * \warning reallocate the edge array and append the internal edges. This may + * modify the behaviour of other functions. * * \remark Fortran interface: * > SUBROUTINE MMGS_GET_NUMBEROFNONBDYEDGES(mesh,nb_edges,retval)\n From 635f124e9b9080ce61175b111a64cec170d4f613 Mon Sep 17 00:00:00 2001 From: Algiane Date: Thu, 3 Jun 2021 18:44:56 +0200 Subject: [PATCH 077/170] Add saving of internal edges for triangle. Implies: - now mesh->namax is setted into mesh->na instead of mesh->na+1 in hash_2d.c; - the MMG5_saveEdge function saves the entire edge array without checking the mesh->na or mesh->namax value; - mesh->namax and mesh->na may differs from the size of the edge array; --- src/common/inout.c | 24 ++++++++++++++++++++---- src/mmg2d/hash_2d.c | 2 +- src/mmg2d/inout_2d.c | 17 ++++++++++++++++- src/mmg2d/libmmg2d_tools.c | 2 ++ src/mmg3d/libmmg3d_tools.c | 2 ++ 5 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/common/inout.c b/src/common/inout.c index e671d94ad..c11e58f91 100644 --- a/src/common/inout.c +++ b/src/common/inout.c @@ -2751,9 +2751,14 @@ int MMG5_saveNode(MMG5_pMesh mesh,const char *filename) { int MMG5_saveEdge(MMG5_pMesh mesh,const char *filename,const char *ext) { FILE* inm; MMG5_pEdge pt; + size_t na_tot; int k,polyfile; + char *ptr_c = (char*)mesh->edge; char *ptr,*data; + if ( !mesh->edge ) { + return 1; + } if ( !mesh->na ) { return 1; } @@ -2798,13 +2803,24 @@ int MMG5_saveEdge(MMG5_pMesh mesh,const char *filename,const char *ext) { /* Save 0 nodes (saved in a separated .node file), dim, 0 attributes, 1 bdy * marker */ fprintf(inm, "0 %d 0 1\n",mesh->dim); - } + /* Get either the number of boundary edges or the total number of edges + * (depending if they have been append to the bdy edges, if yes, edges 1->na + * are bdy, na->na_tot are internal. */ + + /* Get size of the array in octets */ + ptr_c = ptr_c-sizeof(size_t); + na_tot = (*((size_t*)ptr_c)); + /* Recover number of edges allocated */ + na_tot /= sizeof(MMG5_Edge); + /* Array is allocated at size na+1, recover na */ + --na_tot; + /* Save node number, dim, no attributes, 1 bdy marker */ - fprintf(inm, "%d %d\n",mesh->na,1); + fprintf(inm, "%zu %d\n",na_tot,1); - for ( k=1; k<=mesh->na; ++k ) { + for ( k=1; k<=na_tot; ++k ) { /* Save edge idx */ fprintf(inm, "%d ",k); @@ -2820,7 +2836,7 @@ int MMG5_saveEdge(MMG5_pMesh mesh,const char *filename,const char *ext) { fprintf(inm, "0 \n"); } - fprintf(stdout," NUMBER OF EDGES %8d\n",mesh->na); + fprintf(stdout," NUMBER OF EDGES %8zu\n",na_tot); fclose(inm); diff --git a/src/mmg2d/hash_2d.c b/src/mmg2d/hash_2d.c index 85f873e04..d03fdffda 100644 --- a/src/mmg2d/hash_2d.c +++ b/src/mmg2d/hash_2d.c @@ -624,7 +624,7 @@ int MMG2D_pack(MMG5_pMesh mesh,MMG5_pSol sol,MMG5_pSol met) { } /** Pack edges */ - mesh->namax = mesh->na+1; + mesh->namax = mesh->na; if ( mesh->na ) { MMG5_ADD_MEM(mesh,(mesh->namax+1)*sizeof(MMG5_Edge),"final edges", memWarn=1); diff --git a/src/mmg2d/inout_2d.c b/src/mmg2d/inout_2d.c index 1fb55e3b8..b9d1fc466 100644 --- a/src/mmg2d/inout_2d.c +++ b/src/mmg2d/inout_2d.c @@ -2042,8 +2042,23 @@ int MMG2D_saveNeigh(MMG5_pMesh mesh,const char *filename) { static inline int MMG2D_saveEdge(MMG5_pMesh mesh,const char *filename) { + int ier,nb_edges; - return MMG5_saveEdge(mesh,filename,".poly"); + ier = MMG5_saveEdge(mesh,filename,".poly"); + if ( !ier ) { + printf("\n ## Error: %s: unable to save boundary edges\n.",__func__); + return 0; + } + + nb_edges = 0; + ier = MMG2D_Get_numberOfNonBdyEdges( mesh, &nb_edges); + if ( !ier ) { + printf("\n ## Error: %s: unable to count and append internal edges\n.",__func__); + return 0; + } + + ier = MMG5_saveEdge(mesh,filename,".edge"); + return ier; } diff --git a/src/mmg2d/libmmg2d_tools.c b/src/mmg2d/libmmg2d_tools.c index ae53f76ae..5d00a0b77 100644 --- a/src/mmg2d/libmmg2d_tools.c +++ b/src/mmg2d/libmmg2d_tools.c @@ -305,12 +305,14 @@ int MMG2D_Get_nonBdyEdge(MMG5_pMesh mesh, int* e0, int* e1, int* ref, int idx) { " before the %s one and check that the number of internal" " edges is non null.\n", __func__,__func__); + return 0; } if ( mesh->namax+idx > na_tot ) { fprintf(stderr,"\n ## Error: %s: Can't get the internal edge of index %d." " Index must be between 1 and %zu.\n", __func__,idx,na_tot-mesh->namax); + return 0; } ped = &mesh->edge[mesh->namax+idx]; diff --git a/src/mmg3d/libmmg3d_tools.c b/src/mmg3d/libmmg3d_tools.c index 7113e7228..46bce5dfb 100644 --- a/src/mmg3d/libmmg3d_tools.c +++ b/src/mmg3d/libmmg3d_tools.c @@ -916,12 +916,14 @@ int MMG3D_Get_nonBdyTriangle(MMG5_pMesh mesh,int* v0,int* v1,int* v2, " before the %s one and check that the number of internal" " triangles is non null.\n", __func__,__func__); + return 0; } if ( mesh->nt+idx > nt_tot ) { fprintf(stderr,"\n ## Error: %s: Can't get the internal triangle of index %d." " Index must be between 1 and %zu.\n", __func__,idx,nt_tot-mesh->nt); + return 0; } ptt = &mesh->tria[mesh->nt+idx]; From 0a96f19e410c1d3d6fb30019e82542deb50c958c Mon Sep 17 00:00:00 2001 From: Algiane Date: Fri, 4 Jun 2021 15:14:06 +0200 Subject: [PATCH 078/170] remove useless variable. --- src/mmg3d/delaunay_3d.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mmg3d/delaunay_3d.c b/src/mmg3d/delaunay_3d.c index 9788750fa..5898ab666 100644 --- a/src/mmg3d/delaunay_3d.c +++ b/src/mmg3d/delaunay_3d.c @@ -146,7 +146,7 @@ int MMG5_delone(MMG5_pMesh mesh,MMG5_pSol sol,int ip,int *list,int ilist) { int vois[4],iadrold; short i1; char alert; - int isused = 0,ixt,ielnum[3*MMG3D_LONMAX+1],ll; + int isused = 0,ixt,ielnum[3*MMG3D_LONMAX+1]; MMG5_Hash hedg; #ifndef NDEBUG int tref; From 4d15137f1b70f39fdf8d29e72e3cf88b3a4d697d Mon Sep 17 00:00:00 2001 From: Algiane Date: Fri, 4 Jun 2021 15:37:39 +0200 Subject: [PATCH 079/170] Remove memory error in vtk outputs. --- src/common/vtkparser.cpp | 24 ++++++++++++------------ src/mmg2d/mmg2d6.c | 3 ++- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/common/vtkparser.cpp b/src/common/vtkparser.cpp index bc976adbc..d7d74ddd4 100644 --- a/src/common/vtkparser.cpp +++ b/src/common/vtkparser.cpp @@ -616,12 +616,6 @@ int MMG5_loadVtkMesh_part2(MMG5_pMesh mesh,MMG5_pSol *sol,vtkDataSet **dataset, int npointData = pd->GetNumberOfArrays(); for (int j = 0; j < npointData; j++) { - psl = *sol + isol; - psl->ver = mesh->ver; - psl->dim = mesh->dim; - psl->type = 1; - psl->entities = MMG5_Vertex; - char *ptr = NULL; bool metricData = 0; char chaine[MMG5_FILESTR_LGTH]; @@ -635,6 +629,12 @@ int MMG5_loadVtkMesh_part2(MMG5_pMesh mesh,MMG5_pSol *sol,vtkDataSet **dataset, metricData = 1; } + psl = *sol + isol; + psl->ver = mesh->ver; + psl->dim = mesh->dim; + psl->type = 1; + psl->entities = MMG5_Vertex; + if ( !MMG5_Set_inputSolName(mesh,psl,chaine) ) { if ( !mmgWarn1 ) { mmgWarn1 = 1; @@ -753,12 +753,6 @@ int MMG5_loadVtkMesh_part2(MMG5_pMesh mesh,MMG5_pSol *sol,vtkDataSet **dataset, int ncellData = cd->GetNumberOfArrays(); for (int j = 0; j < ncellData; j++) { - psl = *sol + isol; - psl->ver = mesh->ver; - psl->dim = mesh->dim; - psl->type = 1; - psl->entities = MMG5_Tetrahedron; - char *ptr = NULL; char chaine[MMG5_FILESTR_LGTH]; strcpy(chaine,cd->GetArrayName(j)); @@ -767,6 +761,12 @@ int MMG5_loadVtkMesh_part2(MMG5_pMesh mesh,MMG5_pSol *sol,vtkDataSet **dataset, continue; } + psl = *sol + isol; + psl->ver = mesh->ver; + psl->dim = mesh->dim; + psl->type = 1; + psl->entities = MMG5_Tetrahedron; + if ( !MMG5_Set_inputSolName(mesh,psl,chaine) ) { if ( !mmgWarn1 ) { mmgWarn1 = 1; diff --git a/src/mmg2d/mmg2d6.c b/src/mmg2d/mmg2d6.c index f4dfaedf9..f044bd410 100644 --- a/src/mmg2d/mmg2d6.c +++ b/src/mmg2d/mmg2d6.c @@ -830,7 +830,8 @@ int MMG2D_cuttri_ls(MMG5_pMesh mesh, MMG5_pSol sol, MMG5_pSol met){ } if ( !nb ) return 1; - /* Create the intersection points between the edges in the mesh and the 0 level set */ + /* Create the intersection points between the edges in the mesh and the 0 + * level set */ if ( !MMG5_hashNew(mesh,&hash,nb,2*nb) ) return 0; for (k=1; k<=mesh->nt; k++) { From 439e85e93451b2cbad8b514839ad468dd74c8052 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 22 Jun 2021 10:42:39 +0200 Subject: [PATCH 080/170] Remove a bug in the setVertexNmTag analysis function: as mesh->base is incremented inside the boulernm function, the point flag was never equal to mesh->base and the computations were done multiple times for a given points (from each tetra to which the point belong). --- src/mmg3d/hash_3d.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mmg3d/hash_3d.c b/src/mmg3d/hash_3d.c index 38f49c72e..ee45738d6 100644 --- a/src/mmg3d/hash_3d.c +++ b/src/mmg3d/hash_3d.c @@ -681,7 +681,7 @@ int MMG5_setVertexNmTag(MMG5_pMesh mesh) { MMG5_pTetra ptet; MMG5_pPoint ppt; MMG5_Hash hash; - int k,i; + int k,i,base; int nc, nre, ng, nrp,ier; /* Second: seek the non-required non-manifold points and try to analyse @@ -692,15 +692,15 @@ int MMG5_setVertexNmTag(MMG5_pMesh mesh) { if ( ! MMG5_hashNew(mesh,&hash,mesh->np,(int)(3.71*mesh->np)) ) return 0; nc = nre = 0; - ++mesh->base; + base = ++mesh->base; for (k=1; k<=mesh->ne; ++k) { ptet = &mesh->tetra[k]; if ( !MG_EOK(ptet) ) continue; for ( i=0; i<4; ++i ) { ppt = &mesh->point[ptet->v[i]]; - if ( (!MG_VOK(ppt)) || (ppt->flag==mesh->base) ) continue; - ppt->flag = mesh->base; + if ( (!MG_VOK(ppt)) || (ppt->flag==base) ) continue; + ppt->flag = base; if ( (!(ppt->tag & MG_NOM)) || (ppt->tag & MG_REQ) ) continue; From ce114c251d9c975c06e50dca1c36f191af787eb3 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 22 Jun 2021 11:15:46 +0200 Subject: [PATCH 081/170] Modification of the edge hash table size for the analysis of non-manifold points: it was allocated at mesh->np size (too large), now we use the number of non-manifold non required points. --- src/mmg3d/hash_3d.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/mmg3d/hash_3d.c b/src/mmg3d/hash_3d.c index ee45738d6..b1c8388cd 100644 --- a/src/mmg3d/hash_3d.c +++ b/src/mmg3d/hash_3d.c @@ -682,14 +682,21 @@ int MMG5_setVertexNmTag(MMG5_pMesh mesh) { MMG5_pPoint ppt; MMG5_Hash hash; int k,i,base; - int nc, nre, ng, nrp,ier; + int np,nc, nre, ng, nrp,ier; /* Second: seek the non-required non-manifold points and try to analyse * whether they are corner or required. */ /* Hash table used by boulernm to store the special edges passing through * a given point */ - if ( ! MMG5_hashNew(mesh,&hash,mesh->np,(int)(3.71*mesh->np)) ) return 0; + np = 0; + for (k=1; k<=mesh->np; ++k) { + ppt = &mesh->point[k]; + if ( (!(ppt->tag & MG_NOM)) || (ppt->tag & MG_REQ) ) continue; + ++np; + } + + if ( ! MMG5_hashNew(mesh,&hash,np,(int)(3.71*np)) ) return 0; nc = nre = 0; base = ++mesh->base; From f1c6a2ec1224591ec130bc8d7e4579c07e73992a Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 22 Jun 2021 11:17:52 +0200 Subject: [PATCH 082/170] indentation. --- src/mmg3d/libmmg3d.c | 122 +++++++++++++++++++++---------------------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/src/mmg3d/libmmg3d.c b/src/mmg3d/libmmg3d.c index 9a9ed83ec..5d0ca7c4a 100644 --- a/src/mmg3d/libmmg3d.c +++ b/src/mmg3d/libmmg3d.c @@ -46,19 +46,19 @@ * Pack the mesh \a mesh and its associated metric \a met and/or solution \a sol * and return \a val. */ -#define MMG5_RETURN_AND_PACK(mesh,met,sol,val)do \ - { \ - if ( !MMG3D_packMesh(mesh,met,sol) ) { \ - mesh->npi = mesh->np; \ - mesh->nti = mesh->nt; \ - mesh->nai = mesh->na; \ - mesh->nei = mesh->ne; \ - mesh->xt = 0; \ - if ( met ) { met->npi = met->np; } \ - if ( sol ) { sol->npi = sol->np; } \ - return MMG5_STRONGFAILURE; \ - } \ - _LIBMMG5_RETURN(mesh,met,sol,val); \ +#define MMG5_RETURN_AND_PACK(mesh,met,sol,val)do \ + { \ + if ( !MMG3D_packMesh(mesh,met,sol) ) { \ + mesh->npi = mesh->np; \ + mesh->nti = mesh->nt; \ + mesh->nai = mesh->na; \ + mesh->nei = mesh->ne; \ + mesh->xt = 0; \ + if ( met ) { met->npi = met->np; } \ + if ( sol ) { sol->npi = sol->np; } \ + return MMG5_STRONGFAILURE; \ + } \ + _LIBMMG5_RETURN(mesh,met,sol,val); \ }while(0) /** Free adja, xtetra and xpoint tables */ @@ -130,7 +130,7 @@ int MMG3D_bdryBuild(MMG5_pMesh mesh) { ( mesh->xtetra[pt->xt].tag[i] & MG_REQ || MG_EDG(mesh->xtetra[pt->xt].tag[i])) ) if ( !MMG5_hEdge(mesh,&mesh->htab,pt->v[MMG5_iare[i][0]],pt->v[MMG5_iare[i][1]], - mesh->xtetra[pt->xt].edg[i],mesh->xtetra[pt->xt].tag[i])) + mesh->xtetra[pt->xt].edg[i],mesh->xtetra[pt->xt].tag[i])) return -1; } } @@ -144,8 +144,8 @@ int MMG3D_bdryBuild(MMG5_pMesh mesh) { } if ( mesh->na ) { MMG5_ADD_MEM(mesh,(mesh->na+1)*sizeof(MMG5_Edge),"edges", - mesh->na = 0; - printf(" ## Warning: uncomplete mesh\n")); + mesh->na = 0; + printf(" ## Warning: uncomplete mesh\n")); } if ( mesh->na ) { @@ -1123,45 +1123,45 @@ int MMG3D_mmg3dlib(MMG5_pMesh mesh,MMG5_pSol met) { fprintf(stdout," -- PHASE 1 COMPLETED. %s\n",stim); if ( (!mesh->info.nomove) || (!mesh->info.noswap) || (!mesh->info.noinsert) ) { - /* mesh adaptation */ - chrono(ON,&(ctim[3])); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout,"\n -- PHASE 2 : %s MESHING\n",met->size < 6 ? "ISOTROPIC" : "ANISOTROPIC"); - } + /* mesh adaptation */ + chrono(ON,&(ctim[3])); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout,"\n -- PHASE 2 : %s MESHING\n",met->size < 6 ? "ISOTROPIC" : "ANISOTROPIC"); + } - /* renumerotation if available */ + /* renumerotation if available */ if ( !MMG5_scotchCall(mesh,met,NULL,NULL) ) - { + { if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); MMG5_RETURN_AND_PACK(mesh,met,sol,MMG5_LOWFAILURE); - } + } #ifdef PATTERN if ( !MMG5_mmg3d1_pattern(mesh,met,NULL) ) { - if ( !(mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { - fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); + if ( !(mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { + fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); - } + } if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); MMG5_RETURN_AND_PACK(mesh,met,sol,MMG5_LOWFAILURE); - } + } #else if ( !MMG5_mmg3d1_delone(mesh,met,NULL) ) { - if ( (!mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { - fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); + if ( (!mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { + fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); - } + } if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); MMG5_RETURN_AND_PACK(mesh,met,sol,MMG5_LOWFAILURE); - } + } #endif - chrono(OFF,&(ctim[3])); - printim(ctim[3].gdif,stim); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout," -- PHASE 2 COMPLETED. %s\n",stim); - } + chrono(OFF,&(ctim[3])); + printim(ctim[3].gdif,stim); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout," -- PHASE 2 COMPLETED. %s\n",stim); + } } /* last renum to give back a good numbering to the user */ @@ -1258,14 +1258,14 @@ int MMG3D_mmg3dls(MMG5_pMesh mesh,MMG5_pSol sol,MMG5_pSol umet) { /* Specific meshing */ if ( met && met->np ) { - if ( mesh->info.optim ) { + if ( mesh->info.optim ) { printf("\n ## ERROR: MISMATCH OPTIONS: OPTIM OPTION CAN NOT BE USED" " WITH AN INPUT METRIC.\n"); if ( mettofree ) { MMG5_DEL_MEM(mesh,met->m);MMG5_SAFE_FREE (met); } _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); - } + } - if ( mesh->info.hsiz>0. ) { + if ( mesh->info.hsiz>0. ) { printf("\n ## ERROR: MISMATCH OPTIONS: HSIZ OPTION CAN NOT BE USED" " WITH AN INPUT METRIC.\n"); if ( mettofree ) { MMG5_DEL_MEM(mesh,met->m);MMG5_SAFE_FREE (met); } @@ -1556,7 +1556,7 @@ int MMG3D_mmg3dmov(MMG5_pMesh mesh,MMG5_pSol met, MMG5_pSol disp) { #ifndef USE_ELAS fprintf(stderr,"\n ## ERROR: YOU NEED TO COMPILE WITH THE USE_ELAS" - " CMake's FLAG SET TO ON TO USE THE RIGIDBODY MOVEMENT LIBRARY.\n"); + " CMake's FLAG SET TO ON TO USE THE RIGIDBODY MOVEMENT LIBRARY.\n"); _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); #endif @@ -1668,44 +1668,44 @@ int MMG3D_mmg3dmov(MMG5_pMesh mesh,MMG5_pSol met, MMG5_pSol disp) { /* End with a classical remeshing stage, provided mesh->info.lag >= 1 */ if ( (ier > 0) && (mesh->info.lag >= 1) ) { - chrono(ON,&(ctim[4])); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT\n"); - } + chrono(ON,&(ctim[4])); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT\n"); + } - /* renumerotation if available */ + /* renumerotation if available */ if ( !MMG5_scotchCall(mesh,met,disp,NULL) ) - { + { if ( !MMG5_unscaleMesh(mesh,met,disp) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); MMG5_RETURN_AND_PACK(mesh,met,disp,MMG5_LOWFAILURE); - } + } #ifdef PATTERN if ( !MMG5_mmg3d1_pattern(mesh,met,NULL) ) { - if ( !(mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { - fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); + if ( !(mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { + fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); - } + } if ( !MMG5_unscaleMesh(mesh,met,disp) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); MMG5_RETURN_AND_PACK(mesh,met,disp,MMG5_LOWFAILURE); - } + } #else if ( !MMG5_mmg3d1_delone(mesh,met,NULL) ) { - if ( !(mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { - fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); + if ( !(mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { + fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); - } + } if ( !MMG5_unscaleMesh(mesh,met,disp) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); MMG5_RETURN_AND_PACK(mesh,met,disp,MMG5_LOWFAILURE); - } + } #endif - chrono(OFF,&(ctim[4])); - printim(ctim[4].gdif,stim); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout," -- PHASE 3 COMPLETED. %s\n",stim); - } + chrono(OFF,&(ctim[4])); + printim(ctim[4].gdif,stim); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout," -- PHASE 3 COMPLETED. %s\n",stim); } + } /* last renum to give back a good numbering to the user */ if ( !MMG5_scotchCall(mesh,met,disp,NULL) ) From 8fd3ed3959f0342b88400ef971ddae151eec23fa Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 22 Jun 2021 11:31:27 +0200 Subject: [PATCH 083/170] Do not call mmg3d1 in ls + noinsert-noswap-nomove mode. --- src/mmg3d/libmmg3d.c | 131 ++++++++++++++++++++++--------------------- 1 file changed, 68 insertions(+), 63 deletions(-) diff --git a/src/mmg3d/libmmg3d.c b/src/mmg3d/libmmg3d.c index 5d0ca7c4a..708c19088 100644 --- a/src/mmg3d/libmmg3d.c +++ b/src/mmg3d/libmmg3d.c @@ -1398,48 +1398,50 @@ int MMG3D_mmg3dls(MMG5_pMesh mesh,MMG5_pSol sol,MMG5_pSol umet) { if ( mesh->info.imprim > 0 ) fprintf(stdout," -- PHASE 2 COMPLETED. %s\n",stim); - /* mesh adaptation */ - chrono(ON,&(ctim[4])); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT\n"); - } + if ( (!mesh->info.nomove) || (!mesh->info.noswap) || (!mesh->info.noinsert) ) { - /* renumerotation if available */ - if ( !MMG5_scotchCall(mesh,met,NULL,NULL) ) - { - if ( mettofree ) { MMG5_DEL_MEM(mesh,met->m);MMG5_SAFE_FREE (met); } - if ( !MMG5_unscaleMesh(mesh,met,sol) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); - MMG5_RETURN_AND_PACK(mesh,sol,met,MMG5_LOWFAILURE); - } + /* mesh adaptation */ + chrono(ON,&(ctim[4])); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT\n"); + } + + /* renumerotation if available */ + if ( !MMG5_scotchCall(mesh,met,NULL,NULL) ) + { + if ( mettofree ) { MMG5_DEL_MEM(mesh,met->m);MMG5_SAFE_FREE (met); } + if ( !MMG5_unscaleMesh(mesh,met,sol) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + MMG5_RETURN_AND_PACK(mesh,sol,met,MMG5_LOWFAILURE); + } #ifdef PATTERN - if ( !MMG5_mmg3d1_pattern(mesh,met,NULL) ) { - if ( mettofree ) { MMG5_DEL_MEM(mesh,met->m);MMG5_SAFE_FREE (met); } - if ( !(mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { - fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); - _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + if ( !MMG5_mmg3d1_pattern(mesh,met,NULL) ) { + if ( mettofree ) { MMG5_DEL_MEM(mesh,met->m);MMG5_SAFE_FREE (met); } + if ( !(mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { + fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); + _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + } + if ( !MMG5_unscaleMesh(mesh,met,sol) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + MMG5_RETURN_AND_PACK(mesh,sol,met,MMG5_LOWFAILURE); } - if ( !MMG5_unscaleMesh(mesh,met,sol) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); - MMG5_RETURN_AND_PACK(mesh,sol,met,MMG5_LOWFAILURE); - } #else - if ( !MMG5_mmg3d1_pattern(mesh,met,NULL) ) { - if ( mettofree ) { MMG5_DEL_MEM(mesh,met->m);MMG5_SAFE_FREE (met); } - if ( !(mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { - fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); - _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + if ( !MMG5_mmg3d1_pattern(mesh,met,NULL) ) { + if ( mettofree ) { MMG5_DEL_MEM(mesh,met->m);MMG5_SAFE_FREE (met); } + if ( !(mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { + fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); + _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + } + if ( !MMG5_unscaleMesh(mesh,met,sol) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + MMG5_RETURN_AND_PACK(mesh,sol,met,MMG5_LOWFAILURE); } - if ( !MMG5_unscaleMesh(mesh,met,sol) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); - MMG5_RETURN_AND_PACK(mesh,sol,met,MMG5_LOWFAILURE); - } #endif - chrono(OFF,&(ctim[4])); - printim(ctim[4].gdif,stim); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout," -- PHASE 3 COMPLETED. %s\n",stim); + chrono(OFF,&(ctim[4])); + printim(ctim[4].gdif,stim); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout," -- PHASE 3 COMPLETED. %s\n",stim); + } } - /* last renum to give back a good numbering to the user */ if ( !MMG5_scotchCall(mesh,met,NULL,NULL) ) { @@ -1666,44 +1668,47 @@ int MMG3D_mmg3dmov(MMG5_pMesh mesh,MMG5_pSol met, MMG5_pSol disp) { fprintf(stdout," -- PHASE 2 COMPLETED. %s\n",stim); } - /* End with a classical remeshing stage, provided mesh->info.lag >= 1 */ - if ( (ier > 0) && (mesh->info.lag >= 1) ) { - chrono(ON,&(ctim[4])); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT\n"); - } + if ( (!mesh->info.nomove) || (!mesh->info.noswap) || (!mesh->info.noinsert) ) { - /* renumerotation if available */ - if ( !MMG5_scotchCall(mesh,met,disp,NULL) ) - { - if ( !MMG5_unscaleMesh(mesh,met,disp) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); - MMG5_RETURN_AND_PACK(mesh,met,disp,MMG5_LOWFAILURE); - } + /* End with a classical remeshing stage, provided mesh->info.lag >= 1 */ + if ( (ier > 0) && (mesh->info.lag >= 1) ) { + chrono(ON,&(ctim[4])); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT\n"); + } + + /* renumerotation if available */ + if ( !MMG5_scotchCall(mesh,met,disp,NULL) ) + { + if ( !MMG5_unscaleMesh(mesh,met,disp) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); + MMG5_RETURN_AND_PACK(mesh,met,disp,MMG5_LOWFAILURE); + } #ifdef PATTERN - if ( !MMG5_mmg3d1_pattern(mesh,met,NULL) ) { - if ( !(mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { - fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); - _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); + if ( !MMG5_mmg3d1_pattern(mesh,met,NULL) ) { + if ( !(mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { + fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); + _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); + } + if ( !MMG5_unscaleMesh(mesh,met,disp) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); + MMG5_RETURN_AND_PACK(mesh,met,disp,MMG5_LOWFAILURE); } - if ( !MMG5_unscaleMesh(mesh,met,disp) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); - MMG5_RETURN_AND_PACK(mesh,met,disp,MMG5_LOWFAILURE); - } #else - if ( !MMG5_mmg3d1_delone(mesh,met,NULL) ) { - if ( !(mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { - fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); - _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); + if ( !MMG5_mmg3d1_delone(mesh,met,NULL) ) { + if ( !(mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { + fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); + _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); + } + if ( !MMG5_unscaleMesh(mesh,met,disp) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); + MMG5_RETURN_AND_PACK(mesh,met,disp,MMG5_LOWFAILURE); } - if ( !MMG5_unscaleMesh(mesh,met,disp) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); - MMG5_RETURN_AND_PACK(mesh,met,disp,MMG5_LOWFAILURE); - } #endif - chrono(OFF,&(ctim[4])); - printim(ctim[4].gdif,stim); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout," -- PHASE 3 COMPLETED. %s\n",stim); + chrono(OFF,&(ctim[4])); + printim(ctim[4].gdif,stim); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout," -- PHASE 3 COMPLETED. %s\n",stim); + } } } From 841e53e7940c8b2888755af1c0dcfbb0e023ac4e Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 22 Jun 2021 11:39:04 +0200 Subject: [PATCH 084/170] clean unused var. --- src/common/mmg2.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/common/mmg2.c b/src/common/mmg2.c index a2ffac886..1201486c0 100644 --- a/src/common/mmg2.c +++ b/src/common/mmg2.c @@ -357,7 +357,6 @@ int MMG5_isSplit(MMG5_pMesh mesh,int ref,int *refint,int *refext) { */ int MMG5_isNotSplit(MMG5_pMesh mesh,int ref) { MMG5_pInvMat pim; - int8_t k; /* Split material by default if not in multi-material mode */ if( !mesh->info.nmat ) return 0; From 3f236e4aa57130e0599b0da6bc99251d5eb5c73a Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 22 Jun 2021 11:39:43 +0200 Subject: [PATCH 085/170] Indent + do not call adaptation process in noinsert-noswap-nomove mode of mmgs. --- src/mmgs/libmmgs.c | 114 +++++++++++++++++++++++---------------------- 1 file changed, 58 insertions(+), 56 deletions(-) diff --git a/src/mmgs/libmmgs.c b/src/mmgs/libmmgs.c index cac89cf9b..c0b294975 100644 --- a/src/mmgs/libmmgs.c +++ b/src/mmgs/libmmgs.c @@ -44,19 +44,19 @@ /** * Pack the mesh \a mesh and its associated metric \a met and return \a val. */ -#define MMGS_RETURN_AND_PACK(mesh,met,sol,val)do \ - { \ - if ( !MMGS_packMesh(mesh,met,sol) ) { \ - mesh->npi = mesh->np; \ - mesh->nti = mesh->nt; \ - mesh->nai = mesh->na; \ - mesh->nei = mesh->ne; \ - met->npi = met->np; \ - if ( met ) { met->npi = met->np; } \ - if ( sol ) { sol->npi = sol->np; } \ - return MMG5_LOWFAILURE; \ - } \ - _LIBMMG5_RETURN(mesh,met,sol,val); \ +#define MMGS_RETURN_AND_PACK(mesh,met,sol,val)do \ + { \ + if ( !MMGS_packMesh(mesh,met,sol) ) { \ + mesh->npi = mesh->np; \ + mesh->nti = mesh->nt; \ + mesh->nai = mesh->na; \ + mesh->nei = mesh->ne; \ + met->npi = met->np; \ + if ( met ) { met->npi = met->np; } \ + if ( sol ) { sol->npi = sol->np; } \ + return MMG5_LOWFAILURE; \ + } \ + _LIBMMG5_RETURN(mesh,met,sol,val); \ }while(0) /** Free adja, xtetra and xpoint tables */ @@ -225,8 +225,8 @@ int MMGS_packMesh(MMG5_pMesh mesh,MMG5_pSol sol,MMG5_pSol met) { if ( na ) { MMG5_ADD_MEM(mesh,(na+1)*sizeof(MMG5_Edge),"final edges", - na = 0; - printf(" ## Warning: uncomplete mesh\n") + na = 0; + printf(" ## Warning: uncomplete mesh\n") ); } @@ -462,7 +462,7 @@ int MMGS_mmgsls(MMG5_pMesh mesh,MMG5_pSol sol,MMG5_pSol umet) if ( !MMGS_analys(mesh) ) { if ( mettofree ) { MMG5_DEL_MEM(mesh,met->m);MMG5_SAFE_FREE (met); } if ( !MMG5_unscaleMesh(mesh,met,sol) ) - _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); MMGS_RETURN_AND_PACK(mesh,met,sol,MMG5_LOWFAILURE); } @@ -472,27 +472,27 @@ int MMGS_mmgsls(MMG5_pMesh mesh,MMG5_pSol sol,MMG5_pSol umet) fprintf(stdout," -- PHASE 2 COMPLETED. %s\n",stim); if ( (!mesh->info.nomove) || (!mesh->info.noswap) || (!mesh->info.noinsert) ) { - /* mesh adaptation */ - chrono(ON,&(ctim[4])); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT\n"); - } + /* mesh adaptation */ + chrono(ON,&(ctim[4])); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT\n"); + } if ( !MMG5_mmgs1(mesh,met,NULL) ) { if ( mettofree ) { MMG5_DEL_MEM(mesh,met->m);MMG5_SAFE_FREE (met); } - if ( (!mesh->adja) && !MMGS_hashTria(mesh) ) { - fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); + if ( (!mesh->adja) && !MMGS_hashTria(mesh) ) { + fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); - } + } if ( !MMG5_unscaleMesh(mesh,met,sol) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); MMGS_RETURN_AND_PACK(mesh,met,sol,MMG5_LOWFAILURE); - } + } - chrono(OFF,&(ctim[4])); - printim(ctim[4].gdif,stim); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout," -- PHASE 3 COMPLETED. %s\n",stim); - } + chrono(OFF,&(ctim[4])); + printim(ctim[4].gdif,stim); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout," -- PHASE 3 COMPLETED. %s\n",stim); + } } /* save file */ @@ -570,7 +570,7 @@ int MMGS_mmgslib(MMG5_pMesh mesh,MMG5_pSol met) fprintf(stderr,"\n ## ERROR: LEVEL-SET DISCRETISATION UNAVAILABLe" " (MMGS_IPARAM_iso):\n" " YOU MUST CALL THE MMGS_MMGSLS FUNCTION TO USE THIS OPTION.\n"); - _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); } #ifdef USE_SCOTCH @@ -589,27 +589,27 @@ int MMGS_mmgslib(MMG5_pMesh mesh,MMG5_pSol met) } else if ( met->size!=1 && met->size!=6 ) { fprintf(stderr,"\n ## ERROR: WRONG DATA TYPE.\n"); - _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); } /* specific meshing */ if ( met->np ) { - if ( mesh->info.optim ) { + if ( mesh->info.optim ) { printf("\n ## ERROR: MISMATCH OPTIONS: OPTIM OPTION CAN NOT BE USED" " WITH AN INPUT METRIC.\n"); - _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); - } + _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + } if ( mesh->info.hsiz>0. ) { printf("\n ## ERROR: MISMATCH OPTIONS: HSIZ OPTION CAN NOT BE USED" " WITH AN INPUT METRIC.\n"); - _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); } } if ( mesh->info.optim && mesh->info.hsiz>0. ) { printf("\n ## ERROR: MISMATCH OPTIONS: HSIZ AND OPTIM OPTIONS CAN NOT BE USED" " TOGETHER.\n"); - _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); } chrono(OFF,&(ctim[1])); @@ -631,15 +631,15 @@ int MMGS_mmgslib(MMG5_pMesh mesh,MMG5_pSol met) if ( mesh->info.optim ) { if ( !MMGS_doSol(mesh,met) ) { if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); - _LIBMMG5_RETURN(mesh,met,sol,MMG5_LOWFAILURE); + _LIBMMG5_RETURN(mesh,met,sol,MMG5_LOWFAILURE); } MMG5_solTruncatureForOptim(mesh,met); } if ( mesh->info.hsiz > 0. ) { if ( !MMGS_Set_constantSize(mesh,met) ) { - if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); - _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); } } @@ -648,7 +648,7 @@ int MMGS_mmgslib(MMG5_pMesh mesh,MMG5_pSol met) /* mesh analysis */ if ( !MMGS_analys(mesh) ) { if ( !MMG5_unscaleMesh(mesh,met,NULL) ) - _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); MMGS_RETURN_AND_PACK(mesh,met,sol,MMG5_LOWFAILURE); } @@ -668,25 +668,27 @@ int MMGS_mmgslib(MMG5_pMesh mesh,MMG5_pSol met) if ( mesh->info.imprim > 0 ) fprintf(stdout," -- PHASE 1 COMPLETED. %s\n",stim); - /* mesh adaptation */ - chrono(ON,&(ctim[3])); - if ( mesh->info.imprim > 0 ) { + if ( (!mesh->info.nomove) || (!mesh->info.noswap) || (!mesh->info.noinsert) ) { + /* mesh adaptation */ + chrono(ON,&(ctim[3])); + if ( mesh->info.imprim > 0 ) { fprintf(stdout,"\n -- PHASE 2 : %s MESHING\n",met->size < 6 ? "ISOTROPIC" : "ANISOTROPIC"); - } + } - if ( !MMG5_mmgs1(mesh,met,NULL) ) { - if ( (!mesh->adja) && !MMGS_hashTria(mesh) ) { - fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); + if ( !MMG5_mmgs1(mesh,met,NULL) ) { + if ( (!mesh->adja) && !MMGS_hashTria(mesh) ) { + fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + } + if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + MMGS_RETURN_AND_PACK(mesh,met,sol,MMG5_LOWFAILURE); } - if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); - MMGS_RETURN_AND_PACK(mesh,met,sol,MMG5_LOWFAILURE); - } - chrono(OFF,&(ctim[3])); - printim(ctim[3].gdif,stim); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout," -- PHASE 2 COMPLETED. %s\n",stim); + chrono(OFF,&(ctim[3])); + printim(ctim[3].gdif,stim); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout," -- PHASE 2 COMPLETED. %s\n",stim); + } } /* save file */ @@ -713,5 +715,5 @@ int MMGS_mmgslib(MMG5_pMesh mesh,MMG5_pSol met) fprintf(stdout,"\n %s\n END OF MODULE MMGS\n %s\n\n",MG_STR,MG_STR); } - _LIBMMG5_RETURN(mesh,met,sol,MMG5_SUCCESS); + _LIBMMG5_RETURN(mesh,met,sol,MMG5_SUCCESS); } From f5b10eca7cfa39d00b86f2e6f1b594a5299f53cc Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 22 Jun 2021 11:49:34 +0200 Subject: [PATCH 086/170] Do not call adaptation function in noinsert-noswap-nomove mode of mmg2d + call quality and lengths histo before unscaling. --- src/mmg2d/libmmg2d.c | 154 +++++++++++++++++++++++-------------------- src/mmg3d/libmmg3d.c | 2 +- 2 files changed, 84 insertions(+), 72 deletions(-) diff --git a/src/mmg2d/libmmg2d.c b/src/mmg2d/libmmg2d.c index c12cc5495..928da3e64 100644 --- a/src/mmg2d/libmmg2d.c +++ b/src/mmg2d/libmmg2d.c @@ -319,29 +319,32 @@ int MMG2D_mmg2dlib(MMG5_pMesh mesh,MMG5_pSol met) if ( mesh->info.imprim > 0 ) fprintf(stdout," -- PHASE 1 COMPLETED. %s\n",stim); - /* remeshing */ - chrono(ON,&ctim[3]); + if ( (!mesh->info.nomove) || (!mesh->info.noswap) || (!mesh->info.noinsert) ) { - if ( mesh->info.imprim > 0 ) - fprintf(stdout,"\n -- PHASE 2 : %s MESHING\n",met->size < 3 ? "ISOTROPIC" : "ANISOTROPIC"); + /* remeshing */ + chrono(ON,&ctim[3]); - /* Mesh improvement */ - if ( !MMG2D_mmg2d1n(mesh,met) ) { - if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); - MMG2D_RETURN_AND_PACK(mesh,met,sol,MMG5_LOWFAILURE); - } + if ( mesh->info.imprim > 0 ) + fprintf(stdout,"\n -- PHASE 2 : %s MESHING\n",met->size < 3 ? "ISOTROPIC" : "ANISOTROPIC"); - chrono(OFF,&(ctim[3])); - printim(ctim[3].gdif,stim); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout," -- PHASE 2 COMPLETED. %s\n",stim); + /* Mesh improvement */ + if ( !MMG2D_mmg2d1n(mesh,met) ) { + if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + MMG2D_RETURN_AND_PACK(mesh,met,sol,MMG5_LOWFAILURE); + } + + chrono(OFF,&(ctim[3])); + printim(ctim[3].gdif,stim); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout," -- PHASE 2 COMPLETED. %s\n",stim); + } } /* Print output quality history */ if ( !MMG2D_outqua(mesh,met) ) { - if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); - MMG2D_RETURN_AND_PACK(mesh,met,sol,MMG5_LOWFAILURE); - } + if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + MMG2D_RETURN_AND_PACK(mesh,met,sol,MMG5_LOWFAILURE); + } /* Print edge length histories */ if ( abs(mesh->info.imprim) > 4 ) { @@ -585,25 +588,25 @@ int MMG2D_mmg2dmesh(MMG5_pMesh mesh,MMG5_pSol met) { if ( mesh->info.imprim > 0 ) fprintf(stdout," -- PHASE 2 COMPLETED. %s\n",stim); - /* Mesh improvement - call new version of mmg2d1 */ - chrono(ON,&(ctim[4])); - if ( mesh->info.imprim > 0 ) - fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT (%s)\n", - met->size < 3 ? "ISOTROPIC" : "ANISOTROPIC"); + if ( (!mesh->info.nomove) || (!mesh->info.noswap) || (!mesh->info.noinsert) ) { - if ( !MMG2D_mmg2d1n(mesh,met) ) { - if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); - MMG2D_RETURN_AND_PACK(mesh,met,sol,MMG5_LOWFAILURE); - } + /* Mesh improvement - call new version of mmg2d1 */ + chrono(ON,&(ctim[4])); + if ( mesh->info.imprim > 0 ) + fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT (%s)\n", + met->size < 3 ? "ISOTROPIC" : "ANISOTROPIC"); - chrono(OFF,&(ctim[4])); - printim(ctim[4].gdif,stim); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout," -- PHASE 3 COMPLETED. %s\n",stim); - } + if ( !MMG2D_mmg2d1n(mesh,met) ) { + if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + MMG2D_RETURN_AND_PACK(mesh,met,sol,MMG5_LOWFAILURE); + } - /* Unscale mesh */ - if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + chrono(OFF,&(ctim[4])); + printim(ctim[4].gdif,stim); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout," -- PHASE 3 COMPLETED. %s\n",stim); + } + } /* Print quality histories */ if ( !MMG2D_outqua(mesh,met) ) { @@ -615,6 +618,9 @@ int MMG2D_mmg2dmesh(MMG5_pMesh mesh,MMG5_pSol met) { MMG2D_prilen(mesh,met); } + /* Unscale mesh */ + if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + chrono(ON,&(ctim[1])); if ( mesh->info.imprim > 0 ) fprintf(stdout,"\n -- MESH PACKED UP\n"); @@ -859,28 +865,40 @@ int MMG2D_mmg2dls(MMG5_pMesh mesh,MMG5_pSol sol,MMG5_pSol umet) if ( mesh->info.imprim > 0 ) fprintf(stdout," -- PHASE 2 COMPLETED. %s\n",stim); - /* Mesh improvement - call new version of mmg2d1 */ - chrono(ON,&ctim[4]); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT\n"); + if ( (!mesh->info.nomove) || (!mesh->info.noswap) || (!mesh->info.noinsert) ) { + + /* Mesh improvement - call new version of mmg2d1 */ + chrono(ON,&ctim[4]); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT\n"); + } + + if ( !MMG2D_mmg2d1n(mesh,met) ) { + if ( mettofree ) { + MMG5_DEL_MEM(mesh,met->m); + MMG5_SAFE_FREE (met); + } + if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,sol,met,MMG5_STRONGFAILURE); + MMG2D_RETURN_AND_PACK(mesh,sol,met,MMG5_LOWFAILURE); + } + + /* End of mmg2dls */ + chrono(OFF,&(ctim[4])); + printim(ctim[4].gdif,stim); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout," -- PHASE 3 COMPLETED. %s\n",stim); + } } - if ( (!mesh->info.noinsert) && !MMG2D_mmg2d1n(mesh,met) ) { + /* Print quality histories */ + if ( !MMG2D_outqua(mesh,met) ) { if ( mettofree ) { MMG5_DEL_MEM(mesh,met->m); MMG5_SAFE_FREE (met); } - if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,sol,met,MMG5_STRONGFAILURE); MMG2D_RETURN_AND_PACK(mesh,sol,met,MMG5_LOWFAILURE); } - /* End of mmg2dls */ - chrono(OFF,&(ctim[4])); - printim(ctim[4].gdif,stim); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout," -- PHASE 3 COMPLETED. %s\n",stim); - } - /* Unscale mesh */ if ( !MMG5_unscaleMesh(mesh,met,NULL) ) { if ( mettofree ) { @@ -890,15 +908,6 @@ int MMG2D_mmg2dls(MMG5_pMesh mesh,MMG5_pSol sol,MMG5_pSol umet) _LIBMMG5_RETURN(mesh,sol,met,MMG5_STRONGFAILURE); } - /* Print quality histories */ - if ( !MMG2D_outqua(mesh,met) ) { - if ( mettofree ) { - MMG5_DEL_MEM(mesh,met->m); - MMG5_SAFE_FREE (met); - } - MMG2D_RETURN_AND_PACK(mesh,sol,met,MMG5_LOWFAILURE); - } - chrono(ON,&(ctim[1])); if ( mesh->info.imprim > 0 ) fprintf(stdout,"\n -- MESH PACKED UP\n"); @@ -1088,33 +1097,36 @@ int MMG2D_mmg2dmov(MMG5_pMesh mesh,MMG5_pSol met,MMG5_pSol disp) { fprintf(stdout," -- PHASE 2 COMPLETED. %s\n",stim); } - /* End with a classical remeshing stage, provided mesh->info.lag > 1 */ - if ( (ier > 0) && (mesh->info.lag >= 1) ) { - chrono(ON,&(ctim[4])); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT\n"); - } + if ( (!mesh->info.nomove) || (!mesh->info.noswap) || (!mesh->info.noinsert) ) { - if ( !MMG2D_mmg2d1n(mesh,met) ) { - if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); - MMG2D_RETURN_AND_PACK(mesh,met,disp,MMG5_LOWFAILURE); - } + /* End with a classical remeshing stage, provided mesh->info.lag > 1 */ + if ( (ier > 0) && (mesh->info.lag >= 1) ) { + chrono(ON,&(ctim[4])); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT\n"); + } - chrono(OFF,&(ctim[4])); - printim(ctim[4].gdif,stim); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout," -- PHASE 3 COMPLETED. %s\n",stim); + if ( !MMG2D_mmg2d1n(mesh,met) ) { + if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); + MMG2D_RETURN_AND_PACK(mesh,met,disp,MMG5_LOWFAILURE); + } + + chrono(OFF,&(ctim[4])); + printim(ctim[4].gdif,stim); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout," -- PHASE 3 COMPLETED. %s\n",stim); + } } } - /* Unscale mesh */ - if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); - /* Print quality histories */ if ( !MMG2D_outqua(mesh,met) ) { MMG2D_RETURN_AND_PACK(mesh,met,disp,MMG5_LOWFAILURE); } + /* Unscale mesh */ + if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); + chrono(ON,&(ctim[1])); if ( mesh->info.imprim > 0 ) fprintf(stdout,"\n -- MESH PACKED UP\n"); diff --git a/src/mmg3d/libmmg3d.c b/src/mmg3d/libmmg3d.c index 708c19088..1ba7cc7bd 100644 --- a/src/mmg3d/libmmg3d.c +++ b/src/mmg3d/libmmg3d.c @@ -1365,7 +1365,7 @@ int MMG3D_mmg3dls(MMG5_pMesh mesh,MMG5_pSol sol,MMG5_pSol umet) { if ( mesh->info.imprim > 0 ) { fprintf(stdout,"\n -- PHASE 2 : ANALYSIS\n"); } - + /* Specific meshing */ if ( mesh->info.optim ) { if ( !MMG3D_doSol(mesh,met) ) { From 13ee6708c03057ab5f273ad69a4306739c828f62 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 22 Jun 2021 10:42:39 +0200 Subject: [PATCH 087/170] Remove a bug in the setVertexNmTag analysis function: as mesh->base is incremented inside the boulernm function, the point flag was never equal to mesh->base and the computations were done multiple times for a given points (from each tetra to which the point belong). --- src/mmg3d/hash_3d.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mmg3d/hash_3d.c b/src/mmg3d/hash_3d.c index ebc9fcbe9..88c107e3d 100644 --- a/src/mmg3d/hash_3d.c +++ b/src/mmg3d/hash_3d.c @@ -681,7 +681,7 @@ int MMG5_setVertexNmTag(MMG5_pMesh mesh) { MMG5_pTetra ptet; MMG5_pPoint ppt; MMG5_Hash hash; - int k,i; + int k,i,base; int nc, nre, ng, nrp,ier; /* Second: seek the non-required non-manifold points and try to analyse @@ -692,15 +692,15 @@ int MMG5_setVertexNmTag(MMG5_pMesh mesh) { if ( ! MMG5_hashNew(mesh,&hash,mesh->np,(int)(3.71*mesh->np)) ) return 0; nc = nre = 0; - ++mesh->base; + base = ++mesh->base; for (k=1; k<=mesh->ne; ++k) { ptet = &mesh->tetra[k]; if ( !MG_EOK(ptet) ) continue; for ( i=0; i<4; ++i ) { ppt = &mesh->point[ptet->v[i]]; - if ( (!MG_VOK(ppt)) || (ppt->flag==mesh->base) ) continue; - ppt->flag = mesh->base; + if ( (!MG_VOK(ppt)) || (ppt->flag==base) ) continue; + ppt->flag = base; if ( (!(ppt->tag & MG_NOM)) || (ppt->tag & MG_REQ) ) continue; From 137de3853f26e9bbec5708517d2b343d35403d36 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 22 Jun 2021 11:15:46 +0200 Subject: [PATCH 088/170] Modification of the edge hash table size for the analysis of non-manifold points: it was allocated at mesh->np size (too large), now we use the number of non-manifold non required points. --- src/mmg3d/hash_3d.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/mmg3d/hash_3d.c b/src/mmg3d/hash_3d.c index 88c107e3d..f9ec9748a 100644 --- a/src/mmg3d/hash_3d.c +++ b/src/mmg3d/hash_3d.c @@ -682,14 +682,21 @@ int MMG5_setVertexNmTag(MMG5_pMesh mesh) { MMG5_pPoint ppt; MMG5_Hash hash; int k,i,base; - int nc, nre, ng, nrp,ier; + int np,nc, nre, ng, nrp,ier; /* Second: seek the non-required non-manifold points and try to analyse * whether they are corner or required. */ /* Hash table used by boulernm to store the special edges passing through * a given point */ - if ( ! MMG5_hashNew(mesh,&hash,mesh->np,(int)(3.71*mesh->np)) ) return 0; + np = 0; + for (k=1; k<=mesh->np; ++k) { + ppt = &mesh->point[k]; + if ( (!(ppt->tag & MG_NOM)) || (ppt->tag & MG_REQ) ) continue; + ++np; + } + + if ( ! MMG5_hashNew(mesh,&hash,np,(int)(3.71*np)) ) return 0; nc = nre = 0; base = ++mesh->base; From e006c00e4ffea144b4874e8843a41a6294482dac Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 22 Jun 2021 11:17:52 +0200 Subject: [PATCH 089/170] indentation. --- src/mmg3d/libmmg3d.c | 122 +++++++++++++++++++++---------------------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/src/mmg3d/libmmg3d.c b/src/mmg3d/libmmg3d.c index 9a9ed83ec..5d0ca7c4a 100644 --- a/src/mmg3d/libmmg3d.c +++ b/src/mmg3d/libmmg3d.c @@ -46,19 +46,19 @@ * Pack the mesh \a mesh and its associated metric \a met and/or solution \a sol * and return \a val. */ -#define MMG5_RETURN_AND_PACK(mesh,met,sol,val)do \ - { \ - if ( !MMG3D_packMesh(mesh,met,sol) ) { \ - mesh->npi = mesh->np; \ - mesh->nti = mesh->nt; \ - mesh->nai = mesh->na; \ - mesh->nei = mesh->ne; \ - mesh->xt = 0; \ - if ( met ) { met->npi = met->np; } \ - if ( sol ) { sol->npi = sol->np; } \ - return MMG5_STRONGFAILURE; \ - } \ - _LIBMMG5_RETURN(mesh,met,sol,val); \ +#define MMG5_RETURN_AND_PACK(mesh,met,sol,val)do \ + { \ + if ( !MMG3D_packMesh(mesh,met,sol) ) { \ + mesh->npi = mesh->np; \ + mesh->nti = mesh->nt; \ + mesh->nai = mesh->na; \ + mesh->nei = mesh->ne; \ + mesh->xt = 0; \ + if ( met ) { met->npi = met->np; } \ + if ( sol ) { sol->npi = sol->np; } \ + return MMG5_STRONGFAILURE; \ + } \ + _LIBMMG5_RETURN(mesh,met,sol,val); \ }while(0) /** Free adja, xtetra and xpoint tables */ @@ -130,7 +130,7 @@ int MMG3D_bdryBuild(MMG5_pMesh mesh) { ( mesh->xtetra[pt->xt].tag[i] & MG_REQ || MG_EDG(mesh->xtetra[pt->xt].tag[i])) ) if ( !MMG5_hEdge(mesh,&mesh->htab,pt->v[MMG5_iare[i][0]],pt->v[MMG5_iare[i][1]], - mesh->xtetra[pt->xt].edg[i],mesh->xtetra[pt->xt].tag[i])) + mesh->xtetra[pt->xt].edg[i],mesh->xtetra[pt->xt].tag[i])) return -1; } } @@ -144,8 +144,8 @@ int MMG3D_bdryBuild(MMG5_pMesh mesh) { } if ( mesh->na ) { MMG5_ADD_MEM(mesh,(mesh->na+1)*sizeof(MMG5_Edge),"edges", - mesh->na = 0; - printf(" ## Warning: uncomplete mesh\n")); + mesh->na = 0; + printf(" ## Warning: uncomplete mesh\n")); } if ( mesh->na ) { @@ -1123,45 +1123,45 @@ int MMG3D_mmg3dlib(MMG5_pMesh mesh,MMG5_pSol met) { fprintf(stdout," -- PHASE 1 COMPLETED. %s\n",stim); if ( (!mesh->info.nomove) || (!mesh->info.noswap) || (!mesh->info.noinsert) ) { - /* mesh adaptation */ - chrono(ON,&(ctim[3])); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout,"\n -- PHASE 2 : %s MESHING\n",met->size < 6 ? "ISOTROPIC" : "ANISOTROPIC"); - } + /* mesh adaptation */ + chrono(ON,&(ctim[3])); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout,"\n -- PHASE 2 : %s MESHING\n",met->size < 6 ? "ISOTROPIC" : "ANISOTROPIC"); + } - /* renumerotation if available */ + /* renumerotation if available */ if ( !MMG5_scotchCall(mesh,met,NULL,NULL) ) - { + { if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); MMG5_RETURN_AND_PACK(mesh,met,sol,MMG5_LOWFAILURE); - } + } #ifdef PATTERN if ( !MMG5_mmg3d1_pattern(mesh,met,NULL) ) { - if ( !(mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { - fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); + if ( !(mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { + fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); - } + } if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); MMG5_RETURN_AND_PACK(mesh,met,sol,MMG5_LOWFAILURE); - } + } #else if ( !MMG5_mmg3d1_delone(mesh,met,NULL) ) { - if ( (!mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { - fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); + if ( (!mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { + fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); - } + } if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); MMG5_RETURN_AND_PACK(mesh,met,sol,MMG5_LOWFAILURE); - } + } #endif - chrono(OFF,&(ctim[3])); - printim(ctim[3].gdif,stim); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout," -- PHASE 2 COMPLETED. %s\n",stim); - } + chrono(OFF,&(ctim[3])); + printim(ctim[3].gdif,stim); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout," -- PHASE 2 COMPLETED. %s\n",stim); + } } /* last renum to give back a good numbering to the user */ @@ -1258,14 +1258,14 @@ int MMG3D_mmg3dls(MMG5_pMesh mesh,MMG5_pSol sol,MMG5_pSol umet) { /* Specific meshing */ if ( met && met->np ) { - if ( mesh->info.optim ) { + if ( mesh->info.optim ) { printf("\n ## ERROR: MISMATCH OPTIONS: OPTIM OPTION CAN NOT BE USED" " WITH AN INPUT METRIC.\n"); if ( mettofree ) { MMG5_DEL_MEM(mesh,met->m);MMG5_SAFE_FREE (met); } _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); - } + } - if ( mesh->info.hsiz>0. ) { + if ( mesh->info.hsiz>0. ) { printf("\n ## ERROR: MISMATCH OPTIONS: HSIZ OPTION CAN NOT BE USED" " WITH AN INPUT METRIC.\n"); if ( mettofree ) { MMG5_DEL_MEM(mesh,met->m);MMG5_SAFE_FREE (met); } @@ -1556,7 +1556,7 @@ int MMG3D_mmg3dmov(MMG5_pMesh mesh,MMG5_pSol met, MMG5_pSol disp) { #ifndef USE_ELAS fprintf(stderr,"\n ## ERROR: YOU NEED TO COMPILE WITH THE USE_ELAS" - " CMake's FLAG SET TO ON TO USE THE RIGIDBODY MOVEMENT LIBRARY.\n"); + " CMake's FLAG SET TO ON TO USE THE RIGIDBODY MOVEMENT LIBRARY.\n"); _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); #endif @@ -1668,44 +1668,44 @@ int MMG3D_mmg3dmov(MMG5_pMesh mesh,MMG5_pSol met, MMG5_pSol disp) { /* End with a classical remeshing stage, provided mesh->info.lag >= 1 */ if ( (ier > 0) && (mesh->info.lag >= 1) ) { - chrono(ON,&(ctim[4])); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT\n"); - } + chrono(ON,&(ctim[4])); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT\n"); + } - /* renumerotation if available */ + /* renumerotation if available */ if ( !MMG5_scotchCall(mesh,met,disp,NULL) ) - { + { if ( !MMG5_unscaleMesh(mesh,met,disp) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); MMG5_RETURN_AND_PACK(mesh,met,disp,MMG5_LOWFAILURE); - } + } #ifdef PATTERN if ( !MMG5_mmg3d1_pattern(mesh,met,NULL) ) { - if ( !(mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { - fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); + if ( !(mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { + fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); - } + } if ( !MMG5_unscaleMesh(mesh,met,disp) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); MMG5_RETURN_AND_PACK(mesh,met,disp,MMG5_LOWFAILURE); - } + } #else if ( !MMG5_mmg3d1_delone(mesh,met,NULL) ) { - if ( !(mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { - fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); + if ( !(mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { + fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); - } + } if ( !MMG5_unscaleMesh(mesh,met,disp) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); MMG5_RETURN_AND_PACK(mesh,met,disp,MMG5_LOWFAILURE); - } + } #endif - chrono(OFF,&(ctim[4])); - printim(ctim[4].gdif,stim); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout," -- PHASE 3 COMPLETED. %s\n",stim); - } + chrono(OFF,&(ctim[4])); + printim(ctim[4].gdif,stim); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout," -- PHASE 3 COMPLETED. %s\n",stim); } + } /* last renum to give back a good numbering to the user */ if ( !MMG5_scotchCall(mesh,met,disp,NULL) ) From 140861346aa22bfe04b79f868a595cd5e6af8bfb Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 22 Jun 2021 11:31:27 +0200 Subject: [PATCH 090/170] Do not call mmg3d1 in ls + noinsert-noswap-nomove mode. --- src/mmg3d/libmmg3d.c | 131 ++++++++++++++++++++++--------------------- 1 file changed, 68 insertions(+), 63 deletions(-) diff --git a/src/mmg3d/libmmg3d.c b/src/mmg3d/libmmg3d.c index 5d0ca7c4a..708c19088 100644 --- a/src/mmg3d/libmmg3d.c +++ b/src/mmg3d/libmmg3d.c @@ -1398,48 +1398,50 @@ int MMG3D_mmg3dls(MMG5_pMesh mesh,MMG5_pSol sol,MMG5_pSol umet) { if ( mesh->info.imprim > 0 ) fprintf(stdout," -- PHASE 2 COMPLETED. %s\n",stim); - /* mesh adaptation */ - chrono(ON,&(ctim[4])); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT\n"); - } + if ( (!mesh->info.nomove) || (!mesh->info.noswap) || (!mesh->info.noinsert) ) { - /* renumerotation if available */ - if ( !MMG5_scotchCall(mesh,met,NULL,NULL) ) - { - if ( mettofree ) { MMG5_DEL_MEM(mesh,met->m);MMG5_SAFE_FREE (met); } - if ( !MMG5_unscaleMesh(mesh,met,sol) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); - MMG5_RETURN_AND_PACK(mesh,sol,met,MMG5_LOWFAILURE); - } + /* mesh adaptation */ + chrono(ON,&(ctim[4])); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT\n"); + } + + /* renumerotation if available */ + if ( !MMG5_scotchCall(mesh,met,NULL,NULL) ) + { + if ( mettofree ) { MMG5_DEL_MEM(mesh,met->m);MMG5_SAFE_FREE (met); } + if ( !MMG5_unscaleMesh(mesh,met,sol) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + MMG5_RETURN_AND_PACK(mesh,sol,met,MMG5_LOWFAILURE); + } #ifdef PATTERN - if ( !MMG5_mmg3d1_pattern(mesh,met,NULL) ) { - if ( mettofree ) { MMG5_DEL_MEM(mesh,met->m);MMG5_SAFE_FREE (met); } - if ( !(mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { - fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); - _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + if ( !MMG5_mmg3d1_pattern(mesh,met,NULL) ) { + if ( mettofree ) { MMG5_DEL_MEM(mesh,met->m);MMG5_SAFE_FREE (met); } + if ( !(mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { + fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); + _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + } + if ( !MMG5_unscaleMesh(mesh,met,sol) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + MMG5_RETURN_AND_PACK(mesh,sol,met,MMG5_LOWFAILURE); } - if ( !MMG5_unscaleMesh(mesh,met,sol) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); - MMG5_RETURN_AND_PACK(mesh,sol,met,MMG5_LOWFAILURE); - } #else - if ( !MMG5_mmg3d1_pattern(mesh,met,NULL) ) { - if ( mettofree ) { MMG5_DEL_MEM(mesh,met->m);MMG5_SAFE_FREE (met); } - if ( !(mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { - fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); - _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + if ( !MMG5_mmg3d1_pattern(mesh,met,NULL) ) { + if ( mettofree ) { MMG5_DEL_MEM(mesh,met->m);MMG5_SAFE_FREE (met); } + if ( !(mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { + fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); + _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + } + if ( !MMG5_unscaleMesh(mesh,met,sol) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + MMG5_RETURN_AND_PACK(mesh,sol,met,MMG5_LOWFAILURE); } - if ( !MMG5_unscaleMesh(mesh,met,sol) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); - MMG5_RETURN_AND_PACK(mesh,sol,met,MMG5_LOWFAILURE); - } #endif - chrono(OFF,&(ctim[4])); - printim(ctim[4].gdif,stim); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout," -- PHASE 3 COMPLETED. %s\n",stim); + chrono(OFF,&(ctim[4])); + printim(ctim[4].gdif,stim); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout," -- PHASE 3 COMPLETED. %s\n",stim); + } } - /* last renum to give back a good numbering to the user */ if ( !MMG5_scotchCall(mesh,met,NULL,NULL) ) { @@ -1666,44 +1668,47 @@ int MMG3D_mmg3dmov(MMG5_pMesh mesh,MMG5_pSol met, MMG5_pSol disp) { fprintf(stdout," -- PHASE 2 COMPLETED. %s\n",stim); } - /* End with a classical remeshing stage, provided mesh->info.lag >= 1 */ - if ( (ier > 0) && (mesh->info.lag >= 1) ) { - chrono(ON,&(ctim[4])); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT\n"); - } + if ( (!mesh->info.nomove) || (!mesh->info.noswap) || (!mesh->info.noinsert) ) { - /* renumerotation if available */ - if ( !MMG5_scotchCall(mesh,met,disp,NULL) ) - { - if ( !MMG5_unscaleMesh(mesh,met,disp) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); - MMG5_RETURN_AND_PACK(mesh,met,disp,MMG5_LOWFAILURE); - } + /* End with a classical remeshing stage, provided mesh->info.lag >= 1 */ + if ( (ier > 0) && (mesh->info.lag >= 1) ) { + chrono(ON,&(ctim[4])); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT\n"); + } + + /* renumerotation if available */ + if ( !MMG5_scotchCall(mesh,met,disp,NULL) ) + { + if ( !MMG5_unscaleMesh(mesh,met,disp) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); + MMG5_RETURN_AND_PACK(mesh,met,disp,MMG5_LOWFAILURE); + } #ifdef PATTERN - if ( !MMG5_mmg3d1_pattern(mesh,met,NULL) ) { - if ( !(mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { - fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); - _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); + if ( !MMG5_mmg3d1_pattern(mesh,met,NULL) ) { + if ( !(mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { + fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); + _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); + } + if ( !MMG5_unscaleMesh(mesh,met,disp) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); + MMG5_RETURN_AND_PACK(mesh,met,disp,MMG5_LOWFAILURE); } - if ( !MMG5_unscaleMesh(mesh,met,disp) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); - MMG5_RETURN_AND_PACK(mesh,met,disp,MMG5_LOWFAILURE); - } #else - if ( !MMG5_mmg3d1_delone(mesh,met,NULL) ) { - if ( !(mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { - fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); - _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); + if ( !MMG5_mmg3d1_delone(mesh,met,NULL) ) { + if ( !(mesh->adja) && !MMG3D_hashTetra(mesh,1) ) { + fprintf(stderr,"\n ## Hashing problem. Invalid mesh.\n"); + _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); + } + if ( !MMG5_unscaleMesh(mesh,met,disp) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); + MMG5_RETURN_AND_PACK(mesh,met,disp,MMG5_LOWFAILURE); } - if ( !MMG5_unscaleMesh(mesh,met,disp) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); - MMG5_RETURN_AND_PACK(mesh,met,disp,MMG5_LOWFAILURE); - } #endif - chrono(OFF,&(ctim[4])); - printim(ctim[4].gdif,stim); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout," -- PHASE 3 COMPLETED. %s\n",stim); + chrono(OFF,&(ctim[4])); + printim(ctim[4].gdif,stim); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout," -- PHASE 3 COMPLETED. %s\n",stim); + } } } From 89584a4e4bc902936b35bf3f82b85a96e7c78447 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 22 Jun 2021 11:49:34 +0200 Subject: [PATCH 091/170] Do not call adaptation function in noinsert-noswap-nomove mode of mmg2d + call quality and lengths histo before unscaling. --- src/mmg2d/libmmg2d.c | 226 +++++++++++++++++++++++-------------------- src/mmg3d/libmmg3d.c | 2 +- 2 files changed, 120 insertions(+), 108 deletions(-) diff --git a/src/mmg2d/libmmg2d.c b/src/mmg2d/libmmg2d.c index 2b95390bf..f510532f3 100644 --- a/src/mmg2d/libmmg2d.c +++ b/src/mmg2d/libmmg2d.c @@ -27,20 +27,20 @@ * Pack the mesh \a mesh and its associated metric \a met and/or solution \a sol * and return \a val. */ -#define MMG2D_RETURN_AND_PACK(mesh,met,sol,val)do \ - { \ - if ( !MMG2D_pack(mesh,met,sol) ) { \ - mesh->npi = mesh->np; \ - mesh->nti = mesh->nt; \ - mesh->nai = mesh->na; \ - mesh->nei = mesh->ne; \ - mesh->xt = 0; \ - if ( met ) { met->npi = met->np; } \ - if ( sol ) { sol->npi = sol->np; } \ - return MMG5_LOWFAILURE; \ - } \ - _LIBMMG5_RETURN(mesh,met,sol,val); \ - }while(0) +#define MMG2D_RETURN_AND_PACK(mesh,met,sol,val)do \ + { \ + if ( !MMG2D_pack(mesh,met,sol) ) { \ + mesh->npi = mesh->np; \ + mesh->nti = mesh->nt; \ + mesh->nai = mesh->na; \ + mesh->nei = mesh->ne; \ + mesh->xt = 0; \ + if ( met ) { met->npi = met->np; } \ + if ( sol ) { sol->npi = sol->np; } \ + return MMG5_LOWFAILURE; \ + } \ + _LIBMMG5_RETURN(mesh,met,sol,val); \ + }while(0) /** * \param mesh pointer toward the mesh structure. @@ -185,7 +185,7 @@ int MMG2D_mmg2dlib(MMG5_pMesh mesh,MMG5_pSol met) /*uncomment to callback*/ //MMG2D_callbackinsert = titi; - /* interrupts */ + /* interrupts */ signal(SIGABRT,MMG2D_excfun); signal(SIGFPE,MMG2D_excfun); signal(SIGILL,MMG2D_excfun); @@ -283,16 +283,16 @@ int MMG2D_mmg2dlib(MMG5_pMesh mesh,MMG5_pSol met) /* Specific meshing */ if ( mesh->info.optim ) { if ( !MMG2D_doSol(mesh,met) ) { - if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); - _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); } MMG2D_solTruncatureForOptim(mesh,met); } if ( mesh->info.hsiz > 0. ) { if ( !MMG2D_Set_constantSize(mesh,met) ) { - if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); - _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); } } @@ -319,29 +319,32 @@ int MMG2D_mmg2dlib(MMG5_pMesh mesh,MMG5_pSol met) if ( mesh->info.imprim > 0 ) fprintf(stdout," -- PHASE 1 COMPLETED. %s\n",stim); - /* remeshing */ - chrono(ON,&ctim[3]); + if ( (!mesh->info.nomove) || (!mesh->info.noswap) || (!mesh->info.noinsert) ) { - if ( mesh->info.imprim > 0 ) - fprintf(stdout,"\n -- PHASE 2 : %s MESHING\n",met->size < 3 ? "ISOTROPIC" : "ANISOTROPIC"); + /* remeshing */ + chrono(ON,&ctim[3]); - /* Mesh improvement */ - if ( !MMG2D_mmg2d1n(mesh,met) ) { - if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); - MMG2D_RETURN_AND_PACK(mesh,met,sol,MMG5_LOWFAILURE); - } + if ( mesh->info.imprim > 0 ) + fprintf(stdout,"\n -- PHASE 2 : %s MESHING\n",met->size < 3 ? "ISOTROPIC" : "ANISOTROPIC"); - chrono(OFF,&(ctim[3])); - printim(ctim[3].gdif,stim); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout," -- PHASE 2 COMPLETED. %s\n",stim); + /* Mesh improvement */ + if ( !MMG2D_mmg2d1n(mesh,met) ) { + if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + MMG2D_RETURN_AND_PACK(mesh,met,sol,MMG5_LOWFAILURE); + } + + chrono(OFF,&(ctim[3])); + printim(ctim[3].gdif,stim); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout," -- PHASE 2 COMPLETED. %s\n",stim); + } } /* Print output quality history */ if ( !MMG2D_outqua(mesh,met) ) { - if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); - MMG2D_RETURN_AND_PACK(mesh,met,sol,MMG5_LOWFAILURE); - } + if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + MMG2D_RETURN_AND_PACK(mesh,met,sol,MMG5_LOWFAILURE); + } /* Print edge length histories */ if ( abs(mesh->info.imprim) > 4 ) { @@ -386,7 +389,7 @@ int MMG2D_restart(MMG5_pMesh mesh){ /* If we call the library more than one time and if we free the triangles * using the MMG2D_Free_triangles function we need to reallocate it */ MMG5_ADD_MEM(mesh,(mesh->ntmax+1)*sizeof(MMG5_Tria), - "initial triangles",return 0); + "initial triangles",return 0); MMG5_SAFE_CALLOC(mesh->tria,mesh->ntmax+1,MMG5_Tria,return 0); mesh->nenil = mesh->nt + 1; for ( k=mesh->nenil; kntmax-1; k++) { @@ -397,7 +400,7 @@ int MMG2D_restart(MMG5_pMesh mesh){ /* If we call the library more than one time and if we free the triangles * using the MMG2D_Free_triangles function we need to reallocate it */ MMG5_ADD_MEM(mesh,(mesh->namax+1)*sizeof(MMG5_Edge), - "initial edges",return 0); + "initial edges",return 0); MMG5_SAFE_CALLOC(mesh->edge,mesh->namax+1,MMG5_Edge,return 0); if ( mesh->na < mesh->namax ) { mesh->nanil = mesh->na + 1; @@ -529,8 +532,8 @@ int MMG2D_mmg2dmesh(MMG5_pMesh mesh,MMG5_pSol met) { /* Memory alloc */ MMG5_ADD_MEM(mesh,(3*mesh->ntmax+5)*sizeof(int),"adjacency table", - printf(" Exit program.\n"); - return MMG5_STRONGFAILURE); + printf(" Exit program.\n"); + return MMG5_STRONGFAILURE); MMG5_SAFE_CALLOC(mesh->adja,3*mesh->ntmax+5,int,return MMG5_STRONGFAILURE); /* Delaunay triangulation of the set of points contained in the mesh, @@ -561,8 +564,8 @@ int MMG2D_mmg2dmesh(MMG5_pMesh mesh,MMG5_pSol met) { MMG2D_solTruncatureForOptim(mesh,met); } else if (mesh->info.hsiz > 0.) { if ( !MMG2D_Set_constantSize(mesh,met) ) { - if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); - _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); } } else { /* Set default hmin and hmax values */ @@ -585,29 +588,29 @@ int MMG2D_mmg2dmesh(MMG5_pMesh mesh,MMG5_pSol met) { if ( mesh->info.imprim > 0 ) fprintf(stdout," -- PHASE 2 COMPLETED. %s\n",stim); - /* Mesh improvement - call new version of mmg2d1 */ - chrono(ON,&(ctim[4])); - if ( mesh->info.imprim > 0 ) - fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT (%s)\n", - met->size < 3 ? "ISOTROPIC" : "ANISOTROPIC"); + if ( (!mesh->info.nomove) || (!mesh->info.noswap) || (!mesh->info.noinsert) ) { - if ( !MMG2D_mmg2d1n(mesh,met) ) { - if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); - MMG2D_RETURN_AND_PACK(mesh,met,sol,MMG5_LOWFAILURE); - } + /* Mesh improvement - call new version of mmg2d1 */ + chrono(ON,&(ctim[4])); + if ( mesh->info.imprim > 0 ) + fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT (%s)\n", + met->size < 3 ? "ISOTROPIC" : "ANISOTROPIC"); - chrono(OFF,&(ctim[4])); - printim(ctim[4].gdif,stim); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout," -- PHASE 3 COMPLETED. %s\n",stim); - } + if ( !MMG2D_mmg2d1n(mesh,met) ) { + if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + MMG2D_RETURN_AND_PACK(mesh,met,sol,MMG5_LOWFAILURE); + } - /* Unscale mesh */ - if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + chrono(OFF,&(ctim[4])); + printim(ctim[4].gdif,stim); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout," -- PHASE 3 COMPLETED. %s\n",stim); + } + } /* Print quality histories */ if ( !MMG2D_outqua(mesh,met) ) { - MMG2D_RETURN_AND_PACK(mesh,met,sol,MMG5_LOWFAILURE); + MMG2D_RETURN_AND_PACK(mesh,met,sol,MMG5_LOWFAILURE); } /* Print edge length histories */ @@ -615,6 +618,9 @@ int MMG2D_mmg2dmesh(MMG5_pMesh mesh,MMG5_pSol met) { MMG2D_prilen(mesh,met); } + /* Unscale mesh */ + if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + chrono(ON,&(ctim[1])); if ( mesh->info.imprim > 0 ) fprintf(stdout,"\n -- MESH PACKED UP\n"); @@ -714,14 +720,14 @@ int MMG2D_mmg2dls(MMG5_pMesh mesh,MMG5_pSol sol,MMG5_pSol umet) /* specific meshing */ if ( met && met->np ) { - if ( mesh->info.optim ) { + if ( mesh->info.optim ) { printf("\n ## ERROR: MISMATCH OPTIONS: OPTIM OPTION CAN NOT BE USED" " WITH AN INPUT METRIC.\n"); if ( mettofree ) { MMG5_SAFE_FREE (met); } _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); - } + } - if ( mesh->info.hsiz>0. ) { + if ( mesh->info.hsiz>0. ) { printf("\n ## ERROR: MISMATCH OPTIONS: HSIZ OPTION CAN NOT BE USED" " WITH AN INPUT METRIC.\n"); if ( mettofree ) { MMG5_SAFE_FREE (met); } @@ -788,10 +794,10 @@ int MMG2D_mmg2dls(MMG5_pMesh mesh,MMG5_pSol sol,MMG5_pSol umet) /* Print initial quality */ if ( mesh->info.imprim > 0 || mesh->info.imprim < -1 ) { if ( !MMG2D_outqua(mesh,met) ) { - if ( mettofree ) { - MMG5_DEL_MEM(mesh,met->m); - MMG5_SAFE_FREE (met); - } + if ( mettofree ) { + MMG5_DEL_MEM(mesh,met->m); + MMG5_SAFE_FREE (met); + } if ( !MMG5_unscaleMesh(mesh,met,sol) ) { _LIBMMG5_RETURN(mesh,sol,met,MMG5_STRONGFAILURE); } @@ -838,7 +844,7 @@ int MMG2D_mmg2dls(MMG5_pMesh mesh,MMG5_pSol sol,MMG5_pSol umet) if ( !MMG5_unscaleMesh(mesh,met,sol) ) { _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); } - _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); + _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE); } } @@ -859,28 +865,40 @@ int MMG2D_mmg2dls(MMG5_pMesh mesh,MMG5_pSol sol,MMG5_pSol umet) if ( mesh->info.imprim > 0 ) fprintf(stdout," -- PHASE 2 COMPLETED. %s\n",stim); - /* Mesh improvement - call new version of mmg2d1 */ - chrono(ON,&ctim[4]); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT\n"); + if ( (!mesh->info.nomove) || (!mesh->info.noswap) || (!mesh->info.noinsert) ) { + + /* Mesh improvement - call new version of mmg2d1 */ + chrono(ON,&ctim[4]); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT\n"); + } + + if ( !MMG2D_mmg2d1n(mesh,met) ) { + if ( mettofree ) { + MMG5_DEL_MEM(mesh,met->m); + MMG5_SAFE_FREE (met); + } + if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,sol,met,MMG5_STRONGFAILURE); + MMG2D_RETURN_AND_PACK(mesh,sol,met,MMG5_LOWFAILURE); + } + + /* End of mmg2dls */ + chrono(OFF,&(ctim[4])); + printim(ctim[4].gdif,stim); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout," -- PHASE 3 COMPLETED. %s\n",stim); + } } - if ( !MMG2D_mmg2d1n(mesh,met) ) { + /* Print quality histories */ + if ( !MMG2D_outqua(mesh,met) ) { if ( mettofree ) { MMG5_DEL_MEM(mesh,met->m); MMG5_SAFE_FREE (met); } - if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,sol,met,MMG5_STRONGFAILURE); MMG2D_RETURN_AND_PACK(mesh,sol,met,MMG5_LOWFAILURE); } - /* End of mmg2dls */ - chrono(OFF,&(ctim[4])); - printim(ctim[4].gdif,stim); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout," -- PHASE 3 COMPLETED. %s\n",stim); - } - /* Unscale mesh */ if ( !MMG5_unscaleMesh(mesh,met,NULL) ) { if ( mettofree ) { @@ -890,15 +908,6 @@ int MMG2D_mmg2dls(MMG5_pMesh mesh,MMG5_pSol sol,MMG5_pSol umet) _LIBMMG5_RETURN(mesh,sol,met,MMG5_STRONGFAILURE); } - /* Print quality histories */ - if ( !MMG2D_outqua(mesh,met) ) { - if ( mettofree ) { - MMG5_DEL_MEM(mesh,met->m); - MMG5_SAFE_FREE (met); - } - MMG2D_RETURN_AND_PACK(mesh,sol,met,MMG5_LOWFAILURE); - } - chrono(ON,&(ctim[1])); if ( mesh->info.imprim > 0 ) fprintf(stdout,"\n -- MESH PACKED UP\n"); @@ -969,8 +978,8 @@ int MMG2D_mmg2dmov(MMG5_pMesh mesh,MMG5_pSol met,MMG5_pSol disp) { #ifndef USE_ELAS fprintf(stderr,"\n ## ERROR: YOU NEED TO COMPILE WITH THE USE_ELAS" - " CMake's FLAG SET TO ON TO USE THE RIGIDBODY MOVEMENT LIBRARY.\n"); - _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); + " CMake's FLAG SET TO ON TO USE THE RIGIDBODY MOVEMENT LIBRARY.\n"); + _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); #endif if ( !mesh->nt ) { @@ -1088,33 +1097,36 @@ int MMG2D_mmg2dmov(MMG5_pMesh mesh,MMG5_pSol met,MMG5_pSol disp) { fprintf(stdout," -- PHASE 2 COMPLETED. %s\n",stim); } - /* End with a classical remeshing stage, provided mesh->info.lag > 1 */ - if ( (ier > 0) && (mesh->info.lag >= 1) ) { - chrono(ON,&(ctim[4])); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT\n"); - } + if ( (!mesh->info.nomove) || (!mesh->info.noswap) || (!mesh->info.noinsert) ) { - if ( !MMG2D_mmg2d1n(mesh,met) ) { - if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); - MMG2D_RETURN_AND_PACK(mesh,met,disp,MMG5_LOWFAILURE); - } + /* End with a classical remeshing stage, provided mesh->info.lag > 1 */ + if ( (ier > 0) && (mesh->info.lag >= 1) ) { + chrono(ON,&(ctim[4])); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT\n"); + } - chrono(OFF,&(ctim[4])); - printim(ctim[4].gdif,stim); - if ( mesh->info.imprim > 0 ) { - fprintf(stdout," -- PHASE 3 COMPLETED. %s\n",stim); + if ( !MMG2D_mmg2d1n(mesh,met) ) { + if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); + MMG2D_RETURN_AND_PACK(mesh,met,disp,MMG5_LOWFAILURE); + } + + chrono(OFF,&(ctim[4])); + printim(ctim[4].gdif,stim); + if ( mesh->info.imprim > 0 ) { + fprintf(stdout," -- PHASE 3 COMPLETED. %s\n",stim); + } } } - /* Unscale mesh */ - if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); - /* Print quality histories */ if ( !MMG2D_outqua(mesh,met) ) { MMG2D_RETURN_AND_PACK(mesh,met,disp,MMG5_LOWFAILURE); } + /* Unscale mesh */ + if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE); + chrono(ON,&(ctim[1])); if ( mesh->info.imprim > 0 ) fprintf(stdout,"\n -- MESH PACKED UP\n"); diff --git a/src/mmg3d/libmmg3d.c b/src/mmg3d/libmmg3d.c index 708c19088..1ba7cc7bd 100644 --- a/src/mmg3d/libmmg3d.c +++ b/src/mmg3d/libmmg3d.c @@ -1365,7 +1365,7 @@ int MMG3D_mmg3dls(MMG5_pMesh mesh,MMG5_pSol sol,MMG5_pSol umet) { if ( mesh->info.imprim > 0 ) { fprintf(stdout,"\n -- PHASE 2 : ANALYSIS\n"); } - + /* Specific meshing */ if ( mesh->info.optim ) { if ( !MMG3D_doSol(mesh,met) ) { From edd67e6325c6392f443c509f115dbdda469864ac Mon Sep 17 00:00:00 2001 From: Algiane Date: Wed, 30 Jun 2021 14:18:35 +0200 Subject: [PATCH 092/170] Patch bug in MMG3D_Set_edges function + add Doxygen comment. --- src/mmg3d/API_functions_3d.c | 2 +- src/mmg3d/chkmsh_3d.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/mmg3d/API_functions_3d.c b/src/mmg3d/API_functions_3d.c index 5ec10ef58..5c18e3fcd 100644 --- a/src/mmg3d/API_functions_3d.c +++ b/src/mmg3d/API_functions_3d.c @@ -1175,7 +1175,7 @@ int MMG3D_Set_edges(MMG5_pMesh mesh, int *edges, int *refs) { mesh->edge[i].a = edges[j]; mesh->edge[i].b = edges[j+1]; if ( refs != NULL ) - mesh->edge[i].ref = refs[i]; + mesh->edge[i].ref = refs[i-1]; mesh->edge[i].tag |= MG_REF; } diff --git a/src/mmg3d/chkmsh_3d.c b/src/mmg3d/chkmsh_3d.c index d59a69571..b6606fcad 100644 --- a/src/mmg3d/chkmsh_3d.c +++ b/src/mmg3d/chkmsh_3d.c @@ -41,6 +41,9 @@ extern int8_t ddb; /** + * \param mesh pointer toward mesh + * + * Test that tetra have positive volumes. * * \warning Not used. */ From 7911ed4dbbbf79a4404a915fa794f240c03bc9be Mon Sep 17 00:00:00 2001 From: Algiane Date: Mon, 12 Jul 2021 11:55:01 +0200 Subject: [PATCH 093/170] More clear error messages. --- src/mmg3d/boulep_3d.c | 2 +- src/mmg3d/chkmsh_3d.c | 2 +- src/mmg3d/mmg3d1.c | 6 ++++-- src/mmg3d/mmg3d2.c | 4 +++- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/mmg3d/boulep_3d.c b/src/mmg3d/boulep_3d.c index de6d0b9f8..d8c585be1 100644 --- a/src/mmg3d/boulep_3d.c +++ b/src/mmg3d/boulep_3d.c @@ -1823,7 +1823,7 @@ int MMG5_coquilface(MMG5_pMesh mesh,int start,int8_t iface,int ia,int *list, // 2) we have a non-manifold shape immersed in a domain (3 triangles // sharing the edge and a closed shell) printf(" ## Warning: %s: you have %d boundaries in the shell" - " of your edge.\n",__func__,nbdy+1); + " of a manifold edge.\n",__func__,nbdy+1); printf(" Problem may occur during remesh process.\n"); mmgWarn0 = 1; } diff --git a/src/mmg3d/chkmsh_3d.c b/src/mmg3d/chkmsh_3d.c index b6606fcad..c731ff83a 100644 --- a/src/mmg3d/chkmsh_3d.c +++ b/src/mmg3d/chkmsh_3d.c @@ -281,7 +281,7 @@ int MMG5_mmg3dChkmsh(MMG5_pMesh mesh,int severe,int base) { " face is a limit of two subdomains" " and is not tagged %d %d %d -->%d\n",__func__, MMG3D_indElt(mesh,k),i, - MMG3D_indElt(mesh,pt->v[MMG5_idir[i][0]]), + MMG3D_indElt(mesh,pt->v[MMG5_idir[i][0]]), MMG3D_indPt(mesh,pt->v[MMG5_idir[i][1]]), MMG3D_indPt(mesh,pt->v[MMG5_idir[i][2]]), pxt->ftag[i]); } diff --git a/src/mmg3d/mmg3d1.c b/src/mmg3d/mmg3d1.c index dc235dc6f..3aaa1ce6d 100644 --- a/src/mmg3d/mmg3d1.c +++ b/src/mmg3d/mmg3d1.c @@ -458,7 +458,8 @@ int8_t MMG5_chkedg(MMG5_pMesh mesh,MMG5_Tria *pt,int8_t ori, double hmax, if(!((p[i1]->tag & MG_NOM) || MG_EDG(p[i1]->tag) ) ) { if ( !mmgWarn0 ) { fprintf(stderr,"\n ## Warning: %s: a- at least 1 geometrical" - " problem\n",__func__); + " problem: non consistency between point tag (%d) and" + " edge tag (%d.)\n",__func__,p[i1]->tag,pt->tag[i]); mmgWarn0 = 1; } return -1; @@ -480,7 +481,8 @@ int8_t MMG5_chkedg(MMG5_pMesh mesh,MMG5_Tria *pt,int8_t ori, double hmax, if(!((p[i2]->tag & MG_NOM) || MG_EDG(p[i2]->tag) ) ) { if ( !mmgWarn1 ) { fprintf(stderr,"\n ## Warning: %s: b- at least 1 geometrical" - " problem\n",__func__); + " problem: non consistency between point tag (%d) and" + " edge tag (%d.)\n",__func__,p[i2]->tag,pt->tag[i]); mmgWarn1 = 1; } return -1; diff --git a/src/mmg3d/mmg3d2.c b/src/mmg3d/mmg3d2.c index a498257ba..c0d654a49 100755 --- a/src/mmg3d/mmg3d2.c +++ b/src/mmg3d/mmg3d2.c @@ -1496,7 +1496,9 @@ int MMG5_chkmaniball(MMG5_pMesh mesh, int start, int8_t ip){ pt = &mesh->tetra[k]; if( pt->ref == ref ) { fprintf(stderr," *** Topological problem:"); - fprintf(stderr," non manifold surface at point %d \n",nump); + fprintf(stderr," non manifold surface at point %d %d\n",nump, MMG3D_indPt(mesh,nump)); + fprintf(stderr," non manifold surface at tet %d (ip %d)\n", MMG3D_indElt(mesh,start),ip); + fprintf(stderr,"nref (color %d) %d\n",nref,ref); return 0; } } From cb92250d24ae749b19797d2b6c1e50aa56dae3ab Mon Sep 17 00:00:00 2001 From: Algiane Date: Mon, 12 Jul 2021 16:46:42 +0200 Subject: [PATCH 094/170] Update comments for backward understanding. --- src/mmg3d/colver_3d.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/mmg3d/colver_3d.c b/src/mmg3d/colver_3d.c index 2845d192e..b8678ea43 100644 --- a/src/mmg3d/colver_3d.c +++ b/src/mmg3d/colver_3d.c @@ -875,7 +875,11 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in for (j=0; j<3; j++) { i = MMG5_inxt3[i]; if ( pt->v[i] == nq ) { - /* list edges that we need to update */ + /* In each tetra of the shell, 2 edges coming from np will be merged + * with 2 edges coming from nq: list the local indices of the edges + * comig from nq (ind array) and store the global indices of the non nq + * vertices of these edges if they are tagged (so edges np-p0_c and + * np-p1_c must be updated in all tetra) */ if ( pt->xt ) { pxt = &mesh->xtetra[pt->xt]; ip = list[k]%4; @@ -896,14 +900,19 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in } } - /* avoid recreating existing elt */ + /* avoid recreating existing elt and update the tags of the edge ip-p0_c and + * ip-p1_c */ for (k=0; ktetra[iel]; - /* update edges of elements that do not belong to the shell of pq */ + /* update edges ip-p0_c and ip-p1_c in elts of the ball of ip but that do + * not belong to the shell of pq */ if ( !pt->xt ) { continue; } @@ -913,6 +922,8 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in pt1 = &mesh->tetra[-list[i]/4]; pxt1 = &mesh->xtetra[pt1->xt]; if ( p0_c[i] ) { + /* edge nq-p0_c has a tag in the ith tetra of the shell, update + * np-p0_c */ for ( j=0; j<3; j++) { ia = MMG5_idir[ip][j]; if ( pt->v[ia]==p0_c[i] ) { @@ -927,6 +938,8 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in } } if ( p1_c[i] ) { + /* edge nq-p1_c has a tag in the ith tetra of the shell, update + * np-p1_c */ for ( j=0; j<3; j++) { ia = MMG5_idir[ip][j]; if ( pt->v[ia]==p1_c[i] ) { From aa6f2f194af4b6d9dd36826b13b30e9cc02ccaa5 Mon Sep 17 00:00:00 2001 From: Algiane Date: Mon, 12 Jul 2021 16:50:34 +0200 Subject: [PATCH 095/170] Test if the edge ia of pxt has a tag before trying to merge infos on reference and tags of edge iav of pxt1 and edge ia of pxt. --- src/mmg3d/colver_3d.c | 81 ++++++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/src/mmg3d/colver_3d.c b/src/mmg3d/colver_3d.c index b8678ea43..9f5316968 100644 --- a/src/mmg3d/colver_3d.c +++ b/src/mmg3d/colver_3d.c @@ -1040,28 +1040,29 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in ia = MMG5_iarf[ip][j]; p0 = pt->v[MMG5_iare[ia][0]]; p1 = pt->v[MMG5_iare[ia][1]]; - - for ( i=0; i<3; i++ ) { - iav=MMG5_iarf[voyp][i]; - if ( p0==nq ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==np) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==np)) ) - break; - } - else if ( p1==nq ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==np) && (pt1->v[MMG5_iare[iav][1]]==p0)) || - ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==np)) ) - break; - } - else { - if ( ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==p0)) ) - break; + if ( pxt->tag[ia] ) { + for ( i=0; i<3; i++ ) { + iav=MMG5_iarf[voyp][i]; + if ( p0==nq ) { + if ( ((pt1->v[MMG5_iare[iav][0]]==np) && (pt1->v[MMG5_iare[iav][1]]==p1)) || + ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==np)) ) + break; + } + else if ( p1==nq ) { + if ( ((pt1->v[MMG5_iare[iav][0]]==np) && (pt1->v[MMG5_iare[iav][1]]==p0)) || + ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==np)) ) + break; + } + else { + if ( ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==p1)) || + ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==p0)) ) + break; + } } + assert(i!=3); + pxt1->tag[iav] = pxt1->tag[iav] | pxt->tag[ia]; + pxt1->edg[iav] = MG_MAX(pxt1->edg[iav],pxt->edg[ia]); } - assert(i!=3); - pxt1->tag[iav] = pxt1->tag[iav] | pxt->tag[ia]; - pxt1->edg[iav] = MG_MAX(pxt1->edg[iav],pxt->edg[ia]); } } else { @@ -1157,27 +1158,29 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in ia = MMG5_iarf[iq][j]; p0 = pt->v[MMG5_iare[ia][0]]; p1 = pt->v[MMG5_iare[ia][1]]; - for ( i=0; i<3; i++ ) { - iav=MMG5_iarf[voyq][i]; - if ( p0==np ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==nq) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==nq)) ) - break; - } - else if ( p1==np ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==nq ) && (pt1->v[MMG5_iare[iav][1]]==p0)) || - ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==nq )) ) - break; - } - else { - if ( ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==p0)) ) - break; + if ( pxt->tag[ia] ) { + for ( i=0; i<3; i++ ) { + iav=MMG5_iarf[voyq][i]; + if ( p0==np ) { + if ( ((pt1->v[MMG5_iare[iav][0]]==nq) && (pt1->v[MMG5_iare[iav][1]]==p1)) || + ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==nq)) ) + break; + } + else if ( p1==np ) { + if ( ((pt1->v[MMG5_iare[iav][0]]==nq ) && (pt1->v[MMG5_iare[iav][1]]==p0)) || + ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==nq )) ) + break; + } + else { + if ( ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==p1)) || + ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==p0)) ) + break; + } } + assert(i!=3); + pxt1->tag[iav] = pxt1->tag[iav] | pxt->tag[ia]; + pxt1->edg[iav] = MG_MAX(pxt1->edg[iav],pxt->edg[ia]); } - assert(i!=3); - pxt1->tag[iav] = pxt1->tag[iav] | pxt->tag[ia]; - pxt1->edg[iav] = MG_MAX(pxt1->edg[iav],pxt->edg[ia]); } } else { From c6a48f26b475bafa477f375506550f69cfc1795a Mon Sep 17 00:00:00 2001 From: Algiane Date: Mon, 12 Jul 2021 18:02:08 +0200 Subject: [PATCH 096/170] New function to update edge tags in cover. --- src/mmg3d/colver_3d.c | 234 ++++++++++++------------------------------ 1 file changed, 64 insertions(+), 170 deletions(-) diff --git a/src/mmg3d/colver_3d.c b/src/mmg3d/colver_3d.c index 9f5316968..10e2b30ec 100644 --- a/src/mmg3d/colver_3d.c +++ b/src/mmg3d/colver_3d.c @@ -826,6 +826,59 @@ int MMG5_chkcol_nomint(MMG5_pMesh mesh,MMG5_pSol met,int k,int8_t iface, return ilistv; } +/** + * \param pt tetra of the shell of the edge to collapse + * \param pxt xtetra associated to \a pt + * \param np global index of point to collapse + * \param nq global index of point on which we collapse + * \param ip local index of \a np in \a pt + * \param pt1 tetra neighbour to \a pt through \a nq + * \param pxt1 xtetra associated to \a pt1 + * \param voyp point facing tetra \a pt in \a pt1 + * + * Update tag and ref of the edges of \a pxt1 that belongs to the face sharing + * \a pt1 and \a pt (face \a ip in \a pt). + * + */ +static inline +void MMG3D_update_edgeTag(MMG5_pTetra pt,MMG5_pxTetra pxt,int np, int nq, + uint8_t ip, MMG5_pTetra pt1,MMG5_pxTetra pxt1, + uint8_t voyp) { + + int i,j,p0,p1; + uint8_t ia,iav; + + /* update tags for edges */ + for ( j=0; j<3; j++ ) { + ia = MMG5_iarf[ip][j]; + p0 = pt->v[MMG5_iare[ia][0]]; + p1 = pt->v[MMG5_iare[ia][1]]; + if ( pxt->tag[ia] ) { + for ( i=0; i<3; i++ ) { + iav=MMG5_iarf[voyp][i]; + if ( p0==nq ) { + if ( ((pt1->v[MMG5_iare[iav][0]]==np) && (pt1->v[MMG5_iare[iav][1]]==p1)) || + ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==np)) ) + break; + } + else if ( p1==nq ) { + if ( ((pt1->v[MMG5_iare[iav][0]]==np ) && (pt1->v[MMG5_iare[iav][1]]==p0)) || + ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==np )) ) + break; + } + else { + if ( ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==p1)) || + ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==p0)) ) + break; + } + } + assert(i!=3); + pxt1->tag[iav] |= pxt->tag[ia]; + pxt1->edg[iav] = MG_MAX ( pxt1->edg[iav],pxt->edg[ia] ); + } + } +} + /** * \param mesh pointer toward the mesh * \param met pointer toward the metric @@ -846,8 +899,8 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in MMG5_pTetra pt,pt1; MMG5_pxTetra pxt,pxt1; MMG5_xTetra xt,xts; - int i,iel,jel,pel,qel,k,np,nq,*adja,p0,p1; - uint8_t ip,iq,j,voy,voyp,voyq,ia,iav; + int i,iel,jel,pel,qel,k,np,nq,*adja; + uint8_t ip,iq,j,voy,voyp,voyq,ia; uint8_t (ind)[MMG3D_LMAX][2]; int p0_c[MMG3D_LMAX],p1_c[MMG3D_LMAX]; int8_t indar[4][4][2] = { @@ -1036,34 +1089,7 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in #endif /* update tags for edges */ - for ( j=0; j<3; j++ ) { - ia = MMG5_iarf[ip][j]; - p0 = pt->v[MMG5_iare[ia][0]]; - p1 = pt->v[MMG5_iare[ia][1]]; - if ( pxt->tag[ia] ) { - for ( i=0; i<3; i++ ) { - iav=MMG5_iarf[voyp][i]; - if ( p0==nq ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==np) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==np)) ) - break; - } - else if ( p1==nq ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==np) && (pt1->v[MMG5_iare[iav][1]]==p0)) || - ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==np)) ) - break; - } - else { - if ( ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==p0)) ) - break; - } - } - assert(i!=3); - pxt1->tag[iav] = pxt1->tag[iav] | pxt->tag[ia]; - pxt1->edg[iav] = MG_MAX(pxt1->edg[iav],pxt->edg[ia]); - } - } + MMG3D_update_edgeTag(pt,pxt,np,nq,ip,pt1,pxt1,voyp); } else { pxt1 = &xt; @@ -1074,34 +1100,8 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in if ( !MG_GET(pxt->ori,ip) ) MG_CLR(pxt1->ori,voyp); /* update tags for edges */ - for ( j=0; j<3; j++ ) { - ia = MMG5_iarf[ip][j]; - p0 = pt->v[MMG5_iare[ia][0]]; - p1 = pt->v[MMG5_iare[ia][1]]; - if ( pxt->tag[ia] ) { - for ( i=0; i<3; i++ ) { - iav=MMG5_iarf[voyp][i]; - if ( p0==nq ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==np) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==np)) ) - break; - } - else if ( p1==nq ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==np ) && (pt1->v[MMG5_iare[iav][1]]==p0)) || - ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==np )) ) - break; - } - else { - if ( ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==p0)) ) - break; - } - } - assert(i!=3); - pxt1->tag[iav] |= pxt->tag[ia]; - pxt1->edg[iav] = MG_MAX ( pxt1->edg[iav],pxt->edg[ia] ); - } - } + MMG3D_update_edgeTag(pt,pxt,np,nq,ip,pt1,pxt1,voyp); + /* Recover the already used place by pxt */ pt1->xt = pt->xt; memcpy(pxt,pxt1,sizeof(MMG5_xTetra)); @@ -1154,34 +1154,7 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in #endif /* update tags for edges */ - for ( j=0; j<3; j++ ) { - ia = MMG5_iarf[iq][j]; - p0 = pt->v[MMG5_iare[ia][0]]; - p1 = pt->v[MMG5_iare[ia][1]]; - if ( pxt->tag[ia] ) { - for ( i=0; i<3; i++ ) { - iav=MMG5_iarf[voyq][i]; - if ( p0==np ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==nq) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==nq)) ) - break; - } - else if ( p1==np ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==nq ) && (pt1->v[MMG5_iare[iav][1]]==p0)) || - ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==nq )) ) - break; - } - else { - if ( ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==p0)) ) - break; - } - } - assert(i!=3); - pxt1->tag[iav] = pxt1->tag[iav] | pxt->tag[ia]; - pxt1->edg[iav] = MG_MAX(pxt1->edg[iav],pxt->edg[ia]); - } - } + MMG3D_update_edgeTag(pt,pxt,nq,np,iq,pt1,pxt1,voyq); } else { pxt1 = &xt; @@ -1191,34 +1164,8 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in pxt1->ori = 15; if ( !MG_GET(pxt->ori,iq) ) MG_CLR(pxt1->ori,voyq); /* update tags for edges */ - for ( j=0; j<3; j++ ) { - ia = MMG5_iarf[iq][j]; - p0 = pt->v[MMG5_iare[ia][0]]; - p1 = pt->v[MMG5_iare[ia][1]]; - if ( pxt->tag[ia] ) { - for ( i=0; i<3; i++ ) { - iav=MMG5_iarf[voyq][i]; - if ( p0==np ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==nq) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==nq)) ) - break; - } - else if ( p1==np ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==nq ) && (pt1->v[MMG5_iare[iav][1]]==p0)) || - ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==nq )) ) - break; - } - else { - if ( ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==p0)) ) - break; - } - } - assert(i!=3); - pxt1->tag[iav] |= pxt->tag[ia]; - pxt1->edg[iav] = MG_MAX ( pxt1->edg[iav],pxt->edg[ia]); - } - } + MMG3D_update_edgeTag(pt,pxt,nq,np,iq,pt1,pxt1,voyq); + /* Create new field xt */ mesh->xt++; if ( mesh->xt > mesh->xtmax ) { @@ -1255,34 +1202,7 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in MG_SET(pxt1->ori,voyq); /* update tags for edges */ - for ( j=0; j<3; j++ ) { - ia = MMG5_iarf[iq][j]; - p0 = pt->v[MMG5_iare[ia][0]]; - p1 = pt->v[MMG5_iare[ia][1]]; - if ( pxt->tag[ia] ) { - for ( i=0; i<3; i++ ) { - iav=MMG5_iarf[voyq][i]; - if ( p0==np ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==nq) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==nq)) ) - break; - } - else if ( p1==np ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==nq ) && (pt1->v[MMG5_iare[iav][1]]==p0)) || - ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==nq )) ) - break; - } - else { - if ( ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==p0)) ) - break; - } - } - assert(i!=3); - pxt1->tag[iav] |= pxt->tag[ia]; - pxt1->edg[iav] = MG_MAX ( pxt1->edg[iav], pxt->edg[ia]); - } - } + MMG3D_update_edgeTag(pt,pxt,nq,np,iq,pt1,pxt1,voyq); } else { pxt1 = &xt; @@ -1292,34 +1212,8 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in pxt1->ori = 15; /* update tags for edges */ - for ( j=0; j<3; j++ ) { - ia = MMG5_iarf[iq][j]; - p0 = pt->v[MMG5_iare[ia][0]]; - p1 = pt->v[MMG5_iare[ia][1]]; - if ( pxt->tag[ia] ) { - for ( i=0; i<3; i++ ) { - iav = MMG5_iarf[voyq][i]; - if ( p0==np ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==nq) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==nq)) ) - break; - } - else if ( p1==np ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==nq ) && (pt1->v[MMG5_iare[iav][1]]==p0)) || - ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==nq )) ) - break; - } - else { - if ( ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==p0)) ) - break; - } - } - assert(i!=3); - pxt1->tag[iav] |= pxt->tag[ia]; - pxt1->edg[iav] = MG_MAX ( pxt1->edg[iav],pxt->edg[ia]); - } - } + MMG3D_update_edgeTag(pt,pxt,nq,np,iq,pt1,pxt1,voyq); + /* Recover the already used place by pxt */ pt1->xt = pt->xt; memcpy(pxt,pxt1,sizeof(MMG5_xTetra)); From a334ce1b440162a8f7e7da4ab865df8174fefdb2 Mon Sep 17 00:00:00 2001 From: Algiane Date: Mon, 12 Jul 2021 18:21:22 +0200 Subject: [PATCH 097/170] Update comment. --- src/mmg3d/colver_3d.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/mmg3d/colver_3d.c b/src/mmg3d/colver_3d.c index 10e2b30ec..1d6e1aa98 100644 --- a/src/mmg3d/colver_3d.c +++ b/src/mmg3d/colver_3d.c @@ -1092,6 +1092,7 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in MMG3D_update_edgeTag(pt,pxt,np,nq,ip,pt1,pxt1,voyp); } else { + /* shell tet has a xtetra and pel exists but pel don't have a xtetra */ pxt1 = &xt; memset(pxt1,0,sizeof(MMG5_xTetra)); pxt1->ref[voyp] = pxt->ref[ip]; @@ -1108,7 +1109,8 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in } } else { - /* Only the values corresponding to pt become 0 */ + /* Shell tet don't have a xtetra: only the values of pel corresponding + * to pt become 0 */ if ( pt1->xt > 0 ) { pxt1 = &mesh->xtetra[pt1->xt]; pxt1->ref[voyp] = 0; @@ -1157,12 +1159,15 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in MMG3D_update_edgeTag(pt,pxt,nq,np,iq,pt1,pxt1,voyq); } else { + /* pel exists, shell tet has a xtetra but qel doesn't have boundary + * tetra: create it */ pxt1 = &xt; memset(pxt1,0,sizeof(MMG5_xTetra)); pxt1->ref[voyq] = pxt->ref[iq]; pxt1->ftag[voyq] = pxt->ftag[iq]; pxt1->ori = 15; if ( !MG_GET(pxt->ori,iq) ) MG_CLR(pxt1->ori,voyq); + /* update tags for edges */ MMG3D_update_edgeTag(pt,pxt,nq,np,iq,pt1,pxt1,voyq); @@ -1179,7 +1184,8 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in } } else { - /* Only the values corresponding to pt become 0 */ + /* pel exist but shell tet doesn't have a boundary tetra: only the + * values of qel corresponding to pt become 0 */ if ( pt1->xt > 0 ) { pxt1 = &mesh->xtetra[pt1->xt]; pxt1->ref[voyq] = 0; @@ -1190,6 +1196,7 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in } } else { + /* pel==0: No adjacent through face iq */ assert(pt->xt); pxt = &mesh->xtetra[pt->xt]; if ( qel ) { From 2fa98476fb2360b8669c0e6b3abcac38b93f72e3 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 13 Jul 2021 11:05:04 +0200 Subject: [PATCH 098/170] Patch error in the print of the gradation default values when disabled. --- src/common/mmg.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/common/mmg.c b/src/common/mmg.c index 7c90f73ed..dfa7d7907 100644 --- a/src/common/mmg.c +++ b/src/common/mmg.c @@ -171,11 +171,12 @@ void MMG5_mmgDefaultValues(MMG5_pMesh mesh) { "metric sizes otherwise.\n",mesh->info.hmax); fprintf(stdout,"Hausdorff distance (-hausd) : %lf\n", mesh->info.hausd); + fprintf(stdout,"gradation control (-hgrad) : %lf\n", - exp(mesh->info.hgrad)); + (mesh->info.hgrad < 0) ? mesh->info.hgrad : exp(mesh->info.hgrad) ); fprintf(stdout,"gradation control for required entities (-hgradreq) : %lf\n", - exp(mesh->info.hgradreq)); + (mesh->info.hgradreq < 0) ? mesh->info.hgradreq : exp(mesh->info.hgradreq) ); } /** From b539e3ef113d3062815833689912396b9781d242 Mon Sep 17 00:00:00 2001 From: Algiane Date: Fri, 16 Jul 2021 15:04:39 +0200 Subject: [PATCH 099/170] Add debug function to test point and edge tags consistency. --- src/mmg3d/chkmsh_3d.c | 177 ++++++++++++++++++++++++++++++++++++++++++ src/mmg3d/mmg3d.h | 5 +- 2 files changed, 180 insertions(+), 2 deletions(-) diff --git a/src/mmg3d/chkmsh_3d.c b/src/mmg3d/chkmsh_3d.c index b6606fcad..0c7cac06d 100644 --- a/src/mmg3d/chkmsh_3d.c +++ b/src/mmg3d/chkmsh_3d.c @@ -70,6 +70,183 @@ void MMG5_chkvol(MMG5_pMesh mesh) { #endif } +/** + * \param mesh pointer toward the mesh + * + * Test consistency between the tags in the xtetra of all mesh edges marked as + * boundaries. + * + * \warning Not used. + */ +void MMG3D_chkmeshedgestags(MMG5_pMesh mesh) { + MMG5_pTetra pt; + MMG5_pxTetra pxt; + MMG5_Hash hash; + int k,nt,i,ip1,ip2,tag; + + /* Rough eval of the number of boundary triangles */ + nt = 0; + for (k=1; k<=mesh->ne; k++) { + pt = &mesh->tetra[k]; + if ( !MG_EOK(pt) ) continue; + if ( !pt->xt ) continue; + + pxt = &mesh->xtetra[pt->xt]; + for (i=0; i<4; i++) { + if ( pxt->ftag[i] & MG_BDY ) { + ++nt; + } + } + } + nt = nt/2 + 1; + + /* Travel mesh edges and hash boundary ones */ + MMG5_hashNew(mesh,&hash,nt,3*nt); + + for (k=1; k<=mesh->ne; k++) { + pt = &mesh->tetra[k]; + if ( !MG_EOK(pt) ) continue; + if ( !pt->xt ) continue; + + pxt = &mesh->xtetra[pt->xt]; + for (i=0; i<6; i++) { + if ( pxt->tag[i] & MG_BDY ) { + ip1 = pt->v[MMG5_iare[i][0]]; + ip2 = pt->v[MMG5_iare[i][1]]; + tag = MMG5_hashEdgeTag ( mesh,&hash,ip1,ip2,pxt->tag[i]); + if ( tag != pxt->tag[i] ) { + fprintf(stderr,"Error: %s: %d: Non consistency at tet %d (%d), edge %d:%d--%d\n ", + __func__,__LINE__,k,MMG3D_indElt(mesh,k),i,ip1,ip2); + assert( tag == pxt->tag[i] && "edge tag error" ); + } + } + } + } + MMG5_DEL_MEM(mesh,hash.item); +} + + +/** + * \param mesh pointer toward the mesh + * \param ip1 first vertex of edge to test + * \param ip2 second vertex of edge to test + * \param tag edge tag + * + * Test consistency between the tags of the edge \a ip1 - \a ip2 from all the + * tetra of the edge shell. + * + * \warning Not used. + */ +void MMG3D_chkedgetag(MMG5_pMesh mesh, int ip1, int ip2, int tag) { + MMG5_pTetra pt; + MMG5_pxTetra pxt; + int k,i,i1,i2; + + for (k=1; k<=mesh->ne; k++) { + pt = &mesh->tetra[k]; + if ( !MG_EOK(pt) ) continue; + if ( !pt->xt ) continue; + + pxt = &mesh->xtetra[pt->xt]; + for (i=0; i<6; i++) { + i1 = pt->v[MMG5_iare[i][0]]; + i2 = pt->v[MMG5_iare[i][1]]; + + if ( ((i1==ip1) && (i2==ip2)) || ((i2==ip1) && (i1==ip2)) ) { + if ( pxt->tag[i] != tag ) { + fprintf(stderr,"Error: %s: %d: Non consistency at tet %d (%d), edge %d\n ", + __func__,__LINE__,k,MMG3D_indElt(mesh,k),i); + assert(0); + } + } + } + } +} + + +/** + * \param mesh + * + * Test consistency between points and edges tags. If an error is detected, + * hash mesh edges to check the consistency between the tags of tetra edges. + * + * \warning Not used. + */ +void MMG3D_chkpointtag(MMG5_pMesh mesh) { + MMG5_pTetra pt; + MMG5_pxTetra pxt; + MMG5_pPoint p1,p2; + int k,i,i1,i2,ip1,ip2; + + /** Check consistency between edge tags and point tags */ + for (k=1; k<=mesh->ne; k++) { + pt = &mesh->tetra[k]; + if ( !MG_EOK(pt) ) continue; + if ( !pt->xt ) continue; + + pxt = &mesh->xtetra[pt->xt]; + + for ( i=0; i<6; ++i ) { + i1 = MMG5_iare[i][0]; + i2 = MMG5_iare[i][1]; + ip1 = pt->v[i1]; + ip2 = pt->v[i2]; + p1 = &mesh->point[ip1]; + p2 = &mesh->point[ip2]; + + if ( MG_EDG(pxt->tag[i]) ) { + if ( !(MG_EDG(p1->tag) || MG_SIN(p1->tag)) ) { + fprintf(stderr,"Error: %s: %d: Tag error at point %d (%d), " + "tetra %d (%d), edge %d:%d--%d (%d--%d).\n",__func__,__LINE__, + ip1,MMG3D_indPt(mesh,ip1),k,MMG3D_indElt(mesh,k),i,ip1,ip2, + MMG3D_indPt(mesh,ip1),MMG3D_indPt(mesh,ip2)); + fprintf(stderr," point tag: %d; edge tag: %d\n",p1->tag,pxt->tag[i]); + /** An error has been detected: check the consistency between the tags of + * tetra edges */ + MMG3D_chkedgetag(mesh,ip1,ip2,pxt->tag[i]); + assert(0); + } + if ( !(MG_EDG(p2->tag) || MG_SIN(p2->tag)) ) { + fprintf(stderr,"Error: %s: %d: Tag error at point %d (%d), " + "tetra %d (%d), edge %d:%d--%d (%d--%d).\n",__func__,__LINE__, + ip2,MMG3D_indPt(mesh,ip2),k,MMG3D_indElt(mesh,k),i,ip1,ip2, + MMG3D_indPt(mesh,ip1),MMG3D_indPt(mesh,ip2)); + fprintf(stderr," point tag: %d; edge tag: %d\n",p2->tag,pxt->tag[i]); + /** An error has been detected: check the consistency between the tags of + * tetra edges */ + MMG3D_chkedgetag(mesh,ip1,ip2,pxt->tag[i]); + assert(0); + } + } + + if ( pxt->tag[i] & MG_NOM ) { + if ( !(MG_SIN(p1->tag) || (p1->tag & MG_NOM)) ) { + fprintf(stderr,"Error: %s: %d: Tag error at point %d (%d), " + "tetra %d (%d), edge %d:%d--%d (%d--%d).\n",__func__,__LINE__, + ip1,MMG3D_indPt(mesh,ip1),k,MMG3D_indElt(mesh,k),i,ip1,ip2, + MMG3D_indPt(mesh,ip1),MMG3D_indPt(mesh,ip2)); + fprintf(stderr," point tag: %d; edge tag: %d\n",p1->tag,pxt->tag[i]); + /** An error has been detected: check the consistency between the tags of + * tetra edges */ + MMG3D_chkedgetag(mesh,ip1,ip2,pxt->tag[i]); + assert(0); + } + if ( !(MG_SIN(p2->tag) || (p2->tag & MG_NOM)) ) { + fprintf(stderr,"Error: %s: %d: Tag error at point %d (%d), " + "tetra %d (%d), edge %d:%d--%d (%d--%d).\n",__func__,__LINE__, + ip2,MMG3D_indPt(mesh,ip2),k,MMG3D_indElt(mesh,k),i,ip1,ip2, + MMG3D_indPt(mesh,ip1),MMG3D_indPt(mesh,ip2)); + fprintf(stderr," point tag: %d; edge tag: %d\n",p2->tag,pxt->tag[i]); + /** An error has been detected: check the consistency between the tags of + * tetra edges */ + MMG3D_chkedgetag(mesh,ip1,ip2,pxt->tag[i]); + assert(0); + } + } + } + } +} + /** * \return 0 if fail, 1 otherwise * diff --git a/src/mmg3d/mmg3d.h b/src/mmg3d/mmg3d.h index 1370a981f..0de946e07 100644 --- a/src/mmg3d/mmg3d.h +++ b/src/mmg3d/mmg3d.h @@ -456,7 +456,8 @@ void MMG3D_keep_only1Subdomain ( MMG5_pMesh mesh,int nsd ); int MMG3D_indElt(MMG5_pMesh mesh,int kel); int MMG3D_indPt(MMG5_pMesh mesh,int kp); void MMG5_printTetra(MMG5_pMesh mesh,char* fileName); - +void MMG3D_chkpointtag(MMG5_pMesh mesh); +void MMG3D_chkmeshedgestags(MMG5_pMesh mesh); #ifdef USE_SCOTCH int MMG5_mmg3dRenumbering(int,MMG5_pMesh,MMG5_pSol,MMG5_pSol,int*); @@ -494,7 +495,7 @@ int MMG5_movtet(MMG5_pMesh mesh,MMG5_pSol met,MMG3D_pPROctree PROctree, double clickSurf,double clickVol,int moveVol,int improveSurf,int improveVolSurf, int improveVol,int maxit,int testmark); int MMG5_swpmsh(MMG5_pMesh mesh,MMG5_pSol met,MMG3D_pPROctree PROctree, int); - int MMG5_swptet(MMG5_pMesh mesh,MMG5_pSol met,double,double,MMG3D_pPROctree, int,int); +int MMG5_swptet(MMG5_pMesh mesh,MMG5_pSol met,double,double,MMG3D_pPROctree, int,int); /* pointers */ /* init structures */ From a98ab4a0047f9e89b00c4a85524d31446f113948 Mon Sep 17 00:00:00 2001 From: Algiane Date: Mon, 12 Jul 2021 11:55:01 +0200 Subject: [PATCH 100/170] More clear error messages. --- src/mmg3d/boulep_3d.c | 2 +- src/mmg3d/chkmsh_3d.c | 2 +- src/mmg3d/mmg3d1.c | 6 ++++-- src/mmg3d/mmg3d2.c | 4 +++- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/mmg3d/boulep_3d.c b/src/mmg3d/boulep_3d.c index de6d0b9f8..d8c585be1 100644 --- a/src/mmg3d/boulep_3d.c +++ b/src/mmg3d/boulep_3d.c @@ -1823,7 +1823,7 @@ int MMG5_coquilface(MMG5_pMesh mesh,int start,int8_t iface,int ia,int *list, // 2) we have a non-manifold shape immersed in a domain (3 triangles // sharing the edge and a closed shell) printf(" ## Warning: %s: you have %d boundaries in the shell" - " of your edge.\n",__func__,nbdy+1); + " of a manifold edge.\n",__func__,nbdy+1); printf(" Problem may occur during remesh process.\n"); mmgWarn0 = 1; } diff --git a/src/mmg3d/chkmsh_3d.c b/src/mmg3d/chkmsh_3d.c index 0c7cac06d..bce124d6c 100644 --- a/src/mmg3d/chkmsh_3d.c +++ b/src/mmg3d/chkmsh_3d.c @@ -458,7 +458,7 @@ int MMG5_mmg3dChkmsh(MMG5_pMesh mesh,int severe,int base) { " face is a limit of two subdomains" " and is not tagged %d %d %d -->%d\n",__func__, MMG3D_indElt(mesh,k),i, - MMG3D_indElt(mesh,pt->v[MMG5_idir[i][0]]), + MMG3D_indElt(mesh,pt->v[MMG5_idir[i][0]]), MMG3D_indPt(mesh,pt->v[MMG5_idir[i][1]]), MMG3D_indPt(mesh,pt->v[MMG5_idir[i][2]]), pxt->ftag[i]); } diff --git a/src/mmg3d/mmg3d1.c b/src/mmg3d/mmg3d1.c index dc235dc6f..3aaa1ce6d 100644 --- a/src/mmg3d/mmg3d1.c +++ b/src/mmg3d/mmg3d1.c @@ -458,7 +458,8 @@ int8_t MMG5_chkedg(MMG5_pMesh mesh,MMG5_Tria *pt,int8_t ori, double hmax, if(!((p[i1]->tag & MG_NOM) || MG_EDG(p[i1]->tag) ) ) { if ( !mmgWarn0 ) { fprintf(stderr,"\n ## Warning: %s: a- at least 1 geometrical" - " problem\n",__func__); + " problem: non consistency between point tag (%d) and" + " edge tag (%d.)\n",__func__,p[i1]->tag,pt->tag[i]); mmgWarn0 = 1; } return -1; @@ -480,7 +481,8 @@ int8_t MMG5_chkedg(MMG5_pMesh mesh,MMG5_Tria *pt,int8_t ori, double hmax, if(!((p[i2]->tag & MG_NOM) || MG_EDG(p[i2]->tag) ) ) { if ( !mmgWarn1 ) { fprintf(stderr,"\n ## Warning: %s: b- at least 1 geometrical" - " problem\n",__func__); + " problem: non consistency between point tag (%d) and" + " edge tag (%d.)\n",__func__,p[i2]->tag,pt->tag[i]); mmgWarn1 = 1; } return -1; diff --git a/src/mmg3d/mmg3d2.c b/src/mmg3d/mmg3d2.c index a498257ba..c0d654a49 100755 --- a/src/mmg3d/mmg3d2.c +++ b/src/mmg3d/mmg3d2.c @@ -1496,7 +1496,9 @@ int MMG5_chkmaniball(MMG5_pMesh mesh, int start, int8_t ip){ pt = &mesh->tetra[k]; if( pt->ref == ref ) { fprintf(stderr," *** Topological problem:"); - fprintf(stderr," non manifold surface at point %d \n",nump); + fprintf(stderr," non manifold surface at point %d %d\n",nump, MMG3D_indPt(mesh,nump)); + fprintf(stderr," non manifold surface at tet %d (ip %d)\n", MMG3D_indElt(mesh,start),ip); + fprintf(stderr,"nref (color %d) %d\n",nref,ref); return 0; } } From 94d55872c4b6dc0762e452359b6011e125eed41f Mon Sep 17 00:00:00 2001 From: Algiane Date: Mon, 12 Jul 2021 16:46:42 +0200 Subject: [PATCH 101/170] Update comments for backward understanding. --- src/mmg3d/colver_3d.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/mmg3d/colver_3d.c b/src/mmg3d/colver_3d.c index 2845d192e..b8678ea43 100644 --- a/src/mmg3d/colver_3d.c +++ b/src/mmg3d/colver_3d.c @@ -875,7 +875,11 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in for (j=0; j<3; j++) { i = MMG5_inxt3[i]; if ( pt->v[i] == nq ) { - /* list edges that we need to update */ + /* In each tetra of the shell, 2 edges coming from np will be merged + * with 2 edges coming from nq: list the local indices of the edges + * comig from nq (ind array) and store the global indices of the non nq + * vertices of these edges if they are tagged (so edges np-p0_c and + * np-p1_c must be updated in all tetra) */ if ( pt->xt ) { pxt = &mesh->xtetra[pt->xt]; ip = list[k]%4; @@ -896,14 +900,19 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in } } - /* avoid recreating existing elt */ + /* avoid recreating existing elt and update the tags of the edge ip-p0_c and + * ip-p1_c */ for (k=0; ktetra[iel]; - /* update edges of elements that do not belong to the shell of pq */ + /* update edges ip-p0_c and ip-p1_c in elts of the ball of ip but that do + * not belong to the shell of pq */ if ( !pt->xt ) { continue; } @@ -913,6 +922,8 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in pt1 = &mesh->tetra[-list[i]/4]; pxt1 = &mesh->xtetra[pt1->xt]; if ( p0_c[i] ) { + /* edge nq-p0_c has a tag in the ith tetra of the shell, update + * np-p0_c */ for ( j=0; j<3; j++) { ia = MMG5_idir[ip][j]; if ( pt->v[ia]==p0_c[i] ) { @@ -927,6 +938,8 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in } } if ( p1_c[i] ) { + /* edge nq-p1_c has a tag in the ith tetra of the shell, update + * np-p1_c */ for ( j=0; j<3; j++) { ia = MMG5_idir[ip][j]; if ( pt->v[ia]==p1_c[i] ) { From e3231987573315386285329ff3ed6daf71a67e5a Mon Sep 17 00:00:00 2001 From: Algiane Date: Mon, 12 Jul 2021 16:50:34 +0200 Subject: [PATCH 102/170] Test if the edge ia of pxt has a tag before trying to merge infos on reference and tags of edge iav of pxt1 and edge ia of pxt. --- src/mmg3d/colver_3d.c | 81 ++++++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/src/mmg3d/colver_3d.c b/src/mmg3d/colver_3d.c index b8678ea43..9f5316968 100644 --- a/src/mmg3d/colver_3d.c +++ b/src/mmg3d/colver_3d.c @@ -1040,28 +1040,29 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in ia = MMG5_iarf[ip][j]; p0 = pt->v[MMG5_iare[ia][0]]; p1 = pt->v[MMG5_iare[ia][1]]; - - for ( i=0; i<3; i++ ) { - iav=MMG5_iarf[voyp][i]; - if ( p0==nq ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==np) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==np)) ) - break; - } - else if ( p1==nq ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==np) && (pt1->v[MMG5_iare[iav][1]]==p0)) || - ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==np)) ) - break; - } - else { - if ( ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==p0)) ) - break; + if ( pxt->tag[ia] ) { + for ( i=0; i<3; i++ ) { + iav=MMG5_iarf[voyp][i]; + if ( p0==nq ) { + if ( ((pt1->v[MMG5_iare[iav][0]]==np) && (pt1->v[MMG5_iare[iav][1]]==p1)) || + ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==np)) ) + break; + } + else if ( p1==nq ) { + if ( ((pt1->v[MMG5_iare[iav][0]]==np) && (pt1->v[MMG5_iare[iav][1]]==p0)) || + ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==np)) ) + break; + } + else { + if ( ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==p1)) || + ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==p0)) ) + break; + } } + assert(i!=3); + pxt1->tag[iav] = pxt1->tag[iav] | pxt->tag[ia]; + pxt1->edg[iav] = MG_MAX(pxt1->edg[iav],pxt->edg[ia]); } - assert(i!=3); - pxt1->tag[iav] = pxt1->tag[iav] | pxt->tag[ia]; - pxt1->edg[iav] = MG_MAX(pxt1->edg[iav],pxt->edg[ia]); } } else { @@ -1157,27 +1158,29 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in ia = MMG5_iarf[iq][j]; p0 = pt->v[MMG5_iare[ia][0]]; p1 = pt->v[MMG5_iare[ia][1]]; - for ( i=0; i<3; i++ ) { - iav=MMG5_iarf[voyq][i]; - if ( p0==np ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==nq) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==nq)) ) - break; - } - else if ( p1==np ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==nq ) && (pt1->v[MMG5_iare[iav][1]]==p0)) || - ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==nq )) ) - break; - } - else { - if ( ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==p0)) ) - break; + if ( pxt->tag[ia] ) { + for ( i=0; i<3; i++ ) { + iav=MMG5_iarf[voyq][i]; + if ( p0==np ) { + if ( ((pt1->v[MMG5_iare[iav][0]]==nq) && (pt1->v[MMG5_iare[iav][1]]==p1)) || + ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==nq)) ) + break; + } + else if ( p1==np ) { + if ( ((pt1->v[MMG5_iare[iav][0]]==nq ) && (pt1->v[MMG5_iare[iav][1]]==p0)) || + ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==nq )) ) + break; + } + else { + if ( ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==p1)) || + ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==p0)) ) + break; + } } + assert(i!=3); + pxt1->tag[iav] = pxt1->tag[iav] | pxt->tag[ia]; + pxt1->edg[iav] = MG_MAX(pxt1->edg[iav],pxt->edg[ia]); } - assert(i!=3); - pxt1->tag[iav] = pxt1->tag[iav] | pxt->tag[ia]; - pxt1->edg[iav] = MG_MAX(pxt1->edg[iav],pxt->edg[ia]); } } else { From ae6b476082e5cfbabcf61cc63dd53aea0d4b7fa4 Mon Sep 17 00:00:00 2001 From: Algiane Date: Mon, 12 Jul 2021 18:02:08 +0200 Subject: [PATCH 103/170] New function to update edge tags in cover. --- src/mmg3d/colver_3d.c | 234 ++++++++++++------------------------------ 1 file changed, 64 insertions(+), 170 deletions(-) diff --git a/src/mmg3d/colver_3d.c b/src/mmg3d/colver_3d.c index 9f5316968..10e2b30ec 100644 --- a/src/mmg3d/colver_3d.c +++ b/src/mmg3d/colver_3d.c @@ -826,6 +826,59 @@ int MMG5_chkcol_nomint(MMG5_pMesh mesh,MMG5_pSol met,int k,int8_t iface, return ilistv; } +/** + * \param pt tetra of the shell of the edge to collapse + * \param pxt xtetra associated to \a pt + * \param np global index of point to collapse + * \param nq global index of point on which we collapse + * \param ip local index of \a np in \a pt + * \param pt1 tetra neighbour to \a pt through \a nq + * \param pxt1 xtetra associated to \a pt1 + * \param voyp point facing tetra \a pt in \a pt1 + * + * Update tag and ref of the edges of \a pxt1 that belongs to the face sharing + * \a pt1 and \a pt (face \a ip in \a pt). + * + */ +static inline +void MMG3D_update_edgeTag(MMG5_pTetra pt,MMG5_pxTetra pxt,int np, int nq, + uint8_t ip, MMG5_pTetra pt1,MMG5_pxTetra pxt1, + uint8_t voyp) { + + int i,j,p0,p1; + uint8_t ia,iav; + + /* update tags for edges */ + for ( j=0; j<3; j++ ) { + ia = MMG5_iarf[ip][j]; + p0 = pt->v[MMG5_iare[ia][0]]; + p1 = pt->v[MMG5_iare[ia][1]]; + if ( pxt->tag[ia] ) { + for ( i=0; i<3; i++ ) { + iav=MMG5_iarf[voyp][i]; + if ( p0==nq ) { + if ( ((pt1->v[MMG5_iare[iav][0]]==np) && (pt1->v[MMG5_iare[iav][1]]==p1)) || + ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==np)) ) + break; + } + else if ( p1==nq ) { + if ( ((pt1->v[MMG5_iare[iav][0]]==np ) && (pt1->v[MMG5_iare[iav][1]]==p0)) || + ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==np )) ) + break; + } + else { + if ( ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==p1)) || + ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==p0)) ) + break; + } + } + assert(i!=3); + pxt1->tag[iav] |= pxt->tag[ia]; + pxt1->edg[iav] = MG_MAX ( pxt1->edg[iav],pxt->edg[ia] ); + } + } +} + /** * \param mesh pointer toward the mesh * \param met pointer toward the metric @@ -846,8 +899,8 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in MMG5_pTetra pt,pt1; MMG5_pxTetra pxt,pxt1; MMG5_xTetra xt,xts; - int i,iel,jel,pel,qel,k,np,nq,*adja,p0,p1; - uint8_t ip,iq,j,voy,voyp,voyq,ia,iav; + int i,iel,jel,pel,qel,k,np,nq,*adja; + uint8_t ip,iq,j,voy,voyp,voyq,ia; uint8_t (ind)[MMG3D_LMAX][2]; int p0_c[MMG3D_LMAX],p1_c[MMG3D_LMAX]; int8_t indar[4][4][2] = { @@ -1036,34 +1089,7 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in #endif /* update tags for edges */ - for ( j=0; j<3; j++ ) { - ia = MMG5_iarf[ip][j]; - p0 = pt->v[MMG5_iare[ia][0]]; - p1 = pt->v[MMG5_iare[ia][1]]; - if ( pxt->tag[ia] ) { - for ( i=0; i<3; i++ ) { - iav=MMG5_iarf[voyp][i]; - if ( p0==nq ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==np) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==np)) ) - break; - } - else if ( p1==nq ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==np) && (pt1->v[MMG5_iare[iav][1]]==p0)) || - ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==np)) ) - break; - } - else { - if ( ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==p0)) ) - break; - } - } - assert(i!=3); - pxt1->tag[iav] = pxt1->tag[iav] | pxt->tag[ia]; - pxt1->edg[iav] = MG_MAX(pxt1->edg[iav],pxt->edg[ia]); - } - } + MMG3D_update_edgeTag(pt,pxt,np,nq,ip,pt1,pxt1,voyp); } else { pxt1 = &xt; @@ -1074,34 +1100,8 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in if ( !MG_GET(pxt->ori,ip) ) MG_CLR(pxt1->ori,voyp); /* update tags for edges */ - for ( j=0; j<3; j++ ) { - ia = MMG5_iarf[ip][j]; - p0 = pt->v[MMG5_iare[ia][0]]; - p1 = pt->v[MMG5_iare[ia][1]]; - if ( pxt->tag[ia] ) { - for ( i=0; i<3; i++ ) { - iav=MMG5_iarf[voyp][i]; - if ( p0==nq ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==np) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==np)) ) - break; - } - else if ( p1==nq ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==np ) && (pt1->v[MMG5_iare[iav][1]]==p0)) || - ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==np )) ) - break; - } - else { - if ( ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==p0)) ) - break; - } - } - assert(i!=3); - pxt1->tag[iav] |= pxt->tag[ia]; - pxt1->edg[iav] = MG_MAX ( pxt1->edg[iav],pxt->edg[ia] ); - } - } + MMG3D_update_edgeTag(pt,pxt,np,nq,ip,pt1,pxt1,voyp); + /* Recover the already used place by pxt */ pt1->xt = pt->xt; memcpy(pxt,pxt1,sizeof(MMG5_xTetra)); @@ -1154,34 +1154,7 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in #endif /* update tags for edges */ - for ( j=0; j<3; j++ ) { - ia = MMG5_iarf[iq][j]; - p0 = pt->v[MMG5_iare[ia][0]]; - p1 = pt->v[MMG5_iare[ia][1]]; - if ( pxt->tag[ia] ) { - for ( i=0; i<3; i++ ) { - iav=MMG5_iarf[voyq][i]; - if ( p0==np ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==nq) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==nq)) ) - break; - } - else if ( p1==np ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==nq ) && (pt1->v[MMG5_iare[iav][1]]==p0)) || - ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==nq )) ) - break; - } - else { - if ( ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==p0)) ) - break; - } - } - assert(i!=3); - pxt1->tag[iav] = pxt1->tag[iav] | pxt->tag[ia]; - pxt1->edg[iav] = MG_MAX(pxt1->edg[iav],pxt->edg[ia]); - } - } + MMG3D_update_edgeTag(pt,pxt,nq,np,iq,pt1,pxt1,voyq); } else { pxt1 = &xt; @@ -1191,34 +1164,8 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in pxt1->ori = 15; if ( !MG_GET(pxt->ori,iq) ) MG_CLR(pxt1->ori,voyq); /* update tags for edges */ - for ( j=0; j<3; j++ ) { - ia = MMG5_iarf[iq][j]; - p0 = pt->v[MMG5_iare[ia][0]]; - p1 = pt->v[MMG5_iare[ia][1]]; - if ( pxt->tag[ia] ) { - for ( i=0; i<3; i++ ) { - iav=MMG5_iarf[voyq][i]; - if ( p0==np ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==nq) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==nq)) ) - break; - } - else if ( p1==np ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==nq ) && (pt1->v[MMG5_iare[iav][1]]==p0)) || - ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==nq )) ) - break; - } - else { - if ( ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==p0)) ) - break; - } - } - assert(i!=3); - pxt1->tag[iav] |= pxt->tag[ia]; - pxt1->edg[iav] = MG_MAX ( pxt1->edg[iav],pxt->edg[ia]); - } - } + MMG3D_update_edgeTag(pt,pxt,nq,np,iq,pt1,pxt1,voyq); + /* Create new field xt */ mesh->xt++; if ( mesh->xt > mesh->xtmax ) { @@ -1255,34 +1202,7 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in MG_SET(pxt1->ori,voyq); /* update tags for edges */ - for ( j=0; j<3; j++ ) { - ia = MMG5_iarf[iq][j]; - p0 = pt->v[MMG5_iare[ia][0]]; - p1 = pt->v[MMG5_iare[ia][1]]; - if ( pxt->tag[ia] ) { - for ( i=0; i<3; i++ ) { - iav=MMG5_iarf[voyq][i]; - if ( p0==np ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==nq) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==nq)) ) - break; - } - else if ( p1==np ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==nq ) && (pt1->v[MMG5_iare[iav][1]]==p0)) || - ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==nq )) ) - break; - } - else { - if ( ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==p0)) ) - break; - } - } - assert(i!=3); - pxt1->tag[iav] |= pxt->tag[ia]; - pxt1->edg[iav] = MG_MAX ( pxt1->edg[iav], pxt->edg[ia]); - } - } + MMG3D_update_edgeTag(pt,pxt,nq,np,iq,pt1,pxt1,voyq); } else { pxt1 = &xt; @@ -1292,34 +1212,8 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in pxt1->ori = 15; /* update tags for edges */ - for ( j=0; j<3; j++ ) { - ia = MMG5_iarf[iq][j]; - p0 = pt->v[MMG5_iare[ia][0]]; - p1 = pt->v[MMG5_iare[ia][1]]; - if ( pxt->tag[ia] ) { - for ( i=0; i<3; i++ ) { - iav = MMG5_iarf[voyq][i]; - if ( p0==np ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==nq) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==nq)) ) - break; - } - else if ( p1==np ) { - if ( ((pt1->v[MMG5_iare[iav][0]]==nq ) && (pt1->v[MMG5_iare[iav][1]]==p0)) || - ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==nq )) ) - break; - } - else { - if ( ((pt1->v[MMG5_iare[iav][0]]==p0) && (pt1->v[MMG5_iare[iav][1]]==p1)) || - ((pt1->v[MMG5_iare[iav][0]]==p1) && (pt1->v[MMG5_iare[iav][1]]==p0)) ) - break; - } - } - assert(i!=3); - pxt1->tag[iav] |= pxt->tag[ia]; - pxt1->edg[iav] = MG_MAX ( pxt1->edg[iav],pxt->edg[ia]); - } - } + MMG3D_update_edgeTag(pt,pxt,nq,np,iq,pt1,pxt1,voyq); + /* Recover the already used place by pxt */ pt1->xt = pt->xt; memcpy(pxt,pxt1,sizeof(MMG5_xTetra)); From 30ab68c0d551487de061a849c357802dbc3f12e6 Mon Sep 17 00:00:00 2001 From: Algiane Date: Mon, 12 Jul 2021 18:21:22 +0200 Subject: [PATCH 104/170] Update comment. --- src/mmg3d/colver_3d.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/mmg3d/colver_3d.c b/src/mmg3d/colver_3d.c index 10e2b30ec..1d6e1aa98 100644 --- a/src/mmg3d/colver_3d.c +++ b/src/mmg3d/colver_3d.c @@ -1092,6 +1092,7 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in MMG3D_update_edgeTag(pt,pxt,np,nq,ip,pt1,pxt1,voyp); } else { + /* shell tet has a xtetra and pel exists but pel don't have a xtetra */ pxt1 = &xt; memset(pxt1,0,sizeof(MMG5_xTetra)); pxt1->ref[voyp] = pxt->ref[ip]; @@ -1108,7 +1109,8 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in } } else { - /* Only the values corresponding to pt become 0 */ + /* Shell tet don't have a xtetra: only the values of pel corresponding + * to pt become 0 */ if ( pt1->xt > 0 ) { pxt1 = &mesh->xtetra[pt1->xt]; pxt1->ref[voyp] = 0; @@ -1157,12 +1159,15 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in MMG3D_update_edgeTag(pt,pxt,nq,np,iq,pt1,pxt1,voyq); } else { + /* pel exists, shell tet has a xtetra but qel doesn't have boundary + * tetra: create it */ pxt1 = &xt; memset(pxt1,0,sizeof(MMG5_xTetra)); pxt1->ref[voyq] = pxt->ref[iq]; pxt1->ftag[voyq] = pxt->ftag[iq]; pxt1->ori = 15; if ( !MG_GET(pxt->ori,iq) ) MG_CLR(pxt1->ori,voyq); + /* update tags for edges */ MMG3D_update_edgeTag(pt,pxt,nq,np,iq,pt1,pxt1,voyq); @@ -1179,7 +1184,8 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in } } else { - /* Only the values corresponding to pt become 0 */ + /* pel exist but shell tet doesn't have a boundary tetra: only the + * values of qel corresponding to pt become 0 */ if ( pt1->xt > 0 ) { pxt1 = &mesh->xtetra[pt1->xt]; pxt1->ref[voyq] = 0; @@ -1190,6 +1196,7 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in } } else { + /* pel==0: No adjacent through face iq */ assert(pt->xt); pxt = &mesh->xtetra[pt->xt]; if ( qel ) { From cb046a64dfe5f3cbe4ab12e50fa0a9026066b8de Mon Sep 17 00:00:00 2001 From: Algiane Date: Fri, 16 Jul 2021 15:14:05 +0200 Subject: [PATCH 105/170] Add the update of edges tags of the tetra of the shell during vertex collapse. --- src/mmg3d/colver_3d.c | 74 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/src/mmg3d/colver_3d.c b/src/mmg3d/colver_3d.c index 1d6e1aa98..e04c7a0c4 100644 --- a/src/mmg3d/colver_3d.c +++ b/src/mmg3d/colver_3d.c @@ -913,6 +913,20 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in memset( p0_c,0x00,ilist*sizeof(int) ); memset( p1_c,0x00,ilist*sizeof(int) ); + /* coledge[i] contains the local indices of edges that will be merged by the + * collapse corresponding with the configuration i. The edge coledge[i][0] is + * merged with the edge coledge[i][1] a,d the edge coledge[i][2] is merged + * with edge coledge[i][3]. + * Config 0: merge of vertices 0 and 1 + * config 1: merge of vertices 0 and 2 + * config 2: merge of vertices 0 and 3 + * config 3: merge of vertices 1 and 2 + * config 4: merge of vertices 1 and 3 + * config 5: merge of vertices 2 and 3 + */ + const int8_t MMG5_coledge[6][4] = { + {1,2,2,4}, {0,3,2,5}, {0,4,1,5},{0,1,4,5}, {0,2,3,5}, {4,3,2,1} }; + iel = list[0] / 4; ip = list[0] % 4; pt = &mesh->tetra[iel]; @@ -1023,13 +1037,69 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in ip = (-list[k]) % 4; pt = &mesh->tetra[iel]; - iq = ip; + iq = MMG5_inxt3[ip]; for (j=0; j<3; j++) { - iq = MMG5_inxt3[iq]; if ( pt->v[iq] == nq ) break; + iq = MMG5_inxt3[iq]; } assert(j<3); + if ( pt->xt ) { + pxt = &mesh->xtetra[pt->xt]; + /* If shell tetra has a xtetra, update tags of edges that will be merged */ + /* The configuration is computed by setting the ip and iq bits to 1 */ + int8_t cfg = 0; + MG_SET(cfg,ip); + MG_SET(cfg,iq); + + const int8_t *coled; + switch(cfg) { + case 3: + /* collapse of vertices 0 and 1 */ + coled = MMG5_coledge[0]; + break; + case 5: + /* collapse of vertices 0 and 2 */ + coled = MMG5_coledge[1]; + break; + case 9: + /* collapse of vertices 0 and 3 */ + coled = MMG5_coledge[2]; + break; + case 6: + /* collapse of vertices 1 and 2 */ + coled = MMG5_coledge[3]; + break; + case 10: + /* collapse of vertices 1 and 3 */ + coled = MMG5_coledge[4]; + break; + case 12: + /* collapse of vertices 2 and 3 */ + coled = MMG5_coledge[5]; + break; + default: + assert ( 0 && "Unexpected collapse configuration"); + } + + j = 0; + for ( j=0; j<3; j+=2 ) { + /* when j=0 we update 2 edges that will be merged together, when j=2 we + * update the two others */ + int ia1 = coled[j+0]; + int ia2 = coled[j+1]; + if ( pxt->edg[ia1] > pxt->edg[ia2] ) { + pxt->edg[ia2] = pxt->edg[ia1]; + } + else { + pxt->edg[ia1] = pxt->edg[ia2]; + } + + pxt->tag[ia1] |= pxt->tag[ia2]; + pxt->tag[ia2] |= pxt->tag[ia1]; + } + } + adja = &mesh->adja[4*(iel-1)+1]; /* pel = neighbour of iel that belongs to ball of p \setminus shell, same for qel */ From f5a2507a0914d0a0330f022611af63701a177630 Mon Sep 17 00:00:00 2001 From: Algiane Date: Fri, 16 Jul 2021 16:39:01 +0200 Subject: [PATCH 106/170] Add MMG2D_defaultValues wrapper + remove useless prototypes. --- src/mmg2d/libmmg2d.h | 15 +++++++++++++++ src/mmg2d/libmmg2d_tools.c | 16 ++++++++++++++++ src/mmg2d/mmg2d.c | 18 +----------------- src/mmg3d/mmg3d.h | 1 - src/mmgs/mmgs.h | 1 - 5 files changed, 32 insertions(+), 19 deletions(-) diff --git a/src/mmg2d/libmmg2d.h b/src/mmg2d/libmmg2d.h index c39414153..5a6b9d338 100644 --- a/src/mmg2d/libmmg2d.h +++ b/src/mmg2d/libmmg2d.h @@ -1959,6 +1959,21 @@ int MMG2D_loadVtkMesh_and_allData(MMG5_pMesh mesh,MMG5_pSol *sol,const char *fil /* Tools for the library */ // void (*MMG2D_callbackinsert) (int ,int ,int ,int, int); +/** + * \param mesh pointer toward the mesh structure. + * \return 0 if fail, 1 if success. + * + * Print the default parameters values. + * + * \remark Fortran interface: + * > SUBROUTINE MMG2D_DEFAULTVALUES(mesh,retval)\n + * > MMG5_DATA_PTR_T, INTENT(INOUT) :: mesh\n + * > INTEGER, INTENT(OUT) :: retval\n + * > END SUBROUTINE\n + * + */ + int MMG2D_defaultValues(MMG5_pMesh mesh); + /** * \param mesh pointer toward the mesh structure * \param met pointer toward the sol structure diff --git a/src/mmg2d/libmmg2d_tools.c b/src/mmg2d/libmmg2d_tools.c index 5d00a0b77..34c55ae15 100644 --- a/src/mmg2d/libmmg2d_tools.c +++ b/src/mmg2d/libmmg2d_tools.c @@ -56,6 +56,22 @@ void MMG2D_setfunc(MMG5_pMesh mesh,MMG5_pSol met) { return; } +/** + * \param mesh pointer toward the mesh structure. + * \return 0 if fail, 1 if success. + * + * Print the default parameters values. + * + */ +int MMG2D_defaultValues(MMG5_pMesh mesh) { + + MMG5_mmgDefaultValues(mesh); + + fprintf(stdout,"\n\n"); + + return 1; +} + /** * \param mesh pointer toward the mesh * \param met pointer toward the metric diff --git a/src/mmg2d/mmg2d.c b/src/mmg2d/mmg2d.c index e49df4eeb..b24ab297a 100644 --- a/src/mmg2d/mmg2d.c +++ b/src/mmg2d/mmg2d.c @@ -68,22 +68,6 @@ static int MMG2D_usage(char *name) { return 1; } -/** - * \param mesh pointer toward the mesh structure. - * \return 0 if fail, 1 if success. - * - * Print the default parameters values. - * - */ -static inline int MMG5_defaultValues(MMG5_pMesh mesh) { - - MMG5_mmgDefaultValues(mesh); - - fprintf(stdout,"\n\n"); - - return 1; -} - /** * \param mesh pointer toward the mesh structure. * \param bdyRefs pointer toward the list of the boundary references. @@ -331,7 +315,7 @@ int parsar(int argc,char *argv[],MMG5_pMesh mesh,MMG5_pSol met,MMG5_pSol sol) { /* First step: search if user want to see the default parameters values. */ for ( i=1; i< argc; ++i ) { if ( !strcmp(argv[i],"-val") ) { - MMG5_defaultValues(mesh); + MMG2D_defaultValues(mesh); return 0; } } diff --git a/src/mmg3d/mmg3d.h b/src/mmg3d/mmg3d.h index 1370a981f..8ce0b2f06 100644 --- a/src/mmg3d/mmg3d.h +++ b/src/mmg3d/mmg3d.h @@ -425,7 +425,6 @@ void MMG3D_computeLESqua(MMG5_pMesh,MMG5_pSol,int*,double*,double*,double*,int*, int MMG3D_computePrilen(MMG5_pMesh,MMG5_pSol,double*,double*,double*,int*,int*,int*, int*,int*,int*,int8_t,double**, int [9] ); int MMG3D_prilen(MMG5_pMesh mesh,MMG5_pSol met,int8_t); -void MMG5_defaultValues(MMG5_pMesh); int MMG5_intridmet(MMG5_pMesh,MMG5_pSol,int,int,double,double*,double*); int MMG5_intregmet(MMG5_pMesh,MMG5_pSol,int,int8_t,double, double*); int MMG5_intvolmet(MMG5_pMesh,MMG5_pSol,int,int8_t,double, double*); diff --git a/src/mmgs/mmgs.h b/src/mmgs/mmgs.h index 91f04f2ab..10ba4597e 100644 --- a/src/mmgs/mmgs.h +++ b/src/mmgs/mmgs.h @@ -193,7 +193,6 @@ double caleltsig_ani(MMG5_pMesh mesh,MMG5_pSol met,int iel); double caleltsig_iso(MMG5_pMesh mesh,MMG5_pSol met,int iel); int MMGS_defsiz_iso(MMG5_pMesh mesh,MMG5_pSol met); int MMGS_defsiz_ani(MMG5_pMesh mesh,MMG5_pSol met); -void MMG5_defaultValues(MMG5_pMesh); int MMGS_gradsiz_ani(MMG5_pMesh mesh,MMG5_pSol met); int MMGS_gradsizreq_ani(MMG5_pMesh mesh,MMG5_pSol met); int intmet_iso(MMG5_pMesh mesh,MMG5_pSol met,int k,int8_t i,int ip,double s); From b97c04c29859c472652621ce202481421f3ee173 Mon Sep 17 00:00:00 2001 From: Algiane Date: Mon, 19 Jul 2021 15:30:26 +0200 Subject: [PATCH 107/170] New way to update edge info in colver. --- src/mmg3d/chkmsh_3d.c | 123 +++++++++++ src/mmg3d/colver_3d.c | 493 +++++++++++++++++++++++++++++++----------- src/mmg3d/mmg3d.h | 1 + src/mmg3d/mmg3d1.c | 4 +- src/mmg3d/mmg3d2.c | 2 +- 5 files changed, 489 insertions(+), 134 deletions(-) diff --git a/src/mmg3d/chkmsh_3d.c b/src/mmg3d/chkmsh_3d.c index bce124d6c..dfb3e686d 100644 --- a/src/mmg3d/chkmsh_3d.c +++ b/src/mmg3d/chkmsh_3d.c @@ -70,6 +70,129 @@ void MMG5_chkvol(MMG5_pMesh mesh) { #endif } +/** + * \param mesh pointer toward the mesh + * \param start tetra from which we start to travel + * \param na edge vertex + * \param nb edge vertex + * \param tag edge tag + * \param ref edge ref + * \param piv global index of the pivot to set the sense of travel + * \param adj index of adjacent tetra for the travel + * + * \return -1 if fail, \a start if shell has been completely travelled, 0 + * otherwise (open shell). + * + * Test consistency of tag and ref of the edge \a na \a nb from tetra \a start + * by traveling its shell in one direction (given by the pivot \a piv). + * + */ +static inline +int MMG3D_chk_shellEdgeTag_oneDir(MMG5_pMesh mesh,int start, int na, int nb, + int16_t tag,int ref, int piv,int adj) { + MMG5_pTetra pt; + MMG5_pxTetra pxt; + int *adja; + int16_t xtag; + int8_t i; + + /* Remove the BDY tag as it may be non consistent */ + tag &= ~MG_BDY; + + while ( adj && (adj != start) ) { + pt = &mesh->tetra[adj]; + + /* identification of edge number in tetra adj */ + if ( !MMG3D_findEdge(mesh,pt,adj,na,nb,1,NULL,&i) ) return -1; + + /* update edge ref and tag */ + if ( pt->xt ) { + pxt = &mesh->xtetra[pt->xt]; + xtag = (pxt->tag[i] & ~MG_BDY); + assert (xtag == tag && "non consistent tags"); + assert (pxt->edg[i] == ref && "non consistent refs"); + } + + /* set new triangle for travel */ + adja = &mesh->adja[4*(adj-1)+1]; + if ( pt->v[ MMG5_ifar[i][0] ] == piv ) { + adj = adja[ MMG5_ifar[i][0] ] / 4; + piv = pt->v[ MMG5_ifar[i][1] ]; + } + else { + adj = adja[ MMG5_ifar[i][1] ] /4; + piv = pt->v[ MMG5_ifar[i][0] ]; + } + } + + return adj; +} + +/** + * \param mesh pointer toward the mesh + * \param start tetra from which we start to travel + * \param ia local index of edge that must be updated + * \param tag edge tag + * \param ref edge ref + * \return 1 if success, 0 if fail. + * + * Test consistency of tag and ref of the edge \ia of tetra \a start by + * traveling its shell. + * + */ +int MMG3D_chk_shellEdgeTag(MMG5_pMesh mesh,int start, int8_t ia,int16_t tag,int ref) { + MMG5_pTetra pt; + MMG5_pxTetra pxt; + int piv,na,nb,adj,*adja; + int16_t xtag; + + pt = &mesh->tetra[start]; + + assert( start >= 1 && MG_EOK(pt) ); + + pxt = NULL; + na = pt->v[MMG5_iare[ia][0]]; + nb = pt->v[MMG5_iare[ia][1]]; + + /* Remove the BDY tag as it may be non consistent */ + tag &= ~MG_BDY; + + if ( pt->xt ) { + pxt = &mesh->xtetra[pt->xt]; + /* Remove the BDY tag as it may be non consistent */ + xtag = (pxt->tag[ia] & ~MG_BDY); + assert (xtag == tag && "non consistent tags"); ; + assert (pxt->edg[ia] == ref && "non consistent refs"); ; + } + + /* Travel in one direction */ + adja = &mesh->adja[4*(start-1)+1]; + adj = adja[MMG5_ifar[ia][0]] / 4; + piv = pt->v[MMG5_ifar[ia][1]]; + + adj = MMG3D_chk_shellEdgeTag_oneDir(mesh,start,na,nb,tag,ref,piv,adj); + + /* If all shell has been travelled, stop, else, travel it the other sense */ + if ( adj > 0 ) { + assert ( adj == start ); + return 1; + } + else if ( adj < 0 ) return 0; + + assert(!adj); + + pt = &mesh->tetra[start]; + adja = &mesh->adja[4*(start-1)+1]; + adj = adja[MMG5_ifar[ia][1]] / 4; + piv = pt->v[MMG5_ifar[ia][0]]; + + adj = MMG3D_chk_shellEdgeTag_oneDir(mesh,start,na,nb,tag,ref,piv,adj); + + if ( adj < 0 ) return 0; + + return 1; +} + /** * \param mesh pointer toward the mesh * diff --git a/src/mmg3d/colver_3d.c b/src/mmg3d/colver_3d.c index e04c7a0c4..d055597c2 100644 --- a/src/mmg3d/colver_3d.c +++ b/src/mmg3d/colver_3d.c @@ -879,6 +879,241 @@ void MMG3D_update_edgeTag(MMG5_pTetra pt,MMG5_pxTetra pxt,int np, int nq, } } +/** + * \param mesh pointer toward the mesh + * \param start tetra from which we start to travel + * \param na edge vertex + * \param nb edge vertex + * \param tag new edge tag + * \param ref new edge ref + * \param piv global index of the pivot to set the sense of travel + * \param adj index of adjacent tetra for the travel + * + * \return -1 if fail, \a start if shell has been completely travelled, 0 otherwise + * + * Update tag and ref of the edge \a na \a nb from tetra \a start by traveling + * its shell in one direction (given by the pivot \a piv). + * + */ +static inline +int MMG3D_update_shellEdgeTag_oneDir(MMG5_pMesh mesh,int start, int na, int nb, + int16_t tag,int ref, int piv,int adj) { + MMG5_pTetra pt; + MMG5_pxTetra pxt; + int *adja; + int8_t i; + + while ( adj && (adj != start) ) { + pt = &mesh->tetra[adj]; + + /* identification of edge number in tetra adj */ + if ( !MMG3D_findEdge(mesh,pt,adj,na,nb,1,NULL,&i) ) return -1; + + /* update edge ref and tag */ + if ( pt->xt ) { + pxt = &mesh->xtetra[pt->xt]; + pxt->edg[i] = ref; + pxt->tag[i] |= tag; + } + + /* set new triangle for travel */ + adja = &mesh->adja[4*(adj-1)+1]; + if ( pt->v[ MMG5_ifar[i][0] ] == piv ) { + adj = adja[ MMG5_ifar[i][0] ] / 4; + piv = pt->v[ MMG5_ifar[i][1] ]; + } + else { + adj = adja[ MMG5_ifar[i][1] ] /4; + piv = pt->v[ MMG5_ifar[i][0] ]; + } + } + + return adj; +} + +/** + * \param mesh pointer toward the mesh + * \param start tetra from which we start to travel + * \param ia local index of edge that must be updated + * \param tag new edge tag + * \param ref new edge ref + * \return 1 if success, 0 if fail. + * + * Update tag and ref of the edge \ia of tetra \a start by traveling its shell. + * + */ +#warning I think that it is not mandatory to travel the entirely shell if the first met xtetra has the suitable tag +static inline +int MMG3D_update_shellEdgeTag(MMG5_pMesh mesh,int start, int8_t ia,int16_t tag,int ref) { + MMG5_pTetra pt; + MMG5_pxTetra pxt; + int piv,na,nb,adj,*adja; + + pt = &mesh->tetra[start]; + + assert( start >= 1 && MG_EOK(pt) ); + + pxt = NULL; + na = pt->v[MMG5_iare[ia][0]]; + nb = pt->v[MMG5_iare[ia][1]]; + + if ( pt->xt ) { + pxt = &mesh->xtetra[pt->xt]; + pxt->tag[ia] |= tag; + pxt->edg[ia] = ref; + } + + /* Travel in one direction */ + adja = &mesh->adja[4*(start-1)+1]; + adj = adja[MMG5_ifar[ia][0]] / 4; + piv = pt->v[MMG5_ifar[ia][1]]; + + adj = MMG3D_update_shellEdgeTag_oneDir(mesh,start,na,nb,tag,ref,piv,adj); + + /* If all shell has been travelled, stop, else, travel it the other sense */ + if ( adj == start ) return 1; + else if ( adj < 0 ) return 0; + + assert(!adj); + + pt = &mesh->tetra[start]; + adja = &mesh->adja[4*(start-1)+1]; + adj = adja[MMG5_ifar[ia][1]] / 4; + piv = pt->v[MMG5_ifar[ia][0]]; + + adj = MMG3D_update_shellEdgeTag_oneDir(mesh,start,na,nb,tag,ref,piv,adj); + + if ( adj < 0 ) return 0; + + return 1; +} + +/** + * \param mesh pointer toward the mesh + * \param start tetra from which we start to travel + * \param na edge vertex + * \param nb edge vertex + * \param tag new edge tag + * \param ref new edge ref + * \param piv global index of the pivot to set the sense of travel + * \param adj index of adjacent tetra for the travel + * \param filled 1 if an xtetra has been found (so tag and ref are filled) + * + * \return -1 if fail, \a start if shell has been completely travelled without + * founding an xtetra, adj if an xtetra has been found, 0 otherwise + * + * Get tag and ref of the edge \a na \a nb from tetra \a start by traveling + * its shell in one direction (given by the pivot \a piv). + * Stop when meeting the first xtetra (it is sufficient if tags and refs are + * consistent through the edge shell); + * + */ +static inline +int MMG3D_get_shellEdgeTag_oneDir(MMG5_pMesh mesh,int start, int na, int nb, + int16_t *tag,int *ref, int piv,int adj, + int8_t *filled) { + MMG5_pTetra pt; + MMG5_pxTetra pxt; + int *adja; + int8_t i; + + *filled = 0; + while ( adj && (adj != start) ) { + pt = &mesh->tetra[adj]; + + /* identification of edge number in tetra adj */ + if ( !MMG3D_findEdge(mesh,pt,adj,na,nb,1,NULL,&i) ) return -1; + + /* update edge ref and tag */ + if ( pt->xt ) { + pxt = &mesh->xtetra[pt->xt]; + *ref = pxt->edg[i]; + *tag |= pxt->tag[i]; + *filled = 1; +#warning to test + //return adj; + } + + /* set new triangle for travel */ + adja = &mesh->adja[4*(adj-1)+1]; + if ( pt->v[ MMG5_ifar[i][0] ] == piv ) { + adj = adja[ MMG5_ifar[i][0] ] / 4; + piv = pt->v[ MMG5_ifar[i][1] ]; + } + else { + adj = adja[ MMG5_ifar[i][1] ] /4; + piv = pt->v[ MMG5_ifar[i][0] ]; + } + } + + return adj; +} + +/** + * \param mesh pointer toward the mesh + * \param start tetra from which we start to travel + * \param ia local index of edge that must be updated + * \param tag new edge tag + * \param ref new edge ref + * \return 1 if success, 0 if fail. + * + * Get tag and ref of the edge \ia of tetra \a start by traveling its shell. + * Stop when meeting the first xtetra (it is sufficient if tags and refs are + * consistent through the edge shell); + * + */ +static inline +int MMG3D_get_shellEdgeTag(MMG5_pMesh mesh,int start, int8_t ia,int16_t *tag,int *ref) { + MMG5_pTetra pt; + MMG5_pxTetra pxt; + int piv,na,nb,adj,*adja; + int8_t filled; + + pt = &mesh->tetra[start]; + + assert( start >= 1 && MG_EOK(pt) ); + + pxt = NULL; + na = pt->v[MMG5_iare[ia][0]]; + nb = pt->v[MMG5_iare[ia][1]]; + + if ( pt->xt ) { + pxt = &mesh->xtetra[pt->xt]; + *tag |= pxt->tag[ia]; + *ref = pxt->edg[ia]; +#warning to test + //return 1; + } + + /* Travel in one direction */ + adja = &mesh->adja[4*(start-1)+1]; + adj = adja[MMG5_ifar[ia][0]] / 4; + piv = pt->v[MMG5_ifar[ia][1]]; + + adj = MMG3D_get_shellEdgeTag_oneDir(mesh,start,na,nb,tag,ref,piv,adj,&filled); + + /* If an xtetra has been found or if all shell has been travelled, stop, else, + * travel it the other sense */ + if ( adj > 0 ) { + assert ( (adj == start) || filled ); + return 1; + } + else if ( adj < 0 ) return 0; + + assert(!adj); + + pt = &mesh->tetra[start]; + adja = &mesh->adja[4*(start-1)+1]; + adj = adja[MMG5_ifar[ia][1]] / 4; + piv = pt->v[MMG5_ifar[ia][0]]; + + adj = MMG3D_get_shellEdgeTag_oneDir(mesh,start,na,nb,tag,ref,piv,adj,&filled); + + if ( adj < 0 ) return 0; + + return 1; +} + /** * \param mesh pointer toward the mesh * \param met pointer toward the metric @@ -899,19 +1134,15 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in MMG5_pTetra pt,pt1; MMG5_pxTetra pxt,pxt1; MMG5_xTetra xt,xts; - int i,iel,jel,pel,qel,k,np,nq,*adja; - uint8_t ip,iq,j,voy,voyp,voyq,ia; - uint8_t (ind)[MMG3D_LMAX][2]; - int p0_c[MMG3D_LMAX],p1_c[MMG3D_LMAX]; - int8_t indar[4][4][2] = { - /* indar[ip][iq][0/1]: indices of edges which have iq for extremity but not ip*/ - { {-1,-1}, { 3, 4}, { 3, 5}, { 4, 5} }, - { { 1, 2}, {-1,-1}, { 1, 5}, { 2, 5} }, - { { 0, 2}, { 0, 4}, {-1,-1}, { 2, 4} }, - { { 0, 1}, { 0, 3}, { 1, 3}, {-1,-1} } }; - - memset( p0_c,0x00,ilist*sizeof(int) ); - memset( p1_c,0x00,ilist*sizeof(int) ); + int iel,jel,pel,qel,k,np,nq,*adja; + uint8_t ip,iq,j,voy,voyp,voyq; + +#ifndef NDEBUG + if ( mesh->info.ddebug ) { + MMG3D_chkmeshedgestags(mesh); + MMG3D_chkpointtag(mesh); + } +#endif /* coledge[i] contains the local indices of edges that will be merged by the * collapse corresponding with the configuration i. The edge coledge[i][0] is @@ -925,7 +1156,7 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in * config 5: merge of vertices 2 and 3 */ const int8_t MMG5_coledge[6][4] = { - {1,2,2,4}, {0,3,2,5}, {0,4,1,5},{0,1,4,5}, {0,2,3,5}, {4,3,2,1} }; + {1,3,2,4}, {0,3,2,5}, {0,4,1,5},{0,1,4,5}, {0,2,3,5}, {4,3,2,1} }; iel = list[0] / 4; ip = list[0] % 4; @@ -936,31 +1167,12 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in /* Mark elements of the shell of edge (pq) */ for (k=0; ktetra[iel]; for (j=0; j<3; j++) { - i = MMG5_inxt3[i]; - if ( pt->v[i] == nq ) { - /* In each tetra of the shell, 2 edges coming from np will be merged - * with 2 edges coming from nq: list the local indices of the edges - * comig from nq (ind array) and store the global indices of the non nq - * vertices of these edges if they are tagged (so edges np-p0_c and - * np-p1_c must be updated in all tetra) */ - if ( pt->xt ) { - pxt = &mesh->xtetra[pt->xt]; - ip = list[k]%4; - ind[k][0] = indar[ip][i][0]; - if ( pxt->tag[ind[k][0]] || pxt->edg[ind[k][0]] ) { - if ( MMG5_iare[ind[k][0]][0]==i ) p0_c[k] = pt->v[MMG5_iare[ind[k][0]][1]]; - else p0_c[k] = pt->v[MMG5_iare[ind[k][0]][0]]; - } - ind[k][1] = indar[ip][i][1]; - if ( pxt->tag[ind[k][1]] || pxt->edg[ind[k][1]] ) { - if ( MMG5_iare[ind[k][1]][0]==i ) p1_c[k] = pt->v[MMG5_iare[ind[k][1]][1]]; - else p1_c[k] = pt->v[MMG5_iare[ind[k][1]][0]]; - } - } + iq = MMG5_idir[ip][j]; + if ( pt->v[iq] == nq ) { list[k] *= -1; break; } @@ -978,46 +1190,6 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in ip = list[k] % 4; pt = &mesh->tetra[iel]; - /* update edges ip-p0_c and ip-p1_c in elts of the ball of ip but that do - * not belong to the shell of pq */ - if ( !pt->xt ) { - continue; - } - pxt = &mesh->xtetra[pt->xt]; - for ( i=0; i0) || (!(mesh->tetra[-list[i]/4].xt)) ) continue; - pt1 = &mesh->tetra[-list[i]/4]; - pxt1 = &mesh->xtetra[pt1->xt]; - if ( p0_c[i] ) { - /* edge nq-p0_c has a tag in the ith tetra of the shell, update - * np-p0_c */ - for ( j=0; j<3; j++) { - ia = MMG5_idir[ip][j]; - if ( pt->v[ia]==p0_c[i] ) { - pxt->tag[MMG5_arpt[ip][j]] |= pxt1->tag[ind[i][0]]; - if ( !pxt->edg[MMG5_arpt[ip][j]] ) - pxt->edg[MMG5_arpt[ip][j]] = pxt1->edg[ind[i][0]]; - else if ( pxt1->edg[ind[i][0]] ) - pxt->edg[MMG5_arpt[ip][j]] = - MG_MAX(pxt->edg[MMG5_arpt[ip][j]],pxt1->edg[ind[i][0]]); - break; - } - } - } - if ( p1_c[i] ) { - /* edge nq-p1_c has a tag in the ith tetra of the shell, update - * np-p1_c */ - for ( j=0; j<3; j++) { - ia = MMG5_idir[ip][j]; - if ( pt->v[ia]==p1_c[i] ) { - pxt->tag[MMG5_arpt[ip][j]] |= pxt1->tag[ind[i][1]]; - pxt->edg[MMG5_arpt[ip][j]] = - MG_MAX(pxt->edg[MMG5_arpt[ip][j]],pxt1->edg[ind[i][1]]); - break; - } - } - } - } adja = &mesh->adja[4*(iel-1)+1]; jel = adja[ip]; if ( !jel ) continue; @@ -1030,6 +1202,113 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in } } + /** Merge tags and references of edges that will merge due to the collapse + * (the shell of each edge is travelled so each xtetra of the shell is + * updated). Note that it can't be done in the previous loop because the mesh + * would be corrupted if we stop the collapse. It can't neither be done in the + * next loop because we start to delete the elements of the shell. */ + for (k=0; k 0 ) continue; + + iel = -list[k] / 4; + ip = -list[k] % 4; + pt = &mesh->tetra[iel]; + + for (j=0; j<3; j++) { + iq = MMG5_idir[ip][j]; + if ( pt->v[iq] == nq ) { + break; + } + } + + /* The configuration is computed by setting the ip and iq bits to 1 */ + int8_t cfg = 0; + MG_SET(cfg,ip); + MG_SET(cfg,iq); + + const int8_t *coled; + switch(cfg) { + case 3: + /* collapse of vertices 0 and 1 */ + coled = MMG5_coledge[0]; + break; + case 5: + /* collapse of vertices 0 and 2 */ + coled = MMG5_coledge[1]; + break; + case 9: + /* collapse of vertices 0 and 3 */ + coled = MMG5_coledge[2]; + break; + case 6: + /* collapse of vertices 1 and 2 */ + coled = MMG5_coledge[3]; + break; + case 10: + /* collapse of vertices 1 and 3 */ + coled = MMG5_coledge[4]; + break; + case 12: + /* collapse of vertices 2 and 3 */ + coled = MMG5_coledge[5]; + break; + default: + assert ( 0 && "Unexpected collapse configuration"); + } + + int l = 0; + for ( l=0; l<3; l+=2 ) { + /* when l=0 we update 2 edges that will be merged together, when l=2 we + * update the two others. In practice we don't care which edge comes + * from ip and which one from iq, it only matters that iped and iqed + * will be merged at the end of the collapse. */ + int iped = coled[l+0]; + int iqed = coled[l+1]; + + int16_t tagip = 0; + int refip = 0; + int16_t tagiq = 0; + int refiq = 0; + + if ( !MMG3D_get_shellEdgeTag(mesh,iel,iped,&tagip,&refip) ) { + fprintf(stderr,"\n ## Error: %s: 1. unable to get edge info.\n",__func__); + return 0; + } + if ( !MMG3D_get_shellEdgeTag(mesh,iel,iqed,&tagiq,&refiq) ) { + fprintf(stderr,"\n ## Error: %s: 2. unable to get edge info.\n",__func__); + return 0; + } + + if ( (tagip != tagiq) || (refip != refiq) ) { + /* Update edge infos */ + tagip |= tagiq; + refip = (refip > refiq )? refip : refiq; + + /* If the xtetra info are consistent when entering in colver taged and + * refed contains suitable values and we can travel the shell of + * iped and iqed to update all the needed info on edges */ + if ( !MMG3D_update_shellEdgeTag(mesh,iel,iped,tagip,refip) ) { + fprintf(stderr,"\n ## Error: %s: 1. unable to update edge info.\n",__func__); + return 0; + } + if ( !MMG3D_update_shellEdgeTag(mesh,iel,iqed,tagip,refip) ) { + fprintf(stderr,"\n ## Error: %s: 1. unable to update edge info.\n",__func__); + return 0; + } + } +#ifndef NDEBUG + else { + assert ( tagip == tagiq && refip == refiq ); + if ( mesh->info.ddebug ) { + MMG3D_chk_shellEdgeTag(mesh,iel,iped,tagip,refip); + MMG3D_chk_shellEdgeTag(mesh,iel,iqed,tagip,refip); + } + } +#endif + } + } + /* deal with the shell of edge (pq) and the implied updates */ for (k=0; k 0 ) continue; @@ -1044,61 +1323,6 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in } assert(j<3); - if ( pt->xt ) { - pxt = &mesh->xtetra[pt->xt]; - /* If shell tetra has a xtetra, update tags of edges that will be merged */ - /* The configuration is computed by setting the ip and iq bits to 1 */ - int8_t cfg = 0; - MG_SET(cfg,ip); - MG_SET(cfg,iq); - - const int8_t *coled; - switch(cfg) { - case 3: - /* collapse of vertices 0 and 1 */ - coled = MMG5_coledge[0]; - break; - case 5: - /* collapse of vertices 0 and 2 */ - coled = MMG5_coledge[1]; - break; - case 9: - /* collapse of vertices 0 and 3 */ - coled = MMG5_coledge[2]; - break; - case 6: - /* collapse of vertices 1 and 2 */ - coled = MMG5_coledge[3]; - break; - case 10: - /* collapse of vertices 1 and 3 */ - coled = MMG5_coledge[4]; - break; - case 12: - /* collapse of vertices 2 and 3 */ - coled = MMG5_coledge[5]; - break; - default: - assert ( 0 && "Unexpected collapse configuration"); - } - - j = 0; - for ( j=0; j<3; j+=2 ) { - /* when j=0 we update 2 edges that will be merged together, when j=2 we - * update the two others */ - int ia1 = coled[j+0]; - int ia2 = coled[j+1]; - if ( pxt->edg[ia1] > pxt->edg[ia2] ) { - pxt->edg[ia2] = pxt->edg[ia1]; - } - else { - pxt->edg[ia1] = pxt->edg[ia2]; - } - - pxt->tag[ia1] |= pxt->tag[ia2]; - pxt->tag[ia2] |= pxt->tag[ia1]; - } - } adja = &mesh->adja[4*(iel-1)+1]; @@ -1316,5 +1540,12 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in pt->mark=mesh->mark; } +#ifndef NDEBUG + if ( mesh->info.ddebug ) { + MMG3D_chkmeshedgestags(mesh); + MMG3D_chkpointtag(mesh); + } +#endif + return np; } diff --git a/src/mmg3d/mmg3d.h b/src/mmg3d/mmg3d.h index 0de946e07..6afc1727e 100644 --- a/src/mmg3d/mmg3d.h +++ b/src/mmg3d/mmg3d.h @@ -458,6 +458,7 @@ int MMG3D_indPt(MMG5_pMesh mesh,int kp); void MMG5_printTetra(MMG5_pMesh mesh,char* fileName); void MMG3D_chkpointtag(MMG5_pMesh mesh); void MMG3D_chkmeshedgestags(MMG5_pMesh mesh); +int MMG3D_chk_shellEdgeTag(MMG5_pMesh mesh,int start, int8_t ia,int16_t tag,int ref); #ifdef USE_SCOTCH int MMG5_mmg3dRenumbering(int,MMG5_pMesh,MMG5_pSol,MMG5_pSol,int*); diff --git a/src/mmg3d/mmg3d1.c b/src/mmg3d/mmg3d1.c index 3aaa1ce6d..c1cf75ddd 100644 --- a/src/mmg3d/mmg3d1.c +++ b/src/mmg3d/mmg3d1.c @@ -459,7 +459,7 @@ int8_t MMG5_chkedg(MMG5_pMesh mesh,MMG5_Tria *pt,int8_t ori, double hmax, if ( !mmgWarn0 ) { fprintf(stderr,"\n ## Warning: %s: a- at least 1 geometrical" " problem: non consistency between point tag (%d) and" - " edge tag (%d.)\n",__func__,p[i1]->tag,pt->tag[i]); + " edge tag (%d).\n",__func__,p[i1]->tag,pt->tag[i]); mmgWarn0 = 1; } return -1; @@ -482,7 +482,7 @@ int8_t MMG5_chkedg(MMG5_pMesh mesh,MMG5_Tria *pt,int8_t ori, double hmax, if ( !mmgWarn1 ) { fprintf(stderr,"\n ## Warning: %s: b- at least 1 geometrical" " problem: non consistency between point tag (%d) and" - " edge tag (%d.)\n",__func__,p[i2]->tag,pt->tag[i]); + " edge tag (%d).\n",__func__,p[i2]->tag,pt->tag[i]); mmgWarn1 = 1; } return -1; diff --git a/src/mmg3d/mmg3d2.c b/src/mmg3d/mmg3d2.c index c0d654a49..8cc5dd851 100755 --- a/src/mmg3d/mmg3d2.c +++ b/src/mmg3d/mmg3d2.c @@ -1436,7 +1436,7 @@ int MMG5_chkmaniball(MMG5_pMesh mesh, int start, int8_t ip){ k1 /= 4; pt1 = &mesh->tetra[k1]; - if( pt1 ->ref != ref ) continue; + if( pt1->ref != ref ) continue; if( pt1->flag == base ) continue; pt1->flag = base; From 1d784a56a3af809798a6f08375fc2aa46140681a Mon Sep 17 00:00:00 2001 From: Algiane Date: Mon, 19 Jul 2021 15:37:02 +0200 Subject: [PATCH 108/170] For now, perform exhaustive consistency tests. --- src/mmg3d/colver_3d.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/mmg3d/colver_3d.c b/src/mmg3d/colver_3d.c index d055597c2..a81d3a8fd 100644 --- a/src/mmg3d/colver_3d.c +++ b/src/mmg3d/colver_3d.c @@ -1138,10 +1138,10 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in uint8_t ip,iq,j,voy,voyp,voyq; #ifndef NDEBUG - if ( mesh->info.ddebug ) { + //if ( mesh->info.ddebug ) { MMG3D_chkmeshedgestags(mesh); MMG3D_chkpointtag(mesh); - } + //} #endif /* coledge[i] contains the local indices of edges that will be merged by the @@ -1371,7 +1371,6 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in MG_CLR( pxt1->ori,voyp ); } - #ifndef NDEBUG else { /* Check that a non parallel external boundary face has always a good @@ -1541,10 +1540,10 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in } #ifndef NDEBUG - if ( mesh->info.ddebug ) { + //if ( mesh->info.ddebug ) { MMG3D_chkmeshedgestags(mesh); MMG3D_chkpointtag(mesh); - } + //} #endif return np; From 66e71d3b9284eda8234c4417f4688a0e5afc5c51 Mon Sep 17 00:00:00 2001 From: Algiane Date: Mon, 19 Jul 2021 15:45:23 +0200 Subject: [PATCH 109/170] Do not test the entire edge shell when getting the edge tag (stop at the first met xtetra. --- src/mmg3d/colver_3d.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/mmg3d/colver_3d.c b/src/mmg3d/colver_3d.c index a81d3a8fd..f22822d0d 100644 --- a/src/mmg3d/colver_3d.c +++ b/src/mmg3d/colver_3d.c @@ -1030,8 +1030,7 @@ int MMG3D_get_shellEdgeTag_oneDir(MMG5_pMesh mesh,int start, int na, int nb, *ref = pxt->edg[i]; *tag |= pxt->tag[i]; *filled = 1; -#warning to test - //return adj; + return adj; } /* set new triangle for travel */ @@ -1081,8 +1080,7 @@ int MMG3D_get_shellEdgeTag(MMG5_pMesh mesh,int start, int8_t ia,int16_t *tag,in pxt = &mesh->xtetra[pt->xt]; *tag |= pxt->tag[ia]; *ref = pxt->edg[ia]; -#warning to test - //return 1; + return 1; } /* Travel in one direction */ From 8b519a347cb5b0a936929345da1d6f25d32dbad8 Mon Sep 17 00:00:00 2001 From: Algiane Date: Mon, 19 Jul 2021 15:54:10 +0200 Subject: [PATCH 110/170] Update entire shell only if non consistency has been detected in the first met xtetra. --- src/mmg3d/colver_3d.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/mmg3d/colver_3d.c b/src/mmg3d/colver_3d.c index f22822d0d..dff61c119 100644 --- a/src/mmg3d/colver_3d.c +++ b/src/mmg3d/colver_3d.c @@ -901,6 +901,7 @@ int MMG3D_update_shellEdgeTag_oneDir(MMG5_pMesh mesh,int start, int na, int nb, MMG5_pTetra pt; MMG5_pxTetra pxt; int *adja; + int16_t xtag,atag; int8_t i; while ( adj && (adj != start) ) { @@ -912,6 +913,16 @@ int MMG3D_update_shellEdgeTag_oneDir(MMG5_pMesh mesh,int start, int na, int nb, /* update edge ref and tag */ if ( pt->xt ) { pxt = &mesh->xtetra[pt->xt]; + + /* if tag and edge are already consistent, non need to update the shell (do + * not consider the MG_BDY tag) */ + xtag = pxt->tag[i] & ~MG_BDY; + atag = tag & ~MG_BDY; + + if ( xtag == atag && pxt->edg[i] == ref ) { + return start; + } + pxt->edg[i] = ref; pxt->tag[i] |= tag; } @@ -942,12 +953,12 @@ int MMG3D_update_shellEdgeTag_oneDir(MMG5_pMesh mesh,int start, int na, int nb, * Update tag and ref of the edge \ia of tetra \a start by traveling its shell. * */ -#warning I think that it is not mandatory to travel the entirely shell if the first met xtetra has the suitable tag static inline int MMG3D_update_shellEdgeTag(MMG5_pMesh mesh,int start, int8_t ia,int16_t tag,int ref) { MMG5_pTetra pt; MMG5_pxTetra pxt; int piv,na,nb,adj,*adja; + int16_t xtag,atag; pt = &mesh->tetra[start]; @@ -959,6 +970,16 @@ int MMG3D_update_shellEdgeTag(MMG5_pMesh mesh,int start, int8_t ia,int16_t tag, if ( pt->xt ) { pxt = &mesh->xtetra[pt->xt]; + + /* if tag and edge are already consistent, non need to update the shell (do + * not consider the MG_BDY tag) */ + xtag = pxt->tag[ia] & ~MG_BDY; + atag = tag & ~MG_BDY; + + if ( xtag == atag && pxt->edg[ia] == ref ) { + return 1; + } + pxt->tag[ia] |= tag; pxt->edg[ia] = ref; } From d30b167943592b5d693378b256d5ac86bd952ae5 Mon Sep 17 00:00:00 2001 From: Algiane Date: Mon, 19 Jul 2021 17:00:25 +0200 Subject: [PATCH 111/170] Move edge tag check as it is too long to perform. --- src/mmg3d/chkmsh_3d.c | 3 +++ src/mmg3d/colver_3d.c | 14 -------------- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/src/mmg3d/chkmsh_3d.c b/src/mmg3d/chkmsh_3d.c index dfb3e686d..cc2855bc2 100644 --- a/src/mmg3d/chkmsh_3d.c +++ b/src/mmg3d/chkmsh_3d.c @@ -419,6 +419,9 @@ int MMG5_mmg3dChkmsh(MMG5_pMesh mesh,int severe,int base) { uint8_t voy,voy1; static int8_t mmgErr0=0,mmgErr1=0,mmgErr2=0,mmgErr3=0,mmgErr4=0,mmgErr5=0; + MMG3D_chkmeshedgestags(mesh); + MMG3D_chkpointtag(mesh); + for (k=1; k<=mesh->ne; k++) { pt1 = &mesh->tetra[k]; if ( !MG_EOK(pt1) || pt1->ref < 0 ) continue; diff --git a/src/mmg3d/colver_3d.c b/src/mmg3d/colver_3d.c index dff61c119..38eccf0f9 100644 --- a/src/mmg3d/colver_3d.c +++ b/src/mmg3d/colver_3d.c @@ -1156,13 +1156,6 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in int iel,jel,pel,qel,k,np,nq,*adja; uint8_t ip,iq,j,voy,voyp,voyq; -#ifndef NDEBUG - //if ( mesh->info.ddebug ) { - MMG3D_chkmeshedgestags(mesh); - MMG3D_chkpointtag(mesh); - //} -#endif - /* coledge[i] contains the local indices of edges that will be merged by the * collapse corresponding with the configuration i. The edge coledge[i][0] is * merged with the edge coledge[i][1] a,d the edge coledge[i][2] is merged @@ -1558,12 +1551,5 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in pt->mark=mesh->mark; } -#ifndef NDEBUG - //if ( mesh->info.ddebug ) { - MMG3D_chkmeshedgestags(mesh); - MMG3D_chkpointtag(mesh); - //} -#endif - return np; } From f8761351734282bf6bbdca46644bf85067d44a44 Mon Sep 17 00:00:00 2001 From: luca Date: Tue, 20 Jul 2021 10:50:04 +0200 Subject: [PATCH 112/170] Revert "Recognize internal boundaries when traveling the shell of an edge to find non-manifold points (in MMG5_boulenm for MMG3D_nmgeom)." This reverts commit a263872987061c0441aa97e672ec241d31b2af5f. --- src/mmg3d/boulep_3d.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mmg3d/boulep_3d.c b/src/mmg3d/boulep_3d.c index fd5edc515..de6d0b9f8 100644 --- a/src/mmg3d/boulep_3d.c +++ b/src/mmg3d/boulep_3d.c @@ -246,7 +246,7 @@ int MMG5_boulenm(MMG5_pMesh mesh,int start,int ip,int iface, iopp = MMG5_ifar[i][1]; piv = pt->v[ipiv]; } - isface = ((adja[iopp] == 0) || (mesh->tetra[adj].ref != pt->ref)); + isface = (adja[iopp] == 0); } while ( adj && (adj != nvstart) && !isface ); } From cbdde1b09d9eab6cf09c64a43ec72af8c4eed3d7 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 20 Jul 2021 15:08:16 +0200 Subject: [PATCH 113/170] Now consider only MG_BDY edges in colver tests because edges with 0 tags are non consistent with other tags (they are created during collapse when a new xtetra is assign to pel or qel). --- src/mmg3d/chkmsh_3d.c | 30 ++++++++---------- src/mmg3d/colver_3d.c | 71 +++++++++++++++++++++++++++---------------- 2 files changed, 57 insertions(+), 44 deletions(-) diff --git a/src/mmg3d/chkmsh_3d.c b/src/mmg3d/chkmsh_3d.c index cc2855bc2..1b0e3f9e1 100644 --- a/src/mmg3d/chkmsh_3d.c +++ b/src/mmg3d/chkmsh_3d.c @@ -93,12 +93,8 @@ int MMG3D_chk_shellEdgeTag_oneDir(MMG5_pMesh mesh,int start, int na, int nb, MMG5_pTetra pt; MMG5_pxTetra pxt; int *adja; - int16_t xtag; int8_t i; - /* Remove the BDY tag as it may be non consistent */ - tag &= ~MG_BDY; - while ( adj && (adj != start) ) { pt = &mesh->tetra[adj]; @@ -108,9 +104,11 @@ int MMG3D_chk_shellEdgeTag_oneDir(MMG5_pMesh mesh,int start, int na, int nb, /* update edge ref and tag */ if ( pt->xt ) { pxt = &mesh->xtetra[pt->xt]; - xtag = (pxt->tag[i] & ~MG_BDY); - assert (xtag == tag && "non consistent tags"); - assert (pxt->edg[i] == ref && "non consistent refs"); + /* Test only BDY edges */ + if ( pxt->tag[i] & MG_BDY ) { + assert (pxt->tag[i] == tag && "non consistent tags"); + assert (pxt->edg[i] == ref && "non consistent refs"); + } } /* set new triangle for travel */ @@ -136,7 +134,7 @@ int MMG3D_chk_shellEdgeTag_oneDir(MMG5_pMesh mesh,int start, int na, int nb, * \param ref edge ref * \return 1 if success, 0 if fail. * - * Test consistency of tag and ref of the edge \ia of tetra \a start by + * Test consistency of tag and ref of the boundary edge \ia of tetra \a start by * traveling its shell. * */ @@ -144,25 +142,23 @@ int MMG3D_chk_shellEdgeTag(MMG5_pMesh mesh,int start, int8_t ia,int16_t tag,int MMG5_pTetra pt; MMG5_pxTetra pxt; int piv,na,nb,adj,*adja; - int16_t xtag; pt = &mesh->tetra[start]; - assert( start >= 1 && MG_EOK(pt) ); + assert( start >= 1 && MG_EOK(pt) && "invalid tetra" ); + assert ( tag & MG_BDY && "Unexpected non boundary tag"); pxt = NULL; na = pt->v[MMG5_iare[ia][0]]; nb = pt->v[MMG5_iare[ia][1]]; - /* Remove the BDY tag as it may be non consistent */ - tag &= ~MG_BDY; - if ( pt->xt ) { pxt = &mesh->xtetra[pt->xt]; - /* Remove the BDY tag as it may be non consistent */ - xtag = (pxt->tag[ia] & ~MG_BDY); - assert (xtag == tag && "non consistent tags"); ; - assert (pxt->edg[ia] == ref && "non consistent refs"); ; + /* Test only BDY edges */ + if ( pxt->tag[ia] & MG_BDY ) { + assert (pxt->tag[ia] == tag && "non consistent tags"); ; + assert (pxt->edg[ia] == ref && "non consistent refs"); ; + } } /* Travel in one direction */ diff --git a/src/mmg3d/colver_3d.c b/src/mmg3d/colver_3d.c index 38eccf0f9..52a183ece 100644 --- a/src/mmg3d/colver_3d.c +++ b/src/mmg3d/colver_3d.c @@ -901,9 +901,11 @@ int MMG3D_update_shellEdgeTag_oneDir(MMG5_pMesh mesh,int start, int na, int nb, MMG5_pTetra pt; MMG5_pxTetra pxt; int *adja; - int16_t xtag,atag; + int16_t xtag; int8_t i; + assert ( tag & MG_BDY && "Unexpected non boundary tag"); + while ( adj && (adj != start) ) { pt = &mesh->tetra[adj]; @@ -914,13 +916,15 @@ int MMG3D_update_shellEdgeTag_oneDir(MMG5_pMesh mesh,int start, int na, int nb, if ( pt->xt ) { pxt = &mesh->xtetra[pt->xt]; - /* if tag and edge are already consistent, non need to update the shell (do - * not consider the MG_BDY tag) */ - xtag = pxt->tag[i] & ~MG_BDY; - atag = tag & ~MG_BDY; + /* if tag and edge are already consistent, no need to update the shell (do + * not consider edges with tag 0 as they com from the creation of a xtetra + * during a previous collapse and are not updated) */ + xtag = pxt->tag[i] | MG_BDY; - if ( xtag == atag && pxt->edg[i] == ref ) { - return start; + if ( pxt->tag[i] & MG_BDY ) { + if ( xtag == tag && pxt->edg[i] == ref ) { + return start; + } } pxt->edg[i] = ref; @@ -958,11 +962,12 @@ int MMG3D_update_shellEdgeTag(MMG5_pMesh mesh,int start, int8_t ia,int16_t tag, MMG5_pTetra pt; MMG5_pxTetra pxt; int piv,na,nb,adj,*adja; - int16_t xtag,atag; + int16_t xtag; pt = &mesh->tetra[start]; - assert( start >= 1 && MG_EOK(pt) ); + assert( start >= 1 && MG_EOK(pt) && "invalid tetra" ); + assert ( tag & MG_BDY && "Unexpected non boundary tag"); pxt = NULL; na = pt->v[MMG5_iare[ia][0]]; @@ -971,13 +976,15 @@ int MMG3D_update_shellEdgeTag(MMG5_pMesh mesh,int start, int8_t ia,int16_t tag, if ( pt->xt ) { pxt = &mesh->xtetra[pt->xt]; - /* if tag and edge are already consistent, non need to update the shell (do - * not consider the MG_BDY tag) */ - xtag = pxt->tag[ia] & ~MG_BDY; - atag = tag & ~MG_BDY; + /* if tag and edge are already consistent, no need to update the shell (do + * not consider edges with tag 0 as they com from the creation of a xtetra + * during a previous collapse and are not updated) */ + xtag = pxt->tag[ia] | MG_BDY; - if ( xtag == atag && pxt->edg[ia] == ref ) { - return 1; + if ( pxt->tag[ia] & MG_BDY ) { + if ( xtag == tag && pxt->edg[ia] == ref ) { + return 1; + } } pxt->tag[ia] |= tag; @@ -1023,10 +1030,10 @@ int MMG3D_update_shellEdgeTag(MMG5_pMesh mesh,int start, int8_t ia,int16_t tag, * \return -1 if fail, \a start if shell has been completely travelled without * founding an xtetra, adj if an xtetra has been found, 0 otherwise * - * Get tag and ref of the edge \a na \a nb from tetra \a start by traveling - * its shell in one direction (given by the pivot \a piv). - * Stop when meeting the first xtetra (it is sufficient if tags and refs are - * consistent through the edge shell); + * Get tag and ref of the edge \a na \a nb from tetra \a start by traveling its + * shell in one direction (given by the pivot \a piv). Stop when meeting the + * first xtetra with a non 0 tag (it is sufficient if tags and refs are + * consistent through the edge shell except for edges with null tags); * */ static inline @@ -1049,9 +1056,11 @@ int MMG3D_get_shellEdgeTag_oneDir(MMG5_pMesh mesh,int start, int na, int nb, if ( pt->xt ) { pxt = &mesh->xtetra[pt->xt]; *ref = pxt->edg[i]; - *tag |= pxt->tag[i]; - *filled = 1; - return adj; + if ( pxt->tag[i] & MG_BDY ) { + *tag |= pxt->tag[i]; + *filled = 1; + return adj; + } } /* set new triangle for travel */ @@ -1099,9 +1108,11 @@ int MMG3D_get_shellEdgeTag(MMG5_pMesh mesh,int start, int8_t ia,int16_t *tag,in if ( pt->xt ) { pxt = &mesh->xtetra[pt->xt]; - *tag |= pxt->tag[ia]; - *ref = pxt->edg[ia]; - return 1; + if ( pxt->tag[ia] & MG_BDY ) { + *tag |= pxt->tag[ia]; + *ref = pxt->edg[ia]; + return 1; + } } /* Travel in one direction */ @@ -1312,7 +1323,7 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in #ifndef NDEBUG else { assert ( tagip == tagiq && refip == refiq ); - if ( mesh->info.ddebug ) { + if ( mesh->info.ddebug && (tagip & MG_BDY) ) { MMG3D_chk_shellEdgeTag(mesh,iel,iped,tagip,refip); MMG3D_chk_shellEdgeTag(mesh,iel,iqed,tagip,refip); } @@ -1408,7 +1419,10 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in /* update tags for edges */ MMG3D_update_edgeTag(pt,pxt,np,nq,ip,pt1,pxt1,voyp); - /* Recover the already used place by pxt */ + /* Recover the already used place by pxt: now pel has a xtetra but the + * edges coming from voyp (not directly involved in the collapse) will + * have the tag 0 that may be non consistent with other tags in their + * respective shells. */ pt1->xt = pt->xt; memcpy(pxt,pxt1,sizeof(MMG5_xTetra)); } @@ -1483,6 +1497,9 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in "larger xtetra table", mesh->xt--;return -1;); } + /* Now qel has a xtetra but the edges coming from voyq (not directly + * involved in the collapse) will have the tag 0 that may be non + * consistent with other tags in their respective shells. */ pt1->xt = mesh->xt; pxt = &mesh->xtetra[pt1->xt]; memcpy(pxt,pxt1,sizeof(MMG5_xTetra)); From d01646b4ee9d79eefe16df134748b0b07ddbe5c4 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 20 Jul 2021 15:26:34 +0200 Subject: [PATCH 114/170] Settag refactoring. --- src/mmg3d/boulep_3d.c | 126 ++++++++++++++++++++++-------------------- 1 file changed, 66 insertions(+), 60 deletions(-) diff --git a/src/mmg3d/boulep_3d.c b/src/mmg3d/boulep_3d.c index d8c585be1..c4db5068d 100644 --- a/src/mmg3d/boulep_3d.c +++ b/src/mmg3d/boulep_3d.c @@ -1132,6 +1132,67 @@ int MMG5_bouletrid(MMG5_pMesh mesh,int start,int iface,int ip,int *il1,int *l1, return 1; } +/** + * \param mesh pointer toward the mesh + * \param start tetra from which we start to travel + * \param na edge vertex + * \param nb edge vertex + * \param tag new edge tag + * \param ref new edge ref + * \param piv global index of the pivot to set the sense of travel + * \param adj index of adjacent tetra for the travel + * + * \return -1 if fail, \a start if shell has been completely travelled, 0 otherwise + * + * Set tag and ref of the edge \a na \a nb from tetra \a start by traveling + * its shell in one direction (given by the pivot \a piv). + * + */ +static inline +int MMG3D_settag_oneDir(MMG5_pMesh mesh,int start, int na, int nb, + int16_t tag,int edg, int piv,int adj) { + MMG5_pTetra pt; + MMG5_pxTetra pxt; + int *adja; + int16_t taginit; + int8_t i; + + while ( adj && (adj != start) ) { + pt = &mesh->tetra[adj]; + + /* identification of edge number in tetra adj */ + if ( !MMG3D_findEdge(mesh,pt,adj,na,nb,1,NULL,&i) ) { + return -1; + } + + if ( pt->xt ) { + pxt = &mesh->xtetra[pt->xt]; + if ( (pxt->ftag[MMG5_ifar[i][0]] & MG_BDY) || + (pxt->ftag[MMG5_ifar[i][1]] & MG_BDY) ) { + taginit = pxt->tag[i]; + pxt->tag[i] |= tag; + /* Remove the potential nosurf tag if initially the edge is + * really required */ + if ( (taginit & MG_REQ) && ( (!(taginit & MG_NOSURF)) || !(tag & MG_NOSURF) ) ) { + pxt->tag[i] &= ~MG_NOSURF; + } + pxt->edg[i] = MG_MAX(pxt->edg[i],edg); + } + } + /* set new triangle for travel */ + adja = &mesh->adja[4*(adj-1)+1]; + if ( pt->v[ MMG5_ifar[i][0] ] == piv ) { + adj = adja[ MMG5_ifar[i][0] ] / 4; + piv = pt->v[ MMG5_ifar[i][1] ]; + } + else { + adj = adja[ MMG5_ifar[i][1] ] /4; + piv = pt->v[ MMG5_ifar[i][0] ]; + } + } + return adj; +} + /** * \param mesh pointer toward the mesh structure * \param start tetra from which we start @@ -1150,7 +1211,6 @@ int MMG5_settag(MMG5_pMesh mesh,int start,int ia,int16_t tag,int edg) { MMG5_pxTetra pxt; int na,nb,*adja,adj,piv; int16_t taginit; - int8_t i; assert( start >= 1 ); pt = &mesh->tetra[start]; @@ -1177,40 +1237,13 @@ int MMG5_settag(MMG5_pMesh mesh,int start,int ia,int16_t tag,int edg) { pxt->edg[ia] = MG_MAX(pxt->edg[ia],edg); } } - while ( adj && (adj != start) ) { - pt = &mesh->tetra[adj]; - - /* identification of edge number in tetra adj */ - if ( !MMG3D_findEdge(mesh,pt,adj,na,nb,1,NULL,&i) ) return 0; - if ( pt->xt ) { - pxt = &mesh->xtetra[pt->xt]; - if ( (pxt->ftag[MMG5_ifar[i][0]] & MG_BDY) || - (pxt->ftag[MMG5_ifar[i][1]] & MG_BDY) ) { - taginit = pxt->tag[i]; - pxt->tag[i] |= tag; - /* Remove the potential nosurf tag if initially the edge is - * really required */ - if ( (taginit & MG_REQ) && ( (!(taginit & MG_NOSURF)) || !(tag & MG_NOSURF) ) ) { - pxt->tag[i] &= ~MG_NOSURF; - } - pxt->edg[i] = MG_MAX(pxt->edg[i],edg); - } - } - /* set new triangle for travel */ - adja = &mesh->adja[4*(adj-1)+1]; - if ( pt->v[ MMG5_ifar[i][0] ] == piv ) { - adj = adja[ MMG5_ifar[i][0] ] / 4; - piv = pt->v[ MMG5_ifar[i][1] ]; - } - else { - adj = adja[ MMG5_ifar[i][1] ] /4; - piv = pt->v[ MMG5_ifar[i][0] ]; - } - } + adj = MMG3D_settag_oneDir(mesh,start,na,nb,tag,edg,piv,adj); /* If all shell has been travelled, stop, else, travel it the other sense */ if ( adj == start ) return 1; + else if ( adj < 0 ) return 0; + assert(!adj); pt = &mesh->tetra[start]; @@ -1218,37 +1251,10 @@ int MMG5_settag(MMG5_pMesh mesh,int start,int ia,int16_t tag,int edg) { adj = adja[MMG5_ifar[ia][1]] / 4; piv = pt->v[MMG5_ifar[ia][0]]; - while ( adj && (adj != start) ) { - pt = &mesh->tetra[adj]; + adj = MMG3D_settag_oneDir(mesh,start,na,nb,tag,edg,piv,adj); - /* identification of edge number in tetra adj */ - if ( !MMG3D_findEdge(mesh,pt,adj,na,nb,1,NULL,&i) ) return 0; + if ( adj < 0 ) return 0; - if ( pt->xt ) { - pxt = &mesh->xtetra[pt->xt]; - if ( (pxt->ftag[MMG5_ifar[i][0]] & MG_BDY) || - (pxt->ftag[MMG5_ifar[i][1]] & MG_BDY) ) { - taginit = pxt->tag[i]; - pxt->tag[i] |= tag; - /* Remove the potential nosurf tag if initially the edge is - * really required */ - if ( (taginit & MG_REQ) && !(taginit & MG_NOSURF) ) { - pxt->tag[ia] &= ~MG_NOSURF; - } - pxt->edg[i] = MG_MAX(pxt->edg[i],edg); - } - } - /* set new triangle for travel */ - adja = &mesh->adja[4*(adj-1)+1]; - if ( pt->v[ MMG5_ifar[i][0] ] == piv ) { - adj = adja[ MMG5_ifar[i][0] ] / 4; - piv = pt->v[ MMG5_ifar[i][1] ]; - } - else { - adj = adja[ MMG5_ifar[i][1] ] /4; - piv = pt->v[ MMG5_ifar[i][0] ]; - } - } return 1; } From 87b7cb8214214b81304cd6416fbcaae6b5c5fc45 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 20 Jul 2021 16:55:32 +0200 Subject: [PATCH 115/170] Factorization of the shell unfolding in topchkcol_bdy. --- src/mmg3d/colver_3d.c | 136 ++++++++++++++++++++++-------------------- 1 file changed, 70 insertions(+), 66 deletions(-) diff --git a/src/mmg3d/colver_3d.c b/src/mmg3d/colver_3d.c index f4bc58844..9a5eafcd0 100644 --- a/src/mmg3d/colver_3d.c +++ b/src/mmg3d/colver_3d.c @@ -158,6 +158,62 @@ int MMG5_chkcol_int(MMG5_pMesh mesh,MMG5_pSol met,int k,int8_t iface, return ilist; } +/** + * \param mesh pointer toward the mesh + * \param start tetra from which we start to travel + * \param end tetra at which we stop the travel + * \param na edge vertex + * \param nb edge vertex + * \param piv global index of the pivot to set the sense of travel + * \param iel pointer toward the last element of the shell + * \param iopp pointer toward the ending boundary face of the shell + * + * \return -1 if fail, \a piv otherwise. + * + * Unfold the shell of the edge \a na \a nb from tetra \a start in the direction + * given by the pivot \a piv). + * + */ +static inline +int MMG3D_unfold_shell(MMG5_pMesh mesh,int start,int end, int na, int nb,int piv, + int *iel,int8_t *iopp) { + MMG5_pTetra pt; + int adj,*adja; + int8_t i,ipiv,isface; + + adj = start; + do { + *iel = adj; + pt = &mesh->tetra[*iel]; + adja = &mesh->adja[4*(*iel-1)+1]; + + /* Identification of edge number in tetra iel */ + if ( !MMG3D_findEdge(mesh,pt,*iel,na,nb,1,NULL,&i) ) return -1; + + /* set sense of travel */ + if ( pt->v[ MMG5_ifar[i][0] ] == piv ) { + adj = adja[ MMG5_ifar[i][0] ] / 4; + ipiv = MMG5_ifar[i][1]; + *iopp = MMG5_ifar[i][0]; + piv = pt->v[ipiv]; + } + else { + adj = adja[ MMG5_ifar[i][1] ] / 4; + ipiv = MMG5_ifar[i][0]; + *iopp = MMG5_ifar[i][1]; + piv = pt->v[ipiv]; + } + + isface = 0; + if ( pt->xt ) { + isface = (MG_BDY & mesh->xtetra[pt->xt].ftag[*iopp]); + } + } + while ( adj && ( adj != end ) && !isface ); + + return piv; +} + /** * \param mesh pointer toward the mesh structure. * \param k index of the starting tetra. @@ -182,8 +238,8 @@ MMG5_topchkcol_bdy(MMG5_pMesh mesh,int k,int iface,int8_t iedg,int *lists, MMG5_pTetra pt; MMG5_pxTetra pxt; double n0[3],n1[3],devnew; - int nump,numq,piv,iel,jel,jel1,nap,nbp,naq,nbq,nro,adj,*adja; - int8_t ip,iq,ipiv,iopp,i,j,j1,jface,jface1,isface; + int nump,numq,iel,jel,jel1,nap,nbp,naq,nbq,nro; + int8_t ip,iq,iopp,i,j,j1,jface,jface1; pt = &mesh->tetra[k]; ip = MMG5_idir[iface][MMG5_inxt2[iedg]]; @@ -208,40 +264,15 @@ MMG5_topchkcol_bdy(MMG5_pMesh mesh,int k,int iface,int8_t iedg,int *lists, nap = pt->v[i]; - /* Unfold shell of (nq,nro), starting from (k,iface), with pivot np */ - adj = k; - piv = nump; - do { - iel = adj; - pt = &mesh->tetra[iel]; - adja = &mesh->adja[4*(iel-1)+1]; - - /* Identification of edge number in tetra iel */ - if ( !MMG3D_findEdge(mesh,pt,iel,numq,nro,1,NULL,&i) ) return -1; + /* Unfold shell of (numq,nro), starting from (jel,jface), with pivot nump */ + naq = MMG3D_unfold_shell(mesh,k,k,numq,nro,nump,&iel,&iopp); - /* set sense of travel */ - if ( pt->v[ MMG5_ifar[i][0] ] == piv ) { - adj = adja[ MMG5_ifar[i][0] ] / 4; - ipiv = MMG5_ifar[i][1]; - iopp = MMG5_ifar[i][0]; - piv = pt->v[ipiv]; - } - else { - adj = adja[ MMG5_ifar[i][1] ] / 4; - ipiv = MMG5_ifar[i][0]; - iopp = MMG5_ifar[i][1]; - piv = pt->v[ipiv]; - } - - isface = 0; - if ( pt->xt ) { - isface = (MG_BDY & mesh->xtetra[pt->xt].ftag[iopp]); - } + if ( naq < 0 ) { + return -1; + } + else if ( nap == naq ) { + return 0; } - while ( adj && ( adj != k ) && !isface ); - - naq = piv; - if ( nap == naq ) return 0; assert ( mesh->tetra[k].xt && "initial tetra is not boundary"); pxt = &mesh->xtetra[mesh->tetra[k].xt]; @@ -280,40 +311,13 @@ MMG5_topchkcol_bdy(MMG5_pMesh mesh,int k,int iface,int8_t iedg,int *lists, nbp = pt->v[i]; - /* Unfold shell of (nq,nro), starting from (jel,jface), with pivot np */ - adj = lists[ilists-1] / 4; - piv = nump; - do { - iel = adj; - pt = &mesh->tetra[iel]; - adja = &mesh->adja[4*(iel-1)+1]; - - /* Identification of edge number in tetra iel */ - if ( !MMG3D_findEdge(mesh,pt,iel,numq,nro,1,NULL,&i) ) return -1; + /* Unfold shell of (numq,nro), starting from (jel,jface), with pivot nump */ + nbq = MMG3D_unfold_shell(mesh,lists[ilists-1]/4,k,numq,nro,nump,&iel,&iopp); - /* set sense of travel */ - if ( pt->v[ MMG5_ifar[i][0] ] == piv ) { - adj = adja[ MMG5_ifar[i][0] ] / 4; - ipiv = MMG5_ifar[i][1]; - iopp = MMG5_ifar[i][0]; - piv = pt->v[ipiv]; - } - else { - adj = adja[ MMG5_ifar[i][1] ] / 4; - ipiv = MMG5_ifar[i][0]; - iopp = MMG5_ifar[i][1]; - piv = pt->v[ipiv]; - } - - isface = 0; - if ( pt->xt ) { - isface = (MG_BDY & mesh->xtetra[pt->xt].ftag[iopp]); - } + if ( nbq < 0 ) { + return -1; } - while ( adj && ( adj != k ) && !isface ); - - nbq = piv; - if ( nbp == nbq ) { + else if ( nbp == nbq ) { return 0; } From 0c9d9d346deb7199afd4c46617a9fd0b775e05e0 Mon Sep 17 00:00:00 2001 From: luca Date: Tue, 20 Jul 2021 16:55:33 +0200 Subject: [PATCH 116/170] Consistency: always compute a normal vector from adjacent triangle when splitting a REF edge with singular extremities (as in mmg3d1.c) --- src/mmg3d/mmg3d1_delone.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/mmg3d/mmg3d1_delone.c b/src/mmg3d/mmg3d1_delone.c index 7b02a68af..52a543477 100644 --- a/src/mmg3d/mmg3d1_delone.c +++ b/src/mmg3d/mmg3d1_delone.c @@ -198,6 +198,15 @@ MMG5_boucle_for(MMG5_pMesh mesh, MMG5_pSol met,MMG3D_pPROctree *PROctree,int ne, else if ( tag & MG_REF ) { if ( !MMG5_BezierRef(mesh,ip1,ip2,0.5,o,no1,to) ) goto collapse; + if ( MG_SIN(p0->tag) && MG_SIN(p1->tag) ) { + MMG5_tet2tri(mesh,k,i,&ptt); + MMG5_nortri(mesh,&ptt,no1); + if ( !MG_GET(pxt->ori,i) ) { + no1[0] *= -1.0; + no1[1] *= -1.0; + no1[2] *= -1.0; + } + } } else { if ( !MMG5_norface(mesh,k,i,v) ) goto collapse; @@ -557,6 +566,15 @@ MMG5_boucle_for(MMG5_pMesh mesh, MMG5_pSol met,MMG3D_pPROctree *PROctree,int ne, else if ( tag & MG_REF ) { if ( !MMG5_BezierRef(mesh,ip1,ip2,0.5,o,no1,to) ) goto collapse2; + if ( MG_SIN(p0->tag) && MG_SIN(p1->tag) ) { + MMG5_tet2tri(mesh,k,i,&ptt); + MMG5_nortri(mesh,&ptt,no1); + if ( !MG_GET(pxt->ori,i) ) { + no1[0] *= -1.0; + no1[1] *= -1.0; + no1[2] *= -1.0; + } + } } else { if ( !MMG5_norface(mesh,k,i,v) ) goto collapse2; From 446e68741917056e0e7aa76ce6c08e3660096d01 Mon Sep 17 00:00:00 2001 From: luca Date: Tue, 20 Jul 2021 17:02:30 +0200 Subject: [PATCH 117/170] Avoid splitting edges with parallel extremities. --- src/mmg3d/mmg3d1.c | 2 ++ src/mmg3d/mmg3d1_delone.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/mmg3d/mmg3d1.c b/src/mmg3d/mmg3d1.c index dc235dc6f..53adbe4bd 100644 --- a/src/mmg3d/mmg3d1.c +++ b/src/mmg3d/mmg3d1.c @@ -1472,6 +1472,8 @@ int MMG3D_splsurfedge( MMG5_pMesh mesh,MMG5_pSol met,int k, p0 = &mesh->point[ip1]; p1 = &mesh->point[ip2]; + if ( (p0->tag & MG_PARBDY) && (p1->tag & MG_PARBDY) ) continue; + ref = pxt->edg[imax]; tag = pxt->tag[imax]; diff --git a/src/mmg3d/mmg3d1_delone.c b/src/mmg3d/mmg3d1_delone.c index 52a543477..dc5ef6727 100644 --- a/src/mmg3d/mmg3d1_delone.c +++ b/src/mmg3d/mmg3d1_delone.c @@ -156,6 +156,7 @@ MMG5_boucle_for(MMG5_pMesh mesh, MMG5_pSol met,MMG3D_pPROctree *PROctree,int ne, /* Case of a boundary face */ if ( pt->xt && (pxt->ftag[i] & MG_BDY) ) { + if ( (p0->tag & MG_PARBDY) && (p1->tag & MG_PARBDY) ) continue; if ( !(MG_GET(pxt->ori,i)) ) continue; ref = pxt->edg[MMG5_iarf[i][j]]; tag = pxt->tag[MMG5_iarf[i][j]]; @@ -524,6 +525,7 @@ MMG5_boucle_for(MMG5_pMesh mesh, MMG5_pSol met,MMG3D_pPROctree *PROctree,int ne, /* Case of a boundary face */ if ( pt->xt && (pxt->ftag[i] & MG_BDY) ) { + if ( (p0->tag & MG_PARBDY) && (p1->tag & MG_PARBDY) ) continue; if ( !(MG_GET(pxt->ori,i)) ) continue; ref = pxt->edg[MMG5_iarf[i][j]]; tag = pxt->tag[MMG5_iarf[i][j]]; From f8f0c94785b40f82373182d1dd0308dae9fce4b0 Mon Sep 17 00:00:00 2001 From: luca Date: Tue, 20 Jul 2021 17:10:04 +0200 Subject: [PATCH 118/170] Patch error. --- src/mmg3d/mmg3d1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mmg3d/mmg3d1.c b/src/mmg3d/mmg3d1.c index 53adbe4bd..0f9725855 100644 --- a/src/mmg3d/mmg3d1.c +++ b/src/mmg3d/mmg3d1.c @@ -1472,7 +1472,7 @@ int MMG3D_splsurfedge( MMG5_pMesh mesh,MMG5_pSol met,int k, p0 = &mesh->point[ip1]; p1 = &mesh->point[ip2]; - if ( (p0->tag & MG_PARBDY) && (p1->tag & MG_PARBDY) ) continue; + if ( (p0->tag & MG_PARBDY) && (p1->tag & MG_PARBDY) ) return 0; ref = pxt->edg[imax]; tag = pxt->tag[imax]; From f293969eb58828fc6f14f962ac50df62a94d9e4e Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 20 Jul 2021 17:24:54 +0200 Subject: [PATCH 119/170] Merge MMG5_chkcol_bdy and MMG5_chkcol_nomint functions as the only difference is that we skip the tests related to the surface ball and the positive (resp. negative) domains in on internal non manifold points. --- src/mmg3d/colver_3d.c | 159 +++++++------------------------------ src/mmg3d/mmg3d.h | 3 +- src/mmg3d/mmg3d1.c | 6 +- src/mmg3d/mmg3d1_delone.c | 4 +- src/mmg3d/mmg3d1_pattern.c | 2 +- 5 files changed, 37 insertions(+), 137 deletions(-) diff --git a/src/mmg3d/colver_3d.c b/src/mmg3d/colver_3d.c index 9a5eafcd0..971c1bbea 100644 --- a/src/mmg3d/colver_3d.c +++ b/src/mmg3d/colver_3d.c @@ -353,20 +353,25 @@ MMG5_topchkcol_bdy(MMG5_pMesh mesh,int k,int iface,int8_t iedg,int *lists, * \param typchk typchk type of checking permformed for edge length * (hmax or MMG3D_LLONG criterion). * \param isnm 1 if edge is non-manifold + * \param isnmint 1 if ip is an internal non manifold point; * * \return ilistv if success, 0 if the point cannot be collapsed, -1 if fail. * - * Check whether collapse ip -> iq could be performed, ip boundary point ; + * Check whether collapse ip -> iq could be performed, ip boundary point; * 'mechanical' tests (positive jacobian) are not performed here ; * iface = boundary face on which lie edge iedg - in local face num. * (pq, or ia in local tet notation). * If isnm is 1, the collapse occurs along an external MG_NOM edge. + * If isnmint is 1, ip is an internal non manifold point and dont have normals. + * In this last case, \a lists, \a ilists \a refmin, \a refplus and \a isnm + * variables aren't used (we neither have a surfacic ball nor "positive" and + * "negative" volumes) * * \remark we don't check edge lengths. */ int MMG5_chkcol_bdy(MMG5_pMesh mesh,MMG5_pSol met,int k,int8_t iface, int8_t iedg,int *listv,int ilistv,int *lists,int ilists, - int refmin,int refplus, int8_t typchk,int isnm) { + int refmin,int refplus, int8_t typchk,int isnm,int8_t isnmint) { MMG5_pTetra pt,pt0,pt1; MMG5_pxTetra pxt; MMG5_Tria tt; @@ -408,11 +413,13 @@ int MMG5_chkcol_bdy(MMG5_pMesh mesh,MMG5_pSol met,int k,int8_t iface, refplus = MG_PLUS; } - /* prevent collapse in case surface ball has 3 triangles */ - if ( ilists <= 2 ) return 0; // ATTENTION, Normalement, avec 2 c est bon ! + if ( !isnmint ) { + /* prevent collapse in case surface ball has 3 triangles */ + if ( ilists <= 2 ) return 0; // ATTENTION, Normalement, avec 2 c est bon ! - /* Surfacic ball is enumerated with first tet having (pq) as edge n° MMG5_iprv2[ip] on face iopp */ - MMG5_startedgsurfball(mesh,nump,numq,lists,ilists); + /* Surfacic ball is enumerated with first tet having (pq) as edge n° MMG5_iprv2[ip] on face iopp */ + MMG5_startedgsurfball(mesh,nump,numq,lists,ilists); + } /* check tetra quality */ calold = calnew = DBL_MAX; @@ -421,8 +428,10 @@ int MMG5_chkcol_bdy(MMG5_pMesh mesh,MMG5_pSol met,int k,int8_t iface, ipp = listv[l] % 4; pt = &mesh->tetra[iel]; - if ( pt->ref == refmin ) isminp = 1; - else if ( pt->ref == refplus ) isplp = 1; + if ( !isnmint ) { + if ( pt->ref == refmin ) isminp = 1; + else if ( pt->ref == refplus ) isplp = 1; + } /* Topological test for tetras of the shell */ for (iq=0; iq<4; iq++) @@ -457,13 +466,15 @@ int MMG5_chkcol_bdy(MMG5_pMesh mesh,MMG5_pSol met,int k,int8_t iface, continue; } - if ( isnm || mesh->info.iso ) { - /* Volume test for tetras outside the shell */ - if ( (!ndepmin) && (pt->ref == refmin) ) { - ndepmin = iel; - } - else if ( (!ndepplus) && (pt->ref == refplus) ) { - ndepplus = iel; + if ( !isnmint ) { + if ( isnm || mesh->info.iso ) { + /* Volume test for tetras outside the shell */ + if ( (!ndepmin) && (pt->ref == refmin) ) { + ndepmin = iel; + } + else if ( (!ndepplus) && (pt->ref == refplus) ) { + ndepplus = iel; + } } } @@ -493,6 +504,10 @@ int MMG5_chkcol_bdy(MMG5_pMesh mesh,MMG5_pSol met,int k,int8_t iface, if ( calold < MMG5_EPSOK && calnew <= calold ) return 0; else if ( calnew < MMG5_EPSOK || calnew < 0.3*calold ) return 0; + if ( isnmint ) { + return ilistv; + } + /* analyze surfacic ball of p */ for (l=1; l iq could be performed, ip internal non manifold point; - * 'mechanical' tests (positive jacobian) are not performed here ; - * iface = boundary face on which lie edge iedg - in local face num. - * (pq, or ia in local tet notation). - * - */ -int MMG5_chkcol_nomint(MMG5_pMesh mesh,MMG5_pSol met,int k,int8_t iface, - int8_t iedg,int *listv,int ilistv,int8_t typchk) { - MMG5_pTetra pt,pt0; - MMG5_pxTetra pxt; - double calold,calnew,caltmp; - int ipp,nump,numq,l,iel; - int nr,nbbdy; - int8_t ia,ip,i,iq,i0,i1; -#ifndef NDEBUG - MMG5_pPoint p0; -#endif - - pt = &mesh->tetra[k]; - pxt = 0; - pt0 = &mesh->tetra[0]; - ip = MMG5_idir[iface][MMG5_inxt2[iedg]]; - nump = pt->v[ip]; - numq = pt->v[MMG5_idir[iface][MMG5_iprv2[iedg]]]; - -#ifndef NDEBUG - p0 = &mesh->point[nump]; - assert(p0->tag & MG_BDY); - assert(p0->xp); -#endif - - /* check tetra quality */ - calold = calnew = DBL_MAX; - for (l=0; ltetra[iel]; - - /* Topological test for tetras of the shell */ - for (iq=0; iq<4; iq++) - if ( pt->v[iq] == numq ) break; - - if ( iq < 4 ) { - nbbdy = 0; - if ( pt->xt ) pxt = &mesh->xtetra[pt->xt]; - for (i=0; i<4; i++) { - if ( pt->xt && (pxt->ftag[i] & MG_BDY) ) nbbdy++; - } - - /* Topological problem triggered when one of the two faces of collapsed edge is the only - internal one : closing a part of the domain */ - if ( nbbdy == 4 ) - return 0; - else if ( nbbdy == 3 ) { - - /* Identification of edge number in tetra iel */ - if ( !MMG3D_findEdge(mesh,pt,iel,numq,nump,1,NULL,&ia) ) return -1; - - i0 = MMG5_ifar[ia][0]; - i1 = MMG5_ifar[ia][1]; - if ( pt->xt && (!(pxt->ftag[i0] & MG_BDY) || !(pxt->ftag[i1] & MG_BDY)) ) - return 0; - } - - /* Now check that the 2 faces identified by collapse are not boundary */ - if ( pt->xt && (pxt->ftag[ipp] & MG_BDY) && (pxt->ftag[iq] & MG_BDY) ) - return 0; - - continue; - } - - /* Prevent from creating a tetra with 4 ridges vertices */ - if ( mesh->point[numq].tag & MG_GEO ) { - i = ipp; - nr = 0; - for (iq=0; iq<3; iq++) { - i = MMG5_inxt3[i]; - if ( mesh->point[pt->v[i]].tag & MG_GEO ) ++nr; - } - if ( nr==3 ) return 0; - } - - /* Quality checks for tetrahedra outside the shell */ - memcpy(pt0,pt,sizeof(MMG5_Tetra)); - pt0->v[ipp] = numq; - - calold = MG_MIN(calold, pt->qual); - if ( typchk==1 && met->m && met->size > 1 ) - caltmp = MMG5_caltet33_ani(mesh,met,pt0); - else - caltmp = MMG5_orcal(mesh,met,0); - - if ( caltmp < MMG5_NULKAL ) return 0; - calnew = MG_MIN(calnew,caltmp); - } - if ( calold < MMG5_EPSOK && calnew <= calold ) return 0; - else if ( calnew < MMG5_EPSOK || calnew < 0.3*calold ) return 0; - - return ilistv; -} - /** * \param pt tetra of the shell of the edge to collapse * \param pxt xtetra associated to \a pt diff --git a/src/mmg3d/mmg3d.h b/src/mmg3d/mmg3d.h index 6afc1727e..65fa47b9a 100644 --- a/src/mmg3d/mmg3d.h +++ b/src/mmg3d/mmg3d.h @@ -297,8 +297,7 @@ int MMG5_settag(MMG5_pMesh,int,int,int16_t,int); int MMG5_deltag(MMG5_pMesh,int,int,int16_t); int MMG5_setNmTag(MMG5_pMesh mesh, MMG5_Hash *hash); int MMG5_chkcol_int(MMG5_pMesh,MMG5_pSol,int,int8_t,int8_t,int*,int,int8_t); -int MMG5_chkcol_bdy(MMG5_pMesh,MMG5_pSol,int,int8_t,int8_t,int*,int,int*,int,int,int,int8_t,int); -int MMG5_chkcol_nomint(MMG5_pMesh,MMG5_pSol,int,int8_t,int8_t,int*,int,int8_t); +int MMG5_chkcol_bdy(MMG5_pMesh,MMG5_pSol,int,int8_t,int8_t,int*,int,int*,int,int,int,int8_t,int,int8_t); int MMG5_chkmanicoll(MMG5_pMesh,int,int,int,int,int,int,int,int8_t,int8_t); int MMG5_chkmani(MMG5_pMesh mesh); int MMG5_colver(MMG5_pMesh,MMG5_pSol,int *,int,int8_t,int8_t); diff --git a/src/mmg3d/mmg3d1.c b/src/mmg3d/mmg3d1.c index c1cf75ddd..e1bfc452f 100644 --- a/src/mmg3d/mmg3d1.c +++ b/src/mmg3d/mmg3d1.c @@ -1036,15 +1036,15 @@ static int MMG5_coltet(MMG5_pMesh mesh,MMG5_pSol met,int8_t typchk) { if ( isnm ) { isnmint = ( p0->xp && mesh->xpoint[p0->xp].nnor ); if ( isnmint ) { - ilist = MMG5_chkcol_nomint(mesh,met,k,i,j,list,ilist,typchk); + ilist = MMG5_chkcol_bdy(mesh,met,k,i,j,list,ilist,lists,ilists,0,0,typchk,isnm,isnmint); } else { if ( mesh->adja[4*(k-1)+1+i] ) continue; - ilist = MMG5_chkcol_bdy(mesh,met,k,i,j,list,ilist,lists,ilists,refmin,refplus,typchk,isnm); + ilist = MMG5_chkcol_bdy(mesh,met,k,i,j,list,ilist,lists,ilists,refmin,refplus,typchk,isnm,isnmint); } } else { - ilist = MMG5_chkcol_bdy(mesh,met,k,i,j,list,ilist,lists,ilists,0,0,typchk,isnm); + ilist = MMG5_chkcol_bdy(mesh,met,k,i,j,list,ilist,lists,ilists,0,0,typchk,isnm,isnmint); } } /* internal face */ diff --git a/src/mmg3d/mmg3d1_delone.c b/src/mmg3d/mmg3d1_delone.c index 7b02a68af..cf9013cf9 100644 --- a/src/mmg3d/mmg3d1_delone.c +++ b/src/mmg3d/mmg3d1_delone.c @@ -447,7 +447,7 @@ MMG5_boucle_for(MMG5_pMesh mesh, MMG5_pSol met,MMG3D_pPROctree *PROctree,int ne, list,&ilist,lists,&ilists,(p0->tag & MG_NOM)) < 0 ) return -1; - ilist = MMG5_chkcol_bdy(mesh,met,k,i,j,list,ilist,lists,ilists,0,0,2,0); + ilist = MMG5_chkcol_bdy(mesh,met,k,i,j,list,ilist,lists,ilists,0,0,2,0,0); if ( ilist > 0 ) { ier = MMG5_colver(mesh,met,list,ilist,i2,2); @@ -789,7 +789,7 @@ MMG5_boucle_for(MMG5_pMesh mesh, MMG5_pSol met,MMG3D_pPROctree *PROctree,int ne, list,&ilist,lists,&ilists,(p0->tag & MG_NOM)) < 0 ) return -1; - ilist = MMG5_chkcol_bdy(mesh,met,k,i,j,list,ilist,lists,ilists,0,0,2,0); + ilist = MMG5_chkcol_bdy(mesh,met,k,i,j,list,ilist,lists,ilists,0,0,2,0,0); if ( ilist > 0 ) { ier = MMG5_colver(mesh,met,list,ilist,i2,2); if ( ier < 0 ) return -1; diff --git a/src/mmg3d/mmg3d1_pattern.c b/src/mmg3d/mmg3d1_pattern.c index 298d96517..29544ad0c 100644 --- a/src/mmg3d/mmg3d1_pattern.c +++ b/src/mmg3d/mmg3d1_pattern.c @@ -249,7 +249,7 @@ static int MMG5_adpcol(MMG5_pMesh mesh,MMG5_pSol met) { list,&ilist,lists,&ilists,(p0->tag & MG_NOM)) < 0 ) return -1; - ilist = MMG5_chkcol_bdy(mesh,met,k,i,j,list,ilist,lists,ilists,0,0,2,0); + ilist = MMG5_chkcol_bdy(mesh,met,k,i,j,list,ilist,lists,ilists,0,0,2,0,0); } /* Case of an internal face */ else { From 17f78961d2fd05fe6fffec570599d1d2368bf172 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 20 Jul 2021 17:29:50 +0200 Subject: [PATCH 120/170] Test simplification. --- src/mmg3d/mmg3d1.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/mmg3d/mmg3d1.c b/src/mmg3d/mmg3d1.c index e1bfc452f..4cd04967e 100644 --- a/src/mmg3d/mmg3d1.c +++ b/src/mmg3d/mmg3d1.c @@ -1035,13 +1035,11 @@ static int MMG5_coltet(MMG5_pMesh mesh,MMG5_pSol met,int8_t typchk) { isnm = ( tag & MG_NOM ); if ( isnm ) { isnmint = ( p0->xp && mesh->xpoint[p0->xp].nnor ); - if ( isnmint ) { - ilist = MMG5_chkcol_bdy(mesh,met,k,i,j,list,ilist,lists,ilists,0,0,typchk,isnm,isnmint); - } - else { + if ( !isnmint ) { + /* Treat surfacic non manifold points from a surface triangle */ if ( mesh->adja[4*(k-1)+1+i] ) continue; - ilist = MMG5_chkcol_bdy(mesh,met,k,i,j,list,ilist,lists,ilists,refmin,refplus,typchk,isnm,isnmint); } + ilist = MMG5_chkcol_bdy(mesh,met,k,i,j,list,ilist,lists,ilists,refmin,refplus,typchk,isnm,isnmint); } else { ilist = MMG5_chkcol_bdy(mesh,met,k,i,j,list,ilist,lists,ilists,0,0,typchk,isnm,isnmint); From 21b924990b07b342c02e39824776efaccb483482 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 20 Jul 2021 17:33:36 +0200 Subject: [PATCH 121/170] Test simplification (2). --- src/mmg3d/mmg3d1.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/mmg3d/mmg3d1.c b/src/mmg3d/mmg3d1.c index 4cd04967e..05ee392e9 100644 --- a/src/mmg3d/mmg3d1.c +++ b/src/mmg3d/mmg3d1.c @@ -1033,17 +1033,12 @@ static int MMG5_coltet(MMG5_pMesh mesh,MMG5_pSol met,int8_t typchk) { if ( p0->tag > tag ) continue; isnm = ( tag & MG_NOM ); - if ( isnm ) { - isnmint = ( p0->xp && mesh->xpoint[p0->xp].nnor ); - if ( !isnmint ) { - /* Treat surfacic non manifold points from a surface triangle */ - if ( mesh->adja[4*(k-1)+1+i] ) continue; - } - ilist = MMG5_chkcol_bdy(mesh,met,k,i,j,list,ilist,lists,ilists,refmin,refplus,typchk,isnm,isnmint); - } - else { - ilist = MMG5_chkcol_bdy(mesh,met,k,i,j,list,ilist,lists,ilists,0,0,typchk,isnm,isnmint); + isnmint = ( tag & MG_NOM ) ? ( p0->xp && mesh->xpoint[p0->xp].nnor ) : 0; + if ( isnm && (!isnmint) ) { + /* Treat surfacic non manifold points from a surface triangle */ + if ( mesh->adja[4*(k-1)+1+i] ) continue; } + ilist = MMG5_chkcol_bdy(mesh,met,k,i,j,list,ilist,lists,ilists,refmin,refplus,typchk,isnm,isnmint); } /* internal face */ else { From 69f81b2219c57687114f15d42b418dbf44846335 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 20 Jul 2021 17:54:37 +0200 Subject: [PATCH 122/170] Add subfunction to compute tangent in boulep. --- src/mmg3d/boulep_3d.c | 117 +++++++++++++++++++----------------------- 1 file changed, 53 insertions(+), 64 deletions(-) diff --git a/src/mmg3d/boulep_3d.c b/src/mmg3d/boulep_3d.c index c4db5068d..d5b8ddedd 100644 --- a/src/mmg3d/boulep_3d.c +++ b/src/mmg3d/boulep_3d.c @@ -139,6 +139,44 @@ int MMG3D_findEdge(MMG5_pMesh mesh,MMG5_pTetra pt,int k,int na,int nb,int error, return 0; } +static inline +void MMG3D_compute_tangent(MMG5_pMesh mesh,int nump,int ip0,int ip1,double t[3]) { + MMG5_pPoint ppt,p0,p1; + double l0,l1,dd; + int8_t i; + + ppt = &mesh->point[nump]; + p0 = &mesh->point[ip0]; + p1 = &mesh->point[ip1]; + + l0 = (ppt->c[0] - p0->c[0])*(ppt->c[0] - p0->c[0]) \ + + (ppt->c[1] - p0->c[1])*(ppt->c[1] - p0->c[1]) + (ppt->c[2] - p0->c[2])*(ppt->c[2] - p0->c[2]); + l1 = (ppt->c[0] - p1->c[0])*(ppt->c[0] - p1->c[0]) \ + + (ppt->c[1] - p1->c[1])*(ppt->c[1] - p1->c[1]) + (ppt->c[2] - p1->c[2])*(ppt->c[2] - p1->c[2]); + l0 = sqrt(l0); + l1 = sqrt(l1); + + if ( (l0 < MMG5_EPSD2) || (l1 < MMG5_EPSD2) ) { + for ( i=0; i<3; ++i ) { + t[i] = p1->c[i] - p0->c[i]; + } + } + else if ( l0 < l1 ) { + dd = l0 / l1; + for ( i=0; i<3; ++i ) { + t[0] = dd*(p1->c[i] - ppt->c[i]) + ppt->c[i] - p0->c[i]; + } + } + else { + dd = l1 / l0; + for ( i=0; i<3; ++i ) { + t[i] = dd*(p0->c[i] - ppt->c[i]) + ppt->c[i] - p1->c[i]; + } + } + + return; +} + /** * \param mesh pointer toward the mesh structure. * \param start tetra index. @@ -155,8 +193,7 @@ int MMG3D_findEdge(MMG5_pMesh mesh,MMG5_pTetra pt,int k,int na,int nb,int error, int MMG5_boulenm(MMG5_pMesh mesh,int start,int ip,int iface, double n[3],double t[3]) { MMG5_pTetra pt; - MMG5_pPoint p0,p1,ppt; - double dd,nt[3],l0,l1; + double dd,nt[3]; int base,nump,nr,nnm,k,piv,na,nb,adj,nvstart,fstart,aux,ip0,ip1; int *adja; int16_t tag; @@ -264,34 +301,8 @@ int MMG5_boulenm(MMG5_pMesh mesh,int start,int ip,int iface, assert( ip0 && ip1 ); if ( ip0 == ip1 ) return 0; - p0 = &mesh->point[ip0]; - p1 = &mesh->point[ip1]; - ppt = &mesh->point[nump]; + MMG3D_compute_tangent(mesh,nump,ip0,ip1,t); - l0 = (ppt->c[0] - p0->c[0])*(ppt->c[0] - p0->c[0]) \ - + (ppt->c[1] - p0->c[1])*(ppt->c[1] - p0->c[1]) + (ppt->c[2] - p0->c[2])*(ppt->c[2] - p0->c[2]); - l1 = (ppt->c[0] - p1->c[0])*(ppt->c[0] - p1->c[0]) \ - + (ppt->c[1] - p1->c[1])*(ppt->c[1] - p1->c[1]) + (ppt->c[2] - p1->c[2])*(ppt->c[2] - p1->c[2]); - l0 = sqrt(l0); - l1 = sqrt(l1); - - if ( (l0 < MMG5_EPSD2) || (l1 < MMG5_EPSD2) ) { - t[0] = p1->c[0] - p0->c[0]; - t[1] = p1->c[1] - p0->c[1]; - t[2] = p1->c[2] - p0->c[2]; - } - else if ( l0 < l1 ) { - dd = l0 / l1; - t[0] = dd*(p1->c[0] - ppt->c[0]) + ppt->c[0] - p0->c[0]; - t[1] = dd*(p1->c[1] - ppt->c[1]) + ppt->c[1] - p0->c[1]; - t[2] = dd*(p1->c[2] - ppt->c[2]) + ppt->c[2] - p0->c[2]; - } - else { - dd = l1 / l0; - t[0] = dd*(p0->c[0] - ppt->c[0]) + ppt->c[0] - p1->c[0]; - t[1] = dd*(p0->c[1] - ppt->c[1]) + ppt->c[1] - p1->c[1]; - t[2] = dd*(p0->c[2] - ppt->c[2]) + ppt->c[2] - p1->c[2]; - } dd = t[0]*n[0] + t[1]*n[1] + t[2]*n[2]; t[0] -= dd*n[0]; t[1] -= dd*n[1]; @@ -308,16 +319,21 @@ int MMG5_boulenm(MMG5_pMesh mesh,int start,int ip,int iface, return 1; } -/** -Travel the ball of the internal non manifold point ip in tetra start - and calculate the tangent vector to the underlying curve. - Return 1 when the procedure has completed successfully, 0 when more than two NOM points are attached to ip. -*/ +/** + * \param mesh pointer toward the mesh structure. + * \param start tetra index. + * \param ip point index. + * \param t computed tangent vector. + * \return 0 when more than two NOM points are attached to ip, 1 if sucess. + * + * Travel the ball of the internal non manifold point ip in tetra start + * and calculate the tangent vector to the underlying curve. + * + */ int MMG5_boulenmInt(MMG5_pMesh mesh,int start,int ip,double t[3]) { MMG5_pTetra pt,pt1; MMG5_pxTetra pxt; - MMG5_pPoint p0,p1,ppt; - double l0,l1,dd; + double dd; int k,kk,ip0,ip1,nump,na,nb,base,cur,ilist,*adja; int list[MMG3D_LMAX+2]; int8_t i,j,ii,ie; @@ -395,34 +411,7 @@ int MMG5_boulenmInt(MMG5_pMesh mesh,int start,int ip,double t[3]) { } /* At this point, the two points connected to ppt via the NOM curve are ip0 and ip1 */ - ppt = &mesh->point[nump]; - p0 = &mesh->point[ip0]; - p1 = &mesh->point[ip1]; - - l0 = (ppt->c[0] - p0->c[0])*(ppt->c[0] - p0->c[0]) \ - + (ppt->c[1] - p0->c[1])*(ppt->c[1] - p0->c[1]) + (ppt->c[2] - p0->c[2])*(ppt->c[2] - p0->c[2]); - l1 = (ppt->c[0] - p1->c[0])*(ppt->c[0] - p1->c[0]) \ - + (ppt->c[1] - p1->c[1])*(ppt->c[1] - p1->c[1]) + (ppt->c[2] - p1->c[2])*(ppt->c[2] - p1->c[2]); - l0 = sqrt(l0); - l1 = sqrt(l1); - - if ( (l0 < MMG5_EPSD2) || (l1 < MMG5_EPSD2) ) { - t[0] = p1->c[0] - p0->c[0]; - t[1] = p1->c[1] - p0->c[1]; - t[2] = p1->c[2] - p0->c[2]; - } - else if ( l0 < l1 ) { - dd = l0 / l1; - t[0] = dd*(p1->c[0] - ppt->c[0]) + ppt->c[0] - p0->c[0]; - t[1] = dd*(p1->c[1] - ppt->c[1]) + ppt->c[1] - p0->c[1]; - t[2] = dd*(p1->c[2] - ppt->c[2]) + ppt->c[2] - p0->c[2]; - } - else { - dd = l1 / l0; - t[0] = dd*(p0->c[0] - ppt->c[0]) + ppt->c[0] - p1->c[0]; - t[1] = dd*(p0->c[1] - ppt->c[1]) + ppt->c[1] - p1->c[1]; - t[2] = dd*(p0->c[2] - ppt->c[2]) + ppt->c[2] - p1->c[2]; - } + MMG3D_compute_tangent(mesh,nump,ip0,ip1,t); dd = t[0]*t[0] + t[1]*t[1] + t[2]*t[2]; if ( dd > MMG5_EPSD2 ) { From 8c1e4e4c9c7f259e429d81a1bd85c8d4c0e05a12 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 20 Jul 2021 17:54:37 +0200 Subject: [PATCH 123/170] Add subfunction to compute tangent in boulep. --- src/mmg3d/boulep_3d.c | 117 +++++++++++++++++++----------------------- 1 file changed, 53 insertions(+), 64 deletions(-) diff --git a/src/mmg3d/boulep_3d.c b/src/mmg3d/boulep_3d.c index c4db5068d..00447a3b9 100644 --- a/src/mmg3d/boulep_3d.c +++ b/src/mmg3d/boulep_3d.c @@ -139,6 +139,44 @@ int MMG3D_findEdge(MMG5_pMesh mesh,MMG5_pTetra pt,int k,int na,int nb,int error, return 0; } +static inline +void MMG3D_compute_tangent(MMG5_pMesh mesh,int nump,int ip0,int ip1,double t[3]) { + MMG5_pPoint ppt,p0,p1; + double l0,l1,dd; + int8_t i; + + ppt = &mesh->point[nump]; + p0 = &mesh->point[ip0]; + p1 = &mesh->point[ip1]; + + l0 = (ppt->c[0] - p0->c[0])*(ppt->c[0] - p0->c[0]) \ + + (ppt->c[1] - p0->c[1])*(ppt->c[1] - p0->c[1]) + (ppt->c[2] - p0->c[2])*(ppt->c[2] - p0->c[2]); + l1 = (ppt->c[0] - p1->c[0])*(ppt->c[0] - p1->c[0]) \ + + (ppt->c[1] - p1->c[1])*(ppt->c[1] - p1->c[1]) + (ppt->c[2] - p1->c[2])*(ppt->c[2] - p1->c[2]); + l0 = sqrt(l0); + l1 = sqrt(l1); + + if ( (l0 < MMG5_EPSD2) || (l1 < MMG5_EPSD2) ) { + for ( i=0; i<3; ++i ) { + t[i] = p1->c[i] - p0->c[i]; + } + } + else if ( l0 < l1 ) { + dd = l0 / l1; + for ( i=0; i<3; ++i ) { + t[i] = dd*(p1->c[i] - ppt->c[i]) + ppt->c[i] - p0->c[i]; + } + } + else { + dd = l1 / l0; + for ( i=0; i<3; ++i ) { + t[i] = dd*(p0->c[i] - ppt->c[i]) + ppt->c[i] - p1->c[i]; + } + } + + return; +} + /** * \param mesh pointer toward the mesh structure. * \param start tetra index. @@ -155,8 +193,7 @@ int MMG3D_findEdge(MMG5_pMesh mesh,MMG5_pTetra pt,int k,int na,int nb,int error, int MMG5_boulenm(MMG5_pMesh mesh,int start,int ip,int iface, double n[3],double t[3]) { MMG5_pTetra pt; - MMG5_pPoint p0,p1,ppt; - double dd,nt[3],l0,l1; + double dd,nt[3]; int base,nump,nr,nnm,k,piv,na,nb,adj,nvstart,fstart,aux,ip0,ip1; int *adja; int16_t tag; @@ -264,34 +301,8 @@ int MMG5_boulenm(MMG5_pMesh mesh,int start,int ip,int iface, assert( ip0 && ip1 ); if ( ip0 == ip1 ) return 0; - p0 = &mesh->point[ip0]; - p1 = &mesh->point[ip1]; - ppt = &mesh->point[nump]; + MMG3D_compute_tangent(mesh,nump,ip0,ip1,t); - l0 = (ppt->c[0] - p0->c[0])*(ppt->c[0] - p0->c[0]) \ - + (ppt->c[1] - p0->c[1])*(ppt->c[1] - p0->c[1]) + (ppt->c[2] - p0->c[2])*(ppt->c[2] - p0->c[2]); - l1 = (ppt->c[0] - p1->c[0])*(ppt->c[0] - p1->c[0]) \ - + (ppt->c[1] - p1->c[1])*(ppt->c[1] - p1->c[1]) + (ppt->c[2] - p1->c[2])*(ppt->c[2] - p1->c[2]); - l0 = sqrt(l0); - l1 = sqrt(l1); - - if ( (l0 < MMG5_EPSD2) || (l1 < MMG5_EPSD2) ) { - t[0] = p1->c[0] - p0->c[0]; - t[1] = p1->c[1] - p0->c[1]; - t[2] = p1->c[2] - p0->c[2]; - } - else if ( l0 < l1 ) { - dd = l0 / l1; - t[0] = dd*(p1->c[0] - ppt->c[0]) + ppt->c[0] - p0->c[0]; - t[1] = dd*(p1->c[1] - ppt->c[1]) + ppt->c[1] - p0->c[1]; - t[2] = dd*(p1->c[2] - ppt->c[2]) + ppt->c[2] - p0->c[2]; - } - else { - dd = l1 / l0; - t[0] = dd*(p0->c[0] - ppt->c[0]) + ppt->c[0] - p1->c[0]; - t[1] = dd*(p0->c[1] - ppt->c[1]) + ppt->c[1] - p1->c[1]; - t[2] = dd*(p0->c[2] - ppt->c[2]) + ppt->c[2] - p1->c[2]; - } dd = t[0]*n[0] + t[1]*n[1] + t[2]*n[2]; t[0] -= dd*n[0]; t[1] -= dd*n[1]; @@ -308,16 +319,21 @@ int MMG5_boulenm(MMG5_pMesh mesh,int start,int ip,int iface, return 1; } -/** -Travel the ball of the internal non manifold point ip in tetra start - and calculate the tangent vector to the underlying curve. - Return 1 when the procedure has completed successfully, 0 when more than two NOM points are attached to ip. -*/ +/** + * \param mesh pointer toward the mesh structure. + * \param start tetra index. + * \param ip point index. + * \param t computed tangent vector. + * \return 0 when more than two NOM points are attached to ip, 1 if sucess. + * + * Travel the ball of the internal non manifold point ip in tetra start + * and calculate the tangent vector to the underlying curve. + * + */ int MMG5_boulenmInt(MMG5_pMesh mesh,int start,int ip,double t[3]) { MMG5_pTetra pt,pt1; MMG5_pxTetra pxt; - MMG5_pPoint p0,p1,ppt; - double l0,l1,dd; + double dd; int k,kk,ip0,ip1,nump,na,nb,base,cur,ilist,*adja; int list[MMG3D_LMAX+2]; int8_t i,j,ii,ie; @@ -395,34 +411,7 @@ int MMG5_boulenmInt(MMG5_pMesh mesh,int start,int ip,double t[3]) { } /* At this point, the two points connected to ppt via the NOM curve are ip0 and ip1 */ - ppt = &mesh->point[nump]; - p0 = &mesh->point[ip0]; - p1 = &mesh->point[ip1]; - - l0 = (ppt->c[0] - p0->c[0])*(ppt->c[0] - p0->c[0]) \ - + (ppt->c[1] - p0->c[1])*(ppt->c[1] - p0->c[1]) + (ppt->c[2] - p0->c[2])*(ppt->c[2] - p0->c[2]); - l1 = (ppt->c[0] - p1->c[0])*(ppt->c[0] - p1->c[0]) \ - + (ppt->c[1] - p1->c[1])*(ppt->c[1] - p1->c[1]) + (ppt->c[2] - p1->c[2])*(ppt->c[2] - p1->c[2]); - l0 = sqrt(l0); - l1 = sqrt(l1); - - if ( (l0 < MMG5_EPSD2) || (l1 < MMG5_EPSD2) ) { - t[0] = p1->c[0] - p0->c[0]; - t[1] = p1->c[1] - p0->c[1]; - t[2] = p1->c[2] - p0->c[2]; - } - else if ( l0 < l1 ) { - dd = l0 / l1; - t[0] = dd*(p1->c[0] - ppt->c[0]) + ppt->c[0] - p0->c[0]; - t[1] = dd*(p1->c[1] - ppt->c[1]) + ppt->c[1] - p0->c[1]; - t[2] = dd*(p1->c[2] - ppt->c[2]) + ppt->c[2] - p0->c[2]; - } - else { - dd = l1 / l0; - t[0] = dd*(p0->c[0] - ppt->c[0]) + ppt->c[0] - p1->c[0]; - t[1] = dd*(p0->c[1] - ppt->c[1]) + ppt->c[1] - p1->c[1]; - t[2] = dd*(p0->c[2] - ppt->c[2]) + ppt->c[2] - p1->c[2]; - } + MMG3D_compute_tangent(mesh,nump,ip0,ip1,t); dd = t[0]*t[0] + t[1]*t[1] + t[2]*t[2]; if ( dd > MMG5_EPSD2 ) { From 69f6459ee7a5bed159d563d2b9747884d7e6b5ee Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 20 Jul 2021 17:55:09 +0200 Subject: [PATCH 124/170] Whitespace cleanup in boulep. --- src/mmg3d/boulep_3d.c | 62 +++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/src/mmg3d/boulep_3d.c b/src/mmg3d/boulep_3d.c index 00447a3b9..ccb7a6d6a 100644 --- a/src/mmg3d/boulep_3d.c +++ b/src/mmg3d/boulep_3d.c @@ -337,23 +337,23 @@ int MMG5_boulenmInt(MMG5_pMesh mesh,int start,int ip,double t[3]) { int k,kk,ip0,ip1,nump,na,nb,base,cur,ilist,*adja; int list[MMG3D_LMAX+2]; int8_t i,j,ii,ie; - + base = ++mesh->base; ip0 = ip1 = 0; cur = ilist = 0; - + /* Store initial tetrahedron */ pt = &mesh->tetra[start]; nump = pt->v[ip]; list[0] = 4*start+ip; pt->flag = base; ilist++; - + while ( cur < ilist ) { k = list[cur] / 4; i = list[cur] % 4; pt = &mesh->tetra[k]; - + /* If pt bears geometric information, search for endpoints of the NOM curve of ppt */ if ( pt->xt ) { pxt = &mesh->xtetra[pt->xt]; @@ -385,34 +385,34 @@ int MMG5_boulenmInt(MMG5_pMesh mesh,int start,int ip,double t[3]) { } } } - + /* Pile up tetrahedra in the ball of nump */ adja = &mesh->adja[4*(k-1)+1]; - + for (j=0; j<3; j++) { i = MMG5_inxt3[i]; kk = adja[i] / 4; assert ( kk ); - + pt1 = &mesh->tetra[kk]; if ( pt1->flag == base ) continue; - + for (ii=0; ii<4; ii++) if ( pt1->v[ii] == nump ) break; assert ( ii < 4 ); - + list[ilist] = 4*kk+ii; pt1->flag = base; if ( ilist > MMG3D_LMAX-3 ) return 0; ilist++; } - + cur++; } - + /* At this point, the two points connected to ppt via the NOM curve are ip0 and ip1 */ MMG3D_compute_tangent(mesh,nump,ip0,ip1,t); - + dd = t[0]*t[0] + t[1]*t[1] + t[2]*t[2]; if ( dd > MMG5_EPSD2 ) { dd = 1.0 / sqrt(dd); @@ -420,7 +420,7 @@ int MMG5_boulenmInt(MMG5_pMesh mesh,int start,int ip,double t[3]) { t[1] *= dd; t[2] *= dd; } - + return 1; } @@ -749,26 +749,26 @@ int MMG5_boulesurfvolpNom(MMG5_pMesh mesh,int start,int ip,int iface, int base,nump,k,k1,*adja,piv,na,nb,adj,cur,nvstart,fstart,aux; int8_t iopp,ipiv,i,j,l,isface; static int8_t mmgErr0=0, mmgErr1=0, mmgErr2=0; - + if ( isnm ) assert(!mesh->adja[4*(start-1)+iface+1]); - + base = ++mesh->base; *ilists = 0; *ilistv = 0; *refmin = -1; *refplus = -1; - + pt = &mesh->tetra[start]; nump = pt->v[ip]; k = start; - + na = pt->v[ip]; nb = pt->v[MMG5_idir[iface][MMG5_inxt2[MMG5_idirinv[iface][ip]]]]; piv = pt->v[MMG5_idir[iface][MMG5_iprv2[MMG5_idirinv[iface][ip]]]]; - + iopp = iface; fstart = 4*k+iopp; - + do { /* A boundary face has been hit : change travel edge */ lists[(*ilists)] = 4*k+iopp; @@ -783,16 +783,16 @@ int MMG5_boulesurfvolpNom(MMG5_pMesh mesh,int start,int ip,int iface, MMG3D_indPt(mesh,nump)); mmgErr0 = 1; } - + return -1; } - + aux = nb; nb = piv; piv = aux; nvstart = k; adj = k; - + /* Now unfold shell of edge (na,nb) starting from k (included)*/ do { k = adj; @@ -804,7 +804,7 @@ int MMG5_boulesurfvolpNom(MMG5_pMesh mesh,int start,int ip,int iface, assert(i<4); listv[(*ilistv)] = 4*k+i; (*ilistv)++; - + /* Identify references of both subdomains in presence */ if ( *refmin == -1 ) *refmin = pt->ref; @@ -816,10 +816,10 @@ int MMG5_boulesurfvolpNom(MMG5_pMesh mesh,int start,int ip,int iface, } pt->flag = base; } - + /* identification of edge number in tetra k */ if ( !MMG3D_findEdge(mesh,pt,k,na,nb,0,&mmgErr2,&i) ) return -1; - + /* set sense of travel */ if ( pt->v[ MMG5_ifar[i][0] ] == piv ) { iopp = MMG5_ifar[i][0]; @@ -847,14 +847,14 @@ int MMG5_boulesurfvolpNom(MMG5_pMesh mesh,int start,int ip,int iface, while ( adj && (adj != nvstart) && !isface ); } while ( 4*k+iopp != fstart ); - + /* Now, surfacic ball is complete ; finish travel of volumic ball */ cur = 0; // Check numerotation while ( cur < (*ilistv) ) { k = listv[cur]/4; i = listv[cur]%4; // index of point p in tetra k adja = &mesh->adja[4*(k-1)+1]; - + for (l=0; l<3; l++) { i = MMG5_inxt3[i]; k1 = adja[i]; @@ -863,11 +863,11 @@ int MMG5_boulesurfvolpNom(MMG5_pMesh mesh,int start,int ip,int iface, pt1 = &mesh->tetra[k1]; if ( pt1->flag == base ) continue; pt1->flag = base; - + for (j=0; j<4; j++) if ( pt1->v[j] == nump ) break; assert(j<4); - + /* overflow */ if ( *ilistv > MMG3D_LMAX-3 ) { if ( !mmgErr1 ) { @@ -882,7 +882,7 @@ int MMG5_boulesurfvolpNom(MMG5_pMesh mesh,int start,int ip,int iface, } listv[(*ilistv)] = 4*k1+j; (*ilistv)++; - + /* Identify references of both subdomains in presence */ if ( *refmin == -1 ) *refmin = pt1->ref; @@ -895,7 +895,7 @@ int MMG5_boulesurfvolpNom(MMG5_pMesh mesh,int start,int ip,int iface, } cur++; } - + return 1; } From 2153628b655f7a7ebc6a8d7c9d0946721320df02 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 20 Jul 2021 20:41:06 +0200 Subject: [PATCH 125/170] Remove duplication in deltag function. --- src/mmg3d/boulep_3d.c | 108 +++++++++++++++++++++++------------------- 1 file changed, 60 insertions(+), 48 deletions(-) diff --git a/src/mmg3d/boulep_3d.c b/src/mmg3d/boulep_3d.c index ccb7a6d6a..f2d52dad1 100644 --- a/src/mmg3d/boulep_3d.c +++ b/src/mmg3d/boulep_3d.c @@ -1127,7 +1127,7 @@ int MMG5_bouletrid(MMG5_pMesh mesh,int start,int iface,int ip,int *il1,int *l1, * \param na edge vertex * \param nb edge vertex * \param tag new edge tag - * \param ref new edge ref + * \param edg new edge ref * \param piv global index of the pivot to set the sense of travel * \param adj index of adjacent tetra for the travel * @@ -1187,7 +1187,7 @@ int MMG3D_settag_oneDir(MMG5_pMesh mesh,int start, int na, int nb, * \param start tetra from which we start * \param ia local index of the edge in \a start * \param tag tag to set - * \param edge edge reference to set + * \param edg edge reference to set * * \return 1 if success, 0 if fail. * @@ -1247,6 +1247,58 @@ int MMG5_settag(MMG5_pMesh mesh,int start,int ia,int16_t tag,int edg) { return 1; } +/** + * \param mesh pointer toward the mesh + * \param start tetra from which we start to travel + * \param na edge vertex + * \param nb edge vertex + * \param tag new edge tag + * \param piv global index of the pivot to set the sense of travel + * \param adj index of adjacent tetra for the travel + * + * \return -1 if fail, \a start if shell has been completely travelled, 0 otherwise + * + * Remove the tag \a tag of edge \a ia in tetra \a start by travelling its + * shell in one direction (given by the pivot \a piv). + * + */ +static inline +int MMG3D_deltag_oneDir(MMG5_pMesh mesh,int start, int na, int nb, + int16_t tag,int piv,int adj) { + MMG5_pTetra pt; + MMG5_pxTetra pxt; + int *adja; + int8_t i; + + while ( adj && (adj != start) ) { + pt = &mesh->tetra[adj]; + + /* identification of edge number in tetra adj */ + if ( !MMG3D_findEdge(mesh,pt,adj,na,nb,1,NULL,&i) ) { + return -1; + } + + if ( pt->xt ) { + pxt = &mesh->xtetra[pt->xt]; + if ( (pxt->ftag[MMG5_ifar[i][0]] & MG_BDY) || + (pxt->ftag[MMG5_ifar[i][1]] & MG_BDY) ) { + pxt->tag[i] &= ~tag; + } + } + /* set new triangle for travel */ + adja = &mesh->adja[4*(adj-1)+1]; + if ( pt->v[ MMG5_ifar[i][0] ] == piv ) { + adj = adja[ MMG5_ifar[i][0] ] / 4; + piv = pt->v[ MMG5_ifar[i][1] ]; + } + else { + adj = adja[ MMG5_ifar[i][1] ] /4; + piv = pt->v[ MMG5_ifar[i][0] ]; + } + } + return adj; +} + /** * \param mesh pointer toward the mesh structure * \param start index of the starting tetra @@ -1262,7 +1314,6 @@ int MMG5_deltag(MMG5_pMesh mesh,int start,int ia,int16_t tag) { MMG5_pTetra pt; MMG5_pxTetra pxt; int na,nb,*adja,adj,piv; - int8_t i; assert( start >= 1 ); pt = &mesh->tetra[start]; @@ -1282,33 +1333,13 @@ int MMG5_deltag(MMG5_pMesh mesh,int start,int ia,int16_t tag) { pxt->tag[ia] &= ~tag; } } - while ( adj && (adj != start) ) { - pt = &mesh->tetra[adj]; - /* identification of edge number in tetra adj */ - if ( !MMG3D_findEdge(mesh,pt,adj,na,nb,1,NULL,&i) ) return 0; - - if ( pt->xt ) { - pxt = &mesh->xtetra[pt->xt]; - if ( (pxt->ftag[MMG5_ifar[i][0]] & MG_BDY) || - (pxt->ftag[MMG5_ifar[i][1]] & MG_BDY) ) { - pxt->tag[i] &= ~tag; - } - } - /* set new triangle for travel */ - adja = &mesh->adja[4*(adj-1)+1]; - if ( pt->v[ MMG5_ifar[i][0] ] == piv ) { - adj = adja[ MMG5_ifar[i][0] ] / 4; - piv = pt->v[ MMG5_ifar[i][1] ]; - } - else { - adj = adja[ MMG5_ifar[i][1] ] /4; - piv = pt->v[ MMG5_ifar[i][0] ]; - } - } + adj = MMG3D_deltag_oneDir(mesh,start,na,nb,tag,piv,adj); /* If all shell has been travelled, stop, else, travel it the other sense */ if ( adj == start ) return 1; + else if ( adj < 0 ) return 0; + assert(!adj); pt = &mesh->tetra[start]; @@ -1316,29 +1347,10 @@ int MMG5_deltag(MMG5_pMesh mesh,int start,int ia,int16_t tag) { adj = adja[MMG5_ifar[ia][1]] / 4; piv = pt->v[MMG5_ifar[ia][0]]; - while ( adj && (adj != start) ) { - pt = &mesh->tetra[adj]; - /* identification of edge number in tetra adj */ - if ( !MMG3D_findEdge(mesh,pt,adj,na,nb,1,NULL,&i) ) return 0; + adj = MMG3D_deltag_oneDir(mesh,start,na,nb,tag,piv,adj); + + if ( adj < 0 ) return 0; - if ( pt->xt ) { - pxt = &mesh->xtetra[pt->xt]; - if ( (pxt->ftag[MMG5_ifar[i][0]] & MG_BDY) || - (pxt->ftag[MMG5_ifar[i][1]] & MG_BDY) ) { - pxt->tag[i] &= ~tag; - } - } - /* set new triangle for travel */ - adja = &mesh->adja[4*(adj-1)+1]; - if ( pt->v[ MMG5_ifar[i][0] ] == piv ) { - adj = adja[ MMG5_ifar[i][0] ] / 4; - piv = pt->v[ MMG5_ifar[i][1] ]; - } - else { - adj = adja[ MMG5_ifar[i][1] ] /4; - piv = pt->v[ MMG5_ifar[i][0] ]; - } - } return 1; } From 4c15387abb405438afb2788e01c6e93c8e4fa63e Mon Sep 17 00:00:00 2001 From: Algiane Date: Wed, 21 Jul 2021 09:35:27 +0200 Subject: [PATCH 126/170] movpt_3d refactoring. --- src/mmg3d/anisomovpt_3d.c | 130 +++++--------------------------- src/mmg3d/mmg3d.h | 1 + src/mmg3d/movpt_3d.c | 155 +++++++++++++++++++++++--------------- 3 files changed, 113 insertions(+), 173 deletions(-) diff --git a/src/mmg3d/anisomovpt_3d.c b/src/mmg3d/anisomovpt_3d.c index b6ea18b9e..53cd2c844 100644 --- a/src/mmg3d/anisomovpt_3d.c +++ b/src/mmg3d/anisomovpt_3d.c @@ -200,12 +200,12 @@ int MMG5_movbdyregpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre MMG5_pPoint p0,p1,p2,ppt0; MMG5_Tria tt; MMG5_pxPoint pxp; - MMG5_Bezier pb; - double *n,r[3][3],lispoi[3*MMG3D_LMAX+1],ux,uy,uz,det2d; + MMG5_Bezier pb; + double *n,r[3][3],lispoi[3*MMG3D_LMAX+1],det2d; double detloc,gv[2],step,lambda[3]; double uv[2],o[3],no[3],to[3],*m0,ncur[3],nprev[3],nneighi[3]; double calold,calnew,caltmp,*callist; - int k,kel,iel,l,n0,na,nb,ntempa,ntempb,ntempc,nxp,ier; + int k,kel,iel,l,ip0,na,nb,ntempb,ntempc,nxp,ier; uint8_t i0,iface,i; static int warn = 0; @@ -215,9 +215,9 @@ int MMG5_movbdyregpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre k = listv[0] / 4; i0 = listv[0] % 4; pt = &mesh->tetra[k]; - n0 = pt->v[i0]; - p0 = &mesh->point[n0]; - m0 = &met->m[6*n0]; + ip0 = pt->v[i0]; + p0 = &mesh->point[ip0]; + m0 = &met->m[6*ip0]; assert( p0->xp && !MG_EDG(p0->tag) ); n = &(mesh->xpoint[p0->xp].n1[0]); @@ -229,103 +229,7 @@ int MMG5_movbdyregpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre /** Step 2 : rotation of the oriented surfacic ball with r : lispoi[k] is the common edge between faces lists[k-1] and lists[k] */ - k = lists[0] / 4; - iface = lists[0] % 4; - pt = &mesh->tetra[k]; - na = nb = 0; - for (i=0; i<3; i++) { - if ( pt->v[MMG5_idir[iface][i]] != n0 ) { - if ( !na ) - na = pt->v[MMG5_idir[iface][i]]; - else - nb = pt->v[MMG5_idir[iface][i]]; - } - } - - for (l=1; ltetra[k]; - ntempa = ntempb = 0; - for (i=0; i<3; i++) { - if ( pt->v[MMG5_idir[iface][i]] != n0 ) { - if ( !ntempa ) - ntempa = pt->v[MMG5_idir[iface][i]]; - else - ntempb = pt->v[MMG5_idir[iface][i]]; - } - } - if ( ntempa == na ) - p1 = &mesh->point[na]; - else if ( ntempa == nb ) - p1 = &mesh->point[nb]; - else if ( ntempb == na ) - p1 = &mesh->point[na]; - else { - assert(ntempb == nb); - p1 = &mesh->point[nb]; - } - ux = p1->c[0] - p0->c[0]; - uy = p1->c[1] - p0->c[1]; - uz = p1->c[2] - p0->c[2]; - - lispoi[3*l+1] = r[0][0]*ux + r[0][1]*uy + r[0][2]*uz; - lispoi[3*l+2] = r[1][0]*ux + r[1][1]*uy + r[1][2]*uz; - lispoi[3*l+3] = r[2][0]*ux + r[2][1]*uy + r[2][2]*uz; - - na = ntempa; - nb = ntempb; - } - - /* Finish with point 0 */; - k = lists[0] / 4; - iface = lists[0] % 4; - pt = &mesh->tetra[k]; - ntempa = ntempb = 0; - for (i=0; i<3; i++) { - if ( pt->v[MMG5_idir[iface][i]] != n0 ) { - if ( !ntempa ) - ntempa = pt->v[MMG5_idir[iface][i]]; - else - ntempb = pt->v[MMG5_idir[iface][i]]; - } - } - if ( ntempa == na ) - p1 = &mesh->point[na]; - else if ( ntempa == nb ) - p1 = &mesh->point[nb]; - else if ( ntempb == na ) - p1 = &mesh->point[na]; - else { - assert(ntempb == nb); - p1 = &mesh->point[nb]; - } - - ux = p1->c[0] - p0->c[0]; - uy = p1->c[1] - p0->c[1]; - uz = p1->c[2] - p0->c[2]; - - lispoi[1] = r[0][0]*ux + r[0][1]*uy + r[0][2]*uz; - lispoi[2] = r[1][0]*ux + r[1][1]*uy + r[1][2]*uz; - lispoi[3] = r[2][0]*ux + r[2][1]*uy + r[2][2]*uz; - - /* list goes modulo ilist */ - lispoi[3*ilists+1] = lispoi[1]; - lispoi[3*ilists+2] = lispoi[2]; - lispoi[3*ilists+3] = lispoi[3]; - - /* At this point, lispoi contains the oriented surface ball of point p0, that has been rotated - through r, with the convention that triangle l has edges lispoi[l]; lispoi[l+1] */ - - /* Check all projections over tangent plane. */ - for (k=0; kv[i] != n0) && (pt->v[i] != pt->v[iface]) ) { + if ( (pt->v[i] != ip0) && (pt->v[i] != pt->v[iface]) ) { if ( !na ) na = pt->v[i]; else @@ -456,7 +360,7 @@ int MMG5_movbdyregpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre else if (ntempb == nb ) uv[0] = lambda[2]; else { - assert(ntempb == n0); + assert(ntempb == ip0); uv[0] = lambda[0]; } if ( ntempc == na ) @@ -464,7 +368,7 @@ int MMG5_movbdyregpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre else if (ntempc == nb ) uv[1] = lambda[2]; else { - assert(ntempc == n0); + assert(ntempc == ip0); uv[1] = lambda[0]; } } @@ -475,7 +379,7 @@ int MMG5_movbdyregpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre else if (ntempb == nb ) uv[0] = lambda[1]; else { - assert(ntempb == n0); + assert(ntempb == ip0); uv[0] = lambda[0]; } if ( ntempc == na ) @@ -483,7 +387,7 @@ int MMG5_movbdyregpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre else if (ntempc == nb ) uv[1] = lambda[1]; else { - assert(ntempc == n0); + assert(ntempc == ip0); uv[1] = lambda[0]; } } @@ -522,14 +426,14 @@ int MMG5_movbdyregpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre /* For each surfacic triangle build a virtual displaced triangle for check * purposes : * - check the new triangle qualities; - * - check normal deviation with the adjacent through the edge facing n0 + * - check normal deviation with the adjacent through the edge facing ip0 * and the previous one */ k = lists[ilists-1] / 4; iface = lists[ilists-1] % 4; MMG5_tet2tri(mesh,k,iface,&tt); for( i=0 ; i<3 ; i++ ) - if ( tt.v[i] == n0 ) break; + if ( tt.v[i] == ip0 ) break; assert ( i<3 ); if ( i>=3 ) return 0; tt.v[i] = 0; @@ -545,7 +449,7 @@ int MMG5_movbdyregpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre calold = MG_MIN(calold,MMG5_caltri(mesh,met,&tt)); for( i=0 ; i<3 ; i++ ) - if ( tt.v[i] == n0 ) break; + if ( tt.v[i] == ip0 ) break; assert ( i<3 ); if ( i>=3 ) return 0; @@ -562,7 +466,7 @@ int MMG5_movbdyregpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre if ( !MMG5_nortri(mesh, &tt, ncur) ) return 0; if ( ( !(tt.tag[i] & MG_GEO) ) && ( !(tt.tag[i] & MG_NOM) ) ) { - /* Check normal deviation between k and the triangle facing n0 */ + /* Check normal deviation between k and the triangle facing ip0 */ ier = MMG3D_normalAdjaTri(mesh,k,iface, i,nneighi); if ( ier <= 0 ) { return 0; @@ -636,7 +540,7 @@ int MMG5_movbdyregpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre /* When all tests have been carried out, update coordinates, normals and metrics*/ if ( PROctree ) - MMG3D_movePROctree(mesh, PROctree, n0, o, p0->c); + MMG3D_movePROctree(mesh, PROctree, ip0, o, p0->c); p0->c[0] = o[0]; p0->c[1] = o[1]; diff --git a/src/mmg3d/mmg3d.h b/src/mmg3d/mmg3d.h index 65fa47b9a..c7b9688b2 100644 --- a/src/mmg3d/mmg3d.h +++ b/src/mmg3d/mmg3d.h @@ -364,6 +364,7 @@ int MMG5_split4bar(MMG5_pMesh mesh,MMG5_pSol met,int k,int8_t); int MMG3D_simbulgept(MMG5_pMesh mesh,MMG5_pSol met, int *list, int ilist,int); void MMG5_nsort(int ,double *,int8_t *); int MMG3D_optlap(MMG5_pMesh ,MMG5_pSol ); +int MMG3D_rotate_surfacicBall(MMG5_pMesh,int*,int,int,double r[3][3],double*); int MMG5_movintpt_iso(MMG5_pMesh ,MMG5_pSol,MMG3D_pPROctree, int *, int , int); int MMG3D_movnormal_iso(MMG5_pMesh ,MMG5_pSol ,int ,int ); int MMG5_movintptLES_iso(MMG5_pMesh mesh,MMG5_pSol met,MMG3D_pPROctree,int *,int,int); diff --git a/src/mmg3d/movpt_3d.c b/src/mmg3d/movpt_3d.c index d10cde556..fcb490da0 100755 --- a/src/mmg3d/movpt_3d.c +++ b/src/mmg3d/movpt_3d.c @@ -349,63 +349,34 @@ int MMG5_movintptLES_iso(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROctree /** * \param mesh pointer toward the mesh structure. - * \param met pointer toward the metric structure. - * \param PROctree pointer toward the PROctree structure. - * \param listv pointer toward the volumic ball of the point. - * \param ilistv size of the volumic ball. * \param lists pointer toward the surfacic ball of the point. * \param ilists size of the surfacic ball. - * \param improve force the new minimum element quality to be greater or equal - * than 1.02 of the old minimum element quality. - * \return 0 if we can not move, 1 if success, -1 if fail. + * \param ip0 global index of the point that we move + * \param r rotation matrix that sends the normal at \a ip0 to z-axis + * \param lispoi rotated surfacic ball (lispoi[k] is the common edge + * between faces lists[k-1] and lists[k]) * - * Move boundary regular point, whose volumic and surfacic balls are passed. + * \return 1 if success, 0 if the projection along the tangent plane are invalid. + * + * Rotation of the oriented surfacic ball of \a ip0. * - * \remark the metric is not interpolated at the new position. */ -int MMG5_movbdyregpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctree, int *listv, - int ilistv,int *lists,int ilists, - int improveSurf,int improveVol) { - MMG5_pTetra pt,pt0; - MMG5_pxTetra pxt; - MMG5_pPoint p0,p1,p2,ppt0; - MMG5_Tria tt; - MMG5_pxPoint pxp; - MMG5_Bezier b; - double *n,r[3][3],lispoi[3*MMG3D_LMAX+1],ux,uy,uz,det2d; - double detloc,oppt[2],step,lambda[3]; - double ll,m[2],uv[2],o[3],no[3],to[3]; - double calold,calnew,caltmp,*callist; - int k,kel,iel,l,n0,na,nb,ntempa,ntempb,ntempc,nut,nxp; - uint8_t i0,iface,i; - static int8_t mmgErr0=0,mmgErr1=0; - - step = 0.1; - nut = 0; - oppt[0] = 0.0; - oppt[1] = 0.0; - if ( ilists < 2 ) return 0; - - k = listv[0] / 4; - i0 = listv[0] % 4; - pt = &mesh->tetra[k]; - n0 = pt->v[i0]; - p0 = &mesh->point[n0]; - assert( p0->xp && !MG_EDG(p0->tag) ); +int MMG3D_rotate_surfacicBall(MMG5_pMesh mesh,int *lists,int ilists,int ip0, + double r[3][3],double *lispoi) { + MMG5_pTetra pt; + MMG5_pPoint p0,p1; + double ux,uy,uz,det2d; + int k,l,na,nb,ntempa,ntempb; + uint8_t iface,i; - n = &(mesh->xpoint[p0->xp].n1[0]); - - /** Step 1 : rotation matrix that sends normal n to the third coordinate vector of R^3 */ - if ( !MMG5_rotmatrix(n,r) ) return 0; - - /** Step 2 : rotation of the oriented surfacic ball with r : lispoi[k] is the common edge - between faces lists[k-1] and lists[k] */ k = lists[0] / 4; iface = lists[0] % 4; pt = &mesh->tetra[k]; + p0 = &mesh->point[ip0]; + na = nb = 0; for (i=0; i<3; i++) { - if ( pt->v[MMG5_idir[iface][i]] != n0 ) { + if ( pt->v[MMG5_idir[iface][i]] != ip0 ) { if ( !na ) na = pt->v[MMG5_idir[iface][i]]; else @@ -419,7 +390,7 @@ int MMG5_movbdyregpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre pt = &mesh->tetra[k]; ntempa = ntempb = 0; for (i=0; i<3; i++) { - if ( pt->v[MMG5_idir[iface][i]] != n0 ) { + if ( pt->v[MMG5_idir[iface][i]] != ip0 ) { if ( !ntempa ) ntempa = pt->v[MMG5_idir[iface][i]]; else @@ -454,7 +425,7 @@ int MMG5_movbdyregpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre pt = &mesh->tetra[k]; ntempa = ntempb = 0; for (i=0; i<3; i++) { - if ( pt->v[MMG5_idir[iface][i]] != n0 ) { + if ( pt->v[MMG5_idir[iface][i]] != ip0 ) { if ( !ntempa ) ntempa = pt->v[MMG5_idir[iface][i]]; else @@ -485,16 +456,80 @@ int MMG5_movbdyregpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre lispoi[3*ilists+2] = lispoi[2]; lispoi[3*ilists+3] = lispoi[3]; - /* At this point, lispoi contains the oriented surface ball of point p0, that has been rotated - through r, with the convention that triangle l has edges lispoi[l]; lispoi[l+1] */ - + /** At this point, lispoi contains the oriented surface ball of point p0, that + has been rotated through r, with the convention that triangle l has edges + lispoi[l]; lispoi[l+1] */ /* Check all projections over tangent plane. */ for (k=0; ktetra[k]; + ip0 = pt->v[i0]; + p0 = &mesh->point[ip0]; + assert( p0->xp && !MG_EDG(p0->tag) ); + + n = &(mesh->xpoint[p0->xp].n1[0]); + + /** Step 1 : rotation matrix that sends normal n to the third coordinate vector of R^3 */ + if ( !MMG5_rotmatrix(n,r) ) return 0; + + /** Step 2 : rotation of the oriented surfacic ball with r : lispoi[k] is the common edge + between faces lists[k-1] and lists[k] */ + if ( !MMG3D_rotate_surfacicBall(mesh,lists,ilists,ip0,r,lispoi) ) { + return 0; + } /** Step 3 : Compute optimal position to make current triangle equilateral, and average of these positions*/ @@ -584,7 +619,7 @@ int MMG5_movbdyregpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre positively oriented with respect to n */ na = nb = 0; for( i=0 ; i<4 ; i++ ){ - if ( (pt->v[i] != n0) && (pt->v[i] != pt->v[iface]) ) { + if ( (pt->v[i] != ip0) && (pt->v[i] != pt->v[iface]) ) { if ( !na ) na = pt->v[i]; else @@ -606,7 +641,7 @@ int MMG5_movbdyregpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre else if (ntempb == nb ) uv[0] = lambda[2]; else { - assert(ntempb == n0); + assert(ntempb == ip0); uv[0] = lambda[0]; } if ( ntempc == na ) @@ -614,7 +649,7 @@ int MMG5_movbdyregpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre else if (ntempc == nb ) uv[1] = lambda[2]; else { - assert(ntempc == n0); + assert(ntempc == ip0); uv[1] = lambda[0]; } } @@ -625,7 +660,7 @@ int MMG5_movbdyregpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre else if (ntempb == nb ) uv[0] = lambda[1]; else { - assert(ntempb == n0); + assert(ntempb == ip0); uv[0] = lambda[0]; } if ( ntempc == na ) @@ -633,7 +668,7 @@ int MMG5_movbdyregpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre else if (ntempc == nb ) uv[1] = lambda[1]; else { - assert(ntempc == n0); + assert(ntempc == ip0); uv[1] = lambda[0]; } } @@ -680,7 +715,7 @@ int MMG5_movbdyregpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre calold = MG_MIN(calold,MMG5_caltri(mesh,met,&tt)); for( i=0 ; i<3 ; i++ ) - if ( tt.v[i] == n0 ) break; + if ( tt.v[i] == ip0 ) break; assert(i<3); if ( i==3 ) return 0; @@ -745,7 +780,7 @@ int MMG5_movbdyregpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre /* When all tests have been carried out, update coordinates and normals */ if ( PROctree ) - MMG3D_movePROctree(mesh, PROctree, n0, o, p0->c); + MMG3D_movePROctree(mesh, PROctree, ip0, o, p0->c); p0->c[0] = o[0]; p0->c[1] = o[1]; From 9dd76cef65dcbabd7d487e6364a9e3d749bb7928 Mon Sep 17 00:00:00 2001 From: Algiane Date: Wed, 21 Jul 2021 09:52:24 +0200 Subject: [PATCH 127/170] Remove sonarqube bugs (unread values). --- src/mmg2d/inoutcpp_2d.cpp | 12 ++++++++++++ src/mmg3d/inoutcpp_3d.cpp | 8 ++++++++ src/mmgs/inoutcpp_s.cpp | 12 ++++++++++++ 3 files changed, 32 insertions(+) diff --git a/src/mmg2d/inoutcpp_2d.cpp b/src/mmg2d/inoutcpp_2d.cpp index dd8b2c745..ff1df2059 100644 --- a/src/mmg2d/inoutcpp_2d.cpp +++ b/src/mmg2d/inoutcpp_2d.cpp @@ -102,6 +102,10 @@ int MMG2D_loadVtpMesh(MMG5_pMesh mesh,MMG5_pSol sol,const char *filename) { // Mesh alloc and transfer of the mesh from dataset toward the MMG5 Mesh Sol ier = MMG2D_loadVtkMesh_part2(mesh,&sol,&dataset,ptMeditRef,eltMeditRef,nsols); + if ( ier < 1 ) { + fprintf(stderr," ** ERROR WHEN PARSING THE INPUT FILE\n"); + return ier; + } /* Check the metric type */ ier = MMG5_chkMetricType(mesh,&sol->type,NULL); @@ -169,6 +173,10 @@ int MMG2D_loadVtkMesh(MMG5_pMesh mesh,MMG5_pSol sol,const char *filename) { // Mesh alloc and transfer of the mesh from dataset toward the MMG5 Mesh Sol ier = MMG2D_loadVtkMesh_part2(mesh,&sol,&dataset,ptMeditRef,eltMeditRef,nsols); + if ( ier < 1 ) { + fprintf(stderr," ** ERROR WHEN PARSING THE INPUT FILE\n"); + return ier; + } /* Check the metric type */ ier = MMG5_chkMetricType(mesh,&sol->type,NULL); @@ -236,6 +244,10 @@ int MMG2D_loadVtuMesh(MMG5_pMesh mesh,MMG5_pSol sol,const char *filename) { // Mesh alloc and transfer of the mesh from dataset toward the MMG5 Mesh Sol ier = MMG2D_loadVtkMesh_part2(mesh,&sol,&dataset,ptMeditRef,eltMeditRef,nsols); + if ( ier < 1 ) { + fprintf(stderr," ** ERROR WHEN PARSING THE INPUT FILE\n"); + return ier; + } /* Check the metric type */ ier = MMG5_chkMetricType(mesh,&sol->type,NULL); diff --git a/src/mmg3d/inoutcpp_3d.cpp b/src/mmg3d/inoutcpp_3d.cpp index ce87f3334..1e7e31135 100644 --- a/src/mmg3d/inoutcpp_3d.cpp +++ b/src/mmg3d/inoutcpp_3d.cpp @@ -94,6 +94,10 @@ int MMG3D_loadVtuMesh(MMG5_pMesh mesh,MMG5_pSol sol,const char *filename) { // Mesh alloc and transfer of the mesh from dataset toward the MMG5 Mesh Sol ier = MMG3D_loadVtkMesh_part2(mesh,&sol,&dataset,ptMeditRef,eltMeditRef,nsols); + if ( ier < 1 ) { + fprintf(stderr," ** ERROR WHEN PARSING THE INPUT FILE\n"); + return ier; + } /* Check the metric type */ ier = MMG5_chkMetricType(mesh,&sol->type,NULL); @@ -159,6 +163,10 @@ int MMG3D_loadVtkMesh(MMG5_pMesh mesh,MMG5_pSol sol,const char *filename) { // Mesh alloc and transfer of the mesh from dataset toward the MMG5 Mesh Sol ier = MMG3D_loadVtkMesh_part2(mesh,&sol,&dataset,ptMeditRef,eltMeditRef,nsols); + if ( ier < 1 ) { + fprintf(stderr," ** ERROR WHEN PARSING THE INPUT FILE\n"); + return ier; + } /* Check the metric type */ ier = MMG5_chkMetricType(mesh,&sol->type,NULL); diff --git a/src/mmgs/inoutcpp_s.cpp b/src/mmgs/inoutcpp_s.cpp index 2bf8453d7..95aa40c1c 100644 --- a/src/mmgs/inoutcpp_s.cpp +++ b/src/mmgs/inoutcpp_s.cpp @@ -95,6 +95,10 @@ int MMGS_loadVtpMesh(MMG5_pMesh mesh,MMG5_pSol sol,const char *filename) { // Mesh alloc and transfer of the mesh from dataset toward the MMG5 Mesh Sol ier = MMGS_loadVtkMesh_part2(mesh,&sol,&dataset,ptMeditRef,eltMeditRef,nsols); + if ( ier < 1 ) { + fprintf(stderr," ** ERROR WHEN PARSING THE INPUT FILE\n"); + return ier; + } /* Check the metric type */ ier = MMG5_chkMetricType(mesh,&sol->type,NULL); @@ -159,6 +163,10 @@ int MMGS_loadVtkMesh(MMG5_pMesh mesh,MMG5_pSol sol,const char *filename) { // Mesh alloc and transfer of the mesh from dataset toward the MMG5 Mesh Sol ier = MMGS_loadVtkMesh_part2(mesh,&sol,&dataset,ptMeditRef,eltMeditRef,nsols); + if ( ier < 1 ) { + fprintf(stderr," ** ERROR WHEN PARSING THE INPUT FILE\n"); + return ier; + } /* Check the metric type */ ier = MMG5_chkMetricType(mesh,&sol->type,NULL); @@ -223,6 +231,10 @@ int MMGS_loadVtuMesh(MMG5_pMesh mesh,MMG5_pSol sol,const char *filename) { // Mesh alloc and transfer of the mesh from dataset toward the MMG5 Mesh Sol ier = MMGS_loadVtkMesh_part2(mesh,&sol,&dataset,ptMeditRef,eltMeditRef,nsols); + if ( ier < 1 ) { + fprintf(stderr," ** ERROR WHEN PARSING THE INPUT FILE\n"); + return ier; + } /* Check the metric type */ ier = MMG5_chkMetricType(mesh,&sol->type,NULL); From 60c94c3809d2f23bf273233aa5bac2a4e20fb895 Mon Sep 17 00:00:00 2001 From: Algiane Date: Wed, 21 Jul 2021 15:14:51 +0200 Subject: [PATCH 128/170] Add consistent return values for movbdyregpt_ani (with the iso version). --- src/mmg3d/anisomovpt_3d.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/mmg3d/anisomovpt_3d.c b/src/mmg3d/anisomovpt_3d.c index 53cd2c844..36b7e18eb 100644 --- a/src/mmg3d/anisomovpt_3d.c +++ b/src/mmg3d/anisomovpt_3d.c @@ -184,7 +184,7 @@ int MMG5_movintpt_ani(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROctree, i * \param improve force the new minimum element quality to be greater or equal * than 1.02 of the old minimum element quality. - * \return 0 if we can't move the point, 1 if we can. + * \return 0 if we can't move the point, 1 if we can, -1 if we fail. * * \remark we don't check if we break the hausdorff criterion. * \remark the metric is not interpolated at the new position. @@ -208,6 +208,7 @@ int MMG5_movbdyregpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre int k,kel,iel,l,ip0,na,nb,ntempb,ntempc,nxp,ier; uint8_t i0,iface,i; static int warn = 0; + static int8_t mmgErr0=0,mmgErr1=0; step = 0.1; if ( ilists < 2 ) return 0; @@ -247,7 +248,12 @@ int MMG5_movbdyregpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre MMG5_tet2tri(mesh,iel,iface,&tt); if(!MMG5_bezierCP(mesh,&tt,&pb,MG_GET(pxt->ori,iface))){ - return 0; + if( !mmgErr0 ) { + mmgErr0 = 1; + fprintf(stderr,"\n ## Error: %s: function MMG5_bezierCP return 0.\n", + __func__); + } + return -1; } /* Compute integral of sqrt(T^J(xi) M(P(xi)) J(xi)) * P(xi) over the triangle */ @@ -329,7 +335,12 @@ int MMG5_movbdyregpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre MMG5_tet2tri(mesh,iel,iface,&tt); if(!MMG5_bezierCP(mesh,&tt,&pb,MG_GET(pxt->ori,iface))){ - return 0; + if( !mmgErr0 ) { + mmgErr0 = 1; + fprintf(stderr,"\n ## Error: %s: function MMG5_bezierCP return 0.\n", + __func__); + } + return -1; } /* Now, for Bezier interpolation, one should identify which of i,i1,i2 is 0,1,2 @@ -392,7 +403,12 @@ int MMG5_movbdyregpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre } } if(!MMG3D_bezierInt(&pb,uv,o,no,to)){ - return 0; + if( !mmgErr1 ) { + mmgErr1 = 1; + fprintf(stderr," ## Error: %s: function MMG3D_bezierInt return 0.\n", + __func__); + } + return -1; } /* Test : make sure that geometric approximation has not been degraded too much */ From b305bcabdb60b6d72c2c5b74ea4e91565bf9de79 Mon Sep 17 00:00:00 2001 From: Algiane Date: Wed, 21 Jul 2021 15:20:07 +0200 Subject: [PATCH 129/170] Make movbdyregpt_ani function more similar to movebdyregpt_iso one (in order to refactorize it in future commit. --- src/mmg3d/anisomovpt_3d.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/mmg3d/anisomovpt_3d.c b/src/mmg3d/anisomovpt_3d.c index 36b7e18eb..9f1484462 100644 --- a/src/mmg3d/anisomovpt_3d.c +++ b/src/mmg3d/anisomovpt_3d.c @@ -200,7 +200,7 @@ int MMG5_movbdyregpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre MMG5_pPoint p0,p1,p2,ppt0; MMG5_Tria tt; MMG5_pxPoint pxp; - MMG5_Bezier pb; + MMG5_Bezier b; double *n,r[3][3],lispoi[3*MMG3D_LMAX+1],det2d; double detloc,gv[2],step,lambda[3]; double uv[2],o[3],no[3],to[3],*m0,ncur[3],nprev[3],nneighi[3]; @@ -247,7 +247,7 @@ int MMG5_movbdyregpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre MMG5_tet2tri(mesh,iel,iface,&tt); - if(!MMG5_bezierCP(mesh,&tt,&pb,MG_GET(pxt->ori,iface))){ + if(!MMG5_bezierCP(mesh,&tt,&b,MG_GET(pxt->ori,iface))){ if( !mmgErr0 ) { mmgErr0 = 1; fprintf(stderr,"\n ## Error: %s: function MMG5_bezierCP return 0.\n", @@ -257,7 +257,7 @@ int MMG5_movbdyregpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre } /* Compute integral of sqrt(T^J(xi) M(P(xi)) J(xi)) * P(xi) over the triangle */ - if ( !MMG5_elementWeight(mesh,met,&tt,p0,&pb,r,gv) ) { + if ( !MMG5_elementWeight(mesh,met,&tt,p0,&b,r,gv) ) { if ( !warn ) { ++warn; fprintf(stderr,"\n ## Warning: %s:" @@ -334,7 +334,7 @@ int MMG5_movbdyregpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre MMG5_tet2tri(mesh,iel,iface,&tt); - if(!MMG5_bezierCP(mesh,&tt,&pb,MG_GET(pxt->ori,iface))){ + if(!MMG5_bezierCP(mesh,&tt,&b,MG_GET(pxt->ori,iface))){ if( !mmgErr0 ) { mmgErr0 = 1; fprintf(stderr,"\n ## Error: %s: function MMG5_bezierCP return 0.\n", @@ -402,7 +402,7 @@ int MMG5_movbdyregpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre uv[1] = lambda[0]; } } - if(!MMG3D_bezierInt(&pb,uv,o,no,to)){ + if(!MMG3D_bezierInt(&b,uv,o,no,to)){ if( !mmgErr1 ) { mmgErr1 = 1; fprintf(stderr," ## Error: %s: function MMG3D_bezierInt return 0.\n", @@ -423,8 +423,8 @@ int MMG5_movbdyregpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre nxp = mesh->xp + 1; if ( nxp > mesh->xpmax ) { - MMG5_TAB_RECALLOC(mesh,mesh->xpoint,mesh->xpmax,0.2,MMG5_xPoint, - "larger xpoint table",return 0;); + MMG5_TAB_RECALLOC(mesh,mesh->xpoint,mesh->xpmax,MMG5_GAP,MMG5_xPoint, + "larger xpoint table",return 0); n = &(mesh->xpoint[p0->xp].n1[0]); } ppt0->xp = nxp; From 7183dcf5273479295730e446b92c7803f4b6995a Mon Sep 17 00:00:00 2001 From: Algiane Date: Wed, 21 Jul 2021 16:29:16 +0200 Subject: [PATCH 130/170] Remove duplications in movbdyregpt. --- src/mmg3d/anisomovpt_3d.c | 119 ++--------------- src/mmg3d/mmg3d.h | 1 + src/mmg3d/movpt_3d.c | 261 ++++++++++++++++++++++---------------- 3 files changed, 164 insertions(+), 217 deletions(-) diff --git a/src/mmg3d/anisomovpt_3d.c b/src/mmg3d/anisomovpt_3d.c index 9f1484462..07c5e2053 100644 --- a/src/mmg3d/anisomovpt_3d.c +++ b/src/mmg3d/anisomovpt_3d.c @@ -197,18 +197,18 @@ int MMG5_movbdyregpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre int improveSurf, int improveVol) { MMG5_pTetra pt,pt0; MMG5_pxTetra pxt; - MMG5_pPoint p0,p1,p2,ppt0; + MMG5_pPoint p0; MMG5_Tria tt; MMG5_pxPoint pxp; MMG5_Bezier b; double *n,r[3][3],lispoi[3*MMG3D_LMAX+1],det2d; double detloc,gv[2],step,lambda[3]; - double uv[2],o[3],no[3],to[3],*m0,ncur[3],nprev[3],nneighi[3]; + double o[3],no[3],*m0,ncur[3],nprev[3],nneighi[3]; double calold,calnew,caltmp,*callist; - int k,kel,iel,l,ip0,na,nb,ntempb,ntempc,nxp,ier; + int k,kel,iel,l,ip0,nxp,ier; uint8_t i0,iface,i; static int warn = 0; - static int8_t mmgErr0=0,mmgErr1=0; + static int8_t mmgErr0=0; step = 0.1; if ( ilists < 2 ) return 0; @@ -326,115 +326,18 @@ int MMG5_movbdyregpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre lambda[2]*= (det2d); lambda[0] = 1.0 - lambda[1] - lambda[2]; - /** Step 5 : come back to original problem, and compute patch in triangle iel */ - iel = lists[kel] / 4; - iface = lists[kel] % 4; - pt = &mesh->tetra[iel]; - pxt = &mesh->xtetra[pt->xt]; - - MMG5_tet2tri(mesh,iel,iface,&tt); - - if(!MMG5_bezierCP(mesh,&tt,&b,MG_GET(pxt->ori,iface))){ - if( !mmgErr0 ) { - mmgErr0 = 1; - fprintf(stderr,"\n ## Error: %s: function MMG5_bezierCP return 0.\n", - __func__); - } + /** Step 5 : come back to original problem, compute patch in triangle iel and + * check that geometric approx has not been degraded too much */ + nxp = MMG3D_movbdyregpt_geom(mesh,lists,kel,ip0,n,lambda,o,no); + if ( nxp < 0 ) { return -1; } - - /* Now, for Bezier interpolation, one should identify which of i,i1,i2 is 0,1,2 - recall uv[0] = barycentric coord associated to pt->v[1], uv[1] associated to pt->v[2] and - 1 - uv[0] - uv[1] is associated to pt->v[0]. For this, use the fact that kel, kel + 1 is - positively oriented with respect to n */ - na = nb = 0; - for( i=0 ; i<4 ; i++ ){ - if ( (pt->v[i] != ip0) && (pt->v[i] != pt->v[iface]) ) { - if ( !na ) - na = pt->v[i]; - else - nb = pt->v[i]; - } - } - p1 = &mesh->point[na]; - p2 = &mesh->point[nb]; - detloc = MMG5_det3pt1vec(p0->c,p1->c,p2->c,n); - - /* ntempa = point to which is associated 1 -uv[0] - uv[1], ntempb = uv[0], ntempc = uv[1] */ - ntempb = pt->v[MMG5_idir[iface][1]]; - ntempc = pt->v[MMG5_idir[iface][2]]; - - /* na = lispoi[kel] -> lambda[1], nb = lispoi[kel+1] -> lambda[2] */ - if ( detloc > 0.0 ) { - if ( ntempb == na ) - uv[0] = lambda[1]; - else if (ntempb == nb ) - uv[0] = lambda[2]; - else { - assert(ntempb == ip0); - uv[0] = lambda[0]; - } - if ( ntempc == na ) - uv[1] = lambda[1]; - else if (ntempc == nb ) - uv[1] = lambda[2]; - else { - assert(ntempc == ip0); - uv[1] = lambda[0]; - } - } - /* nb = lispoi[kel] -> lambda[1], na = lispoi[kel+1] -> lambda[2] */ - else { - if ( ntempb == na ) - uv[0] = lambda[2]; - else if (ntempb == nb ) - uv[0] = lambda[1]; - else { - assert(ntempb == ip0); - uv[0] = lambda[0]; - } - if ( ntempc == na ) - uv[1] = lambda[2]; - else if (ntempc == nb ) - uv[1] = lambda[1]; - else { - assert(ntempc == ip0); - uv[1] = lambda[0]; - } - } - if(!MMG3D_bezierInt(&b,uv,o,no,to)){ - if( !mmgErr1 ) { - mmgErr1 = 1; - fprintf(stderr," ## Error: %s: function MMG3D_bezierInt return 0.\n", - __func__); - } - return -1; - } - - /* Test : make sure that geometric approximation has not been degraded too much */ - ppt0 = &mesh->point[0]; - ppt0->c[0] = o[0]; - ppt0->c[1] = o[1]; - ppt0->c[2] = o[2]; - - ppt0->tag = p0->tag; - ppt0->ref = p0->ref; - - - nxp = mesh->xp + 1; - if ( nxp > mesh->xpmax ) { - MMG5_TAB_RECALLOC(mesh,mesh->xpoint,mesh->xpmax,MMG5_GAP,MMG5_xPoint, - "larger xpoint table",return 0); - n = &(mesh->xpoint[p0->xp].n1[0]); + else if ( !nxp ) { + return 0; } - ppt0->xp = nxp; pxp = &mesh->xpoint[nxp]; - memcpy(pxp,&(mesh->xpoint[p0->xp]),sizeof(MMG5_xPoint)); - pxp->n1[0] = no[0]; - pxp->n1[1] = no[1]; - pxp->n1[2] = no[2]; - // parallel transport of metric at p0 to new point. + /* parallel transport of metric at p0 to new point. */ if ( !MMG5_paratmet(p0->c,n,m0,o,no,&met->m[0]) ) { return 0; } diff --git a/src/mmg3d/mmg3d.h b/src/mmg3d/mmg3d.h index c7b9688b2..79d95758d 100644 --- a/src/mmg3d/mmg3d.h +++ b/src/mmg3d/mmg3d.h @@ -369,6 +369,7 @@ int MMG5_movintpt_iso(MMG5_pMesh ,MMG5_pSol,MMG3D_pPROctree, int *, int , int int MMG3D_movnormal_iso(MMG5_pMesh ,MMG5_pSol ,int ,int ); int MMG5_movintptLES_iso(MMG5_pMesh mesh,MMG5_pSol met,MMG3D_pPROctree,int *,int,int); int MMG5_movintpt_ani(MMG5_pMesh ,MMG5_pSol,MMG3D_pPROctree,int *,int ,int); +int MMG3D_movbdyregpt_geom(MMG5_pMesh,int *,const int,const int,double[3],double[3],double[3],double[3]); int MMG5_movbdyregpt_iso(MMG5_pMesh, MMG5_pSol,MMG3D_pPROctree, int*, int, int*, int, int ,int); int MMG5_movbdyregpt_ani(MMG5_pMesh, MMG5_pSol,MMG3D_pPROctree, diff --git a/src/mmg3d/movpt_3d.c b/src/mmg3d/movpt_3d.c index fcb490da0..2ebc6c126 100755 --- a/src/mmg3d/movpt_3d.c +++ b/src/mmg3d/movpt_3d.c @@ -474,6 +474,151 @@ int MMG3D_rotate_surfacicBall(MMG5_pMesh mesh,int *lists,int ilists,int ip0, return 1; } + +/** +* \param mesh pointer toward the mesh +* \param lists pointer toward the surface ball of \a ip0 +* \param kel index of the current element in the ball +* \param ip0 global index of the point to move +* \param n normal at \a ip0 +* \param lambda barycentric coor of the new point in triangle +* \param o coordinates of the new point (to compute) +* \param no normal at new point (to compute) +* +* \return -1 if fail, 0 if we can't move the point, \a nxp the index of the new +* xpoint at \a ip0 if success. +* +* Compute the Bezier patch at element \a lists[kel], compute the new point +* coordinates, normal and tangent and check the geometric approximation. +* +*/ +int MMG3D_movbdyregpt_geom(MMG5_pMesh mesh,int *lists,const int kel, + const int ip0,double n[3],double lambda[3],double o[3], + double no[3]) { + MMG5_pTetra pt; + MMG5_pxTetra pxt; + MMG5_pPoint p1,p2,ppt0,p0; + MMG5_Tria tt; + MMG5_pxPoint pxp; + MMG5_Bezier b; + double uv[2],to[3],detloc; + int iel,na,nb,ntempb,ntempc,nxp; + uint8_t iface,i; + static int8_t mmgErr0=0,mmgErr1=0; + + iel = lists[kel] / 4; + iface = lists[kel] % 4; + pt = &mesh->tetra[iel]; + pxt = &mesh->xtetra[pt->xt]; + p0 = &mesh->point[ip0]; + + MMG5_tet2tri(mesh,iel,iface,&tt); + + if(!MMG5_bezierCP(mesh,&tt,&b,MG_GET(pxt->ori,iface))){ + if( !mmgErr0 ) { + mmgErr0 = 1; + fprintf(stderr,"\n ## Error: %s: function MMG5_bezierCP return 0.\n", + __func__); + } + return -1; + } + + /* Now, for Bezier interpolation, one should identify which of i,i1,i2 is + 0,1,2 recall uv[0] = barycentric coord associated to pt->v[1], uv[1] + associated to pt->v[2] and 1-uv[0]-uv[1] is associated to pt->v[0]. For + this, use the fact that kel, kel + 1 is positively oriented with respect to + n */ + na = nb = 0; + for( i=0 ; i<4 ; i++ ){ + if ( (pt->v[i] != ip0) && (pt->v[i] != pt->v[iface]) ) { + if ( !na ) + na = pt->v[i]; + else + nb = pt->v[i]; + } + } + p1 = &mesh->point[na]; + p2 = &mesh->point[nb]; + detloc = MMG5_det3pt1vec(p0->c,p1->c,p2->c,n); + + /* ntempa=point to which is associated 1-uv[0]-uv[1], ntempb=uv[0], ntempc=uv[1] */ + ntempb = pt->v[MMG5_idir[iface][1]]; + ntempc = pt->v[MMG5_idir[iface][2]]; + + /* na = lispoi[kel] -> lambda[1], nb = lispoi[kel+1] -> lambda[2] */ + if ( detloc > 0.0 ) { + if ( ntempb == na ) + uv[0] = lambda[1]; + else if (ntempb == nb ) + uv[0] = lambda[2]; + else { + assert(ntempb == ip0); + uv[0] = lambda[0]; + } + if ( ntempc == na ) + uv[1] = lambda[1]; + else if (ntempc == nb ) + uv[1] = lambda[2]; + else { + assert(ntempc == ip0); + uv[1] = lambda[0]; + } + } + /* nb = lispoi[kel] -> lambda[1], na = lispoi[kel+1] -> lambda[2] */ + else { + if ( ntempb == na ) + uv[0] = lambda[2]; + else if (ntempb == nb ) + uv[0] = lambda[1]; + else { + assert(ntempb == ip0); + uv[0] = lambda[0]; + } + if ( ntempc == na ) + uv[1] = lambda[2]; + else if (ntempc == nb ) + uv[1] = lambda[1]; + else { + assert(ntempc == ip0); + uv[1] = lambda[0]; + } + } + if(!MMG3D_bezierInt(&b,uv,o,no,to)){ + if( !mmgErr1 ) { + mmgErr1 = 1; + fprintf(stderr," ## Error: %s: function MMG3D_bezierInt return 0.\n", + __func__); + } + return -1; + } + + /* Test : make sure that geometric approximation has not been degraded too much */ + ppt0 = &mesh->point[0]; + ppt0->c[0] = o[0]; + ppt0->c[1] = o[1]; + ppt0->c[2] = o[2]; + + ppt0->tag = p0->tag; + ppt0->ref = p0->ref; + + + nxp = mesh->xp + 1; + if ( nxp > mesh->xpmax ) { + MMG5_TAB_RECALLOC(mesh,mesh->xpoint,mesh->xpmax,MMG5_GAP,MMG5_xPoint, + "larger xpoint table", + return 0); + n = &(mesh->xpoint[p0->xp].n1[0]); + } + ppt0->xp = nxp; + pxp = &mesh->xpoint[nxp]; + memcpy(pxp,&(mesh->xpoint[p0->xp]),sizeof(MMG5_xPoint)); + pxp->n1[0] = no[0]; + pxp->n1[1] = no[1]; + pxp->n1[2] = no[2]; + + return nxp; +} + /** * \param mesh pointer toward the mesh structure. * \param met pointer toward the metric structure. @@ -494,18 +639,15 @@ int MMG5_movbdyregpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre int ilistv,int *lists,int ilists, int improveSurf,int improveVol) { MMG5_pTetra pt,pt0; - MMG5_pxTetra pxt; - MMG5_pPoint p0,p1,p2,ppt0; + MMG5_pPoint p0; MMG5_Tria tt; MMG5_pxPoint pxp; - MMG5_Bezier b; double *n,r[3][3],lispoi[3*MMG3D_LMAX+1],ux,uy,det2d; double detloc,oppt[2],step,lambda[3]; - double ll,m[2],uv[2],o[3],no[3],to[3]; + double ll,m[2],o[3],no[3]; double calold,calnew,caltmp,*callist; - int k,kel,iel,l,ip0,na,nb,ntempb,ntempc,nut,nxp; + int k,kel,l,ip0,nut,nxp; uint8_t i0,iface,i; - static int8_t mmgErr0=0,mmgErr1=0; step = 0.1; nut = 0; @@ -597,113 +739,14 @@ int MMG5_movbdyregpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre lambda[0] = 1.0 - lambda[1] - lambda[2]; /** Step 5 : come back to original problem, and compute patch in triangle iel */ - iel = lists[kel] / 4; - iface = lists[kel] % 4; - pt = &mesh->tetra[iel]; - pxt = &mesh->xtetra[pt->xt]; - - MMG5_tet2tri(mesh,iel,iface,&tt); - - if(!MMG5_bezierCP(mesh,&tt,&b,MG_GET(pxt->ori,iface))){ - if( !mmgErr0 ) { - mmgErr0 = 1; - fprintf(stderr,"\n ## Error: %s: function MMG5_bezierCP return 0.\n", - __func__); - } + nxp = MMG3D_movbdyregpt_geom(mesh,lists,kel,ip0,n,lambda,o,no); + if ( nxp < 0 ) { return -1; } - - /* Now, for Bezier interpolation, one should identify which of i,i1,i2 is 0,1,2 - recall uv[0] = barycentric coord associated to pt->v[1], uv[1] associated to pt->v[2] and - 1 - uv[0] - uv[1] is associated to pt->v[0]. For this, use the fact that kel, kel + 1 is - positively oriented with respect to n */ - na = nb = 0; - for( i=0 ; i<4 ; i++ ){ - if ( (pt->v[i] != ip0) && (pt->v[i] != pt->v[iface]) ) { - if ( !na ) - na = pt->v[i]; - else - nb = pt->v[i]; - } - } - p1 = &mesh->point[na]; - p2 = &mesh->point[nb]; - detloc = MMG5_det3pt1vec(p0->c,p1->c,p2->c,n); - - /* ntempa = point to which is associated 1 -uv[0] - uv[1], ntempb = uv[0], ntempc = uv[1] */ - ntempb = pt->v[MMG5_idir[iface][1]]; - ntempc = pt->v[MMG5_idir[iface][2]]; - - /* na = lispoi[kel] -> lambda[1], nb = lispoi[kel+1] -> lambda[2] */ - if ( detloc > 0.0 ) { - if ( ntempb == na ) - uv[0] = lambda[1]; - else if (ntempb == nb ) - uv[0] = lambda[2]; - else { - assert(ntempb == ip0); - uv[0] = lambda[0]; - } - if ( ntempc == na ) - uv[1] = lambda[1]; - else if (ntempc == nb ) - uv[1] = lambda[2]; - else { - assert(ntempc == ip0); - uv[1] = lambda[0]; - } - } - /* nb = lispoi[kel] -> lambda[1], na = lispoi[kel+1] -> lambda[2] */ - else { - if ( ntempb == na ) - uv[0] = lambda[2]; - else if (ntempb == nb ) - uv[0] = lambda[1]; - else { - assert(ntempb == ip0); - uv[0] = lambda[0]; - } - if ( ntempc == na ) - uv[1] = lambda[2]; - else if (ntempc == nb ) - uv[1] = lambda[1]; - else { - assert(ntempc == ip0); - uv[1] = lambda[0]; - } - } - if(!MMG3D_bezierInt(&b,uv,o,no,to)){ - if( !mmgErr1 ) { - mmgErr1 = 1; - fprintf(stderr," ## Error: %s: function MMG3D_bezierInt return 0.\n", - __func__); - } - return -1; - } - - /* Test : make sure that geometric approximation has not been degraded too much */ - ppt0 = &mesh->point[0]; - ppt0->c[0] = o[0]; - ppt0->c[1] = o[1]; - ppt0->c[2] = o[2]; - - ppt0->tag = p0->tag; - ppt0->ref = p0->ref; - - - nxp = mesh->xp + 1; - if ( nxp > mesh->xpmax ) { - MMG5_TAB_RECALLOC(mesh,mesh->xpoint,mesh->xpmax,MMG5_GAP,MMG5_xPoint, - "larger xpoint table", - return 0); - n = &(mesh->xpoint[p0->xp].n1[0]); + else if ( !nxp ) { + return 0; } - ppt0->xp = nxp; pxp = &mesh->xpoint[nxp]; - memcpy(pxp,&(mesh->xpoint[p0->xp]),sizeof(MMG5_xPoint)); - pxp->n1[0] = no[0]; - pxp->n1[1] = no[1]; - pxp->n1[2] = no[2]; /* For each surfacic triangle, build a virtual displaced triangle for check purposes */ calold = calnew = DBL_MAX; From 372c66086cde0555a4b430647545d3f8834e9a97 Mon Sep 17 00:00:00 2001 From: Algiane Date: Wed, 21 Jul 2021 16:41:56 +0200 Subject: [PATCH 131/170] prepare movbdyrefpt_iso refactoring. --- src/mmg3d/movpt_3d.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mmg3d/movpt_3d.c b/src/mmg3d/movpt_3d.c index 2ebc6c126..1091ad6cc 100755 --- a/src/mmg3d/movpt_3d.c +++ b/src/mmg3d/movpt_3d.c @@ -871,7 +871,7 @@ int MMG5_movbdyrefpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre int l,iel,ip0,ipa,ipb,iptmpa,iptmpb,ip1,ip2,ip,nxp; int isloc,j; int16_t tag; - uint8_t i,i0,ie,iface,iea,ieb; + uint8_t i,i0,ie,iface,iea,ieb; step = 0.1; ip1 = ip2 = 0; @@ -1066,7 +1066,8 @@ int MMG5_movbdyrefpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre pxt = &mesh->xtetra[pt->xt]; MMG5_tet2tri(mesh,iel,iface,&tt); - calold = MG_MIN(calold,MMG5_caltri(mesh,met,&tt)); + caltmp = MMG5_caltri(mesh,met,&tt); + calold = MG_MIN(calold,caltmp); for( i=0 ; i<3 ; i++ ) if ( tt.v[i] == ip0 ) break; From 691824f9079a88e1b8144e2db2511799742afde4 Mon Sep 17 00:00:00 2001 From: Algiane Date: Wed, 21 Jul 2021 20:53:47 +0200 Subject: [PATCH 132/170] MMG5_movebdy*pt_iso factorization. --- src/mmg3d/movpt_3d.c | 927 ++++++++----------------------------------- 1 file changed, 166 insertions(+), 761 deletions(-) diff --git a/src/mmg3d/movpt_3d.c b/src/mmg3d/movpt_3d.c index 1091ad6cc..fdc084b0c 100755 --- a/src/mmg3d/movpt_3d.c +++ b/src/mmg3d/movpt_3d.c @@ -851,22 +851,25 @@ int MMG5_movbdyregpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre * \param ilists size of the surfacic ball. * \param improve force the new minimum element quality to be greater or equal * than 1.02 of the old minimum element quality. + * \param edgTag Type of edge on which we move (MG_REF, MG_NOM or MG_GEO). + * * \return 0 if fail, 1 if success. * - * Move boundary reference point, whose volumic and surfacic balls are passed. + * Move boundary reference, ridge or non-manifold point, whose volumic and + * surfacic balls are passed. * * \remark the metric is not interpolated at the new position. */ -int MMG5_movbdyrefpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctree, int *listv, - int ilistv, int *lists, int ilists, - int improve){ +static inline +int MMG3D_movbdycurvept_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctree, int *listv, + int ilistv, int *lists, int ilists,int improve,const int16_t edgTag){ MMG5_pTetra pt,pt0; MMG5_pxTetra pxt; MMG5_pPoint p0,p1,p2,ppt0; MMG5_Tria tt; MMG5_pxPoint pxp; MMG5_pPar par; - double step,ll1old,ll2old,o[3],no[3],to[3]; + double step,ll1old,ll2old,o[3],no[3],no2[3],to[3]; double calold,calnew,caltmp,*callist,hmax,hausd; int l,iel,ip0,ipa,ipb,iptmpa,iptmpb,ip1,ip2,ip,nxp; int isloc,j; @@ -879,10 +882,10 @@ int MMG5_movbdyrefpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre ip0 = pt->v[listv[0]%4]; p0 = &mesh->point[ip0]; - assert ( MG_REF & p0->tag ); + assert ( edgTag & p0->tag ); - /* Travel surfacic ball and recover the two ending points of ref curve : - two senses must be used */ + /* Travel surfacic ball and recover the two ending points of curve : two + * senses must be used */ iel = lists[0]/4; iface = lists[0]%4; pt = &mesh->tetra[iel]; @@ -926,7 +929,7 @@ int MMG5_movbdyrefpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre if ( (iptmpa == ipa) || (iptmpa == ipb) ) { if ( pt->xt ) tag = mesh->xtetra[pt->xt].tag[iea]; else tag = 0; - if ( MG_REF & tag ) { + if ( edgTag & tag ) { ip1 = iptmpa; break; } @@ -934,7 +937,7 @@ int MMG5_movbdyrefpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre if ( (iptmpb == ipa) || (iptmpb == ipb) ) { if ( pt->xt ) tag = mesh->xtetra[pt->xt].tag[ieb]; else tag = 0; - if ( MG_REF & tag ) { + if ( edgTag & tag ) { ip1 = iptmpb; break; } @@ -987,15 +990,20 @@ int MMG5_movbdyrefpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre if ( (iptmpa == ipa) || (iptmpa == ipb) ) { if ( pt->xt ) tag = mesh->xtetra[pt->xt].tag[iea]; else tag = 0; - if ( MG_REF & tag ) { + if ( edgTag & tag ) { ip2 = iptmpa; break; } } if ( (iptmpb == ipa) || (iptmpb == ipb) ) { - assert(pt->xt); - tag = mesh->xtetra[pt->xt].tag[ieb]; - if ( MG_REF & tag ) { + if ( (MG_GEO & edgTag) && (!pt->xt) ) { + tag = 0; + } + else { + assert(pt->xt); + tag = mesh->xtetra[pt->xt].tag[ieb]; + } + if ( edgTag & tag ) { ip2 = iptmpb; break; } @@ -1005,9 +1013,9 @@ int MMG5_movbdyrefpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre } if ( !(ip1 && ip2 && (ip1 != ip2)) ) return 0; - /* At this point, we get the point extremities of the ref limit curve passing through ip0 : - ip1, ip2, along with support tets it1,it2, the surface faces iface1,iface2, and the - associated edges ie1,ie2.*/ + /* At this point, we get the point extremities of the curve passing through + ip0 : ip1, ip2, along with support tets it1,it2, the surface faces + iface1,iface2, and the associated edges ie1,ie2.*/ /* Changes needed for choice of time step : see manuscript notes */ p1 = &mesh->point[ip1]; @@ -1028,7 +1036,25 @@ int MMG5_movbdyrefpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre } /* Compute support of the associated edge, and features of the new position */ - if ( !(MMG5_BezierRef(mesh,ip0,ip,step,o,no,to)) ) return 0; + if ( MG_NOM & edgTag ) { + if ( !(MMG5_BezierNom(mesh,ip0,ip,step,o,no,to)) ) { + return 0; + } + } + else if ( MG_GEO & edgTag ) { + if ( !(MMG5_BezierRidge(mesh,ip0,ip,step,o,no,no2,to)) ) { + return 0; + } + } + else if ( MG_REF & edgTag ) { + if ( !(MMG5_BezierRef(mesh,ip0,ip,step,o,no,to)) ) { + return 0; + } + } + else { + assert ( 0 && "Unexpected edge tag in this function"); + return 0; + } /* Test : make sure that geometric approximation has not been degraded too much */ ppt0 = &mesh->point[0]; @@ -1038,7 +1064,6 @@ int MMG5_movbdyrefpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre ppt0->tag = p0->tag; ppt0->ref = p0->ref; - nxp = mesh->xp + 1; if ( nxp > mesh->xpmax ) { MMG5_TAB_RECALLOC(mesh,mesh->xpoint,mesh->xpmax,MMG5_GAP,MMG5_xPoint, @@ -1057,6 +1082,12 @@ int MMG5_movbdyrefpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre pxp->n1[1] = no[1]; pxp->n1[2] = no[2]; + if ( MG_GEO & edgTag ) { + pxp->n2[0] = no2[0]; + pxp->n2[1] = no2[1]; + pxp->n2[2] = no2[2]; + } + /* For each surface triangle, build a virtual displaced triangle for check purposes */ calold = calnew = DBL_MAX; for( l=0 ; lc); + } p0->c[0] = o[0]; p0->c[1] = o[1]; @@ -1181,6 +1216,12 @@ int MMG5_movbdyrefpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre pxp->n1[1] = no[1]; pxp->n1[2] = no[2]; + if ( MG_GEO & edgTag ) { + pxp->n2[0] = no2[0]; + pxp->n2[1] = no2[1]; + pxp->n2[2] = no2[2]; + } + p0->n[0] = to[0]; p0->n[1] = to[1]; p0->n[2] = to[2]; @@ -1193,6 +1234,28 @@ int MMG5_movbdyrefpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre return 1; } +/** + * \param mesh pointer toward the mesh structure. + * \param met pointer toward the metric structure. + * \param PROctree pointer toward the PROctree structure. + * \param listv pointer toward the volumic ball of the point. + * \param ilistv size of the volumic ball. + * \param lists pointer toward the surfacic ball of the point. + * \param ilists size of the surfacic ball. + * \param improve force the new minimum element quality to be greater or equal + * than 1.02 of the old minimum element quality. + * + * \return 0 if fail, 1 if success. + * + * Move boundary reference point, whose volumic and surfacic balls are passed. + * + * \remark the metric is not interpolated at the new position. + */ +int MMG5_movbdyrefpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctree, int *listv, + int ilistv, int *lists, int ilists,int improve){ + + return MMG3D_movbdycurvept_iso(mesh,met,PROctree,listv,ilistv,lists,ilists,improve,MG_REF); +} /** * \param mesh pointer toward the mesh structure. @@ -1204,28 +1267,43 @@ int MMG5_movbdyrefpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre * \param ilists size of the surfacic ball. * \param improve force the new minimum element quality to be greater or equal * than 1.02 of the old minimum element quality. + * + * \return 0 if fail, 1 if success. + * + * Move boundary non-manifold point, whose volumic and surfacic balls are + * passed. + * + * \remark the metric is not interpolated at the new position. + */ +int MMG5_movbdynompt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctree, int *listv, + int ilistv, int *lists, int ilists,int improve){ + + return MMG3D_movbdycurvept_iso(mesh,met,PROctree,listv,ilistv,lists,ilists,improve,MG_NOM); +} + +/** + * \param mesh pointer toward the mesh structure. + * \param met pointer toward the metric structure. + * \param PROctree pointer toward the PROctree structure. + * \param listv pointer toward the volumic ball of the point. + * \param ilistv size of the volumic ball. + * \param improve force the new minimum element quality to be greater or equal + * than 1.02 of the old minimum element quality. * \return 0 if fail, 1 if success. * - * Move boundary non manifold point, whose volumic and (exterior) - * surfacic balls are passed + * Move internal non manifold point, whose volumic ball is passed * * \remark the metric is not interpolated at the new position. */ -int MMG5_movbdynompt_iso(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROctree, int *listv, - int ilistv, int *lists, int ilists, - int improve){ +int MMG5_movbdynomintpt_iso(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROctree, int *listv, + int ilistv, int improve){ MMG5_pTetra pt,pt0; MMG5_pxTetra pxt; MMG5_pPoint p0,p1,p2,ppt0; - MMG5_pxPoint pxp; - MMG5_Tria tt; - MMG5_pPar par; - double step,ll1old,ll2old,calold,calnew,caltmp,*callist; - double o[3],no[3],to[3],hmax,hausd; - int ip0,ip1,ip2,ip,iel,ipa,ipb,l,iptmpa,iptmpb,nxp; - int j,isloc; - int16_t tag; - int8_t iface,i,i0,iea,ieb,ie; + double step,ll1old,ll2old,calold,calnew,*callist; + double o[3],no[3],to[3]; + int ip0,ip1,ip2,ip,iel,ipa,l; + int8_t i,i0,ie; step = 0.1; ip1 = ip2 = 0; @@ -1233,145 +1311,37 @@ int MMG5_movbdynompt_iso(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROctree ip0 = pt->v[listv[0]%4]; p0 = &mesh->point[ip0]; - assert ( p0->tag & MG_NOM ); - - /* Travel surfacic ball and recover the two ending points of non manifold curve : - two senses must be used */ - iel = lists[0]/4; - iface = lists[0]%4; - pt = &mesh->tetra[iel]; - ipa = ipb = 0; - for (i=0; i<3; i++) { - if ( pt->v[MMG5_idir[iface][i]] != ip0 ) { - if ( !ipa ) - ipa = pt->v[MMG5_idir[iface][i]]; - else - ipb = pt->v[MMG5_idir[iface][i]]; - } - } - assert(ipa && ipb); + assert ( p0->tag & MG_NOM && p0->xp && mesh->xpoint[p0->xp].nnor ); - for (l=1; ltetra[iel]; - iea = ieb = 0; - for (i=0; i<3; i++) { - ie = MMG5_iarf[iface][i]; //edge i on face iface - if ( (pt->v[MMG5_iare[ie][0]] == ip0) || (pt->v[MMG5_iare[ie][1]] == ip0) ) { - if ( !iea ) - iea = ie; - else - ieb = ie; - } - } - if ( pt->v[MMG5_iare[iea][0]] != ip0 ) - iptmpa = pt->v[MMG5_iare[iea][0]]; - else { - assert(pt->v[MMG5_iare[iea][1]] != ip0); - iptmpa = pt->v[MMG5_iare[iea][1]]; - } - if ( pt->v[MMG5_iare[ieb][0]] != ip0 ) - iptmpb = pt->v[MMG5_iare[ieb][0]]; - else { - assert(pt->v[MMG5_iare[ieb][1]] != ip0); - iptmpb = pt->v[MMG5_iare[ieb][1]]; - } - if ( (iptmpa == ipa) || (iptmpa == ipb) ) { - if ( pt->xt ) tag = mesh->xtetra[pt->xt].tag[iea]; - else tag = 0; - if ( MG_NOM & tag ) { - ip1 = iptmpa; - break; - } - } - if ( (iptmpb == ipa) || (iptmpb == ipb) ) { - if ( pt->xt ) tag = mesh->xtetra[pt->xt].tag[ieb]; - else tag = 0; - if ( MG_NOM & tag ) { - ip1 = iptmpb; - break; - } - } - ipa = iptmpa; - ipb = iptmpb; - } - - /* Now travel surfacic list in the reverse sense so as to get the second non manifold point */ - iel = lists[0]/4; - iface = lists[0]%4; - pt = &mesh->tetra[iel]; - ipa = ipb = 0; - for (i=0; i<3; i++) { - if ( pt->v[MMG5_idir[iface][i]] != ip0 ) { - if ( !ipa ) - ipa = pt->v[MMG5_idir[iface][i]]; - else - ipb = pt->v[MMG5_idir[iface][i]]; - } - } - assert(ipa && ipb); + if ( !pt->xt ) continue; + pxt = &mesh->xtetra[pt->xt]; - for (l=ilists-1; l>0; l--) { - iel = lists[l] / 4; - iface = lists[l] % 4; - pt = &mesh->tetra[iel]; - iea = ieb = 0; for (i=0; i<3; i++) { - ie = MMG5_iarf[iface][i]; //edge i on face iface - if ( (pt->v[MMG5_iare[ie][0]] == ip0) || (pt->v[MMG5_iare[ie][1]] == ip0) ) { - if ( !iea ) - iea = ie; - else - ieb = ie; - } - } - if ( pt->v[MMG5_iare[iea][0]] != ip0 ) - iptmpa = pt->v[MMG5_iare[iea][0]]; - else { - assert(pt->v[MMG5_iare[iea][1]] != ip0); - iptmpa = pt->v[MMG5_iare[iea][1]]; - } - if ( pt->v[MMG5_iare[ieb][0]] != ip0 ) - iptmpb = pt->v[MMG5_iare[ieb][0]]; - else { - assert(pt->v[MMG5_iare[ieb][1]] != ip0); - iptmpb = pt->v[MMG5_iare[ieb][1]]; - } - if ( (iptmpa == ipa) || (iptmpa == ipb) ) { - if ( pt->xt ) tag = mesh->xtetra[pt->xt].tag[iea]; - else tag = 0; - if ( MG_NOM & tag ) { - ip2 = iptmpa; - break; - } - } - if ( (iptmpb == ipa) || (iptmpb == ipb) ) { - assert(pt->xt); - tag = mesh->xtetra[pt->xt].tag[ieb]; - if ( MG_NOM & tag ) { - ip2 = iptmpb; - break; + ie = MMG5_arpt[i0][i]; + if ( pxt->tag[ie] & MG_NOM ) { + ipa = ( ip0 == pt->v[MMG5_iare[ie][0]] ) ? pt->v[MMG5_iare[ie][1]] : pt->v[MMG5_iare[ie][0]]; + if ( !ip1 ) ip1 = ipa; + else if ( !ip2 && ipa != ip1 ) ip2 = ipa; } } - ipa = iptmpa; - ipb = iptmpb; } if ( !(ip1 && ip2 && (ip1 != ip2)) ) return 0; - /* At this point, we get the point extremities of the non manifold curve passing through ip0 : - ip1, ip2, along with support tets it1,it2, the surface faces iface1,iface2, and the - associated edges ie1,ie2.*/ - + /* At this point, we get the point extremities ip1, ip2 of the non manifold curve passing through ip0 */ p1 = &mesh->point[ip1]; p2 = &mesh->point[ip2]; ll1old = (p1->c[0] -p0->c[0])* (p1->c[0] -p0->c[0]) \ - + (p1->c[1] -p0->c[1])* (p1->c[1] -p0->c[1]) \ - + (p1->c[2] -p0->c[2])* (p1->c[2] -p0->c[2]); + + (p1->c[1] -p0->c[1])* (p1->c[1] -p0->c[1]) \ + + (p1->c[2] -p0->c[2])* (p1->c[2] -p0->c[2]); ll2old = (p2->c[0] -p0->c[0])* (p2->c[0] -p0->c[0]) \ - + (p2->c[1] -p0->c[1])* (p2->c[1] -p0->c[1]) \ - + (p2->c[2] -p0->c[2])* (p2->c[2] -p0->c[2]); + + (p2->c[1] -p0->c[1])* (p2->c[1] -p0->c[1]) \ + + (p2->c[2] -p0->c[2])* (p2->c[2] -p0->c[2]); if ( ll1old < ll2old ) { //move towards p2 ip = ip2; @@ -1383,7 +1353,10 @@ int MMG5_movbdynompt_iso(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROctree /* Compute support of the associated edge, and features of the new position */ if ( !(MMG5_BezierNom(mesh,ip0,ip,step,o,no,to)) ) return 0; - /* Test : make sure that geometric approximation has not been degraded too much */ + /* Test : check whether all volumes remain positive with new position of the point */ + // Dynamic allocations for windows compatibility + MMG5_SAFE_MALLOC(callist, ilistv, double,return 0); + ppt0 = &mesh->point[0]; ppt0->c[0] = o[0]; ppt0->c[1] = o[1]; @@ -1391,274 +1364,38 @@ int MMG5_movbdynompt_iso(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROctree ppt0->tag = p0->tag; ppt0->ref = p0->ref; - nxp = mesh->xp + 1; - if ( nxp > mesh->xpmax ) { - MMG5_TAB_RECALLOC(mesh,mesh->xpoint,mesh->xpmax,MMG5_GAP,MMG5_xPoint, - "larger xpoint table", - return 0); + calold = calnew = DBL_MAX; + for( l=0 ; ltetra[iel]; + pt0 = &mesh->tetra[0]; + memcpy(pt0,pt,sizeof(MMG5_Tetra)); + pt0->v[i0] = 0; + calold = MG_MIN(calold, pt->qual); + callist[l]= MMG5_orcal(mesh,met,0); + if (callist[l] < MMG5_NULKAL) { + MMG5_SAFE_FREE(callist); + return 0; + } + calnew = MG_MIN(calnew,callist[l]); + } + if ((calold < MMG5_EPSOK && calnew <= calold) || + (calnew < MMG5_EPSOK) || (calnew <= 0.3*calold)) { + MMG5_SAFE_FREE(callist); + return 0; + } else if (improve && calnew < calold) { + MMG5_SAFE_FREE(callist); + return 0; } - ppt0->xp = nxp; - pxp = &mesh->xpoint[nxp]; - memcpy(pxp,&(mesh->xpoint[p0->xp]),sizeof(MMG5_xPoint)); - ppt0->n[0] = to[0]; - ppt0->n[1] = to[1]; - ppt0->n[2] = to[2]; + /* Update coordinates and tangent for new point */ + if ( PROctree ) + MMG3D_movePROctree(mesh, PROctree, ip0, o, p0->c); - pxp->n1[0] = no[0]; - pxp->n1[1] = no[1]; - pxp->n1[2] = no[2]; - - /* For each surface triangle, build a virtual displaced triangle for check purposes */ - calold = calnew = DBL_MAX; - for( l=0 ; ltetra[iel]; - pxt = &mesh->xtetra[pt->xt]; - - MMG5_tet2tri(mesh,iel,iface,&tt); - caltmp = MMG5_caltri(mesh,met,&tt); - calold = MG_MIN(calold,caltmp); - - for( i=0 ; i<3 ; i++ ) - if ( tt.v[i] == ip0 ) break; - assert(i<3); - if ( i==3 ) return 0; - - tt.v[i] = 0; - - caltmp = MMG5_caltri(mesh,met,&tt); - if ( caltmp < MMG5_EPSD2 ) { - /* We don't check the input triangle qualities, thus we may have a very - * bad triangle in our mesh */ - return 0; - } - calnew = MG_MIN(calnew,caltmp); - - /* Local parameters for tt and iel */ - hmax = mesh->info.hmax; - hausd = mesh->info.hausd; - - isloc = 0; - if ( mesh->info.parTyp & MG_Tetra ) { - for ( j=0; jinfo.npar; ++j ) { - par = &mesh->info.par[j]; - - if ( par->elt != MMG5_Tetrahedron ) continue; - if ( par->ref != pt->ref ) continue; - - hmax = par->hmax; - hausd = par->hausd; - isloc = 1; - break; - } - } - if ( mesh->info.parTyp & MG_Tria ) { - if ( isloc ) { - for ( j=0; jinfo.npar; ++j ) { - par = &mesh->info.par[j]; - - if ( par->elt != MMG5_Triangle ) continue; - if ( par->ref != tt.ref ) continue; - - hmax = MG_MIN(hmax,par->hmax); - hausd = MG_MIN(hausd,par->hausd); - break; - } - } - else { - for ( j=0; jinfo.npar; ++j ) { - par = &mesh->info.par[j]; - - if ( par->elt != MMG5_Triangle ) continue; - if ( par->ref != tt.ref ) continue; - - hmax = par->hmax; - hausd = par->hausd; - isloc = 1; - break; - } - } - } - - if ( MMG5_chkedg(mesh,&tt,MG_GET(pxt->ori,iface),hmax,hausd,isloc) > 0 ) { - memset(pxp,0,sizeof(MMG5_xPoint)); - return 0; - } - } - if ( calold < MMG5_EPSOK && calnew <= calold ) return 0; - else if ( calnew < calold ) return 0; - memset(pxp,0,sizeof(MMG5_xPoint)); - - /* Test : check whether all volumes remain positive with new position of the point */ - // Dynamic allocations for windows compatibility - MMG5_SAFE_MALLOC(callist, ilistv, double,return 0); - - calold = calnew = DBL_MAX; - for( l=0 ; ltetra[iel]; - pt0 = &mesh->tetra[0]; - memcpy(pt0,pt,sizeof(MMG5_Tetra)); - pt0->v[i0] = 0; - calold = MG_MIN(calold, pt->qual); - callist[l]= MMG5_orcal(mesh,met,0); - if (callist[l] < MMG5_NULKAL) { - MMG5_SAFE_FREE(callist); - return 0; - } - calnew = MG_MIN(calnew,callist[l]); - } - if ((calold < MMG5_EPSOK && calnew <= calold) || - (calnew < MMG5_EPSOK) || (calnew <= 0.3*calold)) { - MMG5_SAFE_FREE(callist); - return 0; - } else if (improve && calnew < calold) { - MMG5_SAFE_FREE(callist); - return 0; - } - - /* Update coordinates, normals, for new point */ - if ( PROctree ) - MMG3D_movePROctree(mesh, PROctree, ip0, o, p0->c); - p0->c[0] = o[0]; - p0->c[1] = o[1]; - p0->c[2] = o[2]; - - pxp = &mesh->xpoint[p0->xp]; - pxp->n1[0] = no[0]; - pxp->n1[1] = no[1]; - pxp->n1[2] = no[2]; - - p0->n[0] = to[0]; - p0->n[1] = to[1]; - p0->n[2] = to[2]; - - for(l=0; ltetra[listv[l]/4])->qual = callist[l]; - (&mesh->tetra[listv[l]/4])->mark = mesh->mark; - } - MMG5_SAFE_FREE(callist); - return 1; -} - -/** - * \param mesh pointer toward the mesh structure. - * \param met pointer toward the metric structure. - * \param PROctree pointer toward the PROctree structure. - * \param listv pointer toward the volumic ball of the point. - * \param ilistv size of the volumic ball. - * \param improve force the new minimum element quality to be greater or equal - * than 1.02 of the old minimum element quality. - * \return 0 if fail, 1 if success. - * - * Move internal non manifold point, whose volumic ball is passed - * - * \remark the metric is not interpolated at the new position. - */ -int MMG5_movbdynomintpt_iso(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROctree, int *listv, - int ilistv, int improve){ - MMG5_pTetra pt,pt0; - MMG5_pxTetra pxt; - MMG5_pPoint p0,p1,p2,ppt0; - double step,ll1old,ll2old,calold,calnew,*callist; - double o[3],no[3],to[3]; - int ip0,ip1,ip2,ip,iel,ipa,l; - int8_t i,i0,ie; - - step = 0.1; - ip1 = ip2 = 0; - pt = &mesh->tetra[listv[0]/4]; - ip0 = pt->v[listv[0]%4]; - p0 = &mesh->point[ip0]; - - assert ( p0->tag & MG_NOM && p0->xp && mesh->xpoint[p0->xp].nnor ); - - /* Recover the two ending points of the underlying non manifold curve */ - for (l=0; ltetra[iel]; - if ( !pt->xt ) continue; - pxt = &mesh->xtetra[pt->xt]; - - for (i=0; i<3; i++) { - ie = MMG5_arpt[i0][i]; - if ( pxt->tag[ie] & MG_NOM ) { - ipa = ( ip0 == pt->v[MMG5_iare[ie][0]] ) ? pt->v[MMG5_iare[ie][1]] : pt->v[MMG5_iare[ie][0]]; - if ( !ip1 ) ip1 = ipa; - else if ( !ip2 && ipa != ip1 ) ip2 = ipa; - } - } - } - if ( !(ip1 && ip2 && (ip1 != ip2)) ) return 0; - - /* At this point, we get the point extremities ip1, ip2 of the non manifold curve passing through ip0 */ - p1 = &mesh->point[ip1]; - p2 = &mesh->point[ip2]; - - ll1old = (p1->c[0] -p0->c[0])* (p1->c[0] -p0->c[0]) \ - + (p1->c[1] -p0->c[1])* (p1->c[1] -p0->c[1]) \ - + (p1->c[2] -p0->c[2])* (p1->c[2] -p0->c[2]); - ll2old = (p2->c[0] -p0->c[0])* (p2->c[0] -p0->c[0]) \ - + (p2->c[1] -p0->c[1])* (p2->c[1] -p0->c[1]) \ - + (p2->c[2] -p0->c[2])* (p2->c[2] -p0->c[2]); - - if ( ll1old < ll2old ) { //move towards p2 - ip = ip2; - } - else { - ip = ip1; - } - - /* Compute support of the associated edge, and features of the new position */ - if ( !(MMG5_BezierNom(mesh,ip0,ip,step,o,no,to)) ) return 0; - - /* Test : check whether all volumes remain positive with new position of the point */ - // Dynamic allocations for windows compatibility - MMG5_SAFE_MALLOC(callist, ilistv, double,return 0); - - ppt0 = &mesh->point[0]; - ppt0->c[0] = o[0]; - ppt0->c[1] = o[1]; - ppt0->c[2] = o[2]; - ppt0->tag = p0->tag; - ppt0->ref = p0->ref; - - calold = calnew = DBL_MAX; - for( l=0 ; ltetra[iel]; - pt0 = &mesh->tetra[0]; - memcpy(pt0,pt,sizeof(MMG5_Tetra)); - pt0->v[i0] = 0; - calold = MG_MIN(calold, pt->qual); - callist[l]= MMG5_orcal(mesh,met,0); - if (callist[l] < MMG5_NULKAL) { - MMG5_SAFE_FREE(callist); - return 0; - } - calnew = MG_MIN(calnew,callist[l]); - } - if ((calold < MMG5_EPSOK && calnew <= calold) || - (calnew < MMG5_EPSOK) || (calnew <= 0.3*calold)) { - MMG5_SAFE_FREE(callist); - return 0; - } else if (improve && calnew < calold) { - MMG5_SAFE_FREE(callist); - return 0; - } - - /* Update coordinates and tangent for new point */ - if ( PROctree ) - MMG3D_movePROctree(mesh, PROctree, ip0, o, p0->c); - - p0->c[0] = o[0]; - p0->c[1] = o[1]; - p0->c[2] = o[2]; + p0->c[0] = o[0]; + p0->c[1] = o[1]; + p0->c[2] = o[2]; p0->n[0] = to[0]; p0->n[1] = to[1]; @@ -1689,341 +1426,9 @@ int MMG5_movbdynomintpt_iso(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROct * */ int MMG5_movbdyridpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctree, int *listv, - int ilistv,int *lists,int ilists, - int improve) { - MMG5_pTetra pt,pt0; - MMG5_pxTetra pxt; - MMG5_pPoint p0,p1,p2,ppt0; - MMG5_Tria tt; - MMG5_pxPoint pxp; - MMG5_pPar par; - double step,ll1old,ll2old,o[3],no1[3],no2[3],to[3]; - double calold,calnew,caltmp,*callist,hmax,hausd; - int l,iel,ip0,ipa,ipb,iptmpa,iptmpb,ip1,ip2,ip,nxp; - int j,isloc; - int16_t tag; - uint8_t i,i0,ie,iface,iea,ieb; - - step = 0.1; - ip1 = ip2 = 0; - pt = &mesh->tetra[listv[0]/4]; - ip0 = pt->v[listv[0]%4]; - p0 = &mesh->point[ip0]; - - assert ( MG_GEO & p0->tag ); + int ilistv,int *lists,int ilists,int improve) { - /* Travel surfacic ball an recover the two ending points of ridge : two senses must be used - POSSIBLE OPTIMIZATION HERE : One travel only is needed */ - iel = lists[0] / 4; - iface = lists[0] % 4; - pt = &mesh->tetra[iel]; - ipa = ipb = 0; - for (i=0; i<3; i++) { - if ( pt->v[MMG5_idir[iface][i]] != ip0 ) { - if ( !ipa ) - ipa = pt->v[MMG5_idir[iface][i]]; - else - ipb = pt->v[MMG5_idir[iface][i]]; - } - } - assert(ipa && ipb); - - for (l=1; ltetra[iel]; - iea = ieb = 0; - for (i=0; i<3; i++) { - ie = MMG5_iarf[iface][i]; //edge i on face iface - if ( (pt->v[MMG5_iare[ie][0]] == ip0) || (pt->v[MMG5_iare[ie][1]] == ip0) ) { - if ( !iea ) - iea = ie; - else - ieb = ie; - } - } - if ( pt->v[MMG5_iare[iea][0]] != ip0 ) - iptmpa = pt->v[MMG5_iare[iea][0]]; - else { - assert(pt->v[MMG5_iare[iea][1]] != ip0); - iptmpa = pt->v[MMG5_iare[iea][1]]; - } - if ( pt->v[MMG5_iare[ieb][0]] != ip0 ) - iptmpb = pt->v[MMG5_iare[ieb][0]]; - else { - assert(pt->v[MMG5_iare[ieb][1]] != ip0); - iptmpb = pt->v[MMG5_iare[ieb][1]]; - } - if ( (iptmpa == ipa) || (iptmpa == ipb) ) { - if ( pt->xt ) tag = mesh->xtetra[pt->xt].tag[iea]; - else tag = 0; - if ( MG_GEO & tag ) { - ip1 = iptmpa; - break; - } - } - if ( (iptmpb == ipa) || (iptmpb == ipb) ) { - if ( pt->xt ) tag = mesh->xtetra[pt->xt].tag[ieb]; - else tag = 0; - if ( MG_GEO & tag ) { - ip1 = iptmpb; - break; - } - } - ipa = iptmpa; - ipb = iptmpb; - } - - /* Now travel surfacic list in the reverse sense so as to get the second ridge */ - iel = lists[0] / 4; - iface = lists[0] % 4; - pt = &mesh->tetra[iel]; - ipa = ipb = 0; - for (i=0; i<3; i++) { - if ( pt->v[MMG5_idir[iface][i]] != ip0 ) { - if ( !ipa ) - ipa = pt->v[MMG5_idir[iface][i]]; - else - ipb = pt->v[MMG5_idir[iface][i]]; - } - } - assert(ipa && ipb); - - for (l=ilists-1; l>0; l--) { - iel = lists[l]/4; - iface = lists[l]%4; - pt = &mesh->tetra[iel]; - iea = ieb = 0; - for (i=0; i<3; i++) { - ie = MMG5_iarf[iface][i]; //edge i on face iface - if ( (pt->v[MMG5_iare[ie][0]] == ip0) || (pt->v[MMG5_iare[ie][1]] == ip0) ) { - if ( !iea ) - iea = ie; - else - ieb = ie; - } - } - if ( pt->v[MMG5_iare[iea][0]] != ip0 ) - iptmpa = pt->v[MMG5_iare[iea][0]]; - else { - assert(pt->v[MMG5_iare[iea][1]] != ip0); - iptmpa = pt->v[MMG5_iare[iea][1]]; - } - if ( pt->v[MMG5_iare[ieb][0]] != ip0 ) - iptmpb = pt->v[MMG5_iare[ieb][0]]; - else { - assert(pt->v[MMG5_iare[ieb][1]] != ip0); - iptmpb = pt->v[MMG5_iare[ieb][1]]; - } - if ( (iptmpa == ipa) || (iptmpa == ipb) ) { - if ( pt->xt ) tag = mesh->xtetra[pt->xt].tag[iea]; - else tag = 0; - if ( MG_GEO & tag ) { - ip2 = iptmpa; - break; - } - } - if ( (iptmpb == ipa) || (iptmpb == ipb) ) { - if ( pt->xt ) tag = mesh->xtetra[pt->xt].tag[ieb]; - else tag = 0; - if ( MG_GEO & tag ) { - ip2 = iptmpb; - break; - } - } - ipa = iptmpa; - ipb = iptmpb; - } - if ( !(ip1 && ip2 && (ip1 != ip2)) ) return 0; - - /* At this point, we get the point extremities of the ridge curve passing through ip0 : - ip1, ip2, along with support tets it1,it2, the surface faces iface1,iface2, and the - associated edges ie1,ie2.*/ - - /* Changes needed for choice of time step : see manuscript notes */ - p1 = &mesh->point[ip1]; - p2 = &mesh->point[ip2]; - - ll1old = (p1->c[0] -p0->c[0])* (p1->c[0] -p0->c[0]) \ - + (p1->c[1] -p0->c[1])* (p1->c[1] -p0->c[1]) \ - + (p1->c[2] -p0->c[2])* (p1->c[2] -p0->c[2]); - ll2old = (p2->c[0] -p0->c[0])* (p2->c[0] -p0->c[0]) \ - + (p2->c[1] -p0->c[1])* (p2->c[1] -p0->c[1]) \ - + (p2->c[2] -p0->c[2])* (p2->c[2] -p0->c[2]); - - if ( ll1old < ll2old ) { //move towards p2 - ip = ip2; - } - else { - ip = ip1; - } - - /* Compute support of the associated edge, and features of the new position */ - if ( !(MMG5_BezierRidge(mesh,ip0,ip,step,o,no1,no2,to)) ) return 0; - - /* Test : make sure that geometric approximation has not been degraded too much */ - ppt0 = &mesh->point[0]; - ppt0->c[0] = o[0]; - ppt0->c[1] = o[1]; - ppt0->c[2] = o[2]; - ppt0->tag = p0->tag; - ppt0->ref = p0->ref; - - nxp = mesh->xp+1; - if ( nxp > mesh->xpmax ) { - MMG5_TAB_RECALLOC(mesh,mesh->xpoint,mesh->xpmax,MMG5_GAP,MMG5_xPoint, - "larger xpoint table", - return 0); - } - ppt0->xp = nxp; - pxp = &mesh->xpoint[nxp]; - memcpy(pxp,&(mesh->xpoint[p0->xp]),sizeof(MMG5_xPoint)); - - ppt0->n[0] = to[0]; - ppt0->n[1] = to[1]; - ppt0->n[2] = to[2]; - - pxp->n1[0] = no1[0]; - pxp->n1[1] = no1[1]; - pxp->n1[2] = no1[2]; - - pxp->n2[0] = no2[0]; - pxp->n2[1] = no2[1]; - pxp->n2[2] = no2[2]; - - /* For each surfacic triangle, build a virtual displaced triangle for check purposes */ - calold = calnew = DBL_MAX; - for (l=0; ltetra[iel]; - pxt = &mesh->xtetra[pt->xt]; - - MMG5_tet2tri(mesh,iel,iface,&tt); - calold = MG_MIN(calold,MMG5_caltri(mesh,met,&tt)); - - for (i=0; i<3; i++) { - if ( tt.v[i] == ip0 ) break; - } - assert(i<3); - - tt.v[i] = 0; - - caltmp = MMG5_caltri(mesh,met,&tt); - if ( caltmp < MMG5_EPSD2 ) return 0; - calnew = MG_MIN(calnew,caltmp); - - /* Local parameters for tt and iel */ - hmax = mesh->info.hmax; - hausd = mesh->info.hausd; - - isloc = 0; - if ( mesh->info.parTyp & MG_Tetra ) { - for ( j=0; jinfo.npar; ++j ) { - par = &mesh->info.par[j]; - - if ( par->elt != MMG5_Tetrahedron ) continue; - if ( par->ref != pt->ref ) continue; - - hmax = par->hmax; - hausd = par->hausd; - isloc = 1; - break; - } - } - if ( mesh->info.parTyp & MG_Tria ) { - if ( isloc ) { - for ( j=0; jinfo.npar; ++j ) { - par = &mesh->info.par[j]; - - if ( par->elt != MMG5_Triangle ) continue; - if ( par->ref != tt.ref ) continue; - - hmax = MG_MIN(hmax,par->hmax); - hausd = MG_MIN(hausd,par->hausd); - break; - } - } - else { - for ( j=0; jinfo.npar; ++j ) { - par = &mesh->info.par[j]; - - if ( par->elt != MMG5_Triangle ) continue; - if ( par->ref != tt.ref ) continue; - - hmax = par->hmax; - hausd = par->hausd; - isloc = 1; - break; - } - } - } - - if ( MMG5_chkedg(mesh,&tt,MG_GET(pxt->ori,iface),hmax,hausd,isloc) > 0 ) { - memset(pxp,0,sizeof(MMG5_xPoint)); - return 0; - } - } - if ( calold < MMG5_EPSOK && calnew <= calold ) return 0; - else if ( calnew <= calold ) return 0; - memset(pxp,0,sizeof(MMG5_xPoint)); - - /* Test : check whether all volumes remain positive with new position of the point */ - // Dynamic allocations for windows compatibility - MMG5_SAFE_MALLOC(callist, ilistv, double,return 0); - - calold = calnew = DBL_MAX; - for (l=0; ltetra[iel]; - pt0 = &mesh->tetra[0]; - memcpy(pt0,pt,sizeof(MMG5_Tetra)); - pt0->v[i0] = 0; - calold = MG_MIN(calold, pt->qual); - callist[l]=MMG5_orcal(mesh,met,0); - if (callist[l] < MMG5_NULKAL) { - MMG5_SAFE_FREE(callist); - return 0; - } - calnew = MG_MIN(calnew,callist[l]); - } - if ((calold < MMG5_EPSOK && calnew <= calold) || - (calnew < MMG5_EPSOK) || (calnew <= 0.3*calold)) { - MMG5_SAFE_FREE(callist); - return 0; - } else if (improve && calnew < calold) { - MMG5_SAFE_FREE(callist); - return 0; - } - - /* Update coordinates, normals, for new point */ - if ( PROctree ) - MMG3D_movePROctree(mesh, PROctree, ip0, o, p0->c); - - p0->c[0] = o[0]; - p0->c[1] = o[1]; - p0->c[2] = o[2]; - - pxp = &mesh->xpoint[p0->xp]; - pxp->n1[0] = no1[0]; - pxp->n1[1] = no1[1]; - pxp->n1[2] = no1[2]; - - pxp->n2[0] = no2[0]; - pxp->n2[1] = no2[1]; - pxp->n2[2] = no2[2]; - - p0->n[0] = to[0]; - p0->n[1] = to[1]; - p0->n[2] = to[2]; - - for(l=0; ltetra[listv[l]/4])->qual = callist[l]; - (&mesh->tetra[listv[l]/4])->mark = mesh->mark; - } - MMG5_SAFE_FREE(callist); - return 1; + return MMG3D_movbdycurvept_iso(mesh,met,PROctree,listv,ilistv,lists,ilists,improve,MG_GEO); } From 42061ff4e8c836f0809b9e4035d142f2a5cd25d7 Mon Sep 17 00:00:00 2001 From: Algiane Date: Wed, 21 Jul 2021 20:55:52 +0200 Subject: [PATCH 133/170] Remove dynamic alloc of callist. --- src/mmg3d/movpt_3d.c | 57 ++++++-------------------------------------- 1 file changed, 7 insertions(+), 50 deletions(-) diff --git a/src/mmg3d/movpt_3d.c b/src/mmg3d/movpt_3d.c index fdc084b0c..db382dfca 100755 --- a/src/mmg3d/movpt_3d.c +++ b/src/mmg3d/movpt_3d.c @@ -57,14 +57,11 @@ int MMG5_movintpt_iso(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROctree, MMG5_pTetra pt,pt0; MMG5_pPoint p0,p1,p2,p3,ppt0; double vol,totvol; - double calold,calnew,*callist; - double len1,len2; - int iloc; + double calold,calnew,callist[MMG3D_LMAX+2]; + double len1,len2; + int iloc; int k,iel,i0; - // Dynamic alloc for windows comptibility - MMG5_SAFE_MALLOC(callist, ilist, double,return 0); - pt0 = &mesh->tetra[0]; ppt0 = &mesh->point[0]; memset(ppt0,0,sizeof(MMG5_Point)); @@ -88,7 +85,6 @@ int MMG5_movintpt_iso(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROctree, calold = MG_MIN(calold, pt->qual); } if (totvol < MMG5_EPSD2) { - MMG5_SAFE_FREE(callist); return 0; } @@ -109,7 +105,6 @@ int MMG5_movintpt_iso(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROctree, pt0->v[i0] = 0; callist[k] = MMG5_orcal(mesh,met,0); if (callist[k] < MMG5_NULKAL) { - MMG5_SAFE_FREE(callist); return 0; } calnew = MG_MIN(calnew,callist[k]); @@ -120,13 +115,11 @@ int MMG5_movintpt_iso(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROctree, len2 = MMG5_lenedg_iso(mesh,met,MMG5_arpt[i0][iloc],pt0); if ( (len1 < MMG3D_LOPTL && len2 >= MMG3D_LOPTL) || (len1 > MMG3D_LOPTL && len2 >len1 ) ) { - MMG5_SAFE_FREE(callist); return 0; } if ( (len1 > MMG3D_LOPTS && len2 <= MMG3D_LOPTS) || (len1 < MMG3D_LOPTS && len2 tetra[list[k]/4])->mark=mesh->mark; } - - MMG5_SAFE_FREE(callist); return 1; } @@ -196,14 +183,11 @@ int MMG5_movintptLES_iso(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROctree MMG5_pTetra pt,pt0; MMG5_pPoint p0,p1,p2,p3,ppt0; double vol,totvol; - double calold,calnew,*callist; + double calold,calnew,callist[MMG3D_LMAX+2]; double x21,y21,z21,x31,y31,z31,nx,ny,nz,bary[3],dd,len; double u10[3],u20[3],u30[3],oldc[3],coe; int k,iel,ifac,iter,maxtou; - // Dynamic alloc for windows comptibility - MMG5_SAFE_MALLOC(callist, ilist, double,return 0); - pt0 = &mesh->tetra[0]; ppt0 = &mesh->point[0]; memset(ppt0,0,sizeof(MMG5_Point)); @@ -287,7 +271,6 @@ int MMG5_movintptLES_iso(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROctree calold = MG_MIN(calold, pt->qual); } if (totvol < MMG5_EPSD2) { - MMG5_SAFE_FREE(callist); return 0; } @@ -330,7 +313,6 @@ int MMG5_movintptLES_iso(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROctree if ( iter > maxtou ) { memcpy(p0->c,oldc,3*sizeof(double)); - MMG5_SAFE_FREE(callist); return 0; } @@ -343,7 +325,6 @@ int MMG5_movintptLES_iso(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROctree (&mesh->tetra[list[k]/4])->mark=mesh->mark; } - MMG5_SAFE_FREE(callist); return 1; } @@ -645,7 +626,7 @@ int MMG5_movbdyregpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre double *n,r[3][3],lispoi[3*MMG3D_LMAX+1],ux,uy,det2d; double detloc,oppt[2],step,lambda[3]; double ll,m[2],o[3],no[3]; - double calold,calnew,caltmp,*callist; + double calold,calnew,caltmp,callist[MMG3D_LMAX+2]; int k,kel,l,ip0,nut,nxp; uint8_t i0,iface,i; @@ -779,10 +760,6 @@ int MMG5_movbdyregpt_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre memset(pxp,0,sizeof(MMG5_xPoint)); /* Test : check whether all volumes remain positive with new position of the point */ - - // Dynamic allocations for windows compatibility - MMG5_SAFE_MALLOC(callist, ilistv, double,return 0); - calold = calnew = DBL_MAX; for (l=0; ltetra[listv[l]/4])->qual= callist[l]; (&mesh->tetra[listv[l]/4])->mark=mesh->mark; } - MMG5_SAFE_FREE(callist); return 1; } @@ -870,7 +841,7 @@ int MMG3D_movbdycurvept_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROc MMG5_pxPoint pxp; MMG5_pPar par; double step,ll1old,ll2old,o[3],no[3],no2[3],to[3]; - double calold,calnew,caltmp,*callist,hmax,hausd; + double calold,calnew,caltmp,callist[MMG3D_LMAX+2],hmax,hausd; int l,iel,ip0,ipa,ipb,iptmpa,iptmpb,ip1,ip2,ip,nxp; int isloc,j; int16_t tag; @@ -1174,9 +1145,6 @@ int MMG3D_movbdycurvept_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROc memset(pxp,0,sizeof(MMG5_xPoint)); /* Test : check whether all volumes remain positive with new position of the point */ - // Dynamic allocations for windows compatibility - MMG5_SAFE_MALLOC(callist, ilistv, double,return 0); - calold = calnew = DBL_MAX; for( l=0 ; lqual); callist[l] = MMG5_orcal(mesh,met,0); if (callist[l] < MMG5_NULKAL) { - MMG5_SAFE_FREE(callist); return 0; } calnew = MG_MIN(calnew,callist[l]); } if ((calold < MMG5_EPSOK && calnew <= calold) || (calnew < MMG5_EPSOK) || (calnew <= 0.3*calold)) { - MMG5_SAFE_FREE(callist); return 0; } else if (improve && calnew < calold) { - MMG5_SAFE_FREE(callist); return 0; } @@ -1230,7 +1195,6 @@ int MMG3D_movbdycurvept_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROc (&mesh->tetra[listv[l]/4])->qual = callist[l]; (&mesh->tetra[listv[l]/4])->mark = mesh->mark; } - MMG5_SAFE_FREE(callist); return 1; } @@ -1300,7 +1264,7 @@ int MMG5_movbdynomintpt_iso(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROct MMG5_pTetra pt,pt0; MMG5_pxTetra pxt; MMG5_pPoint p0,p1,p2,ppt0; - double step,ll1old,ll2old,calold,calnew,*callist; + double step,ll1old,ll2old,calold,calnew,callist[MMG3D_LMAX+2]; double o[3],no[3],to[3]; int ip0,ip1,ip2,ip,iel,ipa,l; int8_t i,i0,ie; @@ -1354,9 +1318,6 @@ int MMG5_movbdynomintpt_iso(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROct if ( !(MMG5_BezierNom(mesh,ip0,ip,step,o,no,to)) ) return 0; /* Test : check whether all volumes remain positive with new position of the point */ - // Dynamic allocations for windows compatibility - MMG5_SAFE_MALLOC(callist, ilistv, double,return 0); - ppt0 = &mesh->point[0]; ppt0->c[0] = o[0]; ppt0->c[1] = o[1]; @@ -1375,17 +1336,14 @@ int MMG5_movbdynomintpt_iso(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROct calold = MG_MIN(calold, pt->qual); callist[l]= MMG5_orcal(mesh,met,0); if (callist[l] < MMG5_NULKAL) { - MMG5_SAFE_FREE(callist); return 0; } calnew = MG_MIN(calnew,callist[l]); } if ((calold < MMG5_EPSOK && calnew <= calold) || (calnew < MMG5_EPSOK) || (calnew <= 0.3*calold)) { - MMG5_SAFE_FREE(callist); return 0; } else if (improve && calnew < calold) { - MMG5_SAFE_FREE(callist); return 0; } @@ -1406,7 +1364,6 @@ int MMG5_movbdynomintpt_iso(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROct (&mesh->tetra[listv[l]/4])->mark = mesh->mark; } - MMG5_SAFE_FREE(callist); return 1; } From b244a52b165f94446e1287ae90d90965fc29c526 Mon Sep 17 00:00:00 2001 From: Algiane Date: Thu, 22 Jul 2021 08:47:32 +0200 Subject: [PATCH 134/170] Patch error in previous commit: we were copying a (non-initialized and wrong) second normal at non-manifold points in movbdy*pt. --- src/mmg3d/movpt_3d.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mmg3d/movpt_3d.c b/src/mmg3d/movpt_3d.c index db382dfca..aa4b42217 100755 --- a/src/mmg3d/movpt_3d.c +++ b/src/mmg3d/movpt_3d.c @@ -1053,7 +1053,8 @@ int MMG3D_movbdycurvept_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROc pxp->n1[1] = no[1]; pxp->n1[2] = no[2]; - if ( MG_GEO & edgTag ) { + if ( (MG_GEO & edgTag) && !(MG_NOM & edgTag) ) { + /* Copy the second normal for ridge point */ pxp->n2[0] = no2[0]; pxp->n2[1] = no2[1]; pxp->n2[2] = no2[2]; @@ -1181,7 +1182,8 @@ int MMG3D_movbdycurvept_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROc pxp->n1[1] = no[1]; pxp->n1[2] = no[2]; - if ( MG_GEO & edgTag ) { + if ( (MG_GEO & edgTag) && !(MG_NOM & edgTag) ) { + /* Copy the second normal for ridge point */ pxp->n2[0] = no2[0]; pxp->n2[1] = no2[1]; pxp->n2[2] = no2[2]; From a0b3bc1a65019368b319b3f8bea2ef716c6772f4 Mon Sep 17 00:00:00 2001 From: Algiane Date: Thu, 22 Jul 2021 08:49:47 +0200 Subject: [PATCH 135/170] Creation of movbdycurvept_ani function and calling of this function along a ref curve. --- src/mmg3d/anisomovpt_3d.c | 125 ++++++++++++++++++++++++++++++-------- 1 file changed, 99 insertions(+), 26 deletions(-) diff --git a/src/mmg3d/anisomovpt_3d.c b/src/mmg3d/anisomovpt_3d.c index 07c5e2053..3f3bcb29f 100644 --- a/src/mmg3d/anisomovpt_3d.c +++ b/src/mmg3d/anisomovpt_3d.c @@ -479,7 +479,6 @@ int MMG5_movbdyregpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre return 1; } - /** * \param mesh pointer toward the mesh structure. * \param met pointer toward the metric structure. @@ -490,23 +489,25 @@ int MMG5_movbdyregpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre * \param ilists size of the surfacic ball. * \param improve force the new minimum element quality to be greater or equal * than 1.02 of the old minimum element quality. - + * \param edgTag Type of edge on which we move (MG_REF, MG_NOM or MG_GEO). + * * \return 0 if fail, 1 if success. * * \remark we don't check if we break the hausdorff criterion. * - * Move boundary reference point, whose volumic and surfacic balls are passed. + * Move boundary reference, ridge or non-manifold point, whose volumic and + * surfacic balls are passed. * */ -int MMG5_movbdyrefpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctree, int *listv, - int ilistv, int *lists, int ilists, - int improve){ +static inline +int MMG3D_movbdycurvept_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctree, int *listv, + int ilistv, int *lists, int ilists,int improve,const int16_t edgTag){ MMG5_pTetra pt,pt0; MMG5_pPoint p0,ppt0; MMG5_Tria tt; MMG5_pxPoint pxp; double step,ll1old,ll2old,l1new,l2new; - double o[3],no[3],to[3], ncur[3],nprev[3],nneighi[3]; + double o[3],no[3],no2[3],to[3], ncur[3],nprev[3],nneighi[3]; double calold,calnew,caltmp,*callist; int l,iel,ip0,ipa,ipb,iptmpa,iptmpb,ip1,ip2,ip,nxp; int16_t tag,ier; @@ -518,10 +519,10 @@ int MMG5_movbdyrefpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre ip0 = pt->v[listv[0]%4]; p0 = &mesh->point[ip0]; - assert ( MG_REF & p0->tag ); + assert ( edgTag & p0->tag ); - /* Travel surfacic ball and recover the two ending points of ref curve : - two senses must be used */ + /* Travel surfacic ball and recover the two ending points of curve : two + senses must be used */ iel = lists[0]/4; iface = lists[0]%4; pt = &mesh->tetra[iel]; @@ -565,7 +566,7 @@ int MMG5_movbdyrefpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre if ( (iptmpa == ipa) || (iptmpa == ipb) ) { if ( pt->xt ) tag = mesh->xtetra[pt->xt].tag[iea]; else tag = 0; - if ( MG_REF & tag ) { + if ( edgTag & tag ) { ip1 = iptmpa; break; } @@ -573,7 +574,7 @@ int MMG5_movbdyrefpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre if ( (iptmpb == ipa) || (iptmpb == ipb) ) { if ( pt->xt ) tag = mesh->xtetra[pt->xt].tag[ieb]; else tag = 0; - if ( MG_REF & tag ) { + if ( edgTag & tag ) { ip1 = iptmpb; break; } @@ -582,7 +583,7 @@ int MMG5_movbdyrefpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre ipb = iptmpb; } - /* Now travel surfacic list in the reverse sense so as to get the second ridge */ + /* Now travel surfacic list in the reverse sense so as to get the second curve */ iel = lists[0]/4; iface = lists[0]%4; pt = &mesh->tetra[iel]; @@ -626,15 +627,20 @@ int MMG5_movbdyrefpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre if ( (iptmpa == ipa) || (iptmpa == ipb) ) { if ( pt->xt ) tag = mesh->xtetra[pt->xt].tag[iea]; else tag = 0; - if ( MG_REF & tag ) { + if ( edgTag & tag ) { ip2 = iptmpa; break; } } if ( (iptmpb == ipa) || (iptmpb == ipb) ) { - assert(pt->xt); - tag = mesh->xtetra[pt->xt].tag[ieb]; - if ( MG_REF & tag ) { + if ( (MG_GEO & edgTag) && (!pt->xt) ) { + tag = 0; + } + else { + assert(pt->xt); + tag = mesh->xtetra[pt->xt].tag[ieb]; + } + if ( edgTag & tag ) { ip2 = iptmpb; break; } @@ -644,9 +650,9 @@ int MMG5_movbdyrefpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre } if ( !(ip1 && ip2 && (ip1 != ip2)) ) return 0; - /* At this point, we get the point extremities of the ref limit curve passing through ip0 : - ip1, ip2, along with support tets it1,it2, the surface faces iface1,iface2, and the - associated edges ie1,ie2.*/ + /* At this point, we get the point extremities of the curve passing through + ip0 : ip1, ip2, along with support tets it1,it2, the surface faces + iface1,iface2, and the associated edges ie1,ie2.*/ /* Changes needed for choice of time step : see manuscript notes */ ll1old = MMG5_lenSurfEdg(mesh,met,ip0,ip1,0); @@ -662,7 +668,25 @@ int MMG5_movbdyrefpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre } /* Compute support of the associated edge, and features of the new position */ - if ( !(MMG5_BezierRef(mesh,ip0,ip,step,o,no,to)) ) return 0; + if ( MG_NOM & edgTag ) { + if ( !(MMG5_BezierNom(mesh,ip0,ip,step,o,no,to)) ) { + return 0; + } + } + else if ( MG_GEO & edgTag ) { + if ( !(MMG5_BezierRidge(mesh,ip0,ip,step,o,no,no2,to)) ) { + return 0; + } + } + else if ( MG_REF & edgTag ) { + if ( !(MMG5_BezierRef(mesh,ip0,ip,step,o,no,to)) ) { + return 0; + } + } + else { + assert ( 0 && "Unexpected edge tag in this function"); + return 0; + } /* Test : make sure that geometric approximation has not been degraded too much */ ppt0 = &mesh->point[0]; @@ -690,9 +714,25 @@ int MMG5_movbdyrefpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre pxp->n1[1] = no[1]; pxp->n1[2] = no[2]; - /* Interpolation of metric between ip0 and ip2 */ - if ( !MMG5_paratmet(p0->c,mesh->xpoint[p0->xp].n1,&met->m[6*ip0],o,no,&met->m[0]) ) - return 0; + if ( (MG_GEO & edgTag) && !(MG_NOM & edgTag) ) { + /* Copy the second normal for ridge point */ + pxp->n2[0] = no2[0]; + pxp->n2[1] = no2[1]; + pxp->n2[2] = no2[2]; + } + + if ( (MG_GEO & edgTag) && !(MG_NOM & edgTag) ) { + /* Interpolation of metric between ip0 and ip2 along ridge */ + if ( !MMG5_intridmet(mesh,met,ip0,ip,step,no,&met->m[0]) ) { + return 0; + } + } + else { + /* Interpolation of metric between ip0 and ip2 along non manifold or ref edge */ + if ( !MMG5_paratmet(p0->c,mesh->xpoint[p0->xp].n1,&met->m[6*ip0],o,no,&met->m[0]) ) { + return 0; + } + } /* Check whether proposed move is admissible under consideration of distances */ l1new = MMG5_lenSurfEdg(mesh,met,0,ip1,0); @@ -712,8 +752,11 @@ int MMG5_movbdyrefpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre iface = lists[ilists-1] % 4; MMG5_tet2tri(mesh,iel,iface,&tt); - for( i=0 ; i<3 ; i++ ) - if ( tt.v[i] == ip0 ) break; + for( i=0 ; i<3 ; i++ ) { + if ( tt.v[i] == ip0 ) { + break; + } + } assert ( i<3 ); if ( i>=3 ) return 0; @@ -819,6 +862,13 @@ int MMG5_movbdyrefpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre p0->n[1] = to[1]; p0->n[2] = to[2]; + if ( (MG_GEO & edgTag) && !(MG_NOM & edgTag) ) { + /* Copy the second normal for ridge point */ + pxp->n2[0] = no2[0]; + pxp->n2[1] = no2[1]; + pxp->n2[2] = no2[2]; + } + memcpy(&met->m[6*ip0],&met->m[0],6*sizeof(double)); for( l=0 ; l Date: Thu, 22 Jul 2021 08:52:20 +0200 Subject: [PATCH 136/170] Change quality test in movbdyridpt_ani in order to prepare the merge with movbdycurvpt_ani. --- src/mmg3d/anisomovpt_3d.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mmg3d/anisomovpt_3d.c b/src/mmg3d/anisomovpt_3d.c index 3f3bcb29f..b38a6b2d8 100644 --- a/src/mmg3d/anisomovpt_3d.c +++ b/src/mmg3d/anisomovpt_3d.c @@ -1546,7 +1546,7 @@ int MMG5_movbdyridpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre } if ( calold < MMG5_EPSOK && calnew <= calold ) return 0; - else if ( calnew <= calold ) return 0; + else if ( calnew < calold ) return 0; memset(pxp,0,sizeof(MMG5_xPoint)); /* Test : check whether all volumes remain positive with new position of the point */ From fcf607ac63f27f0e1014e6ac40924c7849fa434e Mon Sep 17 00:00:00 2001 From: Algiane Date: Thu, 22 Jul 2021 08:58:49 +0200 Subject: [PATCH 137/170] Remove a useless (and probably erronated) squaring of the old length in movbdyridpt_ani. --- src/mmg3d/anisomovpt_3d.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/mmg3d/anisomovpt_3d.c b/src/mmg3d/anisomovpt_3d.c index b38a6b2d8..7ad007ef9 100644 --- a/src/mmg3d/anisomovpt_3d.c +++ b/src/mmg3d/anisomovpt_3d.c @@ -1424,9 +1424,6 @@ int MMG5_movbdyridpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre if ( (!l1old) || (!l2old) ) return 0; - l1old = l1old*l1old; - l2old = l2old*l2old; - if ( l1old < l2old ) { //move towards p2 ip = ip2; } From 8d91c1a45e95c7a1080900d969f431b23b3a6a56 Mon Sep 17 00:00:00 2001 From: Algiane Date: Thu, 22 Jul 2021 09:05:43 +0200 Subject: [PATCH 138/170] Simplification of ridge test + modification of the call of the lensurfedge function in order to enable the factorization with the movbdyridpt function. --- src/mmg3d/anisomovpt_3d.c | 26 +++++++++++++++----------- src/mmg3d/movpt_3d.c | 18 +++++++++++------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/mmg3d/anisomovpt_3d.c b/src/mmg3d/anisomovpt_3d.c index 7ad007ef9..3b7e51f8a 100644 --- a/src/mmg3d/anisomovpt_3d.c +++ b/src/mmg3d/anisomovpt_3d.c @@ -511,13 +511,17 @@ int MMG3D_movbdycurvept_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROc double calold,calnew,caltmp,*callist; int l,iel,ip0,ipa,ipb,iptmpa,iptmpb,ip1,ip2,ip,nxp; int16_t tag,ier; - uint8_t i,i0,ie,iface,iea,ieb; + uint8_t i,i0,ie,iface,iea,ieb,isrid; - step = 0.1; + step = 0.1; ip1 = ip2 = 0; - pt = &mesh->tetra[listv[0]/4]; - ip0 = pt->v[listv[0]%4]; - p0 = &mesh->point[ip0]; + pt = &mesh->tetra[listv[0]/4]; + ip0 = pt->v[listv[0]%4]; + p0 = &mesh->point[ip0]; + + /* Compute if the edge is a simple ridge to know if we have to compute a + * second normal at point */ + isrid = ((MG_GEO & edgTag) && !(MG_NOM & edgTag)); assert ( edgTag & p0->tag ); @@ -655,8 +659,8 @@ int MMG3D_movbdycurvept_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROc iface1,iface2, and the associated edges ie1,ie2.*/ /* Changes needed for choice of time step : see manuscript notes */ - ll1old = MMG5_lenSurfEdg(mesh,met,ip0,ip1,0); - ll2old = MMG5_lenSurfEdg(mesh,met,ip0,ip2,0); + ll1old = MMG5_lenSurfEdg(mesh,met,ip0,ip1,isrid); + ll2old = MMG5_lenSurfEdg(mesh,met,ip0,ip2,isrid); if ( (!ll1old) || (!ll2old) ) return 0; @@ -714,7 +718,7 @@ int MMG3D_movbdycurvept_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROc pxp->n1[1] = no[1]; pxp->n1[2] = no[2]; - if ( (MG_GEO & edgTag) && !(MG_NOM & edgTag) ) { + if ( isrid ) { /* Copy the second normal for ridge point */ pxp->n2[0] = no2[0]; pxp->n2[1] = no2[1]; @@ -735,8 +739,8 @@ int MMG3D_movbdycurvept_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROc } /* Check whether proposed move is admissible under consideration of distances */ - l1new = MMG5_lenSurfEdg(mesh,met,0,ip1,0); - l2new = MMG5_lenSurfEdg(mesh,met,0,ip2,0); + l1new = MMG5_lenSurfEdg(mesh,met,0,ip1,isrid); + l2new = MMG5_lenSurfEdg(mesh,met,0,ip2,isrid); if ( (!l1new) || (!l2new) ) return 0; @@ -862,7 +866,7 @@ int MMG3D_movbdycurvept_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROc p0->n[1] = to[1]; p0->n[2] = to[2]; - if ( (MG_GEO & edgTag) && !(MG_NOM & edgTag) ) { + if ( isrid ) { /* Copy the second normal for ridge point */ pxp->n2[0] = no2[0]; pxp->n2[1] = no2[1]; diff --git a/src/mmg3d/movpt_3d.c b/src/mmg3d/movpt_3d.c index aa4b42217..e60c5e791 100755 --- a/src/mmg3d/movpt_3d.c +++ b/src/mmg3d/movpt_3d.c @@ -845,13 +845,17 @@ int MMG3D_movbdycurvept_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROc int l,iel,ip0,ipa,ipb,iptmpa,iptmpb,ip1,ip2,ip,nxp; int isloc,j; int16_t tag; - uint8_t i,i0,ie,iface,iea,ieb; + uint8_t i,i0,ie,iface,iea,ieb,isrid; - step = 0.1; + step = 0.1; ip1 = ip2 = 0; - pt = &mesh->tetra[listv[0]/4]; - ip0 = pt->v[listv[0]%4]; - p0 = &mesh->point[ip0]; + pt = &mesh->tetra[listv[0]/4]; + ip0 = pt->v[listv[0]%4]; + p0 = &mesh->point[ip0]; + + /* Compute if the edge is a simple ridge to know if we have to compute a + * second normal at point */ + isrid = ((MG_GEO & edgTag) && !(MG_NOM & edgTag)); assert ( edgTag & p0->tag ); @@ -1053,7 +1057,7 @@ int MMG3D_movbdycurvept_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROc pxp->n1[1] = no[1]; pxp->n1[2] = no[2]; - if ( (MG_GEO & edgTag) && !(MG_NOM & edgTag) ) { + if ( isrid ) { /* Copy the second normal for ridge point */ pxp->n2[0] = no2[0]; pxp->n2[1] = no2[1]; @@ -1182,7 +1186,7 @@ int MMG3D_movbdycurvept_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROc pxp->n1[1] = no[1]; pxp->n1[2] = no[2]; - if ( (MG_GEO & edgTag) && !(MG_NOM & edgTag) ) { + if ( isrid ) { /* Copy the second normal for ridge point */ pxp->n2[0] = no2[0]; pxp->n2[1] = no2[1]; From a47e35ce94ca8461c34b38f66b0033e4a0860ff7 Mon Sep 17 00:00:00 2001 From: Algiane Date: Thu, 22 Jul 2021 09:07:12 +0200 Subject: [PATCH 139/170] Movbdynompt_ani refactoring. --- src/mmg3d/anisomovpt_3d.c | 325 +------------------------------------- 1 file changed, 1 insertion(+), 324 deletions(-) diff --git a/src/mmg3d/anisomovpt_3d.c b/src/mmg3d/anisomovpt_3d.c index 3b7e51f8a..b9080e36a 100644 --- a/src/mmg3d/anisomovpt_3d.c +++ b/src/mmg3d/anisomovpt_3d.c @@ -928,331 +928,8 @@ int MMG5_movbdyrefpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre int MMG5_movbdynompt_ani(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROctree, int *listv, int ilistv, int *lists, int ilists, int improve){ - MMG5_pTetra pt,pt0; - MMG5_pPoint p0,ppt0; - MMG5_pxPoint pxp; - MMG5_Tria tt; - double step,ll1old,ll2old,l1new,l2new; - double calold,calnew,caltmp,*callist; - double o[3],no[3],to[3],nprev[3],ncur[3],nneighi[3]; - int ip0,ip1,ip2,ip,iel,ipa,ipb,l,iptmpa,iptmpb,nxp; - int16_t tag,ier; - int8_t iface,i,i0,iea,ieb,ie; - - step = 0.1; - ip1 = ip2 = 0; - pt = &mesh->tetra[listv[0]/4]; - ip0 = pt->v[listv[0]%4]; - p0 = &mesh->point[ip0]; - - assert ( p0->tag & MG_NOM ); - - /* Travel surfacic ball and recover the two ending points of non manifold curve : - two senses must be used */ - iel = lists[0]/4; - iface = lists[0]%4; - pt = &mesh->tetra[iel]; - ipa = ipb = 0; - for (i=0; i<3; i++) { - if ( pt->v[MMG5_idir[iface][i]] != ip0 ) { - if ( !ipa ) - ipa = pt->v[MMG5_idir[iface][i]]; - else - ipb = pt->v[MMG5_idir[iface][i]]; - } - } - assert(ipa && ipb); - - for (l=1; ltetra[iel]; - iea = ieb = 0; - for (i=0; i<3; i++) { - ie = MMG5_iarf[iface][i]; //edge i on face iface - if ( (pt->v[MMG5_iare[ie][0]] == ip0) || (pt->v[MMG5_iare[ie][1]] == ip0) ) { - if ( !iea ) - iea = ie; - else - ieb = ie; - } - } - if ( pt->v[MMG5_iare[iea][0]] != ip0 ) - iptmpa = pt->v[MMG5_iare[iea][0]]; - else { - assert(pt->v[MMG5_iare[iea][1]] != ip0); - iptmpa = pt->v[MMG5_iare[iea][1]]; - } - if ( pt->v[MMG5_iare[ieb][0]] != ip0 ) - iptmpb = pt->v[MMG5_iare[ieb][0]]; - else { - assert(pt->v[MMG5_iare[ieb][1]] != ip0); - iptmpb = pt->v[MMG5_iare[ieb][1]]; - } - if ( (iptmpa == ipa) || (iptmpa == ipb) ) { - if ( pt->xt ) tag = mesh->xtetra[pt->xt].tag[iea]; - else tag = 0; - if ( MG_NOM & tag ) { - ip1 = iptmpa; - break; - } - } - if ( (iptmpb == ipa) || (iptmpb == ipb) ) { - if ( pt->xt ) tag = mesh->xtetra[pt->xt].tag[ieb]; - else tag = 0; - if ( MG_NOM & tag ) { - ip1 = iptmpb; - break; - } - } - ipa = iptmpa; - ipb = iptmpb; - } - - /* Now travel surfacic list in the reverse sense so as to get the second non manifold point */ - iel = lists[0]/4; - iface = lists[0]%4; - pt = &mesh->tetra[iel]; - ipa = ipb = 0; - for (i=0; i<3; i++) { - if ( pt->v[MMG5_idir[iface][i]] != ip0 ) { - if ( !ipa ) - ipa = pt->v[MMG5_idir[iface][i]]; - else - ipb = pt->v[MMG5_idir[iface][i]]; - } - } - assert(ipa && ipb); - - for (l=ilists-1; l>0; l--) { - iel = lists[l] / 4; - iface = lists[l] % 4; - pt = &mesh->tetra[iel]; - iea = ieb = 0; - for (i=0; i<3; i++) { - ie = MMG5_iarf[iface][i]; //edge i on face iface - if ( (pt->v[MMG5_iare[ie][0]] == ip0) || (pt->v[MMG5_iare[ie][1]] == ip0) ) { - if ( !iea ) - iea = ie; - else - ieb = ie; - } - } - if ( pt->v[MMG5_iare[iea][0]] != ip0 ) - iptmpa = pt->v[MMG5_iare[iea][0]]; - else { - assert(pt->v[MMG5_iare[iea][1]] != ip0); - iptmpa = pt->v[MMG5_iare[iea][1]]; - } - if ( pt->v[MMG5_iare[ieb][0]] != ip0 ) - iptmpb = pt->v[MMG5_iare[ieb][0]]; - else { - assert(pt->v[MMG5_iare[ieb][1]] != ip0); - iptmpb = pt->v[MMG5_iare[ieb][1]]; - } - if ( (iptmpa == ipa) || (iptmpa == ipb) ) { - if ( pt->xt ) tag = mesh->xtetra[pt->xt].tag[iea]; - else tag = 0; - if ( MG_NOM & tag ) { - ip2 = iptmpa; - break; - } - } - if ( (iptmpb == ipa) || (iptmpb == ipb) ) { - assert(pt->xt); - tag = mesh->xtetra[pt->xt].tag[ieb]; - if ( MG_NOM & tag ) { - ip2 = iptmpb; - break; - } - } - ipa = iptmpa; - ipb = iptmpb; - } - if ( !(ip1 && ip2 && (ip1 != ip2)) ) return 0; - - /* At this point, we get the point extremities of the non manifold curve passing through ip0 : - ip1, ip2, along with support tets it1,it2, the surface faces iface1,iface2, and the - associated edges ie1,ie2.*/ - ll1old = MMG5_lenSurfEdg(mesh,met,ip0,ip1,0); - ll2old = MMG5_lenSurfEdg(mesh,met,ip0,ip2,0); - - if ( (!ll1old) || (!ll2old) ) return 0; - - if ( ll1old < ll2old ) { //move towards p2 - ip = ip2; - } - else { - ip = ip1; - } - - /* Compute support of the associated edge, and features of the new position */ - if ( !(MMG5_BezierNom(mesh,ip0,ip,step,o,no,to)) ) return 0; - - /* Test : make sure that geometric approximation has not been degraded too much */ - ppt0 = &mesh->point[0]; - ppt0->c[0] = o[0]; - ppt0->c[1] = o[1]; - ppt0->c[2] = o[2]; - ppt0->tag = p0->tag; - ppt0->ref = p0->ref; - - nxp = mesh->xp + 1; - if ( nxp > mesh->xpmax ) { - MMG5_TAB_RECALLOC(mesh,mesh->xpoint,mesh->xpmax,0.2,MMG5_xPoint, - "larger xpoint table",return 0;); - } - ppt0->xp = nxp; - pxp = &mesh->xpoint[nxp]; - memcpy(pxp,&(mesh->xpoint[p0->xp]),sizeof(MMG5_xPoint)); - - ppt0->n[0] = to[0]; - ppt0->n[1] = to[1]; - ppt0->n[2] = to[2]; - - pxp->n1[0] = no[0]; - pxp->n1[1] = no[1]; - pxp->n1[2] = no[2]; - - /* Interpolation of metric between ip0 and ip2 */ - if ( !MMG5_paratmet(p0->c,mesh->xpoint[p0->xp].n1,&met->m[6*ip0],o,no,&met->m[0]) ) - return 0; - - /* Check whether proposed move is admissible under consideration of distances */ - l1new = MMG5_lenSurfEdg(mesh,met,0,ip1,0); - l2new = MMG5_lenSurfEdg(mesh,met,0,ip2,0); - - if ( (!l1new) || (!l2new) ) return 0; - - if ( fabs(l2new -l1new) >= fabs(ll2old -ll1old) ) - return 0; - /* For each surfacic triangle build a virtual displaced triangle for check - * purposes : - * - check the new triangle qualities; - * - check normal deviation with the adjacent through the edge facing ip0 - * and the previous one */ - iel = lists[ilists-1] / 4; - iface = lists[ilists-1] % 4; - - MMG5_tet2tri(mesh,iel,iface,&tt); - for( i=0 ; i<3 ; i++ ) - if ( tt.v[i] == ip0 ) break; - - assert ( i<3 ); - if ( i>=3 ) return 0; - tt.v[i] = 0; - - if ( !MMG5_nortri(mesh, &tt, nprev) ) return 0; - - calold = calnew = DBL_MAX; - for( l=0 ; l=3 ) return 0; - tt.v[i] = 0; - - caltmp = MMG5_caltri(mesh,met,&tt); - if ( caltmp < MMG5_EPSD2 ) { - /* We don't check the input triangle qualities, thus we may have a very - * bad triangle in our mesh */ - return 0; - } - calnew = MG_MIN(calnew,caltmp); - - if ( !MMG5_nortri(mesh, &tt, ncur) ) return 0; - - if ( ( !(tt.tag[i] & MG_GEO) ) && ( !(tt.tag[i] & MG_NOM) ) ) { - /* Check normal deviation between iel and the triangle facing ip0 */ - ier = MMG3D_normalAdjaTri(mesh,iel,iface, i,nneighi); - if ( ier <=0 ) { - return 0; - } - ier = MMG5_devangle( ncur, nneighi, mesh->info.dhd ); - if ( ier <= 0 ) { - return 0; - } - } - - i = MMG5_iprv2[i]; - - if ( ( !(tt.tag[i] & MG_GEO) ) && ( !(tt.tag[i] & MG_NOM) ) ) { - /* Check normal deviation between k and the previous triangle */ - ier = MMG5_devangle( ncur, nprev, mesh->info.dhd ); - if ( ier<=0 ) { - return 0; - } - } - memcpy(nprev, ncur, 3*sizeof(double)); - } - - if ( calold < MMG5_EPSOK && calnew <= calold ) return 0; - else if ( calnew < calold ) return 0; - memset(pxp,0,sizeof(MMG5_xPoint)); - - /* Test : check whether all volumes remain positive with new position of the point */ - // Dynamic allocations for windows compatibility - MMG5_SAFE_MALLOC(callist, ilistv, double,return 0); - - calold = calnew = DBL_MAX; - for( l=0 ; ltetra[iel]; - pt0 = &mesh->tetra[0]; - memcpy(pt0,pt,sizeof(MMG5_Tetra)); - pt0->v[i0] = 0; - calold = MG_MIN(calold, pt->qual); - callist[l]= MMG5_orcal(mesh,met,0); - if (callist[l] < MMG5_NULKAL) { - MMG5_SAFE_FREE(callist); - return 0; - } - calnew = MG_MIN(calnew,callist[l]); - } - if ((calold < MMG5_EPSOK && calnew <= calold) || - (calnew < MMG5_EPSOK) || (calnew <= 0.3*calold)) { - MMG5_SAFE_FREE(callist); - return 0; - } else if (improve && calnew < calold) { - MMG5_SAFE_FREE(callist); - return 0; - } - - /* Update coordinates, normals, for new point */ - if ( PROctree ) - MMG3D_movePROctree(mesh, PROctree, ip0, o, p0->c); - - p0->c[0] = o[0]; - p0->c[1] = o[1]; - p0->c[2] = o[2]; - - pxp = &mesh->xpoint[p0->xp]; - pxp->n1[0] = no[0]; - pxp->n1[1] = no[1]; - pxp->n1[2] = no[2]; - - p0->n[0] = to[0]; - p0->n[1] = to[1]; - p0->n[2] = to[2]; - - memcpy(&met->m[6*ip0],&met->m[0],6*sizeof(double)); - - for(l=0; ltetra[listv[l]/4])->qual = callist[l]; - (&mesh->tetra[listv[l]/4])->mark = mesh->mark; - } - MMG5_SAFE_FREE(callist); - return 1; + return MMG3D_movbdycurvept_ani(mesh,met,PROctree,listv,ilistv,lists,ilists,improve,MG_NOM); } From 2d4262f8190adea2643ce917d035f29dd6ba6292 Mon Sep 17 00:00:00 2001 From: Algiane Date: Thu, 22 Jul 2021 09:07:50 +0200 Subject: [PATCH 140/170] movbdyridpt_ani refactoring. --- src/mmg3d/anisomovpt_3d.c | 333 +------------------------------------- 1 file changed, 1 insertion(+), 332 deletions(-) diff --git a/src/mmg3d/anisomovpt_3d.c b/src/mmg3d/anisomovpt_3d.c index b9080e36a..61eecef95 100644 --- a/src/mmg3d/anisomovpt_3d.c +++ b/src/mmg3d/anisomovpt_3d.c @@ -952,337 +952,6 @@ int MMG5_movbdynompt_ani(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROctree int MMG5_movbdyridpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctree, int *listv, int ilistv,int *lists,int ilists, int improve) { - MMG5_pTetra pt,pt0; - MMG5_pPoint p0,ppt0; - MMG5_Tria tt; - MMG5_pxPoint pxp; - double step,l1old,l2old,l1new,l2new; - double o[3],no1[3],no2[3],to[3],nprev[3],ncur[3],nneighi[3]; - double calold,calnew,caltmp,*callist; - int l,iel,ip0,ipa,ipb,iptmpa,iptmpb,ip1,ip2,ip,nxp; - int16_t tag,ier; - uint8_t i,i0,ie,iface,iea,ieb; - - step = 0.1; - ip1 = ip2 = 0; - pt = &mesh->tetra[listv[0]/4]; - ip0 = pt->v[listv[0]%4]; - p0 = &mesh->point[ip0]; - - assert ( MG_GEO & p0->tag ); - - /* Travel surfacic ball an recover the two ending points of ridge : two senses - must be used POSSIBLE OPTIMIZATION HERE : One travel only is needed */ - iel = lists[0] / 4; - iface = lists[0] % 4; - pt = &mesh->tetra[iel]; - ipa = ipb = 0; - for (i=0; i<3; i++) { - if ( pt->v[MMG5_idir[iface][i]] != ip0 ) { - if ( !ipa ) - ipa = pt->v[MMG5_idir[iface][i]]; - else - ipb = pt->v[MMG5_idir[iface][i]]; - } - } - assert(ipa && ipb); - - for (l=1; ltetra[iel]; - iea = ieb = 0; - for (i=0; i<3; i++) { - ie = MMG5_iarf[iface][i]; //edge i on face iface - if ( (pt->v[MMG5_iare[ie][0]] == ip0) || (pt->v[MMG5_iare[ie][1]] == ip0) ) { - if ( !iea ) - iea = ie; - else - ieb = ie; - } - } - if ( pt->v[MMG5_iare[iea][0]] != ip0 ) - iptmpa = pt->v[MMG5_iare[iea][0]]; - else { - assert(pt->v[MMG5_iare[iea][1]] != ip0); - iptmpa = pt->v[MMG5_iare[iea][1]]; - } - if ( pt->v[MMG5_iare[ieb][0]] != ip0 ) - iptmpb = pt->v[MMG5_iare[ieb][0]]; - else { - assert(pt->v[MMG5_iare[ieb][1]] != ip0); - iptmpb = pt->v[MMG5_iare[ieb][1]]; - } - if ( (iptmpa == ipa) || (iptmpa == ipb) ) { - if ( pt->xt ) tag = mesh->xtetra[pt->xt].tag[iea]; - else tag = 0; - if ( MG_GEO & tag ) { - ip1 = iptmpa; - break; - } - } - if ( (iptmpb == ipa) || (iptmpb == ipb) ) { - if ( pt->xt ) tag = mesh->xtetra[pt->xt].tag[ieb]; - else tag = 0; - if ( MG_GEO & tag ) { - ip1 = iptmpb; - break; - } - } - ipa = iptmpa; - ipb = iptmpb; - } - - /* Now travel surfacic list in the reverse sense so as to get the second ridge */ - iel = lists[0] / 4; - iface = lists[0] % 4; - pt = &mesh->tetra[iel]; - ipa = ipb = 0; - for (i=0; i<3; i++) { - if ( pt->v[MMG5_idir[iface][i]] != ip0 ) { - if ( !ipa ) - ipa = pt->v[MMG5_idir[iface][i]]; - else - ipb = pt->v[MMG5_idir[iface][i]]; - } - } - assert(ipa && ipb); - - for (l=ilists-1; l>0; l--) { - iel = lists[l]/4; - iface = lists[l]%4; - pt = &mesh->tetra[iel]; - iea = ieb = 0; - for (i=0; i<3; i++) { - ie = MMG5_iarf[iface][i]; //edge i on face iface - if ( (pt->v[MMG5_iare[ie][0]] == ip0) || (pt->v[MMG5_iare[ie][1]] == ip0) ) { - if ( !iea ) - iea = ie; - else - ieb = ie; - } - } - if ( pt->v[MMG5_iare[iea][0]] != ip0 ) - iptmpa = pt->v[MMG5_iare[iea][0]]; - else { - assert(pt->v[MMG5_iare[iea][1]] != ip0); - iptmpa = pt->v[MMG5_iare[iea][1]]; - } - if ( pt->v[MMG5_iare[ieb][0]] != ip0 ) - iptmpb = pt->v[MMG5_iare[ieb][0]]; - else { - assert(pt->v[MMG5_iare[ieb][1]] != ip0); - iptmpb = pt->v[MMG5_iare[ieb][1]]; - } - if ( (iptmpa == ipa) || (iptmpa == ipb) ) { - if ( pt->xt ) tag = mesh->xtetra[pt->xt].tag[iea]; - else tag = 0; - if ( MG_GEO & tag ) { - ip2 = iptmpa; - break; - } - } - if ( (iptmpb == ipa) || (iptmpb == ipb) ) { - if ( pt->xt ) tag = mesh->xtetra[pt->xt].tag[ieb]; - else tag = 0; - if ( MG_GEO & tag ) { - ip2 = iptmpb; - break; - } - } - ipa = iptmpa; - ipb = iptmpb; - } - if ( !(ip1 && ip2 && (ip1 != ip2)) ) return 0; - - /* At this point, we get the point extremities of the ridge curve passing through ip0 : - ip1, ip2, along with support tets it1,it2, the surface faces iface1,iface2, and the - associated edges ie1,ie2.*/ - - /* Changes needed for choice of time step : see manuscript notes */ - l1old = MMG5_lenSurfEdg(mesh,met,ip0,ip1,1); - l2old = MMG5_lenSurfEdg(mesh,met,ip0,ip2,1); - - if ( (!l1old) || (!l2old) ) return 0; - - if ( l1old < l2old ) { //move towards p2 - ip = ip2; - } - else { - ip = ip1; - } - - /* Compute support of the associated edge, and features of the new position */ - if ( !(MMG5_BezierRidge(mesh,ip0,ip,step,o,no1,no2,to)) ) return 0; - - /* Test : make sure that geometric approximation has not been degraded too much */ - ppt0 = &mesh->point[0]; - ppt0->c[0] = o[0]; - ppt0->c[1] = o[1]; - ppt0->c[2] = o[2]; - ppt0->tag = p0->tag; - ppt0->ref = p0->ref; - - nxp = mesh->xp+1; - if ( nxp > mesh->xpmax ) { - MMG5_TAB_RECALLOC(mesh,mesh->xpoint,mesh->xpmax,0.2,MMG5_xPoint, - "larger xpoint table",return 0;); - } - ppt0->xp = nxp; - pxp = &mesh->xpoint[nxp]; - memcpy(pxp,&(mesh->xpoint[p0->xp]),sizeof(MMG5_xPoint)); - - ppt0->n[0] = to[0]; - ppt0->n[1] = to[1]; - ppt0->n[2] = to[2]; - - pxp->n1[0] = no1[0]; - pxp->n1[1] = no1[1]; - pxp->n1[2] = no1[2]; - - pxp->n2[0] = no2[0]; - pxp->n2[1] = no2[1]; - pxp->n2[2] = no2[2]; - - /* Interpolation of metric between ip0 and ip2 */ - if ( !MMG5_intridmet(mesh,met,ip0,ip,step,no1,&met->m[0]) ) return 0; - - /* Check whether proposed move is admissible under consideration of distances */ - l1new = MMG5_lenSurfEdg(mesh,met,0,ip1,1); - l2new = MMG5_lenSurfEdg(mesh,met,0,ip2,1); - - if ( (!l1new) || (!l2new) ) return 0; - - if ( fabs(l2new -l1new) >= fabs(l2old -l1old) ) - return 0; - - /* For each surfacic triangle build a virtual displaced triangle for check - * purposes : - * - check the new triangle qualities; - * - check normal deviation with the adjacent through the edge facing ip0 - * and the previous one */ - iel = lists[ilists-1] / 4; - iface = lists[ilists-1] % 4; - - MMG5_tet2tri(mesh,iel,iface,&tt); - for (i=0; i<3; i++) { - if ( tt.v[i] == ip0 ) break; - } - assert(i<3); - if ( i>=3 ) return 0; - tt.v[i] = 0; - - if ( !MMG5_nortri(mesh, &tt, nprev) ) return 0; - - calold = calnew = DBL_MAX; - for (l=0; l=3 ) return 0; - tt.v[i] = 0; - - caltmp = MMG5_caltri(mesh,met,&tt); - if ( caltmp < MMG5_EPSD2 ) { - /* We don't check the input triangle qualities, thus we may have a very - * bad triangle in our mesh */ - return 0; - } - calnew = MG_MIN(calnew,caltmp); - - if ( !MMG5_nortri(mesh, &tt, ncur) ) return 0; - - if ( ( !(tt.tag[i] & MG_GEO) ) && ( !(tt.tag[i] & MG_NOM) ) ) { - /* Check normal deviation between iel and the triangle facing ip0 */ - ier = MMG3D_normalAdjaTri(mesh,iel,iface, i,nneighi); - if ( ier <=0 ) { - return 0; - } - ier = MMG5_devangle( ncur, nneighi, mesh->info.dhd ); - if ( ier <= 0 ) { - return 0; - } - } - i = MMG5_iprv2[i]; - - if ( ( !(tt.tag[i] & MG_GEO) ) && ( !(tt.tag[i] & MG_NOM) ) ) { - /* Check normal deviation between k and the previous triangle */ - ier = MMG5_devangle( ncur, nprev, mesh->info.dhd ); - if ( ier<=0 ) { - return 0; - } - } - memcpy(nprev, ncur, 3*sizeof(double)); - } - - if ( calold < MMG5_EPSOK && calnew <= calold ) return 0; - else if ( calnew < calold ) return 0; - memset(pxp,0,sizeof(MMG5_xPoint)); - - /* Test : check whether all volumes remain positive with new position of the point */ - // Dynamic allocations for windows compatibility - MMG5_SAFE_MALLOC(callist, ilistv, double,return 0); - - calold = calnew = DBL_MAX; - for (l=0; ltetra[iel]; - pt0 = &mesh->tetra[0]; - memcpy(pt0,pt,sizeof(MMG5_Tetra)); - pt0->v[i0] = 0; - calold = MG_MIN(calold, pt->qual); - callist[l]=MMG5_orcal(mesh,met,0); - if (callist[l] < MMG5_NULKAL) { - MMG5_SAFE_FREE(callist); - return 0; - } - calnew = MG_MIN(calnew,callist[l]); - } - if ((calold < MMG5_EPSOK && calnew <= calold) || - (calnew < MMG5_EPSOK) || (calnew <= 0.3*calold)) { - MMG5_SAFE_FREE(callist); - return 0; - } else if (improve && calnew < calold) { - MMG5_SAFE_FREE(callist); - return 0; - } - - /* Update coordinates, normals, for new point */ - if ( PROctree ) - MMG3D_movePROctree(mesh, PROctree, ip0, o, p0->c); - - p0->c[0] = o[0]; - p0->c[1] = o[1]; - p0->c[2] = o[2]; - - pxp = &mesh->xpoint[p0->xp]; - pxp->n1[0] = no1[0]; - pxp->n1[1] = no1[1]; - pxp->n1[2] = no1[2]; - - pxp->n2[0] = no2[0]; - pxp->n2[1] = no2[1]; - pxp->n2[2] = no2[2]; - - p0->n[0] = to[0]; - p0->n[1] = to[1]; - p0->n[2] = to[2]; - - memcpy(&met->m[6*ip0],&met->m[0],6*sizeof(double)); - - for(l=0; ltetra[listv[l]/4])->qual = callist[l]; - (&mesh->tetra[listv[l]/4])->mark = mesh->mark; - } - MMG5_SAFE_FREE(callist); - return 1; + return MMG3D_movbdycurvept_ani(mesh,met,PROctree,listv,ilistv,lists,ilists,improve,MG_GEO); } From 9f8b8e849f85253ae710e17d08174acd488942d4 Mon Sep 17 00:00:00 2001 From: Algiane Date: Thu, 22 Jul 2021 09:21:21 +0200 Subject: [PATCH 141/170] Remove dynamic allocation of callist in anisomovpt_3d. --- src/mmg3d/anisomovpt_3d.c | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/src/mmg3d/anisomovpt_3d.c b/src/mmg3d/anisomovpt_3d.c index 61eecef95..3afa2089f 100644 --- a/src/mmg3d/anisomovpt_3d.c +++ b/src/mmg3d/anisomovpt_3d.c @@ -59,7 +59,7 @@ int MMG5_movintpt_ani(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROctree, i MMG5_pTetra pt,pt0; MMG5_pPoint p0,p1,p2,p3,ppt0; double vol,totvol,m[6]; - double calold,calnew,*callist,det; + double calold,calnew,callist[MMG3D_LMAX+2],det; int k,iel,i0; assert ( ilist > 0 ); @@ -123,8 +123,6 @@ int MMG5_movintpt_ani(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROctree, i ppt0->c[2] *= totvol; /* Check new position validity */ - // Dynamic alloc for windows comptibility - MMG5_SAFE_MALLOC(callist, ilist, double,return 0); calnew = DBL_MAX; for (k=0; kv[i0] = 0; callist[k] = MMG5_orcal(mesh,met,0); if (callist[k] < MMG5_NULKAL) { - MMG5_SAFE_FREE(callist); return 0; } calnew = MG_MIN(calnew,callist[k]); } if (calold < MMG5_EPSOK && calnew <= calold) { - MMG5_SAFE_FREE(callist); return 0; } else if (calnew < MMG5_EPSOK) { - MMG5_SAFE_FREE(callist); return 0; } else if ( improve && calnew < 1.02* calold ) { - MMG5_SAFE_FREE(callist); return 0; } else if ( calnew < 0.3 * calold ) { - MMG5_SAFE_FREE(callist); return 0; } @@ -169,7 +162,6 @@ int MMG5_movintpt_ani(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROctree, i (&mesh->tetra[list[k]/4])->mark=mesh->mark; } - MMG5_SAFE_FREE(callist); return 1; } @@ -204,7 +196,7 @@ int MMG5_movbdyregpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre double *n,r[3][3],lispoi[3*MMG3D_LMAX+1],det2d; double detloc,gv[2],step,lambda[3]; double o[3],no[3],*m0,ncur[3],nprev[3],nneighi[3]; - double calold,calnew,caltmp,*callist; + double calold,calnew,caltmp,callist[MMG3D_LMAX+2]; int k,kel,iel,l,ip0,nxp,ier; uint8_t i0,iface,i; static int warn = 0; @@ -422,7 +414,6 @@ int MMG5_movbdyregpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre memset(pxp,0,sizeof(MMG5_xPoint)); /* Test : check whether all volumes remain positive with new position of the point */ - MMG5_SAFE_MALLOC(callist, ilistv, double,return 0); calold = calnew = DBL_MAX; for (l=0; lqual); callist[l]=MMG5_orcal(mesh,met,0); if ( callist[l] < MMG5_NULKAL ) { - MMG5_SAFE_FREE(callist); return 0; } calnew = MG_MIN(calnew,callist[l]); } if ( calold < MMG5_EPSOK && calnew <= calold ) { - MMG5_SAFE_FREE(callist); return 0; } else if (calnew < MMG5_EPSOK) { - MMG5_SAFE_FREE(callist); return 0; } else if (improveVol && calnew < calold) { - MMG5_SAFE_FREE(callist); return 0; } else if ( calnew < 0.3*calold ) { - MMG5_SAFE_FREE(callist); return 0; } @@ -475,7 +461,6 @@ int MMG5_movbdyregpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctre (&mesh->tetra[listv[l]/4])->qual= callist[l]; (&mesh->tetra[listv[l]/4])->mark= mesh->mark; } - MMG5_SAFE_FREE(callist); return 1; } @@ -508,7 +493,7 @@ int MMG3D_movbdycurvept_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROc MMG5_pxPoint pxp; double step,ll1old,ll2old,l1new,l2new; double o[3],no[3],no2[3],to[3], ncur[3],nprev[3],nneighi[3]; - double calold,calnew,caltmp,*callist; + double calold,calnew,caltmp,callist[MMG3D_LMAX+2]; int l,iel,ip0,ipa,ipb,iptmpa,iptmpb,ip1,ip2,ip,nxp; int16_t tag,ier; uint8_t i,i0,ie,iface,iea,ieb,isrid; @@ -821,9 +806,6 @@ int MMG3D_movbdycurvept_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROc memset(pxp,0,sizeof(MMG5_xPoint)); /* Test : check whether all volumes remain positive with new position of the point */ - // Dynamic allocations for windows compatibility - MMG5_SAFE_MALLOC(callist, ilistv, double,return 0); - calold = calnew = DBL_MAX; for( l=0 ; lqual); callist[l] = MMG5_orcal(mesh,met,0); if (callist[l] < MMG5_NULKAL) { - MMG5_SAFE_FREE(callist); return 0; } calnew = MG_MIN(calnew,callist[l]); } if ((calold < MMG5_EPSOK && calnew <= calold) || (calnew < MMG5_EPSOK) || (calnew <= 0.3*calold)) { - MMG5_SAFE_FREE(callist); return 0; } else if (improve && calnew < calold) { - MMG5_SAFE_FREE(callist); return 0; } @@ -879,7 +858,6 @@ int MMG3D_movbdycurvept_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROc (&mesh->tetra[listv[l]/4])->qual = callist[l]; (&mesh->tetra[listv[l]/4])->mark = mesh->mark; } - MMG5_SAFE_FREE(callist); return 1; } From c3c673a7581b8e18a18cd99f7f7518475e692dd5 Mon Sep 17 00:00:00 2001 From: Algiane Date: Thu, 22 Jul 2021 09:52:28 +0200 Subject: [PATCH 142/170] Remove code smells. --- src/mmg3d/anisomovpt_3d.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/mmg3d/anisomovpt_3d.c b/src/mmg3d/anisomovpt_3d.c index 3afa2089f..a8578c6b8 100644 --- a/src/mmg3d/anisomovpt_3d.c +++ b/src/mmg3d/anisomovpt_3d.c @@ -759,13 +759,17 @@ int MMG3D_movbdycurvept_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROc iface = lists[l] % 4; MMG5_tet2tri(mesh,iel,iface,&tt); - calold = MG_MIN(calold,MMG5_caltri(mesh,met,&tt)); + caltmp = MMG5_caltri(mesh,met,&tt); + calold = MG_MIN(calold,caltmp); - for( i=0 ; i<3 ; i++ ) - if ( tt.v[i] == ip0 ) break; + for( i=0 ; i<3 ; i++ ) { + if ( tt.v[i] == ip0 ) { + break; + } + } + assert(i<3); + if ( i==3 ) return 0; - assert ( i<3 ); - if ( i>=3 ) return 0; tt.v[i] = 0; caltmp = MMG5_caltri(mesh,met,&tt); From f16f0a77496ef30c7fad7814237e28c0a3ffbdc0 Mon Sep 17 00:00:00 2001 From: Algiane Date: Thu, 22 Jul 2021 14:03:25 +0200 Subject: [PATCH 143/170] Move ll*old computation to make more clear that it is use only by the MMGS_moveTowardPoint function. --- src/mmgs/anisomovpt_s.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mmgs/anisomovpt_s.c b/src/mmgs/anisomovpt_s.c index 14818a49e..dde58d3e1 100644 --- a/src/mmgs/anisomovpt_s.c +++ b/src/mmgs/anisomovpt_s.c @@ -340,9 +340,6 @@ int movridpt_ani(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist) { if ( (!l1old) || (!l2old) ) return 0; - ll1old = l1old*l1old; - ll2old = l2old*l2old; - /* Third step : infer arc length of displacement, parameterized over edges */ if ( !MMGS_paramDisp ( mesh,it1,it2,l1old,l2old,isrid1,isrid2, ip0,ip1,ip2,step,o,&isrid ) ) { @@ -356,6 +353,9 @@ int movridpt_ani(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist) { lam2 = step*step; /* Move is made towards p2 */ + ll1old = l1old*l1old; + ll2old = l2old*l2old; + if ( l2old > l1old ) { if ( !MMGS_moveTowardPoint(mesh,p0,p2,ll2old,lam0,lam1,lam2,nn1,nn2,to) ) { return 0; From 3819ace4cc1abbfe4915e9a31bc621145a2556f3 Mon Sep 17 00:00:00 2001 From: Algiane Date: Thu, 22 Jul 2021 14:21:32 +0200 Subject: [PATCH 144/170] Remove duplication in paramDisp function of mmgs. --- src/mmgs/anisomovpt_s.c | 16 ++++- src/mmgs/mmgs.h | 5 +- src/mmgs/movpt_s.c | 140 ++++++++++++++-------------------------- 3 files changed, 64 insertions(+), 97 deletions(-) diff --git a/src/mmgs/anisomovpt_s.c b/src/mmgs/anisomovpt_s.c index dde58d3e1..cdd3a90a8 100644 --- a/src/mmgs/anisomovpt_s.c +++ b/src/mmgs/anisomovpt_s.c @@ -255,7 +255,7 @@ int movridpt_ani(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist) { double *m0,*m00,step,l1old,l2old,ll1old,ll2old; double lam0,lam1,lam2,o[3],nn1[3],nn2[3],to[3],mo[6]; double l1new,l2new,calold,calnew; - int it1,it2,ip0,ip1,ip2,k,iel; + int it,it1,it2,ip,ip0,ip1,ip2,k,iel; int8_t voy1,voy2,isrid,isrid1,isrid2,i0,i1,i2; static int8_t mmgWarn0 = 0; @@ -340,9 +340,19 @@ int movridpt_ani(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist) { if ( (!l1old) || (!l2old) ) return 0; + if ( l1old < l2old ) { //move towards p2 + ip = ip2; + isrid = isrid2; + it = it2; + } + else { + ip = ip1; + isrid = isrid1; + it = it1; + } + /* Third step : infer arc length of displacement, parameterized over edges */ - if ( !MMGS_paramDisp ( mesh,it1,it2,l1old,l2old,isrid1,isrid2, - ip0,ip1,ip2,step,o,&isrid ) ) { + if ( !MMGS_paramDisp ( mesh,it,isrid,ip0,ip,step,o) ) { return 0; } diff --git a/src/mmgs/mmgs.h b/src/mmgs/mmgs.h index 91f04f2ab..8977c0f7e 100644 --- a/src/mmgs/mmgs.h +++ b/src/mmgs/mmgs.h @@ -199,10 +199,7 @@ int MMGS_gradsizreq_ani(MMG5_pMesh mesh,MMG5_pSol met); int intmet_iso(MMG5_pMesh mesh,MMG5_pSol met,int k,int8_t i,int ip,double s); int intmet_ani(MMG5_pMesh mesh,MMG5_pSol met,int k,int8_t i,int ip,double s); int MMGS_intmet33_ani(MMG5_pMesh,MMG5_pSol,int,int8_t,int,double); -int MMGS_paramDisp(MMG5_pMesh mesh,int it1,int it2, - double l1old,double l2old, - int8_t isrid1, int8_t isrid2,int ip0,int ip1,int ip2, - double step,double o[3],int8_t *isrid); +int MMGS_paramDisp(MMG5_pMesh,int,int8_t,int,int,double,double[3]); int MMGS_moveTowardPoint(MMG5_pMesh mesh,MMG5_pPoint p0,MMG5_pPoint p, double llold,double lam0,double lam1,double lam2, double nn1[3],double nn2[3],double to[3]); diff --git a/src/mmgs/movpt_s.c b/src/mmgs/movpt_s.c index c5e797a78..cf38c4e1a 100644 --- a/src/mmgs/movpt_s.c +++ b/src/mmgs/movpt_s.c @@ -357,18 +357,12 @@ int movintpt_iso(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist) { /** * \param mesh pointer toward the mesh - * \param it1 triangle to which belongs the first edge - * \param it2 triangle to which belongs the second edge - * \param l1old length of the first edge - * \param l2old length of the second edge - * \param isrid1 1 if the first edge is a ridge - * \param isrid2 1 if the second edge is a ridge + * \param it triangle to which belongs the edge along which we move + * \param isrid 1 if the edge is a ridge * \param ip0 edge point that we want to move - * \param ip1 edge point connected by the ref/ridge edge to \a p0 - * \param ip2 edge point connected by the ref/ridge edge to \a p0 + * \param ip edge point connected by the ref/ridge edge to \a p0 * \param step displacement factor along the ref/ridge edge * \param o coordinates of point after relocation - * \param isrid 1 if point is moved toward a ridge. * * \return 1 if success, 0 otherwise. * @@ -376,99 +370,52 @@ int movintpt_iso(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist) { * edges. * */ -int MMGS_paramDisp(MMG5_pMesh mesh,int it1,int it2, - double l1old,double l2old, - int8_t isrid1, int8_t isrid2,int ip0,int ip1,int ip2, - double step,double o[3],int8_t *isrid) { +int MMGS_paramDisp(MMG5_pMesh mesh,int it,int8_t isrid,int ip0,int ip, + double step,double o[3]) { MMG5_pTria pt; MMG5_Bezier b; double uv[2],nn1[3],to[3]; int ier; - /* move towards p2 */ - if ( l2old > l1old ) { - *isrid = isrid2; - pt = &mesh->tria[it2]; + /* move towards ip */ + pt = &mesh->tria[it]; - ier = MMG5_bezierCP(mesh,pt,&b,1); - assert(ier); + ier = MMG5_bezierCP(mesh,pt,&b,1); + assert(ier); - /* fill table uv */ - if ( pt->v[0] == ip0 ) { - if ( pt->v[1] == ip2 ) { - uv[0] = step; - uv[1] = 0.0; - } - else if ( pt->v[2] == ip2 ) { - uv[0] = 0.0; - uv[1] = step; - } + /* fill table uv */ + if ( pt->v[0] == ip0 ) { + if ( pt->v[1] == ip ) { + uv[0] = step; + uv[1] = 0.0; } - else if ( pt->v[0] == ip2 ) { - if ( pt->v[1] == ip0 ) { - uv[0] = 1.0 - step; - uv[1] = 0.0; - } - else if ( pt->v[2] == ip0 ) { - uv[0] = 0.0; - uv[1] = 1.0-step; - } + else if ( pt->v[2] == ip ) { + uv[0] = 0.0; + uv[1] = step; } - else { - if ( pt->v[1] == ip0 ) { - uv[0] = 1.0 - step; - uv[1] = step; - } - else if ( pt->v[2] == ip0 ) { - uv[0] = step; - uv[1] = 1.0-step; - } + } + else if ( pt->v[0] == ip ) { + if ( pt->v[1] == ip0 ) { + uv[0] = 1.0 - step; + uv[1] = 0.0; + } + else if ( pt->v[2] == ip0 ) { + uv[0] = 0.0; + uv[1] = 1.0-step; } - ier = MMGS_bezierInt(&b,uv,o,nn1,to); - assert(ier); } - /* move towards p1 */ else { - *isrid = isrid1; - pt = &mesh->tria[it1]; - - ier = MMG5_bezierCP(mesh,pt,&b,1); - assert(ier); - - /* fill table uv */ - if ( pt->v[0] == ip0 ) { - if ( pt->v[1] == ip1 ) { - uv[0] = step; - uv[1] = 0.0; - } - else if ( pt->v[2] == ip1 ) { - uv[0] = 0.0; - uv[1] = step; - } - } - else if ( pt->v[0] == ip1 ) { - if ( pt->v[1] == ip0 ) { - uv[0] = 1.0 - step; - uv[1] = 0.0; - } - else if ( pt->v[2] == ip0 ) { - uv[0] = 0.0; - uv[1] = 1.0-step; - } + if ( pt->v[1] == ip0 ) { + uv[0] = 1.0 - step; + uv[1] = step; } - else { - if ( pt->v[1] == ip0 ) { - uv[0] = 1.0-step; - uv[1] = step; - } - else if ( pt->v[2] == ip0 ) { - uv[0] = step; - uv[1] = 1.0-step; - } + else if ( pt->v[2] == ip0 ) { + uv[0] = step; + uv[1] = 1.0-step; } - ier = MMGS_bezierInt(&b,uv,o,nn1,to); - assert(ier); } + ier = MMGS_bezierInt(&b,uv,o,nn1,to); + assert(ier); return ier; } @@ -649,7 +596,7 @@ int movridpt_iso(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist) { MMG5_pPoint p0,p1,p2,ppt0; double step,ll1old,ll1new,ll2old,ll2new,o[3]; double nn1[3],nn2[3],to[3],calold,calnew,lam0,lam1,lam2; - int k,iel,ip0,ip1,ip2,it1,it2; + int k,iel,ip,ip0,ip1,ip2,it,it1,it2; int8_t i0,i1,i2,isrid1,isrid2,isrid; step = 0.1; @@ -719,9 +666,22 @@ int movridpt_iso(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist) { + (p2->c[1]-p0->c[1])*(p2->c[1]-p0->c[1]) + (p2->c[2]-p0->c[2])*(p2->c[2]-p0->c[2]); + if ( (!ll1old) || (!ll2old) ) return 0; + + if ( ll1old < ll2old ) { //move towards p2 + ip = ip2; + isrid = isrid2; + it = it2; + } + else { + ip = ip1; + isrid = isrid1; + it = it1; + } + + /* Third step : infer arc length of displacement, parameterized over edges */ - if ( !MMGS_paramDisp ( mesh,it1,it2,ll1old,ll2old,isrid1,isrid2, - ip0,ip1,ip2,step,o,&isrid ) ) { + if ( !MMGS_paramDisp ( mesh,it,isrid,ip0,ip,step,o) ) { return 0; } From ddd2d95fefafacc81b516c1451ac92b81dbd10cf Mon Sep 17 00:00:00 2001 From: Algiane Date: Thu, 22 Jul 2021 14:48:51 +0200 Subject: [PATCH 145/170] Remove sonarqube bugs. --- src/mmg3d/colver_3d.c | 5 +---- src/mmg3d/movpt_3d.c | 1 - 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/mmg3d/colver_3d.c b/src/mmg3d/colver_3d.c index 971c1bbea..e64349c21 100644 --- a/src/mmg3d/colver_3d.c +++ b/src/mmg3d/colver_3d.c @@ -1108,16 +1108,13 @@ int MMG5_colver(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ilist,int8_t indq,in } } - /* avoid recreating existing elt and update the tags of the edge ip-p0_c and - * ip-p1_c */ + /* Avoid recreating existing elt */ for (k=0; ktetra[iel]; adja = &mesh->adja[4*(iel-1)+1]; jel = adja[ip]; diff --git a/src/mmg3d/movpt_3d.c b/src/mmg3d/movpt_3d.c index e60c5e791..d7ee4b1f6 100755 --- a/src/mmg3d/movpt_3d.c +++ b/src/mmg3d/movpt_3d.c @@ -588,7 +588,6 @@ int MMG3D_movbdyregpt_geom(MMG5_pMesh mesh,int *lists,const int kel, MMG5_TAB_RECALLOC(mesh,mesh->xpoint,mesh->xpmax,MMG5_GAP,MMG5_xPoint, "larger xpoint table", return 0); - n = &(mesh->xpoint[p0->xp].n1[0]); } ppt0->xp = nxp; pxp = &mesh->xpoint[nxp]; From 1c9f46d7b7847eac19845baff724d188c4511653 Mon Sep 17 00:00:00 2001 From: luca Date: Sat, 31 Jul 2021 01:49:31 +0200 Subject: [PATCH 146/170] Skip old parallel faces when looking for a triangle to give a second normal vector to a new ridge point. --- src/mmg3d/mmg3d1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mmg3d/mmg3d1.c b/src/mmg3d/mmg3d1.c index 0f9725855..0bd97eb9b 100644 --- a/src/mmg3d/mmg3d1.c +++ b/src/mmg3d/mmg3d1.c @@ -2027,7 +2027,7 @@ MMG3D_anatets_iso(MMG5_pMesh mesh,MMG5_pSol met,int8_t typchk) { for (i=0; i<4; i++) { /* virtual triangle */ memset(&ptt,0,sizeof(MMG5_Tria)); - if ( pt->xt && pxt->ftag[i] ) { + if ( pt->xt && pxt->ftag[i] && pxt->ftag[i] != MG_OLDPARBDY ) { MMG5_tet2tri(mesh,k,i,&ptt); } From a21124daf80c4fcf2496df6372148f63b9e0aeed Mon Sep 17 00:00:00 2001 From: luca Date: Sat, 7 Aug 2021 01:40:53 +0200 Subject: [PATCH 147/170] Skip parallel points when computing geometric support for non-manifold edges. --- src/mmg3d/analys_3d.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mmg3d/analys_3d.c b/src/mmg3d/analys_3d.c index 4daee5450..cbdb1efe8 100644 --- a/src/mmg3d/analys_3d.c +++ b/src/mmg3d/analys_3d.c @@ -691,7 +691,7 @@ int MMG3D_nmgeom(MMG5_pMesh mesh){ ip = MMG5_idir[i][j]; p0 = &mesh->point[pt->v[ip]]; if ( p0->flag == base ) continue; - else if ( !(p0->tag & MG_NOM) ) continue; + else if ( !(p0->tag & MG_NOM) || (p0->tag & MG_PARBDY) ) continue; p0->flag = base; ier = MMG5_boulenm(mesh,k,ip,i,n,t); @@ -728,7 +728,8 @@ int MMG3D_nmgeom(MMG5_pMesh mesh){ for (i=0; i<4; i++) { p0 = &mesh->point[pt->v[i]]; - if ( p0->tag & MG_REQ || !(p0->tag & MG_NOM) || p0->xp ) continue; + if ( p0->tag & MG_REQ || !(p0->tag & MG_NOM) || + p0->xp || (p0->tag & MG_PARBDY) ) continue; ier = MMG5_boulenmInt(mesh,k,i,t); if ( ier ) { ++mesh->xp; From 320e8e62e87cbba49598ba891f9324ae022dd0bb Mon Sep 17 00:00:00 2001 From: luca Date: Thu, 12 Aug 2021 19:58:57 +0200 Subject: [PATCH 148/170] Skip parallel edges in MMG5_setEdgeNmTag. --- src/mmg3d/hash_3d.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mmg3d/hash_3d.c b/src/mmg3d/hash_3d.c index 17d9fb278..b8c5cffeb 100644 --- a/src/mmg3d/hash_3d.c +++ b/src/mmg3d/hash_3d.c @@ -537,8 +537,8 @@ int MMG5_setEdgeNmTag(MMG5_pMesh mesh, MMG5_Hash *hash) { for (l=0; l<3; l++) { - /* Skip edges at the intersection of a parallel interface */ - if ( ptt->tag[l] & MG_BDY ) continue; + /* Skip parallel edges */ + if ( ptt->tag[l] & MG_PARBDY ) continue; if ( ptt->tag[l] & MG_NOM ) { i1 = MMG5_inxt2[l]; From 532a1e17cf28e30771ef5aff3e4eb5e40e1b7d3e Mon Sep 17 00:00:00 2001 From: luca Date: Thu, 12 Aug 2021 20:09:45 +0200 Subject: [PATCH 149/170] Skip parallel edges also on non-parallel triangles. --- src/mmg3d/hash_3d.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mmg3d/hash_3d.c b/src/mmg3d/hash_3d.c index b8c5cffeb..b663f911d 100644 --- a/src/mmg3d/hash_3d.c +++ b/src/mmg3d/hash_3d.c @@ -538,7 +538,7 @@ int MMG5_setEdgeNmTag(MMG5_pMesh mesh, MMG5_Hash *hash) { for (l=0; l<3; l++) { /* Skip parallel edges */ - if ( ptt->tag[l] & MG_PARBDY ) continue; + if ( (ptt->tag[l] & MG_PARBDY) || (ptt->tag[l] & MG_BDY) ) continue; if ( ptt->tag[l] & MG_NOM ) { i1 = MMG5_inxt2[l]; From 25252c99855ee5dd839a92dfd39d6c718b53207c Mon Sep 17 00:00:00 2001 From: Algiane Date: Mon, 16 Aug 2021 16:56:49 +0200 Subject: [PATCH 150/170] Avoid the insertion of a non mergeable vertex during swaps. --- src/mmg3d/swap_3d.c | 30 +++++++++++++++++++++++++++++- src/mmg3d/swapgen_3d.c | 31 ++++++++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/src/mmg3d/swap_3d.c b/src/mmg3d/swap_3d.c index 1f0c906ae..a4dcdaf3e 100644 --- a/src/mmg3d/swap_3d.c +++ b/src/mmg3d/swap_3d.c @@ -379,6 +379,18 @@ int MMG5_chkswpbdy(MMG5_pMesh mesh, MMG5_pSol met, int *list,int ilist, if ( caltmp < MMG5_NULKAL ) return 0; if ( !isshell ) { + /* Test that we don't recreate an existing elt */ + int adj = mesh->adja[4*(iel-1)+1+ip]; + if ( adj ) { + int8_t voy = adj%4; + adj /= 4; + + if ( mesh->tetra[adj].v[voy] == na1 ) { + return 0; + } + } + + /* Test future quality */ pt0->v[ip] = na1; if ( typchk==1 && met->size > 1 && met->m ) @@ -399,6 +411,18 @@ int MMG5_chkswpbdy(MMG5_pMesh mesh, MMG5_pSol met, int *list,int ilist, if ( caltmp < MMG5_NULKAL ) return 0; if ( !isshell ) { + /* Test that we don't recreate an existing elt */ + int adj = mesh->adja[4*(iel-1)+1+iq]; + if ( adj ) { + int8_t voy = adj%4; + adj /= 4; + + if ( mesh->tetra[adj].v[voy] == na1 ) { + return 0; + } + } + + /* Test future quality */ pt0->v[iq] = na1; if ( typchk==1 && met->size > 1 && met->m ) @@ -409,7 +433,8 @@ int MMG5_chkswpbdy(MMG5_pMesh mesh, MMG5_pSol met, int *list,int ilist, calnew = MG_MIN(calnew,caltmp); } } - if ( calold < MMG5_EPSOK && calnew <= calold ) return 0; + if ( calold < MMG5_EPSOK && calnew <= calold ) return 0; + else if ( calnew < 0.3 * calold ) return 0; return 1; @@ -542,6 +567,9 @@ int MMG5_swpbdy(MMG5_pMesh mesh,MMG5_pSol met,int *list,int ret,int it1, ier = 1; } + /* Check for non convex situation */ + assert ( ier && "Unable to collapse the point created during the boundary swap"); + return ier; } diff --git a/src/mmg3d/swapgen_3d.c b/src/mmg3d/swapgen_3d.c index 75ef0a210..0678db26e 100755 --- a/src/mmg3d/swapgen_3d.c +++ b/src/mmg3d/swapgen_3d.c @@ -146,13 +146,17 @@ int MMG5_chkswpgen(MMG5_pMesh mesh,MMG5_pSol met,int start,int ia, ier = 1; if ( mesh->info.fem ) { + /* Do not create internal edges between boundary points */ p0 = &mesh->point[np]; if ( p0->tag & MG_BDY ) { + /* One of the vertices of the pseudo polygon is boundary */ for (l=0; ltetra[iel]; p0 = &mesh->point[pt->v[ip]]; if ( p0->tag & MG_BDY ) { + /* Another vertex is boundary */ ier = 0; break; } @@ -172,15 +177,33 @@ int MMG5_chkswpgen(MMG5_pMesh mesh,MMG5_pSol met,int start,int ia, for (l=0; l<(*ilist); l++) { /* Do not consider tets of the shell of collapsed edge */ if ( k < npol-1 ) { + /* Skip the two elts of the pseudo polygon that contains np */ if ( l == k || l == k+1 ) continue; } else { + /* Skip the two elts of the pseudo polygon that contains np for the last polygon elt */ if ( l == npol-1 || l == 0 ) continue; } iel = list[l] / 6; i = list[l] % 6; pt = &mesh->tetra[iel]; + /* Check that we will not insert a node that we will fail to collapse + * (recreation of an existing element) */ + adja = &mesh->adja[4*(iel-1)+1]; + adj = adja[MMG5_iare[i][0]]/4; + piv = adja[MMG5_iare[i][0]]%4; + if ( adj && mesh->tetra[adj].v[piv]==np ) { + ier = 0; + break; + } + adj = adja[MMG5_iare[i][1]]/4; + piv = adja[MMG5_iare[i][1]]%4; + if ( adj && mesh->tetra[adj].v[piv]==np ) { + ier = 0; + break; + } + /* Prevent from creating a tetra with 4 bdy vertices */ if ( mesh->point[np].tag & MG_BDY ) { if ( ( mesh->point[pt->v[MMG5_ifar[i][0]]].tag & MG_BDY ) && @@ -323,7 +346,13 @@ int MMG5_swpgen(MMG5_pMesh mesh,MMG5_pSol met,int nconf,int ilist,int *list, __func__); return -1; } - else if ( ier ) MMG3D_delPt(mesh,ier); + else if ( ier ) { + MMG3D_delPt(mesh,ier); + } + + /* Check for non convex situation */ + assert ( ier && "Unable to collapse the point created during the internal swap"); + return 1; } From 1775813580b8ebe7bf957c419af4832af6a12c29 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 17 Aug 2021 12:09:17 +0200 Subject: [PATCH 151/170] Comment --- src/mmg3d/mmg3d1_pattern.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mmg3d/mmg3d1_pattern.c b/src/mmg3d/mmg3d1_pattern.c index 29544ad0c..97951efdf 100644 --- a/src/mmg3d/mmg3d1_pattern.c +++ b/src/mmg3d/mmg3d1_pattern.c @@ -455,7 +455,7 @@ int MMG5_mmg3d1_pattern(MMG5_pMesh mesh,MMG5_pSol met,int *permNodGlob) { if ( abs(mesh->info.imprim) > 4 ) fprintf(stdout," ** MESH ANALYSIS\n"); - + if ( mesh->info.iso && !MMG5_chkmani(mesh) ) { fprintf(stderr,"\n ## Non orientable implicit surface. Exit program.\n"); return 0; @@ -496,7 +496,7 @@ int MMG5_mmg3d1_pattern(MMG5_pMesh mesh,MMG5_pSol met,int *permNodGlob) { MMG3D_gradsizreq(mesh,met); } - /*update quality*/ + /* update quality*/ if ( !MMG3D_tetraQual(mesh,met,1) ) return 0; if ( !MMG5_anatet(mesh,met,2,1) ) { From b7c315ca5b6f8ddedda1d8fa31192551792e8a46 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 17 Aug 2021 12:10:49 +0200 Subject: [PATCH 152/170] Check non NaN value for the tetra quality in swap_3d and early failure for chkwap when a null wuality is foud. --- src/mmg3d/swap_3d.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mmg3d/swap_3d.c b/src/mmg3d/swap_3d.c index a4dcdaf3e..2f4f496f3 100644 --- a/src/mmg3d/swap_3d.c +++ b/src/mmg3d/swap_3d.c @@ -356,6 +356,7 @@ int MMG5_chkswpbdy(MMG5_pMesh mesh, MMG5_pSol met, int *list,int ilist, pt = &mesh->tetra[iel]; memcpy(pt0,pt,sizeof(MMG5_Tetra)); calold = MG_MIN(calold, pt->qual); + assert ( isfinite(calold) ); ia1 = ia2 = ip = iq = -1; for (j=0; j< 4; j++) { @@ -430,6 +431,8 @@ int MMG5_chkswpbdy(MMG5_pMesh mesh, MMG5_pSol met, int *list,int ilist, else caltmp = MMG5_orcal(mesh,met,0); + if ( caltmp < MMG5_NULKAL ) return 0; + calnew = MG_MIN(calnew,caltmp); } } From 9ac452223119595f22840f51976b832b48012c34 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 17 Aug 2021 12:11:41 +0200 Subject: [PATCH 153/170] Suitable computation of the quality in -ls -A mode. --- src/mmg3d/mmg3d2.c | 8 ++++---- src/mmg3d/split_3d.c | 29 +++++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/mmg3d/mmg3d2.c b/src/mmg3d/mmg3d2.c index 8cc5dd851..a639b025f 100755 --- a/src/mmg3d/mmg3d2.c +++ b/src/mmg3d/mmg3d2.c @@ -1201,23 +1201,23 @@ static int MMG3D_cuttet_ls(MMG5_pMesh mesh, MMG5_pSol sol,MMG5_pSol met){ } switch (pt->flag) { case 1: case 2: case 4: case 8: case 16: case 32: /* 1 edge split */ - ier = MMG5_split1(mesh,sol,k,vx,1); + ier = MMG5_split1(mesh,met,k,vx,1); ns++; break; case 48: case 24: case 40: case 6: case 34: case 36: case 20: case 5: case 17: case 9: case 3: case 10: /* 2 edges (same face) split */ - ier = MMG5_split2sf(mesh,sol,k,vx,1); + ier = MMG5_split2sf(mesh,met,k,vx,1); ns++; break; case 7: case 25: case 42: case 52: /* 3 edges on conic configuration splitted */ - ier = MMG5_split3cone(mesh,sol,k,vx,1); + ier = MMG5_split3cone(mesh,met,k,vx,1); ns++; break; case 30: case 45: case 51: - ier = MMG5_split4op(mesh,sol,k,vx,1); + ier = MMG5_split4op(mesh,met,k,vx,1); ns++; break; diff --git a/src/mmg3d/split_3d.c b/src/mmg3d/split_3d.c index c1de97248..7dcd6feae 100755 --- a/src/mmg3d/split_3d.c +++ b/src/mmg3d/split_3d.c @@ -237,8 +237,12 @@ int MMG5_split1(MMG5_pMesh mesh,MMG5_pSol met,int k,int vx[6],int8_t metRidTyp) pt->qual=MMG5_caltet33_ani(mesh,met,pt); pt1->qual=MMG5_caltet33_ani(mesh,met,pt1); } - else - { + else if ( (!met) || (!met->m) ) { + /* in ls mode + -A option, orcal calls caltet_ani that fails */ + pt->qual=MMG5_caltet_iso(mesh,met,pt); + pt1->qual=MMG5_caltet_iso(mesh,met,pt1); + } + else { pt->qual=MMG5_orcal(mesh,met,k); pt1->qual=MMG5_orcal(mesh,met,iel); } @@ -1434,8 +1438,13 @@ int MMG5_split2sf(MMG5_pMesh mesh,MMG5_pSol met,int k,int vx[6],int8_t metRidTyp pt[1]->qual=MMG5_caltet33_ani(mesh,met,pt[1]); pt[2]->qual=MMG5_caltet33_ani(mesh,met,pt[2]); } - else - { + else if ( (!met) || (!met->m) ) { + /* in ls mode + -A option, orcal calls caltet_ani that fails */ + pt[0]->qual=MMG5_caltet_iso(mesh,met,pt[0]); + pt[1]->qual=MMG5_caltet_iso(mesh,met,pt[1]); + pt[2]->qual=MMG5_caltet_iso(mesh,met,pt[2]); + } + else { pt[0]->qual=MMG5_orcal(mesh,met,newtet[0]); pt[1]->qual=MMG5_orcal(mesh,met,newtet[1]); pt[2]->qual=MMG5_orcal(mesh,met,newtet[2]); @@ -2527,6 +2536,12 @@ int MMG5_split3cone(MMG5_pMesh mesh,MMG5_pSol met,int k,int vx[6],int8_t metRidT pt[2]->qual=MMG5_caltet33_ani(mesh,met,pt[2]); pt[3]->qual=MMG5_caltet33_ani(mesh,met,pt[3]); } + else if ( (!met) || (!met->m) ) { + /* in ls mode + -A option, orcal calls caltet_ani that fails */ + for (i=0; i<4; i++) { + pt[i]->qual=MMG5_caltet_iso(mesh,met,pt[i]); + } + } else { pt[0]->qual=MMG5_orcal(mesh,met,newtet[0]); pt[1]->qual=MMG5_orcal(mesh,met,newtet[1]); @@ -4364,6 +4379,12 @@ int MMG5_split4op(MMG5_pMesh mesh,MMG5_pSol met,int k,int vx[6],int8_t metRidTyp pt[i]->qual=MMG5_caltet33_ani(mesh,met,pt[i]); } } + else if ( (!met) || (!met->m) ) { + /* in ls mode + -A option, orcal calls caltet_ani that fails */ + for (i=0; i<6; i++) { + pt[i]->qual=MMG5_caltet_iso(mesh,met,pt[i]); + } + } else { for (i=0; i<6; i++) { pt[i]->qual=MMG5_orcal(mesh,met,newtet[i]); From b56a3e9515042adbf6b07f27a5bde9c01e77284e Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 17 Aug 2021 12:15:32 +0200 Subject: [PATCH 154/170] Even if useless, call splitting functions with metric and not ls in mmg2d and mmgs (to be consistent with mmg3d). --- src/mmg2d/mmg2d6.c | 4 ++-- src/mmgs/mmgs2.c | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/mmg2d/mmg2d6.c b/src/mmg2d/mmg2d6.c index f044bd410..6ef0dee38 100644 --- a/src/mmg2d/mmg2d6.c +++ b/src/mmg2d/mmg2d6.c @@ -911,13 +911,13 @@ int MMG2D_cuttri_ls(MMG5_pMesh mesh, MMG5_pSol sol, MMG5_pSol met){ switch( pt->flag ) { /* 1 edge split -> 0-+ */ case 1: case 2: case 4: - ier = MMG2D_split1(mesh,sol,k,vx); + ier = MMG2D_split1(mesh,met,k,vx); ns++; break; /* 2 edge split -> +-- or -++ */ case 3: case 5: case 6: - ier = MMG2D_split2(mesh,sol,k,vx); + ier = MMG2D_split2(mesh,met,k,vx); ns++; break; diff --git a/src/mmgs/mmgs2.c b/src/mmgs/mmgs2.c index aab26a434..df33b5223 100644 --- a/src/mmgs/mmgs2.c +++ b/src/mmgs/mmgs2.c @@ -497,27 +497,27 @@ static int MMGS_cuttri_ls(MMG5_pMesh mesh, MMG5_pSol sol,MMG5_pSol met){ } switch (pt->flag) { case 1: /* 1 edge split */ - ier = MMGS_split1(mesh,sol,k,0,vx); + ier = MMGS_split1(mesh,met,k,0,vx); ns++; break; case 2: /* 1 edge split */ - ier = MMGS_split1(mesh,sol,k,1,vx); + ier = MMGS_split1(mesh,met,k,1,vx); ns++; break; case 4: /* 1 edge split */ - ier = MMGS_split1(mesh,sol,k,2,vx); + ier = MMGS_split1(mesh,met,k,2,vx); ns++; break; case 3: case 5: case 6: /* 2 edges split */ - ier = MMGS_split2(mesh,sol,k,vx); + ier = MMGS_split2(mesh,met,k,vx); ns++; break; case 7: /* 3 edges splitted */ - ier =MMGS_split3(mesh,sol,k,vx); + ier =MMGS_split3(mesh,met,k,vx); ns++; break; From 28582da1cb3d9bffc28d17b22eca64756db6a82c Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 24 Aug 2021 16:46:37 +0200 Subject: [PATCH 155/170] Remove segfault when metric is not defined at the end of the library call. --- src/mmg2d/libmmg2d.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mmg2d/libmmg2d.c b/src/mmg2d/libmmg2d.c index f510532f3..669a38a25 100644 --- a/src/mmg2d/libmmg2d.c +++ b/src/mmg2d/libmmg2d.c @@ -347,7 +347,7 @@ int MMG2D_mmg2dlib(MMG5_pMesh mesh,MMG5_pSol met) } /* Print edge length histories */ - if ( abs(mesh->info.imprim) > 4 ) { + if ( (abs(mesh->info.imprim) > 4) && met->m && met->np ) { MMG2D_prilen(mesh,met); } @@ -614,7 +614,7 @@ int MMG2D_mmg2dmesh(MMG5_pMesh mesh,MMG5_pSol met) { } /* Print edge length histories */ - if ( abs(mesh->info.imprim) > 4 ) { + if ( abs(mesh->info.imprim) > 4 && met->m && met->np ) { MMG2D_prilen(mesh,met); } From daaea190d26b0d2bad294ef5a148f640b8b0d174 Mon Sep 17 00:00:00 2001 From: luca Date: Wed, 25 Aug 2021 18:12:16 +0200 Subject: [PATCH 156/170] Add NOM tag on OPNBDY edges with only 1 adjacent. --- src/mmg3d/analys_3d.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mmg3d/analys_3d.c b/src/mmg3d/analys_3d.c index cbdb1efe8..c1904cd33 100644 --- a/src/mmg3d/analys_3d.c +++ b/src/mmg3d/analys_3d.c @@ -147,6 +147,7 @@ int MMG5_setadj(MMG5_pMesh mesh){ tag = MG_GEO; if ( mesh->info.opnbdy ) tag += MG_OPNBDY; if ( !adja[i] ) { + tag += MG_NOM; pt->tag[i] |= tag; mesh->point[ip1].tag |= tag; mesh->point[ip2].tag |= tag; From 6db8b75896c4cc23d814fb5968fd3ee1a1beca4f Mon Sep 17 00:00:00 2001 From: luca Date: Wed, 15 Sep 2021 15:54:09 +0200 Subject: [PATCH 157/170] Pass MG_PARBDYBDY tag from edges to vertices on intersections of MG_BDY and MG_PARBDY. --- src/common/hash.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/common/hash.c b/src/common/hash.c index d0b55caea..d508136c7 100644 --- a/src/common/hash.c +++ b/src/common/hash.c @@ -189,7 +189,7 @@ int MMG5_mmgHashTria(MMG5_pMesh mesh, int *adjt, MMG5_Hash *hash, int chkISO) { * boundary (!MG_PARBDY || (MG_PARBDY && MG_PARBDYBDY) and a parallel one * (MG_PARBDY && !MG_PARBDYBDY); * - add also a MG_PARBDYBDY tag on those edges (as it cannot be inherited - * from any triangle there). + * from any triangle there) and their extremities. */ for (k=1; k<=mesh->nt; k++) { pt = &mesh->tria[k]; @@ -212,12 +212,16 @@ int MMG5_mmgHashTria(MMG5_pMesh mesh, int *adjt, MMG5_Hash *hash, int chkISO) { j = ph->k % 3; pt1 = &mesh->tria[jel]; pt1->tag[j] |= MG_BDY + MG_PARBDYBDY; + mesh->point[ia].tag |= MG_PARBDYBDY; + mesh->point[ib].tag |= MG_PARBDYBDY; /* update adjacent */ lel = adjt[3*(jel-1)+1+j]/3; l = adjt[3*(jel-1)+1+j]%3; if( lel ) { pt2 = &mesh->tria[lel]; pt2->tag[l] |= MG_BDY + MG_PARBDYBDY; + mesh->point[ia].tag |= MG_PARBDYBDY; + mesh->point[ib].tag |= MG_PARBDYBDY; } break; } else if ( !ph->nxt ) { From 53156cbb338986a961c2b36eba2dac26fbb1b68a Mon Sep 17 00:00:00 2001 From: luca Date: Wed, 15 Sep 2021 15:56:01 +0200 Subject: [PATCH 158/170] Skip required faces and parallel points in MMG5_movtet. --- src/mmg3d/mmg3d1.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mmg3d/mmg3d1.c b/src/mmg3d/mmg3d1.c index 350daaa31..b2e7bcbca 100644 --- a/src/mmg3d/mmg3d1.c +++ b/src/mmg3d/mmg3d1.c @@ -713,6 +713,9 @@ int MMG5_movtet(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROctree, else if ( MG_SIN(ppt->tag) ) continue; if( pt->xt && (pxt->ftag[i] & MG_BDY)) { + /* skip required faces */ + if( pxt->ftag[i] & MG_REQ ) continue; + MMG5_tet2tri(mesh,k,i,&tt); caltri = MMG5_caltri(mesh,met,&tt); @@ -728,6 +731,7 @@ int MMG5_movtet(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROctree, if ( ppt->tag & MG_BDY ) { /* Catch a boundary point by an external face, unless point is internal non manifold */ if ( (!pt->xt) || !(MG_BDY & pxt->ftag[i]) ) continue; + else if( ppt->tag & MG_PARBDY ) continue; /* skip parallel points seen by non-required faces */ else if( ppt->tag & MG_NOM ){ if ( ppt->xp && mesh->xpoint[ppt->xp].nnor ) { ilistv = MMG5_boulevolp(mesh,k,i0,listv); From 1957910cd8ebf5df5da4905b56300cc95f15cc01 Mon Sep 17 00:00:00 2001 From: Algiane Date: Fri, 17 Sep 2021 16:13:30 +0200 Subject: [PATCH 159/170] Add the possibility to read a gmsh 2D Medit file and to save it in 'true' 2D Medit format. --- doc/man/mmg2d.1.gz | Bin 2267 -> 2279 bytes src/mmg2d/inout_2d.c | 101 +++++++++++++++++++++++++++++++++---------- src/mmg2d/mmg2d.c | 3 +- 3 files changed, 78 insertions(+), 26 deletions(-) diff --git a/doc/man/mmg2d.1.gz b/doc/man/mmg2d.1.gz index 276a9505a7ebbea3085afe6b94a323ef8e74ae58..beea8e528b0efccc99cae542360ff4a108f0c4b9 100644 GIT binary patch delta 158 zcmV;P0Ac^z5$6#IABzY87otRAu?SQMe@rZc`0Ju?E74<-&Q^ZZmZuDpMrz5#&c~dB4V@HKH9OHSD@fe{Pm9+vV`W(JX=lRjL0C zjCp6cF5p8B#Lv9xt%9rHQNW%-!CzdfB5PFi8V46cygkN?`>6LX!@j*un0<$D42#eI M0cHGg_|g>s0IfMpNdN!< delta 145 zcmV;C0B-;15!(?6ABzY8V9b4Au?SQMe~4F*K9&rC&i_HS=fma0d`kZuj30*Gx3`f% z%7*o<$`qM+gxwLF(62#djj+YIW4kWXpPS{&b~!v%G>ah9RO)}sVgecBjzZ4?-I=$u zRdDq?3Ya!S!CzdfB5PFi8V46cJR-)6`>6LX!@j*um_~dim); - if(mesh->info.renum==2) { + if ( mesh->info.renum >= 2) { if(mesh->dim!=3) { fprintf(stdout,"WRONG USE OF 3dMedit option \n"); return 0; @@ -291,7 +291,7 @@ int MMG2D_loadMesh(MMG5_pMesh mesh,const char *filename) { ppt = &mesh->point[k]; if (mesh->ver < 2) { /*float*/ if (!bin) { - if(mesh->info.renum==2) { + if ( mesh->info.renum >=2 ) { for (i=0 ; i<3 ; i++) { MMG_FSCANF(inm,"%f",&fc); if(i==2) break; @@ -305,7 +305,7 @@ int MMG2D_loadMesh(MMG5_pMesh mesh,const char *filename) { } MMG_FSCANF(inm,"%d",&ppt->ref); } else { - if(mesh->info.renum==2) { + if ( mesh->info.renum >= 2 ) { fprintf(stderr," ## Warning: %s: binary not available with" " -msh option.\n",__func__); return 0; @@ -320,7 +320,7 @@ int MMG2D_loadMesh(MMG5_pMesh mesh,const char *filename) { } } else { if (!bin) { - if(mesh->info.renum==2) { + if ( mesh->info.renum >= 2 ) { MMG_FSCANF(inm,"%lf %lf %lf %d",&ppt->c[0],&ppt->c[1],&dtmp,&ppt->ref); } else { MMG_FSCANF(inm,"%lf %lf %d",&ppt->c[0],&ppt->c[1],&ppt->ref); @@ -820,7 +820,7 @@ int MMG2D_loadSol(MMG5_pMesh mesh,MMG5_pSol sol,const char *filename) { /** Read the file header */ meshDim = 2; - if ( mesh->info.renum == 2 ) { + if ( mesh->info.renum >= 2 ) { /* -msh mode */ meshDim = 3; } @@ -910,7 +910,7 @@ int MMG2D_loadAllSols(MMG5_pMesh mesh,MMG5_pSol *sol, const char *filename) { /** Read the file header */ meshDim = 2; - if ( mesh->info.renum == 2 ) { + if ( mesh->info.renum >= 2 ) { /* -msh mode */ meshDim = 3; } @@ -1011,9 +1011,11 @@ int MMG2D_saveMesh(MMG5_pMesh mesh,const char *filename) { MMG5_pQuad pq; double dblb; int k,ne,np,nc,nreq,nereq,nedreq,nq,nqreq,ref; - int bin, binch, bpos; + int bin, binch, bpos,gmsh; char *ptr,*data,chaine[MMG5_FILESTR_LGTH]; + gmsh = (mesh->info.renum==1||mesh->info.renum==2); + mesh->ver = 2; bin = 0; @@ -1055,7 +1057,7 @@ int MMG2D_saveMesh(MMG5_pMesh mesh,const char *filename) { if ( !bin ) { strcpy(&chaine[0],"MeshVersionFormatted 2\n"); fprintf(inm,"%s",chaine); - if(mesh->info.renum) { + if ( gmsh ) { strcpy(&chaine[0],"\n\nDimension 3\n"); } else { @@ -1073,7 +1075,9 @@ int MMG2D_saveMesh(MMG5_pMesh mesh,const char *filename) { fwrite(&binch,MMG5_SW,1,inm); bpos = 20; //Pos fwrite(&bpos,MMG5_SW,1,inm); - if(mesh->info.renum) binch = 3; //Dimension + if ( gmsh ) { + binch = 3; //Dimension + } else binch = 2; fwrite(&binch,MMG5_SW,1,inm); } @@ -1094,7 +1098,7 @@ int MMG2D_saveMesh(MMG5_pMesh mesh,const char *filename) { else { binch = 4; //Vertices fwrite(&binch,MMG5_SW,1,inm); - if ( mesh->info.renum ) + if ( gmsh ) bpos += (3+(1+3*mesh->ver)*np)*MMG5_SW; //NullPos else bpos += (3+(1+2*mesh->ver)*np)*MMG5_SW; //NullPos @@ -1108,7 +1112,7 @@ int MMG2D_saveMesh(MMG5_pMesh mesh,const char *filename) { ppt = &mesh->point[k]; if ( MG_VOK(ppt) ) { ref = ppt->ref; - if ( mesh->info.renum ) { + if ( gmsh ) { if ( !bin ) fprintf(inm,"%.15lg %.15lg 0 %d\n",ppt->c[0],ppt->c[1],ref); else { @@ -1447,23 +1451,61 @@ int MMG2D_saveMshMesh_and_allData(MMG5_pMesh mesh,MMG5_pSol *sol,const char *fil * \param inm pointer toward the solution file * \param bin 1 if binary file * \param index of the writted solution + * \param gmsh write in 3D (for gmsh) if 1 * * Write the solution value for vertex of index pos in double precision. * */ static inline -void MMG2D_writeDoubleSol(MMG5_pSol sol,FILE *inm,int bin,int pos) { +void MMG2D_writeDoubleSol(MMG5_pSol sol,FILE *inm,int bin,int pos,int gmsh) { int i,isol; isol = pos * sol->size; - if ( !bin ) { - for (i=0; isize; i++) - fprintf(inm," %.15lg",sol->m[isol + i]); + if ( gmsh ) { + if ( !bin ) { + switch ( sol->size ) { + case 1: + fprintf(inm," %.15lg",sol->m[isol]); + break; + case 2: + fprintf(inm," %.15lg %.15lg 0",sol->m[isol],sol->m[isol+1]); + break; + case 3: + fprintf(inm," %.15lg %.15lg %.15lg 0 0 1",sol->m[isol],sol->m[isol+1],sol->m[isol+2]); + break; + } + } + else { + double dbuf = 0.; + + switch ( sol->size ) { + case 1: + fwrite(&sol->m[isol],MMG5_SD,1,inm); + break; + case 2: + fwrite(&sol->m[isol],MMG5_SD,2,inm); + fwrite(&dbuf,MMG5_SD,1,inm); + break; + case 3: + fwrite(&sol->m[isol],MMG5_SD,3,inm); + fwrite(&dbuf,MMG5_SD,1,inm); + fwrite(&dbuf,MMG5_SD,1,inm); + dbuf = 1.; + fwrite(&dbuf,MMG5_SD,1,inm); + break; + } + } } else { - for (i=0; isize; i++) - fwrite(&sol->m[isol + i],MMG5_SD,1,inm); + if ( !bin ) { + for (i=0; isize; i++) + fprintf(inm," %.15lg",sol->m[isol + i]); + } + else { + for (i=0; isize; i++) + fwrite(&sol->m[isol + i],MMG5_SD,1,inm); + } } } @@ -1481,7 +1523,7 @@ int MMG2D_saveSol(MMG5_pMesh mesh,MMG5_pSol sol,const char *filename) { FILE* inm; MMG5_pPoint ppt; int k,ier; - int binch,bin,bpos,dim; + int binch,bin,bpos,dim,gmsh; if ( !sol->np ) return 1; @@ -1491,10 +1533,11 @@ int MMG2D_saveSol(MMG5_pMesh mesh,MMG5_pSol sol,const char *filename) { return 1; } + gmsh = (mesh->info.renum==1||mesh->info.renum==2); sol->ver = 2; - if ( sol->dim==2 && mesh->info.renum ) { + if ( sol->dim==2 && gmsh ) { dim = 3; } else { @@ -1511,7 +1554,7 @@ int MMG2D_saveSol(MMG5_pMesh mesh,MMG5_pSol sol,const char *filename) { ppt = &mesh->point[k]; if ( !MG_VOK(ppt) ) continue; - MMG2D_writeDoubleSol(sol,inm,bin,k); + MMG2D_writeDoubleSol(sol,inm,bin,k,gmsh); fprintf(inm,"\n"); } @@ -1543,7 +1586,7 @@ int MMG2D_saveAllSols(MMG5_pMesh mesh,MMG5_pSol *sol,const char *filename) { MMG5_pSol psl; int j,k,ier; int binch,bin,bpos,npointSols,ncellSols; - int *type,*size,*entities; + int *type,*size,*entities,gmsh,dim; if ( !(*sol)[0].np ) return 1; @@ -1555,6 +1598,16 @@ int MMG2D_saveAllSols(MMG5_pMesh mesh,MMG5_pSol *sol,const char *filename) { npointSols = 0; ncellSols = 0; + + gmsh = (mesh->info.renum==1||mesh->info.renum==2); + + if ( gmsh ) { + dim = 3; + } + else { + dim = 2; + } + for (k=0; knsols; ++k ) { (*sol)[k].ver = 2; @@ -1577,7 +1630,7 @@ int MMG2D_saveAllSols(MMG5_pMesh mesh,MMG5_pSol *sol,const char *filename) { bpos = 0; ier = MMG5_saveSolHeader( mesh,filename,&inm,(*sol)[0].ver,&bin,&bpos,mesh->np, - (*sol)[0].dim,mesh->nsols,entities,type,size); + dim,mesh->nsols,entities,type,size); if ( ier < 1 ) return ier; @@ -1590,7 +1643,7 @@ int MMG2D_saveAllSols(MMG5_pMesh mesh,MMG5_pSol *sol,const char *filename) { psl = *sol + j; if ( (psl->entities==MMG5_Noentity) || (psl->entities==MMG5_Vertex) ) { - MMG2D_writeDoubleSol(psl,inm,bin,k); + MMG2D_writeDoubleSol(psl,inm,bin,k,gmsh); } } fprintf(inm,"\n"); @@ -1606,7 +1659,7 @@ int MMG2D_saveAllSols(MMG5_pMesh mesh,MMG5_pSol *sol,const char *filename) { for ( j=0; jnsols; ++j ) { psl = *sol + j; if ( psl->entities==MMG5_Triangle ) { - MMG2D_writeDoubleSol(psl,inm,bin,k); + MMG2D_writeDoubleSol(psl,inm,bin,k,gmsh); } } fprintf(inm,"\n"); diff --git a/src/mmg2d/mmg2d.c b/src/mmg2d/mmg2d.c index b24ab297a..0a6dccf70 100644 --- a/src/mmg2d/mmg2d.c +++ b/src/mmg2d/mmg2d.c @@ -50,8 +50,7 @@ static int MMG2D_usage(char *name) { MMG5_2d3dUsage(); /* Specific parameters */ - fprintf(stdout,"-3dMedit val read and write to gmsh visu if val = 1 (out) if val=2 (in and out)\n"); - + fprintf(stdout,"-3dMedit val read and write for gmsh visu: output only if val=1, input and output if val=2, input if val=3\n"); fprintf(stdout,"\n"); fprintf(stdout,"-nofem do not force Mmg to create a finite element mesh \n"); From 4985935418127b4d05f952f9308ceff679da5ce3 Mon Sep 17 00:00:00 2001 From: Algiane Date: Fri, 17 Sep 2021 22:15:13 +0200 Subject: [PATCH 160/170] In mmg2d do not check non-manifoldness along classical boundaries, only along MG_ISO ones. --- src/mmg2d/libmmg2d.c | 5 ++++- src/mmg2d/mmg2d6.c | 19 ++++++++++++------- src/mmg3d/mmg3d2.c | 8 ++++---- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/mmg2d/libmmg2d.c b/src/mmg2d/libmmg2d.c index 669a38a25..df83caa49 100644 --- a/src/mmg2d/libmmg2d.c +++ b/src/mmg2d/libmmg2d.c @@ -808,7 +808,10 @@ int MMG2D_mmg2dls(MMG5_pMesh mesh,MMG5_pSol sol,MMG5_pSol umet) /* Discretization of the mesh->info.ls isovalue of sol in the mesh */ if ( !MMG2D_mmg2d6(mesh,sol,umet) ) { if ( mettofree ) { MMG5_SAFE_FREE (met); } - _LIBMMG5_RETURN(mesh,sol,met,MMG5_STRONGFAILURE); + if ( !MMG5_unscaleMesh(mesh,met,sol) ) { + _LIBMMG5_RETURN(mesh,sol,met,MMG5_STRONGFAILURE); + } + MMG2D_RETURN_AND_PACK(mesh,sol,met,MMG5_LOWFAILURE); } chrono(OFF,&(ctim[2])); diff --git a/src/mmg2d/mmg2d6.c b/src/mmg2d/mmg2d6.c index 6ef0dee38..426ae0f2d 100644 --- a/src/mmg2d/mmg2d6.c +++ b/src/mmg2d/mmg2d6.c @@ -473,7 +473,8 @@ int MMG2D_chkmaniball(MMG5_pMesh mesh, int start, int8_t istart) { return 1; } -/* Check whether the resulting two subdomains occupying mesh are manifold */ +/* Check whether the resulting two subdomains coming from isovalue + * discretization are manifold */ int MMG2D_chkmanimesh(MMG5_pMesh mesh) { MMG5_pTria pt,pt1; int *adja,k,cnt,iel; @@ -505,13 +506,12 @@ int MMG2D_chkmanimesh(MMG5_pMesh mesh) { fprintf(stderr,"\n ## Warning: %s: at least 1 triangle with 3 boundary" " edges.\n",__func__); } - /* return 0; */ } } - /* Second check: check whether the configuration is manifold in the ball of each point; - each vertex on the implicit boundary is caught in such a way that i1 inxt[i1] is one edge of the implicit - boundary */ + /* Second check: check whether the configuration is manifold in the ball of + each point; each vertex on the implicit boundary is caught in such a way + that i1 inxt[i1] is one edge of the implicit boundary */ for (k=1; k<=mesh->nt; k++) { pt = &mesh->tria[k]; if ( !MG_EOK(pt) ) continue; @@ -522,10 +522,15 @@ int MMG2D_chkmanimesh(MMG5_pMesh mesh) { if (! iel ) continue; pt1 = &mesh->tria[iel]; - if ( pt->ref == pt1->ref ) continue; + if ( pt->ref == pt1->ref || pt->edg[i]!= MG_ISO ) continue; i1 = MMG5_inxt2[i]; - if ( !MMG2D_chkmaniball(mesh,k,i1) ) return 0; + if ( !MMG2D_chkmaniball(mesh,k,i1) ) { + fprintf(stderr," *** Topological problem\n"); + fprintf(stderr," non manifold curve at point %d %d\n",pt->v[i1], MMG2D_indPt(mesh,pt->v[i1])); + fprintf(stderr," non manifold curve at tria %d (ip %d)\n", MMG2D_indElt(mesh,k),i1); + return 0; + } } } diff --git a/src/mmg3d/mmg3d2.c b/src/mmg3d/mmg3d2.c index a639b025f..d973dbea2 100755 --- a/src/mmg3d/mmg3d2.c +++ b/src/mmg3d/mmg3d2.c @@ -1495,10 +1495,10 @@ int MMG5_chkmaniball(MMG5_pMesh mesh, int start, int8_t ip){ k = list[cur] / 4; pt = &mesh->tetra[k]; if( pt->ref == ref ) { - fprintf(stderr," *** Topological problem:"); - fprintf(stderr," non manifold surface at point %d %d\n",nump, MMG3D_indPt(mesh,nump)); - fprintf(stderr," non manifold surface at tet %d (ip %d)\n", MMG3D_indElt(mesh,start),ip); - fprintf(stderr,"nref (color %d) %d\n",nref,ref); + fprintf(stderr," *** Topological problem\n"); + fprintf(stderr," non manifold surface at point %d %d\n",nump, MMG3D_indPt(mesh,nump)); + fprintf(stderr," non manifold surface at tet %d (ip %d)\n", MMG3D_indElt(mesh,start),ip); + fprintf(stderr," nref (color %d) %d\n",nref,ref); return 0; } } From 5e50aab91248811e4e4427d784c5283fbfe4a8a3 Mon Sep 17 00:00:00 2001 From: Algiane Date: Fri, 17 Sep 2021 22:27:45 +0200 Subject: [PATCH 161/170] Add ci test for non-manifold check in 2d. --- cmake/testing/mmg2d_tests.cmake | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cmake/testing/mmg2d_tests.cmake b/cmake/testing/mmg2d_tests.cmake index 798569bfb..95ddf943c 100644 --- a/cmake/testing/mmg2d_tests.cmake +++ b/cmake/testing/mmg2d_tests.cmake @@ -463,6 +463,12 @@ ADD_TEST(NAME mmg2d_LSMultiMat_val ${MMG2D_CI_TESTS}/LSMultiMat/multi-mat ${CTEST_OUTPUT_DIR}/mmg2d_multi-mat-val.o.meshb ) +#multi-mat + opnbdy + non-manifold check +ADD_TEST(NAME mmg2d_LSMultiMat_nm + COMMAND ${EXECUT_MMG2D} -v 5 -ls 3 -opnbdy -nr + ${MMG2D_CI_TESTS}/LSMultiMat/2d-opn.mesh + ${CTEST_OUTPUT_DIR}/mmg2d_2d-opn.o.meshb + ) ####### -nsd ADD_TEST(NAME mmg2d_LSMultiMat-nsd22 From 3105b04b596ed3701697786eb6e53f0088037027 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 21 Sep 2021 14:26:53 +0200 Subject: [PATCH 162/170] Change the way to count the number of boundary meeted in coquilFaceFirstLoop (the count along a non-manifold edges with an open shell was false leading to spurious required edges). --- src/mmg3d/boulep_3d.c | 28 ++++++++++++++++++++-------- src/mmg3d/hash_3d.c | 23 +++++++++++------------ 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/src/mmg3d/boulep_3d.c b/src/mmg3d/boulep_3d.c index 0dbe6d129..71c3d0dfe 100644 --- a/src/mmg3d/boulep_3d.c +++ b/src/mmg3d/boulep_3d.c @@ -1566,7 +1566,7 @@ int MMG5_srcbdy(MMG5_pMesh mesh,int start,int ia) { void MMG5_coquilFaceErrorMessage(MMG5_pMesh mesh, int k1, int k2) { MMG5_pTetra pt; int kel1, kel2; - static int8_t mmgErr0; + static int8_t mmgErr0 = 0; if ( mmgErr0 ) return; @@ -1625,7 +1625,7 @@ int MMG5_srcbdy(MMG5_pMesh mesh,int start,int ia) { * (to fill). * \param adj pointer toward the adjacent to treat in the shell (to update) * \param hasadja pointer toward 0 if we don't have adja through iface, - * 0 otherwise (to fill) + * 1 otherwise (to fill) * \param nbdy pointer toward the number of boundaries found minus 1 (to update) * \param silent if 1, print error message for more than 2 boundary triangles * in the shell @@ -1706,6 +1706,7 @@ int MMG3D_coquilFaceFirstLoop(MMG5_pMesh mesh,int start,int na,int nb,int8_t ifa if ( !(*it2) ) { *it2 = 4*pradj+iface; + (*nbdy)++; } else { (*nbdy)++; @@ -1713,6 +1714,11 @@ int MMG3D_coquilFaceFirstLoop(MMG5_pMesh mesh,int start,int na,int nb,int8_t ifa } while ( (*adj) && ((*adj) != start) ); + if ( (*adj) != start ) { + /* The starting boundary face has not been counted (open shell) */ + ++(*nbdy); + } + return 1; } @@ -1818,10 +1824,12 @@ int MMG5_coquilface(MMG5_pMesh mesh,int start,int8_t iface,int ia,int *list, return -1; } - if ( !nbdy ) { - MMG5_coquilFaceErrorMessage(mesh, (*it1)/4, (*it2)/4); - return -1; - } else if ( nbdy > 1 ) { + if ( nbdy != 2 ) { + if ( nbdy < 2 ) { + MMG5_coquilFaceErrorMessage(mesh, (*it1)/4, (*it2)/4); + return -1; + } + if ( !silent ) { if ( !mmgWarn0 ) { // Algiane: for a manifold edge 2 cases : @@ -1829,10 +1837,14 @@ int MMG5_coquilface(MMG5_pMesh mesh,int start,int8_t iface,int ia,int *list, // (highly non-manifold) // 2) we have a non-manifold shape immersed in a domain (3 triangles // sharing the edge and a closed shell) - printf(" ## Warning: %s: you have %d boundaries in the shell" - " of a manifold edge.\n",__func__,nbdy+1); + printf(" ## Warning: %s: you have %d boundary triangles in the close shell" + " of a manifold edge.\n",__func__,nbdy); printf(" Problem may occur during remesh process.\n"); mmgWarn0 = 1; + + /* MMG5_coquilface is called only on edges marked as manifold, check this */ + assert ( pt->xt ); + assert ( !(mesh->xtetra[pt->xt].tag[ia] & MG_NOM) ); } } } diff --git a/src/mmg3d/hash_3d.c b/src/mmg3d/hash_3d.c index b663f911d..03c598dfb 100644 --- a/src/mmg3d/hash_3d.c +++ b/src/mmg3d/hash_3d.c @@ -574,11 +574,10 @@ int MMG5_setEdgeNmTag(MMG5_pMesh mesh, MMG5_Hash *hash) { /* Travel throug the shell of the edge until reaching a tetra without adjacent - * or until reaching th starting tetra */ + * or until reaching the starting tetra */ iface = ptt->cc%4; MMG3D_coquilFaceFirstLoop(mesh,start,na,nb,iface,ia,list,&ilist,&it1,&it2, - &piv,&adj,&hasadja,&nbdy,1); - + &piv,&adj,&hasadja,&nbdy,1); /* At this point, the first travel, in one direction, of the shell is complete. Now, analyze why the travel ended. */ @@ -586,12 +585,12 @@ int MMG5_setEdgeNmTag(MMG5_pMesh mesh, MMG5_Hash *hash) { if ( !it2 ) { if ( !mmgWarn0 ) { mmgWarn0 = 1; - fprintf(stderr,"\n ## Warning: %s: at lesat 1 wrong boundary tag:" - " Only 1 boundary face found in the shell of the edge\n", + fprintf(stderr,"\n ## Warning: %s: at least 1 wrong boundary tag:" + " Only 0 or 1 boundary triangles founded in the shell of the edge\n", __func__); } } - if ( !nbdy ) + if ( nbdy < 2 ) MMG5_coquilFaceErrorMessage(mesh, it1/4, it2/4); } else { @@ -602,13 +601,13 @@ int MMG5_setEdgeNmTag(MMG5_pMesh mesh, MMG5_Hash *hash) { MMG3D_coquilFaceSecondLoopInit(mesh,piv,&iface,&i,list,&ilist,&it1, &pradj,&adj); - nbdy = 0; - + nbdy = 1; while ( adj ) { pradj = adj; - if ( MMG5_openCoquilTravel(mesh,na,nb,&adj,&piv,&iface,&i)<0 ) - return 0;; + if ( MMG5_openCoquilTravel(mesh,na,nb,&adj,&piv,&iface,&i)<0 ) { + return 0; + } /* overflow */ if ( ++ilist > MMG3D_LMAX-2 ) { @@ -627,7 +626,7 @@ int MMG5_setEdgeNmTag(MMG5_pMesh mesh, MMG5_Hash *hash) { pt = &mesh->tetra[pradj]; if ( pt->xt ) { pxt = &mesh->xtetra[pt->xt]; - if ( pxt->ftag[iface] ) ++nbdy; + if ( pxt->ftag[iface] & MG_BDY ) ++nbdy; } } @@ -643,7 +642,7 @@ int MMG5_setEdgeNmTag(MMG5_pMesh mesh, MMG5_Hash *hash) { /* If ph->s do not match the number of encountred boundaries we have separated domains. */ - if ( nbdy+1 != ph->s ) { + if ( nbdy != ph->s ) { if ( !(ptt->tag[l] & MG_REQ) ) { ptt->tag[l] |= MG_REQ; ptt->tag[l] &= ~MG_NOSURF; From 6dc1e0321b690dacda2abe0eae179b31cafdd833 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 21 Sep 2021 15:15:51 +0200 Subject: [PATCH 163/170] Add MG_BDY test instead of non nul tag test to check the presence of a boundary. --- src/mmg3d/boulep_3d.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mmg3d/boulep_3d.c b/src/mmg3d/boulep_3d.c index 71c3d0dfe..19c447f52 100644 --- a/src/mmg3d/boulep_3d.c +++ b/src/mmg3d/boulep_3d.c @@ -1667,7 +1667,7 @@ int MMG3D_coquilFaceFirstLoop(MMG5_pMesh mesh,int start,int na,int nb,int8_t ifa #ifndef NDEBUG pxt = &mesh->xtetra[pt->xt]; - assert ( pxt->ftag[iface] ); + assert ( MG_BDY & pxt->ftag[iface] ); #endif (*it1) = 4*start + iface; @@ -1766,7 +1766,7 @@ void MMG3D_coquilFaceSecondLoopInit(MMG5_pMesh mesh,int piv,int8_t *iface, (*iface) = MMG5_ifar[(*ia)][0]; } - assert ( pxt->ftag[(*iface)] ); + assert ( pxt->ftag[(*iface)] & MG_BDY ); *it1 = 4*(*pradj) + (*iface); From adf9ddee4b29eb16429afa6abfaaf6ef622c0ec1 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 21 Sep 2021 14:27:52 +0200 Subject: [PATCH 164/170] Add a non connected mode to cmake to authorize the run of test cases without internet access. --- cmake/modules/LoadCiTests.cmake | 51 ++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/cmake/modules/LoadCiTests.cmake b/cmake/modules/LoadCiTests.cmake index 6a00c0ff2..1719ca05b 100644 --- a/cmake/modules/LoadCiTests.cmake +++ b/cmake/modules/LoadCiTests.cmake @@ -98,19 +98,44 @@ ENDMACRO ( ) ##### ############################################################################### -# Check if the ci_tests directory exists -IF ( NOT EXISTS ${CI_DIR} ) +if ( MSVC ) + execute_process( + COMMAND ping www.mmgtools.org -n 2 + OUTPUT_QUIET + ERROR_QUIET + RESULT_VARIABLE NO_CONNECTION + ) +else ( ) + execute_process( + COMMAND ping www.mmgtools.org -c 2 + OUTPUT_QUIET + ERROR_QUIET + RESULT_VARIABLE NO_CONNECTION + ) +endif ( ) + +if ( NOT NO_CONNECTION EQUAL 0 ) + set ( CONNECTED OFF ) + message ( STATUS "Offline mode: requires already downloaded test cases") +else() + set ( CONNECTED ON ) +endif() + +IF ( CONNECTED ) + # Check if the ci_tests directory exists + IF ( NOT EXISTS ${CI_DIR} ) + + # First download of the tests + MESSAGE("-- Creation of continuous integration directory: ${CI_DIR}") + FILE(MAKE_DIRECTORY ${CI_DIR}) - # First download of the tests - MESSAGE("-- Creation of continuous integration directory: ${CI_DIR}") - FILE(MAKE_DIRECTORY ${CI_DIR}) + ENDIF ( ) + # + # Download the tests if needed + ##--------------> mmg + DOWNLOAD_TESTS ( "2d" ) + DOWNLOAD_TESTS ( "3d" ) + DOWNLOAD_TESTS ( "s" ) + DOWNLOAD_TESTS ( "" ) ENDIF ( ) - -# -# Download the tests if needed -##--------------> mmg -DOWNLOAD_TESTS ( "2d" ) -DOWNLOAD_TESTS ( "3d" ) -DOWNLOAD_TESTS ( "s" ) -DOWNLOAD_TESTS ( "" ) From 0cf839b08ef57c19b3b060497f32c903aae80ab2 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 21 Sep 2021 21:37:51 +0200 Subject: [PATCH 165/170] Patch typo. --- src/mmg3d/boulep_3d.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mmg3d/boulep_3d.c b/src/mmg3d/boulep_3d.c index 19c447f52..54c4df3bc 100644 --- a/src/mmg3d/boulep_3d.c +++ b/src/mmg3d/boulep_3d.c @@ -1837,7 +1837,7 @@ int MMG5_coquilface(MMG5_pMesh mesh,int start,int8_t iface,int ia,int *list, // (highly non-manifold) // 2) we have a non-manifold shape immersed in a domain (3 triangles // sharing the edge and a closed shell) - printf(" ## Warning: %s: you have %d boundary triangles in the close shell" + printf(" ## Warning: %s: you have %d boundary triangles in the closed shell" " of a manifold edge.\n",__func__,nbdy); printf(" Problem may occur during remesh process.\n"); mmgWarn0 = 1; From 1990c6cc5cdc409153bea6b853e795b2d10d2441 Mon Sep 17 00:00:00 2001 From: Algiane Date: Tue, 21 Sep 2021 21:50:16 +0200 Subject: [PATCH 166/170] Add test case for missing triangles in ls mode. --- cmake/testing/mmg3d_tests.cmake | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cmake/testing/mmg3d_tests.cmake b/cmake/testing/mmg3d_tests.cmake index 15a507584..45a64d7fb 100644 --- a/cmake/testing/mmg3d_tests.cmake +++ b/cmake/testing/mmg3d_tests.cmake @@ -544,6 +544,12 @@ ADD_TEST(NAME mmg3d_LSMultiMat -sol ${MMG3D_CI_TESTS}/LSMultiMat/step.0.phi.sol ${CTEST_OUTPUT_DIR}/mmg3d_LSMultiMat.o.meshb) +#multi-mat + opnbdy + non-manifold check +ADD_TEST(NAME mmg3d_LSMultiMat_nm + COMMAND ${EXECUT_MMG3D} -v 5 -ls -0.1 -hausd 0.05 -hgrad 1.8 -nr -opnbdy + ${MMG3D_CI_TESTS}/LSMultiMat/3d-opn + ${CTEST_OUTPUT_DIR}/mmg3d_3d-opn.o.meshb) + ADD_TEST(NAME mmg3d_OptLs_plane_val COMMAND ${EXECUT_MMG3D} -v 5 -ls -val ${MMG3D_CI_TESTS}/OptLs_plane/plane From e61653adb1bb334716cc5c3a02c381fd60a4845a Mon Sep 17 00:00:00 2001 From: Algiane Date: Thu, 23 Sep 2021 17:08:48 +0200 Subject: [PATCH 167/170] Patch bug introduced by commit b89426d3 : the input edge tags were not stored anymore inside the triangles (so we loose input ridges for example). --- src/mmg3d/hash_3d.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mmg3d/hash_3d.c b/src/mmg3d/hash_3d.c index 03c598dfb..29a798bcf 100644 --- a/src/mmg3d/hash_3d.c +++ b/src/mmg3d/hash_3d.c @@ -1116,6 +1116,9 @@ int MMG5_hGeom(MMG5_pMesh mesh) { if ( mesh->info.nosurf && (tag & MG_REQ) ) pt->tag[i] &= ~MG_NOSURF; + /* Store the edge tag inside the triangle */ + pt->tag[i] |= tag; + MMG5_hTag(&mesh->htab,pt->v[i1],pt->v[i2],edg,pt->tag[i]); } } From 5d4911a0ce99c39d1c85b0e25a4ea29dabf8905c Mon Sep 17 00:00:00 2001 From: luca Date: Thu, 23 Sep 2021 20:47:31 +0200 Subject: [PATCH 168/170] Fix deletion of MG_NOSURF tag in MMG5_settag. --- src/mmg3d/boulep_3d.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mmg3d/boulep_3d.c b/src/mmg3d/boulep_3d.c index 19c447f52..2543c1f43 100644 --- a/src/mmg3d/boulep_3d.c +++ b/src/mmg3d/boulep_3d.c @@ -1162,7 +1162,8 @@ int MMG3D_settag_oneDir(MMG5_pMesh mesh,int start, int na, int nb, pxt->tag[i] |= tag; /* Remove the potential nosurf tag if initially the edge is * really required */ - if ( (taginit & MG_REQ) && ( (!(taginit & MG_NOSURF)) || !(tag & MG_NOSURF) ) ) { + if ( ((taginit & MG_REQ) && !(taginit & MG_NOSURF)) || + (( tag & MG_REQ) && !( tag & MG_NOSURF)) ) { pxt->tag[i] &= ~MG_NOSURF; } pxt->edg[i] = MG_MAX(pxt->edg[i],edg); @@ -1220,7 +1221,8 @@ int MMG5_settag(MMG5_pMesh mesh,int start,int ia,int16_t tag,int edg) { pxt->tag[ia] |= tag; /* Remove the potential nosurf tag if initially the edge is * really required */ - if ( (taginit & MG_REQ) && ( (!(taginit & MG_NOSURF)) || !(tag & MG_NOSURF) ) ) { + if ( ((taginit & MG_REQ) && !(taginit & MG_NOSURF)) || + (( tag & MG_REQ) && !( tag & MG_NOSURF)) ) { pxt->tag[ia] &= ~MG_NOSURF; } pxt->edg[ia] = MG_MAX(pxt->edg[ia],edg); From 0a35f29ade2c9fcb681b31dc6f4f78996e9c3b74 Mon Sep 17 00:00:00 2001 From: Algiane Date: Fri, 24 Sep 2021 10:58:30 +0200 Subject: [PATCH 169/170] Patch CMake policy warnings. --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6639ab253..7a2a0a856 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ ## use this copy of the mmg distribution only if you accept them. ## ============================================================================= -CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0) +CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12) # if PROJECT_NAME is defined, mmg is a subproject if(DEFINED PROJECT_NAME) @@ -318,7 +318,7 @@ ENDFUNCTION() OPTION(BUILD_SHARED_LIBS "Build shared libraries" OFF) INVERT_BOOL("BUILD_STATIC_LIBS" ${BUILD_SHARED_LIBS}) -IF (${BUILD_STATIC_LIBS} AND NOT CMAKE_POSITION_INDEPENDENT_CODE) +IF ( (${BUILD_STATIC_LIBS} EQUAL ON) AND NOT CMAKE_POSITION_INDEPENDENT_CODE) SET(CMAKE_POSITION_INDEPENDENT_CODE ON) ENDIF() From 1fc0aad796091b5d79cd0070a61b88407bc62189 Mon Sep 17 00:00:00 2001 From: Luca Cirrottola Date: Mon, 27 Sep 2021 17:34:15 +0200 Subject: [PATCH 170/170] Implement guards against accidental set of MG_NOSURF tags on edges shared by a required and a parallel face. --- src/mmg3d/colver_3d.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/mmg3d/colver_3d.c b/src/mmg3d/colver_3d.c index e64349c21..bcea85dbf 100644 --- a/src/mmg3d/colver_3d.c +++ b/src/mmg3d/colver_3d.c @@ -752,6 +752,7 @@ void MMG3D_update_edgeTag(MMG5_pTetra pt,MMG5_pxTetra pxt,int np, int nq, int i,j,p0,p1; uint8_t ia,iav; + int16_t tag,tag1; /* update tags for edges */ for ( j=0; j<3; j++ ) { @@ -778,7 +779,12 @@ void MMG3D_update_edgeTag(MMG5_pTetra pt,MMG5_pxTetra pxt,int np, int nq, } } assert(i!=3); + tag1 = pxt1->tag[iav]; + tag = pxt->tag[ia]; pxt1->tag[iav] |= pxt->tag[ia]; + if( ((tag1 & MG_REQ) && !(tag1 & MG_NOSURF)) || + (( tag & MG_REQ) && !( tag & MG_NOSURF)) ) + pxt1->tag[iav] &= ~MG_NOSURF; pxt1->edg[iav] = MG_MAX ( pxt1->edg[iav],pxt->edg[ia] ); } } @@ -834,6 +840,9 @@ int MMG3D_update_shellEdgeTag_oneDir(MMG5_pMesh mesh,int start, int na, int nb, pxt->edg[i] = ref; pxt->tag[i] |= tag; + if( ((xtag & MG_REQ) && !(xtag & MG_NOSURF)) || + (( tag & MG_REQ) && !( tag & MG_NOSURF))) + pxt->tag[i] &= ~MG_NOSURF; } /* set new triangle for travel */ @@ -893,6 +902,9 @@ int MMG3D_update_shellEdgeTag(MMG5_pMesh mesh,int start, int8_t ia,int16_t tag, } pxt->tag[ia] |= tag; + if( ((xtag & MG_REQ) && !(xtag & MG_NOSURF)) || + (( tag & MG_REQ) && !( tag & MG_NOSURF))) + pxt->tag[ia] &= ~MG_NOSURF; pxt->edg[ia] = ref; }