Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
length_2d.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#include "libmmg2d_private.h"
25
26/* Compute isotropic edge length */
27double long_iso(double *ca,double *cb,double *ma,double *mb) {
28 double ha,hb,ux,uy,dd,rap,len;
29
30 ha = *ma;
31 hb = *mb;
32 ux = cb[0] - ca[0];
33 uy = cb[1] - ca[1];
34 dd = sqrt(ux*ux + uy*uy);
35
36 rap = (hb - ha) / ha;
37 if ( fabs(rap) < MMG2D_EPSD )
38 len = dd / ha;
39 else
40 len = dd * (1.0/ha + 1.0/hb + 8.0 / (ha+hb)) / 6.0;
41
42 return len;
43}
44
45
46/* compute aniso edge length */
47double long_ani(double *ca,double *cb,double *ma,double *mb) {
48 double ux,uy,dd1,dd2,len;
49 ux = cb[0] - ca[0];
50 uy = cb[1] - ca[1];
51
52 dd1 = ma[0]*ux*ux + ma[2]*uy*uy + 2.0*ma[1]*ux*uy;
53 if ( dd1 <= 0.0 ) dd1 = 0.0;
54 dd2 = mb[0]*ux*ux + mb[2]*uy*uy + 2.0*mb[1]*ux*uy;
55 if ( dd2 <= 0.0 ) dd2 = 0.0;
56
57 len = (sqrt(dd1)+sqrt(dd2)+4.0*sqrt(0.5*(dd1+dd2))) / 6.0;
58
59 return len;
60}
61
63double MMG2D_lencurv_iso(MMG5_pMesh mesh,MMG5_pSol met,MMG5_int ip1,MMG5_int ip2) {
64 MMG5_pPoint p1,p2;
65 double h1,h2,len,l,r;
66
67 p1 = &mesh->point[ip1];
68 p2 = &mesh->point[ip2];
69
70 h1 = met->m[ip1];
71 h2 = met->m[ip2];
72
73 l = (p2->c[0]-p1->c[0])*(p2->c[0]-p1->c[0]) + (p2->c[1]-p1->c[1])*(p2->c[1]-p1->c[1]);
74 l = sqrt(l);
75 r = h2 / h1 - 1.0;
76 len = ( fabs(r) < MMG5_EPS ) ? ( l/h1 ) : ( l / (h2-h1) * log1p(r) );
77
78 return len;
79}
80
81/* Calculate length of a curve in the considered anisotropic metric by using a two-point quadrature formula */
82double MMG2D_lencurv_ani(MMG5_pMesh mesh,MMG5_pSol met,MMG5_int ip1,MMG5_int ip2) {
83 MMG5_pPoint p1,p2;
84 double len,*m1,*m2,ux,uy,l1,l2;
85 static int8_t mmgWarn0=0,mmgWarn1=0;
86
87 p1 = &mesh->point[ip1];
88 p2 = &mesh->point[ip2];
89
90 m1 = &met->m[3*ip1];
91 m2 = &met->m[3*ip2];
92
93 ux = p2->c[0] - p1->c[0];
94 uy = p2->c[1] - p1->c[1];
95
96 l1 = m1[0]*ux*ux + 2.0*m1[1]*ux*uy + m1[2]*uy*uy;
97 l2 = m2[0]*ux*ux + 2.0*m2[1]*ux*uy + m2[2]*uy*uy;
98
99 if ( l1 < 0.0 ) {
100 if ( !mmgWarn0 ) {
101 mmgWarn0 = 1;
102 fprintf(stderr,"\n ## Error: %s: at least 1 negative edge length"
103 " (l1: %e).\n",__func__,l1);
104 }
105 return 0.;
106 }
107 if ( l2 < 0.0 ) {
108 if ( !mmgWarn1 ) {
109 mmgWarn1 = 1;
110 fprintf(stderr,"\n ## Error: %s: at least 1 negative edge length"
111 " (l2: %e)\n",__func__,l2);
112 }
113 return 0.;
114 }
115
116 l1 = sqrt(l1);
117 l2 = sqrt(l2);
118
119 len = 0.5*(l1+l2);
120
121 return len;
122}
123
124/* print histo of edge lengths */
126 MMG5_pTria pt;
127 double lavg,len,lmin,lmax;
128 int ia,ipa,ipb;
129 MMG5_int iamin,ibmin,iamax,ibmax,hl[9],nullEdge,navg;
130 static double bd[9] = {0.0, 0.3, 0.6, 0.7071, 0.9, 1.3, 1.4142, 2.0, 5.0};
131 MMG5_int k,l;
132
133 navg = 0;
134 lavg = 0.0;
135 lmin = 1.e20;
136 lmax = 0.0;
137 iamin = 0;
138 ibmin = 0;
139 iamax = 0;
140 ibmax = 0;
141 nullEdge = 0;
142
143 for (k=0; k<9; k++) hl[k] = 0;
144
145 for (k=1; k<=mesh->nt; k++) {
146 pt = &mesh->tria[k];
147 if ( !MG_EOK(pt) ) continue;
148
149 for (ia=0; ia<3; ia++) {
150 l = (&mesh->adja[3*(k-1)+1])[ia];
151 if ( l < 3*k ) continue;
152
153 ipa = MMG2D_iare[ia][0];
154 ipb = MMG2D_iare[ia][1];
155
156 if ( sol->m )
157 len = MMG2D_lencurv(mesh,sol,pt->v[ipa],pt->v[ipb]);
158 else
159 len = MMG2D_lencurv_iso(mesh,sol,pt->v[ipa],pt->v[ipb]);
160
161 navg++;
162 lavg += len;
163
164 /* find largest, smallest edge */
165 if (len < lmin) {
166 lmin = len;
167 iamin = pt->v[ipa];
168 ibmin = pt->v[ipb];
169 }
170 if (len > lmax) {
171 lmax = len;
172 iamax = pt->v[ipa];
173 ibmax = pt->v[ipb];
174 }
175
176 /* update histogram */
177 if (len < bd[3]) {
178 if (len > bd[2]) hl[2]++;
179 else if (len > bd[1]) hl[1]++;
180 else hl[0]++;
181 }
182 else if (len < bd[5]) {
183 if (len > bd[4]) hl[4]++;
184 else if (len > bd[3]) hl[3]++;
185 }
186 else if (len < bd[6]) hl[5]++;
187 else if (len < bd[7]) hl[6]++;
188 else if (len < bd[8]) hl[7]++;
189 else hl[8]++;
190 }
191 }
192 MMG5_displayLengthHisto(mesh, navg, &lavg, iamin, ibmin, lmin,
193 iamax, ibmax, lmax,nullEdge, &bd[0], &hl[0],0);
194
195
196 return 1;
197}
MMG5_pMesh MMG5_pSol * sol
MMG5_pMesh * mesh
#define MMG5_EPS
double MMG2D_lencurv_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int ip1, MMG5_int ip2)
Definition: length_2d.c:63
double MMG2D_lencurv_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int ip1, MMG5_int ip2)
Definition: length_2d.c:82
double long_ani(double *ca, double *cb, double *ma, double *mb)
Definition: length_2d.c:47
int MMG2D_prilen(MMG5_pMesh mesh, MMG5_pSol sol)
Definition: length_2d.c:125
double long_iso(double *ca, double *cb, double *ma, double *mb)
Definition: length_2d.c:27
static const int MMG2D_iare[3][2]
#define MMG2D_EPSD
#define MG_EOK(pt)
void MMG5_displayLengthHisto(MMG5_pMesh, MMG5_int, double *, MMG5_int, MMG5_int, double, MMG5_int, MMG5_int, double, int, double *, MMG5_int *, int8_t)
Definition: quality.c:252
MMG mesh structure.
Definition: libmmgtypes.h:605
MMG5_pPoint point
Definition: libmmgtypes.h:641
MMG5_int * adja
Definition: libmmgtypes.h:624
MMG5_int nt
Definition: libmmgtypes.h:612
MMG5_pTria tria
Definition: libmmgtypes.h:647
Structure to store points of a MMG mesh.
Definition: libmmgtypes.h:270
double c[3]
Definition: libmmgtypes.h:271
double * m
Definition: libmmgtypes.h:671
MMG5_int v[3]
Definition: libmmgtypes.h:334