Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
hash_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"
24
25#define KTA 7
26#define KTB 11
27
36 MMG5_pTria pt,pt1;
37 MMG5_int k,kk,pp,l,ll,mins,mins1,maxs,maxs1;
38 MMG5_int *hcode,*link,inival,hsize,iadr;
39 uint8_t i,ii,i1,i2;
40 unsigned int key;
41
42 if ( mesh->adja ) return 1;
43 if ( !mesh->nt ) return 0;
44
45 /* memory alloc */
46 MMG5_SAFE_CALLOC(hcode,mesh->nt+1,MMG5_int,return 0);
47
48 /* memory alloc */
49 MMG5_ADD_MEM(mesh,(3*mesh->ntmax+5)*sizeof(MMG5_int),"adjacency table",
50 printf(" Exit program.\n");
51 return 0;);
52 MMG5_SAFE_CALLOC(mesh->adja,3*mesh->ntmax+5,MMG5_int,return 0);
53
54 link = mesh->adja;
55 hsize = mesh->nt;
56
57 /* init */
58 inival = INT_MAX;
59 for (k=0; k<=mesh->nt; k++)
60 hcode[k] = -inival;
61
62 /* build hash table */
63 for (k=1; k<=mesh->nt; k++) {
64 pt = &mesh->tria[k];
65
66 if ( !pt->v[0] ) continue;
67 for (i=0; i<3; i++) {
68 i1 = MMG2D_idir[i+1];
69 i2 = MMG2D_idir[i+2];
70 if ( pt->v[i1] < pt->v[i2] ) {
71 mins = pt->v[i1];
72 maxs = pt->v[i2];
73 }
74 else {
75 mins = pt->v[i2];
76 maxs = pt->v[i1];
77 }
78
79 /* compute key */
80 key = (KTA*(int64_t)mins + KTB*(int64_t)maxs)%hsize+1;
81
82 /* insert */
83 iadr = 3*(k-1) + i+1;
84 link[iadr] = hcode[key];
85 hcode[key] = -iadr;
86 }
87 }
88
89 /* set adjacency */
90 for (l=3*mesh->nt; l>0; l--) {
91 if ( link[l] >= 0 ) continue;
92 k = (l-1) / 3 + 1;
93 i = (l-1) % 3;
94 i1 = MMG2D_idir[i+1];
95 i2 = MMG2D_idir[i+2];
96 pt = &mesh->tria[k];
97
98 mins = M_MIN(pt->v[i1],pt->v[i2]);
99 maxs = M_MAX(pt->v[i1],pt->v[i2]);
100
101 /* accross link */
102 ll = -link[l];
103 pp = 0;
104 link[l] = 0;
105
106 while ( ll != inival ) {
107 kk = (ll-1) / 3 + 1;
108 ii = (ll-1) % 3;
109 i1 = MMG2D_idir[ii+1];
110 i2 = MMG2D_idir[ii+2];
111 pt1 = &mesh->tria[kk];
112 if ( pt1->v[i1] < pt1->v[i2] ) {
113 mins1 = pt1->v[i1];
114 maxs1 = pt1->v[i2];
115 }
116 else {
117 mins1 = pt1->v[i2];
118 maxs1 = pt1->v[i1];
119 }
120
121 if ( mins1 == mins && maxs1 == maxs ) {
122 /* adjacent found */
123 if ( pp != 0 ) link[pp] = link[ll];
124 link[l] = 3*kk + ii;
125 link[ll]= 3*k + i;
126 break;
127 }
128 pp = ll;
129 ll = -link[ll];
130 }
131 }
132 MMG5_SAFE_FREE(hcode);
133
134 return 1;
135}
136
151 MMG5_pQuad pq,pq1;
152 MMG5_pTria pt;
153 MMG5_Hash hash;
154 MMG5_int k,kk,pp,l,ll,mins,mins1,maxs,maxs1,iadr;
155 MMG5_int *hcode,*link,hsize,inival;
156 uint8_t i,ii,i1,i2;
157 unsigned int key;
158
160 if ( !mesh->nquad ) {
161 return 1;
162 }
163
164 /* default */
165 if ( mesh->adjq ) {
166 if ( abs(mesh->info.imprim) > 3 || mesh->info.ddebug ) {
167 fprintf(stderr,"\n ## Warning: %s: no re-build of adjacencies of quadrangles. "
168 "mesh->adjq must be freed to enforce analysis.\n",__func__);
169 }
170 return 1;
171 }
172
173 if ( abs(mesh->info.imprim) > 5 || mesh->info.ddebug )
174 fprintf(stdout," ** SETTING QUAD ADJACENCY\n");
175
176 /* memory alloc */
177 MMG5_ADD_MEM(mesh,(4*mesh->nquad+5)*sizeof(MMG5_int),"quad adjacency table",
178 fprintf(stderr," Exit program.\n");
179 return 0);
180 MMG5_SAFE_CALLOC(mesh->adjq,4*mesh->nquad+5,MMG5_int,return 0);
181 MMG5_SAFE_CALLOC(hcode,mesh->nquad+5,MMG5_int,return 0);
182
183 link = mesh->adjq;
184 hsize = mesh->nquad;
185
186 /* init */
187 if ( mesh->info.ddebug ) fprintf(stdout," h- stage 1: init\n");
188 inival = INT_MAX;
189 iadr = 0;
190 for (k=0; k<=mesh->nquad; k++)
191 hcode[k] = -inival;
192
193 /* hash quads */
194 for (k=1; k<=mesh->nquad; k++) {
195 pq = &mesh->quadra[k];
196 if ( !MG_EOK(pq) ) continue;
197 for (i=0; i<4; i++) {
198 i1 = MMG2D_idir_q[i][0];
199 i2 = MMG2D_idir_q[i][1];
200 if ( pq->v[i1] < pq->v[i2] ) {
201 mins = pq->v[i1];
202 maxs = pq->v[i2];
203 }
204 else {
205 mins = pq->v[i2];
206 maxs = pq->v[i1];
207 }
208
209 /* compute key */
210 key = (KTA*(int64_t)mins + KTB*(int64_t)maxs)%hsize+1;
211
212 /* insert */
213 iadr++;
214 link[iadr] = hcode[key];
215 hcode[key] = -iadr;
216 }
217 }
218
219 /* set adjacency */
220 if ( mesh->info.ddebug ) fprintf(stdout," h- stage 2: adjacencies\n");
221
222 for (l=iadr; l>0; l--) {
223 if ( link[l] >= 0 ) continue;
224
225 /* current element */
226 k = (l-1) / 4 + 1;
227 i = (l-1) % 4;
228 i1 = MMG2D_idir_q[i][0];
229 i2 = MMG2D_idir_q[i][1];
230
231 pq = &mesh->quadra[k];
232 if ( pq->v[i1] < pq->v[i2] ) {
233 mins = pq->v[i1];
234 maxs = pq->v[i2];
235 }
236 else {
237 mins = pq->v[i2];
238 maxs = pq->v[i1];
239 }
240
241 /* accross link */
242 ll = -link[l];
243 pp = 0;
244 link[l] = 0;
245 while ( ll != inival ) {
246 kk = (ll-1) / 4 + 1;
247 ii = (ll-1) % 4;
248 i1 = MMG2D_idir_q[ii][0];
249 i2 = MMG2D_idir_q[ii][1];
250 pq1 = &mesh->quadra[kk];
251
252 if ( pq1->v[i1] < pq1->v[i2] ) {
253 mins1 = pq1->v[i1];
254 maxs1 = pq1->v[i2];
255 }
256 else {
257 mins1 = pq1->v[i2];
258 maxs1 = pq1->v[i1];
259 }
260
261 if ( mins1 == mins && maxs1 == maxs ) {
262 /* adjacent found */
263 if ( pp != 0 ) link[pp] = link[ll];
264 link[l] = 4*kk + ii;
265 link[ll] = 4*k + i;
266 break;
267 }
268 pp = ll;
269 ll = -link[ll];
270 }
271 }
272 MMG5_SAFE_FREE(hcode);
273
275 /* Temporarily allocate a hash structure for storing edges */
276 if ( !MMG5_hashNew( mesh,&hash,0.51*mesh->nt, 1.51*mesh->nt) ) return 0;
277
278 /* Hash edge belonging to only one triangle (hcode==0) */
279 for (k=1; k<=mesh->nt; k++) {
280 pt = &mesh->tria[k];
281 if ( !MG_EOK(pt) ) continue;
282
283 hcode = &mesh->adja[3*(k-1)+1];
284 for (i=0; i<3; i++) {
285 if ( hcode[i] ) {
286 continue;
287 }
288 /* The edge belongs to one tria only */
289 MMG5_hashEdge(mesh,&hash,pt->v[MMG5_iprv2[i]],pt->v[MMG5_inxt2[i]],3*k+i);
290 }
291 }
292
293 /* Search edges that belong to one quad only and update adjacency array if the
294 * edge is founded in the hash table */
295 for (k=1; k<=mesh->nquad; k++) {
296 pq = &mesh->quadra[k];
297 if ( !MG_EOK(pq) ) continue;
298
299 hcode = &mesh->adjq[4*(k-1)+1];
300 for (i=0; i<4; i++) {
301 assert ( hcode[i] >= 0 );
302
303 if ( hcode[i] ) {
304 continue;
305 }
306
307 /* The edge belongs to one quad only */
308 i1 = MMG2D_idir_q[i][0];
309 i2 = MMG2D_idir_q[i][1];
310
311 kk = MMG5_hashGet(&hash,pq->v[i1],pq->v[i2]);
312 if ( kk ) {
313 /* The edge is at the interface between a quad and a triangle */
314 hcode[i] = -kk;
315 }
316 }
317 }
318 MMG5_DEL_MEM(mesh,hash.item);
319
320 return 1;
321}
322
332 MMG5_Hash hash;
333 MMG5_pTria pt;
334 MMG5_pQuad pq;
335 MMG5_pEdge pa;
336 MMG5_int ia;
337 MMG5_int k;
338 int8_t ier;
339 uint8_t i,i1,i2;
340
352 if ( !mesh->info.metRidTyp ) {
353 /* Try to clean triangle structure (in case where mmg2dlib is called after
354 * mmg2dmesh) */
355 for (k=1; k<=mesh->nt; k++) {
356 pt = &mesh->tria[k];
357 if ( !MG_EOK(pt) ) continue;
358
359 /* If all edges are required, the triangle is maybe required by the user */
360 if ( (pt->tag[0] & MG_REQ) && (pt->tag[1] & MG_REQ) && (pt->tag[2] & MG_REQ) ) {
361 continue;
362 }
363
364 /* Otherwise there is no reason to have required tags on edges */
365 for ( ia = 0; ia < 3; ++ia ) {
366 pt->tag[ia] &= ~MG_REQ;
367 }
368 }
369 mesh->info.metRidTyp = 1;
370 }
371
372 if ( !mesh->na ) return 1;
373
374 /* Temporarily allocate a hash structure for storing edges */
375 ier = MMG5_hashNew ( mesh,&hash, mesh->na,3*mesh->na );
376 if ( !ier ) {
377 printf(" ## Error: %s: Unable to allocate edge hash table\n.",__func__);
378 return 0;
379 }
380
381 /* hash mesh edges */
382 for (k=1; k<=mesh->na; k++) {
383 ier = MMG5_hashEdge(mesh,&hash,mesh->edge[k].a,mesh->edge[k].b,k);
384 if ( !ier ) {
385 fprintf(stderr,"\n ## Error: %s: unable to hash edge %" MMG5_PRId " %" MMG5_PRId ".\n",__func__,
387 return 0;
388 }
389 }
390
391 /* set references to triangles */
392 for (k=1; k<=mesh->nt; k++) {
393 pt = &mesh->tria[k];
394 if ( !MG_EOK(pt) ) continue;
395
396 for (i=0; i<3; i++) {
397 i1 = MMG5_inxt2[i];
398 ia = MMG5_hashGet(&hash,pt->v[i],pt->v[i1]);
399 if ( ia ) {
400 i2 = MMG5_inxt2[i1];
401 pa = &mesh->edge[ia];
402 pt->edg[i2] = pa->ref;
403 pt->tag[i2] |= pa->tag;
404
405 }
406 }
407 }
408
409 /* set references to quadrangles */
410 for (k=1; k<=mesh->nquad; k++) {
411 pq = &mesh->quadra[k];
412 if ( !MG_EOK(pq) ) continue;
413
414 for (i=0; i<4; i++) {
415 i1 = MMG2D_idir_q[i][0];
416 i2 = MMG2D_idir_q[i][1];
417 ia = MMG5_hashGet(&hash,pq->v[i1],pq->v[i2]);
418 if ( ia ) {
419 pa = &mesh->edge[ia];
420 pq->edg[i] = pa->ref;
421 pq->tag[i] |= pa->tag;
422 }
423 }
424 }
425
426 /* Delete the hash for edges */
427 MMG5_DEL_MEM(mesh,hash.item);
429 mesh->na = 0;
430
431 return 1;
432}
433
447 MMG5_pTria pt,pt1;
448 MMG5_pEdge pa;
449 MMG5_pPoint p0;
450 MMG5_int k,*adja,natmp,iel;
451 int8_t i,i1,i2;
452
453 natmp = 0;
454 mesh->na = 0;
455
456 /* First step: Count number of boundary edges */
457 for (k=1; k<=mesh->nt; k++) {
458 pt = &mesh->tria[k];
459 if ( !MG_EOK(pt) ) continue;
460
461 adja = &mesh->adja[3*(k-1)+1];
462
463 for (i=0; i<3; i++) {
464 iel = adja[i] / 3;
465 pt1 = &mesh->tria[iel];
466
467 if ( iel && pt->ref <= pt1->ref ) continue;
468 natmp++;
469 }
470 }
471
472 /* Second step: Create edge mesh and store the corresponding edges */
473 MMG5_ADD_MEM(mesh,(natmp+1)*sizeof(MMG5_Edge),"edges",return 0);
474 MMG5_SAFE_CALLOC(mesh->edge,natmp+1,MMG5_Edge,return 0);
475
476 for (k=1; k<=mesh->nt; k++) {
477 pt = &mesh->tria[k];
478 if ( !MG_EOK(pt) ) continue;
479
480 adja = &mesh->adja[3*(k-1)+1];
481
482 for (i=0; i<3; i++) {
483 iel = adja[i] / 3;
484 pt1 = &mesh->tria[iel];
485
486 if ( iel && pt->ref <= pt1->ref ) continue;
487
488 i1 = MMG5_inxt2[i];
489 i2 = MMG5_inxt2[i1];
490
491 mesh->na++;
492 pa = &mesh->edge[mesh->na];
493 pa->a = pt->v[i1];
494 pa->b = pt->v[i2];
495
496 pa->tag = pt->tag[i];
497 pa->ref = pt->edg[i];
498
499 }
500 }
501
502 /* Set point tags */
503 for (k=1; k<=mesh->na; k++) {
504 pa = &mesh->edge[k];
505 p0 = &mesh->point[pa->a];
506 p0->tag |= MG_BDY;
507
508 p0 = &mesh->point[pa->b];
509 p0->tag |= MG_BDY;
510 }
511
512 return 1;
513}
514
515
528 MMG5_pTria pt,ptnew,pt1;
529 MMG5_pQuad pq,pq1;
530 MMG5_pEdge ped;
531 MMG5_pPoint ppt,pptnew;
532 MMG5_int np,ned,nt,k,iel,nbl,isol,isolnew,memWarn,nc;
533 MMG5_int iadr,iadrnew,iadrv,*adjav,*adja,*adjanew,voy;
534 int8_t i,i1,i2;
535
536 /* Keep only one domain if asked */
538
540 if ( !MMG2D_hashTria(mesh) ) {
541 fprintf(stderr,"\n ## Warning: %s: hashing problem. Exit program.\n",
542 __func__);
543 return 0;
544 }
545
547 np = nc = 0;
548 for (k=1; k<=mesh->np; k++) {
549 ppt = &mesh->point[k];
550 if ( !MG_VOK(ppt) ) continue;
551 ppt->tmp = ++np;
552
553 if ( ppt->tag & MG_CRN ) nc++;
554
555 if ( ppt->tag & MG_NOSURF ) {
556 ppt->tag &= ~MG_NOSURF;
557 ppt->tag &= ~MG_REQ;
558 }
559 }
560
562 memWarn = 0;
563 ned = 0;
564
565 if ( mesh->edge ) {
566 fprintf(stderr,"\n ## Warning: %s: unexpected edge table..."
567 " Ignored data.\n",__func__);
569 mesh->na = 0;
570 }
571
572 if ( mesh->nquad && mesh->quadra ) {
573 if ( !MMG2D_hashQuad(mesh) ) {
574 fprintf(stderr,"\n ## Warning: %s: unable to build quad adjacencies."
575 " Quad edges will be ignored.\n",__func__);
576 }
577 }
578
579 mesh->na = 0;
581 for (k=1; k<=mesh->nt; k++) {
582 pt = &mesh->tria[k];
583 if ( !MG_EOK(pt) ) continue;
584 adja = &mesh->adja[3*(k-1)+1];
585
586 for (i=0; i<3; i++) {
587 iel = adja[i] / 3;
588
589 if ( pt->tag[i] & MG_NOSURF ) {
590 pt->tag[i] &= ~MG_REQ;
591 pt->tag[i] &= ~MG_NOSURF;
592 }
593
594 pt1 = &mesh->tria[iel];
595 if ( (!iel) || (pt->ref > pt1->ref) ) {
596 ++mesh->na;
597 }
598 else if ( (pt->ref==pt1->ref) && MG_SIN(pt->tag[i]) ) {
599 ++mesh->na;
600 }
601 else if ( mesh->info.opnbdy ) {
602 if ( (pt->tag[i] & MG_REF) || pt->tag[i] & MG_BDY ) {
603 assert ( pt->tag[i] & (MG_REF+MG_BDY) );
604 ++mesh->na;
605 }
606 }
607 }
608 }
610 for (k=1; k<=mesh->nquad; k++) {
611 pq = &mesh->quadra[k];
612 if ( !MG_EOK(pq) ) continue;
613 adja = &mesh->adjq[4*(k-1)+1];
614
615 for (i=0; i<4; i++) {
616 iel = adja[i] / 4;
617
618 if ( iel < 0) {
619 /* Edge at the interface between a quad and a tria: treated from the tria */
620 continue;
621 }
622
623 pq1 = &mesh->quadra[iel];
624 if ( (!iel) || (pq->ref > pq1->ref) ) {
625 ++mesh->na;
626 }
627 else if ( (pq->ref==pq1->ref) && MG_SIN(pq->tag[i]) ) {
628 ++mesh->na;
629 }
630 else if ( mesh->info.opnbdy ) {
631 if ( (pq->tag[i] & MG_REF) || pq->tag[i] & MG_BDY ) {
632 assert ( pq->tag[i] & (MG_REF+MG_BDY) );
633 ++mesh->na;
634 }
635 }
636 }
637 }
638
640 mesh->namax = mesh->na;
641 if ( mesh->na ) {
642
643 MMG5_ADD_MEM(mesh,(mesh->namax+1)*sizeof(MMG5_Edge),"final edges", memWarn=1);
644
645 if ( memWarn ) {
646 if ( mesh->info.ddebug )
647 printf(" -- Attempt to allocate a smallest edge table...\n");
648 mesh->namax = mesh->na;
649 memWarn = 0;
650 MMG5_ADD_MEM(mesh,(mesh->namax+1)*sizeof(MMG5_Edge),"final edges",
651 fprintf(stderr,"\n ## Warning: %s: uncomplete mesh.\n",
652 __func__);
653 memWarn=1);
654 }
655
656 if ( memWarn )
657 mesh->na = 0;
658 else {
659 /* We have enough memory to allocate the edge table */
660 MMG5_SAFE_CALLOC(mesh->edge,(mesh->namax+1),MMG5_Edge, return 0);
661
662 nt = 0;
663 /* Edges stored in triangles */
664 for (k=1; k<=mesh->nt; k++) {
665 pt = &mesh->tria[k];
666 if ( !MG_EOK(pt) ) continue;
667 ++nt;
668 adja = &mesh->adja[3*(k-1)+1];
669
670 for (i=0; i<3; i++) {
671 i1 = MMG5_inxt2[i];
672 i2 = MMG5_iprv2[i];
673 iel = adja[i] / 3;
674 pt1 = &mesh->tria[iel];
675 if ( !iel || (pt->ref > pt1->ref) ||
676 ((pt->ref==pt1->ref) && MG_SIN(pt->tag[i])) ||
677 (mesh->info.opnbdy && ((pt->tag[i] & MG_REF) || (pt->tag[i] & MG_BDY)))) {
678 ++ned;
679 ped = &mesh->edge[ned];
680 ped->a = pt->v[i1];
681 ped->b = pt->v[i2];
682 /* the base field is used to be able to recover the tria (and its face)
683 * from which comes a boundary edge */
684 ped->base = 3*nt+i;
685 ped->ref = pt->edg[i];
686 ped->tag = pt->tag[i];
687 }
688 }
689 }
690
691 /* Edges stored in quadrangles */
692 nt = 0;
693 for (k=1; k<=mesh->nquad; k++) {
694 pq = &mesh->quadra[k];
695 if ( !MG_EOK(pq) ) continue;
696 ++nt;
697 adja = &mesh->adjq[4*(k-1)+1];
698
699 for (i=0; i<4; i++) {
700 i1 = MMG2D_idir_q[i][0];
701 i2 = MMG2D_idir_q[i][1];
702
703 iel = adja[i] / 4;
704
705 if ( iel < 0) {
706 /* Edge at the interface between a quad and a tria: treated from the tria */
707 continue;
708 }
709
710 pq1 = &mesh->quadra[iel];
711 if ( !iel || (pq->ref > pq1->ref) ||
712 ((pq->ref==pq1->ref) && MG_SIN(pq->tag[i])) ||
713 (mesh->info.opnbdy && ((pq->tag[i] & MG_REF) || (pq->tag[i] & MG_BDY)))) {
714 ++ned;
715 ped = &mesh->edge[ned];
716 ped->a = pq->v[i1];
717 ped->b = pq->v[i2];
718 /* the base field is used to be able to recover the quad (and its face)
719 * from which comes a boundary edge */
720 ped->base = 4*nt+i;
721 ped->ref = pq->edg[i];
722 ped->tag = pq->tag[i];
723 }
724 }
725 }
726 }
727 }
728
729 for (k=1; k<=mesh->na; k++) {
730 ped = &mesh->edge[k];
731 if ( !ped->a ) continue;
732 ped->a = mesh->point[ped->a].tmp;
733 ped->b = mesh->point[ped->b].tmp;
734 }
735
737 nt = 0;
738 nbl = 1;
739 for (k=1; k<=mesh->nt; k++) {
740 pt = &mesh->tria[k];
741 if ( !MG_EOK(pt) ) continue;
742
743 pt->v[0] = mesh->point[pt->v[0]].tmp;
744 pt->v[1] = mesh->point[pt->v[1]].tmp;
745 pt->v[2] = mesh->point[pt->v[2]].tmp;
746 nt++;
747
748 if ( k != nbl ) {
749 ptnew = &mesh->tria[nbl];
750 memcpy(ptnew,pt,sizeof(MMG5_Tria));
751
752 /* Update the adjacency */
753 iadr = 3*(k-1) + 1;
754 adja = &mesh->adja[iadr];
755 iadrnew = 3*(nbl-1) + 1;
756 adjanew = &mesh->adja[iadrnew];
757
758 for(i=0; i<3; i++) {
759 adjanew[i] = adja[i];
760 if ( !adja[i] ) continue;
761 iadrv = 3*(adja[i]/3-1)+1;
762 adjav = &mesh->adja[iadrv];
763 voy = i;
764 adjav[adja[i]%3] = 3*nbl + voy;
765 adja[i] = 0;
766 }
767 memset(pt,0,sizeof(MMG5_Tria));
768 }
769 nbl++;
770 }
771 mesh->nt = nt;
772
774 if ( mesh->quadra ) {
775 k = 1;
776 do {
777 pq = &mesh->quadra[k];
778 if ( !MG_EOK(pq) ) {
779 pq1 = &mesh->quadra[mesh->nquad];
780 assert( pq && pq1 && MG_EOK(pq1) );
781 memcpy(pq,pq1,sizeof(MMG5_Quad));
782 --mesh->nquad;
783 }
784 }
785 while ( ++k < mesh->nquad );
786 }
787
788 if ( mesh->quadra ) {
789 for (k=1; k<=mesh->nquad; k++) {
790 pq = &mesh->quadra[k];
791 if ( !MG_EOK(pq) ) continue;
792 pq->v[0] = mesh->point[pq->v[0]].tmp;
793 pq->v[1] = mesh->point[pq->v[1]].tmp;
794 pq->v[2] = mesh->point[pq->v[2]].tmp;
795 pq->v[3] = mesh->point[pq->v[3]].tmp;
796 }
797 }
798
800 if ( sol && sol->m ) {
801 nbl = 1;
802 for (k=1; k<=mesh->np; k++) {
803 ppt = &mesh->point[k];
804 if ( !MG_VOK(ppt) ) continue;
805 isol = k * sol->size;
806 isolnew = nbl * sol->size;
807
808 for (i=0; i<sol->size; i++)
809 sol->m[isolnew + i] = sol->m[isol + i];
810 ++nbl;
811 }
812 }
813
814 if ( met && met->m ) {
815 nbl = 1;
816 for (k=1; k<=mesh->np; k++) {
817 ppt = &mesh->point[k];
818 if ( !MG_VOK(ppt) ) continue;
819 isol = k * met->size;
820 isolnew = nbl * met->size;
821
822 for (i=0; i<met->size; i++)
823 met->m[isolnew + i] = met->m[isol + i];
824 ++nbl;
825 }
826 }
827
829 np = 0;
830 nbl = 1;
831 for (k=1; k<=mesh->np; k++) {
832 ppt = &mesh->point[k];
833 if ( !MG_VOK(ppt) ) continue;
834
835 if ( k != nbl ) {
836 pptnew = &mesh->point[nbl];
837 memcpy(pptnew,ppt,sizeof(MMG5_Point));
838 ppt->tag = 0;
839 assert ( ppt->tmp == nbl );
840 }
841 np++;
842 if ( k != nbl ) {
843 ppt = &mesh->point[k];
844 memset(ppt,0,sizeof(MMG5_Point));
845 ppt->tag = 0;
846 }
847 nbl++;
848 }
849 mesh->np = np;
850 if ( sol && sol->m ) sol->np = np;
851
853 for(k=1 ; k<=mesh->np ; k++)
854 mesh->point[k].tmp = 0;
855
856 if(mesh->np < mesh->npmax - 3) {
857 mesh->npnil = mesh->np + 1;
858 for (k=mesh->npnil; k<mesh->npmax-1; k++)
859 mesh->point[k].tmp = k+1;
860 }
861 else {
862 mesh->npnil = 0;
863 }
864
866 if ( mesh->nt < mesh->ntmax - 3 ) {
867 mesh->nenil = mesh->nt + 1;
868 for (k=mesh->nenil; k<mesh->ntmax-1; k++)
869 mesh->tria[k].v[2] = k+1;
870 }
871 else {
872 mesh->nenil = 0;
873 }
874
875 if ( mesh->info.imprim > 0 ) {
876 fprintf(stdout," NUMBER OF VERTICES %8" MMG5_PRId " CORNERS %8" MMG5_PRId "\n",mesh->np,nc);
877 fprintf(stdout," NUMBER OF TRIANGLES %8" MMG5_PRId "\n",mesh->nt);
878 if ( mesh->nquad ) {
879 fprintf(stdout," NUMBER OF QUADRILATERALS %8" MMG5_PRId "\n",mesh->nquad);
880 }
881 if ( mesh->na )
882 fprintf(stdout," NUMBER OF EDGES %8" MMG5_PRId "\n",mesh->na);
883 }
884
885 if ( memWarn ) return 0;
886
887 return 1;
888}
int ier
MMG5_pMesh MMG5_pSol * sol
MMG5_pMesh * mesh
int MMG5_hashNew(MMG5_pMesh mesh, MMG5_Hash *hash, MMG5_int hsiz, MMG5_int hmax)
Definition: hash.c:526
MMG5_int MMG5_hashGet(MMG5_Hash *hash, MMG5_int a, MMG5_int b)
Definition: hash.c:495
int MMG5_hashEdge(MMG5_pMesh mesh, MMG5_Hash *hash, MMG5_int a, MMG5_int b, MMG5_int k)
Definition: hash.c:345
int MMG2D_bdryEdge(MMG5_pMesh mesh)
Definition: hash_2d.c:446
int MMG2D_hashQuad(MMG5_pMesh mesh)
Definition: hash_2d.c:150
int MMG2D_assignEdge(MMG5_pMesh mesh)
Definition: hash_2d.c:331
#define KTA
Definition: hash_2d.c:25
int MMG2D_hashTria(MMG5_pMesh mesh)
Definition: hash_2d.c:35
#define KTB
Definition: hash_2d.c:26
int MMG2D_pack(MMG5_pMesh mesh, MMG5_pSol sol, MMG5_pSol met)
Definition: hash_2d.c:527
MMG5_int MMG2D_indPt(MMG5_pMesh mesh, MMG5_int kp)
Definition: tools_2d.c:70
#define M_MIN(a, b)
static const unsigned int MMG2D_idir[5]
#define M_MAX(a, b)
static const uint8_t MMG2D_idir_q[4][2]
idir[i]: vertices of edge i for a quad
void MMG2D_keep_only1Subdomain(MMG5_pMesh mesh, int nsd)
Definition: tools_2d.c:92
#define MG_REQ
#define MMG5_SAFE_CALLOC(ptr, size, type, law)
#define MG_EOK(pt)
#define MMG5_ADD_MEM(mesh, size, message, law)
static const uint8_t MMG5_iprv2[3]
#define MG_SIN(tag)
static const uint8_t MMG5_inxt2[6]
#define MG_VOK(ppt)
#define MG_CRN
#define MG_BDY
#define MG_NOSURF
#define MG_REF
#define MMG5_SAFE_FREE(ptr)
#define MMG5_DEL_MEM(mesh, ptr)
Structure to store edges of a MMG mesh.
Definition: libmmgtypes.h:305
MMG5_int b
Definition: libmmgtypes.h:306
MMG5_int base
Definition: libmmgtypes.h:308
MMG5_int ref
Definition: libmmgtypes.h:307
int16_t tag
Definition: libmmgtypes.h:310
MMG5_int a
Definition: libmmgtypes.h:306
Identic as MMG5_HGeom but use MMG5_hedge to store edges instead of MMG5_hgeom (memory economy).
Definition: libmmgtypes.h:595
MMG5_hedge * item
Definition: libmmgtypes.h:597
int8_t ddebug
Definition: libmmgtypes.h:532
uint8_t metRidTyp
Definition: libmmgtypes.h:547
MMG5_int nsd
Definition: libmmgtypes.h:522
MMG mesh structure.
Definition: libmmgtypes.h:605
MMG5_int ntmax
Definition: libmmgtypes.h:612
MMG5_pQuad quadra
Definition: libmmgtypes.h:648
MMG5_Info info
Definition: libmmgtypes.h:651
MMG5_pPoint point
Definition: libmmgtypes.h:641
MMG5_int * adja
Definition: libmmgtypes.h:624
MMG5_int nquad
Definition: libmmgtypes.h:613
MMG5_int npmax
Definition: libmmgtypes.h:612
MMG5_int nenil
Definition: libmmgtypes.h:622
MMG5_int * adjq
Definition: libmmgtypes.h:636
MMG5_int namax
Definition: libmmgtypes.h:612
MMG5_int nt
Definition: libmmgtypes.h:612
MMG5_pTria tria
Definition: libmmgtypes.h:647
MMG5_int np
Definition: libmmgtypes.h:612
MMG5_pEdge edge
Definition: libmmgtypes.h:649
MMG5_int na
Definition: libmmgtypes.h:612
MMG5_int npnil
Definition: libmmgtypes.h:621
Structure to store points of a MMG mesh.
Definition: libmmgtypes.h:270
int16_t tag
Definition: libmmgtypes.h:284
MMG5_int tmp
Definition: libmmgtypes.h:280
MMG5_int ref
Definition: libmmgtypes.h:368
int16_t tag[4]
Definition: libmmgtypes.h:372
MMG5_int v[4]
Definition: libmmgtypes.h:367
MMG5_int edg[4]
Definition: libmmgtypes.h:370
double * m
Definition: libmmgtypes.h:671
MMG5_int edg[3]
Definition: libmmgtypes.h:339
int16_t tag[3]
Definition: libmmgtypes.h:342
MMG5_int ref
Definition: libmmgtypes.h:335
MMG5_int v[3]
Definition: libmmgtypes.h:334