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
93static
94inline double MMG5_lenedg33_ani(MMG5_pMesh mesh ,MMG5_pSol met, int ia,
95 MMG5_pTetra pt)
96{
97 MMG5_int ip1,ip2;
98 int8_t isedg;
99
100 ip1 = pt->v[MMG5_iare[ia][0]];
101 ip2 = pt->v[MMG5_iare[ia][1]];
102
103 if ( pt->xt && (mesh->xtetra[pt->xt].tag[ia] & MG_BDY)) {
104 isedg = ( mesh->xtetra[pt->xt].tag[ia] & MG_GEO);
105 return MMG5_lenSurfEdg33_ani(mesh, met, ip1, ip2, isedg);
106 } else {
107 return MMG5_lenedgCoor_ani(mesh->point[ip1].c,mesh->point[ip2].c,
108 &met->m[6*ip1],&met->m[6*ip2]);
109 }
110 return 0.0;
111}
112
124static
126 MMG5_pTetra pt)
127{
128 MMG5_pPoint pp1,pp2;
129 double *m1,*m2;
130 MMG5_int ip1,ip2;
131
132 ip1 = pt->v[MMG5_iare[ia][0]];
133 ip2 = pt->v[MMG5_iare[ia][1]];
134
135 pp1 = &mesh->point[ip1];
136 pp2 = &mesh->point[ip2];
137
138 m1 = &met->m[6*ip1];
139 m2 = &met->m[6*ip2];
140
141 return MMG5_lenedgCoor_ani(pp1->c,pp2->c,m1,m2);
142}
143
144
145
157static
158inline double MMG5_lenedgspl_ani(MMG5_pMesh mesh ,MMG5_pSol met, int ia,
159 MMG5_pTetra pt)
160{
161 MMG5_pPoint pp1,pp2;
162 double m1[6],m2[6];
163 MMG5_int ip1,ip2;
164 int i;
165
166 ip1 = pt->v[MMG5_iare[ia][0]];
167 ip2 = pt->v[MMG5_iare[ia][1]];
168
169 pp1 = &mesh->point[ip1];
170 pp2 = &mesh->point[ip2];
171
172 if ( MG_RID(pp1->tag) ) {
173 if ( !MMG5_moymet(mesh,met,pt,m1) ) return 0;
174 } else {
175 for ( i=0; i<6; ++i )
176 m1[i] = met->m[6*ip1+i];
177 }
178
179 if ( MG_RID(pp2->tag) ) {
180 if ( !MMG5_moymet(mesh,met,pt,m2) ) return 0;
181 } else {
182 for ( i=0; i<6; ++i )
183 m2[i] = met->m[6*ip2+i];
184 }
185
186 return MMG5_lenedgCoor_ani(pp1->c,pp2->c,m1,m2);
187}
188
200static
201inline double MMG5_lenedg_ani(MMG5_pMesh mesh ,MMG5_pSol met, int ia,
202 MMG5_pTetra pt)
203{
204 MMG5_int ip1,ip2;
205 int8_t isedg;
206
207 ip1 = pt->v[MMG5_iare[ia][0]];
208 ip2 = pt->v[MMG5_iare[ia][1]];
209
210 if ( pt->xt && (mesh->xtetra[pt->xt].tag[ia] & MG_BDY)) {
211 isedg = ( mesh->xtetra[pt->xt].tag[ia] & MG_GEO);
212 return MMG5_lenSurfEdg_ani(mesh, met, ip1, ip2, isedg);
213 } else {
214 return MMG5_lenedgspl_ani(mesh ,met, ia, pt);
215 }
216 return 0.0;
217}
218
230static
231inline double MMG5_lenedg_iso(MMG5_pMesh mesh,MMG5_pSol met,int ia,
232 MMG5_pTetra pt) {
233 MMG5_int ip1,ip2;
234
235 ip1 = pt->v[MMG5_iare[ia][0]];
236 ip2 = pt->v[MMG5_iare[ia][1]];
237 return MMG5_lenSurfEdg_iso(mesh,met,ip1,ip2,0);
238}
239
240static
241inline double MMG5_lenedgspl_iso(MMG5_pMesh mesh ,MMG5_pSol met, int ia,
242 MMG5_pTetra pt) {
243 MMG5_int ip1,ip2;
244
245 ip1 = pt->v[MMG5_iare[ia][0]];
246 ip2 = pt->v[MMG5_iare[ia][1]];
247
248 return MMG5_lenSurfEdg_iso(mesh,met,ip1,ip2,0);
249
250}
251
252
262static
263inline double MMG5_orcal(MMG5_pMesh mesh,MMG5_pSol met,MMG5_int iel) {
264 MMG5_pTetra pt;
265
266 pt = &mesh->tetra[iel];
267
268 return MMG5_caltet(mesh,met,pt);
269}
270
271
283static
285 double ct[12],cs[3],rad,Vref,V,cal;
286 int j,l;
287
288 for (j=0,l=0; j<4; j++,l+=3) {
289 memcpy(&ct[l],mesh->point[pt->v[j]].c,3*sizeof(double));
290 }
291
292 if(!MMG5_cenrad_iso(mesh,ct,cs,&rad)) {
293 return 0.0;
294 }
295
296 assert(rad>0.);
297
298 /* Vref volume */
299 Vref = 8.*sqrt(3)/27.*rad*sqrt(rad);
300
301 V = MMG5_orvol(mesh->point,pt->v) * MMG3D_DET2VOL;
302
303 if ( V<0. ) {
304 return 0.0;
305 }
306
307 cal = V/Vref; //1-Qles in order to have the best quality equal to 1
308
309 /* Prevent calities > 1 due to the machin epsilon */
310 cal = MG_MIN (1., cal);
311
312 // the normalization by ALPHAD
313 //in order to be coherent with the other quality measure
314 return cal/MMG3D_ALPHAD;
315}
316
328static
329inline double MMG5_caltet_iso_4pt(double *a, double *b, double *c, double *d) {
330 double abx,aby,abz,acx,acy,acz,adx,ady,adz,bcx,bcy,bcz,bdx,bdy,bdz;
331 double cdx,cdy,cdz;
332 double vol,v1,v2,v3,rap;
333
334 /* volume: (ac^ad).ab/6. Note that here we compute 6*vol. */
335 abx = b[0] - a[0];
336 aby = b[1] - a[1];
337 abz = b[2] - a[2];
338 rap = abx*abx + aby*aby + abz*abz;
339
340 acx = c[0] - a[0];
341 acy = c[1] - a[1];
342 acz = c[2] - a[2];
343 rap += acx*acx + acy*acy + acz*acz;
344
345 adx = d[0] - a[0];
346 ady = d[1] - a[1];
347 adz = d[2] - a[2];
348 rap += adx*adx + ady*ady + adz*adz;
349
350 v1 = acy*adz - acz*ady;
351 v2 = acz*adx - acx*adz;
352 v3 = acx*ady - acy*adx;
353 vol = abx * v1 + aby * v2 + abz * v3;
354 if ( vol < MMG5_EPSD2 ) return 0.0;
355
356 bcx = c[0] - b[0];
357 bcy = c[1] - b[1];
358 bcz = c[2] - b[2];
359 rap += bcx*bcx + bcy*bcy + bcz*bcz;
360
361 bdx = d[0] - b[0];
362 bdy = d[1] - b[1];
363 bdz = d[2] - b[2];
364 rap += bdx*bdx + bdy*bdy + bdz*bdz;
365
366 cdx = d[0] - c[0];
367 cdy = d[1] - c[1];
368 cdz = d[2] - c[2];
369 rap += cdx*cdx + cdy*cdy + cdz*cdz;
370 if ( rap < MMG5_EPSD2 ) return 0.0;
371
372 /* quality = 6*vol / len^3/2. Q = 1/(12 sqrt(3)) for the regular tetra of length 1. */
373 rap = rap * sqrt(rap);
374 return vol / rap;
375}
376
387static
389 double *a,*b,*c,*d;
390 MMG5_int ia, ib, ic, id;
391
392 ia = pt->v[0];
393 ib = pt->v[1];
394 ic = pt->v[2];
395 id = pt->v[3];
396
397 a = mesh->point[ia].c;
398 b = mesh->point[ib].c;
399 c = mesh->point[ic].c;
400 d = mesh->point[id].c;
401
402 return MMG5_caltet_iso_4pt(a,b,c,d);
403
404}
405
417static
419 double cal,abx,aby,abz,acx,acy,acz,adx,ady,adz;
420 double h1,h2,h3,h4,h5,h6,det,vol,rap,v1,v2,v3,num;
421 double bcx,bcy,bcz,bdx,bdy,bdz,cdx,cdy,cdz;
422 double *a,*b,*c,*d;
423 double mm[6];
424 MMG5_int ip[4];
425
426 ip[0] = pt->v[0];
427 ip[1] = pt->v[1];
428 ip[2] = pt->v[2];
429 ip[3] = pt->v[3];
430
431 /* average metric */
432 if ( !MMG5_moymet(mesh,met,pt,&mm[0]) )
433 return (0.0);
434
435 a = mesh->point[ip[0]].c;
436 b = mesh->point[ip[1]].c;
437 c = mesh->point[ip[2]].c;
438 d = mesh->point[ip[3]].c;
439
440 /* volume */
441 abx = b[0] - a[0];
442 aby = b[1] - a[1];
443 abz = b[2] - a[2];
444
445 acx = c[0] - a[0];
446 acy = c[1] - a[1];
447 acz = c[2] - a[2];
448
449 adx = d[0] - a[0];
450 ady = d[1] - a[1];
451 adz = d[2] - a[2];
452
453 bcx = c[0] - b[0];
454 bcy = c[1] - b[1];
455 bcz = c[2] - b[2];
456
457 bdx = d[0] - b[0];
458 bdy = d[1] - b[1];
459 bdz = d[2] - b[2];
460
461 cdx = d[0] - c[0];
462 cdy = d[1] - c[1];
463 cdz = d[2] - c[2];
464
465 v1 = acy*adz - acz*ady;
466 v2 = acz*adx - acx*adz;
467 v3 = acx*ady - acy*adx;
468 vol = abx * v1 + aby * v2 + abz * v3;
469 if ( vol <= 0. ) return 0.0;
470
471 det = mm[0] * ( mm[3]*mm[5] - mm[4]*mm[4]) \
472 - mm[1] * ( mm[1]*mm[5] - mm[2]*mm[4]) \
473 + mm[2] * ( mm[1]*mm[4] - mm[2]*mm[3]);
474 if ( det < MMG5_EPSD2 ) {
475 return 0.0;
476 }
477 det = sqrt(det) * vol;
478
479 /* edge lengths */
480 h1 = mm[0]*abx*abx + mm[3]*aby*aby + mm[5]*abz*abz
481 + 2.0*(mm[1]*abx*aby + mm[2]*abx*abz + mm[4]*aby*abz);
482 h2 = mm[0]*acx*acx + mm[3]*acy*acy + mm[5]*acz*acz
483 + 2.0*(mm[1]*acx*acy + mm[2]*acx*acz + mm[4]*acy*acz);
484 h3 = mm[0]*adx*adx + mm[3]*ady*ady + mm[5]*adz*adz
485 + 2.0*(mm[1]*adx*ady + mm[2]*adx*adz + mm[4]*ady*adz);
486 h4 = mm[0]*bcx*bcx + mm[3]*bcy*bcy + mm[5]*bcz*bcz
487 + 2.0*(mm[1]*bcx*bcy + mm[2]*bcx*bcz + mm[4]*bcy*bcz);
488 h5 = mm[0]*bdx*bdx + mm[3]*bdy*bdy + mm[5]*bdz*bdz
489 + 2.0*(mm[1]*bdx*bdy + mm[2]*bdx*bdz + mm[4]*bdy*bdz);
490 h6 = mm[0]*cdx*cdx + mm[3]*cdy*cdy + mm[5]*cdz*cdz
491 + 2.0*(mm[1]*cdx*cdy + mm[2]*cdx*cdz + mm[4]*cdy*cdz);
492
493 /* quality */
494 rap = h1 + h2 + h3 + h4 + h5 + h6;
495
496 num = sqrt(rap) * rap;
497
498 cal = det / num;
499
500 return cal;
501}
502
503#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:605
MMG5_pPoint point
Definition: libmmgtypes.h:641
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
double c[3]
Definition: libmmgtypes.h:271
double * m
Definition: libmmgtypes.h:671
MMG5_int v[4]
Definition: libmmgtypes.h:403
MMG5_int xt
Definition: libmmgtypes.h:407
int16_t tag[6]
Definition: libmmgtypes.h:425