Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
intmet_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_private.h"
37
57int MMG5_intmet_ani(MMG5_pMesh mesh,MMG5_pSol met,MMG5_int k,int8_t i,MMG5_int ip,
58 double s) {
59 MMG5_pTetra pt;
60 MMG5_pxTetra pxt;
61 MMG5_pPoint ppt;
62 MMG5_pxPoint pxp;
63 double *m;
64 MMG5_int ip1,ip2;
65
66 pt = &mesh->tetra[k];
67 m = &met->m[6*ip];
68 ip1 = pt->v[MMG5_iare[i][0]];
69 ip2 = pt->v[MMG5_iare[i][1]];
70
71 if ( pt->xt ) {
72 pxt = &mesh->xtetra[pt->xt];
73 if ( pxt->tag[i] & MG_GEO && !(pxt->tag[i] & MG_NOM) ) {
74 ppt = &mesh->point[ip];
75 assert(ppt->xp);
76 pxp = &mesh->xpoint[ppt->xp];
77 return MMG5_intridmet(mesh,met,ip1,ip2,s,pxp->n1,m);
78 }
79 else if ( pxt->tag[i] & MG_BDY ) {
80 return MMG5_intregmet(mesh,met,k,i,s,m);
81 }
82 }
83
84 /* If we pass here, either we don't have an xtetra, or the edge is not marked
85 * as MG_BDY */
86 assert ( (!pt->xt) || !(pxt->tag[i] & MG_BDY) );
87
88#ifndef NDEBUG
89 /* Assert that we are not dealing by error with a boundary edge (we may have
90 * regular edges without MG_BDY tag or edges ) */
91
92 // If we come from anatets/v, mesh->adja is not allocated and we cannot called
93 // the get_shellEdgeTag function: in this case, the MG_BDY tag has been
94 // explicitely added if we arrive from a boundary face and a boundary edge
95 // should not be splitted from a non boundary face
96 if ( mesh->adja ) {
97 uint16_t tag = 0;
98 MMG5_int ref = 0;
99 if ( !MMG3D_get_shellEdgeTag(mesh,k,i,&tag,&ref) ) {
100 fprintf(stderr,"\n ## Warning: %s: 0. unable to get edge info"
101 " (tetra %d).\n",__func__,MMG3D_indElt(mesh,k));
102 return 0;
103 }
104 assert ( (!(tag & MG_BDY)) && "Boundary edge is seen as internal");
105 }
106#endif
107
108 /* The edge is an internal edge. */
109 return MMG5_intvolmet(mesh,met,k,i,s,m);
110
111}
112
126int MMG3D_intmet33_ani(MMG5_pMesh mesh,MMG5_pSol met,MMG5_int k,int8_t i,MMG5_int ip,
127 double s) {
128 MMG5_pTetra pt;
129 MMG5_int ip1,ip2;
130
131 pt = &mesh->tetra[k];
132 ip1 = pt->v[MMG5_iare[i][0]];
133 ip2 = pt->v[MMG5_iare[i][1]];
134
135 return MMG3D_intmet33_ani_edge(met,ip1,ip2,ip,s);
136}
137
150int MMG3D_intmet33_ani_edge(MMG5_pSol met,MMG5_int ip1,MMG5_int ip2,MMG5_int ip,
151 double s) {
152 double *m,*n,*mr;
153
154 m = &met->m[6*ip1];
155 n = &met->m[6*ip2];
156 mr = &met->m[6*ip];
157
158 return MMG5_mmgIntmet33_ani(m,n,mr,s);
159}
160
174int MMG5_intmet_iso(MMG5_pMesh mesh,MMG5_pSol met,MMG5_int k,int8_t i,MMG5_int ip,
175 double s) {
176 MMG5_pTetra pt;
177 MMG5_int ip1, ip2;
178
179 pt = &mesh->tetra[k];
180 ip1 = pt->v[MMG5_iare[i][0]];
181 ip2 = pt->v[MMG5_iare[i][1]];
182
183 return MMG5_intmet_iso_edge(met,ip1,ip2,ip,s);
184}
185
197int MMG5_intmet_iso_edge(MMG5_pSol met,MMG5_int ip1,MMG5_int ip2,MMG5_int ip,
198 double s) {
199 double *m1,*m2,*mm;
200
201 m1 = &met->m[met->size*ip1];
202 m2 = &met->m[met->size*ip2];
203 mm = &met->m[met->size*ip];
204
205 return MMG5_interp_iso(m1,m2,mm,s);
206}
207
222int MMG5_intregmet(MMG5_pMesh mesh,MMG5_pSol met,MMG5_int k,int8_t i,double s,
223 double mr[6]) {
224 MMG5_pTetra pt;
225 MMG5_pxTetra pxt;
226 MMG5_Tria ptt;
227 int ifa0, ifa1, iloc, ier;
228
229 pt = &mesh->tetra[k];
230 pxt = &mesh->xtetra[pt->xt];
231 ifa0 = MMG5_ifar[i][0];
232 ifa1 = MMG5_ifar[i][1];
233
234 ier = -1;
235
236 if ( pxt->ftag[ifa0] & MG_BDY ) {
237 MMG5_tet2tri( mesh,k,ifa0,&ptt);
238 iloc = MMG5_iarfinv[ifa0][i];
239 assert(iloc >= 0);
240 ier = MMG5_interpreg_ani(mesh,met,&ptt,iloc,s,mr);
241 }
242 else if ( pxt->ftag[ifa1] & MG_BDY ) {
243 MMG5_tet2tri( mesh,k,ifa1,&ptt);
244 iloc = MMG5_iarfinv[ifa1][i];
245 assert(iloc >= 0);
246 ier = MMG5_interpreg_ani(mesh,met,&ptt,iloc,s,mr);
247 }
248
249 /* if ier = -1, then i is a boundary edge but the tet has no bdy face. Don't
250 * do anything, the edge will be split via a boundary tetra. Otherwise, if
251 * ier=0, interpreg_ani has failed, if ier=1, interpreg_ani succeed. */
252 if ( mesh->info.ddebug && !ier ) {
253 fprintf(stderr," %s: %d: interpreg_ani error.\n",__func__,__LINE__);
254 fprintf(stderr," Elt %"MMG5_PRId": %"MMG5_PRId" %"MMG5_PRId" %"MMG5_PRId" %"MMG5_PRId"\n",
256 MMG3D_indPt(mesh,pt->v[1]),MMG3D_indPt(mesh,pt->v[2]),
257 MMG3D_indPt(mesh,pt->v[3]));
258 }
259
260 return ier;
261}
262
263
274static inline int
275MMG5_intregvolmet(double *ma,double *mb,double *mp,double t) {
276 double dma[6],dmb[6],mai[6],mbi[6],mi[6];
277 int i;
278 static int8_t mmgWarn=0;
279
280 for (i=0; i<6; i++) {
281 dma[i] = ma[i];
282 dmb[i] = mb[i];
283 }
284 if ( !MMG5_invmat(dma,mai) || !MMG5_invmat(dmb,mbi) ) {
285 if ( !mmgWarn ) {
286 mmgWarn = 1;
287 fprintf(stderr,"\n ## Warning: %s: at least 1 invalid metric.\n",__func__);
288 }
289 return 0;
290 }
291 for (i=0; i<6; i++)
292 mi[i] = (1.0-t)*mai[i] + t*mbi[i];
293
294 if ( !MMG5_invmat(mi,mai) ) {
295 if ( !mmgWarn ) {
296 mmgWarn = 1;
297 fprintf(stderr,"\n ## Warning: %s: at least 1 invalid metric.\n",__func__);
298 }
299 return 0;
300 }
301
302 for (i=0; i<6; i++) mp[i] = mai[i];
303 return 1;
304}
305
320int MMG5_intvolmet(MMG5_pMesh mesh,MMG5_pSol met,MMG5_int k,int8_t i,double s,
321 double mr[6]) {
322 MMG5_pTetra pt;
323 MMG5_pPoint pp1,pp2;
324 double m1[6],m2[6];
325 MMG5_int ip1,ip2;
326 int l,ier;
327
328 pt = &mesh->tetra[k];
329
330 ip1 = pt->v[MMG5_iare[i][0]];
331 ip2 = pt->v[MMG5_iare[i][1]];
332
333 pp1 = &mesh->point[ip1];
334 pp2 = &mesh->point[ip2];
335
336 // build metric at ma and mb points
337 if ( MG_RID(pp1->tag) ) {
338 if (!MMG5_moymet(mesh,met,pt,m1)) return 0;
339 } else {
340 for ( l=0; l<6; ++l )
341 m1[l] = met->m[6*ip1+l];
342 }
343 if ( MG_RID(pp2->tag) ) {
344 if (!MMG5_moymet(mesh,met,pt,m2)) return 0;
345 } else {
346 for ( l=0; l<6; ++l )
347 m2[l] = met->m[6*ip2+l];
348 }
349
350 ier = MMG5_intregvolmet(m1,m2,mr,s);
351 if ( mesh->info.ddebug && ( (!ier) || (fabs(mr[5]) < 1e-6) ) ) {
352 fprintf(stderr," ## Error: %s:\n",__func__);
353 fprintf(stderr," pp1 : %d %d \n",
354 MG_SIN(pp1->tag) || (MG_NOM & pp1->tag),pp1->tag & MG_GEO);
355 fprintf(stderr," m1 %e %e %e %e %e %e\n",
356 m1[0],m1[1],m1[2],m1[3],m1[4],m1[5]);
357 fprintf(stderr," pp2 : %d %d \n",
358 MG_SIN(pp2->tag) || (MG_NOM & pp2->tag),pp2->tag & MG_GEO);
359 fprintf(stderr," m2 %e %e %e %e %e %e\n",
360 m2[0],m2[1],m2[2],m2[3],m2[4],m2[5]);
361 fprintf(stderr," mr %e %e %e %e %e %e\n",
362 mr[0],mr[1],mr[2],mr[3],mr[4],mr[5]);
363 return 0;
364 }
365
366 return 1;
367}
380int MMG5_interp4bar_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k, MMG5_int ip,
381 double cb[4]) {
382 MMG5_pTetra pt;
383
384 pt = &mesh->tetra[k];
385
386 met->m[ip] = cb[0]*met->m[pt->v[0]]+cb[1]*met->m[pt->v[1]] +
387 cb[2]*met->m[pt->v[2]]+cb[3]*met->m[pt->v[3]];
388
389 return 1;
390
391}
392
407static inline
408int MMG5_interp4barintern(MMG5_pSol met,MMG5_int ip,double cb[4],double dm0[6],
409 double dm1[6],double dm2[6],double dm3[6]) {
410 double m0i[6],m1i[6],m2i[6],m3i[6],mi[6];
411 int i;
412 static int8_t mmgWarn=0;
413
414 if ( !MMG5_invmat(dm0,m0i) || !MMG5_invmat(dm1,m1i) ||
415 !MMG5_invmat(dm2,m2i) || !MMG5_invmat(dm3,m3i) ) {
416 if ( !mmgWarn ) {
417 mmgWarn = 1;
418 fprintf(stderr,"\n ## Warning: %s: at least 1 invalid metric.\n",__func__);
419 }
420 return 0;
421 }
422 for (i=0; i<6; i++)
423 mi[i] = cb[0]*m0i[i] + cb[1]*m1i[i] + cb[2]*m2i[i] + cb[3]*m3i[i];
424
425 if ( !MMG5_invmat(mi,m0i) ) {
426 if ( !mmgWarn ) {
427 mmgWarn = 1;
428 fprintf(stderr,"\n ## Warning: %s: at least 1 invalid metric.\n",__func__);
429 }
430 return 0;
431 }
432
433 for (i=0; i<6; i++) met->m[met->size*ip+i] = m0i[i];
434
435 return 1;
436}
437
450int MMG5_interp4bar_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k, MMG5_int ip,
451 double cb[4]) {
452 MMG5_pTetra pt;
453 MMG5_pPoint pp1,pp2,pp3,pp4;
454 double dm0[6],dm1[6],dm2[6],dm3[6];
455 int i;
456
457 pt = &mesh->tetra[k];
458 pp1 = &mesh->point[pt->v[0]];
459 if ( MG_SIN_OR_NOM(pp1->tag) ) {
460 for (i=0; i<6; i++) {
461 dm0[i] = met->m[met->size*pt->v[0]+i];
462 }
463 } else if(pp1->tag & MG_GEO) {
464 if (!MMG5_moymet(mesh,met,pt,&dm0[0])) return 0;
465 } else{
466 for (i=0; i<6; i++) {
467 dm0[i] = met->m[met->size*pt->v[0]+i];
468 }
469 }
470 pp2 = &mesh->point[pt->v[1]];
471 if ( MG_SIN_OR_NOM(pp2->tag) ) {
472 for (i=0; i<6; i++) {
473 dm1[i] = met->m[met->size*pt->v[1]+i];
474 }
475 } else if(pp2->tag & MG_GEO) {
476 if (!MMG5_moymet(mesh,met,pt,&dm1[0])) return 0;
477 } else{
478 for (i=0; i<6; i++) {
479 dm1[i] = met->m[met->size*pt->v[1]+i];
480 }
481 }
482 pp3 = &mesh->point[pt->v[2]];
483 if ( MG_SIN_OR_NOM(pp3->tag) ) {
484 for (i=0; i<6; i++) {
485 dm2[i] = met->m[met->size*pt->v[2]+i];
486 }
487 } else if(pp3->tag & MG_GEO) {
488 if (!MMG5_moymet(mesh,met,pt,&dm2[0])) return 0;
489 } else{
490 for (i=0; i<6; i++) {
491 dm2[i] = met->m[met->size*pt->v[2]+i];
492 }
493 }
494 pp4 = &mesh->point[pt->v[3]];
495 if ( MG_SIN_OR_NOM(pp4->tag) ) {
496 for (i=0; i<6; i++) {
497 dm3[i] = met->m[met->size*pt->v[3]+i];
498 }
499 } else if(pp4->tag & MG_GEO) {
500 if (!MMG5_moymet(mesh,met,pt,&dm3[0])) return 0;
501 } else{
502 for (i=0; i<6; i++) {
503 dm3[i] = met->m[met->size*pt->v[3]+i];
504 }
505 }
506
507 return MMG5_interp4barintern(met,ip,cb,dm0,dm1,dm2,dm3);
508}
509
522int MMG5_interp4bar33_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k, MMG5_int ip,
523 double cb[4]) {
524 MMG5_pTetra pt;
525 double dm0[6],dm1[6],dm2[6],dm3[6];
526 int i;
527
528 pt = &mesh->tetra[k];
529 for (i=0; i<6; i++) {
530 dm0[i] = met->m[met->size*pt->v[0]+i];
531 }
532
533 for (i=0; i<6; i++) {
534 dm1[i] = met->m[met->size*pt->v[1]+i];
535 }
536
537 for (i=0; i<6; i++) {
538 dm2[i] = met->m[met->size*pt->v[2]+i];
539 }
540
541 for (i=0; i<6; i++) {
542 dm3[i] = met->m[met->size*pt->v[3]+i];
543 }
544 return MMG5_interp4barintern(met,ip,cb,dm0,dm1,dm2,dm3);
545}
int ier
MMG5_pMesh * mesh
int MMG5_moymet(MMG5_pMesh mesh, MMG5_pSol met, MMG5_pTetra pt, double *m1)
Definition: anisosiz_3d.c:144
int MMG3D_get_shellEdgeTag(MMG5_pMesh mesh, MMG5_int start, int8_t ia, uint16_t *tag, MMG5_int *ref)
Definition: colver_3d.c:439
int MMG5_interp_iso(double *ma, double *mb, double *mp, double t)
Definition: intmet.c:484
int MMG5_mmgIntmet33_ani(double *m, double *n, double *mr, double s)
Definition: intmet.c:50
int MMG5_interpreg_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG5_pTria pt, int8_t i, double s, double mr[6])
Definition: intmet.c:504
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
int MMG5_interp4bar33_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k, MMG5_int ip, double cb[4])
Definition: intmet_3d.c:522
int MMG3D_intmet33_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k, int8_t i, MMG5_int ip, double s)
Definition: intmet_3d.c:126
int MMG5_intvolmet(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k, int8_t i, double s, double mr[6])
Definition: intmet_3d.c:320
int MMG5_interp4bar_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k, MMG5_int ip, double cb[4])
Definition: intmet_3d.c:450
int MMG5_interp4bar_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k, MMG5_int ip, double cb[4])
Definition: intmet_3d.c:380
int MMG5_intmet_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k, int8_t i, MMG5_int ip, double s)
Definition: intmet_3d.c:174
int MMG3D_intmet33_ani_edge(MMG5_pSol met, MMG5_int ip1, MMG5_int ip2, MMG5_int ip, double s)
Definition: intmet_3d.c:150
int MMG5_intmet_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k, int8_t i, MMG5_int ip, double s)
Definition: intmet_3d.c:57
static int MMG5_intregvolmet(double *ma, double *mb, double *mp, double t)
Definition: intmet_3d.c:275
static int MMG5_interp4barintern(MMG5_pSol met, MMG5_int ip, double cb[4], double dm0[6], double dm1[6], double dm2[6], double dm3[6])
Definition: intmet_3d.c:408
int MMG5_intmet_iso_edge(MMG5_pSol met, MMG5_int ip1, MMG5_int ip2, MMG5_int ip, double s)
Definition: intmet_3d.c:197
int MMG5_intregmet(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k, int8_t i, double s, double mr[6])
Definition: intmet_3d.c:222
MMG5_int MMG3D_indPt(MMG5_pMesh mesh, MMG5_int kp)
Definition: tools_3d.c:918
static const int8_t MMG5_iarfinv[4][6]
num of the j^th edge in the i^th face
static const uint8_t MMG5_iare[6][2]
vertices of extremities of the edges of the tetra
static const uint8_t MMG5_ifar[6][2]
ifar[i][]: faces sharing the ith edge of the tetra
void MMG5_tet2tri(MMG5_pMesh mesh, MMG5_int k, int8_t ie, MMG5_Tria *ptt)
Definition: mmg3d1.c:102
MMG5_int MMG3D_indElt(MMG5_pMesh mesh, MMG5_int kel)
Definition: tools_3d.c:862
#define MG_GEO
#define MG_SIN(tag)
#define MG_RID(tag)
#define MG_BDY
#define MG_NOM
#define MG_SIN_OR_NOM(tag)
int MMG5_invmat(double *m, double *mi)
Definition: tools.c:562
int8_t ddebug
Definition: libmmgtypes.h:539
MMG mesh structure.
Definition: libmmgtypes.h:613
MMG5_Info info
Definition: libmmgtypes.h:659
MMG5_pPoint point
Definition: libmmgtypes.h:649
MMG5_int * adja
Definition: libmmgtypes.h:632
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
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
Structure to store triangles of a MMG mesh.
Definition: libmmgtypes.h:338
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
uint16_t tag[6]
Definition: libmmgtypes.h:432
uint16_t ftag[4]
Definition: libmmgtypes.h:430