Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
chkmsh_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
24#include "libmmg2d.h"
25#include "libmmg2d_private.h"
26
36int MMG5_mmg2dChkmsh(MMG5_pMesh mesh, int severe,MMG5_int base) {
37 MMG5_pPoint ppt;
38 MMG5_pTria pt,pt1,pt2;
39 MMG5_int *adja,*adja1,adj,adj1,k,iadr;
40 int i,j,lon,len;
41 MMG5_int kk,l,nk,ip;
42 MMG5_int *list;
43 uint8_t voy,voy1;
44 static int8_t mmgErr0=0,mmgErr1=0,mmgErr2=0,mmgErr3=0,mmgErr4=0,mmgErr5=0;
45 static int8_t mmgErr6=0,mmgErr7=0,mmgErr8=0,mmgErr9=0,mmgErr10=0,mmgErr11=0;
46 static int8_t mmgErr12=0,mmgErr13=0,mmgErr14=0,mmgErr15=0;
47
49 for (k=1; k<=mesh->nt; k++) {
50 pt1 = &mesh->tria[k];
51 if ( !MG_EOK(pt1) ) continue;
52 iadr = (k-1)*3 + 1;
53 adja = &mesh->adja[iadr];
54
55 for (i=0; i<3; i++) {
56 adj = adja[i] / 3;
57 voy = adja[i] % 3;
58 if ( !adj ) {
59 continue;
60 }
61
62 /* Check that curent elt is not adjacent to itself */
63 if ( adj == k ) {
64 if ( !mmgErr0 ) {
65 mmgErr0 = 1;
66 fprintf(stderr,"\n ## Error: %s: 1. at least 1 wrong"
67 " adjacency %" MMG5_PRId " %" MMG5_PRId "\n",__func__,MMG2D_indElt(mesh,k),
68 MMG2D_indElt(mesh,adj));
69 fprintf(stderr,"vertices of %" MMG5_PRId ": %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " \n",MMG2D_indElt(mesh,k),
70 MMG2D_indPt(mesh,pt1->v[0]),MMG2D_indPt(mesh,pt1->v[1]),
71 MMG2D_indPt(mesh,pt1->v[2]));
72 fprintf(stderr,"adj of %" MMG5_PRId ": %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " \n",
73 k,adja[0]/3,adja[1]/3,adja[2]/3);
74 }
75 return 0;
76 }
77
78 /* Check existence of adja elt */
79 pt2 = &mesh->tria[adj];
80 if ( !MG_EOK(pt2) ) {
81 if ( !mmgErr1 ) {
82 mmgErr1 = 1;
83 fprintf(stderr,"\n ## Error: %s: 4. at least 1 invalid"
84 " adjacent %" MMG5_PRId " %" MMG5_PRId "\n",__func__,MMG2D_indElt(mesh,adj),
86 fprintf(stderr,"vertices of %" MMG5_PRId ": %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "\n",
88 MMG2D_indPt(mesh,pt1->v[1]),MMG2D_indPt(mesh,pt1->v[2]));
89 fprintf(stderr,"vertices adj %" MMG5_PRId ": %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " \n",
90 adj,pt2->v[0],pt2->v[1],pt2->v[2]);
91 fprintf(stderr,"adj of %" MMG5_PRId ": %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "\n",MMG2D_indElt(mesh,k),
92 MMG2D_indElt(mesh,adja[0]/3),MMG2D_indElt(mesh,adja[1]/3),
93 MMG2D_indElt(mesh,adja[2]/3));
94 }
95 return 0;
96 }
97
98 /* Check consistency of adjacency array */
99 iadr = (adj-1)*3 + 1;
100 adja1 = &mesh->adja[iadr];
101 adj1 = adja1[voy] / 3;
102 voy1 = adja1[voy] % 3;
103 if ( adj1 != k || voy1 != i ) {
104 if ( !mmgErr2 ) {
105 mmgErr2 = 1;
106 fprintf(stderr,"\n ## Error: %s: 2. at least 1 inconsistency in adja array"
107 " %" MMG5_PRId " %" MMG5_PRId "\n",__func__,MMG2D_indElt(mesh,k),MMG2D_indElt(mesh,adj1));
108 fprintf(stderr,"vertices of %" MMG5_PRId ": %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " \n",MMG2D_indElt(mesh,k),
109 MMG2D_indPt(mesh,pt1->v[0]),MMG2D_indPt(mesh,pt1->v[1]),
110 MMG2D_indPt(mesh,pt1->v[2]));
111 fprintf(stderr,"adj(k) %" MMG5_PRId ": %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " \n",MMG2D_indElt(mesh,adj),
112 MMG2D_indPt(mesh,pt2->v[0]),MMG2D_indPt(mesh,pt2->v[1]),
113 MMG2D_indPt(mesh,pt2->v[2]));
114 fprintf(stderr,"adj(%" MMG5_PRId "): %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "\n",
115 MMG2D_indElt(mesh,k),MMG2D_indElt(mesh,adja[0]/3),
116 MMG2D_indElt(mesh,adja[1]/3),MMG2D_indElt(mesh,adja[2]/3));
117 fprintf(stderr,"adj(%" MMG5_PRId "): %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "\n",
118 MMG2D_indElt(mesh,adj),MMG2D_indElt(mesh,adja1[0]/3),
119 MMG2D_indElt(mesh,adja1[1]/3),MMG2D_indElt(mesh,adja1[2]/3),
120 MMG2D_indElt(mesh,adja1[3]/3));
121 }
122 return 0;
123 }
124 }
125 }
126
128 for (k=1; k<=mesh->nt; k++) {
129 pt = &mesh->tria[k];
130 if ( !MG_EOK(pt) ) continue;
131
132 for (i=0; i<3; i++) {
133 int i1 = MMG5_inxt2[i];
134 int i2 = MMG5_iprv2[i];
135 /* Check that a GEO edg has GEO or singular vertices (CRN or REQ) */
136 if ( pt->tag[i] & MG_GEO ) {
137 if ( !(mesh->point[pt->v[i1]].tag & MG_GEO) && !( MG_SIN(mesh->point[pt->v[i1]].tag) )) {
138 if ( !mmgErr3 ) {
139 mmgErr3 = 1;
140 fprintf(stderr,"\n ## Error: %s: at least 1 tag inconsistency"
141 " (triangle %" MMG5_PRId ": edge %d, vertex %" MMG5_PRId ")\n",__func__,
142 MMG2D_indElt(mesh,k),i,MMG2D_indPt(mesh,pt->v[i1]));
143 }
144 return 0;
145 }
146 if ( !(mesh->point[pt->v[i2]].tag & MG_GEO) && !( MG_SIN(mesh->point[pt->v[i2]].tag) )) {
147 if ( !mmgErr4 ) {
148 mmgErr4 = 1;
149 fprintf(stderr,"\n ## Error: %s: at least 1 tag inconsistency"
150 " (triangle %" MMG5_PRId ": edge %d, vertex %" MMG5_PRId ")\n",__func__,
151 MMG2D_indElt(mesh,k),i,MMG2D_indPt(mesh,pt->v[i2]));
152 }
153 return 0;
154 }
155 }
156
157 /* Check that a REF edg has REF or singular vertices (CRN or REQ) */
158 if ( pt->tag[i] & MG_REF ) {
159 if ( !(mesh->point[pt->v[i1]].tag & MG_REF) && !( MG_SIN(mesh->point[pt->v[i1]].tag)) ) {
160 if ( !mmgErr5 ) {
161 mmgErr5 = 1;
162 fprintf(stderr,"\n ## Error: %s: at least 1 tag inconsistency"
163 " (triangle %" MMG5_PRId ": edge %d, vertex %" MMG5_PRId ")\n",__func__,
164 MMG2D_indElt(mesh,k),i,MMG2D_indPt(mesh,pt->v[i1]));
165 }
166 return 0;
167 }
168 if ( !(mesh->point[pt->v[i2]].tag & MG_REF) && !( MG_SIN(mesh->point[pt->v[i2]].tag)) ) {
169 if ( !mmgErr6 ) {
170 mmgErr6 = 1;
171 fprintf(stderr,"\n ## Error: %s: at least 1 tag inconsistency"
172 " (triangle %" MMG5_PRId ": edge %d, vertex %" MMG5_PRId ")\n",__func__,
173 MMG2D_indElt(mesh,k),i,MMG2D_indPt(mesh,pt->v[i2]));
174 }
175 return 0;
176 }
177 }
178
179 }
180 }
181
183 for (k=1; k<=mesh->nt; k++) {
184 pt = &mesh->tria[k];
185 if ( !MG_EOK(pt) ) continue;
186
187 adja = &mesh->adja[3*(k-1)+1];
188 for (i=0; i<3; i++) {
189 int i1 = MMG5_inxt2[i];
190 int i2 = MMG5_iprv2[i];
191
192 MMG5_int jel = adja[i] / 3;
193
194 if ( base ) {
195 if ( !jel ) {
196 /* Check that a boundary edge has a bdy tag */
197 if ( !(pt->tag[i] & MG_GEO ) ) {
198 if ( !mmgErr7 ) {
199 mmgErr7 = 1;
200 fprintf(stderr,"\n ## Error: %s: at least 1 wrong edge tag"
201 " (edge %d in tria %" MMG5_PRId ".)\n",
202 __func__,i,MMG2D_indElt(mesh,k));
203 }
204 return 0;
205 }
206 }
207 else if ( pt->tag[i] & MG_GEO ) {
208 /* Check that an internal edge (even between 2 domains) is not MG_GEO
209 * (used to mark opn bdy) */
210 if ( !mmgErr8 ) {
211 mmgErr8 = 1;
212 fprintf(stderr,"\n ## Error: %s: at least 1 edge tagged boundary"
213 " while it has a neighbour (%" MMG5_PRId " %" MMG5_PRId ").\n",__func__,
214 MMG2D_indPt(mesh,pt->v[i1]),MMG2D_indPt(mesh,pt->v[i2]));
215 }
216 return 0;
217 }
218 }
219
220 if ( !mesh->info.opnbdy ) {
221 /* Check that we don't have REF tag between tria of same refs */
222 if ( pt->tag[i] & MG_REF ) {
223 pt1 = &mesh->tria[jel];
224 if ( pt->ref == pt1->ref ) {
225 if ( !mmgErr9 ) {
226 mmgErr9 = 1;
227 fprintf(stderr,"\n ## Error: %s: at least 1 edge tagged ref while"
228 " both corresponding triangles have same ref (%" MMG5_PRId
229 " %" MMG5_PRId ").\n",__func__,
230 MMG2D_indPt(mesh,pt->v[i1]), MMG2D_indPt(mesh,pt->v[i2]));
231 }
232 return 0;
233 }
234 }
235 }
236 }
237 }
238
240 for (k=1; k<=mesh->nt; k++) {
241 pt = &mesh->tria[k];
242 if ( !MG_EOK(pt) ) continue;
243
244 for (i=0; i<3; i++) {
245 if ( pt->tag[i] & MG_GEO || pt->tag[i] & MG_REF ) {
246 int i1 = MMG5_inxt2[i];
247 int i2 = MMG5_iprv2[i];
248
249 /* Check that a GEO or REF edge is BDY too */
250 if ( !(pt->tag[i] & MG_BDY) ) {
251 if ( !mmgErr10 ) {
252 mmgErr10 = 1;
253 fprintf(stderr,"\n ## Error: %s: at least 1 edge (%" MMG5_PRId " %" MMG5_PRId ") tagged"
254 " %d, but not MG_BDY\n",__func__,MMG2D_indPt(mesh,pt->v[i1]),
255 MMG2D_indPt(mesh,pt->v[i2]),pt->tag[i]);
256 }
257 return 0;
258 }
259
260 /* Check that a bdy edge has bdy vertices */
261 MMG5_pPoint p1 = &mesh->point[pt->v[i1]];
262 if ( !(p1->tag & MG_BDY) ) {
263 if ( !mmgErr11 ) {
264 mmgErr11 = 1;
265 fprintf(stderr,"\n ## Error: %s: at least 1 edge (%" MMG5_PRId " %" MMG5_PRId ") tagged %d,"
266 " with a point (%" MMG5_PRId ") not tagged BDY.\n",__func__,
267 MMG2D_indPt(mesh,pt->v[i1]),MMG2D_indPt(mesh,pt->v[i2]),
268 pt->tag[i],MMG2D_indPt(mesh,pt->v[i1]));
269 }
270 return 0;
271 }
272
273 MMG5_pPoint p2 = &mesh->point[pt->v[i2]];
274 if ( !(p2->tag & MG_BDY) ) {
275 if ( !mmgErr12 ) {
276 mmgErr12 = 1;
277 fprintf(stderr,"\n ## Error: %s: at least 1 edge (%" MMG5_PRId " %" MMG5_PRId ") tagged %d,"
278 " with a point (%" MMG5_PRId ") not tagged BDY.\n",__func__,
279 MMG2D_indPt(mesh,pt->v[i1]),MMG2D_indPt(mesh,pt->v[i2]),
280 pt->tag[i],MMG2D_indPt(mesh,pt->v[i2]));
281 }
282 return 0;
283 }
284 }
285 }
286 }
287
288 if ( !severe ) return 1;
289
290
291 MMG5_SAFE_CALLOC(list,MMG2D_LMAX,MMG5_int,return 0);
292
294 for (k=1; k<=mesh->nt; k++) {
295 pt1 = &mesh->tria[k];
296 if ( !MG_EOK(pt1) ) continue;
297 iadr = 3*(k-1) + 1;
298 adja = &mesh->adja[iadr];
299
300 for (i=0; i<3; i++) {
301 adj = (adja[i]-1) / 3 + 1;
302 if ( !adj ) continue;
303
304 ip = pt1->v[i];
305 ppt = &mesh->point[ip];
306
307 /* Check that a used elt has used vertices */
308 if ( !MG_VOK(ppt) ) {
309 if ( !mmgErr13 ) {
310 mmgErr13 = 1;
311 fprintf(stderr,"\n ## Error: %s: at least 1 unused vertex %" MMG5_PRId
312 " %" MMG5_PRId "\n",__func__,
314 fprintf(stderr,"%" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "\n",
315 MMG2D_indPt(mesh,pt1->v[0]),
316 MMG2D_indPt(mesh,pt1->v[1]),MMG2D_indPt(mesh,pt1->v[2]));
317 }
318 MMG5_SAFE_FREE(list);
319 return 0;
320 }
321
322 /* Check the validity of the ball of point */
323 lon = MMG2D_boulep(mesh,k,i,list);
324 for (l=1; l<=lon; l++) {
325 kk = list[l] / 3;
326 nk = list[l] % 3;
327 pt2 = &mesh->tria[kk];
328 if ( pt2->v[nk] != ip ) {
329 if ( !mmgErr14 ) {
330 mmgErr14 = 1;
331 fprintf(stderr,"\n ## Error: %s: at least 1 wrong ball %" MMG5_PRId
332 ", %" MMG5_PRId "\n",
333 __func__,MMG2D_indPt(mesh,ip),MMG2D_indPt(mesh,pt2->v[nk]));
334 }
335 MMG5_SAFE_FREE(list);
336 return 0;
337 }
338 }
339 if ( lon < 1 ) continue;
340
341 /* Check that the number of valid triangles containing the vertex ip is
342 * equal to the length of the ball of ip. */
343 len = 0;
344 for (kk=1; kk<=mesh->nt; kk++) {
345 pt2 = &mesh->tria[kk];
346 if ( !MG_EOK(pt2) ) continue;
347 for (j=0; j<3; j++)
348 if ( pt2->v[j] == ip ) {
349 len++;
350 break;
351 }
352 }
353 if ( len != lon ) {
354 if ( !mmgErr15 ) {
355 mmgErr15 = 1;
356 fprintf(stderr,"\n ## Error: %s: at least 1 incorrect ball %"
357 MMG5_PRId ": %d %d\n",
358 __func__,MMG2D_indPt(mesh,pt1->v[i]),lon,len);
359 }
360 MMG5_SAFE_FREE(list);
361 return 0;
362 }
363 }
364 }
365 MMG5_SAFE_FREE(list);
366 return 1;
367}
MMG5_pMesh * mesh
int MMG2D_boulep(MMG5_pMesh mesh, MMG5_int ifirst, int iploc, MMG5_int *list)
Definition: boulep_2d.c:36
int MMG5_mmg2dChkmsh(MMG5_pMesh mesh, int severe, MMG5_int base)
Definition: chkmsh_2d.c:36
API headers for the mmg2d library.
#define MMG2D_LMAX
Definition: libmmg2d.h:47
MMG5_int MMG2D_indPt(MMG5_pMesh mesh, MMG5_int kp)
Definition: tools_2d.c:70
MMG5_int MMG2D_indElt(MMG5_pMesh mesh, MMG5_int kel)
Definition: tools_2d.c:46
#define MG_GEO
#define MMG5_SAFE_CALLOC(ptr, size, type, law)
#define MG_EOK(pt)
static const uint8_t MMG5_iprv2[3]
#define MG_SIN(tag)
static const uint8_t MMG5_inxt2[6]
#define MG_VOK(ppt)
#define MG_BDY
#define MG_REF
#define MMG5_SAFE_FREE(ptr)
MMG mesh structure.
Definition: libmmgtypes.h:605
MMG5_Info info
Definition: libmmgtypes.h:651
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
int16_t tag
Definition: libmmgtypes.h:284
int16_t tag[3]
Definition: libmmgtypes.h:342
MMG5_int ref
Definition: libmmgtypes.h:335
MMG5_int v[3]
Definition: libmmgtypes.h:334