Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
quality_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*/
34#include "libmmg2d_private.h"
36
47 MMG5_pPoint p0,p1,p2;
48 double cal;
49
50 p0 = &mesh->point[pt->v[0]];
51 p1 = &mesh->point[pt->v[1]];
52 p2 = &mesh->point[pt->v[2]];
53
54 cal = MMG2D_quickarea(p0->c,p1->c,p2->c);
55 return cal;
56}
57
68double MMG2D_caltri_iso_3pt(double *a,double *b,double *c) {
69 double abx,aby,acx,acy,bcx,bcy,area,h1,h2,h3,hm;
70
71 abx = b[0] - a[0];
72 aby = b[1] - a[1];
73 acx = c[0] - a[0];
74 acy = c[1] - a[1];
75 bcx = c[0] - b[0];
76 bcy = c[1] - b[1];
77
78 /* orientation */
79 area = abx*acy - aby*acx;
80 if ( area <= 0.0 ) return 0.0;
81
82 /* edge lengths */
83 h1 = abx*abx + aby*aby;
84 h2 = acx*acx + acy*acy;
85 h3 = bcx*bcx + bcy*bcy;
86
87 hm = h1 + h2 + h3;
88
89 if ( hm > 0. ) {
90 return area / hm;
91 }
92 else {
93 return 0.0;
94 }
95}
96
108 double *a,*b,*c;
109
110 a = mesh->point[pt->v[0]].c;
111 b = mesh->point[pt->v[1]].c;
112 c = mesh->point[pt->v[2]].c;
113
114 return MMG2D_caltri_iso_3pt(a,b,c);
115}
116
117
118
119/* Compute quality of the triangle pt when the supplied metric is anisotropic;
120 return 0 in the case that the triangle has inverted orientation */
122 double abx,aby,acx,acy,bcx,bcy;
123 double *a,*b,*c,*ma,*mb,*mc;
124 double area,aream,hm,m[6],h1,h2,h3;
125 MMG5_int ipa,ipb,ipc;
126 int i;
127
128 ipa = pt->v[0];
129 ipb = pt->v[1];
130 ipc = pt->v[2];
131
132 a = mesh->point[ipa].c;
133 b = mesh->point[ipb].c;
134 c = mesh->point[ipc].c;
135
136 ma = &met->m[3*ipa];
137 mb = &met->m[3*ipb];
138 mc = &met->m[3*ipc];
139
140 /* Isotropic area of pt */
141 abx = b[0] - a[0];
142 aby = b[1] - a[1];
143 acx = c[0] - a[0];
144 acy = c[1] - a[1];
145 bcx = c[0] - b[0];
146 bcy = c[1] - b[1];
147 area = abx*acy - aby*acx;
148 if ( area <= 0.0 ) return 0.0;
149
150 for (i=0; i<3; i++) m[i] = (ma[i]+mb[i]+mc[i]) / 3.0;
151
152 /* Anisotropic edge lengths */
153 h1 = m[0]*abx*abx + m[2]*aby*aby + 2.0*m[1]*abx*aby;
154 h1 = h1 > 0.0 ? sqrt(h1) : 0.0;
155 h2 = m[0]*acx*acx + m[2]*acy*acy + 2.0*m[1]*acx*acy;
156 h2 = h2 > 0.0 ? sqrt(h2) : 0.0;
157 h3 = m[0]*bcx*bcx + m[2]*bcy*bcy + 2.0*m[1]*bcx*bcy;
158 h3 = h3 > 0.0 ? sqrt(h3) : 0.0;
159
160 hm = h1*h1 + h2*h2 + h3*h3;
161
162 /* Anisotropic volume of pt */
163 aream = sqrt(m[0]*m[2]-m[1]*m[1])*area;
164
165 /* Quality measure = (Vol_M(T) / (l(ab)^2+l(ac)^2+l(bc)^2)) */
166 if ( hm > 0. ) {
167 return aream/hm;
168 }
169 else {
170 return (0.0);
171 }
172}
173
184 MMG5_pTria pt;
185 double rap,rapmin,rapmax,rapavg,med,good;
186 int i,ir,imax,his[5];
187 MMG5_int k,iel,ok,nex;
188 static int8_t mmgWarn0;
189
190 /* Compute triangle quality*/
191 for (k=1; k<=mesh->nt; k++) {
192 pt = &mesh->tria[k];
193 if( !MG_EOK(pt) ) continue;
194
195 if ( !met->m ) {
196 pt->qual = MMG2D_caltri_iso(mesh,met,pt);
197 }
198 else
199 pt->qual = MMG2D_caltri(mesh,met,pt);
200 }
201 if ( mesh->info.imprim <= 0 ) return 1;
202
203 rapmin = 2.0;
204 rapmax = 0.0;
205 rapavg = med = good = 0.0;
206 iel = 0;
207
208 for (k=0; k<5; k++) his[k] = 0;
209
210 nex = ok = 0;
211 for (k=1; k<=mesh->nt; k++) {
212 pt = &mesh->tria[k];
213 if( !MG_EOK(pt) ) {
214 nex++;
215 continue;
216 }
217 ok++;
218 if ( (!mmgWarn0) && (MMG2D_quickcal(mesh,pt) < 0.0) ) {
219 mmgWarn0 = 1;
220 fprintf(stderr," ## Warning: %s: at least 1 negative area\n",__func__);
221 }
222
223 if ( !met->m ) {
224 rap = MMG2D_ALPHAD * MMG2D_caltri_iso(mesh,met,pt);
225 }
226 else
227 rap = MMG2D_ALPHAD * MMG2D_caltri(mesh,met,pt);
228
229 if ( rap < rapmin ) {
230 rapmin = rap;
231 iel = ok;
232 }
233 if ( rap > 0.5 ) med++;
234 if ( rap > 0.12 ) good++;
235 if ( rap < MMG2D_BADKAL ) mesh->info.badkal = 1;
236 rapavg += rap;
237 rapmax = MG_MAX(rapmax,rap);
238 ir = MG_MIN(4,(int)(5.0*rap));
239 his[ir] += 1;
240 }
241
242#ifndef DEBUG
243 fprintf(stdout,"\n -- MESH QUALITY %" MMG5_PRId "\n",mesh->nt - nex);
244 fprintf(stdout," BEST %8.6f AVRG. %8.6f WRST. %8.6f (%" MMG5_PRId ")\n",
245 rapmax,rapavg / (mesh->nt-nex),rapmin,iel);
246#else
247 fprintf(stdout," BEST %e AVRG. %e WRST. %e (%" MMG5_PRId ")\n => %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "\n",
248 rapmax,rapavg / (mesh->nt-nex),rapmin,iel,
249 MMG5_indPt(mesh,mesh->tria[iel].v[0]),MMG5_indPt(mesh,mesh->tria[iel].v[1]),
250 MMG5_indPt(mesh,mesh->tria[iel].v[2]));
251#endif
252
253 /* print histo */
254 fprintf(stdout," HISTOGRAMM:");
255 fprintf(stdout," %6.2f %% > 0.12\n",100.0*(good/(float)(mesh->nt-nex)));
256 if ( abs(mesh->info.imprim) > 3 ) {
257 fprintf(stdout," %6.2f %% > 0.5\n",100.0*( med/(float)(mesh->nt-nex)));
258 imax = MG_MIN(4,(int)(5.*rapmax));
259 for (i=imax; i>=(int)(5*rapmin); i--) {
260 fprintf(stdout," %5.1f < Q < %5.1f %7d %6.2f %%\n",
261 i/5.,i/5.+0.2,his[i],100.*(his[i]/(float)(mesh->nt-nex)));
262 }
263 }
264
265 return MMG5_minQualCheck(iel,rapmin,1.);
266}
MMG5_pMesh * mesh
#define MMG2D_BADKAL
#define MMG2D_ALPHAD
int MMG5_minQualCheck(MMG5_int iel, double minqual, double alpha)
Definition: quality.c:343
double MMG2D_quickarea(double a[2], double b[2], double c[2])
Definition: tools.c:971
#define MG_EOK(pt)
#define MG_MIN(a, b)
#define MG_MAX(a, b)
double MMG2D_caltri_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG5_pTria pt)
Definition: quality_2d.c:107
double MMG2D_caltri_iso_3pt(double *a, double *b, double *c)
Definition: quality_2d.c:68
double MMG2D_caltri_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG5_pTria pt)
Definition: quality_2d.c:121
int MMG2D_outqua(MMG5_pMesh mesh, MMG5_pSol met)
Definition: quality_2d.c:183
double MMG2D_quickcal(MMG5_pMesh mesh, MMG5_pTria pt)
Definition: quality_2d.c:46
int8_t badkal
Definition: libmmgtypes.h:533
MMG mesh structure.
Definition: libmmgtypes.h:605
MMG5_Info info
Definition: libmmgtypes.h:651
MMG5_pPoint point
Definition: libmmgtypes.h:641
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
double qual
Definition: libmmgtypes.h:333
MMG5_int v[3]
Definition: libmmgtypes.h:334