Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
inlined_functions_3d_private.h
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
34#include "libmmg3d_private.h"
37
38#ifndef _INLINED_FUNCT_3D_H
39#define _INLINED_FUNCT_3D_H
40
41
55static
56inline double MMG5_lenedgCoor_ani(double *ca,double *cb,double *sa,double *sb) {
57 double ux,uy,uz,dd1,dd2,len;
58
59 ux = cb[0] - ca[0];
60 uy = cb[1] - ca[1];
61 uz = cb[2] - ca[2];
62
63 dd1 = sa[0]*ux*ux + sa[3]*uy*uy + sa[5]*uz*uz \
64 + 2.0*(sa[1]*ux*uy + sa[2]*ux*uz + sa[4]*uy*uz);
65 if ( dd1 <= 0.0 ) dd1 = 0.0;
66
67 dd2 = sb[0]*ux*ux + sb[3]*uy*uy + sb[5]*uz*uz \
68 + 2.0*(sb[1]*ux*uy + sb[2]*ux*uz + sb[4]*uy*uz);
69 if ( dd2 <= 0.0 ) dd2 = 0.0;
70
71 /*longueur approchee*/
72 /*precision a 3.5 10e-3 pres*/
73 if(fabs(dd1-dd2) < 0.05 ) {
74 len = sqrt(0.5*(dd1+dd2));
75 return len;
76 }
77 len = (sqrt(dd1)+sqrt(dd2)+4.0*sqrt(0.5*(dd1+dd2))) / 6.0;
78
79 return len;
80}
81
96static
97inline double MMG5_lenedg33_ani(MMG5_pMesh mesh ,MMG5_pSol met, int ia,
98 MMG5_pTetra pt)
99{
100 MMG5_int ip1,ip2;
101 int8_t isedg;
102
103 ip1 = pt->v[MMG5_iare[ia][0]];
104 ip2 = pt->v[MMG5_iare[ia][1]];
105
106 if ( pt->xt && (mesh->xtetra[pt->xt].tag[ia] & MG_BDY)) {
107 isedg = ( mesh->xtetra[pt->xt].tag[ia] & MG_GEO);
108 // Computation of the length of a curve edge with 33 aniso metric
109 return MMG5_lenSurfEdg33_ani(mesh, met, ip1, ip2, isedg);
110 } else {
111 // Computation for an internal edge with 33 aniso metric
112 return MMG5_lenedgCoor_ani(mesh->point[ip1].c,mesh->point[ip2].c,
113 &met->m[6*ip1],&met->m[6*ip2]);
114 }
115 return 0.0;
116}
117
129static
131 MMG5_pTetra pt)
132{
133 MMG5_pPoint pp1,pp2;
134 double *m1,*m2;
135 MMG5_int ip1,ip2;
136
137 ip1 = pt->v[MMG5_iare[ia][0]];
138 ip2 = pt->v[MMG5_iare[ia][1]];
139
140 pp1 = &mesh->point[ip1];
141 pp2 = &mesh->point[ip2];
142
143 m1 = &met->m[6*ip1];
144 m2 = &met->m[6*ip2];
145
146 return MMG5_lenedgCoor_ani(pp1->c,pp2->c,m1,m2);
147}
148
149
150
162static
163inline double MMG5_lenedgspl_ani(MMG5_pMesh mesh ,MMG5_pSol met, int ia,
164 MMG5_pTetra pt)
165{
166 MMG5_pPoint pp1,pp2;
167 double m1[6],m2[6];
168 MMG5_int ip1,ip2;
169 int i;
170
171 ip1 = pt->v[MMG5_iare[ia][0]];
172 ip2 = pt->v[MMG5_iare[ia][1]];
173
174 pp1 = &mesh->point[ip1];
175 pp2 = &mesh->point[ip2];
176
177 if ( MG_RID(pp1->tag) ) {
178 if ( !MMG5_moymet(mesh,met,pt,m1) ) return 0;
179 } else {
180 for ( i=0; i<6; ++i )
181 m1[i] = met->m[6*ip1+i];
182 }
183
184 if ( MG_RID(pp2->tag) ) {
185 if ( !MMG5_moymet(mesh,met,pt,m2) ) return 0;
186 } else {
187 for ( i=0; i<6; ++i )
188 m2[i] = met->m[6*ip2+i];
189 }
190
191 return MMG5_lenedgCoor_ani(pp1->c,pp2->c,m1,m2);
192}
193
209static
210inline double MMG5_lenedg_ani(MMG5_pMesh mesh ,MMG5_pSol met, int ia,
211 MMG5_pTetra pt)
212{
213 MMG5_int ip1,ip2;
214 int8_t isedg;
215
216 ip1 = pt->v[MMG5_iare[ia][0]];
217 ip2 = pt->v[MMG5_iare[ia][1]];
218
219 if ( pt->xt && (mesh->xtetra[pt->xt].tag[ia] & MG_BDY)) {
220 isedg = ( mesh->xtetra[pt->xt].tag[ia] & MG_GEO);
221 // Computation of the length of a curve edge with ridge metric
222 return MMG5_lenSurfEdg_ani(mesh, met, ip1, ip2, isedg);
223 } else {
224 // Computation for an internal edge with ridge metric
225 return MMG5_lenedgspl_ani(mesh ,met, ia, pt);
226 }
227 return 0.0;
228}
229
241static
242inline double MMG5_lenedg_iso(MMG5_pMesh mesh,MMG5_pSol met,int ia,
243 MMG5_pTetra pt) {
244 MMG5_int ip1,ip2;
245
246 ip1 = pt->v[MMG5_iare[ia][0]];
247 ip2 = pt->v[MMG5_iare[ia][1]];
248 return MMG5_lenSurfEdg_iso(mesh,met,ip1,ip2,0);
249}
250
251static
252inline double MMG5_lenedgspl_iso(MMG5_pMesh mesh ,MMG5_pSol met, int ia,
253 MMG5_pTetra pt) {
254 MMG5_int ip1,ip2;
255
256 ip1 = pt->v[MMG5_iare[ia][0]];
257 ip2 = pt->v[MMG5_iare[ia][1]];
258
259 return MMG5_lenSurfEdg_iso(mesh,met,ip1,ip2,0);
260
261}
262
263
273static
274inline double MMG5_orcal(MMG5_pMesh mesh,MMG5_pSol met,MMG5_int iel) {
275 MMG5_pTetra pt;
276
277 pt = &mesh->tetra[iel];
278
279 return MMG5_caltet(mesh,met,pt);
280}
281
282
294static
296 double ct[12],cs[3],rad,Vref,V,cal;
297 int j,l;
298
299 for (j=0,l=0; j<4; j++,l+=3) {
300 memcpy(&ct[l],mesh->point[pt->v[j]].c,3*sizeof(double));
301 }
302
303 if(!MMG5_cenrad_iso(mesh,ct,cs,&rad)) {
304 return 0.0;
305 }
306
307 assert(rad>0.);
308
309 /* Vref volume */
310 Vref = 8.*sqrt(3)/27.*rad*sqrt(rad);
311
312 V = MMG5_orvol(mesh->point,pt->v) * MMG3D_DET2VOL;
313
314 if ( V<0. ) {
315 return 0.0;
316 }
317
318 cal = V/Vref; //1-Qles in order to have the best quality equal to 1
319
320 /* Prevent calities > 1 due to the machin epsilon */
321 cal = MG_MIN (1., cal);
322
323 // the normalization by ALPHAD
324 //in order to be coherent with the other quality measure
325 return cal/MMG3D_ALPHAD;
326}
327
339static
340inline double MMG5_caltet_iso_4pt(double *a, double *b, double *c, double *d) {
341 double abx,aby,abz,acx,acy,acz,adx,ady,adz,bcx,bcy,bcz,bdx,bdy,bdz;
342 double cdx,cdy,cdz;
343 double vol,v1,v2,v3,rap;
344
345 /* volume: (ac^ad).ab/6. Note that here we compute 6*vol. */
346 abx = b[0] - a[0];
347 aby = b[1] - a[1];
348 abz = b[2] - a[2];
349 rap = abx*abx + aby*aby + abz*abz;
350
351 acx = c[0] - a[0];
352 acy = c[1] - a[1];
353 acz = c[2] - a[2];
354 rap += acx*acx + acy*acy + acz*acz;
355
356 adx = d[0] - a[0];
357 ady = d[1] - a[1];
358 adz = d[2] - a[2];
359 rap += adx*adx + ady*ady + adz*adz;
360
361 v1 = acy*adz - acz*ady;
362 v2 = acz*adx - acx*adz;
363 v3 = acx*ady - acy*adx;
364 vol = abx * v1 + aby * v2 + abz * v3;
365 if ( vol < MMG5_EPSD2 ) return 0.0;
366
367 bcx = c[0] - b[0];
368 bcy = c[1] - b[1];
369 bcz = c[2] - b[2];
370 rap += bcx*bcx + bcy*bcy + bcz*bcz;
371
372 bdx = d[0] - b[0];
373 bdy = d[1] - b[1];
374 bdz = d[2] - b[2];
375 rap += bdx*bdx + bdy*bdy + bdz*bdz;
376
377 cdx = d[0] - c[0];
378 cdy = d[1] - c[1];
379 cdz = d[2] - c[2];
380 rap += cdx*cdx + cdy*cdy + cdz*cdz;
381 if ( rap < MMG5_EPSD2 ) return 0.0;
382
383 /* quality = 6*vol / len^3/2. Q = 1/(12 sqrt(3)) for the regular tetra of length 1. */
384 rap = rap * sqrt(rap);
385 return vol / rap;
386}
387
398static
400 double *a,*b,*c,*d;
401 MMG5_int ia, ib, ic, id;
402
403 ia = pt->v[0];
404 ib = pt->v[1];
405 ic = pt->v[2];
406 id = pt->v[3];
407
408 a = mesh->point[ia].c;
409 b = mesh->point[ib].c;
410 c = mesh->point[ic].c;
411 d = mesh->point[id].c;
412
413 return MMG5_caltet_iso_4pt(a,b,c,d);
414
415}
416
428static
430 double cal,abx,aby,abz,acx,acy,acz,adx,ady,adz;
431 double h1,h2,h3,h4,h5,h6,det,vol,rap,v1,v2,v3,num;
432 double bcx,bcy,bcz,bdx,bdy,bdz,cdx,cdy,cdz;
433 double *a,*b,*c,*d;
434 double mm[6];
435 MMG5_int ip[4];
436
437 ip[0] = pt->v[0];
438 ip[1] = pt->v[1];
439 ip[2] = pt->v[2];
440 ip[3] = pt->v[3];
441
442 /* average metric */
443 if ( !MMG5_moymet(mesh,met,pt,&mm[0]) )
444 return (0.0);
445
446 a = mesh->point[ip[0]].c;
447 b = mesh->point[ip[1]].c;
448 c = mesh->point[ip[2]].c;
449 d = mesh->point[ip[3]].c;
450
451 /* volume */
452 abx = b[0] - a[0];
453 aby = b[1] - a[1];
454 abz = b[2] - a[2];
455
456 acx = c[0] - a[0];
457 acy = c[1] - a[1];
458 acz = c[2] - a[2];
459
460 adx = d[0] - a[0];
461 ady = d[1] - a[1];
462 adz = d[2] - a[2];
463
464 bcx = c[0] - b[0];
465 bcy = c[1] - b[1];
466 bcz = c[2] - b[2];
467
468 bdx = d[0] - b[0];
469 bdy = d[1] - b[1];
470 bdz = d[2] - b[2];
471
472 cdx = d[0] - c[0];
473 cdy = d[1] - c[1];
474 cdz = d[2] - c[2];
475
476 v1 = acy*adz - acz*ady;
477 v2 = acz*adx - acx*adz;
478 v3 = acx*ady - acy*adx;
479 vol = abx * v1 + aby * v2 + abz * v3;
480 if ( vol <= 0. ) return 0.0;
481
482 det = mm[0] * ( mm[3]*mm[5] - mm[4]*mm[4]) \
483 - mm[1] * ( mm[1]*mm[5] - mm[2]*mm[4]) \
484 + mm[2] * ( mm[1]*mm[4] - mm[2]*mm[3]);
485 if ( det < MMG5_EPSD2 ) {
486 return 0.0;
487 }
488 det = sqrt(det) * vol;
489
490 /* edge lengths */
491 h1 = mm[0]*abx*abx + mm[3]*aby*aby + mm[5]*abz*abz
492 + 2.0*(mm[1]*abx*aby + mm[2]*abx*abz + mm[4]*aby*abz);
493 h2 = mm[0]*acx*acx + mm[3]*acy*acy + mm[5]*acz*acz
494 + 2.0*(mm[1]*acx*acy + mm[2]*acx*acz + mm[4]*acy*acz);
495 h3 = mm[0]*adx*adx + mm[3]*ady*ady + mm[5]*adz*adz
496 + 2.0*(mm[1]*adx*ady + mm[2]*adx*adz + mm[4]*ady*adz);
497 h4 = mm[0]*bcx*bcx + mm[3]*bcy*bcy + mm[5]*bcz*bcz
498 + 2.0*(mm[1]*bcx*bcy + mm[2]*bcx*bcz + mm[4]*bcy*bcz);
499 h5 = mm[0]*bdx*bdx + mm[3]*bdy*bdy + mm[5]*bdz*bdz
500 + 2.0*(mm[1]*bdx*bdy + mm[2]*bdx*bdz + mm[4]*bdy*bdz);
501 h6 = mm[0]*cdx*cdx + mm[3]*cdy*cdy + mm[5]*cdz*cdz
502 + 2.0*(mm[1]*cdx*cdy + mm[2]*cdx*cdz + mm[4]*cdy*cdz);
503
504 /* quality */
505 rap = h1 + h2 + h3 + h4 + h5 + h6;
506
507 num = sqrt(rap) * rap;
508
509 cal = det / num;
510
511 return cal;
512}
513
514#endif
MMG5_pMesh * mesh
int MMG5_moymet(MMG5_pMesh mesh, MMG5_pSol met, MMG5_pTetra pt, double *m1)
Definition: anisosiz_3d.c:144
int MMG5_cenrad_iso(MMG5_pMesh mesh, double *ct, double *c, double *rad)
Definition: cenrad_3d.c:45
static double MMG5_caltet_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG5_pTetra pt)
static double MMG5_caltet_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG5_pTetra pt)
static double MMG5_caltet_iso_4pt(double *a, double *b, double *c, double *d)
static double MMG5_lenedg_iso(MMG5_pMesh mesh, MMG5_pSol met, int ia, MMG5_pTetra pt)
static double MMG5_lenedg33_ani(MMG5_pMesh mesh, MMG5_pSol met, int ia, MMG5_pTetra pt)
static double MMG3D_caltetLES_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG5_pTetra pt)
static double MMG5_lenedgspl_iso(MMG5_pMesh mesh, MMG5_pSol met, int ia, MMG5_pTetra pt)
static double MMG5_lenedg_ani(MMG5_pMesh mesh, MMG5_pSol met, int ia, MMG5_pTetra pt)
static double MMG5_lenedgspl_ani(MMG5_pMesh mesh, MMG5_pSol met, int ia, MMG5_pTetra pt)
static double MMG5_lenedgCoor_ani(double *ca, double *cb, double *sa, double *sb)
inlined Functions
static double MMG5_lenedgspl33_ani(MMG5_pMesh mesh, MMG5_pSol met, int ia, MMG5_pTetra pt)
static double MMG5_orcal(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int iel)
static double MMG5_lenSurfEdg_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int ip1, MMG5_int ip2, int8_t isedg)
static double MMG5_lenSurfEdg33_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int np0, MMG5_int np1, int8_t isedg)
static double MMG5_lenSurfEdg_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int np0, MMG5_int np1, int8_t isedg)
#define MMG3D_ALPHAD
#define MMG3D_DET2VOL
static const uint8_t MMG5_iare[6][2]
vertices of extremities of the edges of the tetra
#define MG_GEO
#define MG_MIN(a, b)
#define MG_RID(tag)
double MMG5_orvol(MMG5_pPoint point, MMG5_int *v)
Definition: tools.c:951
#define MG_BDY
#define MMG5_EPSD2
MMG mesh structure.
Definition: libmmgtypes.h:613
MMG5_pPoint point
Definition: libmmgtypes.h:649
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
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
uint16_t tag[6]
Definition: libmmgtypes.h:432