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
51int MMG5_intmet_ani(MMG5_pMesh mesh,MMG5_pSol met,MMG5_int k,int8_t i,MMG5_int ip,
52 double s) {
53 MMG5_pTetra pt;
54 MMG5_pxTetra pxt;
55 MMG5_pPoint ppt;
56 MMG5_pxPoint pxp;
57 double *m;
58 MMG5_int ip1,ip2;
59
60 pt = &mesh->tetra[k];
61 m = &met->m[6*ip];
62 ip1 = pt->v[MMG5_iare[i][0]];
63 ip2 = pt->v[MMG5_iare[i][1]];
64
65 if ( pt->xt ) {
66 pxt = &mesh->xtetra[pt->xt];
67 if ( pxt->tag[i] & MG_GEO && !(pxt->tag[i] & MG_NOM) ) {
68 ppt = &mesh->point[ip];
69 assert(ppt->xp);
70 pxp = &mesh->xpoint[ppt->xp];
71 return MMG5_intridmet(mesh,met,ip1,ip2,s,pxp->n1,m);
72 }
73 else if ( pxt->tag[i] & MG_BDY ) {
74 return MMG5_intregmet(mesh,met,k,i,s,m);
75 }
76 else {
77 /* The edge is an internal edge. */
78 return MMG5_intvolmet(mesh,met,k,i,s,m);
79 }
80 }
81 else {
82 /* The edge is an internal edge. */
83 return MMG5_intvolmet(mesh,met,k,i,s,m);
84 }
85 return 0;
86}
87
101int MMG3D_intmet33_ani(MMG5_pMesh mesh,MMG5_pSol met,MMG5_int k,int8_t i,MMG5_int ip,
102 double s) {
103 MMG5_pTetra pt;
104 double *m,*n,*mr;
105 MMG5_int ip1,ip2;
106
107 pt = &mesh->tetra[k];
108 ip1 = pt->v[MMG5_iare[i][0]];
109 ip2 = pt->v[MMG5_iare[i][1]];
110
111 m = &met->m[6*ip1];
112 n = &met->m[6*ip2];
113 mr = &met->m[6*ip];
114
115 return MMG5_mmgIntmet33_ani(m,n,mr,s);
116}
117
131int MMG5_intmet_iso(MMG5_pMesh mesh,MMG5_pSol met,MMG5_int k,int8_t i,MMG5_int ip,
132 double s) {
133 MMG5_pTetra pt;
134 MMG5_int ip1, ip2;
135 double *m1,*m2,*mm;
136
137 pt = &mesh->tetra[k];
138 ip1 = pt->v[MMG5_iare[i][0]];
139 ip2 = pt->v[MMG5_iare[i][1]];
140
141 m1 = &met->m[met->size*ip1];
142 m2 = &met->m[met->size*ip2];
143 mm = &met->m[met->size*ip];
144
145 return MMG5_interp_iso(m1,m2,mm,s);
146}
147
162int MMG5_intregmet(MMG5_pMesh mesh,MMG5_pSol met,MMG5_int k,int8_t i,double s,
163 double mr[6]) {
164 MMG5_pTetra pt;
165 MMG5_pxTetra pxt;
166 MMG5_Tria ptt;
167 int ifa0, ifa1, iloc, ier;
168
169 pt = &mesh->tetra[k];
170 pxt = &mesh->xtetra[pt->xt];
171 ifa0 = MMG5_ifar[i][0];
172 ifa1 = MMG5_ifar[i][1];
173
174 ier = -1;
175
176 if ( pxt->ftag[ifa0] & MG_BDY ) {
177 MMG5_tet2tri( mesh,k,ifa0,&ptt);
178 iloc = MMG5_iarfinv[ifa0][i];
179 assert(iloc >= 0);
180 ier = MMG5_interpreg_ani(mesh,met,&ptt,iloc,s,mr);
181 }
182 else if ( pxt->ftag[ifa1] & MG_BDY ) {
183 MMG5_tet2tri( mesh,k,ifa1,&ptt);
184 iloc = MMG5_iarfinv[ifa1][i];
185 assert(iloc >= 0);
186 ier = MMG5_interpreg_ani(mesh,met,&ptt,iloc,s,mr);
187 }
188
189 /* if ier = -1, then i is a boundary edge but the tet has no bdy face. Don't
190 * do anything, the edge will be split via a boundary tetra. Otherwise, if
191 * ier=0, interpreg_ani has failed, if ier=1, interpreg_ani succeed. */
192 if ( mesh->info.ddebug && !ier ) {
193 fprintf(stderr," %s: %d: interpreg_ani error.\n",__func__,__LINE__);
194 fprintf(stderr," Elt %"MMG5_PRId": %"MMG5_PRId" %"MMG5_PRId" %"MMG5_PRId" %"MMG5_PRId"\n",
196 MMG3D_indPt(mesh,pt->v[1]),MMG3D_indPt(mesh,pt->v[2]),
197 MMG3D_indPt(mesh,pt->v[3]));
198 }
199
200 return ier;
201}
202
203
214static inline int
215MMG5_intregvolmet(double *ma,double *mb,double *mp,double t) {
216 double dma[6],dmb[6],mai[6],mbi[6],mi[6];
217 int i;
218 static int8_t mmgWarn=0;
219
220 for (i=0; i<6; i++) {
221 dma[i] = ma[i];
222 dmb[i] = mb[i];
223 }
224 if ( !MMG5_invmat(dma,mai) || !MMG5_invmat(dmb,mbi) ) {
225 if ( !mmgWarn ) {
226 mmgWarn = 1;
227 fprintf(stderr,"\n ## Warning: %s: at least 1 invalid metric.\n",__func__);
228 }
229 return 0;
230 }
231 for (i=0; i<6; i++)
232 mi[i] = (1.0-t)*mai[i] + t*mbi[i];
233
234 if ( !MMG5_invmat(mi,mai) ) {
235 if ( !mmgWarn ) {
236 mmgWarn = 1;
237 fprintf(stderr,"\n ## Warning: %s: at least 1 invalid metric.\n",__func__);
238 }
239 return 0;
240 }
241
242 for (i=0; i<6; i++) mp[i] = mai[i];
243 return 1;
244}
245
260int MMG5_intvolmet(MMG5_pMesh mesh,MMG5_pSol met,MMG5_int k,int8_t i,double s,
261 double mr[6]) {
262 MMG5_pTetra pt;
263 MMG5_pPoint pp1,pp2;
264 double m1[6],m2[6];
265 MMG5_int ip1,ip2;
266 int l,ier;
267
268 pt = &mesh->tetra[k];
269
270 ip1 = pt->v[MMG5_iare[i][0]];
271 ip2 = pt->v[MMG5_iare[i][1]];
272
273 pp1 = &mesh->point[ip1];
274 pp2 = &mesh->point[ip2];
275
276 // build metric at ma and mb points
277 if ( MG_RID(pp1->tag) ) {
278 if (!MMG5_moymet(mesh,met,pt,m1)) return 0;
279 } else {
280 for ( l=0; l<6; ++l )
281 m1[l] = met->m[6*ip1+l];
282 }
283 if ( MG_RID(pp2->tag) ) {
284 if (!MMG5_moymet(mesh,met,pt,m2)) return 0;
285 } else {
286 for ( l=0; l<6; ++l )
287 m2[l] = met->m[6*ip2+l];
288 }
289
290 ier = MMG5_intregvolmet(m1,m2,mr,s);
291 if ( mesh->info.ddebug && ( (!ier) || (fabs(mr[5]) < 1e-6) ) ) {
292 fprintf(stderr," ## Error: %s:\n",__func__);
293 fprintf(stderr," pp1 : %d %d \n",
294 MG_SIN(pp1->tag) || (MG_NOM & pp1->tag),pp1->tag & MG_GEO);
295 fprintf(stderr," m1 %e %e %e %e %e %e\n",
296 m1[0],m1[1],m1[2],m1[3],m1[4],m1[5]);
297 fprintf(stderr," pp2 : %d %d \n",
298 MG_SIN(pp2->tag) || (MG_NOM & pp2->tag),pp2->tag & MG_GEO);
299 fprintf(stderr," m2 %e %e %e %e %e %e\n",
300 m2[0],m2[1],m2[2],m2[3],m2[4],m2[5]);
301 fprintf(stderr," mr %e %e %e %e %e %e\n",
302 mr[0],mr[1],mr[2],mr[3],mr[4],mr[5]);
303 return 0;
304 }
305
306 return 1;
307}
320int MMG5_interp4bar_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k, MMG5_int ip,
321 double cb[4]) {
322 MMG5_pTetra pt;
323
324 pt = &mesh->tetra[k];
325
326 met->m[ip] = cb[0]*met->m[pt->v[0]]+cb[1]*met->m[pt->v[1]] +
327 cb[2]*met->m[pt->v[2]]+cb[3]*met->m[pt->v[3]];
328
329 return 1;
330
331}
332
347static inline
348int MMG5_interp4barintern(MMG5_pSol met,MMG5_int ip,double cb[4],double dm0[6],
349 double dm1[6],double dm2[6],double dm3[6]) {
350 double m0i[6],m1i[6],m2i[6],m3i[6],mi[6];
351 int i;
352 static int8_t mmgWarn=0;
353
354 if ( !MMG5_invmat(dm0,m0i) || !MMG5_invmat(dm1,m1i) ||
355 !MMG5_invmat(dm2,m2i) || !MMG5_invmat(dm3,m3i) ) {
356 if ( !mmgWarn ) {
357 mmgWarn = 1;
358 fprintf(stderr,"\n ## Warning: %s: at least 1 invalid metric.\n",__func__);
359 }
360 return 0;
361 }
362 for (i=0; i<6; i++)
363 mi[i] = cb[0]*m0i[i] + cb[1]*m1i[i] + cb[2]*m2i[i] + cb[3]*m3i[i];
364
365 if ( !MMG5_invmat(mi,m0i) ) {
366 if ( !mmgWarn ) {
367 mmgWarn = 1;
368 fprintf(stderr,"\n ## Warning: %s: at least 1 invalid metric.\n",__func__);
369 }
370 return 0;
371 }
372
373 for (i=0; i<6; i++) met->m[met->size*ip+i] = m0i[i];
374
375 return 1;
376}
377
390int MMG5_interp4bar_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k, MMG5_int ip,
391 double cb[4]) {
392 MMG5_pTetra pt;
393 MMG5_pPoint pp1,pp2,pp3,pp4;
394 double dm0[6],dm1[6],dm2[6],dm3[6];
395 int i;
396
397 pt = &mesh->tetra[k];
398 pp1 = &mesh->point[pt->v[0]];
399 if ( MG_SIN_OR_NOM(pp1->tag) ) {
400 for (i=0; i<6; i++) {
401 dm0[i] = met->m[met->size*pt->v[0]+i];
402 }
403 } else if(pp1->tag & MG_GEO) {
404 if (!MMG5_moymet(mesh,met,pt,&dm0[0])) return 0;
405 } else{
406 for (i=0; i<6; i++) {
407 dm0[i] = met->m[met->size*pt->v[0]+i];
408 }
409 }
410 pp2 = &mesh->point[pt->v[1]];
411 if ( MG_SIN_OR_NOM(pp2->tag) ) {
412 for (i=0; i<6; i++) {
413 dm1[i] = met->m[met->size*pt->v[1]+i];
414 }
415 } else if(pp2->tag & MG_GEO) {
416 if (!MMG5_moymet(mesh,met,pt,&dm1[0])) return 0;
417 } else{
418 for (i=0; i<6; i++) {
419 dm1[i] = met->m[met->size*pt->v[1]+i];
420 }
421 }
422 pp3 = &mesh->point[pt->v[2]];
423 if ( MG_SIN_OR_NOM(pp3->tag) ) {
424 for (i=0; i<6; i++) {
425 dm2[i] = met->m[met->size*pt->v[2]+i];
426 }
427 } else if(pp3->tag & MG_GEO) {
428 if (!MMG5_moymet(mesh,met,pt,&dm2[0])) return 0;
429 } else{
430 for (i=0; i<6; i++) {
431 dm2[i] = met->m[met->size*pt->v[2]+i];
432 }
433 }
434 pp4 = &mesh->point[pt->v[3]];
435 if ( MG_SIN_OR_NOM(pp4->tag) ) {
436 for (i=0; i<6; i++) {
437 dm3[i] = met->m[met->size*pt->v[3]+i];
438 }
439 } else if(pp4->tag & MG_GEO) {
440 if (!MMG5_moymet(mesh,met,pt,&dm3[0])) return 0;
441 } else{
442 for (i=0; i<6; i++) {
443 dm3[i] = met->m[met->size*pt->v[3]+i];
444 }
445 }
446
447 return MMG5_interp4barintern(met,ip,cb,dm0,dm1,dm2,dm3);
448}
449
462int MMG5_interp4bar33_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k, MMG5_int ip,
463 double cb[4]) {
464 MMG5_pTetra pt;
465 double dm0[6],dm1[6],dm2[6],dm3[6];
466 int i;
467
468 pt = &mesh->tetra[k];
469 for (i=0; i<6; i++) {
470 dm0[i] = met->m[met->size*pt->v[0]+i];
471 }
472
473 for (i=0; i<6; i++) {
474 dm1[i] = met->m[met->size*pt->v[1]+i];
475 }
476
477 for (i=0; i<6; i++) {
478 dm2[i] = met->m[met->size*pt->v[2]+i];
479 }
480
481 for (i=0; i<6; i++) {
482 dm3[i] = met->m[met->size*pt->v[3]+i];
483 }
484 return MMG5_interp4barintern(met,ip,cb,dm0,dm1,dm2,dm3);
485}
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 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:462
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:101
int MMG5_intvolmet(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k, int8_t i, double s, double mr[6])
Definition: intmet_3d.c:260
int MMG5_interp4bar_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k, MMG5_int ip, double cb[4])
Definition: intmet_3d.c:390
int MMG5_interp4bar_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k, MMG5_int ip, double cb[4])
Definition: intmet_3d.c:320
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:131
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:51
static int MMG5_intregvolmet(double *ma, double *mb, double *mp, double t)
Definition: intmet_3d.c:215
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:348
int MMG5_intregmet(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k, int8_t i, double s, double mr[6])
Definition: intmet_3d.c:162
MMG5_int MMG3D_indPt(MMG5_pMesh mesh, MMG5_int kp)
Definition: tools_3d.c:916
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:860
#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:532
MMG mesh structure.
Definition: libmmgtypes.h:605
MMG5_Info info
Definition: libmmgtypes.h:651
MMG5_pPoint point
Definition: libmmgtypes.h:641
MMG5_pxPoint xpoint
Definition: libmmgtypes.h:642
MMG5_pTetra tetra
Definition: libmmgtypes.h:643
MMG5_pxTetra xtetra
Definition: libmmgtypes.h:644
Structure to store points of a MMG mesh.
Definition: libmmgtypes.h:270
int16_t tag
Definition: libmmgtypes.h:284
MMG5_int xp
Definition: libmmgtypes.h:279
double * m
Definition: libmmgtypes.h:671
MMG5_int v[4]
Definition: libmmgtypes.h:403
MMG5_int xt
Definition: libmmgtypes.h:407
Structure to store surface points of a MMG mesh.
Definition: libmmgtypes.h:294
double n1[3]
Definition: libmmgtypes.h:295
Structure to store the surface tetrahedra of a MMG mesh.
Definition: libmmgtypes.h:418
int16_t ftag[4]
Definition: libmmgtypes.h:423
int16_t tag[6]
Definition: libmmgtypes.h:425