59 double vfrac,lam,area,o1[3],o2[3],o3[3];
66 lam = v[i0] / (v[i0]-v[i1]);
67 o1[0] = ppt[i0]->
c[0] + lam*(ppt[i1]->
c[0]-ppt[i0]->
c[0]);
68 o1[1] = ppt[i0]->
c[1] + lam*(ppt[i1]->
c[1]-ppt[i0]->
c[1]);
69 o1[2] = ppt[i0]->
c[2] + lam*(ppt[i1]->
c[2]-ppt[i0]->
c[2]);
71 lam = v[i0] / (v[i0]-v[i2]);
72 o2[0] = ppt[i0]->
c[0] + lam*(ppt[i2]->
c[0]-ppt[i0]->
c[0]);
73 o2[1] = ppt[i0]->
c[1] + lam*(ppt[i2]->
c[1]-ppt[i0]->
c[1]);
74 o2[2] = ppt[i0]->
c[2] + lam*(ppt[i2]->
c[2]-ppt[i0]->
c[2]);
76 lam = v[i0] / (v[i0]-v[i3]);
77 o3[0] = ppt[i0]->
c[0] + lam*(ppt[i3]->
c[0]-ppt[i0]->
c[0]);
78 o3[1] = ppt[i0]->
c[1] + lam*(ppt[i3]->
c[1]-ppt[i0]->
c[1]);
79 o3[2] = ppt[i0]->
c[2] + lam*(ppt[i3]->
c[2]-ppt[i0]->
c[2]);
87 area =
MMG5_det4pt(ppt[0]->c,ppt[1]->c,ppt[2]->c,ppt[3]->c);
88 vfrac = fabs(area) - vfrac;
110 double v[4],vfm,vfp,lam,eps,o[18];
111 int nplus,nminus,nzero;
114 int8_t i,i0,i1,imin1,imin2,iplus1,iplus2,iz;
116 const uint8_t *taued;
119 pt = &
mesh->tetra[k];
126 ppt[0] = &
mesh->point[ip[0]];
127 ppt[1] = &
mesh->point[ip[1]];
128 ppt[2] = &
mesh->point[ip[2]];
129 ppt[3] = &
mesh->point[ip[3]];
131 v[0] =
sol->m[ip[0]];
132 v[1] =
sol->m[ip[1]];
133 v[2] =
sol->m[ip[2]];
134 v[3] =
sol->m[ip[3]];
138 nplus = nminus = nzero = 0;
139 imin1 = imin2 = iplus1 = iplus2 = iz = -1;
141 for (i=0; i<4; i++) {
142 if ( fabs(v[i]) < eps ) {
144 if ( iz < 0 ) iz = i;
146 else if ( v[i] >= eps ) {
148 if ( iplus1 < 0 ) iplus1 = i;
149 else if ( iplus2 < 0 ) iplus2 = i;
153 if ( imin1 < 0 ) imin1 = i;
154 else if ( imin2 < 0 ) imin2 = i;
159 if ( nzero == 4 )
return 0.0;
163 vfp =
MMG5_det4pt(ppt[0]->c,ppt[1]->c,ppt[2]->c,ppt[3]->c);
165 if ( pm == 1 )
return vfp;
171 vfm =
MMG5_det4pt(ppt[0]->c,ppt[1]->c,ppt[2]->c,ppt[3]->c);
173 if ( pm == -1 )
return vfm;
188 for ( ia=0; ia<18; ++ia ) {
193 assert ( nplus==2 && nminus==2 );
196 for ( ia=0; ia<6; ++ia ) {
201 else if (
MG_SMSGN(v[i0],v[i1]) )
continue;
206 lam = v[i0] / (v[i0]-v[i1]);
207 o[3*ia ] = ppt[i0]->
c[0] + lam*(ppt[i1]->
c[0]-ppt[i0]->
c[0]);
208 o[3*ia+1] = ppt[i0]->
c[1] + lam*(ppt[i1]->
c[1]-ppt[i0]->
c[1]);
209 o[3*ia+2] = ppt[i0]->
c[2] + lam*(ppt[i1]->
c[2]-ppt[i0]->
c[2]);
212 assert ( flag==30 || flag==45 || flag==51 );
215 tau[0] = 0 ; tau[1] = 1 ; tau[2] = 2 ; tau[3] = 3;
220 tau[0] = 1 ; tau[1] = 3 ; tau[2] = 2 ; tau[3] = 0;
225 tau[0] = 1 ; tau[1] = 2 ; tau[2] = 0 ; tau[3] = 3;
231 if ( v[tau[0]] < 0.0 ) {
242 if ( v[tau[0]] < 0.0 ) {
250 assert ( cfg == 0 || cfg == 2 );
254 vfp = fabs (
MMG5_det4pt(ppt[tau[0]]->c,ppt[tau[1]]->c,&o[3*taued[3]],&o[3*taued[4]]) );
255 vfp += fabs (
MMG5_det4pt(ppt[tau[0]]->c,&o[3*taued[4]],&o[3*taued[3]],&o[3*taued[2]]) );
256 vfp += fabs (
MMG5_det4pt(ppt[tau[0]]->c,&o[3*taued[3]],&o[3*taued[1]],&o[3*taued[2]]) );
261 else if ( cfg == 2 ) {
262 vfm = fabs (
MMG5_det4pt(&o[3*taued[2]],&o[3*taued[4]],ppt[tau[2]]->c,ppt[tau[3]]->c) );
263 vfm += fabs (
MMG5_det4pt(&o[3*taued[2]],&o[3*taued[3]],ppt[tau[2]]->c,&o[3*taued[4]]) );
264 vfm += fabs (
MMG5_det4pt(&o[3*taued[1]],&o[3*taued[3]],ppt[tau[2]]->c,&o[3*taued[2]]) );
274 vfm = fabs (
MMG5_det4pt(&o[3*taued[2]],&o[3*taued[4]],ppt[tau[2]]->c,ppt[tau[3]]->c) );
275 vfm += fabs (
MMG5_det4pt(&o[3*taued[2]],&o[3*taued[3]],ppt[tau[2]]->c,&o[3*taued[4]]) );
276 vfm += fabs (
MMG5_det4pt(&o[3*taued[1]],&o[3*taued[3]],ppt[tau[2]]->c,&o[3*taued[2]]) );
278 else if ( cfg == 2 ) {
279 vfp = fabs (
MMG5_det4pt(ppt[tau[0]]->c,ppt[tau[1]]->c,&o[3*taued[3]],&o[3*taued[4]]) );
280 vfp += fabs (
MMG5_det4pt(ppt[tau[0]]->c,&o[3*taued[4]],&o[3*taued[3]],&o[3*taued[2]]) );
281 vfp += fabs (
MMG5_det4pt(ppt[tau[0]]->c,&o[3*taued[3]],&o[3*taued[1]],&o[3*taued[2]]) );
287 vf = fabs (
MMG5_det4pt(ppt[0]->c,ppt[1]->c,ppt[2]->c,ppt[3]->c) );
321 for (k=1; k<=
mesh->ne; k++) {
322 pt = &
mesh->tetra[k];
323 if ( !
MG_EOK(pt) )
continue;
325 for (i=0; i<4; i++) {
326 p0 = &
mesh->point[pt->
v[i]];
330 if ( p0->
ref ==
mesh->info.isoref ) {
340 for ( k=1; k<=
mesh->ne; k++ ) {
341 pt = &
mesh->tetra[k];
343 if ( !
MG_EOK(pt) )
continue;
367 detA = A[0][0]*(A[1][1]*A[2][2] - A[2][1]*A[1][2]) \
368 - A[0][1]*(A[1][0]*A[2][2] - A[2][0]*A[1][2]) \
369 + A[0][2]*(A[1][0]*A[2][1] - A[2][0]*A[1][1]);
373 r[0] = b[0]*(A[1][1]*A[2][2] - A[2][1]*A[1][2]) \
374 - A[0][1]*(b[1]*A[2][2] - b[2]*A[1][2]) \
375 + A[0][2]*(b[1]*A[2][1] - b[2]*A[1][1]);
377 r[1] = A[0][0]*(b[1]*A[2][2] - b[2]*A[1][2]) \
378 - b[0]*(A[1][0]*A[2][2] - A[2][0]*A[1][2]) \
379 + A[0][2]*(A[1][0]*b[2] - A[2][0]*b[1]);
381 r[2] = A[0][0]*(A[1][1]*b[2] - A[2][1]*b[1]) \
382 - A[0][1]*(A[1][0]*b[2] - A[2][0]*b[1]) \
383 + b[0]*(A[1][0]*A[2][1] - A[2][0]*A[1][1]);
410 int ibdy,ilist,cur,l;
412 int8_t i,i0,i1,i2,j0,j1,j2,j,ip,nzeros,nopp,nsame;
413 static int8_t mmgWarn0 = 0;
415 pt = &
mesh->tetra[k];
419 memset(bdy,0,(
MMG3D_LMAX+1)*
sizeof(MMG5_int));
420 memset(list,0,(
MMG3D_LMAX+1)*
sizeof(MMG5_int));
423 for (j=0; j<3; j++) {
425 if (
sol->m[pt->
v[ip]] != 0.0 )
break;
430 fprintf(stderr,
"\n ## Warning: %s: at least 1 tetra with 4 null"
431 " values.\n",__func__);
436 v =
sol->m[pt->
v[ip]];
440 list[ilist] = 4*k+indp;
446 while ( cur < ilist ) {
449 pt = &
mesh->tetra[iel];
450 adja = &
mesh->adja[4*(iel-1)+1];
454 for (j=0; j<3; j++) {
456 v1 =
sol->m[pt->
v[i1]];
457 if ( ( v1 != 0.0 ) && !
MG_SMSGN(v,v1) ) {
465 for (j=0; j<3; j++) {
468 v1 =
sol->m[pt->
v[i1]];
469 v2 =
sol->m[pt->
v[i2]];
471 if ( ( ( v1 != 0.0 ) &&
MG_SMSGN(v,v1) ) ||
472 ( ( v2 != 0.0 ) &&
MG_SMSGN(v,v2) ) ) {
477 pt1 = &
mesh->tetra[jel];
479 if ( pt1->
flag == base )
continue;
480 for (ip=0; ip<4; ip++) {
481 if ( pt1->
v[ip] == np )
break;
485 list[ilist] = 4*jel + ip;
495 for(l=0; l<ilist; l++) {
498 pt = &
mesh->tetra[iel];
500 nzeros = nsame = nopp = 0;
506 v0 =
sol->m[pt->
v[i0]];
507 v1 =
sol->m[pt->
v[i1]];
508 v2 =
sol->m[pt->
v[i2]];
534 if ( !res && nzeros == 2 && nsame == 1 ) {
535 for (j=0; j<3; j++) {
537 v0 =
sol->m[pt->
v[i0]];
538 if ( v0 != 0.0 &&
MG_SMSGN(v,v0) )
break;
541 adja = &
mesh->adja[4*(iel-1)+1];
544 pt1 = &
mesh->tetra[jel];
545 v1 =
sol->m[pt1->
v[j0]];
546 if ( v1 != 0.0 && !
MG_SMSGN(v,v1) ) {
548 if ( pt1->
v[j] == np )
break;
553 if ( ( nzeros == 2 && nsame == 1 ) || ( nsame >= 1 && nopp >= 1 ) ) {
565 pt = &
mesh->tetra[iel];
569 memset(list,0,(
MMG3D_LMAX+1)*
sizeof(MMG5_int));
573 while ( cur < ilist ) {
576 pt = &
mesh->tetra[iel];
577 adja = &
mesh->adja[4*(iel-1)+1];
580 for (j=0; j<3; j++) {
583 v1 =
sol->m[pt->
v[i1]];
584 v2 =
sol->m[pt->
v[i2]];
586 if ( v1 == 0.0 && v2 == 0.0 ) {
590 pt1 = &
mesh->tetra[jel];
594 else if ( ( ( v1 != 0.0 ) && (!
MG_SMSGN(v,v1)) ) || ( ( v2 != 0.0 ) && (!
MG_SMSGN(v,v2)) ) ) {
598 pt1 = &
mesh->tetra[jel];
604 v0 =
sol->m[pt1->
v[j0]];
605 v1 =
sol->m[pt1->
v[j1]];
606 v2 =
sol->m[pt1->
v[j2]];
608 nzeros = nsame = nopp = 0;
631 if ( ( nzeros == 2 && nsame == 1 ) || ( nsame >= 1 && nopp >= 1 ) ) {
632 if ( pt1->
flag < base - 1 )
return 0;
635 if ( pt1->
flag == base )
continue;
636 for (ip=0; ip<4; ip++) {
637 if ( pt1->
v[ip] == np )
break;
641 list[ilist] = 4*jel + ip;
650 for (l=0; l<ibdy; l++) {
652 pt = &
mesh->tetra[iel];
653 if ( pt->
flag != base )
return 0;
672 MMG5_int k,nc,ns,ip,ncg;
677 fprintf(stderr,
"\n ## Error: %s: hashing problem (1). Exit program.\n",
683 for (k=1; k<=
mesh->np; k++)
684 mesh->point[k].flag = 0;
687 fprintf(stderr,
" Exit program.\n");
692 for (k=1; k<=
mesh->ne; k++) {
693 pt = &
mesh->tetra[k];
694 if ( !pt->
v[0] )
continue;
696 for (i=0; i<4; i++) {
701 for (i=0; i<4; i++) {
711 for (k=1; k<=
mesh->np; k++) {
712 p0 = &
mesh->point[k];
713 if ( !
MG_VOK(p0) )
continue;
715 if (
mesh->info.ddebug )
716 fprintf(stderr,
" ## Warning: %s: snapping value at vertex %" MMG5_PRId
"; "
717 "previous value: %E.\n",__func__,k,fabs(
sol->m[k]));
731 for (k=1; k<=
mesh->ne; k++) {
732 pt = &
mesh->tetra[k];
733 if ( !
MG_EOK(pt) )
continue;
734 for (i=0; i<4; i++) {
736 p0 = &
mesh->point[ip];
737 if ( p0->
flag == 1 ) {
754 if ( (abs(
mesh->info.imprim) > 5 ||
mesh->info.ddebug) && ns+ncg > 0 )
755 fprintf(stdout,
" %8" MMG5_PRId
" points snapped, %" MMG5_PRId
" corrected\n",ns,ncg);
758 for (k=1; k<=
mesh->np; k++)
759 mesh->point[k].flag = 0;
781 double volc,voltot,v0,v1,v2,v3;
783 MMG5_int ncp,ncm,base,k,kk,ll,ip0,ip1,ip2,ip3,*adja,*pile;
790 for (k=1; k<=
mesh->ne; k++)
mesh->tetra[k].flag = 0;
794 for (k=1; k<=
mesh->ne; k++) {
795 pt = &
mesh->tetra[k];
796 if ( !
MG_EOK(pt) )
continue;
802 printf(
" Exit program.\n");
809 for (k=1; k<=
mesh->ne; k++) {
812 pt = &
mesh->tetra[k];
813 if ( !
MG_EOK(pt) )
continue;
814 if ( pt->
flag == base )
continue;
827 if ( v0 <= 0.0 && v1 <= 0.0 && v2 <= 0.0 && v3 <= 0.0 )
continue;
833 if ( ipile >
mesh->ne ) {
834 fprintf(stderr,
"\n ## Problem in length of pile; function rmc.\n"
835 " Check that the level-set intersect the mesh.\n"
845 pt1 = &
mesh->tetra[kk];
851 adja = &
mesh->adja[4*(kk-1)+1];
852 for (i=0; i<4; i++) {
854 if (
sol->m[ip0] <= 0.0 )
continue;
856 for ( i1=0; i1<3; ++i1 ) {
860 pt2 = &
mesh->tetra[ll];
865 if ( ipile >
mesh->ne ) {
866 fprintf(stderr,
"\n ## Problem in length of pile; function rmc. Exit program.\n");
873 while ( ++cur < ipile );
876 if ( volc < mesh->
info.rmc * voltot ) {
877 for (l=0; l<ipile; l++) {
878 pt1 = &
mesh->tetra[pile[l]];
879 for (i=0; i<4; i++) {
881 if (
sol->m[ip0] > 0.0 ) {
893 for (k=1; k<=
mesh->ne; k++) {
896 pt = &
mesh->tetra[k];
897 if ( !
MG_EOK(pt) )
continue;
898 if ( pt->
flag == base )
continue;
911 if ( v0 >= 0.0 && v1 >= 0.0 && v2 >= 0.0 && v3 >= 0.0 )
continue;
917 if ( ipile >
mesh->ne ) {
918 fprintf(stderr,
"\n ## Problem in length of pile; function rmc. Exit program.\n");
926 pt1 = &
mesh->tetra[kk];
932 adja = &
mesh->adja[4*(kk-1)+1];
933 for (i=0; i<4; i++) {
935 if (
sol->m[ip0] >= 0.0 )
continue;
937 for ( i1=0; i1<3; ++i1 ) {
941 pt2 = &
mesh->tetra[ll];
946 if ( ipile >
mesh->ne ) {
947 fprintf(stderr,
"\n ## Problem in length of pile; function rmc. Exit program.\n");
954 while ( ++cur < ipile );
957 if ( volc < mesh->
info.rmc * voltot ) {
958 for (l=0; l<ipile; l++) {
959 pt1 = &
mesh->tetra[pile[l]];
960 for (i=0; i<4; i++) {
969 if (
mesh->info.nbr ) {
971 for (l=0; l<ipile; l++) {
972 pt1 = &
mesh->tetra[pile[l]];
974 pxt = &
mesh->xtetra[pt1->
xt];
975 for (i=0; i<4; i++) {
977 for (j=0; j<3; j++) {
979 if (
sol->m[ip0] < 0.0 ) {
991 for (l=0; l<ipile; l++) {
992 pt1 = &
mesh->tetra[pile[l]];
993 for (i=0; i<4; i++) {
1004 for (k=1; k<=
mesh->ne; k++)
mesh->tetra[k].flag = 0;
1009 if (
mesh->info.imprim > 0 ||
mesh->info.ddebug ) {
1010 printf(
"\n *** Removed %" MMG5_PRId
" positive parasitic bubbles and %" MMG5_PRId
" negative parasitic bubbles\n",ncp,ncm);
1031 double c[3],v0,v1,s;
1033 MMG5_int vx[6],k,ip0,ip1,np,nb,ns,ne,src,refext,refint;
1035 static int8_t mmgWarn = 0;
1038 for (k=1; k<=
mesh->np; k++)
1039 mesh->point[k].flag = 0;
1043 for (k=1; k<=
mesh->ne; k++) {
1044 pt = &
mesh->tetra[k];
1045 for (ia=0; ia<6; ia++) {
1048 p0 = &
mesh->point[ip0];
1049 p1 = &
mesh->point[ip1];
1050 if ( p0->
flag && p1->
flag )
continue;
1063 if ( ! nb )
return 1;
1068 for (k=1; k<=
mesh->ne; k++) {
1069 pt = &
mesh->tetra[k];
1070 if ( !
MG_EOK(pt) )
continue;
1074 for (ia=0; ia<6; ia++) {
1083 if ( !pt->
xt )
continue;
1085 pxt = &
mesh->xtetra[pt->
xt];
1086 for (ia=0; ia<4; ia++) {
1089 for (j=0; j<3; j++) {
1101 for (k=1; k<=
mesh->ne; k++) {
1102 pt = &
mesh->tetra[k];
1103 if ( !
MG_EOK(pt) )
continue;
1105 for (ia=0; ia<6; ia++) {
1110 if ( np>0 )
continue;
1114 p0 = &
mesh->point[ip0];
1115 p1 = &
mesh->point[ip1];
1119 else if (
MG_SMSGN(v0,v1) )
continue;
1120 else if ( !p0->
flag || !p1->
flag )
continue;
1127 c[0] = p0->
c[0] + s*(p1->
c[0]-p0->
c[0]);
1128 c[1] = p0->
c[1] + s*(p1->
c[1]-p0->
c[1]);
1129 c[2] = p0->
c[2] + s*(p1->
c[2]-p0->
c[2]);
1138 MMG5_int oldnpmax =
mesh->npmax;
1140 fprintf(stderr,
"\n ## Error: %s: unable to"
1141 " allocate a new point\n",__func__);
1151 mesh->npmax = oldnpmax;
1157 double,
"larger solution",
1160 mesh->npmax = oldnpmax;
1170 if ( met && met->
m ) {
1171 if ( met->
size > 1 ) {
1179 fprintf(stderr,
"\n ## Error: %s: unable to"
1180 " interpolate the metric during the level-set"
1181 " discretization\n",__func__);
1190 fprintf(stderr,
" ## Warning: %s: the level-set intersect at least"
1191 " one required entity. Required entity ignored.\n\n",__func__);
1204 for (k=1; k<=ne; k++) {
1205 pt = &
mesh->tetra[k];
1206 if ( !
MG_EOK(pt) )
continue;
1208 memset(vx,0,6*
sizeof(MMG5_int));
1209 for (ia=0; ia<6; ia++) {
1214 case 1:
case 2:
case 4:
case 8:
case 16:
case 32:
1219 case 48:
case 24:
case 40:
case 6:
case 34:
case 36:
1220 case 20:
case 5:
case 17:
case 9:
case 3:
case 10:
1225 case 7:
case 25:
case 42:
case 52:
1230 case 30:
case 45:
case 51:
1236 assert(pt->
flag == 0);
1239 if ( !
ier )
return 0;
1241 if ( (
mesh->info.ddebug || abs(
mesh->info.imprim) > 5) && ns > 0 )
1242 fprintf(stdout,
" %7" MMG5_PRId
" splitted\n",ns);
1261 MMG5_int ref,refint,refext,k,ip;
1262 int8_t nmns,npls,nz,i;
1264 for (k=1; k<=
mesh->ne; k++) {
1265 pt = &
mesh->tetra[k];
1266 if ( !
MG_EOK(pt) )
continue;
1270 nmns = npls = nz = 0;
1271 for (i=0; i<4; i++) {
1314 MMG5_int *adja,k,jel;
1316 if ( (!
mesh->info.iso) || (!
mesh->info.opnbdy) ) {
1324 if ( !
mesh->xtetra ) {
1325 fprintf(stderr,
"\n ## Error: %s: the xtetra array must be allocated.\n",
1329 if ( !
mesh->adja ) {
1330 fprintf(stderr,
"\n ## Error: %s: the ajda array must be allocated.\n",
1336 for (k=1; k<=
mesh->ne; k++) {
1337 pt = &
mesh->tetra[k];
1339 adja = &
mesh->adja[4*(k-1)+1];
1341 for (i=0; i<4; i++) {
1348 pt1 = &
mesh->tetra[jel];
1350 if ( pt->
ref == pt1->
ref ) {
1357 if ( pt->
ref > pt1->
ref ) {
1376 "larger xtetra table",
1378 fprintf(stderr,
" Exit program.\n");
return 0;);
1383 pxt = &
mesh->xtetra[ptmax->
xt];
1384 pxt->
ref[imax] =
mesh->info.isoref;
1393 "larger xtetra table",
1395 fprintf(stderr,
" Exit program.\n");
return 0;);
1400 pxt = &
mesh->xtetra[ptmin->
xt];
1401 pxt->
ref[imin] =
mesh->info.isoref;
1423 MMG5_int base,ref,*adja,list[
MMG3D_LMAX+2],k,k1,nump;
1426 base = ++
mesh->base;
1429 pt = &
mesh->tetra[start];
1435 list[ilist] = 4*start+ip;
1440 while( cur < ilist ) {
1444 adja = &
mesh->adja[4*(k-1)+1];
1452 pt1 = &
mesh->tetra[k1];
1455 if( pt1->
ref != ref )
continue;
1457 if( pt1->
flag == base )
continue;
1460 for(j=0; j<4 ; j++){
1461 if(pt1->
v[j] == nump)
1468 list[ilist] = 4*k1+j;
1483 adja = &
mesh->adja[4*(k-1)+1];
1488 if ( !k1 )
continue;
1491 pt1 = &
mesh->tetra[k1];
1494 if(pt1->
flag == base)
continue;
1497 for(j=0; j<4 ; j++){
1498 if(pt1->
v[j] == nump)
1505 list[ilist] = 4*k1+j;
1512 for(cur=nref; cur<ilist; cur++) {
1514 pt = &
mesh->tetra[k];
1515 if( pt->
ref == ref ) {
1516 fprintf(stderr,
" *** Topological problem\n");
1517 fprintf(stderr,
" non manifold surface at point %" MMG5_PRId
" %" MMG5_PRId
"\n",nump,
MMG3D_indPt(
mesh,nump));
1518 fprintf(stderr,
" non manifold surface at tet %" MMG5_PRId
" (ip %d)\n",
MMG3D_indElt(
mesh,start),ip);
1519 fprintf(stderr,
" nref (color %d) %" MMG5_PRId
"\n",nref,ref);
1531 MMG5_int iel,k,*adja;
1533 static int8_t mmgWarn0 = 0;
1535 for(k=1; k<=
mesh->np; k++){
1536 mesh->point[k].flag = 0;
1540 for(k=1; k<=
mesh->ne; k++) {
1541 pt = &
mesh->tetra[k];
1542 if ( !
MG_EOK(pt) )
continue;
1543 adja = &
mesh->adja[4*(k-1)+1];
1547 for(i=0; i<4; i++) {
1552 pt1 = &
mesh->tetra[adja[i]/4];
1553 if ( pt1->
ref != ref ) cnt++;
1559 fprintf(stderr,
"\n ## Warning: %s: at least 1 tetra with 4 boundary"
1560 " faces.\n",__func__);
1567 for(k=1; k<=
mesh->ne; k++){
1568 pt = &
mesh->tetra[k];
1570 adja = &
mesh->adja[4*(k-1)+1];
1573 if(!adja[i])
continue;
1575 pt1 = &
mesh->tetra[iel];
1592 if (
mesh->info.imprim > 0 ||
mesh->info.ddebug )
1593 fprintf(stdout,
" *** Manifold implicit surface.\n");
1613 for(k=1; k<=
mesh->np; k++){
1614 mesh->point[k].flag = 0;
1618 for(k=1; k<=
mesh->ne; k++){
1619 pt = &
mesh->tetra[k];
1623 for(j=0; j<4; j++) {
1624 if(
sol->m[pt->
v[j]] == 0.0 ) cnt++;
1627 fprintf(stderr,
"\n ## Error: %s: tetra %" MMG5_PRId
": 4 vertices on implicit boundary.\n",
1634 for(k=1; k<=
mesh->ne; k++){
1635 pt = &
mesh->tetra[k];
1637 adja = &
mesh->adja[4*(k-1)+1];
1640 if(!adja[i])
continue;
1642 pt1 = &
mesh->tetra[iel];
1643 if(pt1->
ref == pt->
ref)
continue;
1653 fprintf(stderr,
"\n ## Error: %s: non orientable implicit surface:"
1654 " ball of point %" MMG5_PRId
".\n",__func__,pt->
v[ip]);
1661 if (
mesh->info.ddebug ) fprintf(stdout,
" *** Manifold implicit surface.\n");
1687 MMG5_int ref,nump,numq,list[
MMG3D_LMAX+2],*adja,*adja1,iel,jel,ndepmq,ndeppq,base;
1688 int8_t i,j,ip,jp,iq,jq,voy,indp,indq,isminq,isplq,ismin,ispl;
1691 ndepmq = ndeppq = 0;
1694 pt = &
mesh->tetra[k];
1702 if ( !ndepmin || !ndepplus ) {
1703 base = ++
mesh->base;
1705 pt = &
mesh->tetra[k];
1706 for(j=0; j<4; j++) {
1707 if ( pt->
v[j] == numq )
break;
1710 list[ilist] = 4*k+j;
1715 if ( pt->
ref == refmin ) isminq = 1;
1716 else if ( pt->
ref == refplus ) isplq = 1;
1719 while( cur < ilist ) {
1720 iel = list[cur] / 4;
1722 adja = &
mesh->adja[4*(iel-1)+1];
1724 for (j=0; j<3; j++) {
1727 if ( !jel )
continue;
1730 pt1 = &
mesh->tetra[jel];
1732 if ( pt1->
ref == refmin ) isminq = 1;
1733 else if ( pt1->
ref == refplus ) isplq = 1;
1735 if ( pt1->
flag == base )
continue;
1737 for(iq=0; iq<4; iq++)
1738 if ( pt1->
v[iq] == numq )
break;
1743 list[ilist] = 4*jel+iq;
1747 if ( !ndeppq && pt1->
ref == refplus ) {
1748 for(ip=0; ip<4; ip++)
1749 if ( pt1->
v[ip] == nump )
break;
1750 if( ip == 4 ) ndeppq = jel;
1752 if( !ndepmq && pt1->
ref == refmin ) {
1753 for(ip=0; ip<4; ip++)
1754 if ( pt1->
v[ip] == nump )
break;
1755 if( ip == 4 ) ndepmq = jel;
1761 memset(list,0,(
MMG3D_LMAX+2)*
sizeof(MMG5_int));
1765 ispl = ( isplp || isplq ) ? 1 : 0;
1766 ismin = ( isminp || isminq ) ? 1 : 0;
1771 base = ++
mesh->base;
1774 pt = &
mesh->tetra[ndepmin];
1777 for(j=0; j<4; j++) {
1778 if ( pt->
v[j] == nump )
break;
1783 list[ilist] = - (4*ndepmin+j);
1786 else if ( ndepmq ) {
1787 pt = &
mesh->tetra[ndepmq];
1790 for(j=0; j<4; j++) {
1791 if ( pt->
v[j] == numq )
break;
1796 list[ilist] = 4*ndepmq+j;
1800 if ( ismin && ispl )
1808 while ( cur < ilist ) {
1816 adja = &
mesh->adja[4*(iel-1)+1];
1819 for (i=0; i<3; i++) {
1822 if ( !jel )
continue;
1827 pt1 = &
mesh->tetra[jel];
1828 if ( pt1->
ref != ref )
continue;
1831 if( pt1->
v[voy] == numq ) {
1832 adja1 = &
mesh->adja[4*(jel-1)+1];
1834 if (pt1->
v[j] == nump )
break;
1838 if (!jel )
continue;
1841 pt1 = &
mesh->tetra[jel];
1843 if ( pt1->
ref != ref)
continue;
1844 if ( pt1->
flag == base )
continue;
1847 for(j=0; j<4; j++) {
1848 if ( pt1->
v[j] == nump )
break;
1850 if ( j<4 )
continue;
1855 if ( pt1->
v[j] == numq )
break;
1858 list[ilist] = 4*jel+j;
1863 if ( pt1->
flag == base )
continue;
1866 if ( pt1->
v[j] == nump )
break;
1869 list[ilist] = - (4*jel+j);
1880 adja = &
mesh->adja[4*(iel-1)+1];
1883 for (i=0; i<3; i++) {
1886 if ( !jel )
continue;
1891 pt1 = &
mesh->tetra[jel];
1892 if ( pt1->
ref != ref )
continue;
1895 if( pt1->
v[voy] == nump ) {
1896 adja1 = &
mesh->adja[4*(jel-1)+1];
1898 if (pt1->
v[j] == numq )
break;
1902 if (!jel )
continue;
1906 pt1 = &
mesh->tetra[jel];
1907 if ( pt1->
ref != ref)
continue;
1908 if ( pt1->
flag == base )
continue;
1911 for(j=0; j<4; j++) {
1912 if ( pt1->
v[j] == numq )
break;
1914 if ( j<4 )
continue;
1918 if (pt1->
v[j] == nump )
break;
1921 list[ilist] = -(4*jel+j);
1926 if ( pt1->
flag == base )
continue;
1929 if (pt1->
v[j] == numq )
break;
1932 list[ilist] = 4*jel+j;
1941 assert( cur == ilist );
1945 pt = &
mesh->tetra[ndepplus];
1946 for(j=0; j<4; j++) {
1947 if ( pt->
v[j] == nump )
break;
1952 list[ilist] = - (4*ndepplus+j);
1956 else if ( ndeppq ) {
1957 pt = &
mesh->tetra[ndeppq];
1958 for(j=0; j<4; j++) {
1959 if ( pt->
v[j] == numq )
break;
1964 list[ilist] = 4*ndeppq+j;
1969 if ( ismin && ispl )
1975 while ( cur < ilist ) {
1983 adja = &
mesh->adja[4*(iel-1)+1];
1987 for (i=0; i<3; i++) {
1991 if ( !jel )
continue;
1996 pt1 = &
mesh->tetra[jel];
1997 if ( pt1->
ref != ref )
continue;
2000 if( pt1->
v[voy] == numq ) {
2001 adja1 = &
mesh->adja[4*(jel-1)+1];
2003 if (pt1->
v[j] == nump )
break;
2007 if (!jel )
continue;
2010 pt1 = &
mesh->tetra[jel];
2011 if ( pt1->
ref != ref)
continue;
2012 if ( pt1->
flag == base )
continue;
2015 for(j=0; j<4; j++) {
2016 if ( pt1->
v[j] == nump )
break;
2018 if ( j<4 )
continue;
2022 if ( pt1->
v[j] == numq )
break;
2025 list[ilist] = 4*jel+j;
2030 if ( pt1->
flag == base )
continue;
2033 if (pt1->
v[j] == nump )
break;
2036 list[ilist] = - (4*jel+j);
2047 adja = &
mesh->adja[4*(iel-1)+1];
2051 for (i=0; i<3; i++) {
2055 if ( !jel )
continue;
2060 pt1 = &
mesh->tetra[jel];
2062 if ( pt1->
ref != ref )
continue;
2065 if( pt1->
v[voy] == nump ) {
2066 adja1 = &
mesh->adja[4*(jel-1)+1];
2068 if (pt1->
v[j] == numq )
break;
2072 if (!jel )
continue;
2075 pt1 = &
mesh->tetra[jel];
2076 if ( pt1->
ref != ref)
continue;
2077 if ( pt1->
flag == base )
continue;
2080 for(j=0; j<4; j++) {
2081 if ( pt1->
v[j] == numq )
break;
2083 if ( j<4 )
continue;
2087 if (pt1->
v[j] == nump )
break;
2090 list[ilist] = -(4*jel+j);
2095 if ( pt1->
flag == base )
continue;
2098 if (pt1->
v[j] == numq )
break;
2101 list[ilist] = 4*jel+j;
2109 assert( cur == ilist );
2114 while ( cur < ilist ) {
2121 adja = &
mesh->adja[4*(iel-1)+1];
2124 for(i=0; i<3; i++) {
2128 if ( !jel )
continue;
2131 pt1 = &
mesh->tetra[jel];
2132 if (pt1->
flag == base )
continue;
2137 for(j=0; j<4; j++) {
2138 if ( pt1->
v[j] == nump )
2140 else if ( pt1->
v[j] == numq )
2143 assert( indp >= 0 && indp < 4 );
2148 if (
mesh->info.ddebug ) {
2149 fprintf(stderr,
"\n ## Warning: %s: we should rarely passed here. "
2150 "tetra %" MMG5_PRId
" = %" MMG5_PRId
" %" MMG5_PRId
" %" MMG5_PRId
" %" MMG5_PRId
", ref = %" MMG5_PRId
".",__func__,
2151 jel,pt1->
v[0],pt1->
v[1],pt1->
v[2],pt1->
v[3],pt1->
ref);
2156 list[ilist] = -(4*jel+indp);
2164 adja = &
mesh->adja[4*(iel-1)+1];
2167 for(i=0; i<3; i++) {
2171 if ( !jel )
continue;
2174 pt1 = &
mesh->tetra[jel];
2175 if (pt1->
flag == base )
continue;
2181 for(j=0; j<4; j++) {
2182 if ( pt1->
v[j] == nump )
2184 else if ( pt1->
v[j] == numq )
2187 assert( indq >= 0 && indq < 4 );
2191 if (
mesh->info.ddebug ) {
2192 fprintf(stderr,
"\n ## Warning: %s: we should rarely passed here. "
2193 "tetra %" MMG5_PRId
" = %" MMG5_PRId
" %" MMG5_PRId
" %" MMG5_PRId
" %" MMG5_PRId
", ref = %" MMG5_PRId
"\n",__func__,
2194 jel,pt1->
v[0],pt1->
v[1],pt1->
v[2],pt1->
v[3],pt1->
ref);
2199 list[ilist] = 4*jel+indq;
2223 if (
mesh->info.isosurf ) {
2224 strcat(str,
"(BOUNDARY PART)");
2238 if ( abs(
mesh->info.imprim) > 3 )
2239 fprintf(stdout,
" ** ISOSURFACE EXTRACTION %s\n",str);
2241 if (
mesh->nprism ||
mesh->nquad ) {
2242 fprintf(stderr,
"\n ## Error: Isosurface extraction not available with"
2243 " hybrid meshes. Exit program.\n");
2249 for (k=1; k<=
sol->np; k++)
2253 if ( !MMG3D_snpval(
mesh,
sol) ) {
2254 fprintf(stderr,
"\n ## Problem with implicit function. Exit program.\n");
2259 fprintf(stderr,
"\n ## Hashing problem. Exit program.\n");
2265 fprintf(stderr,
"\n ## Boundary orientation problem. Exit program.\n");
2270 fprintf(stderr,
"\n ## Boundary problem. Exit program.\n");
2276 fprintf(stderr,
"\n ## Hashing problem (0). Exit program.\n");
2281 fprintf(stderr,
"\n ## Problem in setting boundary. Exit program.\n");
2286 if ( !MMG3D_resetRef(
mesh) ) {
2287 fprintf(stderr,
"\n ## Problem in resetting references. Exit program.\n");
2292 if (
mesh->info.iso ) {
2294 fprintf(stderr,
"\n ## Error in removing small parasitic components."
2295 " Exit program.\n");
2301 if (
mesh->info.rmc > 0 ) {
2302 fprintf(stdout,
"\n ## Warning: rmc option not implemented for boundary"
2303 " isosurface extraction.\n");
2310 for( ip = 1; ip <=
mesh->np; ip++ )
2311 mesh->point[ip].src = ip;
2314 if ( !MMG3D_cuttet(
mesh,
sol,met) ) {
2315 fprintf(stderr,
"\n ## Problem in discretizing implicit function. Exit program.\n");
2325 if ( !MMG3D_setref(
mesh,
sol) ) {
2326 fprintf(stderr,
"\n ## Problem in setting references. Exit program.\n");
2331 for ( MMG5_int k=1; k<=
mesh->np; ++k ) {
MMG5_pMesh MMG5_pSol * sol
int MMG5_hashUpdate(MMG5_Hash *hash, MMG5_int a, MMG5_int b, MMG5_int k)
int MMG5_hashNew(MMG5_pMesh mesh, MMG5_Hash *hash, MMG5_int hsiz, MMG5_int hmax)
MMG5_int MMG5_hashGet(MMG5_Hash *hash, MMG5_int a, MMG5_int b)
int MMG5_hashEdge(MMG5_pMesh mesh, MMG5_Hash *hash, MMG5_int a, MMG5_int b, MMG5_int k)
int MMG3D_hashTetra(MMG5_pMesh mesh, int pack)
Create array of adjacency.
int MMG5_hGeom(MMG5_pMesh mesh)
int MMG5_chkBdryTria(MMG5_pMesh mesh)
int MMG5_bdrySet(MMG5_pMesh mesh)
int MMG5_bdryPerm(MMG5_pMesh mesh)
int MMG3D_intmet33_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k, int8_t i, MMG5_int ip, double s)
int MMG5_intmet_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k, int8_t i, MMG5_int ip, double s)
API headers and documentation for the mmg3d library, for volumetric meshes in 3D.
int MMG3D_cuttet_lssurf(MMG5_pMesh mesh, MMG5_pSol sol, MMG5_pSol met)
int MMG5_split4op(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k, MMG5_int vx[6], int8_t)
int MMG3D_snpval_lssurf(MMG5_pMesh mesh, MMG5_pSol sol)
int MMG3D_rmc(MMG5_pMesh, MMG5_pSol)
int MMG3D_setref_ls(MMG5_pMesh mesh, MMG5_pSol sol)
int MMG5_split1(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k, MMG5_int vx[6], int8_t metRidTyp)
static const uint8_t MMG5_permedge[12][6]
MMG5_int MMG3D_indPt(MMG5_pMesh mesh, MMG5_int kp)
MMG5_int MMG3D_newPt(MMG5_pMesh mesh, double c[3], uint16_t tag, MMG5_int src)
static const int8_t MMG5_iarf[4][3]
iarf[i]: edges of face opposite to vertex i
static const uint8_t MMG5_iare[6][2]
vertices of extremities of the edges of the tetra
int MMG3D_cuttet_ls(MMG5_pMesh mesh, MMG5_pSol sol, MMG5_pSol met)
int MMG3D_setref_lssurf(MMG5_pMesh mesh, MMG5_pSol sol)
int MMG5_split2sf(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k, MMG5_int vx[6], int8_t)
#define MMG3D_POINT_REALLOC(mesh, sol, ip, wantedGap, law, o, tag, src)
int MMG5_split3cone(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k, MMG5_int vx[6], int8_t)
int MMG3D_snpval_ls(MMG5_pMesh mesh, MMG5_pSol sol)
static const uint8_t MMG5_inxt3[7]
next vertex of tetra: {1,2,3,0,1,2,3}
int MMG3D_resetRef_lssurf(MMG5_pMesh mesh)
int MMG3D_resetRef_ls(MMG5_pMesh mesh)
static const uint8_t MMG5_idir[4][3]
idir[i]: vertices of face opposite to vertex i
MMG5_int MMG3D_indElt(MMG5_pMesh mesh, MMG5_int kel)
MMG5_xTetra * MMG5_pxTetra
int MMG5_isLevelSet(MMG5_pMesh mesh, MMG5_int ref0, MMG5_int ref1)
int MMG5_isNotSplit(MMG5_pMesh mesh, MMG5_int ref)
static int MMG5_isbr(MMG5_pMesh mesh, MMG5_int ref)
int MMG5_isSplit(MMG5_pMesh mesh, MMG5_int ref, MMG5_int *refint, MMG5_int *refext)
int MMG5_getStartRef(MMG5_pMesh mesh, MMG5_int ref, MMG5_int *pref)
int MMG3D_ismaniball(MMG5_pMesh mesh, MMG5_pSol sol, MMG5_int k, int indp)
int MMG3D_update_xtetra(MMG5_pMesh mesh)
int MMG3D_chkmanicoll(MMG5_pMesh mesh, MMG5_int k, int iface, int iedg, MMG5_int ndepmin, MMG5_int ndepplus, MMG5_int refmin, MMG5_int refplus, int8_t isminp, int8_t isplp)
int MMG3D_chkmaniball(MMG5_pMesh mesh, MMG5_int start, int8_t ip)
int MMG3D_chkmani2(MMG5_pMesh mesh, MMG5_pSol sol)
int MMG3D_setref_ls(MMG5_pMesh mesh, MMG5_pSol sol)
int MMG3D_chkmani(MMG5_pMesh mesh)
int MMG3D_mmg3d2(MMG5_pMesh mesh, MMG5_pSol sol, MMG5_pSol met)
int MMG3D_cuttet_ls(MMG5_pMesh mesh, MMG5_pSol sol, MMG5_pSol met)
static double MMG3D_vfrac_1vertex(MMG5_pPoint ppt[4], int8_t i0, double v[4], int8_t part_opp)
int MMG3D_rmc(MMG5_pMesh mesh, MMG5_pSol sol)
static int MMG5_invsl(double A[3][3], double b[3], double r[3])
int MMG3D_snpval_ls(MMG5_pMesh mesh, MMG5_pSol sol)
int MMG3D_resetRef_ls(MMG5_pMesh mesh)
double MMG3D_vfrac(MMG5_pMesh mesh, MMG5_pSol sol, MMG5_int k, int pm)
#define MMG5_SAFE_CALLOC(ptr, size, type, law)
#define MMG5_INCREASE_MEM_MESSAGE()
#define MG_CLR(flag, bit)
#define MMG5_ADD_MEM(mesh, size, message, law)
#define MMG5_SAFE_REALLOC(ptr, prevSize, newSize, type, message, law)
static const uint8_t MMG5_iprv2[3]
double MMG5_det4pt(double c0[3], double c1[3], double c2[3], double c3[3])
#define MMG5_TAB_RECALLOC(mesh, ptr, initSize, wantedGap, type, message, law)
static const uint8_t MMG5_inxt2[6]
double MMG5_orvol(MMG5_pPoint point, MMG5_int *v)
#define MMG5_DEL_MEM(mesh, ptr)
#define MG_SET(flag, bit)
#define MMG5_SAFE_RECALLOC(ptr, prevSize, newSize, type, message, law)
Identic as MMG5_HGeom but use MMG5_hedge to store edges instead of MMG5_hgeom (memory economy).
Structure to store vertices of an MMG mesh.
Structure to store additional information for the surface tetrahedra of an MMG mesh.