Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
libmmg2d.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"
27#include "mmgexterns_private.h"
28
33#define MMG2D_RETURN_AND_PACK(mesh,met,sol,val)do \
34 { \
35 if ( !MMG2D_pack(mesh,met,sol) ) { \
36 mesh->npi = mesh->np; \
37 mesh->nti = mesh->nt; \
38 mesh->nai = mesh->na; \
39 mesh->nei = mesh->ne; \
40 mesh->xt = 0; \
41 if ( met ) { met->npi = met->np; } \
42 if ( sol ) { sol->npi = sol->np; } \
43 return MMG5_LOWFAILURE; \
44 } \
45 _LIBMMG5_RETURN(mesh,met,sol,val); \
46 }while(0)
47
53 MMG5_chkmsh = MMG5_mmg2dChkmsh;
54 MMG5_grad2met_ani = MMG2D_grad2met_ani;
55 MMG5_grad2metreq_ani = MMG2D_grad2metreq_ani;
56 MMG5_solTruncature_ani = MMG5_2dSolTruncature_ani;
57 MMG5_indPt = MMG2D_indPt;
58 MMG5_indElt = MMG2D_indElt;
59
60 return;
61}
62
64 MMG5_pSol sol=NULL; // unused
65 mytime ctim[TIMEMAX];
66 char stim[32];
67
68 assert ( mesh );
69 assert ( met );
70 assert ( mesh->point );
71 assert ( mesh->tria );
72
73 MMG5_version(mesh,"2D");
74
75 /*uncomment to callback*/
76 //MMG2D_callbackinsert = titi;
77
78 /* interrupts */
79 signal(SIGABRT,MMG2D_excfun);
80 signal(SIGFPE,MMG2D_excfun);
81 signal(SIGILL,MMG2D_excfun);
82 signal(SIGSEGV,MMG2D_excfun);
83 signal(SIGTERM,MMG2D_excfun);
84 signal(SIGINT,MMG2D_excfun);
85
86 tminit(ctim,TIMEMAX);
87 chrono(ON,&(ctim[0]));
88
89 /* Check options */
90 if ( !mesh->nt ) {
91 fprintf(stdout,"\n ## ERROR: NO TRIANGLES IN THE MESH. \n");
92 fprintf(stdout," To generate a mesh from boundaries call the"
93 " MMG2D_mmg2dmesh function\n.");
95 }
96 else if ( mesh->info.iso || mesh->info.isosurf ) {
97 fprintf(stdout,"\n ## ERROR: LEVEL-SET DISCRETISATION UNAVAILABLE"
98 " (MMG2D_IPARAM_iso or MMG2D_IPARAM_isosurf ):\n"
99 " YOU MUST CALL THE MMG2D_mmg2dls FUNCTION TO USE THIS"
100 " OPTION.\n");
102 }
103 else if ( mesh->info.lag >= 0 ) {
104 fprintf(stdout,"\n ## ERROR: LAGRANGIAN MODE UNAVAILABLE (MMG2D_IPARAM_lag):\n"
105 " YOU MUST CALL THE MMG2D_mmg2dmov FUNCTION TO MOVE A"
106 " RIGIDBODY.\n");
108 }
109
110 if ( mesh->info.imprim > 0 ) fprintf(stdout,"\n -- MMG2DLIB: INPUT DATA\n");
111
112 /* Check input */
113 chrono(ON,&(ctim[1]));
114
115 if ( met->np && ( met->np != mesh->np ) ) {
116 fprintf(stdout,"\n ## WARNING: WRONG SOLUTION NUMBER : %" MMG5_PRId " != %" MMG5_PRId "\n",met->np,mesh->np);
118 }
119 else if ( met->size!=1 && met->size!=3 ) {
120 fprintf(stderr,"\n ## ERROR: WRONG DATA TYPE.\n");
122 }
123
124 /* specific meshing */
125 if ( met->np ) {
126 if ( mesh->info.optim ) {
127 printf("\n ## ERROR: MISMATCH OPTIONS: OPTIM OPTION CAN NOT BE USED"
128 " WITH AN INPUT METRIC.\n");
130 }
131
132 if ( mesh->info.hsiz>0. ) {
133 printf("\n ## ERROR: MISMATCH OPTIONS: HSIZ OPTION CAN NOT BE USED"
134 " WITH AN INPUT METRIC.\n");
136 }
137 }
138
139 if ( mesh->info.optim && mesh->info.hsiz>0. ) {
140 printf("\n ## ERROR: MISMATCH OPTIONS: HSIZ AND OPTIM OPTIONS CAN NOT BE USED"
141 " TOGETHER.\n");
143 }
144
145 chrono(OFF,&(ctim[1]));
146 printim(ctim[1].gdif,stim);
147
148 if ( mesh->info.imprim > 0 )
149 fprintf(stdout," -- INPUT DATA COMPLETED. %s\n",stim);
150
151 /* Set function pointers */
152 MMG2D_setfunc(mesh,met);
154
155 if ( abs(mesh->info.imprim) > 5 || mesh->info.ddebug ) {
156 fprintf(stdout," MAXIMUM NUMBER OF POINTS (NPMAX) : %8" MMG5_PRId "\n",mesh->npmax);
157 fprintf(stdout," MAXIMUM NUMBER OF TRIANGLES (NTMAX) : %8" MMG5_PRId "\n",mesh->ntmax);
158 }
159
160 /* Data analysis */
161 chrono(ON,&ctim[2]);
162 if ( mesh->info.imprim > 0 ) fprintf(stdout,"\n -- PHASE 1 : DATA ANALYSIS\n");
163
164 /* Keep only one domain if asked */
166
167 /* reset fem value to user setting (needed for multiple library call) */
169
170 /* reset metRidTyp value to 0 (needed for multiple library call because it is
171 * used to mark if input edge have been stored into triangles) */
172 mesh->info.metRidTyp = 0;
173
174 /* Scale input mesh */
176
177 /* Specific meshing */
178 if ( mesh->info.optim ) {
179 if ( !MMG2D_doSol(mesh,met) ) {
182 }
183 }
184
185 if ( mesh->info.hsiz > 0. ) {
186 if ( !MMG2D_Set_constantSize(mesh,met) ) {
189 }
190 }
191
192 /* Print initial quality history */
193 if ( mesh->info.imprim > 0 || mesh->info.imprim < -1 ) {
194 if ( !MMG2D_outqua(mesh,met) ) {
197 }
198 }
199
200 /* Mesh analysis */
201 if (! MMG2D_analys(mesh) ) {
204 }
205
206 if ( mesh->info.ddebug && !MMG5_chkmsh(mesh,1,0) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE);
207
208 if ( mesh->info.imprim > 1 && met->m && met->np ) MMG2D_prilen(mesh,met);
209
210 chrono(OFF,&(ctim[2]));
211 printim(ctim[2].gdif,stim);
212 if ( mesh->info.imprim > 0 )
213 fprintf(stdout," -- PHASE 1 COMPLETED. %s\n",stim);
214
215 /* remeshing */
216 chrono(ON,&ctim[3]);
217
218 if ( mesh->info.imprim > 0 )
219 fprintf(stdout,"\n -- PHASE 2 : %s MESHING\n",met->size < 3 ? "ISOTROPIC" : "ANISOTROPIC");
220
221 /* Mesh improvement */
222 if ( !MMG2D_mmg2d1n(mesh,met) ) {
225 }
226
227 chrono(OFF,&(ctim[3]));
228 printim(ctim[3].gdif,stim);
229 if ( mesh->info.imprim > 0 ) {
230 fprintf(stdout," -- PHASE 2 COMPLETED. %s\n",stim);
231 }
232
233 /* Print output quality history */
234 if ( !MMG2D_outqua(mesh,met) ) {
237 }
238
239 /* Print edge length histories */
240 if ( (abs(mesh->info.imprim) > 4) && met->m && met->np ) {
241 MMG2D_prilen(mesh,met);
242 }
243
244 chrono(ON,&(ctim[1]));
245 if ( mesh->info.imprim > 0 ) fprintf(stdout,"\n -- MESH PACKED UP\n");
246
247 /* Unscale mesh */
250
251 chrono(OFF,&(ctim[1]));
252
253 chrono(OFF,&ctim[0]);
254 printim(ctim[0].gdif,stim);
255 if ( mesh->info.imprim >= 0 ) {
256 fprintf(stdout,"\n MMG2DLIB: ELAPSED TIME %s\n",stim);
257 fprintf(stdout,"\n %s\n END OF MODULE MMG2D\n %s\n\n",MG_STR,MG_STR);
258 }
260
261}
262
273static inline
275 MMG5_int k;
276
278 if ( !mesh->tria ) {
279 /* If we call the library more than one time and if we free the triangles
280 * using the MMG2D_Free_triangles function we need to reallocate it */
281 MMG5_ADD_MEM(mesh,(mesh->ntmax+1)*sizeof(MMG5_Tria),
282 "initial triangles",return 0);
284 mesh->nenil = mesh->nt + 1;
285 for ( k=mesh->nenil; k<mesh->ntmax-1; k++) {
286 mesh->tria[k].v[2] = k+1;
287 }
288 }
289 if ( mesh->na && !mesh->edge ) {
290 /* If we call the library more than one time and if we free the triangles
291 * using the MMG2D_Free_triangles function we need to reallocate it */
292 MMG5_ADD_MEM(mesh,(mesh->namax+1)*sizeof(MMG5_Edge),
293 "initial edges",return 0);
295 if ( mesh->na < mesh->namax ) {
296 mesh->nanil = mesh->na + 1;
297 }
298 else
299 mesh->nanil = 0;
300 }
301
302 return 1;
303}
304
306 MMG5_pSol sol=NULL; // unused
307 mytime ctim[TIMEMAX];
308 char stim[32];
309
310 assert ( mesh );
311 assert ( met );
312 assert ( mesh->point );
313
314 MMG5_version(mesh,"2D");
315
316 /*uncomment for callback*/
317 //MMG2D_callbackinsert = titi;
318
319 /* interrupts */
320 signal(SIGABRT,MMG2D_excfun);
321 signal(SIGFPE,MMG2D_excfun);
322 signal(SIGILL,MMG2D_excfun);
323 signal(SIGSEGV,MMG2D_excfun);
324 signal(SIGTERM,MMG2D_excfun);
325 signal(SIGINT,MMG2D_excfun);
326
327 tminit(ctim,TIMEMAX);
328 chrono(ON,&(ctim[0]));
329
330 /* Check options */
331 if ( mesh->nt ) {
332 fprintf(stdout,"\n ## ERROR: YOUR MESH CONTAINS ALREADY TRIANGLES.\n"
333 " THE MESH GENERATION OPTION IS UNAVAILABLE.\n");
335 }
336
337 else if ( mesh->info.iso || mesh->info.isosurf ) {
338 fprintf(stdout,"\n ## ERROR: LEVEL-SET DISCRETISATION UNAVAILABLE"
339 " (MMG2D_IPARAM_iso || MMG2D_IPARAM_isosurf ):\n"
340 " YOU MUST CALL THE MMG2D_MMG2DLS FUNCTION TO USE THIS OPTION.\n");
342 }
343
344 else if ( mesh->info.lag >= 0 ) {
345 fprintf(stdout,"\n ## ERROR: LAGRANGIAN MODE UNAVAILABLE (MMG2D_IPARAM_lag):\n"
346 " YOU MUST CALL THE MMG2D_MMG2DMOV FUNCTION TO MOVE A RIGIDBODY.\n");
348 }
349 /* specific meshing */
350 if ( met->np ) {
351 if ( mesh->info.optim ) {
352 printf("\n ## ERROR: MISMATCH OPTIONS: OPTIM OPTION CAN NOT BE USED"
353 " WITH AN INPUT METRIC.\n");
355 }
356
357 if ( mesh->info.hsiz>0. ) {
358 printf("\n ## ERROR: MISMATCH OPTIONS: HSIZ OPTION CAN NOT BE USED"
359 " WITH AN INPUT METRIC.\n");
361 }
362 }
363
364 if ( mesh->info.optim && mesh->info.hsiz>0. ) {
365 printf("\n ## ERROR: MISMATCH OPTIONS: HSIZ AND OPTIM OPTIONS CAN NOT BE USED"
366 " TOGETHER.\n");
368 }
369
370 if ( mesh->info.imprim > 0 ) fprintf(stdout,"\n -- MMG2DMESH: INPUT DATA\n");
371
372 /* Check input */
373 chrono(ON,&(ctim[1]));
374
375 if ( met->np && (met->np != mesh->np) ) {
376 fprintf(stdout,"\n ## WARNING: WRONG SOLUTION NUMBER : %" MMG5_PRId " != %" MMG5_PRId "\n",met->np,mesh->np);
378 } else if ( met->size!=1 && met->size!=3 ) {
379 fprintf(stderr,"\n ## ERROR: WRONG DATA TYPE.\n");
381 }
382
383 chrono(OFF,&(ctim[1]));
384 printim(ctim[1].gdif,stim);
385 if ( mesh->info.imprim > 0 )
386 fprintf(stdout," -- INPUT DATA COMPLETED. %s\n",stim);
387
388 /* Create function pointers */
389 MMG2D_setfunc(mesh,met);
391
392 if ( abs(mesh->info.imprim) > 5 || mesh->info.ddebug ) {
393 fprintf(stdout," MAXIMUM NUMBER OF POINTS (NPMAX) : %8" MMG5_PRId "\n",mesh->npmax);
394 fprintf(stdout," MAXIMUM NUMBER OF TRIANGLES (NTMAX) : %8" MMG5_PRId "\n",mesh->ntmax);
395 }
396
397 /* analysis */
398 chrono(ON,&ctim[2]);
399
400 if ( !MMG2D_restart(mesh) ) {
402 }
403
404 if ( mesh->info.imprim > 0 ) fprintf(stdout,"\n -- PHASE 1 : MESH GENERATION\n");
405
406 /* reset fem value to user setting (needed for multiple library call) */
408
409 /* reset metRidTyp value to 0 (needed for multiple library call because it is
410 * used to mark if input edge have been stored into triangles) */
411 mesh->info.metRidTyp = 0;
412
413 /* scaling mesh */
415
416 if ( mesh->info.ddebug && !MMG5_chkmsh(mesh,1,0) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE);
417
418 /* Memory alloc */
419 MMG5_ADD_MEM(mesh,(3*mesh->ntmax+5)*sizeof(MMG5_int),"adjacency table",
420 printf(" Exit program.\n");
421 return MMG5_STRONGFAILURE);
422 MMG5_SAFE_CALLOC(mesh->adja,3*mesh->ntmax+5,MMG5_int,return MMG5_STRONGFAILURE);
423
424 /* Delaunay triangulation of the set of points contained in the mesh,
425 * enforcing the edges of the mesh */
426 if ( !MMG2D_mmg2d2(mesh,met) ) {
429 }
430
431 chrono(OFF,&(ctim[2]));
432 printim(ctim[2].gdif,stim);
433 if ( mesh->info.imprim > 0 )
434 fprintf(stdout," -- PHASE 1 COMPLETED. %s\n",stim);
435
436 /* remeshing */
437 chrono(ON,&ctim[3]);
438 if ( mesh->info.imprim > 0 ) {
439 fprintf(stdout,"\n -- PHASE 2 : ANALYSIS\n");
440 }
441
442 /* specific meshing */
443 if ( mesh->info.optim ) {
444 if ( !MMG2D_doSol(mesh,met) ) {
445 if ( !MMG5_unscaleMesh(mesh,met,NULL) )
448 }
449 } else if (mesh->info.hsiz > 0.) {
450 if ( !MMG2D_Set_constantSize(mesh,met) ) {
453 }
454 } else {
455 /* Set default hmin and hmax values */
457 if ( !MMG5_unscaleMesh(mesh,met,NULL) )
460 }
461 }
462
463 /* Mesh analysis */
464 if (! MMG2D_analys(mesh) ) {
465 if ( !MMG5_unscaleMesh(mesh,met,NULL) )
468 }
469 if ( mesh->info.ddebug && !MMG5_chkmsh(mesh,1,1) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE);
470
471 chrono(OFF,&(ctim[3]));
472 printim(ctim[3].gdif,stim);
473 if ( mesh->info.imprim > 0 )
474 fprintf(stdout," -- PHASE 2 COMPLETED. %s\n",stim);
475
476 /* Mesh improvement - call new version of mmg2d1 */
477 chrono(ON,&(ctim[4]));
478 if ( mesh->info.imprim > 0 )
479 fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT (%s)\n",
480 met->size < 3 ? "ISOTROPIC" : "ANISOTROPIC");
481
482 if ( !MMG2D_mmg2d1n(mesh,met) ) {
485 }
486
487 chrono(OFF,&(ctim[4]));
488 printim(ctim[4].gdif,stim);
489 if ( mesh->info.imprim > 0 ) {
490 fprintf(stdout," -- PHASE 3 COMPLETED. %s\n",stim);
491 }
492
493 /* Print quality histories */
494 if ( !MMG2D_outqua(mesh,met) ) {
496 }
497
498 /* Print edge length histories */
499 if ( abs(mesh->info.imprim) > 4 && met->m && met->np ) {
500 MMG2D_prilen(mesh,met);
501 }
502
503 /* Unscale mesh */
505
506 chrono(ON,&(ctim[1]));
507 if ( mesh->info.imprim > 0 ) fprintf(stdout,"\n -- MESH PACKED UP\n");
508
510
511 chrono(OFF,&(ctim[1]));
512
513 chrono(OFF,&ctim[0]);
514 printim(ctim[0].gdif,stim);
515 if ( mesh->info.imprim >= 0 ) {
516 fprintf(stdout,"\n MMG2DMESH: ELAPSED TIME %s\n",stim);
517 fprintf(stdout,"\n %s\n END OF MODULE MMG2D\n %s\n\n",MG_STR,MG_STR);
518 }
519
521
522}
523
525 MMG5_pSol met=NULL;
526 mytime ctim[TIMEMAX];
527 char stim[32];
528 int8_t mettofree = 0;
529
530 assert ( mesh );
531 assert ( sol );
532 assert ( mesh->point );
533 assert ( mesh->tria );
534
535 MMG5_version(mesh,"2D");
536
537 if ( (!mesh->info.iso) && (!mesh->info.isosurf) ) {
538 fprintf(stdout,"\n ## WARNING: ISO MODE NOT PROVIDED: ENABLING ISOVALUE DISCRETIZATION MODE (-ls) \n");
539 mesh->info.iso = 1;
540 }
541
542 if ( !umet ) {
543 /* User doesn't provide the metric, allocate our own one */
545 mettofree = 1;
546 }
547 else {
548 met = umet;
549 }
550
551 /*uncomment for callback*/
552 //MMG2D_callbackinsert = titi;
553
554 /* interrupts */
555 signal(SIGABRT,MMG2D_excfun);
556 signal(SIGFPE,MMG2D_excfun);
557 signal(SIGILL,MMG2D_excfun);
558 signal(SIGSEGV,MMG2D_excfun);
559 signal(SIGTERM,MMG2D_excfun);
560 signal(SIGINT,MMG2D_excfun);
561
562 tminit(ctim,TIMEMAX);
563 chrono(ON,&(ctim[0]));
564
565 /* Check options */
566 if ( mesh->info.lag >= 0 ) {
567 fprintf(stdout,"\n ## ERROR: LAGRANGIAN MODE UNAVAILABLE (MMG2D_IPARAM_lag):\n"
568 " YOU MUST CALL THE MMG2D_mmg2dmov FUNCTION TO MOVE A RIGIDBODY.\n");
570 }
571
572 /* Check input */
573 if ( mesh->info.imprim > 0 ) fprintf(stdout,"\n -- MMG2DLS: INPUT DATA\n");
574 chrono(ON,&(ctim[1]));
575
576 sol->ver = mesh->ver;
577
578 if ( !mesh->nt ) {
579 fprintf(stdout,"\n ## ERROR: NO TRIANGLES IN THE MESH \n");
580 if ( mettofree ) { MMG5_SAFE_FREE (met); }
582 }
583 else if ( !sol->m ) {
584 fprintf(stdout,"\n ## ERROR: A VALID SOLUTION FILE IS NEEDED \n");
585 if ( mettofree ) { MMG5_SAFE_FREE (met); }
587 }
588 else if ( sol->size != 1 ) {
589 fprintf(stdout,"\n ## ERROR: WRONG DATA TYPE.\n");
590 if ( mettofree ) { MMG5_SAFE_FREE (met); }
592 }
593 else if ( sol->np && (sol->np != mesh->np) ) {
594 fprintf(stdout,"\n ## WARNING: WRONG SOLUTION NUMBER. IGNORED\n");
595 if ( mettofree ) { MMG5_SAFE_FREE (met); }
597 }
598
599 /* specific meshing */
600 if ( met && met->np ) {
601 if ( mesh->info.optim ) {
602 printf("\n ## ERROR: MISMATCH OPTIONS: OPTIM OPTION CAN NOT BE USED"
603 " WITH AN INPUT METRIC.\n");
604 if ( mettofree ) { MMG5_SAFE_FREE (met); }
606 }
607 if ( mesh->info.hsiz>0. ) {
608 printf("\n ## ERROR: MISMATCH OPTIONS: HSIZ OPTION CAN NOT BE USED"
609 " WITH AN INPUT METRIC.\n");
610 if ( mettofree ) { MMG5_SAFE_FREE (met); }
612 }
613 if ( met->np != mesh->np ) {
614 fprintf(stdout,"\n ## WARNING: WRONG METRIC NUMBER. IGNORED\n");
615 if ( mettofree ) { MMG5_SAFE_FREE (met); }
617 }
618 }
619
620 if ( mesh->info.optim && mesh->info.hsiz>0. ) {
621 printf("\n ## ERROR: MISMATCH OPTIONS: HSIZ AND OPTIM OPTIONS CAN NOT BE USED"
622 " TOGETHER.\n");
623 if ( mettofree ) { MMG5_SAFE_FREE (met); }
625 }
626
627 if ( mesh->nquad && mesh->quadra ) {
628 printf("\n ## ERROR: UNABLE TO HANDLE HYBRID MESHES IN ISOVALUE DISCRETIZATION MODE.\n");
629 if ( mettofree ) { MMG5_SAFE_FREE (met); }
631 }
632
633 chrono(OFF,&(ctim[1]));
634 printim(ctim[1].gdif,stim);
635 if ( mesh->info.imprim > 0 )
636 fprintf(stdout," -- INPUT DATA COMPLETED. %s\n",stim);
637
638 chrono(ON,&ctim[2]);
639
640 /* Set pointers */
641 MMG2D_setfunc(mesh,met);
643
644 if ( mesh->info.imprim > 0 )
645 fprintf(stdout,"\n -- PHASE 1 : ISOSURFACE DISCRETIZATION\n");
646
647 if ( abs(mesh->info.imprim) > 5 || mesh->info.ddebug ) {
648 fprintf(stdout," MAXIMUM NUMBER OF POINTS (NPMAX) : %8"MMG5_PRId"\n",mesh->npmax);
649 fprintf(stdout," MAXIMUM NUMBER OF TRIANGLES (NTMAX) : %8"MMG5_PRId"\n",mesh->ntmax);
650 }
651
652 /* reset fem value to user setting (needed for multiple library call) */
654
655 /* reset metRidTyp value to 0 (needed for multiple library call because it is
656 * used to mark if input edge have been stored into triangles) */
657 mesh->info.metRidTyp = 0;
658
659 /* scaling mesh */
660 if ( !MMG5_scaleMesh(mesh,met,sol) ) {
661 if ( mettofree ) { MMG5_SAFE_FREE (met); }
663 }
664
665 if ( mesh->nt && !MMG2D_hashTria(mesh) ) {
666 if ( mettofree ) { MMG5_SAFE_FREE (met); }
668 }
669
670 if ( mesh->info.ddebug && !MMG5_chkmsh(mesh,1,0) ) {
671 if ( mettofree ) { MMG5_SAFE_FREE (met); }
673 }
674
675 /* Print initial quality */
676 if ( mesh->info.imprim > 0 || mesh->info.imprim < -1 ) {
677 if ( !MMG2D_outqua(mesh,met) ) {
678 if ( mettofree ) {
679 MMG5_DEL_MEM(mesh,met->m);
680 MMG5_SAFE_FREE (met);
681 }
682 if ( !MMG5_unscaleMesh(mesh,met,sol) ) {
684 }
686 }
687 }
688
689 /* Specific meshing: compute optim option here because after isovalue
690 * discretization mesh elements have too bad qualities */
691 if ( mesh->info.optim ) {
692 if ( !MMG2D_doSol(mesh,met) ) {
693 if ( mettofree ) {
694 MMG5_DEL_MEM(mesh,met->m);
695 MMG5_SAFE_FREE (met);
696 }
697
698 if ( !MMG5_unscaleMesh(mesh,met,NULL) ) {
701 }
702 }
703
704 /* Discretization of the mesh->info.ls isovalue of sol in the mesh */
705 if ( !MMG2D_mmg2d6(mesh,sol,met) ) {
706 if ( mettofree ) { MMG5_SAFE_FREE (met); }
707 if ( !MMG5_unscaleMesh(mesh,met,sol) ) {
709 }
711 }
712
713 chrono(OFF,&(ctim[2]));
714 printim(ctim[2].gdif,stim);
715 if ( mesh->info.imprim > 0 )
716 fprintf(stdout," -- PHASE 1 COMPLETED. %s\n",stim);
717
718 chrono(ON,&(ctim[3]));
719 if ( mesh->info.imprim > 0 ) {
720 fprintf(stdout,"\n -- PHASE 2 : ANALYSIS\n");
721 }
722
723 /* Specific meshing: compute hsiz on mesh after isovalue discretization */
724 if ( mesh->info.hsiz > 0. ) {
725 if ( !MMG2D_Set_constantSize(mesh,met) ) {
726 if ( mettofree ) {
727 MMG5_DEL_MEM(mesh,met->m);
728 MMG5_SAFE_FREE (met);
729 }
730 if ( !MMG5_unscaleMesh(mesh,met,sol) ) {
732 }
734 }
735 }
736
737 /* Mesh analysis */
738 if (! MMG2D_analys(mesh) ) {
739 if ( mettofree ) {
740 MMG5_DEL_MEM(mesh,met->m);
741 MMG5_SAFE_FREE (met);
742 }
743 if ( !MMG5_unscaleMesh(mesh,met,NULL) ) {
745 }
747 }
748 if ( mesh->info.ddebug && !MMG5_chkmsh(mesh,1,1) ) _LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE);
749
750 chrono(OFF,&(ctim[3]));
751 printim(ctim[3].gdif,stim);
752 if ( mesh->info.imprim > 0 )
753 fprintf(stdout," -- PHASE 2 COMPLETED. %s\n",stim);
754
755 /* Mesh improvement - call new version of mmg2d1 */
756 chrono(ON,&ctim[4]);
757 if ( mesh->info.imprim > 0 ) {
758 fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT\n");
759 }
760
761 if ( !MMG2D_mmg2d1n(mesh,met) ) {
762 if ( mettofree ) {
763 MMG5_DEL_MEM(mesh,met->m);
764 MMG5_SAFE_FREE (met);
765 }
768 }
769
770 /* End of mmg2dls */
771 chrono(OFF,&(ctim[4]));
772 printim(ctim[4].gdif,stim);
773 if ( mesh->info.imprim > 0 ) {
774 fprintf(stdout," -- PHASE 3 COMPLETED. %s\n",stim);
775 }
776
777 /* Print quality histories */
778 if ( !MMG2D_outqua(mesh,met) ) {
779 if ( mettofree ) {
780 MMG5_DEL_MEM(mesh,met->m);
781 MMG5_SAFE_FREE (met);
782 }
784 }
785
786 /* Unscale mesh */
787 if ( !MMG5_unscaleMesh(mesh,met,NULL) ) {
788 if ( mettofree ) {
789 MMG5_DEL_MEM(mesh,met->m);
790 MMG5_SAFE_FREE (met);
791 }
793 }
794
795 chrono(ON,&(ctim[1]));
796 if ( mesh->info.imprim > 0 ) fprintf(stdout,"\n -- MESH PACKED UP\n");
797
798 /* Pack mesh */
799 if (!MMG2D_pack(mesh,sol,met) ) {
800 if ( mettofree ) { MMG5_SAFE_FREE (met); }
802 }
803
804 chrono(OFF,&(ctim[1]));
805
806 chrono(OFF,&ctim[0]);
807 printim(ctim[0].gdif,stim);
808 if ( mesh->info.imprim >= 0 ) {
809 fprintf(stdout,"\n MMG2DLS: ELAPSED TIME %s\n",stim);
810 fprintf(stdout,"\n %s\n END OF MODULE MMG2D\n %s\n\n",MG_STR,MG_STR);
811 }
812 if ( mettofree ) {
813 MMG5_DEL_MEM(mesh,met->m);
814 MMG5_SAFE_FREE (met);
815 }
817
818}
819
821 mytime ctim[TIMEMAX];
822 char stim[32];
823 int ier;
824 MMG5_int k,*invalidTris;
825
826 assert ( mesh );
827 assert ( disp );
828 assert ( met );
829 assert ( mesh->point );
830 assert ( mesh->tria );
831
832 MMG5_version(mesh,"2D");
833
834 /*uncomment for callback*/
835 //MMG2D_callbackinsert = titi;
836
837 /* interrupts */
838 signal(SIGABRT,MMG2D_excfun);
839 signal(SIGFPE,MMG2D_excfun);
840 signal(SIGILL,MMG2D_excfun);
841 signal(SIGSEGV,MMG2D_excfun);
842 signal(SIGTERM,MMG2D_excfun);
843 signal(SIGINT,MMG2D_excfun);
844
845 tminit(ctim,TIMEMAX);
846 chrono(ON,&(ctim[0]));
847
848 /* Check data compatibility */
849 if ( mesh->info.imprim > 0 ) fprintf(stdout,"\n -- MMG2DMOV: INPUT DATA\n");
850 chrono(ON,&(ctim[1]));
851
852 disp->ver = mesh->ver;
853
854#ifndef USE_ELAS
855 fprintf(stderr,"\n ## ERROR: YOU NEED TO COMPILE WITH THE USE_ELAS"
856 " CMake's FLAG SET TO ON TO USE THE RIGIDBODY MOVEMENT LIBRARY.\n");
858#endif
859
860 if ( !mesh->nt ) {
861 fprintf(stdout,"\n ## ERROR: NO TRIANGLES IN THE MESH \n");
863 }
864 else if ( !disp->m ) {
865 fprintf(stdout,"\n ## ERROR: A VALID SOLUTION FILE IS NEEDED \n");
867 }
868 else if ( disp->size != 2 ) {
869 fprintf(stdout,"\n ## ERROR: LAGRANGIAN MOTION OPTION NEED A VECTOR DISPLACEMENT.\n");
871 }
872 else if ( disp->np && (disp->np != mesh->np) ) {
873 fprintf(stdout,"\n ## WARNING: WRONG SOLUTION NUMBER. IGNORED\n");
874 MMG5_DEL_MEM(mesh,disp->m);
875 disp->np = 0;
876 }
877
878 if ( mesh->info.optim ) {
879 printf("\n ## ERROR: OPTIM OPTION UNAVAILABLE IN LAGRANGIAN"
880 " MOVEMENT MODE.\n");
882 }
883 if ( mesh->info.hsiz>0. ) {
884 printf("\n ## ERROR: HSIZ OPTION UNAVAILABLE IN LAGRANGIAN"
885 " MOVEMENT MODE.\n");
887 }
888
889 if ( mesh->nquad && mesh->quadra ) {
890 printf("\n ## ERROR: UNABLE TO HANDLE HYBRID MESHES IN LAGRANGIAN MOVEMENT MODE.\n");
892 }
893
894
895 chrono(OFF,&(ctim[1]));
896 printim(ctim[1].gdif,stim);
897 if ( mesh->info.imprim > 0 )
898 fprintf(stdout," -- INPUT DATA COMPLETED. %s\n",stim);
899
900 /* Set pointers */
901 MMG2D_setfunc(mesh,met);
903
904 chrono(ON,&ctim[2]);
905
906 if ( mesh->info.imprim > 0 ) {
907 fprintf(stdout,"\n -- PHASE 1 : ANALYSIS\n");
908 }
909
910 if ( abs(mesh->info.imprim) > 5 || mesh->info.ddebug ) {
911 fprintf(stdout," MAXIMUM NUMBER OF POINTS (NPMAX) : %8" MMG5_PRId "\n",mesh->npmax);
912 fprintf(stdout," MAXIMUM NUMBER OF TRIANGLES (NTMAX) : %8" MMG5_PRId "\n",mesh->ntmax);
913 }
914
915 /* Analysis */
916
917 /* reset fem value to user setting (needed for multiple library call) */
919
920 /* reset metRidTyp value to 0 (needed for multiple library call because it is
921 * used to mark if input edge have been stored into triangles) */
922 mesh->info.metRidTyp = 0;
923
924 /* scaling mesh */
925 if ( !MMG5_scaleMesh(mesh,NULL,disp) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE);
926
928
929 /* Print initial quality */
930 if ( mesh->info.imprim > 0 || mesh->info.imprim < -1 ) {
931 if ( !MMG2D_outqua(mesh,met) ) {
932 if ( !MMG5_unscaleMesh(mesh,NULL,disp) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE);
934 }
935 }
936
937 /* Mesh analysis */
938 if (! MMG2D_analys(mesh) )
940
941 if ( mesh->info.ddebug && !MMG5_chkmsh(mesh,1,1) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE);
942
943 chrono(OFF,&(ctim[2]));
944 printim(ctim[2].gdif,stim);
945 if ( mesh->info.imprim > 0 )
946 fprintf(stdout," -- PHASE 1 COMPLETED. %s\n",stim);
947
948 /* Lagrangian motion */
949 chrono(ON,&(ctim[3]));
950 if ( mesh->info.imprim > 0 ) {
951 fprintf(stdout,"\n -- PHASE 2 : LAGRANGIAN MOTION\n");
952 }
953
954 /* Lagrangian mode */
955 invalidTris = NULL;
956 ier = MMG2D_mmg2d9(mesh,disp,met,&invalidTris);
957 if ( !ier ) {
958 disp->npi = disp->np;
960 }
961 else if ( ier < 0 ) {
962 printf("\n ## Warning: Unable to perform any movement "
963 "(%d intersecting triangles).\n",-ier);
964 if ( mesh->info.imprim > 1 ) {
965 printf(" List of invalid trias: ");
966 for ( k=0; k<-ier; ++k ) {
967 printf("%" MMG5_PRId " ",MMG2D_indElt(mesh,invalidTris[k]));
968 }
969 printf("\n\n");
970 }
971 MMG5_SAFE_FREE(invalidTris);
972 }
973
974 chrono(OFF,&(ctim[3]));
975 printim(ctim[3].gdif,stim);
976 if ( mesh->info.imprim > 0 ) {
977 fprintf(stdout," -- PHASE 2 COMPLETED. %s\n",stim);
978 }
979
980 /* End with a classical remeshing stage, provided mesh->info.lag > 1 */
981 if ( (ier > 0) && (mesh->info.lag >= 1) ) {
982 chrono(ON,&(ctim[4]));
983 if ( mesh->info.imprim > 0 ) {
984 fprintf(stdout,"\n -- PHASE 3 : MESH IMPROVEMENT\n");
985 }
986
987 if ( !MMG2D_mmg2d1n(mesh,met) ) {
988 if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE);
990 }
991
992 chrono(OFF,&(ctim[4]));
993 printim(ctim[4].gdif,stim);
994 if ( mesh->info.imprim > 0 ) {
995 fprintf(stdout," -- PHASE 3 COMPLETED. %s\n",stim);
996 }
997 }
998
999 /* Print quality histories */
1000 if ( !MMG2D_outqua(mesh,met) ) {
1002 }
1003
1004 /* Unscale mesh */
1005 if ( !MMG5_unscaleMesh(mesh,met,NULL) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_STRONGFAILURE);
1006
1007 chrono(ON,&(ctim[1]));
1008 if ( mesh->info.imprim > 0 ) fprintf(stdout,"\n -- MESH PACKED UP\n");
1009
1010 /* Pack mesh */
1011 if (!MMG2D_pack(mesh,met,disp) ) _LIBMMG5_RETURN(mesh,met,disp,MMG5_LOWFAILURE);
1012
1013 chrono(OFF,&(ctim[1]));
1014
1015 chrono(OFF,&ctim[0]);
1016 printim(ctim[0].gdif,stim);
1017 if ( mesh->info.imprim >= 0 ) {
1018 fprintf(stdout,"\n MMG2DMOV: ELAPSED TIME %s\n",stim);
1019 fprintf(stdout,"\n %s\n END OF MODULE MMG2D\n %s\n\n",MG_STR,MG_STR);
1020 }
1021
1023}
int MMG5_Set_defaultTruncatureSizes(MMG5_pMesh mesh, int8_t sethmin, int8_t sethmax)
int ier
MMG5_pMesh MMG5_pSol * sol
MMG5_pMesh * mesh
int MMG2D_analys(MMG5_pMesh mesh)
Definition: analys_2d.c:1014
int MMG2D_grad2metreq_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG5_pTria pt, MMG5_int npmaster, MMG5_int npslave)
Definition: anisosiz_2d.c:600
MMG5_int MMG2D_grad2met_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG5_pTria pt, MMG5_int np1, MMG5_int np2)
Definition: anisosiz_2d.c:537
int MMG5_mmg2dChkmsh(MMG5_pMesh mesh, int severe, MMG5_int base)
Definition: chkmsh_2d.c:36
void tminit(mytime *t, int maxtim)
Initialize mytime object.
Definition: chrono.c:120
void printim(double elps, char *stim)
Print real time.
Definition: chrono.c:160
void chrono(int cmode, mytime *ptt)
Function to measure time.
Definition: chrono.c:49
#define TIMEMAX
int MMG2D_hashTria(MMG5_pMesh mesh)
Definition: hash_2d.c:35
int MMG2D_pack(MMG5_pMesh mesh, MMG5_pSol sol, MMG5_pSol met)
Definition: hash_2d.c:530
int MMG2D_prilen(MMG5_pMesh mesh, MMG5_pSol sol)
Definition: length_2d.c:125
int MMG2D_mmg2dlib(MMG5_pMesh mesh, MMG5_pSol met)
Main "program" for the mesh adaptation library.
Definition: libmmg2d.c:63
#define MMG2D_RETURN_AND_PACK(mesh, met, sol, val)
Definition: libmmg2d.c:33
int MMG2D_mmg2dls(MMG5_pMesh mesh, MMG5_pSol sol, MMG5_pSol umet)
Main "program" for the level-set discretization library.
Definition: libmmg2d.c:524
int MMG2D_mmg2dmesh(MMG5_pMesh mesh, MMG5_pSol met)
Main "program" for the mesh generation library.
Definition: libmmg2d.c:305
static int MMG2D_restart(MMG5_pMesh mesh)
Definition: libmmg2d.c:274
void MMG2D_Set_commonFunc(void)
Set common function pointers between mmgs and mmg2d to the matching mmg2d functions.
Definition: libmmg2d.c:52
int MMG2D_mmg2dmov(MMG5_pMesh mesh, MMG5_pSol met, MMG5_pSol disp)
Main "program" for the rigid-body movement library.
Definition: libmmg2d.c:820
API headers and documentation for the mmg2d library.
LIBMMG2D_EXPORT int(* MMG2D_doSol)(MMG5_pMesh mesh, MMG5_pSol met)
Compute unit tensor according to the lengths of the edges passing through a vertex.
Definition: mmg2dexterns.c:9
LIBMMG2D_EXPORT int MMG2D_Set_constantSize(MMG5_pMesh mesh, MMG5_pSol met)
Compute a constant size map according to the hsiz, hmin and hmax parameters.
LIBMMG2D_EXPORT void MMG2D_setfunc(MMG5_pMesh mesh, MMG5_pSol met)
Set function pointers for length, caltri... depending if case is iso or aniso.
int MMG2D_mmg2d1n(MMG5_pMesh, MMG5_pSol)
Definition: mmg2d1.c:819
MMG5_int MMG2D_indPt(MMG5_pMesh mesh, MMG5_int kp)
Definition: tools_2d.c:70
static void MMG2D_excfun(int sigid)
int MMG2D_mmg2d9(MMG5_pMesh, MMG5_pSol, MMG5_pSol, MMG5_int **)
Definition: mmg2d9.c:459
int MMG2D_mmg2d2(MMG5_pMesh, MMG5_pSol)
Definition: mmg2d2.c:507
MMG5_int MMG2D_indElt(MMG5_pMesh mesh, MMG5_int kel)
Definition: tools_2d.c:46
int MMG2D_outqua(MMG5_pMesh, MMG5_pSol)
Definition: quality_2d.c:183
void MMG2D_keep_only1Subdomain(MMG5_pMesh mesh, int nsd)
Definition: tools_2d.c:92
int MMG2D_mmg2d6(MMG5_pMesh, MMG5_pSol, MMG5_pSol)
Definition: mmg2d6.c:204
LIBMMG_CORE_EXPORT int MMG5_unscaleMesh(MMG5_pMesh mesh, MMG5_pSol met, MMG5_pSol ls)
Definition: scalem.c:689
LIBMMG_CORE_EXPORT int MMG5_scaleMesh(MMG5_pMesh mesh, MMG5_pSol met, MMG5_pSol ls)
Definition: scalem.c:649
#define MMG5_STRONGFAILURE
Definition: libmmgtypes.h:65
#define MMG5_LOWFAILURE
Definition: libmmgtypes.h:57
#define MMG5_SUCCESS
Definition: libmmgtypes.h:49
void MMG5_version(MMG5_pMesh mesh, char *dim)
Functions needed by libraries API.
Definition: libtools.c:43
#define MMG5_SAFE_CALLOC(ptr, size, type, law)
#define _LIBMMG5_RETURN(mesh, sol, met, val)
#define MMG5_ADD_MEM(mesh, size, message, law)
#define MG_STR
int MMG5_2dSolTruncature_ani(MMG5_pMesh mesh, MMG5_pSol met)
Definition: scalem.c:365
#define MMG5_SAFE_FREE(ptr)
#define MMG5_DEL_MEM(mesh, ptr)
Structure to store edges of am MMG mesh.
Definition: libmmgtypes.h:311
int8_t iso
Definition: libmmgtypes.h:541
int8_t ddebug
Definition: libmmgtypes.h:539
double hsiz
Definition: libmmgtypes.h:525
int8_t isosurf
Definition: libmmgtypes.h:542
double hmin
Definition: libmmgtypes.h:525
int8_t setfem
Definition: libmmgtypes.h:543
uint8_t metRidTyp
Definition: libmmgtypes.h:554
double hmax
Definition: libmmgtypes.h:525
int8_t lag
Definition: libmmgtypes.h:547
MMG5_int nsd
Definition: libmmgtypes.h:529
uint8_t optim
Definition: libmmgtypes.h:553
int8_t fem
Definition: libmmgtypes.h:546
MMG mesh structure.
Definition: libmmgtypes.h:613
MMG5_int ntmax
Definition: libmmgtypes.h:620
MMG5_pQuad quadra
Definition: libmmgtypes.h:656
MMG5_Info info
Definition: libmmgtypes.h:659
MMG5_pPoint point
Definition: libmmgtypes.h:649
MMG5_int * adja
Definition: libmmgtypes.h:632
MMG5_int nquad
Definition: libmmgtypes.h:621
MMG5_int npmax
Definition: libmmgtypes.h:620
MMG5_int nenil
Definition: libmmgtypes.h:630
MMG5_int namax
Definition: libmmgtypes.h:620
MMG5_int nt
Definition: libmmgtypes.h:620
MMG5_pTria tria
Definition: libmmgtypes.h:655
MMG5_int np
Definition: libmmgtypes.h:620
MMG5_pEdge edge
Definition: libmmgtypes.h:657
MMG5_int nanil
Definition: libmmgtypes.h:631
MMG5_int na
Definition: libmmgtypes.h:620
MMG5_int npi
Definition: libmmgtypes.h:676
double * m
Definition: libmmgtypes.h:680
MMG5_int np
Definition: libmmgtypes.h:674
Structure to store triangles of a MMG mesh.
Definition: libmmgtypes.h:338
MMG5_int v[3]
Definition: libmmgtypes.h:340
Chrono object.