Skip to content

Commit

Permalink
avoid needless failures in MMG5_coltet()
Browse files Browse the repository at this point in the history
  Let MMG5_boulesurfvolpNom() return different values for different failures,
  and let MMG5_coltet() take them into account by just lumbering on if the
  failure does not look fatal. This is currently necessary to make the larger
  or more difficult test cases in the MICROCARD project get through Mmg
  when the cell domains are preserved (so there can well be 4 or 5 references
  around a single vertex).
  • Loading branch information
mpotse committed Mar 31, 2024
1 parent a4a5ba3 commit fb4331d
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 32 deletions.
47 changes: 26 additions & 21 deletions src/mmg3d/boulep_3d.c
Original file line number Diff line number Diff line change
Expand Up @@ -748,7 +748,7 @@ int MMG5_boulesurfvolp(MMG5_pMesh mesh,MMG5_int start,int ip,int iface,

/**
* \param mesh pointer to the mesh structure.
* \param start index of the starting tetra.
* \param start index of the starting tetrahedron.
* \param ip index in \a start of the looked point.
* \param iface index in \a start of the starting face.
* \param listv pointer to the computed volumic ball.
Expand All @@ -758,15 +758,21 @@ int MMG5_boulesurfvolp(MMG5_pMesh mesh,MMG5_int start,int ip,int iface,
* \param refmin return the reference of one of the two subdomains in presence
* \param refplus return the reference of the other subdomain in presence
* \param isnm is the looked point \a ip non-manifold?
* \return -1 if fail, 1 otherwise.
* \return 1 if succesful, a negative value if the ball cannot be computed:
* -1 if a surface ball had too many elements,
* -2 if there are more than two references around,
* -3 if an edge cannot be found, and
* -4 if a volume ball had too many elements.
* Among these, -1 and -4 can be taken as a sign that further remeshing
* is not possible, while -2 and -3 just mean the job could not be done.
*
* Compute the volumic ball of a SURFACE point \a p, as well as its surfacic
* ball, starting from tetra \a start, with point \a ip, and face \a if in tetra
* volumic ball.
* \a listv[k] = 4*number of tet + index of point surfacic ball.
* \a lists[k] = 4*number of tet + index of face.
*
* \warning Don't work for a non-manifold point if \a start has an adjacent
* \warning Doesn't work for a non-manifold point if \a start has an adjacent
* through \a iface (for example : a non-manifold subdomain). Thus, if \a ip is
* non-manifold, must be called only if \a start has no adjacent through iface.
*
Expand All @@ -780,9 +786,9 @@ int MMG5_boulesurfvolpNom(MMG5_pMesh mesh,MMG5_int start,int ip,int iface,
MMG5_int k,k1,nump,*adja,piv,na,nb,adj,cur,nvstart,fstart,aux,base;
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;
Expand Down Expand Up @@ -814,16 +820,15 @@ int MMG5_boulesurfvolpNom(MMG5_pMesh mesh,MMG5_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;
Expand All @@ -835,22 +840,22 @@ int MMG5_boulesurfvolpNom(MMG5_pMesh mesh,MMG5_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;
else {
if ( *refplus == -1 ) {
if ( pt->ref != *refmin ) *refplus = pt->ref;
}
else if ( pt->ref != *refmin && pt->ref != *refplus ) return -1;
else if ( pt->ref != *refmin && pt->ref != *refplus ) return -2;
}
pt->flag = base;
}

/* identification of edge number in tetra k */
if ( !MMG3D_findEdge(mesh,pt,k,na,nb,0,&mmgErr2,&i) ) return -1;
if ( !MMG3D_findEdge(mesh,pt,k,na,nb,0,&mmgErr2,&i) ) return -3;

/* set sense of travel */
if ( pt->v[ MMG5_ifar[i][0] ] == piv ) {
iopp = MMG5_ifar[i][0];
Expand Down Expand Up @@ -878,14 +883,14 @@ int MMG5_boulesurfvolpNom(MMG5_pMesh mesh,MMG5_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];
Expand All @@ -894,11 +899,11 @@ int MMG5_boulesurfvolpNom(MMG5_pMesh mesh,MMG5_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 ) {
Expand All @@ -909,24 +914,24 @@ int MMG5_boulesurfvolpNom(MMG5_pMesh mesh,MMG5_int start,int ip,int iface,
" or/and the maximum mesh.\n");
mmgErr1 = 1;
}
return -1;
return -4;
}
listv[(*ilistv)] = 4*k1+j;
(*ilistv)++;

/* Identify references of both subdomains in presence */
if ( *refmin == -1 )
*refmin = pt1->ref;
else {
if ( *refplus == -1 ) {
if ( pt1->ref != *refmin ) *refplus = pt1->ref;
}
else if ( pt1->ref != *refmin && pt1->ref != *refplus ) return -1;
else if ( pt1->ref != *refmin && pt1->ref != *refplus ) return -2;
}
}
cur++;
}

