Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
mmg2d.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
28
32static void MMG5_endcod(void) {
33 char stim[32];
34
35 chrono(OFF,&MMG5_ctim[0]);
36 printim(MMG5_ctim[0].gdif,stim);
37 fprintf(stdout,"\n ELAPSED TIME %s\n",stim);
38}
39
50static inline
52 int npar,ier;
53 MMG5_int k;
54
56 (*bdyRefs) = NULL;
57
58 k = mesh->na? mesh->edge[1].ref : 0;
59
60 /* Try to alloc the first node */
61 ier = MMG5_Add_inode( mesh, bdyRefs, k );
62 if ( ier < 0 ) {
63 fprintf(stderr,"\n ## Error: %s: unable to allocate the first boundary"
64 " reference node.\n",__func__);
65 return 0;
66 }
67 else {
68 assert(ier);
69 npar = 1;
70 }
71
72 for ( k=1; k<=mesh->na; ++k ) {
73 ier = MMG5_Add_inode( mesh, bdyRefs, mesh->edge[k].ref );
74
75 if ( ier < 0 ) {
76 fprintf(stderr,"\n ## Warning: %s: unable to list the edge references.\n"
77 " Uncomplete parameters file.\n",__func__);
78 break;
79 }
80 else if ( ier ) ++npar;
81 }
82
83 return npar;
84}
85
95static inline
97 FILE *out ) {
98 MMG5_iNode *cur;
99
100 cur = bdryRefs;
101 while( cur ) {
102 fprintf(out,"%"MMG5_PRId" Edge %e %e %e \n",cur->val,
104 cur = cur->nxt;
105 }
106
107 MMG5_Free_ilinkedList(mesh,bdryRefs);
108
109 return 1;
110}
111
120static inline
122 MMG5_iNode *edgRefs,*triRefs;
123 int nparEdg,nparTri;
124 char *ptr,data[MMG5_FILESTR_LGTH];
125 FILE *out;
126
128 strcpy(data,mesh->namein);
129
130 ptr = MMG5_Get_filenameExt(data);
131
132 if ( ptr ) *ptr = '\0';
133 strcat(data,".mmg2d");
134
135 if ( !(out = fopen(data,"wb")) ) {
136 fprintf(stderr,"\n ** UNABLE TO OPEN %s.\n",data);
137 return 0;
138 }
139
140 fprintf(stdout,"\n %%%% %s OPENED\n",data);
141
142 nparEdg = MMG2D_countLocalParamAtEdg( mesh, &edgRefs);
143 if ( !nparEdg ) {
144 fclose(out);
145 return 0;
146 }
147
148 nparTri = MMG5_countLocalParamAtTri( mesh, &triRefs);
149 if ( !nparTri ) {
150 fclose(out);
151 return 0;
152 }
153
154 fprintf(out,"parameters\n %d\n",nparTri+nparEdg);
155
157 if (! MMG2D_writeLocalParamAtEdg(mesh,edgRefs,out) ) {
158 fclose(out);
159 return 0;
160 }
161
163 if (! MMG5_writeLocalParamAtTri(mesh,triRefs,out) ) {
164 fclose(out);
165 return 0;
166 }
167
168 fclose(out);
169 fprintf(stdout," -- WRITING COMPLETED\n");
170
171 return 1;
172}
173
188static inline
190 mytime ctim[TIMEMAX];
191 double hsiz;
192 char stim[32];
193
194 signal(SIGABRT,MMG2D_excfun);
195 signal(SIGFPE,MMG2D_excfun);
196 signal(SIGILL,MMG2D_excfun);
197 signal(SIGSEGV,MMG2D_excfun);
198 signal(SIGTERM,MMG2D_excfun);
199 signal(SIGINT,MMG2D_excfun);
200
201 tminit(ctim,TIMEMAX);
202 chrono(ON,&(ctim[0]));
203
204 if ( mesh->info.npar ) {
205 fprintf(stderr,"\n ## Error: %s: "
206 "unable to save of a local parameter file with"
207 " the default parameters values because local parameters"
208 " are provided.\n",__func__);
210 }
211
212
213 if ( mesh->info.imprim > 0 ) fprintf(stdout,"\n -- INPUT DATA\n");
214 /* load data */
215 chrono(ON,&(ctim[1]));
216
217 if ( met && met->np && (met->np != mesh->np) ) {
218 fprintf(stderr,"\n ## WARNING: WRONG SOLUTION NUMBER. IGNORED\n");
219 MMG5_DEL_MEM(mesh,met->m);
220 met->np = 0;
221 }
222
223 if ( sol && sol->np && (sol->np != mesh->np) ) {
224 fprintf(stderr,"\n ## WARNING: WRONG SOLUTION NUMBER. IGNORED\n");
226 sol->np = 0;
227 }
228
229 chrono(OFF,&(ctim[1]));
230 printim(ctim[1].gdif,stim);
231 if ( mesh->info.imprim > 0 )
232 fprintf(stdout," -- INPUT DATA COMPLETED. %s\n",stim);
233
234 /* analysis */
235 chrono(ON,&(ctim[2]));
236 MMG2D_setfunc(mesh,met);
238
239 if ( mesh->info.imprim > 0 ) {
240 fprintf(stdout,"\n -- DEFAULT PARAMETERS COMPUTATION\n");
241 }
242
243 /* scaling mesh and hmin/hmax computation*/
245
246 /* specific meshing + update hmin/hmax */
247 if ( mesh->info.optim ) {
248 if ( !MMG2D_doSol(mesh,met) ) {
249 if ( !MMG5_unscaleMesh(mesh,met,sol) )
252 }
253 }
254 if ( mesh->info.hsiz > 0. ) {
255 if ( !MMG5_Compute_constantSize(mesh,met,&hsiz) ) {
258 }
259 }
260
261 /* unscaling mesh */
263
264 /* Save the local parameters file */
265 mesh->mark = 0;
266 if ( !MMG2D_writeLocalParam(mesh) ) {
267 fprintf(stderr,"\n ## Error: %s: Unable to save the local parameters file.\n"
268 " Exit program.\n",__func__);
270 }
271
273}
274
275int main(int argc,char *argv[]) {
277 MMG5_pSol sol,met,disp,ls;
278 int ier,ierSave,fmtin,fmtout;
279 char stim[32],*ptr;
280
281 /* Select line buffering even if the output is not a terminal and force stderr
282 * and stdout to print in the same order as the events */
283 setvbuf(stdout, NULL, _IOLBF, 1024);
284 setvbuf(stderr, NULL, _IOLBF, 1024);
285
286 /* Version info */
287#ifndef MMG_COMPARABLE_OUTPUT
288 fprintf(stdout," -- MMG2D, Release %s (%s) \n",MMG_VERSION_RELEASE,MMG_RELEASE_DATE);
289 fprintf(stdout," %s\n",MMG_COPYRIGHT);
290 fprintf(stdout," %s %s\n",__DATE__,__TIME__);
291#endif
292
293 /* Print timer at exit */
294 atexit(MMG5_endcod);
295
298 chrono(ON,&MMG5_ctim[0]);
299
300 /* assign default values */
301 mesh = NULL;
302 met = NULL;
303 ls = NULL;
304 disp = NULL;
305
308 MMG5_ARG_ppLs,&ls,
309 MMG5_ARG_ppDisp,&disp,
310 MMG5_ARG_end) )
311 return MMG5_STRONGFAILURE;
312
313 /* reset default values for file names */
316 MMG5_ARG_ppLs,&ls,
317 MMG5_ARG_ppDisp,&disp,
318 MMG5_ARG_end) )
319 return MMG5_STRONGFAILURE;
320
321 /* Set default metric size */
324
325 /* Read command line */
326 if ( !MMG2D_parsar(argc,argv,mesh,met,ls) ) return MMG5_STRONGFAILURE;
327
328 /* load data */
329 if ( mesh->info.imprim >= 0 )
330 fprintf(stdout,"\n -- INPUT DATA\n");
331 chrono(ON,&MMG5_ctim[1]);
332
333 /* For each mode: pointer over the solution structure to load */
334 if ( mesh->info.lag >= 0 ) {
335 sol = disp;
336 }
337 else if ( mesh->info.iso || mesh->info.isosurf ) {
338 sol = ls;
339 }
340 else {
341 sol = met;
342 }
343
344 /* read mesh/sol files */
347
348 switch ( fmtin ) {
349 case ( MMG5_FMT_GmshASCII ): case ( MMG5_FMT_GmshBinary ):
351 break;
352
353 case ( MMG5_FMT_VtkVtp ):
355 break;
356
357 case ( MMG5_FMT_VtkVtu ):
359 break;
360
361 case ( MMG5_FMT_VtkVtk ):
363 break;
364
365 case ( MMG5_FMT_MeditASCII ): case ( MMG5_FMT_MeditBinary ):
367 if ( ier < 1 ) { break; }
368
369 /* Read displacement in lag mode */
370 if ( mesh->info.lag >= 0 ) {
371 /* In Lagrangian mode, the name of the displacement file has been parsed in ls */
372 if ( !MMG2D_Set_inputSolName(mesh,disp,ls->namein) ) {
374 }
376 }
377
378 if ( mesh->info.lag >= 0 || mesh->info.iso || mesh->info.isosurf ) {
379 /* displacement or isovalue are mandatory */
380 if ( MMG2D_loadSol(mesh,sol,sol->namein) < 1 ) {
381 /* displacement or isovalue are mandatory */
382 fprintf(stdout," ## ERROR: UNABLE TO LOAD SOLUTION.\n");
384 }
385 }
386 else {
387 /* Facultative metric */
388 if ( MMG2D_loadSol(mesh,met,met->namein) == -1 ) {
389 fprintf(stdout,"\n ## ERROR: WRONG DATA TYPE OR WRONG SOLUTION NUMBER.\n");
391 }
392 }
393 /* In iso mode: read metric if any */
394 if ( ( mesh->info.iso || mesh->info.isosurf ) && met->namein ) {
395 if ( MMG2D_loadSol(mesh,met,met->namein) < 1 ) {
396 fprintf(stdout," ## ERROR: UNABLE TO LOAD METRIC.\n");
398 }
399 }
400 break;
401 default:
402 fprintf(stderr," ** I/O AT FORMAT %s NOT IMPLEMENTED.\n",MMG5_Get_formatName(fmtin) );
404 }
405
406 if ( ier < 1) {
407 if ( ier==0 ) {
408 fprintf(stderr," ** %s NOT FOUND.\n",mesh->namein);
409 fprintf(stderr," ** UNABLE TO OPEN INPUT FILE.\n");
410 }
412 }
413
414 /* Check input data */
415 if ( mesh->info.lag >= 0 ) {
416 if ( met->namein ) {
417 fprintf(stdout," ## WARNING: MESH ADAPTATION UNAVAILABLE IN"
418 " LAGRANGIAN MODE. METRIC IGNORED.\n");
420 }
421 }
422 else if ( mesh->info.iso || mesh->info.isosurf ) {
423 if ( ls->m == NULL ) {
424 fprintf(stderr,"\n ## ERROR: NO ISOVALUE DATA.\n");
426 }
427 }
428
429 /* Read parameter file */
430 if ( !MMG2D_parsop(mesh,met) )
432
433 chrono(OFF,&MMG5_ctim[1]);
434 if ( mesh->info.imprim >= 0 ) {
435 printim(MMG5_ctim[1].gdif,stim);
436 fprintf(stdout," -- DATA READING COMPLETED. %s\n",stim);
437 }
438
439 if ( mesh->mark ) {
440 /* Save a local parameters file containing the default parameters */
441 ier = MMG2D_defaultOption(mesh,met,disp);
442 MMG2D_RETURN_AND_FREE(mesh,met,ls,disp,ier);
443 }
444 /* Lagrangian mode */
445 else if ( mesh->info.lag > -1 ) {
446 ier = MMG2D_mmg2dmov(mesh,met,disp);
447 }
448 /* Level Set mode */
449 else if ( mesh->info.iso || mesh->info.isosurf ) {
450 ier = MMG2D_mmg2dls(mesh,ls,met);
451 }
452 /* Mesh generation mode */
453 else if ( !mesh->nt ) {
454 ier = MMG2D_mmg2dmesh(mesh,met);
455 }
456 /* Remeshing mode */
457 else {
458 if ( met && ls && met->namein && ls->namein ) {
459 fprintf(stdout,"\n ## ERROR: IMPOSSIBLE TO PROVIDE BOTH A METRIC"
460 " AND A SOLUTION IN ADAPTATION MODE.\n");
462 }
463
464 ier = MMG2D_mmg2dlib(mesh,met);
465 }
466
467 if ( ier != MMG5_STRONGFAILURE ) {
468 chrono(ON,&MMG5_ctim[1]);
469 if ( mesh->info.imprim > 0 )
470 fprintf(stdout,"\n -- WRITING DATA FILE %s\n",mesh->nameout);
471
473 fmtout = MMG5_Get_format(ptr,fmtin);
474
475 switch ( fmtout ) {
476 case ( MMG5_FMT_GmshASCII ): case ( MMG5_FMT_GmshBinary ):
477 ierSave = MMG2D_saveMshMesh(mesh,met,mesh->nameout);
478 break;
479 case ( MMG5_FMT_VtkVtp ):
480 ierSave = MMG2D_saveVtpMesh(mesh,met,mesh->nameout);
481 break;
482 case ( MMG5_FMT_VtkVtu ):
483 ierSave = MMG2D_saveVtuMesh(mesh,met,mesh->nameout);
484 break;
485 case ( MMG5_FMT_VtkVtk ):
486 ierSave = MMG2D_saveVtkMesh(mesh,met,mesh->nameout);
487 break;
488 case ( MMG5_FMT_Tetgen ):
490 /* This format dont allow to save a solution: use a .sol file */
491 if ( !ierSave ) {
493 }
494 if ( met && met->np ) {
495 ierSave = MMG2D_saveSol(mesh,met,mesh->nameout);
496 }
497 break;
498 default:
499 ierSave = MMG2D_saveMesh(mesh,mesh->nameout);
500 if ( !ierSave ) {
502 }
503 if ( met && met->np ) {
504 ierSave = MMG2D_saveSol(mesh,met,mesh->nameout);
505 }
506 break;
507 }
508
509 if ( !ierSave )
511
512 chrono(OFF,&MMG5_ctim[1]);
513 if ( mesh->info.imprim > 0 ) fprintf(stdout," -- WRITING COMPLETED\n");
514 }
515
516 /* free mem */
517 MMG2D_RETURN_AND_FREE(mesh,met,ls,disp,ier);
518}
int MMG5_Compute_constantSize(MMG5_pMesh mesh, MMG5_pSol met, double *hsiz)
const char * MMG5_Get_formatName(enum MMG5_Format fmt)
int MMG5_Get_format(char *ptr, int fmt)
char * MMG5_Get_filenameExt(char *filename)
int MMG2D_Init_mesh(const int starter,...)
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_Free_names(const int starter,...)
int ier
MMG5_pMesh MMG5_pSol * sol
MMG5_pMesh * mesh
program main
Example for using mmglib (basic use)
Definition: main.F90:6
int MMG5_Add_inode(MMG5_pMesh mesh, MMG5_iNode **liLi, int val)
Definition: apptools.c:68
int MMG5_countLocalParamAtTri(MMG5_pMesh mesh, MMG5_iNode **bdryRefs)
Definition: apptools.c:142
void MMG5_Free_ilinkedList(MMG5_pMesh mesh, MMG5_iNode *liLi)
Definition: apptools.c:120
int MMG5_writeLocalParamAtTri(MMG5_pMesh mesh, MMG5_iNode *bdryRefs, FILE *out)
Definition: apptools.c:186
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_saveTetgenMesh(MMG5_pMesh mesh, const char *filename)
Definition: inout_2d.c:2209
int MMG2D_saveMesh(MMG5_pMesh mesh, const char *filename)
Definition: inout_2d.c:1096
int MMG2D_saveMshMesh(MMG5_pMesh mesh, MMG5_pSol sol, const char *filename)
Definition: inout_2d.c:1531
int MMG2D_saveSol(MMG5_pMesh mesh, MMG5_pSol sol, const char *filename)
Definition: inout_2d.c:1612
int MMG2D_loadMesh(MMG5_pMesh mesh, const char *filename)
Definition: inout_2d.c:28
int MMG2D_loadSol(MMG5_pMesh mesh, MMG5_pSol sol, const char *filename)
Definition: inout_2d.c:900
int MMG2D_loadMshMesh(MMG5_pMesh mesh, MMG5_pSol sol, const char *filename)
Definition: inout_2d.c:701
int MMG2D_loadVtkMesh(MMG5_pMesh mesh, MMG5_pSol sol, const char *filename)
int MMG2D_saveVtkMesh(MMG5_pMesh mesh, MMG5_pSol sol, const char *filename)
int MMG2D_saveVtuMesh(MMG5_pMesh mesh, MMG5_pSol sol, const char *filename)
int MMG2D_loadVtuMesh(MMG5_pMesh mesh, MMG5_pSol sol, const char *filename)
int MMG2D_saveVtpMesh(MMG5_pMesh mesh, MMG5_pSol sol, const char *filename)
int MMG2D_loadVtpMesh(MMG5_pMesh mesh, MMG5_pSol sol, const char *filename)
Definition: inoutcpp_2d.cpp:83
int MMG2D_mmg2dlib(MMG5_pMesh mesh, MMG5_pSol met)
Definition: libmmg2d.c:63
int MMG2D_mmg2dls(MMG5_pMesh mesh, MMG5_pSol sol, MMG5_pSol umet)
Definition: libmmg2d.c:526
int MMG2D_mmg2dmesh(MMG5_pMesh mesh, MMG5_pSol met)
Definition: libmmg2d.c:307
void MMG2D_Set_commonFunc(void)
Definition: libmmg2d.c:52
int MMG2D_mmg2dmov(MMG5_pMesh mesh, MMG5_pSol met, MMG5_pSol disp)
Definition: libmmg2d.c:822
API headers for the mmg2d library.
LIBMMG2D_EXPORT int MMG2D_parsop(MMG5_pMesh mesh, MMG5_pSol met)
LIBMMG2D_EXPORT int MMG2D_parsar(int argc, char *argv[], MMG5_pMesh mesh, MMG5_pSol met, MMG5_pSol sol)
LIBMMG2D_EXPORT int(* MMG2D_doSol)(MMG5_pMesh mesh, MMG5_pSol met)
Definition: mmg2dexterns.c:9
LIBMMG2D_EXPORT void MMG2D_setfunc(MMG5_pMesh mesh, MMG5_pSol met)
static void MMG2D_excfun(int sigid)
#define MMG2D_RETURN_AND_FREE(mesh, met, ls, disp, val)
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_ARG_ppMesh
Definition: libmmgtypes.h:96
#define MMG5_ARG_end
Definition: libmmgtypes.h:173
#define MMG5_ARG_ppLs
Definition: libmmgtypes.h:106
#define MMG5_STRONGFAILURE
Definition: libmmgtypes.h:59
#define MMG5_LOWFAILURE
Definition: libmmgtypes.h:51
#define MMG5_SUCCESS
Definition: libmmgtypes.h:43
@ MMG5_Scalar
Definition: libmmgtypes.h:213
@ MMG5_FMT_MeditBinary
Definition: libmmgtypes.h:236
@ MMG5_FMT_Tetgen
Definition: libmmgtypes.h:244
@ MMG5_FMT_VtkVtk
Definition: libmmgtypes.h:243
@ MMG5_FMT_GmshBinary
Definition: libmmgtypes.h:238
@ MMG5_FMT_GmshASCII
Definition: libmmgtypes.h:237
@ MMG5_FMT_MeditASCII
Definition: libmmgtypes.h:235
@ MMG5_FMT_VtkVtp
Definition: libmmgtypes.h:242
@ MMG5_FMT_VtkVtu
Definition: libmmgtypes.h:241
#define MMG5_ARG_ppDisp
Definition: libmmgtypes.h:126
#define MMG5_ARG_start
Definition: libmmgtypes.h:87
@ MMG5_Vertex
Definition: libmmgtypes.h:224
#define MMG5_ARG_ppMet
Definition: libmmgtypes.h:116
static int MMG2D_writeLocalParamAtEdg(MMG5_pMesh mesh, MMG5_iNode *bdryRefs, FILE *out)
Definition: mmg2d.c:96
static int MMG2D_countLocalParamAtEdg(MMG5_pMesh mesh, MMG5_iNode **bdyRefs)
Definition: mmg2d.c:51
static int MMG2D_defaultOption(MMG5_pMesh mesh, MMG5_pSol met, MMG5_pSol sol)
Definition: mmg2d.c:189
mytime MMG5_ctim[TIMEMAX]
Definition: mmg2d.c:27
static void MMG5_endcod(void)
Definition: mmg2d.c:32
static int MMG2D_writeLocalParam(MMG5_pMesh mesh)
Definition: mmg2d.c:121
#define _LIBMMG5_RETURN(mesh, sol, met, val)
#define MMG5_FILESTR_LGTH
#define MMG5_DEL_MEM(mesh, ptr)
MMG5_int ref
Definition: libmmgtypes.h:307
int8_t iso
Definition: libmmgtypes.h:534
double hsiz
Definition: libmmgtypes.h:518
int8_t isosurf
Definition: libmmgtypes.h:535
double hmin
Definition: libmmgtypes.h:518
double hmax
Definition: libmmgtypes.h:518
int8_t lag
Definition: libmmgtypes.h:540
uint8_t optim
Definition: libmmgtypes.h:546
double hausd
Definition: libmmgtypes.h:518
MMG mesh structure.
Definition: libmmgtypes.h:605
MMG5_Info info
Definition: libmmgtypes.h:651
char * nameout
Definition: libmmgtypes.h:653
MMG5_int mark
Definition: libmmgtypes.h:618
MMG5_int nt
Definition: libmmgtypes.h:612
MMG5_int np
Definition: libmmgtypes.h:612
MMG5_pEdge edge
Definition: libmmgtypes.h:649
MMG5_int na
Definition: libmmgtypes.h:612
char * namein
Definition: libmmgtypes.h:652
char * namein
Definition: libmmgtypes.h:673
double * m
Definition: libmmgtypes.h:671
MMG5_int np
Definition: libmmgtypes.h:665
Cell for linked list of integer value.
Chrono object.