Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
libmmg2d_tools.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
33#include "libmmg2d.h"
34#include "libmmg2d_private.h"
36#include "mmgexterns_private.h"
37
39 if ( mesh->info.ani || (met && met->size==3 ) ) {
40 /* Force data consistency: if aniso metric is provided, met->size==3 and
41 * info.ani==0; with -A option, met->size==1 and info.ani==1 */
42 met->size = 3;
43 mesh->info.ani = 1;
44
45 /* Set pointers */
46 MMG2D_lencurv = MMG2D_lencurv_ani;
47 MMG5_compute_meanMetricAtMarkedPoints = MMG5_compute_meanMetricAtMarkedPoints_ani;
48 MMG2D_defsiz = MMG2D_defsiz_ani;
49 MMG2D_gradsiz = lissmet_ani;
50 MMG2D_gradsizreq = MMG5_gradsizreq_ani;
51 MMG2D_caltri = MMG2D_caltri_ani;
52 MMG2D_intmet = MMG2D_intmet_ani;
54 }
55 else {
56 MMG2D_lencurv = MMG2D_lencurv_iso;
57 MMG5_compute_meanMetricAtMarkedPoints = MMG5_compute_meanMetricAtMarkedPoints_iso;
58 MMG2D_defsiz = MMG2D_defsiz_iso;
59 MMG2D_gradsiz = MMG5_gradsiz_iso;
60 MMG2D_gradsizreq = MMG5_gradsizreq_iso;
61 MMG2D_caltri = MMG2D_caltri_iso;
62 MMG2D_intmet = MMG2D_intmet_iso;
64 }
65 return;
66}
67
68int MMG2D_usage(char *name) {
69
70 /* Common generic options, file options and mode options */
71 MMG5_mmgUsage(name);
72
73 /* Lagrangian option (only for mmg2d/3d) */
75
76 /* Common parameters (first section) */
78
79 /* Parameters shared by mmg2d and 3d only*/
81
82 /* Specific parameters */
83 fprintf(stdout,"-3dMedit val read and write for gmsh visu: output only if val=1, input and output if val=2, input if val=3\n");
84 fprintf(stdout,"\n");
85
86 fprintf(stdout,"-nofem do not force Mmg to create a finite element mesh \n");
87 fprintf(stdout,"-nosurf no surface modifications\n");
88
89 /* Common parameters (second section) */
91
92 /* Common options for advanced users */
94
95 fprintf(stdout,"\n\n");
96
97 return 1;
98}
99
100// In ls mode : metric must be provided using -met option (-sol or default is the ls).
101// In adp mode : -sol or -met or default allow to store the metric.
102int MMG2D_parsar(int argc,char *argv[],MMG5_pMesh mesh,MMG5_pSol met,MMG5_pSol sol) {
103 MMG5_pSol tmp = NULL;
104 int i;
105 char namein[MMG5_FILESTR_LGTH];
106
107 /* First step: search if user want to see the default parameters values. */
108 for ( i=1; i< argc; ++i ) {
109 if ( !strcmp(argv[i],"-val") ) {
111 return 0;
112 }
113 }
114
115 /* Second step: read all other arguments. */
116 i = 1;
117 while ( i < argc ) {
118 if ( *argv[i] == '-' ) {
119 switch(argv[i][1]) {
120 case '?':
121 MMG2D_usage(argv[0]);
122 return 0;
123 case 'a':
124 if ( !strcmp(argv[i],"-ar") && ++i < argc ) {
126 atof(argv[i])) )
127 return 0;
128 }
129 break;
130 case 'A': /* anisotropy */
132 return 0;
133 break;
134 case 'd':
135 if ( !strcmp(argv[i],"-default") ) {
136 mesh->mark=1;
137 } else { /* debug */
139 return 0;
140 }
141 break;
142 case 'h':
143 if ( !strcmp(argv[i],"-hmin") && ++i < argc ) {
145 atof(argv[i])) )
146 return 0;
147 }
148 else if ( !strcmp(argv[i],"-hmax") && ++i < argc ) {
150 atof(argv[i])) )
151 return 0;
152 }
153 else if ( !strcmp(argv[i],"-hsiz") && ++i < argc ) {
155 atof(argv[i])) )
156 return 0;
157
158 }
159 else if ( !strcmp(argv[i],"-hausd") && ++i <= argc ) {
161 atof(argv[i])) )
162 return 0;
163 }
164 else if ( !strcmp(argv[i],"-hgradreq") && ++i <= argc ) {
166 atof(argv[i])) )
167 return 0;
168 }
169 else if ( !strcmp(argv[i],"-hgrad") && ++i <= argc ) {
171 atof(argv[i])) )
172 return 0;
173 }
174 else {
175 MMG2D_usage(argv[0]);
176 return 0;
177 }
178 break;
179 case 'i':
180 if ( !strcmp(argv[i],"-in") ) {
181 if ( ++i < argc && isascii(argv[i][0]) && argv[i][0]!='-') {
182 if ( !MMG2D_Set_inputMeshName(mesh, argv[i]) )
183 return 0;
184
186 return 0;
187 }else{
188 fprintf(stderr,"Missing filname for %c%c\n",argv[i-1][1],argv[i-1][2]);
189 MMG2D_usage(argv[0]);
190 return 0;
191 }
192 }
193 else if ( !strcmp(argv[i],"-isoref") && ++i <= argc ) {
195 atoi(argv[i])) )
196 return 0;
197 }
198 else {
199 MMG2D_usage(argv[0]);
200 return 0;
201 }
202 break;
203 case 'l':
204 if ( !strcmp(argv[i],"-lag") ) {
205 if ( ++i < argc && isdigit(argv[i][0]) ) {
206 if ( !MMG2D_Set_iparameter(mesh,met,MMG2D_IPARAM_lag,atoi(argv[i])) )
207 return 0;
208 }
209 else if ( i == argc ) {
210 fprintf(stderr,"Missing argument option %s\n",argv[i-1]);
211 MMG2D_usage(argv[0]);
212 return 0;
213 }
214 else {
215 fprintf(stderr,"Missing argument option %s\n",argv[i-1]);
216 MMG2D_usage(argv[0]);
217 return 0;
218 }
219 }
220 else if ( !strcmp(argv[i],"-ls") ) {
222 return 0;
223 if ( ++i < argc && (isdigit(argv[i][0]) ||
224 (argv[i][0]=='-' && isdigit(argv[i][1])) ) ) {
225 if ( !MMG2D_Set_dparameter(mesh,met,MMG2D_DPARAM_ls,atof(argv[i])) )
226 return 0;
227 }
228 else i--;
229 }
230 else if ( !strcmp(argv[i],"-lssurf") ) {
232 return 0;
233 if ( ++i < argc && (isdigit(argv[i][0]) ||
234 (argv[i][0]=='-' && isdigit(argv[i][1])) ) ) {
235 if ( !MMG2D_Set_dparameter(mesh,met,MMG2D_DPARAM_ls,atof(argv[i])) )
236 return 0;
237 }
238 else i--;
239 }
240 break;
241 case 'm': /* memory */
242 if ( !strcmp(argv[i],"-met") ) {
243 if ( !met ) {
244 fprintf(stderr,"No metric structure allocated for %c%c%c option\n",
245 argv[i-1][1],argv[i-1][2],argv[i-1][3]);
246 return 0;
247 }
248 if ( ++i < argc && isascii(argv[i][0]) && argv[i][0]!='-' ) {
249 if ( !MMG2D_Set_inputSolName(mesh,met,argv[i]) )
250 return 0;
251 }
252 else {
253 fprintf(stderr,"Missing filname for %c%c%c\n",argv[i-1][1],argv[i-1][2],argv[i-1][3]);
254 MMG2D_usage(argv[0]);
255 return 0;
256 }
257 }
258 else if (!strcmp(argv[i],"-m") ) {
259 if ( ++i < argc && isdigit(argv[i][0]) ) {
260 if ( !MMG2D_Set_iparameter(mesh,met,MMG2D_IPARAM_mem,atoi(argv[i])) )
261 return 0;
262 }
263 else {
264 fprintf(stderr,"Missing argument option %c\n",argv[i-1][1]);
265 MMG2D_usage(argv[0]);
266 return 0;
267 }
268 }
269 break;
270 case 'n':
271 if ( !strcmp(argv[i],"-nofem") ) {
273 return 0;
274 }
275 if ( !strcmp(argv[i],"-nreg") ) {
277 return 0;
278 }
279 else if ( !strcmp(argv[i],"-nr") ) {
281 return 0;
282 }
283 else if ( !strcmp(argv[i],"-nsd") ) {
284 if ( ++i < argc && isdigit(argv[i][0]) ) {
285 if ( !MMG2D_Set_iparameter(mesh,met,MMG2D_IPARAM_numsubdomain,atoi(argv[i])) )
286 return 0;
287 }
288 else {
289 fprintf(stderr,"Missing argument option %c\n",argv[i-1][1]);
290 MMG2D_usage(argv[0]);
291 return 0;
292 }
293 } else if ( !strcmp(argv[i],"-noswap") ) {
295 return 0;
296 }
297 else if( !strcmp(argv[i],"-noinsert") ) {
299 return 0;
300 }
301 else if( !strcmp(argv[i],"-nomove") ) {
303 return 0;
304 }
305 else if( !strcmp(argv[i],"-nosurf") ) {
307 return 0;
308 }
309 else if( !strcmp(argv[i],"-nosizreq") ) {
311 return 0;
312 }
313 }
314 break;
315 case 'o':
316 if ( (!strcmp(argv[i],"-out")) || (!strcmp(argv[i],"-o")) ) {
317 if ( ++i < argc && isascii(argv[i][0]) && argv[i][0]!='-') {
318 if ( !MMG2D_Set_outputMeshName(mesh,argv[i]) )
319 return 0;
320 }else{
321 fprintf(stderr,"Missing filname for %c%c%c\n",
322 argv[i-1][1],argv[i-1][2],argv[i-1][3]);
323 MMG2D_usage(argv[0]);
324 return 0;
325 }
326 }
327 else if ( !strcmp(argv[i],"-opnbdy") ) {
329 return 0;
330 }
331 else if( !strcmp(argv[i],"-optim") ) {
333 return 0;
334 }
335 break;
336 case 'r':
337 if ( !strcmp(argv[i],"-rmc") ) {
339 return 0;
340 if ( ++i < argc && (isdigit(argv[i][0]) ) ) {
341 if ( !MMG2D_Set_dparameter(mesh,met,MMG2D_DPARAM_rmc,atof(argv[i])) )
342 return 0;
343 }
344 else i--;
345 }
346 break;
347 case 's':
348 if ( !strcmp(argv[i],"-sol") ) {
349 /* For retrocompatibility, store the metric if no sol structure available */
350 tmp = sol ? sol : met;
351
352 assert(tmp);
353 if ( ++i < argc && isascii(argv[i][0]) && argv[i][0]!='-' ) {
354 if ( !MMG2D_Set_inputSolName(mesh,tmp,argv[i]) )
355 return 0;
356 }
357 else {
358 fprintf(stderr,"Missing filname for %c%c%c\n",argv[i-1][1],argv[i-1][2],argv[i-1][3]);
359 MMG2D_usage(argv[0]);
360 return 0;
361 }
362 }
363 break;
364 case 'v':
365 if ( ++i < argc ) {
366 if ( argv[i][0] == '-' || isdigit(argv[i][0]) ) {
367 if ( !MMG2D_Set_iparameter(mesh,met,MMG2D_IPARAM_verbose,atoi(argv[i])) )
368 return 0;
369 }
370 else
371 i--;
372 }
373 else {
374 fprintf(stderr,"Missing argument option %c\n",argv[i-1][1]);
375 MMG2D_usage(argv[0]);
376 return 0;
377 }
378 break;
379 case 'x':
380 if ( !strcmp(argv[i],"-xreg") ) {
382 return 0;
383 }
384 break;
385 case '3':
386 if(!strcmp(argv[i],"-3dMedit") ) {
387 if ( ++i < argc && isdigit(argv[i][0]) ) {
388 if ( !MMG2D_Set_iparameter(mesh,met,MMG2D_IPARAM_3dMedit,atoi(argv[i])) )
389 return 0;
390 }
391 else {
392 fprintf(stderr,"Missing argument option %c\n",argv[i-1][1]);
393 MMG2D_usage(argv[0]);
394 return 0;
395 }
396 }
397 break;
398 default:
399 fprintf(stderr,"Unrecognized option %s\n",argv[i]);
400 MMG2D_usage(argv[0]);
401 return 0;
402 }
403
404 }
405
406 else {
407 if ( mesh->namein == NULL ) {
408 if ( !MMG2D_Set_inputMeshName(mesh,argv[i]) )
409 return 0;
410 if ( mesh->info.imprim == -99 ) {
412 return 0;
413 }
414 }
415 else if ( mesh->nameout == NULL ) {
416 if ( !MMG2D_Set_outputMeshName(mesh,argv[i]) )
417 return 0;
418 }
419 else {
420 fprintf(stdout," Argument %s ignored\n",argv[i]);
421 MMG2D_usage(argv[0]);
422 return 0;
423 }
424 }
425 i++;
426 }
427
429 if ( mesh->info.imprim == -99 ) {
430 fprintf(stdout,"\n -- PRINT (0 10(advised) -10) ?\n");
431 fflush(stdin);
432 MMG_FSCANF(stdin,"%d",&i);
434 return 0;
435 }
436
437 if ( mesh->namein == NULL ) {
438 fprintf(stdout," -- INPUT MESH NAME ?\n");
439 fflush(stdin);
440 MMG_FSCANF(stdin,"%127s",namein);
441 if ( !MMG2D_Set_inputMeshName(mesh,namein) )
442 return 0;
443 }
444 if ( mesh->nameout == NULL ) {
446 return 0;
447 }
448
449 /* adp mode: if the metric name has been stored in sol, move it in met */
450 if ( met->namein==NULL && sol && sol->namein && !(mesh->info.iso || mesh->info.isosurf || mesh->info.lag>=0) ) {
452 return 0;
454 }
455
456 /* default : store solution (resp. displacement) name in iso
457 * (resp. lagrangian) mode, metric name otherwise */
458 tmp = ( mesh->info.iso || mesh->info.isosurf || mesh->info.lag >=0 ) ? sol : met;
459 assert ( tmp );
460 if ( tmp->namein == NULL ) {
462 return 0;
463 }
464 if ( met->nameout == NULL ) {
465 if ( !MMG2D_Set_outputSolName(mesh,met,"") )
466 return 0;
467 }
468
469 return 1;
470}
471
480
482
483 fprintf(stdout,"\n\n");
484
485 return 1;
486}
487
498 int ret,i,j,npar,nbr,split;
499 MMG5_int ref,rin,rex,br;
500 float fp1,fp2,fp3;
501 char *ptr,data[256];
502 FILE *in;
503 fpos_t position;
504
505 /* Check for parameter file */
506 strcpy(data,mesh->namein);
507
508 ptr = MMG5_Get_filenameExt(data);
509
510 if ( ptr ) *ptr = '\0';
511 strcat(data,".mmg2d");
512
513 in = fopen(data,"rb");
514
515 if ( !in ) {
516 sprintf(data,"%s","DEFAULT.mmg2d");
517 in = fopen(data,"rb");
518 if ( !in ) {
519 return 1;
520 }
521 }
522 if ( mesh->info.imprim >= 0 ) {
523 fprintf(stdout,"\n %%%% %s OPENED\n",data);
524 }
525
526 /* Read parameters */
527 while ( !feof(in) ) {
528 ret = fscanf(in,"%255s",data);
529 if ( !ret || feof(in) ) break;
530 for (i=0; (size_t)i<strlen(data); i++) data[i] = tolower(data[i]);
531
532 /* Read user-defined references for the LS mode */
533 if ( !strcmp(data,"lsreferences") ) {
534 ret = fscanf(in,"%d",&npar);
535 if ( !ret ) {
536 fprintf(stderr," %%%% Wrong format for lsreferences: %d\n",npar);
537 return 0;
538 }
539
541 return 0;
542 }
543 for (i=0; i<mesh->info.nmat; i++) {
544 MMG_FSCANF(in,"%" MMG5_PRId "",&ref);
545 fgetpos(in,&position);
546 MMG_FSCANF(in,"%255s",data);
547 split = MMG5_MMAT_NoSplit;
548 rin = rex = ref;
549 if ( strcmp(data,"nosplit") ) {
550 fsetpos(in,&position);
551 split = MMG5_MMAT_Split;
552 MMG_FSCANF(in,"%" MMG5_PRId "",&rin);
553 MMG_FSCANF(in,"%" MMG5_PRId "",&rex);
554 }
555 if ( !MMG2D_Set_multiMat(mesh,met,ref,split,rin,rex) ) {
556 return 0;
557 }
558 }
559 }
560 /* Read user-defined local parameters and store them in the structure info->par */
561 else if ( !strcmp(data,"parameters") ) {
562 ret = fscanf(in,"%d",&npar);
563
564 if ( !ret ) {
565 fprintf(stderr," %%%% Wrong format for parameters: %d\n",npar);
566 return 0;
567 }
568 else if ( npar > MMG5_LPARMAX ) {
569 fprintf(stderr," %%%% Too many local parameters %d. Abort\n",npar);
570 return 0;
571 }
572
573 /* Allocate memory and fill the info->par table (adding one, corresponding to the command line data) */
574 if ( npar ) {
576 return 0;
577
578 for (i=0; i<mesh->info.npar; i++) {
579 ret = fscanf(in,"%" MMG5_PRId " %255s",&ref,data);
580 if ( ret ) ret = fscanf(in,"%f %f %f",&fp1,&fp2,&fp3);
581
582 if ( !ret ) {
583 fprintf(stderr," %%%% Wrong format: %s\n",data);
584 return (0);
585 }
586
587 for (j=0; (size_t)j<strlen(data); j++) data[j] = tolower(data[j]);
588 if ( !strcmp(data,"triangles") || !strcmp(data,"triangle") ) {
589 if ( !MMG2D_Set_localParameter(mesh,met,MMG5_Triangle,ref,fp1,fp2,fp3) ) {
590 return 0;
591 }
592 }
593 else if ( !strcmp(data,"edges") || !strcmp(data,"edge") ) {
594 if ( !MMG2D_Set_localParameter(mesh,met,MMG5_Edg,ref,fp1,fp2,fp3) ) {
595 return 0;
596 }
597 }
598 else {
599 fprintf(stderr," %%%% Wrong format: %s\n",data);
600 return 0;
601 }
602 }
603 }
604 }
605 /* Read user-defined references where connected components should stay attached in ls mode */
606 else if ( !strcmp(data,"lsbasereferences") ) {
607 MMG_FSCANF(in,"%d",&nbr);
609 return 0;
610
611 for (i=0; i<mesh->info.nbr; i++) {
612 MMG_FSCANF(in,"%" MMG5_PRId "",&br);
613 if ( !MMG2D_Set_lsBaseReference(mesh,met,br) ) {
614 return 0;
615 }
616 }
617 }
618 else {
619 fprintf(stderr," %%%% Wrong format: %s\n",data);
620 return 0;
621 }
622 }
623
624 fclose(in);
625 return 1;
626}
627
628/* Free the structure dedicated to the management of multiple local parameters */
630
631 free(mesh->info.par);
632 mesh->info.npar = 0;
633
634 return 1;
635}
636
638 MMG5_pTria pt,pt1;
639 MMG5_pEdge ped;
640 MMG5_int *adja,k,i,j,i1,i2,iel;
641
642 *nb_edges = 0;
643 if ( mesh->tria ) {
644 /* Create the triangle adjacency if needed */
645 if ( !mesh->adja ) {
646 if ( !MMG2D_hashTria( mesh ) ) {
647 fprintf(stderr,"\n ## Error: %s: unable to create "
648 "adjacency table.\n",__func__);
649 return 0;
650 }
651 }
652
653 /* Count the number of non boundary edges */
654 for ( k=1; k<=mesh->nt; k++ ) {
655 pt = &mesh->tria[k];
656 if ( !MG_EOK(pt) ) continue;
657
658 adja = &mesh->adja[3*(k-1)+1];
659
660 for ( i=0; i<3; i++ ) {
661 iel = adja[i] / 3;
662 assert ( iel != k );
663
664 pt1 = &mesh->tria[iel];
665
666 if ( (!iel) || (pt->ref != pt1->ref) ||
667 ((pt->ref==pt1->ref) && MG_SIN(pt->tag[i])) ||
668 (mesh->info.opnbdy && pt->tag[i]) ) {
669 /* Do not treat boundary edges */
670 continue;
671 }
672 if ( k < iel ) {
673 /* Treat edge from the triangle with lowest index */
674 ++(*nb_edges);
675 }
676 }
677 }
678
679 /* Append the non boundary edges to the boundary edges array */
680 if ( mesh->namax ) {
681 MMG5_ADD_MEM(mesh,(*nb_edges)*sizeof(MMG5_Edge),"non boundary edges",
682 printf(" Exit program.\n");
683 return 0);
684 MMG5_SAFE_RECALLOC(mesh->edge,(mesh->namax+1),(mesh->namax+(*nb_edges)+1),
685 MMG5_Edge,"non bdy edges arrray",return 0);
686 }
687 else {
688 MMG5_ADD_MEM(mesh,((*nb_edges)+1)*sizeof(MMG5_Edge),"non boundary edges",
689 printf(" Exit program.\n");
690 return 0);
691 MMG5_SAFE_RECALLOC(mesh->edge,0,((*nb_edges)+1),
692 MMG5_Edge,"non bdy edges arrray",return 0);
693 }
694
695 j = mesh->namax+1;
696 for ( k=1; k<=mesh->nt; k++ ) {
697 pt = &mesh->tria[k];
698 if ( !MG_EOK(pt) ) continue;
699
700 adja = &mesh->adja[3*(k-1)+1];
701
702 for ( i=0; i<3; i++ ) {
703 i1 = MMG5_inxt2[i];
704 i2 = MMG5_iprv2[i];
705 iel = adja[i] / 3;
706 assert ( iel != k );
707
708 pt1 = &mesh->tria[iel];
709
710 if ( (!iel) || (pt->ref != pt1->ref) ||
711 ((pt->ref==pt1->ref) && MG_SIN(pt->tag[i])) ||
712 (mesh->info.opnbdy && pt->tag[i]) ) {
713 /* Do not treat boundary edges */
714 continue;
715 }
716 if ( k < iel ) {
717 /* Treat edge from the triangle with lowest index */
718 ped = &mesh->edge[j++];
719 assert ( ped );
720 ped->a = pt->v[i1];
721 ped->b = pt->v[i2];
722 ped->ref = pt->edg[i];
723 }
724 }
725 }
726 }
727 return 1;
728}
729
730int MMG2D_Get_nonBdyEdge(MMG5_pMesh mesh, MMG5_int* e0, MMG5_int* e1, MMG5_int* ref, MMG5_int idx) {
731 MMG5_pEdge ped;
732 size_t na_tot=0;
733 char *ptr_c = (char*)mesh->edge;
734
735 if ( !mesh->edge ) {
736 fprintf(stderr,"\n ## Error: %s: edge array is not allocated.\n"
737 " Please, call the MMG2D_Get_numberOfNonBdyEdges function"
738 " before the %s one.\n",
739 __func__,__func__);
740 return 0;
741 }
742
743 ptr_c = ptr_c-sizeof(size_t);
744 na_tot = *((size_t*)ptr_c);
745
746 if ( mesh->namax==(MMG5_int)na_tot ) {
747 fprintf(stderr,"\n ## Error: %s: no internal edge.\n"
748 " Please, call the MMG2D_Get_numberOfNonBdyEdges function"
749 " before the %s one and check that the number of internal"
750 " edges is non null.\n",
751 __func__,__func__);
752 return 0;
753 }
754
755 if ( mesh->namax+idx > (MMG5_int)na_tot ) {
756 fprintf(stderr,"\n ## Error: %s: Can't get the internal edge of index %" MMG5_PRId "."
757 " Index must be between 1 and %"MMG5_PRId".\n",
758 __func__,idx,(MMG5_int)na_tot-mesh->namax);
759 return 0;
760 }
761
762 ped = &mesh->edge[mesh->namax+idx];
763
764 *e0 = ped->a;
765 *e1 = ped->b;
766
767 if ( ref != NULL ) {
768 *ref = mesh->edge[mesh->namax+idx].ref;
769 }
770
771 return 1;
772}
773
774int MMG2D_Get_adjaTri(MMG5_pMesh mesh, MMG5_int kel, MMG5_int listri[3]) {
775
776 if ( ! mesh->adja ) {
777 if (! MMG2D_hashTria(mesh))
778 return 0;
779 }
780
781 listri[0] = mesh->adja[3*(kel-1)+1]/3;
782 listri[1] = mesh->adja[3*(kel-1)+2]/3;
783 listri[2] = mesh->adja[3*(kel-1)+3]/3;
784
785 return 1;
786}
787
788MMG5_int MMG2D_Get_adjaVertices(MMG5_pMesh mesh, MMG5_int ip, MMG5_int lispoi[MMG2D_LMAX])
789{
790 MMG5_int start;
791
792 if ( !mesh->tria ) return 0;
793
794 start=MMG2D_findTria(mesh,ip);
795 if ( !start ) return 0;
796
797 return MMG2D_Get_adjaVerticesFast(mesh,ip,start,lispoi);
798}
799
800MMG5_int MMG2D_Get_adjaVerticesFast(MMG5_pMesh mesh, MMG5_int ip,MMG5_int start, MMG5_int lispoi[MMG2D_LMAX])
801{
802 MMG5_pTria pt;
803 int iploc,i,i1,i2;
804 MMG5_int prevk,k,*adja,nbpoi;
805
806 pt = &mesh->tria[start];
807
808 for ( iploc=0; iploc<3; ++iploc ) {
809 if ( pt->v[iploc] == ip ) break;
810 }
811
812 assert(iploc!=3);
813
814 k = start;
815 i = iploc;
816 nbpoi = 0;
817 do {
818 if ( nbpoi == MMG2D_LMAX ) {
819 fprintf(stderr,"\n ## Warning: %s: unable to compute adjacent"
820 " vertices of the vertex %" MMG5_PRId ":\nthe ball of point contain too many"
821 " elements.\n",__func__,ip);
822 return 0;
823 }
824 i1 = MMG5_inxt2[i];
825 lispoi[nbpoi] = mesh->tria[k].v[i1];
826 ++nbpoi;
827
828 adja = &mesh->adja[3*(k-1)+1];
829 prevk = k;
830 k = adja[i1] / 3;
831 i = adja[i1] % 3;
832 i = MMG5_inxt2[i];
833 }
834 while ( k && k != start );
835
836 if ( k > 0 ) return nbpoi;
837
838 /* store the last point of the boundary triangle */
839 if ( nbpoi == MMG2D_LMAX ) {
840 fprintf(stderr,"\n ## Warning: %s: unable to compute adjacent vertices of the"
841 " vertex %" MMG5_PRId ":\nthe ball of point contain too many elements.\n",
842 __func__,ip);
843 return 0;
844 }
845 i1 = MMG5_inxt2[i1];
846 lispoi[nbpoi] = mesh->tria[prevk].v[i1];
847 ++nbpoi;
848
849 /* check if boundary hit */
850 k = start;
851 i = iploc;
852 do {
853 adja = &mesh->adja[3*(k-1)+1];
854 i2 = MMG5_iprv2[i];
855 k = adja[i2] / 3;
856 if ( k == 0 ) break;
857
858 if ( nbpoi == MMG2D_LMAX ) {
859 fprintf(stderr,"\n ## Warning: %s: unable to compute adjacent vertices of the"
860 " vertex %" MMG5_PRId ":\nthe ball of point contain too many elements.\n",
861 __func__,ip);
862 return 0;
863 }
864 i = adja[i2] % 3;
865 lispoi[nbpoi] = mesh->tria[k].v[i];
866 ++nbpoi;
867
868 i = MMG5_iprv2[i];
869 }
870 while ( k );
871
872 return nbpoi;
873}
874
875int MMG2D_Get_triFromEdge(MMG5_pMesh mesh, MMG5_int ked, MMG5_int *ktri, int *ied)
876{
877 MMG5_int val;
878
879 val = mesh->edge[ked].base;
880
881 if ( !val ) {
882 fprintf(stderr," ## Error: %s: the main fonction of the Mmg library must be"
883 " called before this function.\n",__func__);
884 return 0;
885 }
886
887 *ktri = val/3;
888
889 *ied = val%3;
890
891 return 1;
892}
893
894int MMG2D_Get_trisFromEdge(MMG5_pMesh mesh, MMG5_int ked, MMG5_int ktri[2], int ied[2])
895{
896 int ier;
897 MMG5_int itri;
898#ifndef NDEBUG
899 MMG5_int ia0,ib0,ia1,ib1;
900#endif
901
902 ktri[0] = ktri[1] = 0;
903 ied[0] = ied[1] = 0;
904
905 ier = MMG2D_Get_triFromEdge(mesh, ked, ktri, ied);
906
907 if ( !ier ) return 0;
908
909 if ( !mesh->adja ) {
910 if (!MMG2D_hashTria(mesh) )
911 return 0;
912 }
913
914 itri = mesh->adja[3*(*ktri-1) + *ied + 1 ];
915
916 if ( itri ) {
917 ktri[1] = itri/3;
918 ied[1] = itri%3;
919
920#ifndef NDEBUG
921 ia0 = mesh->tria[ktri[0]].v[MMG5_inxt2[ied[0]]];
922 ib0 = mesh->tria[ktri[0]].v[MMG5_iprv2[ied[0]]];
923
924 ia1 = mesh->tria[ktri[1]].v[MMG5_inxt2[ied[1]]];
925 ib1 = mesh->tria[ktri[1]].v[MMG5_iprv2[ied[1]]];
926
927 assert ( ( (ia0 == ia1) && (ib0 == ib1) ) ||
928 ( (ia0 == ib1) && (ib0 == ia1) ) );
929#endif
930 }
931
932 return 1;
933}
934
936 double hsiz;
937
938 /* Set solution size */
939 if ( mesh->info.ani ) {
940 met->size = 3;
941 }
942 else {
943 met->size = 1;
944 }
945
946 /* Memory alloc */
947 if ( !MMG2D_Set_solSize(mesh,met,MMG5_Vertex,mesh->np,met->size) )
948 return 0;
949
950 if ( !MMG5_Compute_constantSize(mesh,met,&hsiz) )
951 return 0;
952
953 mesh->info.hsiz = hsiz;
954
955 MMG5_Set_constantSize(mesh,met,hsiz);
956
957 return 1;
958}
959
960int MMG2D_Compute_eigenv(double m[3],double lambda[2],double vp[2][2]) {
961
962 return MMG5_eigensym(m,lambda,vp);
963
964}
965
966
968 MMG5_int k;
969
970 for ( k=1; k<=mesh->np; ++k ) {
971 mesh->point[k].tag = 0;
972 }
973
974}
975
977
978 if ( mesh->adja )
980
981 if ( mesh->tria )
983
984 mesh->nt = 0;
985 mesh->nti = 0;
986 mesh->nenil = 0;
987
988 return;
989}
990
992
993 if ( mesh->edge )
995
996 if ( mesh->xpoint )
998
999 mesh->na = 0;
1000 mesh->nai = 0;
1001 mesh->nanil = 0;
1002
1003 mesh->xp = 0;
1004
1005 return;
1006}
1007
1009
1010 /* sol */
1011 if ( !sol ) return;
1012
1013 if ( sol->m )
1014 MMG5_DEL_MEM(mesh,sol->m);
1015
1016 if ( sol->namein ) {
1018 }
1019
1020 if ( sol->nameout ) {
1022 }
1023
1024 memset ( sol, 0x0, sizeof(MMG5_Sol) );
1025
1026 /* Reset state to a scalar status */
1027 sol->dim = 2;
1028 sol->ver = 2;
1029 sol->size = 1;
1030 sol->type = 1;
1031
1032 return;
1033}
int MMG5_Compute_constantSize(MMG5_pMesh mesh, MMG5_pSol met, double *hsiz)
void MMG5_Set_constantSize(MMG5_pMesh mesh, MMG5_pSol met, double hsiz)
char * MMG5_Get_filenameExt(char *filename)
int MMG2D_Set_lsBaseReference(MMG5_pMesh mesh, MMG5_pSol sol, MMG5_int br)
int MMG2D_Set_iparameter(MMG5_pMesh mesh, MMG5_pSol sol, int iparam, MMG5_int val)
int MMG2D_Set_solSize(MMG5_pMesh mesh, MMG5_pSol sol, int typEntity, MMG5_int np, int typSol)
int MMG2D_Set_inputSolName(MMG5_pMesh mesh, MMG5_pSol sol, const char *solin)
int MMG2D_Set_inputMeshName(MMG5_pMesh mesh, const char *meshin)
int MMG2D_Set_localParameter(MMG5_pMesh mesh, MMG5_pSol sol, int typ, MMG5_int ref, double hmin, double hmax, double hausd)
int MMG2D_Set_dparameter(MMG5_pMesh mesh, MMG5_pSol sol, int dparam, double val)
int MMG2D_Set_multiMat(MMG5_pMesh mesh, MMG5_pSol sol, MMG5_int ref, int split, MMG5_int rin, MMG5_int rout)
int MMG2D_Set_outputMeshName(MMG5_pMesh mesh, const char *meshout)
int MMG2D_Set_outputSolName(MMG5_pMesh mesh, MMG5_pSol sol, const char *solout)
int ier
tmp[*strlen0]
MMG5_pMesh MMG5_pSol * sol
if(!ier) exit(EXIT_FAILURE)
MMG5_pMesh * mesh
int MMG5_gradsizreq_ani(MMG5_pMesh mesh, MMG5_pSol met)
Definition: anisosiz.c:2322
int MMG5_compute_meanMetricAtMarkedPoints_ani(MMG5_pMesh mesh, MMG5_pSol met)
Definition: anisosiz.c:2205
int MMG2D_defsiz_ani(MMG5_pMesh mesh, MMG5_pSol met)
Definition: anisosiz_2d.c:363
int MMG5_eigensym(double m[3], double lambda[2], double vp[2][2])
Definition: eigenv.c:973
int MMG2D_hashTria(MMG5_pMesh mesh)
Definition: hash_2d.c:35
int MMG2D_intmet_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k, int8_t i, MMG5_int ip, double s)
Definition: intmet_2d.c:38
int MMG2D_intmet_ani(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int k, int8_t i, MMG5_int ip, double s)
Definition: intmet_2d.c:209
int MMG5_gradsiz_iso(MMG5_pMesh mesh, MMG5_pSol met)
Definition: isosiz.c:278
int MMG5_compute_meanMetricAtMarkedPoints_iso(MMG5_pMesh mesh, MMG5_pSol met)
Definition: isosiz.c:167
int MMG5_gradsizreq_iso(MMG5_pMesh mesh, MMG5_pSol met)
Definition: isosiz.c:372
int MMG2D_defsiz_iso(MMG5_pMesh mesh, MMG5_pSol met)
Definition: isosiz_2d.c:133
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
API headers for the mmg2d library.
@ MMG2D_DPARAM_hgradreq
Definition: libmmg2d.h:87
@ MMG2D_IPARAM_numsubdomain
Definition: libmmg2d.h:75
@ MMG2D_IPARAM_iso
Definition: libmmg2d.h:63
@ MMG2D_IPARAM_optim
Definition: libmmg2d.h:68
@ MMG2D_IPARAM_numberOfLocalParam
Definition: libmmg2d.h:76
@ MMG2D_IPARAM_nosurf
Definition: libmmg2d.h:72
@ MMG2D_DPARAM_hgrad
Definition: libmmg2d.h:86
@ MMG2D_DPARAM_hmin
Definition: libmmg2d.h:82
@ MMG2D_IPARAM_mem
Definition: libmmg2d.h:60
@ MMG2D_IPARAM_nofem
Definition: libmmg2d.h:90
@ MMG2D_IPARAM_nosizreq
Definition: libmmg2d.h:80
@ MMG2D_IPARAM_isoref
Definition: libmmg2d.h:91
@ MMG2D_DPARAM_rmc
Definition: libmmg2d.h:89
@ MMG2D_DPARAM_hausd
Definition: libmmg2d.h:85
@ MMG2D_IPARAM_angle
Definition: libmmg2d.h:62
@ MMG2D_DPARAM_hmax
Definition: libmmg2d.h:83
@ MMG2D_IPARAM_isosurf
Definition: libmmg2d.h:64
@ MMG2D_DPARAM_ls
Definition: libmmg2d.h:88
@ MMG2D_IPARAM_noinsert
Definition: libmmg2d.h:69
@ MMG2D_IPARAM_nreg
Definition: libmmg2d.h:73
@ MMG2D_IPARAM_noswap
Definition: libmmg2d.h:70
@ MMG2D_IPARAM_xreg
Definition: libmmg2d.h:74
@ MMG2D_IPARAM_nomove
Definition: libmmg2d.h:71
@ MMG2D_IPARAM_lag
Definition: libmmg2d.h:66
@ MMG2D_IPARAM_opnbdy
Definition: libmmg2d.h:65
@ MMG2D_IPARAM_verbose
Definition: libmmg2d.h:59
@ MMG2D_IPARAM_3dMedit
Definition: libmmg2d.h:67
@ MMG2D_IPARAM_numberOfLSBaseReferences
Definition: libmmg2d.h:77
@ MMG2D_IPARAM_numberOfMat
Definition: libmmg2d.h:78
@ MMG2D_DPARAM_angleDetection
Definition: libmmg2d.h:81
@ MMG2D_DPARAM_hsiz
Definition: libmmg2d.h:84
@ MMG2D_IPARAM_debug
Definition: libmmg2d.h:61
LIBMMG2D_EXPORT int(* MMG2D_doSol)(MMG5_pMesh mesh, MMG5_pSol met)
Definition: mmg2dexterns.c:9
#define MMG2D_LMAX
Definition: libmmg2d.h:47
MMG5_int MMG2D_findTria(MMG5_pMesh, MMG5_int)
Definition: locate_2d.c:221
int lissmet_ani(MMG5_pMesh mesh, MMG5_pSol sol)
Definition: lissmet_2d.c:47
double MMG2D_caltri_ani(MMG5_pMesh mesh, MMG5_pSol sol, MMG5_pTria)
Definition: quality_2d.c:121
int MMG2D_doSol_iso(MMG5_pMesh mesh, MMG5_pSol sol)
Definition: solmap_2d.c:97
int MMG2D_doSol_ani(MMG5_pMesh mesh, MMG5_pSol sol)
Definition: solmap_2d.c:175
double MMG2D_caltri_iso(MMG5_pMesh mesh, MMG5_pSol sol, MMG5_pTria)
Definition: quality_2d.c:107
int MMG2D_defaultValues(MMG5_pMesh mesh)
int MMG2D_usage(char *name)
int MMG2D_Get_trisFromEdge(MMG5_pMesh mesh, MMG5_int ked, MMG5_int ktri[2], int ied[2])
int MMG2D_freeLocalPar(MMG5_pMesh mesh)
int MMG2D_Get_numberOfNonBdyEdges(MMG5_pMesh mesh, MMG5_int *nb_edges)
int MMG2D_Compute_eigenv(double m[3], double lambda[2], double vp[2][2])
void MMG2D_setfunc(MMG5_pMesh mesh, MMG5_pSol met)
void MMG2D_Reset_verticestags(MMG5_pMesh mesh)
MMG5_int MMG2D_Get_adjaVertices(MMG5_pMesh mesh, MMG5_int ip, MMG5_int lispoi[MMG2D_LMAX])
Return adjacent elements of a triangle.
int MMG2D_Get_adjaTri(MMG5_pMesh mesh, MMG5_int kel, MMG5_int listri[3])
Return adjacent elements of a triangle.
MMG5_int MMG2D_Get_adjaVerticesFast(MMG5_pMesh mesh, MMG5_int ip, MMG5_int start, MMG5_int lispoi[MMG2D_LMAX])
Return adjacent elements of a triangle.
void MMG2D_Free_edges(MMG5_pMesh mesh)
int MMG2D_Get_nonBdyEdge(MMG5_pMesh mesh, MMG5_int *e0, MMG5_int *e1, MMG5_int *ref, MMG5_int idx)
int MMG2D_parsop(MMG5_pMesh mesh, MMG5_pSol met)
int MMG2D_parsar(int argc, char *argv[], MMG5_pMesh mesh, MMG5_pSol met, MMG5_pSol sol)
void MMG2D_Free_triangles(MMG5_pMesh mesh)
void MMG2D_Free_solutions(MMG5_pMesh mesh, MMG5_pSol sol)
int MMG2D_Get_triFromEdge(MMG5_pMesh mesh, MMG5_int ked, MMG5_int *ktri, int *ied)
int MMG2D_Set_constantSize(MMG5_pMesh mesh, MMG5_pSol met)
#define MMG5_MMAT_Split
Definition: libmmgtypes.h:205
@ MMG5_Tensor
Definition: libmmgtypes.h:215
#define MMG5_MMAT_NoSplit
Definition: libmmgtypes.h:197
@ MMG5_Vertex
Definition: libmmgtypes.h:224
@ MMG5_Edg
Definition: libmmgtypes.h:225
@ MMG5_Triangle
Definition: libmmgtypes.h:226
void MMG5_advancedUsage(void)
Definition: libtools.c:302
void MMG5_mmgUsage(char *prog)
Definition: libtools.c:210
void MMG5_paramUsage1(void)
Definition: libtools.c:239
void MMG5_2d3dUsage(void)
Definition: libtools.c:291
void MMG5_mmgDefaultValues(MMG5_pMesh mesh)
Definition: libtools.c:70
void MMG5_lagUsage(void)
Definition: libtools.c:275
void MMG5_paramUsage2(void)
Definition: libtools.c:258
#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 MMG5_LPARMAX
#define MMG5_FILESTR_LGTH
#define MMG_FSCANF(stream, format,...)
#define MMG5_DEL_MEM(mesh, ptr)
#define MMG5_SAFE_RECALLOC(ptr, prevSize, newSize, type, message, law)
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
MMG5_int a
Definition: libmmgtypes.h:306
int8_t iso
Definition: libmmgtypes.h:534
double hsiz
Definition: libmmgtypes.h:518
int8_t isosurf
Definition: libmmgtypes.h:535
uint8_t ani
Definition: libmmgtypes.h:546
int8_t lag
Definition: libmmgtypes.h:540
MMG5_pPar par
Definition: libmmgtypes.h:517
MMG mesh structure.
Definition: libmmgtypes.h:605
MMG5_Info info
Definition: libmmgtypes.h:651
MMG5_pPoint point
Definition: libmmgtypes.h:641
char * nameout
Definition: libmmgtypes.h:653
MMG5_int mark
Definition: libmmgtypes.h:618
MMG5_int * adja
Definition: libmmgtypes.h:624
MMG5_pxPoint xpoint
Definition: libmmgtypes.h:642
MMG5_int nenil
Definition: libmmgtypes.h:622
MMG5_int xp
Definition: libmmgtypes.h:620
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 nanil
Definition: libmmgtypes.h:623
MMG5_int nti
Definition: libmmgtypes.h:612
MMG5_int nai
Definition: libmmgtypes.h:612
MMG5_int na
Definition: libmmgtypes.h:612
char * namein
Definition: libmmgtypes.h:652
int16_t tag
Definition: libmmgtypes.h:284
char * nameout
Definition: libmmgtypes.h:674
char * namein
Definition: libmmgtypes.h:673
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