return 1;
}

Expand Down
27 changes: 16 additions & 11 deletions src/mmg3d/mmg3d1.c
Original file line number Diff line number Diff line change
Expand Up @@ -880,12 +880,12 @@ MMG5_int MMG5_movtet(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROctree,
* \param mesh pointer to the mesh structure.
* \param met pointer to the metric structure.
* \param typchk type of checking permformed for edge length (hmin or LSHORT criterion).
* \return -1 if failed, number of collapsed points otherwise.
* \return a negative value in case of failure, number of collapsed points otherwise.
*
* Attempt to collapse small edges.
* Attempt to collapse short edges.
*
*/
static int MMG5_coltet(MMG5_pMesh mesh,MMG5_pSol met,int8_t typchk) {
static MMG5_int MMG5_coltet(MMG5_pMesh mesh,MMG5_pSol met,int8_t typchk) {
MMG5_pTetra pt,ptloc;
MMG5_pxTetra pxt;
MMG5_pPoint p0,p1;
Expand All @@ -897,7 +897,7 @@ static int MMG5_coltet(MMG5_pMesh mesh,MMG5_pSol met,int8_t typchk) {
int l,kk,isloc,ifac1;
int16_t tag,isnm,isnmint;
int8_t i,j,ip,iq;
int ier;
int ier, bsret; // function return values/error codes

nc = nnm = 0;

Expand Down Expand Up @@ -971,7 +971,7 @@ static int MMG5_coltet(MMG5_pMesh mesh,MMG5_pSol met,int8_t typchk) {
else {
if (MMG5_boulesurfvolp(mesh,k,ip,i,
list,&ilist,lists,&ilists,p0->tag & MG_NOM) < 0 )
return -1;
return -2;
}
}
else {
Expand Down Expand Up @@ -1094,15 +1094,20 @@ static int MMG5_coltet(MMG5_pMesh mesh,MMG5_pSol met,int8_t typchk) {
}
else {
if ( mesh->adja[4*(k-1)+1+i] ) continue;
if (MMG5_boulesurfvolpNom(mesh,k,ip,i,
list,&ilist,lists,&ilists,&refmin,&refplus,p0->tag & MG_NOM) < 0 )
return -1;
bsret = MMG5_boulesurfvolpNom(mesh,k,ip,i,
list,&ilist,lists,&ilists,&refmin,&refplus,p0->tag & MG_NOM);
if(bsret==-1 || bsret==-4){
return -3; // fatal
}else if(bsret==-2 || bsret==-3){
continue; // ball computation failed: cannot handle this vertex
}
assert(bsret==1 && "unexpected return value from MMG5_boulesurfvolpNom");
}
}
else {
if (MMG5_boulesurfvolp(mesh,k,ip,i,
list,&ilist,lists,&ilists,p0->tag & MG_NOM) < 0 )
return -1;
return -4;
}
}
else {
Expand Down Expand Up @@ -1134,13 +1139,13 @@ static int MMG5_coltet(MMG5_pMesh mesh,MMG5_pSol met,int8_t typchk) {

if ( ilist > 0 ) {
ier = MMG5_colver(mesh,met,list,ilist,iq,typchk);
if ( ier < 0 ) return -1;
if ( ier < 0 ) return -5;
else if ( ier ) {
MMG3D_delPt(mesh,ier);
break;
}
}
else if (ilist < 0 ) return -1;
else if (ilist < 0 ) return -6;
}
if ( ier ) {
p1->flag = base;
Expand Down

0 comments on commit fb4331d

Please sign in to comment.