Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
anisomovpt_3d.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"
39#include "mmgexterns_private.h"
40
58int MMG5_movintpt_ani(MMG5_pMesh mesh,MMG5_pSol met, MMG3D_pPROctree PROctree, int64_t *list,int ilist,
59 int improve) {
60
61
62 MMG5_pTetra pt,pt0;
63 MMG5_pPoint p0,p1,p2,p3,ppt0;
64 double vol,totvol,m[6];
65 double calold,calnew,callist[MMG3D_LMAX+2],det;
66 MMG5_int iel;
67 int k,i0;
68
69 assert ( ilist > 0 );
70 if ( ilist <= 0 ) {
71 fprintf(stderr,"\n ## Error: %s:"
72 " volumic ball has null or negative size (%d)\n",
73 __func__,ilist);
74 return 0;
75 }
76
77 pt0 = &mesh->tetra[0];
78 ppt0 = &mesh->point[0];
79 memset(ppt0,0,sizeof(MMG5_Point));
80
81 if ( met->m ) {
82 iel = list[0] / 4;
83 i0 = list[0] % 4;
84 memcpy(&met->m[0],&met->m[met->size*mesh->tetra[iel].v[i0]],met->size*sizeof(double));
85 }
86
87 /* Coordinates of optimal point */
88 calold = DBL_MAX;
89 totvol = 0.0;
90 for (k=0; k<ilist; k++) {
91 iel = list[k] / 4;
92 pt = &mesh->tetra[iel];
93 p0 = &mesh->point[pt->v[0]];
94 p1 = &mesh->point[pt->v[1]];
95 p2 = &mesh->point[pt->v[2]];
96 p3 = &mesh->point[pt->v[3]];
97 vol= MMG5_det4pt(p0->c,p1->c,p2->c,p3->c);
98
99 if ( !MMG5_moymet(mesh,met,pt,m) ) {
100 // MMG5_moymet must succeed because we have at least 1 point of the tet
101 // that is internal.
102 return 0;
103 }
104
105 det = m[0] * ( m[3]*m[5] - m[4]*m[4]) - m[1] * ( m[1]*m[5] - m[2]*m[4])
106 + m[2] * ( m[1]*m[4] - m[2]*m[3]);
107 if ( det < MMG5_EPSD2 ) {
108 return 0;
109 }
110
111 vol *= sqrt(det);
112
113 totvol += vol;
114 /* barycenter */
115 ppt0->c[0] += 0.25 * vol*(p0->c[0] + p1->c[0] + p2->c[0] + p3->c[0]);
116 ppt0->c[1] += 0.25 * vol*(p0->c[1] + p1->c[1] + p2->c[1] + p3->c[1]);
117 ppt0->c[2] += 0.25 * vol*(p0->c[2] + p1->c[2] + p2->c[2] + p3->c[2]);
118 calold = MG_MIN(calold, pt->qual);
119 }
120 if (totvol < MMG5_EPSD2) {
121 return 0;
122 }
123
124 totvol = 1.0 / totvol;
125 ppt0->c[0] *= totvol;
126 ppt0->c[1] *= totvol;
127 ppt0->c[2] *= totvol;
128
129 /* Check new position validity */
130 calnew = DBL_MAX;
131 for (k=0; k<ilist; k++) {
132 iel = list[k] / 4;
133 i0 = list[k] % 4;
134 pt = &mesh->tetra[iel];
135 memcpy(pt0,pt,sizeof(MMG5_Tetra));
136 pt0->v[i0] = 0;
137 callist[k] = MMG5_orcal(mesh,met,0);
138 if (callist[k] < MMG5_NULKAL) {
139 return 0;
140 }
141 calnew = MG_MIN(calnew,callist[k]);
142 }
143 if (calold < MMG5_EPSOK && calnew <= calold) {
144 return 0;
145 }
146 else if (calnew < MMG5_EPSOK) {
147 return 0;
148 }
149 else if ( improve && calnew < 1.02* calold ) {
150 return 0;
151 }
152 else if ( calnew < 0.3 * calold ) {
153 return 0;
154 }
155
156 /* update position */
157 if ( PROctree )
158 MMG3D_movePROctree(mesh, PROctree, pt->v[i0], ppt0->c, p0->c);
159
160 p0 = &mesh->point[pt->v[i0]];
161 p0->c[0] = ppt0->c[0];
162 p0->c[1] = ppt0->c[1];
163 p0->c[2] = ppt0->c[2];
164 for (k=0; k<ilist; k++) {
165 (&mesh->tetra[list[k]/4])->qual=callist[k];
166 (&mesh->tetra[list[k]/4])->mark=mesh->mark;
167 }
168
169 return 1;
170}
171
192 int64_t *listv,int ilistv,MMG5_int *lists,int ilists,
193 int improveSurf, int improveVol) {
194 MMG5_pTetra pt,pt0;
195 MMG5_pxTetra pxt;
196 MMG5_pPoint p0;
197 MMG5_Tria tt;
198 MMG5_pxPoint pxp;
199 MMG5_Bezier b;
200 double n[3],r[3][3],lispoi[3*MMG3D_LMAX+1],det2d;
201 double detloc,gv[2],step,lambda[3];
202 double o[3],no[3],*m0,ncur[3],nprev[3],nneighi[3];
203 double calold,calnew,caltmp,callist[MMG3D_LMAX+2];
204 MMG5_int k,kel,iel,ip0,nxp;
205 int ier,l;
206 uint8_t i0,iface,i;
207 static int warn = 0;
208 static int8_t mmgErr0=0;
209
210 step = 0.1;
211 if ( ilists < 2 ) return 0;
212
213 k = listv[0] / 4;
214 i0 = listv[0] % 4;
215 pt = &mesh->tetra[k];
216 ip0 = pt->v[i0];
217 p0 = &mesh->point[ip0];
218 m0 = &met->m[6*ip0];
219 assert( p0->xp && !MG_EDG(p0->tag) );
220
221 n[0] = mesh->xpoint[p0->xp].n1[0];
222 n[1] = mesh->xpoint[p0->xp].n1[1];
223 n[2] = mesh->xpoint[p0->xp].n1[2];
224
226 if ( !MMG5_rotmatrix(n,r) ) {
227 return 0;
228 }
229
232 if ( !MMG3D_rotate_surfacicBall(mesh,lists,ilists,ip0,r,lispoi) ) {
233 return 0;
234 }
235
238 gv[0] = 0.0;
239 gv[1] = 0.0;
240
241 for (k=0; k<ilists; k++) {
242 iel = lists[k] / 4;
243 iface = lists[k] % 4;
244 pt = &mesh->tetra[iel];
245 pxt = &mesh->xtetra[pt->xt];
246
247 assert( 0<=iface && iface<4 && "unexpected local face idx");
248 MMG5_tet2tri(mesh,iel,iface,&tt);
249
250 if(!MMG5_bezierCP(mesh,&tt,&b,MG_GET(pxt->ori,iface))){
251 if( !mmgErr0 ) {
252 mmgErr0 = 1;
253 fprintf(stderr,"\n ## Error: %s: function MMG5_bezierCP return 0.\n",
254 __func__);
255 }
256 return -1;
257 }
258
259 /* Compute integral of sqrt(T^J(xi) M(P(xi)) J(xi)) * P(xi) over the triangle */
260 if ( !MMG5_elementWeight(mesh,met,&tt,p0,&b,r,gv) ) {
261 if ( !warn ) {
262 ++warn;
263 fprintf(stderr,"\n ## Warning: %s:"
264 " unable to compute optimal position for at least"
265 " 1 point.\n",__func__);
266 }
267 return 0;
268 }
269 }
270
271 /* At this point : gv = - gradient of V = direction to follow */
273 det2d = lispoi[1]*gv[1] - lispoi[2]*gv[0];
274 kel = 0;
275 if ( det2d >= 0.0 ) {
276 for (k=0; k<ilists; k++) {
277 detloc = gv[0]*lispoi[3*(k+1)+2] - gv[1]*lispoi[3*(k+1)+1];
278 if ( detloc >= 0.0 ) {
279 kel = k;
280 break;
281 }
282 }
283 if ( k == ilists ) {
284 return 0;
285 }
286 }
287 else {
288 for (k=ilists-1; k>=0; k--) {
289 detloc = lispoi[3*k+1]*gv[1] - lispoi[3*k+2]*gv[0];
290 if ( detloc >= 0.0 ) {
291 kel = k;
292 break;
293 }
294 }
295 if ( k == -1 ) {
296 return 0;
297 }
298 }
299
300 /* Sizing of time step : make sure point does not go out corresponding triangle. */
301 det2d = -gv[1]*(lispoi[3*(kel+1)+1] - lispoi[3*(kel)+1]) + \
302 gv[0]*(lispoi[3*(kel+1)+2] - lispoi[3*(kel)+2]);
303 if ( fabs(det2d) < MMG5_EPSD2 ) {
304 return 0;
305 }
306
307 det2d = 1.0 / det2d;
308 step *= det2d;
309
310 det2d = lispoi[3*(kel)+1]*(lispoi[3*(kel+1)+2] - lispoi[3*(kel)+2]) - \
311 lispoi[3*(kel)+2 ]*(lispoi[3*(kel+1)+1] - lispoi[3*(kel)+1]);
312 step *= det2d;
313 step = fabs(step);
314 gv[0] *= step;
315 gv[1] *= step;
316
317 /* Computation of the barycentric coordinates of the new point in the corresponding triangle. */
318 det2d = lispoi[3*kel+1]*lispoi[3*(kel+1)+2] - lispoi[3*kel+2]*lispoi[3*(kel+1)+1];
319 if ( det2d < MMG5_EPSD2 ) {
320 return 0;
321 }
322 det2d = 1.0 / det2d;
323 lambda[1] = lispoi[3*(kel+1)+2]*gv[0] - lispoi[3*(kel+1)+1]*gv[1];
324 lambda[2] = -lispoi[3*(kel)+2]*gv[0] + lispoi[3*(kel)+1]*gv[1];
325 lambda[1]*= (det2d);
326 lambda[2]*= (det2d);
327 lambda[0] = 1.0 - lambda[1] - lambda[2];
328
331 // Remark: if we call following function with a pointer for n, we have to set
332 // the pointer again after the function call as it may invalidate it if it
333 // reallocates the xpoint array
334 nxp = MMG3D_movbdyregpt_geom(mesh,lists,kel,ip0,n,lambda,o,no);
335 if ( nxp < 0 ) {
336 return -1;
337 }
338 else if ( !nxp ) {
339 return 0;
340 }
341 pxp = &mesh->xpoint[nxp];
342
343 /* parallel transport of metric at p0 to new point. */
344 if ( !MMG5_paratmet(p0->c,n,m0,o,no,&met->m[0]) ) {
345 return 0;
346 }
347
348 /* For each surfacic triangle build a virtual displaced triangle for check
349 * purposes :
350 * - check the new triangle qualities;
351 * - check normal deviation with the adjacent through the edge facing ip0
352 * and the previous one */
353 k = lists[ilists-1] / 4;
354 iface = lists[ilists-1] % 4;
355
356 assert( 0<=iface && iface<4 && "unexpected local face idx");
357 MMG5_tet2tri(mesh,k,iface,&tt);
358 for( i=0 ; i<3 ; i++ )
359 if ( tt.v[i] == ip0 ) break;
360 assert ( i<3 );
361 if ( i>=3 ) return 0;
362 tt.v[i] = 0;
363
364 if ( !MMG5_nortri(mesh, &tt, nprev) ) return 0;
365
366 calold = calnew = DBL_MAX;
367 for (l=0; l<ilists; l++) {
368 k = lists[l] / 4;
369 iface = lists[l] % 4;
370
371 assert( 0<=iface && iface<4 && "unexpected local face idx");
372 MMG5_tet2tri(mesh,k,iface,&tt);
373 calold = MG_MIN(calold,MMG5_caltri(mesh,met,&tt));
374
375 for( i=0 ; i<3 ; i++ )
376 if ( tt.v[i] == ip0 ) break;
377
378 assert ( i<3 );
379 if ( i>=3 ) return 0;
380 tt.v[i] = 0;
381
382 caltmp = MMG5_caltri(mesh,met,&tt);
383 if ( caltmp < MMG5_EPSD2 ) {
384 /* We don't check the input triangle qualities, thus we may have a very
385 * bad triangle in our mesh */
386 return 0;
387 }
388 calnew = MG_MIN(calnew,caltmp);
389
390 if ( !MMG5_nortri(mesh, &tt, ncur) ) return 0;
391
392 if ( !MG_GEO_OR_NOM(tt.tag[i]) ) {
393 /* Check normal deviation between k and the triangle facing ip0 */
394 /* Note that we don't check the ridge creation along non-manifold edges
395 * because nm edges are skipped while we add ridge tags during analysis
396 * step. */
397 ier = MMG3D_normalAdjaTri(mesh,k,iface, i,nneighi);
398 if ( ier <= 0 ) {
399 return 0;
400 }
401 ier = MMG5_devangle( ncur, nneighi, mesh->info.dhd );
402 if ( ier <= 0 ) {
403 return 0;
404 }
405 }
406
407 i = MMG5_iprv2[i];
408
409 if ( !MG_GEO_OR_NOM(tt.tag[i]) ) {
410 /* Check normal deviation between k and the previous triangle */
411 ier = MMG5_devangle( ncur, nprev, mesh->info.dhd );
412 if ( ier<=0 ) {
413 return 0;
414 }
415 }
416 memcpy(nprev, ncur, 3*sizeof(double));
417
418 }
419 if ( calold < MMG5_EPSOK && calnew <= calold ) {
420 return 0;
421 } else if (calnew < MMG5_EPSOK) {
422 return 0;
423 }
424 else if (improveSurf && calnew < 1.02*calold) {
425 return 0;
426 }
427 else if ( calnew < 0.3*calold ) {
428 return 0;
429 }
430 memset(pxp,0,sizeof(MMG5_xPoint));
431
432 /* Test : check whether all volumes remain positive with new position of the point */
433 calold = calnew = DBL_MAX;
434 for (l=0; l<ilistv; l++) {
435 k = listv[l] / 4;
436 i0 = listv[l] % 4;
437 pt = &mesh->tetra[k];
438 pt0 = &mesh->tetra[0];
439 memcpy(pt0,pt,sizeof(MMG5_Tetra));
440 pt0->v[i0] = 0;
441 calold = MG_MIN(calold, pt->qual);
442 callist[l]=MMG5_orcal(mesh,met,0);
443 if ( callist[l] < MMG5_NULKAL ) {
444 return 0;
445 }
446 calnew = MG_MIN(calnew,callist[l]);
447 }
448
449 if ( calold < MMG5_EPSOK && calnew <= calold ) {
450 return 0;
451 }
452 else if (calnew < MMG5_EPSOK) {
453 return 0;
454 }
455 else if (improveVol && calnew < calold) {
456 return 0;
457 }
458 else if ( calnew < 0.3*calold ) {
459 return 0;
460 }
461
462 /* When all tests have been carried out, update coordinates, normals and metrics*/
463 if ( PROctree )
464 MMG3D_movePROctree(mesh, PROctree, ip0, o, p0->c);
465
466 p0->c[0] = o[0];
467 p0->c[1] = o[1];
468 p0->c[2] = o[2];
469
470 n[0] = no[0];
471 n[1] = no[1];
472 n[2] = no[2];
473
474 memcpy(m0,&met->m[0],6*sizeof(double));
475
476 for(l=0; l<ilistv; l++){
477 (&mesh->tetra[listv[l]/4])->qual= callist[l];
478 (&mesh->tetra[listv[l]/4])->mark= mesh->mark;
479 }
480 return 1;
481}
482
504static inline
506 int ilistv,MMG5_int *lists, int ilists,int improve,const uint16_t edgTag){
507 MMG5_pTetra pt;
508 MMG5_pPoint p0;
509 MMG5_Tria tt;
510 double ll1old,ll2old,l1new,l2new;
511 double o[3],no[3],no2[3],to[3], ncur[3],nprev[3],nneighi[3];
512 double calold,calnew,caltmp;
513 MMG5_int l,iel,ip0,ip1,ip2,ip;
514 uint8_t i,iface,isrid;
515
516 ip1 = ip2 = 0;
517 pt = &mesh->tetra[listv[0]/4];
518 ip0 = pt->v[listv[0]%4];
519 p0 = &mesh->point[ip0];
520
523 isrid = ((MG_GEO & edgTag) && !(MG_NOM & edgTag));
524
525 assert ( edgTag & p0->tag );
526
529 int ier = MMG3D_curveEndingPts(mesh,lists,ilists,edgTag,ip0,&ip1,&ip2);
530 if ( !ier ) {
531 return 0;
532 }
533
540 ll1old = MMG5_lenSurfEdg(mesh,met,ip0,ip1,isrid);
541 ll2old = MMG5_lenSurfEdg(mesh,met,ip0,ip2,isrid);
542
543 if ( (!ll1old) || (!ll2old) ) {
544 return 0;
545 }
546
549 ip = MMG3D_movbdycurvept_newPosForSimu( mesh,p0,ip0,ip1,ip2,ll1old,ll2old,
550 isrid,MMG3D_MOVSTEP,o,no,no2,to,edgTag );
551 if ( !ip ) {
552 return 0;
553 }
554
556 if ( (MG_GEO & edgTag) && !(MG_NOM & edgTag) ) {
557 /* Interpolation of metric between ip0 and ip2 along ridge */
558 if ( !MMG5_intridmet(mesh,met,ip0,ip,MMG3D_MOVSTEP,no,&met->m[0]) ) {
559 return 0;
560 }
561 }
562 else {
563 /* Interpolation of metric between ip0 and ip2 along non manifold or ref edge */
564 if ( !MMG5_paratmet(p0->c,mesh->xpoint[p0->xp].n1,&met->m[6*ip0],o,no,&met->m[0]) ) {
565 return 0;
566 }
567 }
568
570 l1new = MMG5_lenSurfEdg(mesh,met,0,ip1,isrid);
571 l2new = MMG5_lenSurfEdg(mesh,met,0,ip2,isrid);
572
573 if ( (!l1new) || (!l2new) ) {
574 return 0;
575 }
576
577 if ( fabs(l2new -l1new) >= fabs(ll2old -ll1old) ) {
578 return 0;
579 }
580
586 iel = lists[ilists-1] / 4;
587 iface = lists[ilists-1] % 4;
588
589 assert( 0<=iface && iface<4 && "unexpected local face idx");
590 MMG5_tet2tri(mesh,iel,iface,&tt);
591 for( i=0 ; i<3 ; i++ ) {
592 if ( tt.v[i] == ip0 ) {
593 break;
594 }
595 }
596
597 assert ( i<3 );
598 if ( i>=3 ) {
599 return 0;
600 }
601 tt.v[i] = 0;
602
603 if ( !MMG5_nortri(mesh, &tt, nprev) ) {
604 return 0;
605 }
606
607 calold = calnew = DBL_MAX;
608 for( l=0 ; l<ilists ; l++ ){
609 iel = lists[l] / 4;
610 iface = lists[l] % 4;
611
612 assert( 0<=iface && iface<4 && "unexpected local face idx");
613 MMG5_tet2tri(mesh,iel,iface,&tt);
614 caltmp = MMG5_caltri(mesh,met,&tt);
615 calold = MG_MIN(calold,caltmp);
616
617 for( i=0 ; i<3 ; i++ ) {
618 if ( tt.v[i] == ip0 ) {
619 break;
620 }
621 }
622 assert(i<3);
623 if ( i==3 ) {
624 return 0;
625 }
626
627 tt.v[i] = 0;
628
629 caltmp = MMG5_caltri(mesh,met,&tt);
630 if ( caltmp < MMG5_EPSD2 ) {
631 /* We don't check the input triangle qualities, thus we may have a very
632 * bad triangle in our mesh */
633 return 0;
634 }
635 calnew = MG_MIN(calnew,caltmp);
636
637 if ( !MMG5_nortri(mesh, &tt, ncur) ) {
638 return 0;
639 }
640
641 if ( !MG_GEO_OR_NOM(tt.tag[i]) ) {
642 /* Check normal deviation between iel and the triangle facing ip0 */
643 /* Note that we don't check the ridge creation along non-manifold edges
644 * because nm edges are skipped while we add ridge tags during analysis
645 * step. */
646 int16_t ier2 = MMG3D_normalAdjaTri(mesh,iel,iface, i,nneighi);
647 if ( ier2 <=0 ) {
648 return 0;
649 }
650 ier2 = MMG5_devangle( ncur, nneighi, mesh->info.dhd );
651 if ( ier2 <= 0 ) {
652 return 0;
653 }
654 }
655
656 i = MMG5_iprv2[i];
657
658 if ( !MG_GEO_OR_NOM(tt.tag[i]) ) {
659 /* Check normal deviation between k and the previous triangle */
660 int16_t ier2 = MMG5_devangle( ncur, nprev, mesh->info.dhd );
661 if ( ier2<=0 ) {
662 return 0;
663 }
664 }
665 memcpy(nprev, ncur, 3*sizeof(double));
666 }
667 if ( calold < MMG5_EPSOK && calnew <= calold ) {
668 return 0;
669 }
670 else if ( calnew < calold ) {
671 return 0;
672 }
673 memset(&mesh->xpoint[mesh->point[0].xp],0,sizeof(MMG5_xPoint));
674
678 ier = MMG3D_movbdycurvept_chckAndUpdate(mesh,met,PROctree,listv,ilistv,
679 improve,p0,ip0,isrid,o,no,no2,to);
680
681 if ( ier ) {
682 memcpy(&met->m[6*ip0],&met->m[0],6*sizeof(double));
683 }
684
685 return ier;
686}
687
707 int ilistv, MMG5_int *lists, int ilists,int improve){
708
709 return MMG3D_movbdycurvept_ani(mesh,met,PROctree,listv,ilistv,lists,ilists,improve,MG_REF);
710}
711
731 int64_t *listv,int ilistv, MMG5_int *lists, int ilists,
732 int improve){
733
734 return MMG3D_movbdycurvept_ani(mesh,met,PROctree,listv,ilistv,lists,ilists,improve,MG_NOM);
735}
736
737
755 int64_t *listv,int ilistv,MMG5_int *lists,int ilists,
756 int improve) {
757
758 return MMG3D_movbdycurvept_ani(mesh,met,PROctree,listv,ilistv,lists,ilists,improve,MG_GEO);
759}
int ier
MMG5_pMesh * mesh
int MMG3D_movePROctree(MMG5_pMesh mesh, MMG3D_pPROctree q, MMG5_int no, double *newVer, double *oldVer)
Definition: PRoctree_3d.c:225
int MMG5_elementWeight(MMG5_pMesh mesh, MMG5_pSol met, MMG5_pTria pt, MMG5_pPoint p0, MMG5_Bezier *pb, double r[3][3], double gv[2])
Definition: anisomovpt.c:53
int MMG5_movbdynompt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctree, int64_t *listv, int ilistv, MMG5_int *lists, int ilists, int improve)
static int MMG3D_movbdycurvept_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctree, int64_t *listv, int ilistv, MMG5_int *lists, int ilists, int improve, const uint16_t edgTag)
int MMG5_movbdyregpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctree, int64_t *listv, int ilistv, MMG5_int *lists, int ilists, int improveSurf, int improveVol)
int MMG5_movbdyrefpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctree, int64_t *listv, int ilistv, MMG5_int *lists, int ilists, int improve)
int MMG5_movintpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctree, int64_t *list, int ilist, int improve)
Definition: anisomovpt_3d.c:58
int MMG5_movbdyridpt_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctree, int64_t *listv, int ilistv, MMG5_int *lists, int ilists, int improve)
int MMG5_moymet(MMG5_pMesh mesh, MMG5_pSol met, MMG5_pTetra pt, double *m1)
Definition: anisosiz_3d.c:144
static double MMG5_orcal(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int iel)
int MMG5_intridmet(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int ip1, MMG5_int ip2, double s, double v[3], double mr[6])
Definition: intmet.c:163
API headers and documentation for the mmg3d library, for volumetric meshes in 3D.
#define MMG3D_LMAX
Definition: libmmg3d.h:130
int MMG3D_movbdycurvept_chckAndUpdate(MMG5_pMesh mesh, MMG5_pSol met, MMG3D_pPROctree PROctree, int64_t *listv, int ilistv, int improve, MMG5_pPoint p0, MMG5_int ip0, uint8_t isrid, double o[3], double no[3], double no2[3], double to[3])
Definition: movpt_3d.c:1056
#define MMG3D_MOVSTEP
int MMG3D_rotate_surfacicBall(MMG5_pMesh, MMG5_int *, int, MMG5_int, double r[3][3], double *)
Definition: movpt_3d.c:350
int MMG3D_normalAdjaTri(MMG5_pMesh, MMG5_int, int8_t, int, double n[3])
Definition: split_3d.c:472
int MMG3D_movbdycurvept_newPosForSimu(MMG5_pMesh, MMG5_pPoint, MMG5_int, MMG5_int, MMG5_int, double, double, uint8_t, const double, double[3], double[3], double[3], double[3], const uint16_t)
Definition: movpt_3d.c:1150
void MMG5_tet2tri(MMG5_pMesh mesh, MMG5_int k, int8_t ie, MMG5_Tria *ptt)
Definition: mmg3d1.c:102
int MMG3D_curveEndingPts(MMG5_pMesh, MMG5_int *, int, const uint16_t, MMG5_int, MMG5_int *, MMG5_int *)
Definition: movpt_3d.c:944
int MMG3D_movbdyregpt_geom(MMG5_pMesh, MMG5_int *, const MMG5_int, const MMG5_int, double[3], double[3], double[3], double[3])
Definition: movpt_3d.c:483
int MMG5_paratmet(double c0[3], double n0[3], double m[6], double c1[3], double n1[3], double mt[6])
Definition: mettools.c:1390
#define MG_GEO
#define MMG5_EPSOK
#define MG_MIN(a, b)
#define MG_EDG(tag)
static const uint8_t MMG5_iprv2[3]
double MMG5_det4pt(double c0[3], double c1[3], double c2[3], double c3[3])
Definition: tools.c:932
#define MMG5_NULKAL
#define MG_GEO_OR_NOM(tag)
#define MG_GET(flag, bit)
int MMG5_devangle(double *n1, double *n2, double crit)
Definition: tools.c:103
int MMG5_nortri(MMG5_pMesh mesh, MMG5_pTria pt, double *n)
Definition: tools.c:209
int MMG5_rotmatrix(double n[3], double r[3][3])
Definition: tools.c:467
#define MG_NOM
#define MMG5_EPSD2
#define MG_REF
double dhd
Definition: libmmgtypes.h:525
MMG mesh structure.
Definition: libmmgtypes.h:613
MMG5_Info info
Definition: libmmgtypes.h:659
MMG5_pPoint point
Definition: libmmgtypes.h:649
MMG5_int mark
Definition: libmmgtypes.h:626
MMG5_pxPoint xpoint
Definition: libmmgtypes.h:650
MMG5_pTetra tetra
Definition: libmmgtypes.h:651
MMG5_pxTetra xtetra
Definition: libmmgtypes.h:652
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 xp
Definition: libmmgtypes.h:285
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
double qual
Definition: libmmgtypes.h:408
Structure to store triangles of a MMG mesh.
Definition: libmmgtypes.h:338
uint16_t tag[3]
Definition: libmmgtypes.h:348
MMG5_int v[3]
Definition: libmmgtypes.h:340
Structure to store surface vertices of an MMG mesh.
Definition: libmmgtypes.h:300
double n1[3]
Definition: libmmgtypes.h:301
Structure to store additional information for the surface tetrahedra of an MMG mesh.
Definition: libmmgtypes.h:425
int8_t ori
Definition: libmmgtypes.h:434