Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
mmg3d3.c
Go to the documentation of this file.
1/* =============================================================================
2** This file is part of the mmg software package for the tetrahedral
3** mesh modification.
4** Copyright (c) Bx INP/CNRS/Inria/UBordeaux/UPMC, 2004-
5**
6** mmg is free software: you can redistribute it and/or modify it
7** under the terms of the GNU Lesser General Public License as published
8** by the Free Software Foundation, either version 3 of the License, or
9** (at your option) any later version.
10**
11** mmg is distributed in the hope that it will be useful, but WITHOUT
12** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13** FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14** License for more details.
15**
16** You should have received a copy of the GNU Lesser General Public
17** License and of the GNU General Public License along with mmg (in
18** files COPYING.LESSER and COPYING). If not, see
19** <http://www.gnu.org/licenses/>. Please read their terms carefully and
20** use this copy of the mmg distribution only if you accept them.
21** =============================================================================
22*/
23
36#include "libmmg3d.h"
37#include "libmmg3d_private.h"
40
41#define MMG5_DEGTOL 1.e-1
42
43extern int8_t ddb;
44
47 MMG5_pTetra pt;
48 MMG5_pPoint p1,p2;
49 MMG5_int k,na;
50 double len,lent,dna;
51 int8_t i,i1,i2;
52
53 na = 0;
54 lent = 0.0;
55
56 for (k=1; k<=mesh->ne; k++) {
57 pt = &mesh->tetra[k];
58 for (i=0; i<6; i++) {
59 i1 = MMG5_iare[i][0];
60 i2 = MMG5_iare[i][1];
61
62 p1 = &mesh->point[pt->v[i1]];
63 p2 = &mesh->point[pt->v[i2]];
64
65 len = (p2->c[0] - p1->c[0])*(p2->c[0] - p1->c[0])
66 + (p2->c[1] - p1->c[1])*(p2->c[1] - p1->c[1])
67 + (p2->c[2] - p1->c[2])*(p2->c[2] - p1->c[2]);
68
69 lent += sqrt(len);
70 na++;
71 }
72 }
73
74 dna = (double)na;
75 dna = 1.0 / dna;
76 lent *= dna;
77
78 return lent;
79}
80
82static
83inline int MMG5_intdispvol(double *v1, double *v2, double *vp, double t) {
84 int8_t i;
85
86 for(i=0; i<3; i++)
87 vp[i] = (1.0-t)*v1[i] + t*v2[i];
88
89 return 1;
90}
91
104static MMG5_int MMG5_spllag(MMG5_pMesh mesh,MMG5_pSol disp,MMG5_pSol met,int itdeg, int* warn) {
105 MMG5_pTetra pt;
106 MMG5_pxTetra pxt;
107 MMG5_pPoint p0,p1;
108 double len,lmax,o[3],hma2;
109 double *m1,*m2,*mp;
110 int ilist,ier;
111 MMG5_int src,ns,k,ip,ip1,ip2,iadr;
112 int64_t list[MMG3D_LMAX+2];
113 int8_t imax,i,i1,i2;
114 static int8_t mmgWarn0 = 0;
115
116 *warn=0;
117 ns = 0;
118 hma2 = mesh->info.hmax*mesh->info.hmax;
119
120 for (k=1; k<=mesh->ne; k++) {
121 pt = &mesh->tetra[k];
122 pxt = pt->xt ? &mesh->xtetra[pt->xt] : NULL;
123
124 if ( !MG_EOK(pt) || (pt->tag & MG_REQ) ) continue;
125 if ( pt->mark != itdeg ) continue;
126
127 /* find longest, internal edge */
128 imax = -1;
129 lmax = 0.0;
130 for (i=0; i<6; i++) {
131 i1 = MMG5_iare[i][0];
132 i2 = MMG5_iare[i][1];
133 ip1 = pt->v[i1];
134 ip2 = pt->v[i2];
135 p0 = &mesh->point[ip1];
136 p1 = &mesh->point[ip2];
137
138 /* Skip the non-internal edges */
139
140 // Fast check but incomplete: regular boundary edges may have no tags (bdy
141 // tags are not added at new edges created during the split of boudary
142 // faces for example).
143 if ( pxt && (pxt->tag[i] & MG_BDY) ) continue;
144
145 // Slower test but allowing to be sure to detect boundary edges
146 uint16_t tag = 0;
147 MMG5_int ref = 0;
148 if ( !MMG3D_get_shellEdgeTag(mesh,k,i,&tag,&ref) ) {
149 fprintf(stderr,"\n ## Warning: %s: 0. unable to get edge info"
150 " (tetra %" MMG5_PRId").\n",__func__,MMG3D_indElt(mesh,k));
151 continue;
152 }
153
154 if ( tag & MG_BDY ) {
155 continue;
156 }
157
158 /* Here we are sure to work on a non-boundary edge */
159 len = (p1->c[0]-p0->c[0])*(p1->c[0]-p0->c[0])
160 + (p1->c[1]-p0->c[1])*(p1->c[1]-p0->c[1])
161 + (p1->c[2]-p0->c[2])*(p1->c[2]-p0->c[2]);
162
163 if ( len > lmax ) {
164 lmax = len;
165 imax = i;
166 }
167 }
168
169 if ( imax==-1 ) {
170 if ( !mmgWarn0 ){
171 mmgWarn0 = 1;
172 fprintf(stderr,"\n ## Warning: %s: No possible edge split in tetra %" MMG5_PRId
173 ".\n",__func__,MMG3D_indElt(mesh,k));
174 }
175 continue;
176 }
177
178 if ( lmax < hma2 ) continue;
179
180 /* proceed edges according to lengths */
181 i1 = MMG5_iare[imax][0];
182 i2 = MMG5_iare[imax][1];
183 ip1 = pt->v[i1];
184 ip2 = pt->v[i2];
185 p0 = &mesh->point[ip1];
186 p1 = &mesh->point[ip2];
187
188 /* Deal only with internal faces */
189 int8_t isbdy;
190 ilist = MMG5_coquil(mesh,k,imax,list,&isbdy);
191
192 if ( !ilist ) continue;
193 else if ( ilist<0 ) return -1;
194 else if ( isbdy ) {
195 /* Skip bdy edges */
196 continue;
197 }
198
199#ifndef NDEBUG
200 if ( pxt ) {
201 assert( !(pxt->tag[imax] & MG_BDY) ); }
202#endif
203
204 o[0] = 0.5*(p0->c[0] + p1->c[0]);
205 o[1] = 0.5*(p0->c[1] + p1->c[1]);
206 o[2] = 0.5*(p0->c[2] + p1->c[2]);
207
208#ifdef USE_POINTMAP
209 src = p0->src;
210#else
211 src = 1;
212#endif
213 ip = MMG3D_newPt(mesh,o,MG_NOTAG,src);
214
215 if ( !ip ) {
216 /* reallocation of point table */
217 MMG5_int oldnpmax = mesh->npmax;
218 MMG3D_POINT_REALLOC(mesh,met,ip,mesh->gap,*warn=1;break,o,MG_NOTAG,src);
219 if( disp->m ) {
220 MMG5_ADD_MEM(mesh,(disp->size*(mesh->npmax-disp->npmax))*sizeof(double),
221 "larger displacement",
223 mesh->memCur -= (mesh->npmax - oldnpmax)*sizeof(MMG5_Point);
224 mesh->npmax = oldnpmax;
225 mesh->np = mesh->npmax-1;
226 mesh->npnil = 0;
227 break);
228 MMG5_SAFE_REALLOC(disp->m,disp->size*(disp->npmax+1),
229 disp->size*(mesh->npmax+1),
230 double,"larger displacement",
232 mesh->memCur -= (mesh->npmax - oldnpmax)*sizeof(MMG5_Point);
233 mesh->npmax = oldnpmax;
234 mesh->np = mesh->npmax-1;
235 mesh->npnil = 0;
236 break);
237 }
238 disp->npmax = mesh->npmax;
239 }
240
241 /* Interpolation of metric, if any */
242 if ( met->m ) {
243 if ( !MMG5_intmet(mesh,met,k,imax,ip,0.5) ) {
244 MMG3D_delPt(mesh,ip);
245 return -1;
246 }
247 }
248
249 /* Interpolation of displacement */
250 if ( disp->m ) {
251 iadr = disp->size*ip1;
252 m1 = &disp->m[iadr];
253 iadr = disp->size*ip2;
254 m2 = &disp->m[iadr];
255 iadr = disp->size*ip;
256 mp = &disp->m[iadr];
257
258 if ( !MMG5_intdispvol(m1,m2,mp,0.5) ) {
259 MMG3D_delPt(mesh,ip);
260 return -1;
261 }
262 }
263
264 /* Il y a un check sur la taille des arĂȘtes ici aussi ! */
265 ier = MMG5_split1b(mesh,met,list,ilist,ip,1,1,0);
266 if ( ier < 0 ) {
267 fprintf(stderr,"\n ## Error: %s: unable to split.\n",__func__);
268 return -1;
269 }
270 else if ( !ier ) {
271 MMG3D_delPt(mesh,ip);
272 }
273 else {
274 ns++;
275 }
276 }
277
278 return ns;
279}
280
294MMG5_int MMG5_swptetlag(MMG5_pMesh mesh,MMG5_pSol met,double crit,MMG3D_pPROctree PROctree,int itdeg) {
295 MMG5_pTetra pt;
296 MMG5_pxTetra pxt;
297 int ilist,it,maxit,ier;
298 MMG5_int k,nconf,ns,nns;
299 int64_t list[MMG3D_LMAX+2];
300 int8_t i;
301
302 maxit = 2;
303 it = nns = 0;
304
305 do {
306 ns = 0;
307 for (k=1; k<=mesh->ne; k++) {
308 pt = &mesh->tetra[k];
309 if ( !MG_EOK(pt) || (pt->tag & MG_REQ) ) continue;
310 if ( pt->mark != itdeg ) continue;
311
312 for (i=0; i<6; i++) {
313 /* Prevent swap of a ref or tagged edge */
314 if ( pt->xt ) {
315 pxt = &mesh->xtetra[pt->xt];
316 if ( pxt->edg[i] || pxt->tag[i] ) continue;
317 }
318
319 nconf = MMG5_chkswpgen(mesh,met,k,i,&ilist,list,crit,2);
320
321 if ( nconf<0 ) return -1;
322 else if ( nconf ) {
323 ier = MMG5_swpgen(mesh,met,nconf,ilist,list,PROctree,2);
324 if ( ier > 0 ) ns++;
325 else if ( ier < 0 ) return -1;
326 break;
327 }
328 }
329 }
330 nns += ns;
331 }
332 while ( ++it < maxit && ns > 0 );
333 return nns;
334}
335
345MMG5_int MMG5_movtetlag(MMG5_pMesh mesh,MMG5_pSol met, int itdeg) {
346 MMG5_pTetra pt;
347 MMG5_pPoint ppt;
348 int ier,ilistv,it;
349 MMG5_int k,nm,nnm,base;
350 int64_t listv[MMG3D_LMAX+2];
351 uint8_t i;
352 int maxit;
353
354 base = 1;
355 for (k=1; k<=mesh->np; k++)
356 mesh->point[k].flag = base;
357
358 maxit = 2;
359 it = nnm = 0;
360
361 do {
362 base++;
363 nm = 0;
364 for (k=1; k<=mesh->ne; k++) {
365 pt = &mesh->tetra[k];
366 if ( !MG_EOK(pt) || pt->ref < 0 || (pt->tag & MG_REQ) ) continue;
367 if ( pt->mark != itdeg ) continue;
368
369 /* point i */
370 for (i=0; i<4; i++) {
371 ppt = &mesh->point[pt->v[i]];
372 if ( ppt->flag == base ) continue;
373 else if ( ppt->tag & MG_BDY ) continue;
374
375 ilistv = MMG5_boulevolp(mesh,k,i,listv);
376 if ( !ilistv ) continue;
377
378 ier = MMG5_movintpt_iso(mesh,met, NULL, listv,ilistv,0);
379
380 if ( ier ) {
381 nm++;
382 ppt->flag = base;
383
384 /* Somehow interpolate displacement ? */
385 }
386 }
387 }
388 nnm += nm;
389 }
390 while( ++it < maxit && nm > 0 );
391
392 return nnm;
393}
394
405static MMG5_int MMG5_coltetlag(MMG5_pMesh mesh,MMG5_pSol met,int itdeg) {
406 MMG5_pTetra pt;
407 MMG5_pPoint p0,p1;
408 double ll,ux,uy,uz,hmi2;
409 int ilist;
410 int64_t list[MMG3D_LMAX+2];
411 MMG5_int k,nc,nnm,base;
412 int ier;
413 int8_t i,j,ip,iq,isnm;
414 int16_t tag0, tag1;
415
416 nc = nnm = 0;
417 hmi2 = mesh->info.hmin*mesh->info.hmin;
418
419 /* init of point flags, otherwise it can be uninitialized */
420 for (k=1; k<=mesh->np; k++)
421 mesh->point[k].flag = 0;
422
423 for (k=1; k<=mesh->ne; k++) {
424 base = ++mesh->base;
425 pt = &mesh->tetra[k];
426 if ( !MG_EOK(pt) || (pt->tag & MG_REQ) ) continue;
427 if ( pt->mark != itdeg ) continue;
428
429 for (i=0; i<4; i++) {
430 ier = 0;
431 for (j=0; j<3; j++) {
432 ip = MMG5_idir[i][MMG5_inxt2[j]];
433 iq = MMG5_idir[i][MMG5_iprv2[j]];
434 assert( 0<=ip && ip<4 && "unexpected local index for vertex");
435 assert( 0<=iq && iq<4 && "unexpected local index for vertex");
436
437 p0 = &mesh->point[pt->v[ip]];
438 p1 = &mesh->point[pt->v[iq]];
439 tag0 = p0->tag & ~MG_OLDPARBDY;
440 tag1 = p1->tag & ~MG_OLDPARBDY;
441 if ( p0->flag == base ) continue;
442 else if ( p0->tag & MG_BDY ) continue;
443 else if ( (p0->tag & MG_REQ) || (tag0 > tag1) ) continue;
444
445 /* check length */
446 ux = p1->c[0] - p0->c[0];
447 uy = p1->c[1] - p0->c[1];
448 uz = p1->c[2] - p0->c[2];
449 ll = ux*ux + uy*uy + uz*uz;
450
451 if ( ll > hmi2 ) continue;
452
453 isnm = 0;
454 ilist = MMG5_boulevolp(mesh,k,ip,list);
455 ilist = MMG5_chkcol_int(mesh,met,k,i,j,list,ilist,2);
456
457 if ( ilist > 0 ) {
458 ier = MMG5_colver(mesh,met,list,ilist,iq,2);
459 if ( ier < 0 ) return -1;
460 else if ( ier ) {
462 break;
463 }
464 }
465 else if ( ilist < 0 ) return -1;
466 }
467 if ( ier ) {
468 p1->flag = base;
469 if ( isnm ) nnm++;
470 nc++;
471 break;
472 }
473 }
474 }
475
476 return nc;
477}
478
492MMG5_int MMG5_chkmovmesh(MMG5_pMesh mesh,MMG5_pSol disp,short t,MMG5_int *tetIdx) {
493 MMG5_pTetra pt;
494 MMG5_pPoint ppt;
495 double *v,c[4][3],tau;
496 MMG5_int k,np;
497 MMG5_int idx;
498 int8_t i,j;
499
500 /* Pseudo time-step = fraction of disp to perform */
501 tau = (double)t / MMG3D_SHORTMAX;
502 idx = 0;
503
504 for (k=1; k<=mesh->ne; k++) {
505 pt = &mesh->tetra[k];
506 if ( !MG_EOK(pt) ) continue;
507
508 for (i=0; i<4; i++) {
509 np = pt->v[i];
510 ppt = &mesh->point[np];
511 v = &disp->m[3*np];
512 for (j=0; j<3; j++)
513 c[i][j] = ppt->c[j]+tau*v[j];
514 }
515
516 // Other criteria : eg. a rate of degradation, etc... ?
517 if( MMG5_caltet_iso_4pt(c[0],c[1],c[2],c[3]) < MMG5_EPSOK) {
518
519 if ( tetIdx ) {
520 tetIdx[idx++] = k;
521 }
522 else {
523 return 1;
524 }
525 }
526 }
527 return idx;
528}
529
531int MMG5_dispmesh(MMG5_pMesh mesh,MMG5_pSol disp,short t,int itdeg) {
532 MMG5_pTetra pt;
533 MMG5_pPoint ppt;
534 double *v,tau,ctau,c[4][3],ocal,ncal;
535 MMG5_int k,np;
536 int8_t i,j;
537
538 tau = (double)t /MMG3D_SHORTMAX;
539 ctau = 1.0 - tau;
540
541 /* Identify elements which are very distorted in the process */
542 for (k=1; k<=mesh->ne; k++) {
543 pt = &mesh->tetra[k];
544 if ( !MG_EOK(pt) ) continue;
545
546 for (i=0; i<4; i++) {
547 np = pt->v[i];
548 ppt = &mesh->point[np];
549 for (j=0; j<3; j++)
550 c[i][j] = ppt->c[j];
551 }
552
553 ocal = MMG5_caltet_iso_4pt(c[0],c[1],c[2],c[3]);
554
555 for (i=0; i<4; i++) {
556 np = pt->v[i];
557 v = &disp->m[3*np];
558 for (j=0; j<3; j++)
559 c[i][j] += tau*v[j];
560 }
561
562 ncal = MMG5_caltet_iso_4pt(c[0],c[1],c[2],c[3]);
563
564 if ( ncal < MMG5_DEGTOL*ocal )
565 pt->mark = itdeg;
566
567 }
568
569 /* Perform physical displacement */
570 for (k=1; k<=mesh->np; k++) {
571 ppt = &mesh->point[k];
572
573 if ( !MG_VOK(ppt) ) continue;
574 v = &disp->m[3*k];
575
576 for (i=0; i<3; i++) {
577 ppt->c[i] = ppt->c[i] + tau*v[i];
578 v[i] *= ctau;
579 }
580 }
581
582 return 1;
583}
584
585
602int MMG5_mmg3d3(MMG5_pMesh mesh,MMG5_pSol disp,MMG5_pSol met,MMG5_int **invalidTets) {
603 double avlen,tau,hmintmp,hmaxtmp;
604 int itdc,itmn,maxitmn,maxitdc,iit,warn;
605 MMG5_int nspl,ns,nm,nc,k;
606 MMG5_int nns,nnm,nnc,nnspl,nnns,nnnm,nnnc,nnnspl;
607 MMG5_int ninvalidTets;
608 short t,lastt;
609 int8_t ier;
610
611 maxitmn = 10;
612 maxitdc = 100;
613 t = 0;
614 tau = 0.0;
615 ninvalidTets = 0;
616
617 nnnspl = nnnc = nnns = nnnm = lastt = 0;
618
619 if ( abs(mesh->info.imprim) > 4 || mesh->info.ddebug )
620 fprintf(stdout," ** LAGRANGIAN MOTION\n");
621
622 /* Field mark stores information about whether a tetra has been greatly deformed during current step */
623 for (k=1; k<=mesh->ne; k++)
624 mesh->tetra[k].mark = 0;
625
626 /* Estimates of the minimum and maximum edge lengths in the mesh */
627 avlen = MMG5_estavglen(mesh);
628
629 hmintmp = mesh->info.hmin;
630 hmaxtmp = mesh->info.hmax;
631
632 mesh->info.hmax = MMG3D_LLONG*avlen;
633 mesh->info.hmin = MMG3D_LSHRT*avlen;
634
635 for (itmn=0; itmn<maxitmn; itmn++) {
636
637#ifdef USE_ELAS
638 /* Extension of the displacement field */
639 if ( !MMG5_velextLS(mesh,disp) ) {
640 fprintf(stderr,"\n ## Problem in func. MMG5_velextLS. Exit program.\n");
641 return 0;
642 }
643#else
644 fprintf(stderr,"\n ## Error: %s: you need to compile with the USE_ELAS"
645 " CMake's flag set to ON to use the rigidbody movement.\n",__func__);
646 return 0;
647#endif
648
649 //MMG5_saveDisp(mesh,disp);
650
651 /* Sequence of dichotomy loops to find the largest admissible displacements */
652 for (itdc=0; itdc<maxitdc; itdc++) {
653 nnspl = nnc = nns = nnm = 0;
654
656 if ( t == 0 ) {
657 if ( abs(mesh->info.imprim) > 4 || mesh->info.ddebug )
658 fprintf(stderr,"\n *** Stop: impossible to proceed further\n");
659 break;
660 }
661
662 ier = MMG5_dispmesh(mesh,disp,t,itdc);
663 if ( !ier ) {
664 fprintf(stderr,"\n ** Impossible motion\n");
665 return 0;
666 }
667
668 tau = tau + ((double)t /MMG3D_SHORTMAX)*(1.0-tau);
669 if ( (abs(mesh->info.imprim) > 3 ) || mesh->info.ddebug )
670 printf(" ---> Realized displacement: %f\n",tau);
671
672 /* Local remeshing depending on the option */
673 if ( mesh->info.lag > 0 ) {
674 for ( iit=0; iit<5; iit++) {
675
676 nspl = nc = ns = nm = 0;
677
678 if ( mesh->info.lag > 1 ) {
679 if ( !mesh->info.noinsert ) {
680 /* Split of points */
681 nspl = MMG5_spllag(mesh,disp,met,itdc,&warn);
682 if ( nspl < 0 ) {
683 fprintf(stderr,"\n ## Problem in spllag. Exiting.\n");
684 return 0;
685 }
686
687 /* Collapse of points */
688 nc = MMG5_coltetlag(mesh,met,itdc);
689 if ( nc < 0 ) {
690 fprintf(stderr,"\n ## Problem in coltetlag. Exiting.\n");
691 return 0;
692 }
693 }
694 }
695
696 /* Swap of edges in tetra that have resulted distorted from the process */
697 /* I do not know whether it is safe to put NULL in metric here (a
698 * priori ok, since there is no vertex creation or suppression) */
699 if ( !mesh->info.noswap ) {
700 ns = MMG5_swptetlag(mesh,met,MMG3D_LSWAPIMPROVE,NULL,itdc);
701 if ( ns < 0 ) {
702 fprintf(stderr,"\n ## Problem in swaptetlag. Exiting.\n");
703 return 0;
704 }
705 }
706
707 /* Relocate vertices of tetra which have been distorted in the displacement process */
708 nm = MMG5_movtetlag(mesh,met,itdc);
709 if ( nm < 0 ) {
710 fprintf(stderr,"\n ## Problem in movtetlag. Exiting.\n");
711 return 0;
712 }
713
714 if ( (abs(mesh->info.imprim) > 4 || mesh->info.ddebug) && (nspl+nc+ns+nm > 0) )
715 printf(" %" MMG5_PRId " edges splitted, %" MMG5_PRId " vertices collapsed, %" MMG5_PRId " elements"
716 " swapped, %" MMG5_PRId " vertices moved.\n",nspl,nc,ns,nm);
717 nnspl+= nspl;
718 nnm += nm;
719 nnc += nc;
720 nns += ns;
721 }
722 /* Five iterations of local remeshing have been performed: print final stats */
723 if ( abs(mesh->info.imprim) > 3 && abs(mesh->info.imprim) < 5 && (nnspl+nnm+nns+nnc > 0) )
724 printf(" %" MMG5_PRId " edges splitted, %" MMG5_PRId " vertices collapsed, %" MMG5_PRId " elements"
725 " swapped, %" MMG5_PRId " vertices moved.\n",nnspl,nnc,nns,nnm);
726 }
727
728 nnnspl += nnspl;
729 nnnm += nnm;
730 nnnc += nnc;
731 nnns += nns;
732
733 if ( t == MMG3D_SHORTMAX ) break;
734 }
735
736 /* End of dichotomy loop: maximal displacement of the extended velocity
737 * field has been performed */
738 if ( mesh->info.imprim > 1 && abs(mesh->info.imprim) < 4 ) {
739 printf(" ---> Realized displacement: %f\n",tau);
740 }
741
742 if ( abs(mesh->info.imprim) > 2 && mesh->info.lag )
743 printf(" %"MMG5_PRId" edges splitted, %"MMG5_PRId" vertices collapsed,"
744 " %"MMG5_PRId" elements swapped, %"MMG5_PRId" vertices moved.\n",
745 nnnspl,nnnc,nnns,nnnm);
746
747 if ( t == MMG3D_SHORTMAX || (t==0 && itdc==0) ) break;
748 }
749
750 /* Reinsert standard values for hmin, hmax */
751 mesh->info.hmin = hmintmp;
752 mesh->info.hmax = hmaxtmp;
753
754 if ( tau < MMG5_EPSD2 ) {
755 MMG5_SAFE_CALLOC(*invalidTets,mesh->np,MMG5_int,
756 printf("## Warning: Not enough memory to keep track of"
757 " the invalid tetrahedron.\n");
758 MMG5_DEL_MEM(mesh,disp->m);
759 return 1);
760 ninvalidTets = MMG5_chkmovmesh(mesh,disp,lastt,*invalidTets);
761 assert ( ninvalidTets );
762 }
763
764 /* Clean memory */
765 /* Doing this, memcur of mesh is decreased by size of displacement */
766 MMG5_DEL_MEM(mesh,disp->m);
767
768 if ( ninvalidTets ) {
769 return -ninvalidTets;
770 }
771 else {
772 return 1;
773 }
774}
int ier
MMG5_pMesh * mesh
int MMG5_boulevolp(MMG5_pMesh mesh, MMG5_int start, int ip, int64_t *list)
Given a vertex and a tetrahedron, find all tetrahedra in the ball of this vertex.
Definition: boulep_3d.c:57
int MMG5_coquil(MMG5_pMesh mesh, MMG5_int start, int ia, int64_t *list, int8_t *isbdy)
Definition: boulep_3d.c:1406
int MMG3D_get_shellEdgeTag(MMG5_pMesh mesh, MMG5_int start, int8_t ia, uint16_t *tag, MMG5_int *ref)
Definition: colver_3d.c:439
MMG5_int MMG5_colver(MMG5_pMesh mesh, MMG5_pSol met, int64_t *list, int ilist, int8_t indq, int8_t typchk)
Definition: colver_3d.c:1154
int MMG5_chkcol_int(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k, int8_t iface, int8_t iedg, int64_t *list, int ilist, int8_t typchk)
Definition: colver_3d.c:43
static double MMG5_caltet_iso_4pt(double *a, double *b, double *c, double *d)
API headers and documentation for the mmg3d library, for volumetric meshes in 3D.
#define MMG3D_LMAX
Definition: libmmg3d.h:130
int MMG5_split1b(MMG5_pMesh, MMG5_pSol, int64_t *, int, MMG5_int, int, int8_t, int8_t)
Definition: split_3d.c:629
MMG5_int MMG5_chkswpgen(MMG5_pMesh, MMG5_pSol, MMG5_int, int, int *, int64_t *, double, int8_t)
Definition: swapgen_3d.c:57
int MMG5_velextLS(MMG5_pMesh, MMG5_pSol)
Definition: velextls_3d.c:393
void MMG3D_delPt(MMG5_pMesh mesh, MMG5_int ip)
Definition: zaldy_3d.c:80
MMG5_int MMG3D_newPt(MMG5_pMesh mesh, double c[3], uint16_t tag, MMG5_int src)
Definition: zaldy_3d.c:39
#define MMG3D_SHORTMAX
int MMG5_swpgen(MMG5_pMesh, MMG5_pSol, MMG5_int, int, int64_t *, MMG3D_pPROctree, int8_t)
Definition: swapgen_3d.c:271
static const uint8_t MMG5_iare[6][2]
vertices of extremities of the edges of the tetra
#define MMG3D_POINT_REALLOC(mesh, sol, ip, wantedGap, law, o, tag, src)
int MMG5_movintpt_iso(MMG5_pMesh, MMG5_pSol, MMG3D_pPROctree, int64_t *, int, int)
Definition: movpt_3d.c:58
#define MMG3D_LSWAPIMPROVE
static const uint8_t MMG5_idir[4][3]
idir[i]: vertices of face opposite to vertex i
#define MMG3D_LLONG
MMG5_int MMG3D_indElt(MMG5_pMesh mesh, MMG5_int kel)
Definition: tools_3d.c:862
#define MMG3D_LSHRT
short MMG5_dikmov(MMG5_pMesh mesh, MMG5_pSol disp, short *lastt, short shortmax, MMG5_int chkmovmesh(MMG5_pMesh, MMG5_pSol, short, MMG5_int *))
common functions for lagrangian meshing.
Definition: mmg3.c:49
static int MMG5_intdispvol(double *v1, double *v2, double *vp, double t)
Definition: mmg3d3.c:83
static MMG5_int MMG5_spllag(MMG5_pMesh mesh, MMG5_pSol disp, MMG5_pSol met, int itdeg, int *warn)
Definition: mmg3d3.c:104
int MMG5_dispmesh(MMG5_pMesh mesh, MMG5_pSol disp, short t, int itdeg)
Definition: mmg3d3.c:531
static MMG5_int MMG5_coltetlag(MMG5_pMesh mesh, MMG5_pSol met, int itdeg)
Definition: mmg3d3.c:405
MMG5_int MMG5_chkmovmesh(MMG5_pMesh mesh, MMG5_pSol disp, short t, MMG5_int *tetIdx)
Definition: mmg3d3.c:492
MMG5_int MMG5_swptetlag(MMG5_pMesh mesh, MMG5_pSol met, double crit, MMG3D_pPROctree PROctree, int itdeg)
Definition: mmg3d3.c:294
#define MMG5_DEGTOL
Definition: mmg3d3.c:41
double MMG5_estavglen(MMG5_pMesh mesh)
Definition: mmg3d3.c:46
int8_t ddb
Definition: mmg3d1_delone.c:42
MMG5_int MMG5_movtetlag(MMG5_pMesh mesh, MMG5_pSol met, int itdeg)
Definition: mmg3d3.c:345
int MMG5_mmg3d3(MMG5_pMesh mesh, MMG5_pSol disp, MMG5_pSol met, MMG5_int **invalidTets)
Definition: mmg3d3.c:602
#define MG_REQ
#define MMG5_SAFE_CALLOC(ptr, size, type, law)
#define MMG5_EPSOK
#define MG_EOK(pt)
#define MMG5_ADD_MEM(mesh, size, message, law)
#define MMG5_SAFE_REALLOC(ptr, prevSize, newSize, type, message, law)
#define MG_NOTAG
static const uint8_t MMG5_iprv2[3]
static const uint8_t MMG5_inxt2[6]
#define MG_VOK(ppt)
#define MG_BDY
#define MMG5_EPSD2
#define MMG5_DEL_MEM(mesh, ptr)
#define MMG5_SAFE_RECALLOC(ptr, prevSize, newSize, type, message, law)
int8_t ddebug
Definition: libmmgtypes.h:539
uint8_t noswap
Definition: libmmgtypes.h:553
double hmin
Definition: libmmgtypes.h:525
uint8_t noinsert
Definition: libmmgtypes.h:553
double hmax
Definition: libmmgtypes.h:525
int8_t lag
Definition: libmmgtypes.h:547
MMG mesh structure.
Definition: libmmgtypes.h:613
size_t memCur
Definition: libmmgtypes.h:615
MMG5_Info info
Definition: libmmgtypes.h:659
MMG5_int ne
Definition: libmmgtypes.h:620
MMG5_pPoint point
Definition: libmmgtypes.h:649
MMG5_int npmax
Definition: libmmgtypes.h:620
double gap
Definition: libmmgtypes.h:616
MMG5_int base
Definition: libmmgtypes.h:624
MMG5_pTetra tetra
Definition: libmmgtypes.h:651
MMG5_int np
Definition: libmmgtypes.h:620
MMG5_pxTetra xtetra
Definition: libmmgtypes.h:652
MMG5_int npnil
Definition: libmmgtypes.h:629
Structure to store vertices of an MMG mesh.
Definition: libmmgtypes.h:276
double c[3]
Definition: libmmgtypes.h:277
uint16_t tag
Definition: libmmgtypes.h:290
MMG5_int flag
Definition: libmmgtypes.h:288
MMG5_int npmax
Definition: libmmgtypes.h:675
double * m
Definition: libmmgtypes.h:680
Structure to store tetrahedra of an MMG mesh.
Definition: libmmgtypes.h:407
MMG5_int v[4]
Definition: libmmgtypes.h:409
MMG5_int xt
Definition: libmmgtypes.h:413
MMG5_int ref
Definition: libmmgtypes.h:410
MMG5_int mark
Definition: libmmgtypes.h:412
uint16_t tag
Definition: libmmgtypes.h:417
Structure to store additional information for the surface tetrahedra of an MMG mesh.
Definition: libmmgtypes.h:425
uint16_t tag[6]
Definition: libmmgtypes.h:432
MMG5_int edg[6]
Definition: libmmgtypes.h:428