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 if ( pxt && (pxt->tag[i] & MG_BDY) ) continue;
140
141
142 if( (p0->tag & MG_BDY) && (p1->tag & MG_BDY) ) continue;
143
144 len = (p1->c[0]-p0->c[0])*(p1->c[0]-p0->c[0])
145 + (p1->c[1]-p0->c[1])*(p1->c[1]-p0->c[1])
146 + (p1->c[2]-p0->c[2])*(p1->c[2]-p0->c[2]);
147
148 if ( len > lmax ) {
149 lmax = len;
150 imax = i;
151 }
152 }
153 if ( imax==-1 ) {
154 if ( !mmgWarn0 ){
155 mmgWarn0 = 1;
156 fprintf(stderr,"\n ## Warning: %s: all edges of tetra %" MMG5_PRId " are required"
157 " or of length null.\n",__func__,k);
158 }
159 continue;
160 }
161
162 if ( lmax < hma2 ) continue;
163
164 /* proceed edges according to lengths */
165 i1 = MMG5_iare[imax][0];
166 i2 = MMG5_iare[imax][1];
167 ip1 = pt->v[i1];
168 ip2 = pt->v[i2];
169 p0 = &mesh->point[ip1];
170 p1 = &mesh->point[ip2];
171
172 /* Deal only with internal faces */
173 int8_t isbdy;
174 ilist = MMG5_coquil(mesh,k,imax,list,&isbdy);
175
176 if ( !ilist ) continue;
177 else if ( ilist<0 ) return -1;
178 else if ( isbdy ) {
179 /* Skip bdy edges */
180 continue;
181 }
182
183#ifndef NDEBUG
184 if ( pxt ) {
185 assert( !(pxt->tag[imax] & MG_BDY) ); }
186#endif
187
188 o[0] = 0.5*(p0->c[0] + p1->c[0]);
189 o[1] = 0.5*(p0->c[1] + p1->c[1]);
190 o[2] = 0.5*(p0->c[2] + p1->c[2]);
191
192#ifdef USE_POINTMAP
193 src = p0->src;
194#else
195 src = 1;
196#endif
197 ip = MMG3D_newPt(mesh,o,MG_NOTAG,src);
198
199 if ( !ip ) {
200 /* reallocation of point table */
201 MMG5_int oldnpmax = mesh->npmax;
202 MMG3D_POINT_REALLOC(mesh,met,ip,mesh->gap,*warn=1;break,o,MG_NOTAG,src);
203 if( disp->m ) {
204 MMG5_ADD_MEM(mesh,(disp->size*(mesh->npmax-disp->npmax))*sizeof(double),
205 "larger displacement",
207 mesh->memCur -= (mesh->npmax - oldnpmax)*sizeof(MMG5_Point);
208 mesh->npmax = oldnpmax;
209 mesh->np = mesh->npmax-1;
210 mesh->npnil = 0;
211 break);
212 MMG5_SAFE_REALLOC(disp->m,disp->size*(disp->npmax+1),
213 disp->size*(mesh->npmax+1),
214 double,"larger displacement",
216 mesh->memCur -= (mesh->npmax - oldnpmax)*sizeof(MMG5_Point);
217 mesh->npmax = oldnpmax;
218 mesh->np = mesh->npmax-1;
219 mesh->npnil = 0;
220 break);
221 }
222 disp->npmax = mesh->npmax;
223 }
224
225 /* Interpolation of metric, if any */
226 if ( met->m ) {
227 if ( !MMG5_intmet(mesh,met,k,imax,ip,0.5) ) {
228 MMG3D_delPt(mesh,ip);
229 return -1;
230 }
231 }
232
233 /* Interpolation of displacement */
234 if ( disp->m ) {
235 iadr = disp->size*ip1;
236 m1 = &disp->m[iadr];
237 iadr = disp->size*ip2;
238 m2 = &disp->m[iadr];
239 iadr = disp->size*ip;
240 mp = &disp->m[iadr];
241
242 if ( !MMG5_intdispvol(m1,m2,mp,0.5) ) {
243 MMG3D_delPt(mesh,ip);
244 return -1;
245 }
246 }
247
248 /* Il y a un check sur la taille des arĂȘtes ici aussi ! */
249 ier = MMG5_split1b(mesh,met,list,ilist,ip,1,1,0);
250 if ( ier < 0 ) {
251 fprintf(stderr,"\n ## Error: %s: unable to split.\n",__func__);
252 return -1;
253 }
254 else if ( !ier ) {
255 MMG3D_delPt(mesh,ip);
256 }
257 else {
258 ns++;
259 }
260 }
261
262 return ns;
263}
264
278MMG5_int MMG5_swptetlag(MMG5_pMesh mesh,MMG5_pSol met,double crit,MMG3D_pPROctree PROctree,int itdeg) {
279 MMG5_pTetra pt;
280 MMG5_pxTetra pxt;
281 int ilist,it,maxit,ier;
282 MMG5_int k,nconf,ns,nns;
283 int64_t list[MMG3D_LMAX+2];
284 int8_t i;
285
286 maxit = 2;
287 it = nns = 0;
288
289 do {
290 ns = 0;
291 for (k=1; k<=mesh->ne; k++) {
292 pt = &mesh->tetra[k];
293 if ( !MG_EOK(pt) || (pt->tag & MG_REQ) ) continue;
294 if ( pt->mark != itdeg ) continue;
295
296 for (i=0; i<6; i++) {
297 /* Prevent swap of a ref or tagged edge */
298 if ( pt->xt ) {
299 pxt = &mesh->xtetra[pt->xt];
300 if ( pxt->edg[i] || pxt->tag[i] ) continue;
301 }
302
303 nconf = MMG5_chkswpgen(mesh,met,k,i,&ilist,list,crit,2);
304
305 if ( nconf<0 ) return -1;
306 else if ( nconf ) {
307 ier = MMG5_swpgen(mesh,met,nconf,ilist,list,PROctree,2);
308 if ( ier > 0 ) ns++;
309 else if ( ier < 0 ) return -1;
310 break;
311 }
312 }
313 }
314 nns += ns;
315 }
316 while ( ++it < maxit && ns > 0 );
317 return nns;
318}
319
329MMG5_int MMG5_movtetlag(MMG5_pMesh mesh,MMG5_pSol met, int itdeg) {
330 MMG5_pTetra pt;
331 MMG5_pPoint ppt;
332 int ier,ilistv,it;
333 MMG5_int k,nm,nnm,base;
334 int64_t listv[MMG3D_LMAX+2];
335 uint8_t i;
336 int maxit;
337
338 base = 1;
339 for (k=1; k<=mesh->np; k++)
340 mesh->point[k].flag = base;
341
342 maxit = 2;
343 it = nnm = 0;
344
345 do {
346 base++;
347 nm = 0;
348 for (k=1; k<=mesh->ne; k++) {
349 pt = &mesh->tetra[k];
350 if ( !MG_EOK(pt) || pt->ref < 0 || (pt->tag & MG_REQ) ) continue;
351 if ( pt->mark != itdeg ) continue;
352
353 /* point i */
354 for (i=0; i<4; i++) {
355 ppt = &mesh->point[pt->v[i]];
356 if ( ppt->flag == base ) continue;
357 else if ( ppt->tag & MG_BDY ) continue;
358
359 ilistv = MMG5_boulevolp(mesh,k,i,listv);
360 if ( !ilistv ) continue;
361
362 ier = MMG5_movintpt_iso(mesh,met, NULL, listv,ilistv,0);
363
364 if ( ier ) {
365 nm++;
366 ppt->flag = base;
367
368 /* Somehow interpolate displacement ? */
369 }
370 }
371 }
372 nnm += nm;
373 }
374 while( ++it < maxit && nm > 0 );
375
376 return nnm;
377}
378
389static MMG5_int MMG5_coltetlag(MMG5_pMesh mesh,MMG5_pSol met,int itdeg) {
390 MMG5_pTetra pt;
391 MMG5_pPoint p0,p1;
392 double ll,ux,uy,uz,hmi2;
393 int ilist;
394 int64_t list[MMG3D_LMAX+2];
395 MMG5_int k,nc,nnm,base;
396 int ier;
397 int8_t i,j,ip,iq,isnm;
398
399 nc = nnm = 0;
400 hmi2 = mesh->info.hmin*mesh->info.hmin;
401
402 /* init of point flags, otherwise it can be uninitialized */
403 for (k=1; k<=mesh->np; k++)
404 mesh->point[k].flag = 0;
405
406 for (k=1; k<=mesh->ne; k++) {
407 base = ++mesh->base;
408 pt = &mesh->tetra[k];
409 if ( !MG_EOK(pt) || (pt->tag & MG_REQ) ) continue;
410 if ( pt->mark != itdeg ) continue;
411
412 for (i=0; i<4; i++) {
413 ier = 0;
414 for (j=0; j<3; j++) {
415 ip = MMG5_idir[i][MMG5_inxt2[j]];
416 iq = MMG5_idir[i][MMG5_iprv2[j]];
417 assert( 0<=ip && ip<4 && "unexpected local index for vertex");
418 assert( 0<=iq && iq<4 && "unexpected local index for vertex");
419
420 p0 = &mesh->point[pt->v[ip]];
421 p1 = &mesh->point[pt->v[iq]];
422 if ( p0->flag == base ) continue;
423 else if ( p0->tag & MG_BDY ) continue;
424 else if ( (p0->tag & MG_REQ) || (p0->tag > p1->tag) ) continue;
425
426 /* check length */
427 ux = p1->c[0] - p0->c[0];
428 uy = p1->c[1] - p0->c[1];
429 uz = p1->c[2] - p0->c[2];
430 ll = ux*ux + uy*uy + uz*uz;
431
432 if ( ll > hmi2 ) continue;
433
434 isnm = 0;
435 ilist = MMG5_boulevolp(mesh,k,ip,list);
436 ilist = MMG5_chkcol_int(mesh,met,k,i,j,list,ilist,2);
437
438 if ( ilist > 0 ) {
439 ier = MMG5_colver(mesh,met,list,ilist,iq,2);
440 if ( ier < 0 ) return -1;
441 else if ( ier ) {
443 break;
444 }
445 }
446 else if ( ilist < 0 ) return -1;
447 }
448 if ( ier ) {
449 p1->flag = base;
450 if ( isnm ) nnm++;
451 nc++;
452 break;
453 }
454 }
455 }
456
457 return nc;
458}
459
473MMG5_int MMG5_chkmovmesh(MMG5_pMesh mesh,MMG5_pSol disp,short t,MMG5_int *tetIdx) {
474 MMG5_pTetra pt;
475 MMG5_pPoint ppt;
476 double *v,c[4][3],tau;
477 MMG5_int k,np;
478 MMG5_int idx;
479 int8_t i,j;
480
481 /* Pseudo time-step = fraction of disp to perform */
482 tau = (double)t / MMG3D_SHORTMAX;
483 idx = 0;
484
485 for (k=1; k<=mesh->ne; k++) {
486 pt = &mesh->tetra[k];
487 if ( !MG_EOK(pt) ) continue;
488
489 for (i=0; i<4; i++) {
490 np = pt->v[i];
491 ppt = &mesh->point[np];
492 v = &disp->m[3*np];
493 for (j=0; j<3; j++)
494 c[i][j] = ppt->c[j]+tau*v[j];
495 }
496
497 // Other criteria : eg. a rate of degradation, etc... ?
498 if( MMG5_caltet_iso_4pt(c[0],c[1],c[2],c[3]) < MMG5_EPSOK) {
499
500 if ( tetIdx ) {
501 tetIdx[idx++] = k;
502 }
503 else {
504 return 1;
505 }
506 }
507 }
508 return idx;
509}
510
512int MMG5_dispmesh(MMG5_pMesh mesh,MMG5_pSol disp,short t,int itdeg) {
513 MMG5_pTetra pt;
514 MMG5_pPoint ppt;
515 double *v,tau,ctau,c[4][3],ocal,ncal;
516 MMG5_int k,np;
517 int8_t i,j;
518
519 tau = (double)t /MMG3D_SHORTMAX;
520 ctau = 1.0 - tau;
521
522 /* Identify elements which are very distorted in the process */
523 for (k=1; k<=mesh->ne; k++) {
524 pt = &mesh->tetra[k];
525 if ( !MG_EOK(pt) ) continue;
526
527 for (i=0; i<4; i++) {
528 np = pt->v[i];
529 ppt = &mesh->point[np];
530 for (j=0; j<3; j++)
531 c[i][j] = ppt->c[j];
532 }
533
534 ocal = MMG5_caltet_iso_4pt(c[0],c[1],c[2],c[3]);
535
536 for (i=0; i<4; i++) {
537 np = pt->v[i];
538 v = &disp->m[3*np];
539 for (j=0; j<3; j++)
540 c[i][j] += tau*v[j];
541 }
542
543 ncal = MMG5_caltet_iso_4pt(c[0],c[1],c[2],c[3]);
544
545 if ( ncal < MMG5_DEGTOL*ocal )
546 pt->mark = itdeg;
547
548 }
549
550 /* Perform physical displacement */
551 for (k=1; k<=mesh->np; k++) {
552 ppt = &mesh->point[k];
553
554 if ( !MG_VOK(ppt) ) continue;
555 v = &disp->m[3*k];
556
557 for (i=0; i<3; i++) {
558 ppt->c[i] = ppt->c[i] + tau*v[i];
559 v[i] *= ctau;
560 }
561 }
562
563 return 1;
564}
565
566
583int MMG5_mmg3d3(MMG5_pMesh mesh,MMG5_pSol disp,MMG5_pSol met,MMG5_int **invalidTets) {
584 double avlen,tau,hmintmp,hmaxtmp;
585 int itdc,itmn,maxitmn,maxitdc,iit,warn;
586 MMG5_int nspl,ns,nm,nc,k;
587 MMG5_int nns,nnm,nnc,nnspl,nnns,nnnm,nnnc,nnnspl;
588 MMG5_int ninvalidTets;
589 short t,lastt;
590 int8_t ier;
591
592 maxitmn = 10;
593 maxitdc = 100;
594 t = 0;
595 tau = 0.0;
596 ninvalidTets = 0;
597
598 nnnspl = nnnc = nnns = nnnm = lastt = 0;
599
600 if ( abs(mesh->info.imprim) > 4 || mesh->info.ddebug )
601 fprintf(stdout," ** LAGRANGIAN MOTION\n");
602
603 /* Field mark stores information about whether a tetra has been greatly deformed during current step */
604 for (k=1; k<=mesh->ne; k++)
605 mesh->tetra[k].mark = 0;
606
607 /* Estimates of the minimum and maximum edge lengths in the mesh */
608 avlen = MMG5_estavglen(mesh);
609
610 hmintmp = mesh->info.hmin;
611 hmaxtmp = mesh->info.hmax;
612
613 mesh->info.hmax = MMG3D_LLONG*avlen;
614 mesh->info.hmin = MMG3D_LSHRT*avlen;
615
616 for (itmn=0; itmn<maxitmn; itmn++) {
617
618#ifdef USE_ELAS
619 /* Extension of the displacement field */
620 if ( !MMG5_velextLS(mesh,disp) ) {
621 fprintf(stderr,"\n ## Problem in func. MMG5_velextLS. Exit program.\n");
622 return 0;
623 }
624#else
625 fprintf(stderr,"\n ## Error: %s: you need to compile with the USE_ELAS"
626 " CMake's flag set to ON to use the rigidbody movement.\n",__func__);
627 return 0;
628#endif
629
630 //MMG5_saveDisp(mesh,disp);
631
632 /* Sequence of dichotomy loops to find the largest admissible displacements */
633 for (itdc=0; itdc<maxitdc; itdc++) {
634 nnspl = nnc = nns = nnm = 0;
635
637 if ( t == 0 ) {
638 if ( abs(mesh->info.imprim) > 4 || mesh->info.ddebug )
639 fprintf(stderr,"\n *** Stop: impossible to proceed further\n");
640 break;
641 }
642
643 ier = MMG5_dispmesh(mesh,disp,t,itdc);
644 if ( !ier ) {
645 fprintf(stderr,"\n ** Impossible motion\n");
646 return 0;
647 }
648
649 tau = tau + ((double)t /MMG3D_SHORTMAX)*(1.0-tau);
650 if ( (abs(mesh->info.imprim) > 3 ) || mesh->info.ddebug )
651 printf(" ---> Realized displacement: %f\n",tau);
652
653 /* Local remeshing depending on the option */
654 if ( mesh->info.lag > 0 ) {
655 for ( iit=0; iit<5; iit++) {
656
657 nspl = nc = ns = nm = 0;
658
659 if ( mesh->info.lag > 1 ) {
660 if ( !mesh->info.noinsert ) {
661 /* Split of points */
662 nspl = MMG5_spllag(mesh,disp,met,itdc,&warn);
663 if ( nspl < 0 ) {
664 fprintf(stderr,"\n ## Problem in spllag. Exiting.\n");
665 return 0;
666 }
667
668 /* Collapse of points */
669 nc = MMG5_coltetlag(mesh,met,itdc);
670 if ( nc < 0 ) {
671 fprintf(stderr,"\n ## Problem in coltetlag. Exiting.\n");
672 return 0;
673 }
674 }
675 }
676
677 /* Swap of edges in tetra that have resulted distorted from the process */
678 /* I do not know whether it is safe to put NULL in metric here (a
679 * priori ok, since there is no vertex creation or suppression) */
680 if ( !mesh->info.noswap ) {
681 ns = MMG5_swptetlag(mesh,met,MMG3D_LSWAPIMPROVE,NULL,itdc);
682 if ( ns < 0 ) {
683 fprintf(stderr,"\n ## Problem in swaptetlag. Exiting.\n");
684 return 0;
685 }
686 }
687
688 /* Relocate vertices of tetra which have been distorted in the displacement process */
689 nm = MMG5_movtetlag(mesh,met,itdc);
690 if ( nm < 0 ) {
691 fprintf(stderr,"\n ## Problem in movtetlag. Exiting.\n");
692 return 0;
693 }
694
695 if ( (abs(mesh->info.imprim) > 4 || mesh->info.ddebug) && (nspl+nc+ns+nm > 0) )
696 printf(" %" MMG5_PRId " edges splitted, %" MMG5_PRId " vertices collapsed, %" MMG5_PRId " elements"
697 " swapped, %" MMG5_PRId " vertices moved.\n",nspl,nc,ns,nm);
698 nnspl+= nspl;
699 nnm += nm;
700 nnc += nc;
701 nns += ns;
702 }
703 /* Five iterations of local remeshing have been performed: print final stats */
704 if ( abs(mesh->info.imprim) > 3 && abs(mesh->info.imprim) < 5 && (nnspl+nnm+nns+nnc > 0) )
705 printf(" %" MMG5_PRId " edges splitted, %" MMG5_PRId " vertices collapsed, %" MMG5_PRId " elements"
706 " swapped, %" MMG5_PRId " vertices moved.\n",nnspl,nnc,nns,nnm);
707 }
708
709 nnnspl += nnspl;
710 nnnm += nnm;
711 nnnc += nnc;
712 nnns += nns;
713
714 if ( t == MMG3D_SHORTMAX ) break;
715 }
716
717 /* End of dichotomy loop: maximal displacement of the extended velocity
718 * field has been performed */
719 if ( mesh->info.imprim > 1 && abs(mesh->info.imprim) < 4 ) {
720 printf(" ---> Realized displacement: %f\n",tau);
721 }
722
723 if ( abs(mesh->info.imprim) > 2 && mesh->info.lag )
724 printf(" %"MMG5_PRId" edges splitted, %"MMG5_PRId" vertices collapsed,"
725 " %"MMG5_PRId" elements swapped, %"MMG5_PRId" vertices moved.\n",
726 nnnspl,nnnc,nnns,nnnm);
727
728 if ( t == MMG3D_SHORTMAX || (t==0 && itdc==0) ) break;
729 }
730
731 /* Reinsert standard values for hmin, hmax */
732 mesh->info.hmin = hmintmp;
733 mesh->info.hmax = hmaxtmp;
734
735 if ( tau < MMG5_EPSD2 ) {
736 MMG5_SAFE_CALLOC(*invalidTets,mesh->np,MMG5_int,
737 printf("## Warning: Not enough memory to keep track of"
738 " the invalid tetrahedron.\n");
739 MMG5_DEL_MEM(mesh,disp->m);
740 return 1);
741 ninvalidTets = MMG5_chkmovmesh(mesh,disp,lastt,*invalidTets);
742 assert ( ninvalidTets );
743 }
744
745 /* Clean memory */
746 /* Doing this, memcur of mesh is decreased by size of displacement */
747 MMG5_DEL_MEM(mesh,disp->m);
748
749 if ( ninvalidTets ) {
750 return -ninvalidTets;
751 }
752 else {
753 return 1;
754 }
755}
int ier
MMG5_pMesh * mesh
int MMG5_boulevolp(MMG5_pMesh mesh, MMG5_int start, int ip, int64_t *list)
Definition: boulep_3d.c:54
int MMG5_coquil(MMG5_pMesh mesh, MMG5_int start, int ia, int64_t *list, int8_t *isbdy)
Definition: boulep_3d.c:1403
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:1144
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 for the mmg3d library.
#define MMG3D_LMAX
Definition: libmmg3d.h:58
MMG5_int MMG3D_newPt(MMG5_pMesh mesh, double c[3], int16_t tag, MMG5_int src)
Definition: zaldy_3d.c:39
int MMG5_split1b(MMG5_pMesh, MMG5_pSol, int64_t *, int, MMG5_int, int, int8_t, int8_t)
Definition: split_3d.c:617
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:400
void MMG3D_delPt(MMG5_pMesh mesh, MMG5_int ip)
Definition: zaldy_3d.c:80
#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
#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:512
static MMG5_int MMG5_coltetlag(MMG5_pMesh mesh, MMG5_pSol met, int itdeg)
Definition: mmg3d3.c:389
MMG5_int MMG5_chkmovmesh(MMG5_pMesh mesh, MMG5_pSol disp, short t, MMG5_int *tetIdx)
Definition: mmg3d3.c:473
MMG5_int MMG5_swptetlag(MMG5_pMesh mesh, MMG5_pSol met, double crit, MMG3D_pPROctree PROctree, int itdeg)
Definition: mmg3d3.c:278
#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:329
int MMG5_mmg3d3(MMG5_pMesh mesh, MMG5_pSol disp, MMG5_pSol met, MMG5_int **invalidTets)
Definition: mmg3d3.c:583
#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:532
uint8_t noswap
Definition: libmmgtypes.h:546
double hmin
Definition: libmmgtypes.h:518
uint8_t noinsert
Definition: libmmgtypes.h:546
double hmax
Definition: libmmgtypes.h:518
int8_t lag
Definition: libmmgtypes.h:540
MMG mesh structure.
Definition: libmmgtypes.h:605
size_t memCur
Definition: libmmgtypes.h:607
MMG5_Info info
Definition: libmmgtypes.h:651
MMG5_int ne
Definition: libmmgtypes.h:612
MMG5_pPoint point
Definition: libmmgtypes.h:641
MMG5_int npmax
Definition: libmmgtypes.h:612
double gap
Definition: libmmgtypes.h:608
MMG5_int base
Definition: libmmgtypes.h:616
MMG5_pTetra tetra
Definition: libmmgtypes.h:643
MMG5_int np
Definition: libmmgtypes.h:612
MMG5_pxTetra xtetra
Definition: libmmgtypes.h:644
MMG5_int npnil
Definition: libmmgtypes.h:621
Structure to store points of a MMG mesh.
Definition: libmmgtypes.h:270
int16_t tag
Definition: libmmgtypes.h:284
double c[3]
Definition: libmmgtypes.h:271
MMG5_int flag
Definition: libmmgtypes.h:282
MMG5_int npmax
Definition: libmmgtypes.h:666
double * m
Definition: libmmgtypes.h:671
MMG5_int v[4]
Definition: libmmgtypes.h:403
MMG5_int xt
Definition: libmmgtypes.h:407
MMG5_int ref
Definition: libmmgtypes.h:404
MMG5_int mark
Definition: libmmgtypes.h:406
int16_t tag
Definition: libmmgtypes.h:410
Structure to store the surface tetrahedra of a MMG mesh.
Definition: libmmgtypes.h:418
int16_t tag[6]
Definition: libmmgtypes.h:425
MMG5_int edg[6]
Definition: libmmgtypes.h:421