Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
inout.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
36#include "mmgcommon_private.h"
37
42int MMG5_swapbin(int sbin)
43{
44 int inv;
45 char *p_in = (char *) &sbin;
46 char *p = (char *)&inv;
47
48
49 p[0] = p_in[3];
50 p[1] = p_in[2];
51 p[2] = p_in[1];
52 p[3] = p_in[0];
53
54 return inv;
55}
56
61MMG5_int MMG5_swapbin_int(MMG5_int sbin)
62{
63 MMG5_int out;
64 char *p_in = (char *) &sbin;
65 char *p_out = (char *) &out;
66 int8_t i;
67
68 for(i=0;i<8;i++)
69 {
70 p_out[i] = p_in[7-i];
71 }
72
73 return out;
74}
75
80float MMG5_swapf(float sbin)
81{
82 float out;
83 char *p_in = (char *) &sbin;
84 char *p_out = (char *) &out;
85 p_out[0] = p_in[3];
86 p_out[1] = p_in[2];
87 p_out[2] = p_in[1];
88 p_out[3] = p_in[0];
89
90 return out;
91}
92
97double MMG5_swapd(double sbin)
98{
99 double out;
100 char *p_in = (char *) &sbin;
101 char *p_out = (char *) &out;
102 int8_t i;
103
104 for(i=0;i<8;i++)
105 {
106 p_out[i] = p_in[7-i];
107 }
108
109 return out;
110}
111
126static
127int MMG5_countBinaryElts(FILE **inm, const int nelts,const int iswp,
128 int *np, int *na, int* nt,int *nq, int *ne, int *npr)
129{
130 int typ,tagNum,i,l;
131 int k,num,idx;
132 static char mmgWarn = 0;
133
134 k = 0;
135
136 while ( k<nelts ) {
137 MMG_FREAD(&typ,MMG5_SW,1,(*inm));
138 if(iswp) typ = MMG5_swapbin(typ);
139
140 switch (typ) {
141 case 1:
142 /* Edge */
143 MMG_FREAD(&num,MMG5_SW,1,(*inm));
144 MMG_FREAD(&tagNum,MMG5_SW,1,(*inm));
145 if(iswp) {
146 num = MMG5_swapbin(num);
147 tagNum = MMG5_swapbin(tagNum);
148 }
149 for ( idx=0; idx<num; ++idx ) {
150 MMG_FREAD(&i,MMG5_SW,1,(*inm));
151 for ( l=0; l<tagNum; ++l ) MMG_FREAD(&i,MMG5_SW,1,(*inm));
152 MMG_FREAD(&i,MMG5_SW,1,(*inm)); // edge->a
153 MMG_FREAD(&i,MMG5_SW,1,(*inm)); // edge->b
154 }
155 (*na) += num;
156 k += num;
157 break;
158 case 2:
159 /* Tria */
160 MMG_FREAD(&num,MMG5_SW,1,(*inm));
161 MMG_FREAD(&tagNum,MMG5_SW,1,(*inm));
162 if(iswp) {
163 num = MMG5_swapbin(num);
164 tagNum = MMG5_swapbin(tagNum);
165 }
166 for ( idx=0; idx<num; ++idx ) {
167 MMG_FREAD(&i,MMG5_SW,1,(*inm));
168 for ( l=0; l<tagNum; ++l ) MMG_FREAD(&i,MMG5_SW,1,(*inm));
169 MMG_FREAD(&i,MMG5_SW,1,(*inm)); // tria->v[0]
170 MMG_FREAD(&i,MMG5_SW,1,(*inm)); // tria->v[1]
171 MMG_FREAD(&i,MMG5_SW,1,(*inm)); // tria->v[2]
172 }
173 (*nt) += num;
174 k += num;
175 break;
176 case 3:
177 /* Quad */
178 MMG_FREAD(&num,MMG5_SW,1,(*inm));
179 MMG_FREAD(&tagNum,MMG5_SW,1,(*inm));
180 if(iswp) {
181 num = MMG5_swapbin(num);
182 tagNum = MMG5_swapbin(tagNum);
183 }
184 for ( idx=0; idx<num; ++idx ) {
185 MMG_FREAD(&i,MMG5_SW,1,(*inm));
186 for ( l=0; l<tagNum; ++l ) MMG_FREAD(&i,MMG5_SW,1,(*inm));
187 MMG_FREAD(&i,MMG5_SW,1,(*inm)); // quadra->v[0]
188 MMG_FREAD(&i,MMG5_SW,1,(*inm)); // quadra->v[1]
189 MMG_FREAD(&i,MMG5_SW,1,(*inm)); // quadra->v[2]
190 MMG_FREAD(&i,MMG5_SW,1,(*inm)); // quadra->v[3]
191 }
192 (*nq) += num;
193 k += num;
194 break;
195 case 4:
196 /* Tetra */
197 MMG_FREAD(&num,MMG5_SW,1,(*inm));
198 MMG_FREAD(&tagNum,MMG5_SW,1,(*inm));
199 if(iswp) {
200 num = MMG5_swapbin(num);
201 tagNum = MMG5_swapbin(tagNum);
202 }
203 for ( idx=0; idx<num; ++idx ) {
204 MMG_FREAD(&i,MMG5_SW,1,(*inm));
205 for ( l=0; l<tagNum; ++l ) MMG_FREAD(&i,MMG5_SW,1,(*inm));
206 MMG_FREAD(&i,MMG5_SW,1,(*inm)); // tetra->v[0]
207 MMG_FREAD(&i,MMG5_SW,1,(*inm)); // tetra->v[1]
208 MMG_FREAD(&i,MMG5_SW,1,(*inm)); // tetra->v[2]
209 MMG_FREAD(&i,MMG5_SW,1,(*inm)); // tetra->v[3]
210 }
211 (*ne) += num;
212 k += num;
213 break;
214 case 6:
215 /* Prism */
216 MMG_FREAD(&num,MMG5_SW,1,(*inm));
217 MMG_FREAD(&tagNum,MMG5_SW,1,(*inm));
218 if(iswp) {
219 num = MMG5_swapbin(num);
220 tagNum = MMG5_swapbin(tagNum);
221 }
222 for ( idx=0; idx<num; ++idx ){
223 MMG_FREAD(&i,MMG5_SW,1,(*inm));
224 for ( l=0; l<tagNum; ++l ) MMG_FREAD(&i,MMG5_SW,1,(*inm));
225 MMG_FREAD(&i,MMG5_SW,1,(*inm)); // prism->v[0]
226 MMG_FREAD(&i,MMG5_SW,1,(*inm)); // prism->v[1]
227 MMG_FREAD(&i,MMG5_SW,1,(*inm)); // prism->v[2]
228 MMG_FREAD(&i,MMG5_SW,1,(*inm)); // prism->v[3]
229 MMG_FREAD(&i,MMG5_SW,1,(*inm)); // prism->v[4]
230 MMG_FREAD(&i,MMG5_SW,1,(*inm)); // prism->v[5]
231 }
232 (*npr) += num;
233 k += num;
234 break;
235 case 15:
236 /* Node */
237 MMG_FREAD(&num,MMG5_SW,1,(*inm));
238 MMG_FREAD(&tagNum,MMG5_SW,1,(*inm));
239 if(iswp) {
240 num = MMG5_swapbin(num);
241 tagNum = MMG5_swapbin(tagNum);
242 }
243 for ( idx=0; idx<num; ++idx ){
244 MMG_FREAD(&i,MMG5_SW,1,(*inm));
245 for ( l=0; l<tagNum; ++l ) MMG_FREAD(&i,MMG5_SW,1,(*inm));
246 MMG_FREAD(&i,MMG5_SW,1,(*inm)); //node idx
247 }
248 (*np) += num;
249 k += num;
250 break;
251 default:
252 if ( !mmgWarn ) {
253 fprintf(stderr,"\n ## Warning: %s: unexpected type of element (%d) for at"
254 " least 1 element (%d).\n",__func__,typ,k);
255 mmgWarn = 1;
256 }
257 }
258 }
259 return 1;
260}
261
279 FILE **inm,
280 long *posNodes, long *posElts,
281 long **posNodeData, int *bin, int *iswp,
282 MMG5_int *nelts,int *nsols) {
283 double dbuf[9];
284 float fbuf[9];
285 int ver,oneBin,i;
286 int k,nt,na,nq,ne,npr,np;
287 int typ,tagNum,posNodeDataSize,initPosNodeDataSize;
288 char *ptr,*data,chaine[MMG5_FILESTR_LGTH],verNum[5];
289
290 ver = oneBin = 0;
291 *posNodes = 0;
292 *posElts = 0;
293 *nelts = 0;
294 *nsols = 0;
295 *bin = 0;
296 *iswp = 0;
297 mesh->np = mesh->nt = mesh->ne = 0;
298 nt = na = nq = ne = npr = np = 0;
299
300 MMG5_SAFE_CALLOC(data,strlen(filename)+7,char,return -1);
301
302 /* Allocation of the posNodeData array: we assume that we have less than 20
303 * solutions in the file (for a greater number of sol, posNoteData is
304 * reallocated) */
305 initPosNodeDataSize = posNodeDataSize = 20;
306 MMG5_SAFE_CALLOC(*posNodeData,posNodeDataSize,long,return -1);
307
308 strcpy(data,filename);
309 ptr = strstr(data,".msh");
310 if ( !ptr ) {
311 /* data contains the filename without extension */
312 strcat(data,".mshb");
313 if (!(*inm = fopen(data,"rb")) ) {
314 ptr = strstr(data,".msh");
315 *ptr = '\0';
316 strcat(data,".msh");
317 if( !((*inm) = fopen(data,"rb")) ) {
318 MMG5_SAFE_FREE(data);
319 MMG5_SAFE_FREE(*posNodeData);
320 return 0;
321 }
322 }
323 }
324 else {
325 if( !((*inm) = fopen(data,"rb")) ) {
326 MMG5_SAFE_FREE(data);
327 MMG5_SAFE_FREE(*posNodeData);
328 return 0;
329 }
330 }
331
332 if ( mesh->info.imprim >= 0 )
333 fprintf(stdout," %%%% %s OPENED\n",data);
334 MMG5_SAFE_FREE(data);
335
336
337 /* Detection of the different fields of the file */
338 strcpy(chaine,"D");
339 while(fscanf((*inm),"%127s ",&chaine[0])!=EOF ) {
340 if(!strncmp(chaine,"$MeshFormat",strlen("$MeshFormat"))) {
341 MMG_FSCANF((*inm),"%4s %d %d ",verNum,bin,&ver);
342 mesh->ver = ver/4;
343 if ( strncmp(verNum,"2.2",3) ) {
344 fprintf(stderr,"\n ## Warning: %s: format version (%s) may be not supported."
345 " Please, use the format version 2.2.\n",__func__,verNum);
346 }
347 if ( *bin ) {
348 MMG_FREAD(&oneBin,MMG5_SW,1,(*inm));
349 if ( oneBin!=1 ) {
350 assert(oneBin==16777216);
351 *iswp=1;
352 oneBin = MMG5_swapbin(oneBin);
353 }
354 }
355 continue;
356 } else if(!strncmp(chaine,"$EndMeshFormat",strlen("EndMeshFormat"))) {
357 continue;
358 } else if(!strncmp(chaine,"$Nodes",strlen("$Nodes"))) {
359 MMG_FSCANF((*inm),"%" MMG5_PRId " ",&mesh->npi);
360 *posNodes = ftell((*inm));
361 if ( *bin ) {
362 /* Skip the binary nodes data */
363 if ( mesh->ver==1 ) {
364 for ( k=1; k<=mesh->npi; ++k ) {
365 MMG_FREAD(&i,MMG5_SW,1,(*inm));
366 MMG_FREAD( &fbuf[0],MMG5_SW,3,(*inm) );
367 }
368 }
369 else {
370 for ( k=1; k<=mesh->npi; ++k ) {
371 MMG_FREAD(&i,MMG5_SW,1,(*inm));
372 MMG_FREAD( &dbuf[0],MMG5_SD,3,(*inm) );
373 }
374 }
375 }
376 continue;
377 } else if(!strncmp(chaine,"$EndNodes",strlen("$EndNodes"))) {
378 continue;
379 } else if(!strncmp(chaine,"$NodeData",strlen("$NodeData"))) {
380
381 (*posNodeData)[*nsols] = ftell((*inm));
382 if ( ++(*nsols) == posNodeDataSize ) {
383 MMG5_SAFE_RECALLOC(*posNodeData,*nsols,
384 posNodeDataSize+initPosNodeDataSize,
385 long,"posNodeData",return -1);
386 posNodeDataSize += initPosNodeDataSize;
387 }
388
389 if ( *bin ) {
390 /* Skip the binary nodes data */
391 /* String tags */
392 MMG_FSCANF((*inm),"%d ",&tagNum);
393 for ( k=0; k<tagNum; ++k ) {
394 if ( 0 != fscanf((*inm),"%*[^\n]%*c") ) {
395 fputs ( "Reading error", stderr );
396 return -1;
397 }
398 }
399
400 /* Real tags */
401 MMG_FSCANF((*inm),"%d ",&tagNum);
402 for ( k=0; k<tagNum; ++k ) {
403 if ( 0 != fscanf((*inm),"%*[^\n]%*c") ) {
404 fputs ( "Reading error", stderr );
405 return -1;
406 }
407 }
408
409 /* Integer tags */
410 MMG_FSCANF((*inm),"%d ",&tagNum);
411 MMG_FSCANF((*inm),"%d ",&i); //time step
412 MMG_FSCANF((*inm),"%d ",&typ); //type of solution
413 MMG_FSCANF((*inm),"%d ",&np);
414 for ( k=3; k<tagNum; ++k ) {
415 MMG_FSCANF((*inm),"%d",&i);
416 }
417 if ( mesh->ver==1 ) {
418 for ( k=1; k<=np; ++k ) {
419 MMG_FREAD(&i,MMG5_SW,1,(*inm));
420 MMG_FREAD( &fbuf[0],MMG5_SW,typ,(*inm) );
421 }
422 }
423 else {
424 for ( k=1; k<=np; ++k ) {
425 MMG_FREAD(&i,MMG5_SW,1,(*inm));
426 MMG_FREAD( &dbuf[0],MMG5_SD,typ,(*inm) );
427 }
428 }
429 }
430 continue;
431 } else if(!strncmp(chaine,"$EndNodeData",strlen("$EndNodeData"))) {
432 continue;
433 } else if(!strncmp(chaine,"$Elements",strlen("$Elements"))) {
434 MMG_FSCANF((*inm),"%" MMG5_PRId " ",nelts);
435 *posElts = ftell((*inm));
436
437 /* Count the elements */
438 if ( !*bin ) {
439 for ( k=0; k<*nelts; ++k) {
440 MMG_FSCANF((*inm),"%d %d ",&i,&typ);
441 switch (typ) {
442 case 1:
443 /* Edge */
444 ++na;
445 break;
446 case 2:
447 /* Tria */
448 ++nt;
449 break;
450 case 3:
451 /* Quad */
452 ++nq;
453 break;
454 case 4:
455 /* Tetra */
456 ++ne;
457 break;
458 case 6:
459 /* Prism */
460 ++npr;
461 break;
462 case 15:
463 /* Node */
464 ++np;
465 break;
466 }
467 if ( 0 != fscanf((*inm),"%*[^\n]%*c") ) {
468 fputs ( "Reading error", stderr );
469 return -1;
470 }
471 }
472 }
473 else {
474 if ( !MMG5_countBinaryElts(inm,*nelts,*iswp,&np,&na,&nt,&nq,&ne,&npr) ) {
475 fclose(*inm);
476 MMG5_SAFE_FREE(*posNodeData);
477 return -1;
478 }
479 }
480 continue;
481 }
482 else if(!strncmp(chaine,"$EndElements",strlen("$EndElements"))) {
483 continue;
484 }
485 }
486
487 if ( !mesh->npi ) {
488 fprintf(stderr," ** MISSING DATA.\n");
489 fprintf(stderr," Check that your mesh contains points and elements.\n");
490 fprintf(stderr," Exit program.\n");
491 fclose(*inm);
492 MMG5_SAFE_FREE(*posNodeData);
493 return -1;
494 }
495
496 /* memory allocation */
497 mesh->np = mesh->npi;
498 mesh->nt = mesh->nti = nt;
499 mesh->ne = mesh->nei = ne;
500 mesh->na = mesh->nai = na;
501 mesh->nprism = npr;
502 mesh->nquad = nq;
503
504 if ( !mesh->np ) {
505 fprintf(stderr," ** MISSING DATA.\n");
506 fprintf(stderr," Check that your mesh contains points.\n");
507 fprintf(stderr," Exit program.\n");
508 fclose(*inm);
509 MMG5_SAFE_FREE(*posNodeData);
510 return -1;
511 }
512
513 return 1;
514}
515
526int MMG5_check_readedMesh ( MMG5_pMesh mesh, MMG5_int nref ) {
527 MMG5_pPoint ppt;
528 MMG5_pTria ptt;
529 MMG5_pQuad pq;
530 MMG5_pPrism pp;
531 MMG5_pTetra pt;
532 int i;
533 MMG5_int k,aux;
534 double area;
535
536 if ( nref ) {
537 fprintf(stdout,"\n $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ \n");
538 fprintf(stdout," WARNING : %" MMG5_PRId " entities with unexpected refs (ref< 0).",nref);
539 fprintf(stdout," We take their absolute values.\n");
540 fprintf(stdout," $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ \n\n");
541 }
542
543 /* Cross the elements, mark their vertices as used and reorient the elements
544 * with negative orientation */
545 mesh->xt = 0;
546
547 if ( mesh->dim == 2 ) {
548 for (k=1; k<=mesh->nt; k++) {
549 ptt = &mesh->tria[k];
550
551 for (i=0; i<3; i++) {
552 ppt = &mesh->point[ ptt->v[i] ];
553 ppt->tag &= ~MG_NUL;
554 }
555
556 for(i=0 ; i<3 ; i++)
557 ptt->edg[i] = 0;
558
559 area = MMG2D_quickarea(mesh->point[ptt->v[0]].c,
560 mesh->point[ptt->v[1]].c,
561 mesh->point[ptt->v[2]].c);
562 if ( area < 0.0 ) {
563 mesh->xt++; /* mesh->xt temporarily used to count reoriented tetra*/
564 aux = ptt->v[2];
565 ptt->v[2] = ptt->v[1];
566 ptt->v[1] = aux;
567 }
568 }
569 for (k=1; k<=mesh->nquad; k++) {
570 pq = &mesh->quadra[k];
571 for (i=0; i<4; i++) {
572 ppt = &mesh->point[ pq->v[i] ];
573 ppt->tag &= ~MG_NUL;
574 }
575 }
576 }
577 else {
578 if ( mesh->ne ) {
579 /* mmg3d */
580 for ( k=1; k<=mesh->ne; k++ ) {
581 pt = &mesh->tetra[k];
582 if ( !MG_EOK(pt) ) continue;
583
584 for (i=0; i<4; i++) {
585 ppt = &mesh->point[pt->v[i]];
586 ppt->tag &= ~MG_NUL;
587 }
588
589 /* Possibly switch 2 vertices number so that each tet is positively oriented */
590 if ( MMG5_orvol(mesh->point,pt->v) < 0.0 ) {
591 /* mesh->xt temporary used to count reoriented tetra*/
592 mesh->xt++;
593 aux = pt->v[2];
594 pt->v[2] = pt->v[3];
595 pt->v[3] = aux;
596 }
597 }
598 }
599 else {
600 /* mmgs */
601 for ( k=1; k<=mesh->nt; k++ ) {
602 ptt = &mesh->tria[k];
603 if ( !MG_EOK(ptt) ) continue;
604 for (i=0; i<3; i++) {
605 ppt = &mesh->point[ptt->v[i]];
606 ppt->tag &= ~MG_NUL;
607 }
608 }
609 }
610 }
611
612 if(mesh->xt) {
613 fprintf(stdout,"\n $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ \n");
614 fprintf(stdout," BAD ORIENTATION : vol < 0 -- %8" MMG5_PRId " element(s) reoriented\n",mesh->xt);
615 fprintf(stdout," $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ \n\n");
616 }
617 mesh->xt = 0;
618
619 /* Cross the prisms and mark their vertices as used */
620 for ( k=1; k<=mesh->nprism; k++ ) {
621 pp = &mesh->prism[k];
622 for (i=0; i<6; i++) {
623 ppt = &mesh->point[pp->v[i]];
624 ppt->tag &= ~MG_NUL;
625 }
626 }
627
628 /* stats */
629 if ( abs(mesh->info.imprim) > 3 ) {
630 fprintf(stdout," NUMBER OF VERTICES %8" MMG5_PRId "\n",mesh->np);
631 if ( mesh->ne )
632 fprintf(stdout," NUMBER OF TETRAHEDRA %8" MMG5_PRId "\n",mesh->ne);
633
634 if ( mesh->nprism )
635 fprintf(stdout," NUMBER OF PRISMS %8" MMG5_PRId "\n",mesh->nprism);
636 if ( mesh->nt )
637 fprintf(stdout," NUMBER OF TRIANGLES %8" MMG5_PRId "\n",mesh->nt);
638 if ( mesh->nquad )
639 fprintf(stdout," NUMBER OF QUADRILATERALS %8" MMG5_PRId "\n",mesh->nquad);
640 if ( mesh->na ) {
641 fprintf(stdout," NUMBER OF EDGES %8" MMG5_PRId "\n",mesh->na);
642 }
643 }
644 return 1;
645}
646
665 const long posNodes,const long posElts,
666 const long *posNodeData,const int bin,const int iswp,
667 const MMG5_int nelts,const int nsols) {
668 MMG5_pTetra pt;
669 MMG5_pPrism pp;
670 MMG5_pTria ptt;
671 MMG5_pQuad pq1;
672 MMG5_pEdge pa;
673 MMG5_pPoint ppt;
674 MMG5_pSol psl;
675 double dbuf[9];
676 float fbuf[9],fc;
677 int i,ier;
678 int l,nref,nbl_t,nbl_a,k,v[4],nt,na,nq,ne,npr,idx,ref,num,iadr;
679 int typ,tagNum;
680 int isol;
681 int8_t metricData;
682 char chaine[MMG5_FILESTR_LGTH],*ptr;
683 static int8_t mmgWarn=0, mmgWarn1=0;
684
686 rewind((*inm));
687 fseek((*inm),posNodes,SEEK_SET);
688
689 if ( mesh->ver < 2 ) {
690 for ( k=0; k< mesh->np; ++k)
691 {
692 if ( !bin ) {
693 MMG_FSCANF((*inm),"%d ",&idx);
694 ppt = &mesh->point[idx];
695 for (i=0 ; i<mesh->dim ; i++) {
696 MMG_FSCANF((*inm),"%f ",&fc);
697 ppt->c[i] = (double) fc;
698 }
699 }
700 else {
701 MMG_FREAD(&idx,MMG5_SW,1,(*inm));
702 if ( iswp ) idx = MMG5_swapbin(idx);
703 ppt = &mesh->point[idx];
704 for (i=0 ; i<mesh->dim ; i++) {
705 MMG_FREAD(&fc,MMG5_SW,1,(*inm));
706 if(iswp) fc=MMG5_swapf(fc);
707 ppt->c[i] = (double) fc;
708 }
709 }
710 ppt->tag = MG_NUL;
711 ppt->tmp = 0;
712 ppt->ref = 0;
713 }
714 }
715 else {
716 for ( k=0; k< mesh->np; ++k)
717 {
718 if ( !bin ) {
719 MMG_FSCANF((*inm),"%d ",&i);
720 ppt = &mesh->point[i];
721 MMG_FSCANF((*inm),"%lf %lf %lf ",&ppt->c[0],&ppt->c[1],&ppt->c[2]);
722 }
723 else {
724 MMG_FREAD(&i,MMG5_SW,1,(*inm));
725 if ( iswp ) i = MMG5_swapbin(i);
726 ppt = &mesh->point[i];
727 for (i=0 ; i<3 ; i++) {
728 MMG_FREAD(&ppt->c[i],MMG5_SD,1,(*inm));
729 if(iswp) ppt->c[i]=MMG5_swapd(ppt->c[i]);
730 }
731 }
732 ppt->tag = MG_NUL;
733 ppt->tmp = 0;
734 ppt->ref = 0;
735 }
736 }
737
738 rewind((*inm));
739 fseek((*inm),posElts,SEEK_SET);
740
741 nbl_a = nbl_t = nt = na = nq = ne = npr = 0;
742 nref = 0;
743
744 if ( !bin ) {
745 for ( k=0; k<nelts; ++k)
746 {
747 MMG_FSCANF((*inm),"%d %d %d ",&i,&typ, &tagNum);
748 if ( tagNum < 2 ) {
749 fprintf(stderr,"\n ## Error: %s: elt %d (type %d): Expected at least 2 tags (%d given).\n",
750 __func__,k,typ,tagNum);
751 fclose(*inm);
752 return -1;
753 }
754 MMG_FSCANF((*inm),"%d %d ",&ref,&i);
755 for ( l=2; l<tagNum; ++l ) {
756 MMG_FSCANF((*inm),"%d ",&i);
757 }
758
759 switch (typ) {
760 case 1:
761 /* Edge */
762 /* Skip edges with mesh->info.isoref refs */
763 if ( mesh->info.iso && MMG5_abs(ref)== mesh->info.isoref ) {
764 /* Skip this edge but advance the file pointer */
765 pa = &mesh->edge[0];
766 MMG_FSCANF((*inm),"%" MMG5_PRId " %" MMG5_PRId " ",&pa->a,&pa->b);
767 ++nbl_a;
768 }
769 else {
770 pa = &mesh->edge[++na];
771 MMG_FSCANF((*inm),"%" MMG5_PRId " %" MMG5_PRId " ",&pa->a,&pa->b);
772 pa->ref = ref;
773 if ( pa->ref < 0 ) {
774 pa->ref = -pa->ref;
775 ++nref;
776 }
777 pa->tag |= MG_REF;
778 }
779 assert( na+nbl_a<=mesh->na );
780 break;
781 case 2:
782 /* Tria */
783 /* Skip triangles with mesh->info.isoref refs in 3D */
784 if ( mesh->info.iso && MMG5_abs(ref)== mesh->info.isoref && mesh->dim == 3 ) {
785 /* Skip this triangle but advance the file pointer */
786 ptt = &mesh->tria[0];
787 MMG_FSCANF((*inm),"%" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "",&ptt->v[0],&ptt->v[1],&ptt->v[2]);
788 ++nbl_t;
789 }
790 else {
791 ptt = &mesh->tria[++nt];
792 MMG_FSCANF((*inm),"%" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " ",&ptt->v[0],&ptt->v[1],&ptt->v[2]);
793 ptt->ref = ref;
794 if ( ptt->ref < 0 ) {
795 ptt->ref = -ptt->ref;
796 ++nref;
797 }
798 }
799 assert( nt+nbl_t<=mesh->nt );
800 break;
801 case 3:
802 /* Quad */
803 pq1 = &mesh->quadra[++nq];
804 MMG_FSCANF((*inm),"%" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " ",&pq1->v[0],&pq1->v[1],&pq1->v[2],&pq1->v[3]);
805 pq1->ref = ref;
806 if ( pq1->ref < 0 ) {
807 pq1->ref = -pq1->ref;
808 ++nref;
809 }
810 assert( nq<=mesh->nquad );
811 break;
812 case 4:
813 /* Tetra for mmg3d */
814 if ( mesh->ne ) {
815 pt = &mesh->tetra[++ne];
816 MMG_FSCANF((*inm),"%" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " ",&pt->v[0],&pt->v[1],&pt->v[2],&pt->v[3]);
817 pt->ref = MMG5_abs(ref);
818 } else { /*skip tetra*/
819 MMG_FSCANF((*inm),"%d %d %d %d ",&v[0],&v[1],&v[2],&v[3]);
820 }
821
822 if(ref < 0) {
823 nref++;
824 }
825
826 assert( ne<=mesh->ne );
827 break;
828 case 6:
829 /* Prism for mmg3d */
830 if ( mesh->nprism )
831 {
832 pp = &mesh->prism[++npr];
833 MMG_FSCANF((*inm),"%" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " ",&pp->v[0],&pp->v[1],&pp->v[2],
834 &pp->v[3],&pp->v[4],&pp->v[5]);
835 pp->ref = MMG5_abs(ref);
836 }
837 if(ref < 0) {
838 nref++;
839 }
840 assert( npr<=mesh->nprism );
841 break;
842 case 15:
843 /* Node */
844 MMG_FSCANF((*inm),"%d ",&l);
845 ppt = &mesh->point[l];
846 ppt->ref = ref;
847 if ( ppt->ref < 0 ) {
848 ppt->ref = -ppt->ref;
849 ++nref;
850 }
851 assert( l<=mesh->np );
852 break;
853 default:
854 if ( !mmgWarn ) {
855 fprintf(stderr,"\n ## Warning: %s: unexpected type for at least 1 element:"
856 " element %d, type %d\n",__func__,k,typ );
857 mmgWarn = 1;
858 }
859 }
860 }
861 }
862 else {
863 k = 0;
864
865 while ( k<nelts ) {
866 MMG_FREAD(&typ,MMG5_SW,1,(*inm));
867 if(iswp) typ = MMG5_swapbin(typ);
868
869 switch (typ) {
870 case 1:
871 /* Edge */
872 MMG_FREAD(&num,MMG5_SW,1,(*inm));
873 MMG_FREAD(&tagNum,MMG5_SW,1,(*inm));
874 if(iswp) {
875 num = MMG5_swapbin(num);
876 tagNum = MMG5_swapbin(tagNum);
877 }
878 if ( tagNum < 2 ) {
879 fprintf(stderr,"\n ## Error: %s: Expected at least 2 tags per element (%d given).\n",
880 __func__,tagNum);
881 fclose(*inm);
882 return -1;
883 }
884
885 for ( idx=0; idx<num; ++idx ) {
886 MMG_FREAD(&i,MMG5_SW,1,(*inm));
887
888 MMG_FREAD(&ref,MMG5_SW,1,(*inm));
889 MMG_FREAD(&i,MMG5_SW,1,(*inm));
890
891 for ( l=2; l<tagNum; ++l ) {
892 MMG_FREAD(&i,MMG5_SW,1,(*inm));
893 }
894
895 if(iswp) ref = MMG5_swapbin(ref);
896
897 /* Skip edges with mesh->info.isoref refs */
898 if ( mesh->info.iso && MMG5_abs(ref) == mesh->info.isoref ) {
899 /* Skip this edge but advance the file pointer */
900 pa = &mesh->edge[0];
901 MMG_FREAD(&pa->a,MMG5_SW,1,(*inm));
902 MMG_FREAD(&pa->b,MMG5_SW,1,(*inm));
903 ++nbl_a;
904 }
905 else {
906 pa = &mesh->edge[++na];
907 int a,b;
908 MMG_FREAD(&a,MMG5_SW,1,(*inm));
909 MMG_FREAD(&b,MMG5_SW,1,(*inm));
910 if ( iswp ) {
911 pa->a = MMG5_swapbin(a);
912 pa->b = MMG5_swapbin(b);
913 }
914 else {
915 pa->a = a;
916 pa->b = b;
917 }
918 pa->ref = ref;
919 if ( pa->ref < 0 ) {
920 pa->ref = -pa->ref;
921 ++nref;
922 }
923 pa->tag |= MG_REF;
924 }
925 assert( na+nbl_a<=mesh->na );
926 }
927 k += num;
928
929 break;
930 case 2:
931 /* Tria */
932 MMG_FREAD(&num,MMG5_SW,1,(*inm));
933 MMG_FREAD(&tagNum,MMG5_SW,1,(*inm));
934 if(iswp) {
935 num = MMG5_swapbin(num);
936 tagNum = MMG5_swapbin(tagNum);
937 }
938 if ( tagNum < 2 ) {
939 fprintf(stderr,"\n ## Error: %s: Expected at least 2 tags per element (%d given).\n",
940 __func__,tagNum);
941 fclose(*inm);
942 return -1;
943 }
944
945 for ( idx=0; idx<num; ++idx ) {
946 MMG_FREAD(&i,MMG5_SW,1,(*inm));
947
948 MMG_FREAD(&ref,MMG5_SW,1,(*inm));
949 MMG_FREAD(&i,MMG5_SW,1,(*inm));
950
951 for ( l=2; l<tagNum; ++l ) {
952 MMG_FREAD(&i,MMG5_SW,1,(*inm));
953 }
954
955 if(iswp) ref = MMG5_swapbin(ref);
956
957 /* Skip triangles with mesh->info.isoref refs in 3D */
958 if ( mesh->info.iso && MMG5_abs(ref) == mesh->info.isoref && mesh->dim == 3 ) {
959 /* Skip this triangle but advance the file pointer */
960 for ( i=0; i<3 ; ++i ) {
961 MMG_FREAD(&l,MMG5_SW,1,(*inm));
962 }
963 ++nbl_t;
964 }
965 else {
966 ptt = &mesh->tria[++nt];
967 for ( i=0; i<3 ; ++i ) {
968 MMG_FREAD(&l,MMG5_SW,1,(*inm));
969 if ( iswp ) l = MMG5_swapbin(l);
970 ptt->v[i] = l;
971 }
972 ptt->ref = ref;
973 if ( ptt->ref < 0 ) {
974 ptt->ref = -ptt->ref;
975 ++nref;
976 }
977 }
978 assert( nt+nbl_t<=mesh->nt );
979 }
980 k += num;
981 break;
982 case 3:
983 /* Quad */
984 MMG_FREAD(&num,MMG5_SW,1,(*inm));
985 MMG_FREAD(&tagNum,MMG5_SW,1,(*inm));
986 if(iswp) {
987 num = MMG5_swapbin(num);
988 tagNum = MMG5_swapbin(tagNum);
989 }
990 if ( tagNum < 2 ) {
991 fprintf(stderr,"\n ## Error: %s: Expected at least 2 tags per element (%d given).\n",
992 __func__,tagNum);
993 fclose(*inm);
994 return -1;
995 }
996
997 for ( idx=0; idx<num; ++idx ) {
998 MMG_FREAD(&i,MMG5_SW,1,(*inm));
999
1000 MMG_FREAD(&ref,MMG5_SW,1,(*inm));
1001 MMG_FREAD(&i,MMG5_SW,1,(*inm));
1002
1003 for ( l=2; l<tagNum; ++l ) {
1004 MMG_FREAD(&i,MMG5_SW,1,(*inm));
1005 }
1006
1007 if(iswp) ref = MMG5_swapbin(ref);
1008
1009 pq1 = &mesh->quadra[++nq];
1010 for ( i=0; i<4 ; ++i ) {
1011 MMG_FREAD(&l,MMG5_SW,1,(*inm));
1012 if ( iswp ) l = MMG5_swapbin(l);
1013 pq1->v[i] = l;
1014 }
1015 pq1->ref = ref;
1016 if ( pq1->ref < 0 ) {
1017 pq1->ref = -pq1->ref;
1018 ++nref;
1019 }
1020 assert( nq<=mesh->nquad );
1021 }
1022 k += num;
1023 break;
1024 case 4:
1025 /* Tetra */
1026 MMG_FREAD(&num,MMG5_SW,1,(*inm));
1027 MMG_FREAD(&tagNum,MMG5_SW,1,(*inm));
1028 if(iswp) {
1029 num = MMG5_swapbin(num);
1030 tagNum = MMG5_swapbin(tagNum);
1031 }
1032
1033 if ( tagNum < 2 ) {
1034 fprintf(stderr,"\n ## Error: %s: Expected at least 2 tags per element (%d given).\n",
1035 __func__,tagNum);
1036 fclose(*inm);
1037 return -1;
1038 }
1039
1040 for ( idx=0; idx<num; ++idx ) {
1041 MMG_FREAD(&i,MMG5_SW,1,(*inm));
1042
1043 MMG_FREAD(&ref,MMG5_SW,1,(*inm));
1044 MMG_FREAD(&i,MMG5_SW,1,(*inm));
1045
1046 for ( l=2; l<tagNum; ++l ) {
1047 MMG_FREAD(&i,MMG5_SW,1,(*inm));
1048 }
1049
1050 if(iswp) ref = MMG5_swapbin(ref);
1051
1052 if ( mesh->ne ) {
1053 pt = &mesh->tetra[++ne];
1054 for ( i=0; i<4 ; ++i ) {
1055 MMG_FREAD(&l,MMG5_SW,1,(*inm));
1056 if ( iswp ) l = MMG5_swapbin(l);
1057 pt->v[i] = l;
1058 }
1059 pt->ref = MMG5_abs(ref);
1060 assert( ne<=mesh->ne );
1061 }
1062 else
1063 for ( i=0; i<4 ; ++i )
1064 MMG_FREAD(&l,MMG5_SW,1,(*inm));
1065
1066 if(ref < 0) {
1067 nref++;
1068 }
1069 }
1070 k += num;
1071 break;
1072 case 6:
1073 /* Prism */
1074 MMG_FREAD(&num,MMG5_SW,1,(*inm));
1075 MMG_FREAD(&tagNum,MMG5_SW,1,(*inm));
1076 if(iswp) {
1077 num = MMG5_swapbin(num);
1078 tagNum = MMG5_swapbin(tagNum);
1079 }
1080 if ( tagNum < 2 ) {
1081 fprintf(stderr,"\n ## Error: %s: Expected at least 2 tags per element (%d given).\n",
1082 __func__,tagNum);
1083 fclose(*inm);
1084 return -1;
1085 }
1086
1087 for ( idx=0; idx<num; ++idx ) {
1088 MMG_FREAD(&i,MMG5_SW,1,(*inm));
1089
1090 MMG_FREAD(&ref,MMG5_SW,1,(*inm));
1091 MMG_FREAD(&i,MMG5_SW,1,(*inm));
1092
1093 for ( l=2; l<tagNum; ++l ) {
1094 MMG_FREAD(&i,MMG5_SW,1,(*inm));
1095 }
1096
1097 if(iswp) ref = MMG5_swapbin(ref);
1098
1099 if ( mesh->nprism ) {
1100 pp = &mesh->prism[++npr];
1101 for ( i=0; i<6 ; ++i ) {
1102 MMG_FREAD(&l,MMG5_SW,1,(*inm));
1103 if ( iswp ) l = MMG5_swapbin(l);
1104 pp->v[i] = l;
1105 }
1106 pp->ref = MMG5_abs(ref);
1107 assert( npr<=mesh->nprism );
1108 }
1109 else {
1110 for ( i=0; i<6 ; ++i )
1111 MMG_FREAD(&l,MMG5_SW,1,(*inm));
1112 }
1113
1114 if(ref < 0) {
1115 nref++;
1116 }
1117 }
1118 k += num;
1119 break;
1120 case 15:
1121 /* Node */
1122 MMG_FREAD(&num,MMG5_SW,1,(*inm));
1123 MMG_FREAD(&tagNum,MMG5_SW,1,(*inm));
1124 if(iswp) {
1125 num = MMG5_swapbin(num);
1126 tagNum = MMG5_swapbin(tagNum);
1127 }
1128 if ( tagNum < 2 ) {
1129 fprintf(stderr,"\n ## Error: %s: Expected at least 2 tags per element (%d given).\n",
1130 __func__,tagNum);
1131 fclose(*inm);
1132 return -1;
1133 }
1134
1135 for ( idx=0; idx<num; ++idx ) {
1136 MMG_FREAD(&i,MMG5_SW,1,(*inm));
1137
1138 MMG_FREAD(&ref,MMG5_SW,1,(*inm));
1139 MMG_FREAD(&i,MMG5_SW,1,(*inm));
1140
1141 for ( l=2; l<tagNum; ++l ) {
1142 MMG_FREAD(&i,MMG5_SW,1,(*inm));
1143 }
1144
1145 if(iswp) ref = MMG5_swapbin(ref);
1146
1147 MMG_FREAD(&l,MMG5_SW,1,(*inm));
1148 if(iswp) l = MMG5_swapbin(l);
1149 ppt = &mesh->point[l];
1150 ppt->ref = ref;
1151 if ( ppt->ref < 0 ) {
1152 ppt->ref = -ppt->ref;
1153 ++nref;
1154 }
1155 assert( l<=mesh->np );
1156 }
1157 k += num;
1158 break;
1159 default:
1160 fprintf(stderr,"\n ## Error: %s: unexpected type of element (%d)\n",
1161 __func__,typ);
1162 fclose(*inm);
1163 return -1;
1164 }
1165 }
1166 }
1167
1168 /* Check data */
1169 assert ( na + nbl_a == mesh->na );
1170 assert ( nt + nbl_t == mesh->nt );
1171
1172 /* Array reallocation if ISO refs has been skipped */
1173 if ( mesh->info.iso ) {
1174 if ( mesh->nt ) {
1175 if( !nt )
1177
1178 else if ( nt < mesh->nt ) {
1179 MMG5_ADD_MEM(mesh,(nt-mesh->nt)*sizeof(MMG5_Tria),"triangles",
1180 fprintf(stderr," Exit program.\n");
1181 fclose(*inm);
1182 return -1);
1183 MMG5_SAFE_RECALLOC(mesh->tria,mesh->nt+1,(nt+1),MMG5_Tria,"triangles",
1184 return -1);
1185 }
1186 mesh->nt = nt;
1187 }
1188 if ( mesh->na ) {
1189 if( !na )
1191 else if ( na < mesh->na ) {
1192 MMG5_ADD_MEM(mesh,(na-mesh->na)*sizeof(MMG5_Edge),"edges",
1193 fprintf(stderr," Exit program.\n");
1194 fclose(*inm);
1195 return -1);
1196 MMG5_SAFE_RECALLOC(mesh->edge,mesh->na+1,(na+1),MMG5_Edge,"edges",
1197 return -1);
1198 }
1199 mesh->na = na;
1200 }
1201 }
1202
1204 if ( ier < 1 ) return ier;
1205
1206 if ( sol && *sol ) {
1208 /* Init (*sol)[0] for the case where nsols=0 */
1209 psl = *sol;
1210 psl->ver = mesh->ver;
1211 psl->dim = mesh->dim;
1212 psl->type = 1;
1213
1214 for ( isol=0; isol < nsols; ++isol ) {
1215 assert ( posNodeData[isol] );
1216
1217 rewind((*inm));
1218 fseek((*inm),posNodeData[isol],SEEK_SET);
1219
1220 psl = *sol + isol;
1221
1222 psl->ver = mesh->ver;
1223 psl->dim = mesh->dim;
1224 psl->entities = MMG5_Vertex;
1225 psl->type = 1;
1226
1227 /* String tags: The first one stores the solution name */
1228 MMG_FSCANF((*inm),"%d ",&tagNum);
1229 if ( 1 != fscanf(*inm,"\"%127s\"\n",&chaine[0]) ) {
1230 MMG_FSCANF(*inm,"%127s\n",&chaine[0]);
1231 }
1232
1233 ptr = NULL;
1234 ptr = strstr(chaine,":metric");
1235
1236 metricData = 0;
1237 if ( ptr ) {
1238 *ptr = '\0';
1239 metricData = 1;
1240 }
1241
1242
1243 if ( !MMG5_Set_inputSolName(mesh,psl,chaine) ) {
1244 if ( !mmgWarn1 ) {
1245 mmgWarn1 = 1;
1246 fprintf(stderr,"\n ## Warning: %s: unable to set solution name for"
1247 " at least 1 solution.\n",__func__);
1248 }
1249 }
1250
1251 for ( k=1; k<tagNum; ++k ) {
1252 if ( 0 != fscanf((*inm),"%*[^\n]%*c") ) return -1;
1253 }
1254
1255 /* Real tags ignored */
1256 if ( fscanf((*inm),"%d",&tagNum) ) {
1257 for ( k=0; k<tagNum; ++k ) {
1258 MMG_FSCANF((*inm),"%f",&fc);
1259 }
1260 }
1261
1262 /* Integer tags : allow to recover the number of sols and their types */
1263 MMG_FSCANF((*inm),"%d ",&tagNum);
1264 if ( tagNum < 3 ) {
1265 fprintf(stderr," Error: %s: node data: Expected at least 3 tags (%d given).\n",
1266 __func__,tagNum);
1267 fclose(*inm);
1268 return -1;
1269 }
1270
1271 MMG_FSCANF((*inm),"%d ",&i); //time step;
1272 MMG_FSCANF((*inm),"%d ",&typ); //type of solution: 1=scalar, 3=vector, 9=tensor ;
1273 MMG_FSCANF((*inm),"%" MMG5_PRId " ",&psl->np);
1274
1275 for ( k=3; k<tagNum; ++k ) {
1276 MMG_FSCANF((*inm),"%d",&i);
1277 }
1278
1279 if ( mesh->np != psl->np ) {
1280 fprintf(stderr," ** MISMATCHES DATA: THE NUMBER OF VERTICES IN "
1281 "THE MESH (%" MMG5_PRId ") DIFFERS FROM THE NUMBER OF VERTICES IN "
1282 "THE SOLUTION (%" MMG5_PRId ") \n",mesh->np,psl->np);
1283 fclose(*inm);
1284 return -1;
1285 }
1286
1287 if ( typ == 1 ) {
1288 psl->size = 1;
1289 psl->type = 1;
1290 }
1291 else if ( typ == 3 ) {
1292 psl->size = psl->dim;
1293 psl->type = 2;
1294 }
1295 else if ( typ == 9 ) {
1296 if ( metricData ) {
1297 psl->size = (psl->dim*(psl->dim+1))/2;
1298 psl->type = 3;
1299 }
1300 else {
1301 psl->size = psl->dim*psl->dim;
1302 psl->type = 4;
1303 }
1304 }
1305 else {
1306 fprintf(stderr," ** DATA TYPE IGNORED %d \n",typ);
1307 fclose(*inm);
1308 return -1;
1309 }
1310
1311 /* mem alloc */
1312 if ( psl->m ) MMG5_DEL_MEM(mesh,psl->m);
1313 psl->npmax = mesh->npmax;
1314
1315 MMG5_ADD_MEM(mesh,(psl->size*(psl->npmax+1))*sizeof(double),"initial solution",
1316 fprintf(stderr," Exit program.\n");
1317 fclose(*inm);
1318 return -1);
1319 MMG5_SAFE_CALLOC(psl->m,psl->size*(psl->npmax+1),double,return -1);
1320
1321 /* isotropic solution */
1322 if ( psl->size == 1 ) {
1323 if ( psl->ver == 1 ) {
1324 for (k=1; k<=psl->np; k++) {
1325 if(!bin){
1326 MMG_FSCANF((*inm),"%d ",&idx);
1327 MMG_FSCANF((*inm),"%f ",&fbuf[0]);
1328 } else {
1329 MMG_FREAD(&idx,MMG5_SW,1, (*inm));
1330 if(iswp) idx = MMG5_swapbin(idx);
1331 MMG_FREAD(&fbuf[0],MMG5_SW,1,(*inm));
1332 if(iswp) fbuf[0]=MMG5_swapf(fbuf[0]);
1333 }
1334 psl->m[idx] = fbuf[0];
1335 }
1336 }
1337 else {
1338 for (k=1; k<=psl->np; k++) {
1339 if(!bin){
1340 MMG_FSCANF((*inm),"%d ",&idx);
1341 MMG_FSCANF((*inm),"%lf ",&dbuf[0]);
1342 } else {
1343 MMG_FREAD(&idx,MMG5_SW,1, (*inm));
1344 if(iswp) idx = MMG5_swapbin(idx);
1345 MMG_FREAD(&dbuf[0],MMG5_SD,1,(*inm));
1346 if(iswp) dbuf[0]=MMG5_swapd(dbuf[0]);
1347 }
1348 psl->m[idx] = dbuf[0];
1349 }
1350 }
1351 }
1352 /* vector displacement only */
1353 else if ( psl->size == psl->dim ) {
1354 if ( psl->ver == 1 ) {
1355 for (k=1; k<=psl->np; k++) {
1356 if(!bin){
1357 MMG_FSCANF((*inm),"%d ",&idx);
1358 for (i=0; i<psl->dim; i++) {
1359 MMG_FSCANF((*inm),"%f ",&fbuf[0]);
1360 psl->m[psl->dim*idx+i] = fbuf[0];
1361 }
1362 } else {
1363 MMG_FREAD(&idx,MMG5_SW,1, (*inm));
1364 if(iswp) idx = MMG5_swapbin(idx);
1365 for (i=0; i<psl->dim; i++) {
1366 MMG_FREAD(&fbuf[0],MMG5_SW,1,(*inm));
1367 if(iswp) fbuf[0]=MMG5_swapf(fbuf[0]);
1368 psl->m[psl->dim*idx+i] = fbuf[0];
1369 }
1370 }
1371 }
1372 }
1373 else {
1374 for (k=1; k<=psl->np; k++) {
1375 if(!bin){
1376 MMG_FSCANF((*inm),"%d ",&idx);
1377
1378 for (i=0; i<psl->dim; i++) {
1379 MMG_FSCANF((*inm),"%lf ",&dbuf[0]);
1380 psl->m[psl->dim*idx+i] = dbuf[0];
1381 }
1382
1383 } else {
1384 MMG_FREAD(&idx,MMG5_SW,1, (*inm));
1385 if(iswp) idx = MMG5_swapbin(idx);
1386
1387 for (i=0; i<psl->dim; i++) {
1388 MMG_FREAD(&dbuf[0],MMG5_SD,1,(*inm));
1389 if(iswp) dbuf[0]=MMG5_swapd(dbuf[0]);
1390 psl->m[psl->dim*idx+i] = dbuf[0];
1391 }
1392
1393 }
1394 }
1395 }
1396 }
1397 /* anisotropic sol */
1398 else {
1399 if ( psl->ver == 1 ) {
1400 /* Solution at simple precision */
1401 for (k=1; k<=psl->np; k++) {
1402
1403 if(!bin){
1404 MMG_FSCANF((*inm),"%d ",&idx);
1405 for(i=0 ; i<9 ; i++)
1406 MMG_FSCANF((*inm),"%f ",&fbuf[i]);
1407 } else {
1408 MMG_FREAD(&idx,MMG5_SW,1, (*inm));
1409 if(iswp) idx = MMG5_swapbin(idx);
1410 for(i=0 ; i<9 ; i++) {
1411 MMG_FREAD(&fbuf[i],MMG5_SW,1,(*inm));
1412 if(iswp) fbuf[i]=MMG5_swapf(fbuf[i]);
1413 }
1414 }
1415
1416 iadr = psl->size*idx;
1417
1418 if ( !metricData ) {
1419 if ( psl->dim ==2 ) {
1420 psl->m[iadr] = fbuf[0];
1421 psl->m[iadr+1] = fbuf[1];
1422 psl->m[iadr+2] = fbuf[3];
1423 psl->m[iadr+3] = fbuf[4];
1424 }
1425 else {
1426 for(i=0 ; i<9 ; i++) {
1427 psl->m[iadr+i] = fbuf[i];
1428 }
1429 }
1430 }
1431 else {
1432 if ( psl->dim ==2 ) {
1433 assert ( fbuf[1] == fbuf[3] );
1434
1435 psl->m[iadr] = fbuf[0];
1436 psl->m[iadr+1] = fbuf[1];
1437 psl->m[iadr+2] = fbuf[4];
1438 }
1439 else {
1440 assert ( fbuf[1]==fbuf[3] && fbuf[2]==fbuf[6] && fbuf[5]==fbuf[7] );
1441
1442 psl->m[iadr+0] = fbuf[0];
1443 psl->m[iadr+1] = fbuf[1];
1444 psl->m[iadr+2] = fbuf[2];
1445 psl->m[iadr+3] = fbuf[4];
1446 psl->m[iadr+4] = fbuf[5];
1447 psl->m[iadr+5] = fbuf[8];
1448 }
1449 }
1450 }
1451 }
1452 else {
1453 for (k=1; k<=psl->np; k++) {
1454 /* Solution at double precision */
1455 if(!bin){
1456 MMG_FSCANF((*inm),"%d ",&idx);
1457 for(i=0 ; i<9 ; i++)
1458 MMG_FSCANF((*inm),"%lf ",&dbuf[i]);
1459 } else {
1460 MMG_FREAD(&idx,MMG5_SW,1, (*inm));
1461 if(iswp) idx = MMG5_swapbin(idx);
1462 for(i=0 ; i<9 ; i++) {
1463 MMG_FREAD(&dbuf[i],MMG5_SD,1,(*inm));
1464 if(iswp) dbuf[i]=MMG5_swapd(dbuf[i]);
1465 }
1466 }
1467
1468 iadr = psl->size*idx;
1469
1470 if ( !metricData ) {
1471 if ( psl->dim ==2 ) {
1472 psl->m[iadr ] = dbuf[0];
1473 psl->m[iadr+1] = dbuf[1];
1474 psl->m[iadr+2] = dbuf[3];
1475 psl->m[iadr+3] = dbuf[4];
1476 }
1477 else {
1478 for(i=0 ; i<9 ; i++) {
1479 psl->m[iadr+i] = dbuf[i];
1480 }
1481 }
1482 }
1483 else {
1484 if ( psl->dim ==2 ) {
1485 assert ( dbuf[1] == dbuf[3] );
1486
1487 psl->m[iadr ] = dbuf[0];
1488 psl->m[iadr+1] = dbuf[1];
1489 psl->m[iadr+2] = dbuf[4];
1490 }
1491 else {
1492 assert ( dbuf[1]==dbuf[3] || dbuf[2]==dbuf[6] || dbuf[5]==dbuf[7] );
1493
1494 psl->m[iadr+0] = dbuf[0];
1495 psl->m[iadr+1] = dbuf[1];
1496 psl->m[iadr+2] = dbuf[2];
1497 psl->m[iadr+3] = dbuf[4];
1498 psl->m[iadr+4] = dbuf[5];
1499 psl->m[iadr+5] = dbuf[8];
1500 }
1501 }
1502 }
1503 }
1504 }
1505
1506 psl->npi = psl->np;
1507 }
1508 }
1509
1510 fclose((*inm));
1511
1512 return 1;
1513}
1514
1525 double dbuf[6]) {
1526 MMG5_pPoint ppt;
1527 double mtmp[3],r[3][3];
1528 int i;
1529
1530 ppt = &mesh->point[ip];
1531 if ( mesh->info.metRidTyp &&
1532 ( !(MG_SIN(ppt->tag) || (ppt->tag & MG_NOM) || (ppt->tag & MG_NOSURF))
1533 && (ppt->tag & MG_GEO) ) ) {
1534 /* Specific storage of the aniso metric at ridge */
1535 if ( mesh->xp ) {
1536 // Arbitrary, we take the metric associated to the surface ruled by n_1
1537 mtmp[0] = sol->m[sol->size*(ip)];
1538 mtmp[1] = sol->m[sol->size*(ip)+1];
1539 mtmp[2] = sol->m[sol->size*(ip)+3];
1540
1541 // Rotation matrix.
1542 r[0][0] = ppt->n[0];
1543 r[1][0] = ppt->n[1];
1544 r[2][0] = ppt->n[2];
1545 r[0][1] = mesh->xpoint[ppt->xp].n1[1]*ppt->n[2]
1546 - mesh->xpoint[ppt->xp].n1[2]*ppt->n[1];
1547 r[1][1] = mesh->xpoint[ppt->xp].n1[2]*ppt->n[0]
1548 - mesh->xpoint[ppt->xp].n1[0]*ppt->n[2];
1549 r[2][1] = mesh->xpoint[ppt->xp].n1[0]*ppt->n[1]
1550 - mesh->xpoint[ppt->xp].n1[1]*ppt->n[0];
1551 r[0][2] = mesh->xpoint[ppt->xp].n1[0];
1552 r[1][2] = mesh->xpoint[ppt->xp].n1[1];
1553 r[2][2] = mesh->xpoint[ppt->xp].n1[2];
1554
1555 // Metric in the canonic space
1556 dbuf[0] = mtmp[0]*r[0][0]*r[0][0] + mtmp[1]*r[0][1]*r[0][1] + mtmp[2]*r[0][2]*r[0][2];
1557 dbuf[1] = mtmp[0]*r[0][0]*r[1][0] + mtmp[1]*r[0][1]*r[1][1] + mtmp[2]*r[0][2]*r[1][2];
1558 dbuf[2] = mtmp[0]*r[0][0]*r[2][0] + mtmp[1]*r[0][1]*r[2][1] + mtmp[2]*r[0][2]*r[2][2];
1559 dbuf[3] = mtmp[0]*r[1][0]*r[1][0] + mtmp[1]*r[1][1]*r[1][1] + mtmp[2]*r[1][2]*r[1][2];
1560 dbuf[4] = mtmp[0]*r[1][0]*r[2][0] + mtmp[1]*r[1][1]*r[2][1] + mtmp[2]*r[1][2]*r[2][2];
1561 dbuf[5] = mtmp[0]*r[2][0]*r[2][0] + mtmp[1]*r[2][1]*r[2][1] + mtmp[2]*r[2][2]*r[2][2];
1562 }
1563 else { // Cannot recover the metric
1564 for (i=0; i<sol->size; i++) dbuf[i] = 0.;
1565 }
1566 }
1567 else {
1568 for (i=0; i<sol->size; i++) dbuf[i] = sol->m[sol->size*ip+i];
1569 }
1570}
1571
1584 int metricData) {
1585 FILE* inm;
1586 MMG5_pPoint ppt;
1587 MMG5_pTetra pt;
1588 MMG5_pPrism pp;
1589 MMG5_pTria ptt;
1590 MMG5_pQuad pq;
1591 MMG5_pEdge pa;
1592 MMG5_pSol psl;
1593 double dbuf[6];
1594 int bin,i,typ;
1595 MMG5_int header[3],nq,ne,npr,np,nt,na,k,iadr,nelts,word;
1596 int isol,nsols;
1597 char *ptr,*data;
1598 static char mmgWarn = 0;
1599
1600 bin = 0;
1601
1602 MMG5_SAFE_CALLOC(data,strlen(filename)+7,char,return 0);
1603 strcpy(data,filename);
1604
1605 ptr = strstr(data,".msh");
1606 if ( !ptr ) {
1607 /* data contains the filename without extension */
1608 strcat(data,".mshb");
1609 if (!(inm = fopen(data,"wb")) ) {
1610 ptr = strstr(data,".msh");
1611 *ptr = '\0';
1612 strcat(data,".msh");
1613 if( !(inm = fopen(data,"wb")) ) {
1614 fprintf(stderr," ** UNABLE TO OPEN %s.\n",data);
1615 MMG5_SAFE_FREE(data);
1616 return 0;
1617 }
1618 }
1619 else bin=1;
1620 }
1621 else {
1622 ptr = strstr(data,".mshb");
1623 if ( ptr ) bin = 1;
1624 if( !(inm = fopen(data,"wb")) ) {
1625 fprintf(stderr," ** UNABLE TO OPEN %s.\n",data);
1626 MMG5_SAFE_FREE(data);
1627 return 0;
1628 }
1629 }
1630
1631 if ( mesh->info.imprim >= 0 )
1632 fprintf(stdout," %%%% %s OPENED\n",data);
1633 MMG5_SAFE_FREE(data);
1634
1635 /* Entete fichier*/
1636 fprintf(inm,"$MeshFormat\n");
1637 fprintf(inm,"2.2 %d %d\n",bin,8);
1638 if ( bin ) {
1639 word = 1;
1640 fwrite(&word,MMG5_SW,1,inm);
1641 fprintf(inm,"\n");
1642 }
1643 fprintf(inm,"$EndMeshFormat\n");
1644
1645 /* Vertices */
1646 np = 0;
1647 for (k=1; k<=mesh->np; k++) {
1648 ppt = &mesh->point[k];
1649 if ( MG_VOK(ppt) ) {
1650 ppt->tmp = ++np;
1651 if ( mesh->dim==2 ) ppt->c[2] = 0.;
1652 }
1653 }
1654 fprintf(inm,"$Nodes\n");
1655 fprintf(inm,"%" MMG5_PRId "\n",np);
1656
1657 for (k=1; k<=mesh->np; k++) {
1658 ppt = &mesh->point[k];
1659 if ( MG_VOK(ppt) ) {
1660 if(!bin) {
1661 fprintf(inm," %" MMG5_PRId "",ppt->tmp);
1662 for ( i=0; i<3; ++i )
1663 fprintf(inm," %.15lg",ppt->c[i]);
1664 fprintf(inm,"\n");
1665 } else {
1666 fwrite(&ppt->tmp,MMG5_SW,1,inm);
1667 fwrite(&ppt->c[0],MMG5_SD,3,inm);
1668 }
1669 }
1670 }
1671 if ( bin ) fprintf(inm,"\n");
1672 fprintf(inm,"$EndNodes\n");
1673
1674 /* Data reading */
1676 ne = 0;
1677 for (k=1; k<=mesh->ne; k++) {
1678 pt = &mesh->tetra[k];
1679 if ( !MG_EOK(pt) ) continue;
1680 ++ne;
1681 }
1682 npr = 0;
1683 for (k=1; k<=mesh->nprism; k++) {
1684 pp = &mesh->prism[k];
1685 if ( !MG_EOK(pp) ) continue;
1686 npr++;
1687 }
1688 nq = 0;
1689 for (k=1; k<=mesh->nquad; k++) {
1690 pq = &mesh->quadra[k];
1691 if ( !MG_EOK(pq) ) continue;
1692 nq++;
1693 }
1694 nt = 0;
1695 for (k=1; k<=mesh->nt; k++) {
1696 ptt = &mesh->tria[k];
1697 if ( !MG_EOK(ptt) ) continue;
1698 nt++;
1699 }
1700 na = 0;
1701 for (k=1; k<=mesh->na; k++) {
1702 pa = &mesh->edge[k];
1703 if ( (!pa || !pa->a) ) continue;
1704 na++;
1705 }
1706
1707 fprintf(inm,"$Elements\n");
1708 fprintf(inm,"%" MMG5_PRId "\n", np + ne + npr + nt + nq + na );
1709
1712 nelts = 0;
1713
1714 /* Nodes */
1715 if ( bin ) {
1716 header[0] = 15;// Node keyword
1717 header[1] = np;
1718 header[2] = 2; // 2 tags per node
1719 fwrite(header, MMG5_SW, 3, inm);
1720 }
1721
1722 for ( k=1; k<= mesh->np; ++k)
1723 {
1724 ppt = &mesh->point[k];
1725 if ( !MG_VOK(ppt) ) continue;
1726 ++nelts;
1727
1728 if ( !bin ) fprintf(inm,"%" MMG5_PRId " 15 2 %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "\n",nelts,MMG5_abs(ppt->ref),
1729 MMG5_abs(ppt->ref),ppt->tmp);
1730 else {
1731 fwrite(&nelts,MMG5_SW,1,inm);
1732 word = MMG5_abs(ppt->ref);
1733 fwrite(&word,MMG5_SW,1,inm);
1734 fwrite(&word,MMG5_SW,1,inm);
1735 fwrite(&ppt->tmp,MMG5_SW,1,inm);
1736 }
1737 }
1738
1739 /* Edges */
1740 if ( bin && na ) {
1741 header[0] = 1;// Edge keyword
1742 header[1] = na;
1743 header[2] = 2; // 2 tags per edge
1744 fwrite(header, MMG5_SW, 3, inm);
1745 }
1746
1747 for (k=1; k<=mesh->na; ++k) {
1748 pa = &mesh->edge[k];
1749
1750 if ( !pa || !pa->a ) continue;
1751 ++nelts;
1752
1753 if(!bin)
1754 fprintf(inm,"%" MMG5_PRId " 1 2 %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "\n",nelts,pa->ref,pa->ref,
1755 mesh->point[pa->a].tmp,mesh->point[pa->b].tmp);
1756 else {
1757 fwrite(&nelts,MMG5_SW,1,inm);
1758 fwrite(&pa->ref,MMG5_SW,1,inm);
1759 fwrite(&pa->ref,MMG5_SW,1,inm);
1760 fwrite(&mesh->point[pa->a].tmp,MMG5_SW,1,inm);
1761 fwrite(&mesh->point[pa->b].tmp,MMG5_SW,1,inm);
1762 }
1763 }
1764
1765 /* Triangles */
1766 if ( bin && nt ) {
1767 header[0] = 2;// Tria keyword
1768 header[1] = nt;
1769 header[2] = 2; // 2 tags per tria
1770 fwrite(header, MMG5_SW, 3, inm);
1771 }
1772
1773 for (k=1; k<=mesh->nt; ++k) {
1774 ptt = &mesh->tria[k];
1775
1776 if ( !MG_EOK(ptt) ) continue;
1777 ++nelts;
1778
1779 if(!bin)
1780 fprintf(inm,"%" MMG5_PRId " 2 2 %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "\n",nelts,ptt->ref,ptt->ref,
1781 mesh->point[ptt->v[0]].tmp,mesh->point[ptt->v[1]].tmp,
1782 mesh->point[ptt->v[2]].tmp);
1783 else {
1784 fwrite(&nelts,MMG5_SW,1,inm);
1785 fwrite(&ptt->ref,MMG5_SW,1,inm);
1786 fwrite(&ptt->ref,MMG5_SW,1,inm);
1787 fwrite(&mesh->point[ptt->v[0]].tmp,MMG5_SW,1,inm);
1788 fwrite(&mesh->point[ptt->v[1]].tmp,MMG5_SW,1,inm);
1789 fwrite(&mesh->point[ptt->v[2]].tmp,MMG5_SW,1,inm);
1790 }
1791 }
1792
1793 /* Quads */
1794 if ( bin && nq ) {
1795 header[0] = 3;// Quad keyword
1796 header[1] = nq;
1797 header[2] = 2; // 2 tags per quad
1798 fwrite(header, MMG5_SW, 3, inm);
1799 }
1800
1801 for (k=1; k<=mesh->nquad; ++k) {
1802 pq = &mesh->quadra[k];
1803 if ( !MG_EOK(pq) ) continue;
1804 ++nelts;
1805
1806 if(!bin)
1807 fprintf(inm,"%" MMG5_PRId " 3 2 %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "\n",nelts,pq->ref,pq->ref,
1808 mesh->point[pq->v[0]].tmp,mesh->point[pq->v[1]].tmp,
1809 mesh->point[pq->v[2]].tmp,mesh->point[pq->v[3]].tmp);
1810 else {
1811 fwrite(&nelts,MMG5_SW,1,inm);
1812 fwrite(&pq->ref,MMG5_SW,1,inm);
1813 fwrite(&pq->ref,MMG5_SW,1,inm);
1814 fwrite(&mesh->point[pq->v[0]].tmp,MMG5_SW,1,inm);
1815 fwrite(&mesh->point[pq->v[1]].tmp,MMG5_SW,1,inm);
1816 fwrite(&mesh->point[pq->v[2]].tmp,MMG5_SW,1,inm);
1817 fwrite(&mesh->point[pq->v[3]].tmp,MMG5_SW,1,inm);
1818 }
1819 }
1820
1821 /* Tetra */
1822 if ( bin && ne ) {
1823 header[0] = 4;// Tetra keyword
1824 header[1] = ne;
1825 header[2] = 2; // 2 tags per quad
1826 fwrite(header, MMG5_SW, 3, inm);
1827 }
1828
1829 for (k=1; k<=mesh->ne; ++k) {
1830 pt = &mesh->tetra[k];
1831 if ( !MG_EOK(pt) ) continue;
1832 ++nelts;
1833
1834 if(!bin)
1835 fprintf(inm,"%" MMG5_PRId " 4 2 %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "\n",nelts,pt->ref,pt->ref,
1836 mesh->point[pt->v[0]].tmp,mesh->point[pt->v[1]].tmp,
1837 mesh->point[pt->v[2]].tmp,mesh->point[pt->v[3]].tmp);
1838 else {
1839 fwrite(&nelts,MMG5_SW,1,inm);
1840 fwrite(&pt->ref,MMG5_SW,1,inm);
1841 fwrite(&pt->ref,MMG5_SW,1,inm);
1842 fwrite(&mesh->point[pt->v[0]].tmp,MMG5_SW,1,inm);
1843 fwrite(&mesh->point[pt->v[1]].tmp,MMG5_SW,1,inm);
1844 fwrite(&mesh->point[pt->v[2]].tmp,MMG5_SW,1,inm);
1845 fwrite(&mesh->point[pt->v[3]].tmp,MMG5_SW,1,inm);
1846 }
1847 }
1848
1849 /* Prisms */
1850 if ( bin && npr ) {
1851 header[0] = 6;// Prism keyword
1852 header[1] = npr;
1853 header[2] = 2; // 2 tags per prism
1854 fwrite(header, MMG5_SW, 3, inm);
1855 }
1856
1857 for (k=1; k<=mesh->nprism; ++k) {
1858 pp = &mesh->prism[k];
1859 if ( !MG_EOK(pp) ) continue;
1860 ++nelts;
1861
1862 if(!bin)
1863 fprintf(inm,"%" MMG5_PRId " 6 2 %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "\n",nelts,pp->ref,pp->ref,
1864 mesh->point[pp->v[0]].tmp,mesh->point[pp->v[1]].tmp,
1865 mesh->point[pp->v[2]].tmp,mesh->point[pp->v[3]].tmp,
1866 mesh->point[pp->v[4]].tmp,mesh->point[pp->v[5]].tmp);
1867 else {
1868 fwrite(&nelts,MMG5_SW,1,inm);
1869 fwrite(&pp->ref,MMG5_SW,1,inm);
1870 fwrite(&pp->ref,MMG5_SW,1,inm);
1871 fwrite(&mesh->point[pp->v[0]].tmp,MMG5_SW,1,inm);
1872 fwrite(&mesh->point[pp->v[1]].tmp,MMG5_SW,1,inm);
1873 fwrite(&mesh->point[pp->v[2]].tmp,MMG5_SW,1,inm);
1874 fwrite(&mesh->point[pp->v[3]].tmp,MMG5_SW,1,inm);
1875 fwrite(&mesh->point[pp->v[4]].tmp,MMG5_SW,1,inm);
1876 fwrite(&mesh->point[pp->v[5]].tmp,MMG5_SW,1,inm);
1877 }
1878 }
1879 if ( bin ) fprintf(inm,"\n");
1880 fprintf(inm,"$EndElements\n");
1881
1882 /* stats */
1883 if ( abs(mesh->info.imprim) > 3 ) {
1884 fprintf(stdout," NUMBER OF VERTICES %8" MMG5_PRId "\n",np);
1885 fprintf(stdout," NUMBER OF TETRAHEDRA %8" MMG5_PRId "\n",ne);
1886 if ( npr )
1887 fprintf(stdout," NUMBER OF PRISMS %8" MMG5_PRId "\n",npr);
1888 if ( nt )
1889 fprintf(stdout," NUMBER OF TRIANGLES %8" MMG5_PRId "\n",nt);
1890 if ( nq )
1891 fprintf(stdout," NUMBER OF QUADRILATERALS %8" MMG5_PRId "\n",nq);
1892 if ( na ) {
1893 fprintf(stdout," NUMBER OF EDGES %8" MMG5_PRId "\n",na);
1894 }
1895
1896 }
1897
1899 if ( metricData==1 ) {
1900 if ( sol && *sol && sol[0]->np ) {
1901 nsols = 1;
1902 }
1903 else {
1904 /* In analysis mode (-noinsert -noswap -nomove), metric is not allocated */
1905 nsols = 0;
1906 }
1907 }
1908 else {
1909 nsols = mesh->nsols;
1910 }
1911
1912 for ( isol=0; isol<nsols; ++isol) {
1913 psl = *sol + isol;
1914
1915 if ( !psl ) {
1916 continue;
1917 }
1918
1919 if ( !psl->m ) {
1920 if ( !mmgWarn ) {
1921 mmgWarn = 1;
1922 fprintf(stderr, " ## Warning: %s: missing data for at least 1 solution."
1923 " Skipped.\n",__func__);
1924 }
1925 continue;
1926 }
1927
1928 fprintf(inm,"$NodeData\n");
1929
1930 /* One string tag saying the type of solution saved.
1931 Add the "metric" keyword if we save a metric */
1932 fprintf(inm,"1\n");
1933
1934 if ( psl->size == 1 ) {
1935 typ = 1;
1936 }
1937 else if ( psl->size == psl->dim ) {
1938 typ = 3;
1939 }
1940 else {
1941 typ = 9;
1942 }
1943
1944 if ( psl->namein ) {
1945 char *tmp = MMG5_Get_basename(psl->namein);
1946 if ( metricData ) {
1947 fprintf(inm,"\"%s:metric\"\n",tmp);
1948 }
1949 else {
1950 fprintf(inm,"\"%s\"\n",tmp);
1951 }
1952 free(tmp); tmp = 0;
1953 }
1954 else {
1955 if ( metricData ) {
1956 fprintf(inm,"\"solution:metric\"\n");
1957 }
1958 else {
1959 fprintf(inm,"\"solution\"\n");
1960 }
1961 }
1962
1963 /* One real tag unused */
1964 fprintf(inm,"1\n");
1965 fprintf(inm,"0.0\n"); // time value: unused
1966
1967 /* Three integer tags */
1968 fprintf(inm,"3\n");
1969 fprintf(inm,"0\n"); // Time step: unused
1970 fprintf(inm,"%d\n",typ);
1971 fprintf(inm,"%" MMG5_PRId "\n",np);
1972
1975 if ( psl->size!= (psl->dim*(psl->dim+1))/2 ) {
1976 for (k=1; k<=mesh->np; k++) {
1977 ppt = &mesh->point[k];
1978 if ( !MG_VOK(ppt) ) continue;
1979
1980 iadr = k*psl->size;
1981 if ( psl->dim == 2 )
1982 dbuf[2] = 0; // z-component for a vector field
1983
1984 for ( i=0; i<psl->size; ++i )
1985 dbuf[i] = psl->m[iadr+i];
1986
1987 if ( !bin ) {
1988 fprintf(inm,"%" MMG5_PRId "",ppt->tmp);
1989 for ( i=0; i<typ; ++i )
1990 fprintf(inm," %lg",dbuf[i]);
1991 fprintf(inm,"\n");
1992 }
1993 else {
1994 fwrite(&ppt->tmp,MMG5_SW,1,inm);
1995 fwrite(&dbuf,MMG5_SD,typ,inm);
1996 }
1997 }
1998 }
1999 else {
2000 for (k=1; k<=mesh->np; k++) {
2001 ppt = &mesh->point[k];
2002 if ( !MG_VOK(ppt) ) continue;
2003
2004 if ( psl->dim == 3 ) {
2005 if ( metricData ) {
2006 assert(!mesh->nsols);
2007 MMG5_build3DMetric(mesh,psl,k,dbuf);
2008 }
2009 else {
2010 for (i=0; i<psl->size; i++) dbuf[i] = psl->m[psl->size*k+i];
2011 }
2012 }
2013
2014 if(!bin) {
2015 fprintf(inm,"%" MMG5_PRId "",ppt->tmp);
2016 if ( psl->dim==2 ) {
2017 iadr = k*psl->size;
2018 fprintf(inm," %.15lg %.15lg %.15lg %.15lg %.15lg %.15lg"
2019 " %.15lg %.15lg %.15lg \n",
2020 psl->m[iadr],psl->m[iadr+1],0.,psl->m[iadr+1],psl->m[iadr+2],0.,0.,0.,1.);
2021 }
2022 else {
2023 fprintf(inm," %.15lg %.15lg %.15lg %.15lg %.15lg %.15lg"
2024 " %.15lg %.15lg %.15lg \n", dbuf[0],dbuf[1],dbuf[2],
2025 dbuf[1],dbuf[3],dbuf[4],dbuf[2],dbuf[4],dbuf[5]);
2026 }
2027 }
2028 else {
2029 fwrite(&ppt->tmp,MMG5_SW,1,inm);
2030 if ( psl->dim==2 ) {
2031 iadr = k*psl->size;
2032 fwrite(&psl->m[iadr],MMG5_SD,2,inm);
2033 dbuf[0] = dbuf[1] = dbuf[2] = 0.;
2034 dbuf[3] = 1.;
2035 fwrite(&dbuf,MMG5_SD,1,inm);
2036 fwrite(&psl->m[iadr+1],MMG5_SD,2,inm);
2037 fwrite(&dbuf,MMG5_SD,4,inm);
2038 }
2039 else {
2040 fwrite(&dbuf[0],MMG5_SD,3,inm);
2041 fwrite(&dbuf[1],MMG5_SD,1,inm);
2042 fwrite(&dbuf[3],MMG5_SD,2,inm);
2043 fwrite(&dbuf[2],MMG5_SD,1,inm);
2044 fwrite(&dbuf[4],MMG5_SD,2,inm);
2045 }
2046 }
2047 }
2048 }
2049 if ( bin ) fprintf(inm,"\n");
2050 fprintf(inm,"$EndNodeData\n");
2051 }
2052 fclose(inm);
2053
2054 return 1;
2055}
2056
2076int MMG5_loadSolHeader( const char *filename,int meshDim,FILE **inm,int *ver,
2077 int *bin,int *iswp,MMG5_int *np,int *dim,int *nsols,int **type,
2078 long *posnp, int imprim) {
2079 int binch,bdim;
2080 int bpos,i;
2081 char *ptr,*data,chaine[MMG5_FILESTR_LGTH];
2082
2083 *posnp = 0;
2084 *bin = 0;
2085 *iswp = 0;
2086 *ver = 0;
2087
2088 MMG5_SAFE_CALLOC(data,strlen(filename)+6,char,return -1);
2089 strcpy(data,filename);
2090
2091 /* Get last dot character to avoid issues with <basename>.mesh.mesh files */
2092 char *dot = strrchr(data,'.');
2093
2094 ptr = NULL;
2095 if ( dot) {
2096 ptr = strstr(dot,".mesh");
2097 }
2098 if ( ptr ) *ptr = '\0';
2099
2100 ptr = strstr(data,".sol");
2101
2102 if ( !ptr ) {
2103 /* data contains the filename without extension */
2104 strcat(data,".solb");
2105 if (!(*inm = fopen(data,"rb")) ) {
2106 /* our file is not a .solb file, try with .sol ext */
2107 ptr = strstr(data,".solb");
2108 *ptr = '\0';
2109 strcat(data,".sol");
2110 if (!(*inm = fopen(data,"rb")) ) {
2111 if ( imprim >= 0 )
2112 fprintf(stderr," ** %s NOT FOUND. USE DEFAULT METRIC.\n",data);
2113 MMG5_SAFE_FREE(data);
2114 return 0;
2115 }
2116 } else {
2117 *bin = 1;
2118 }
2119 }
2120 else {
2121 ptr = strstr(data,".solb");
2122 if ( ptr ) *bin = 1;
2123
2124 if (!(*inm = fopen(data,"rb")) ) {
2125 if ( imprim >= 0 )
2126 fprintf(stderr," ** %s NOT FOUND. USE DEFAULT METRIC.\n",data);
2127 MMG5_SAFE_FREE(data);
2128 return 0;
2129 }
2130 }
2131 if ( imprim >= 0 )
2132 fprintf(stdout," %%%% %s OPENED\n",data);
2133 MMG5_SAFE_FREE(data);
2134
2135 /* read solution or metric */
2136 if(!*bin) {
2137 strcpy(chaine,"DDD");
2138 while(fscanf(*inm,"%127s",&chaine[0])!=EOF && strncmp(chaine,"End",strlen("End")) ) {
2139 if(!strncmp(chaine,"Dimension",strlen("Dimension"))) {
2140 MMG_FSCANF(*inm,"%d",dim);
2141 if ( *dim!=meshDim ) {
2142 fprintf(stderr,"BAD SOL DIMENSION: %d\n",*dim);
2143 fclose(*inm);
2144 return -1;
2145 }
2146 continue;
2147 } else if(!strncmp(chaine,"SolAtVertices",strlen("SolAtVertices"))) {
2148 MMG_FSCANF(*inm,"%" MMG5_PRId "",np);
2149 MMG_FSCANF(*inm,"%d",nsols);
2150 MMG5_SAFE_CALLOC(*type,*nsols,int,return -1);
2151 for ( i=0; i<*nsols; ++i ) {
2152 MMG_FSCANF(*inm,"%d",&((*type)[i]));
2153 }
2154 *posnp = ftell(*inm);
2155 break;
2156 }
2157 }
2158 } else {
2159 MMG_FREAD(&binch,MMG5_SW,1,*inm);
2160 if(binch==16777216) (*iswp)=1;
2161 else if(binch!=1) {
2162 fprintf(stdout,"BAD FILE ENCODING\n");
2163 fclose(*inm);
2164 return -1;
2165 }
2166 MMG_FREAD(ver,MMG5_SW,1,*inm);
2167 if ( *iswp ) *ver = MMG5_swapbin(*ver);
2168 while(fread(&binch,MMG5_SW,1,*inm)!=EOF && binch!=54 ) {
2169 if ( *iswp ) binch=MMG5_swapbin(binch);
2170 if(binch==54) break;
2171 if(binch==3) { //Dimension
2172 MMG_FREAD(&bdim,MMG5_SW,1,*inm); //NulPos=>20
2173 if ( *iswp ) bdim=MMG5_swapbin(bdim);
2174 MMG_FREAD(dim,MMG5_SW,1,*inm);
2175 if ( *iswp ) *dim=MMG5_swapbin(*dim);
2176 if ( *dim!=meshDim ) {
2177 fprintf(stderr,"BAD SOL DIMENSION: %d\n",*dim);
2178 printf(" Exit program.\n");
2179 fclose(*inm);
2180 return -1;
2181 }
2182 continue;
2183 } else if(binch==62) { //SolAtVertices
2184 MMG_FREAD(&binch,MMG5_SW,1,*inm); //Pos
2185 if ( *iswp ) binch=MMG5_swapbin(binch);
2186 MMG_FREAD(np,MMG5_SW,1,*inm);
2187 if ( *iswp ) *np=MMG5_swapbin(*np);
2188 MMG_FREAD(nsols,MMG5_SW,1,*inm); //nb sol
2189 if ( *iswp ) *nsols =MMG5_swapbin(*nsols);
2190
2191 MMG5_SAFE_CALLOC(*type,*nsols,int,return -1); //typSol
2192 for ( i=0; i<*nsols; ++i ) {
2193 MMG_FREAD(&((*type)[i]),MMG5_SW,1,*inm);
2194 if ( *iswp ) (*type)[i]=MMG5_swapbin((*type)[i]);
2195 }
2196 *posnp = ftell(*inm);
2197 break;
2198 } else {
2199 MMG_FREAD(&bpos,MMG5_SW,1,*inm); //Pos
2200 if ( *iswp ) bpos=MMG5_swapbin(bpos);
2201 rewind(*inm);
2202 fseek(*inm,bpos,SEEK_SET);
2203 }
2204 }
2205 }
2206
2207 return 1;
2208}
2209
2222int MMG5_readFloatSol3D(MMG5_pSol sol,FILE *inm,int bin,int iswp,int pos) {
2223 float fbuf[6],tmpf;
2224 int i;
2225
2226 switch ( sol->size ) {
2227 case 1: case 3:
2228 /* scalar or vector solution */
2229 for (i=0; i<sol->size; i++) {
2230 if(!bin){
2231 MMG_FSCANF(inm,"%f",&fbuf[0]);
2232 } else {
2233 MMG_FREAD(&fbuf[0],MMG5_SW,1,inm);
2234 if(iswp) fbuf[0]=MMG5_swapf(fbuf[0]);
2235 }
2236 sol->m[sol->size*pos+i] = fbuf[0];
2237 }
2238 break;
2239 case 6 :
2240 /* Tensor solution */
2241 if(!bin){
2242 for(i=0 ; i<sol->size ; i++)
2243 MMG_FSCANF(inm,"%f",&fbuf[i]);
2244 } else {
2245 for(i=0 ; i<sol->size ; i++) {
2246 MMG_FREAD(&fbuf[i],MMG5_SW,1,inm);
2247 if(iswp) fbuf[i]=MMG5_swapf(fbuf[i]);
2248 }
2249 }
2250 tmpf = fbuf[2];
2251 fbuf[2] = fbuf[3];
2252 fbuf[3] = tmpf;
2253 for (i=0; i<6; i++) sol->m[6*pos+i] = fbuf[i];
2254 break;
2255 }
2256 return 1;
2257}
2258
2271int MMG5_readDoubleSol3D(MMG5_pSol sol,FILE *inm,int bin,int iswp,MMG5_int pos) {
2272 double dbuf[6],tmpd;
2273 int i;
2274
2275 switch ( sol->size ) {
2276 case 1: case 3:
2277 /* scalar or vector solution */
2278 for (i=0; i<sol->size; i++) {
2279 if(!bin){
2280 MMG_FSCANF(inm,"%lf",&dbuf[i]);
2281 } else {
2282 MMG_FREAD(&dbuf[i],MMG5_SD,1,inm);
2283 if(iswp) dbuf[i]=MMG5_swapd(dbuf[i]);
2284 }
2285 sol->m[sol->size*pos+i] = dbuf[i];
2286 }
2287 break;
2288
2289 case 6 :
2290 /* tensor solution */
2291 if(!bin){
2292 for(i=0 ; i<sol->size ; i++)
2293 MMG_FSCANF(inm,"%lf",&dbuf[i]);
2294 } else {
2295 for(i=0 ; i<sol->size ; i++) {
2296 MMG_FREAD(&dbuf[i],MMG5_SD,1,inm);
2297 if(iswp) dbuf[i]=MMG5_swapd(dbuf[i]);
2298 }
2299 }
2300 tmpd = dbuf[2];
2301 dbuf[2] = dbuf[3];
2302 dbuf[3] = tmpd;
2303 for (i=0; i<sol->size; i++) sol->m[6*pos+i] = dbuf[i];
2304 break;
2305 }
2306 return 1;
2307}
2308
2321 MMG5_int pos,int metricData) {
2322 double dbuf[6],tmp;
2323 int i;
2324
2325 switch ( sol->size ) {
2326 case 1: case 3:
2327 /* scalar or vector solution */
2328 for (i=0; i<sol->size; i++) {
2329 for (i=0; i<sol->size; i++) dbuf[i] = sol->m[sol->size*pos+i];
2330 if(!bin){
2331 for (i=0; i<sol->size; i++)
2332 fprintf(inm," %.15lg",dbuf[i]);
2333 } else {
2334 for(i=0; i<sol->size; i++)
2335 fwrite((unsigned char*)&dbuf[i],MMG5_SD,1,inm);
2336 }
2337 }
2338 break;
2339
2340 case 6 :
2341 /* tensor solution */
2342 if ( metricData )
2343 {
2344 MMG5_build3DMetric(mesh,sol,pos,dbuf);
2345 }
2346 else
2347 {
2348 for (i=0; i<sol->size; i++)
2349 {
2350 dbuf[i] = sol->m[6*pos+i];
2351 }
2352 }
2353
2354 tmp = dbuf[2];
2355 dbuf[2] = dbuf[3];
2356 dbuf[3] = tmp;
2357
2358 if(!bin) {
2359 for(i=0; i<sol->size; i++)
2360 fprintf(inm," %.15lg",dbuf[i]);
2361 } else {
2362 for(i=0; i<sol->size; i++)
2363 fwrite((unsigned char*)&dbuf[i],MMG5_SD,1,inm);
2364 }
2365 break;
2366 }
2367}
2368
2390 FILE **inm,int ver,int *bin,MMG5_int *bpos,MMG5_int np,int dim,
2391 int nsols,int *entities,int *type,int *size) {
2392 MMG5_pPoint ppt;
2393 int binch;
2394 MMG5_int k;
2395 char *ptr,*data,chaine[MMG5_FILESTR_LGTH];
2396
2397 *bin = 0;
2398
2399 MMG5_SAFE_CALLOC(data,strlen(filename)+6,char,return 0);
2400 strcpy(data,filename);
2401 ptr = strstr(data,".sol");
2402 if ( ptr ) {
2403 // filename contains the solution extension
2404 ptr = strstr(data,".solb");
2405
2406 if ( ptr ) *bin = 1;
2407
2408 if( !(*inm = fopen(data,"wb")) ) {
2409 fprintf(stderr," ** UNABLE TO OPEN %s.\n",data);
2410 MMG5_SAFE_FREE(data);
2411 return 0;
2412 }
2413 }
2414 else
2415 {
2416 // filename don't contains the solution extension
2417 ptr = strstr(data,".mesh");
2418 if ( ptr ) *ptr = '\0';
2419
2420 strcat(data,".sol");
2421 if (!(*inm = fopen(data,"wb")) ) {
2422 ptr = strstr(data,".solb");
2423 *ptr = '\0';
2424 strcat(data,".sol");
2425 if (!(*inm = fopen(data,"wb")) ) {
2426 fprintf(stderr," ** UNABLE TO OPEN %s.\n",data);
2427 MMG5_SAFE_FREE(data);
2428 return 0;
2429 }
2430 else *bin = 1;
2431 }
2432 }
2433
2434 if ( mesh->info.imprim >= 0 )
2435 fprintf(stdout," %%%% %s OPENED\n",data);
2436 MMG5_SAFE_FREE(data);
2437
2438 /*entete fichier*/
2439 binch=(*bpos)=0;
2440 if(!*bin) {
2441 strcpy(&chaine[0],"MeshVersionFormatted\n");
2442 fprintf(*inm,"%s %d",chaine,ver);
2443 strcpy(&chaine[0],"\n\nDimension\n");
2444 fprintf(*inm,"%s %d",chaine,dim);
2445 } else {
2446 binch = 1; //MeshVersionFormatted
2447 fwrite(&binch,MMG5_SW,1,*inm);
2448 binch = ver; //version
2449 fwrite(&binch,MMG5_SW,1,*inm);
2450 binch = 3; //Dimension
2451 fwrite(&binch,MMG5_SW,1,*inm);
2452 (*bpos) = 20; //Pos
2453 fwrite(bpos,MMG5_SW,1,*inm);
2454 binch = dim;
2455 fwrite(&binch,MMG5_SW,1,*inm);
2456 }
2457
2458 np = 0;
2459 for (k=1; k<=mesh->np; k++) {
2460 ppt = &mesh->point[k];
2461 if ( MG_VOK(ppt) ) np++;
2462 }
2463
2464 /* Count the number of solutions at vertices */
2465 int npointSols = 0;
2466 for (k=0; k<nsols; ++k ) {
2467 if ( (entities[k]==MMG5_Noentity) || (entities[k]==MMG5_Vertex) ) {
2468 ++npointSols;
2469 }
2470 }
2471
2472 /* Sol at vertices header */
2473 if(!*bin) {
2474 strcpy(&chaine[0],"\n\nSolAtVertices\n");
2475 fprintf(*inm,"%s",chaine);
2476 fprintf(*inm,"%" MMG5_PRId "\n",np);
2477 fprintf(*inm,"%d",npointSols);
2478 for (k=0; k<nsols; ++k ) {
2479 if ( (entities[k]!=MMG5_Noentity) && (entities[k]!=MMG5_Vertex) ) {
2480 continue;
2481 }
2482 fprintf(*inm," %d",type[k]);
2483 }
2484 fprintf(*inm,"\n");
2485 } else {
2486 binch = 62; //Vertices
2487 fwrite(&binch,MMG5_SW,1,*inm);
2488 (*bpos) += 16;
2489
2490 for (k=0; k<nsols; ++k ) {
2491 if ( (entities[k]!=MMG5_Noentity) && (entities[k]!=MMG5_Vertex) ) {
2492 continue;
2493 }
2494 (*bpos) += 4 + (size[k]*ver)*4*np; //Pos
2495 }
2496 fwrite(bpos,MMG5_SW,1,*inm);
2497
2498 fwrite(&np,MMG5_SW,1,*inm);
2499 fwrite(&npointSols,MMG5_SW,1,*inm);
2500 for (k=0; k<nsols; ++k ) {
2501 if ( (entities[k]!=MMG5_Noentity) && (entities[k]!=MMG5_Vertex) ) {
2502 continue;
2503 }
2504 fwrite(&type[k],MMG5_SW,1,*inm);
2505 }
2506 }
2507
2508 return 1;
2509}
2510
2527 FILE *inm,int ver,int bin,MMG5_int *bpos,
2528 int nsols,int nsolsAtTriangles,
2529 int *entities,int *type,int *size) {
2530 MMG5_pTria pt;
2531 int binch;
2532 MMG5_int k,nt;
2533
2534 nt = 0;
2535 for (k=1; k<=mesh->nt; k++) {
2536 pt = &mesh->tria[k];
2537 if ( MG_EOK(pt) ) {
2538 ++nt;
2539 }
2540 }
2541
2542 /* Sol at vertices header */
2543 if(!bin) {
2544 fprintf(inm,"\n\nSolAtTriangles\n");
2545 fprintf(inm,"%" MMG5_PRId "\n",nt);
2546 fprintf(inm,"%d",nsolsAtTriangles);
2547 for (k=0; k<nsols; ++k ) {
2548 if ( entities[k]!=MMG5_Triangle ) {
2549 continue;
2550 }
2551 fprintf(inm," %d",type[k]);
2552 }
2553 fprintf(inm,"\n");
2554 } else {
2555 binch = 64; //SolsAtTriangles
2556 fwrite(&binch,MMG5_SW,1,inm);
2557 (*bpos) += 16;
2558
2559 for (k=0; k<nsols; ++k ) {
2560 if ( entities[k]!=MMG5_Triangle ) {
2561 continue;
2562 }
2563 (*bpos) += 4 + (size[k]*ver)*4*nt; //Pos
2564 }
2565 fwrite(bpos,MMG5_SW,1,inm);
2566
2567 fwrite(&nt,MMG5_SW,1,inm);
2568 fwrite(&nsolsAtTriangles,MMG5_SW,1,inm);
2569 for (k=0; k<nsols; ++k ) {
2570 if ( entities[k]!=MMG5_Triangle ) {
2571 continue;
2572 }
2573 fwrite(&type[k],MMG5_SW,1,inm);
2574 }
2575 }
2576
2577 return 1;
2578}
2579
2596 FILE *inm,int ver,int bin,MMG5_int *bpos,
2597 int nsols,int nsolsAtTetra,
2598 int *entities,int *type,int *size) {
2599 MMG5_pTetra pt;
2600 int binch;
2601 MMG5_int k,ne;
2602
2603 ne = 0;
2604 for (k=1; k<=mesh->ne; k++) {
2605 pt = &mesh->tetra[k];
2606 if ( MG_EOK(pt) ) {
2607 ++ne;
2608 }
2609 }
2610
2611 /* Sol at vertices header */
2612 if(!bin) {
2613 fprintf(inm,"\n\nSolAtTetrahedra\n");
2614 fprintf(inm,"%" MMG5_PRId "\n",ne);
2615 fprintf(inm,"%d",nsolsAtTetra);
2616 for (k=0; k<nsols; ++k ) {
2617 if ( entities[k]!=MMG5_Tetrahedron ) {
2618 continue;
2619 }
2620 fprintf(inm," %d",type[k]);
2621 }
2622 fprintf(inm,"\n");
2623 } else {
2624 binch = 66; //SolsAtTetrahedron
2625 fwrite(&binch,MMG5_SW,1,inm);
2626 (*bpos) += 16;
2627
2628 for (k=0; k<nsols; ++k ) {
2629 if ( entities[k]!=MMG5_Tetrahedron ) {
2630 continue;
2631 }
2632 (*bpos) += 4 + (size[k]*ver)*4*ne; //Pos
2633 }
2634 fwrite(bpos,MMG5_SW,1,inm);
2635
2636 fwrite(&ne,MMG5_SW,1,inm);
2637 fwrite(&nsolsAtTetra,MMG5_SW,1,inm);
2638 for (k=0; k<nsols; ++k ) {
2639 if ( entities[k]!=MMG5_Tetrahedron ) {
2640 continue;
2641 }
2642 fwrite(&type[k],MMG5_SW,1,inm);
2643 }
2644 }
2645
2646 return 1;
2647}
2648
2663int MMG5_chkMetricType(MMG5_pMesh mesh,int *type, int *entities, FILE *inm) {
2664
2665 /* Metric can be provided only on vertices */
2666 if ( (*entities != MMG5_Vertex) && (*entities != MMG5_Noentity) ) {
2667 fprintf(stderr," ## Error: %s: Metric should apply on vertices.\n"
2668 " If your input file is at a non Medit"
2669 " file format, please ensure to remove non metric fields from your"
2670 " file and that the metric field"
2671 " contains the \":metric\" string.\n",__FILE__);
2672 if ( inm ) fclose(inm);
2673 return -1;
2674 }
2675
2676 /* 1: scalar solution (isotropic metric or ls function,
2677 2: vector field (displacement in Lagrangian mode),
2678 3: anisotropic metric */
2679 if ( mesh->info.lag == -1 ) {
2680 if ( type[0]!=1 && type[0]!=3) {
2681 fprintf(stderr," ** DATA TYPE IGNORED %d \n",type[0]);
2682 fprintf(stderr," ## Error: %s: if your input file is at a non Medit"
2683 " file format, please ensure that the metric field"
2684 " contains the \":metric\" string.\n",__FILE__);
2685 if ( inm ) fclose(inm);
2686 return -1;
2687 }
2688 }
2689 else {
2690 if ( type[0] != 2 ) {
2691 fprintf(stderr," ** MISMATCH DATA TYPE FOR LAGRANGIAN MODE %d \n",
2692 type[0]);
2693 if ( inm ) fclose(inm);
2694 return -1;
2695 }
2696 }
2697 return 1;
2698}
2699
2708 if ( abs(mesh->info.imprim) > 3 ) {
2709 if ( met->size == 1 )
2710 fprintf(stdout," NUMBER OF SCALAR VALUES %8" MMG5_PRId "\n",met->np);
2711 else if ( met->size == 3 )
2712 fprintf(stdout," NUMBER OF VECTOR VALUES %8" MMG5_PRId "\n",met->np);
2713 else
2714 fprintf(stdout," NUMBER OF TENSOR VALUES %8" MMG5_PRId "\n",met->np);
2715 }
2716}
2717
2726 int j;
2727
2728 if ( abs(mesh->info.imprim) > 3 ) {
2729 fprintf(stdout," NUMBER OF SOLUTIONS PER ENTITY %8d\n",mesh->nsols);
2730 fprintf(stdout," TYPE OF SOLUTIONS:\n ");
2731 for ( j=0; j<mesh->nsols; ++j ) {
2732 if ( (*sol)[j].size == 1 )
2733 fprintf(stdout," SCALAR");
2734 else if ( (*sol)[j].size == 3 )
2735 fprintf(stdout," VECTOR");
2736 else
2737 fprintf(stdout," TENSOR");
2738 }
2739 fprintf(stdout,"\n");
2740 }
2741}
2742
2744 FILE* inm;
2745 MMG5_pPoint ppt;
2746 int i;
2747 MMG5_int k,np;
2748 char *ptr,*data;
2749
2750 if ( !mesh->np ) {
2751 return 1;
2752 }
2753
2754 if ( (!filename) || !(*filename) ) {
2756 }
2757 if ( (!filename) || !(*filename) ) {
2758 printf("\n ## Error: %s: unable to save a file without a valid filename\n.",
2759 __func__);
2760 return 0;
2761 }
2762
2763 /* Name of file */
2764 MMG5_SAFE_CALLOC(data,strlen(filename)+7,char,return 0);
2765 strcpy(data,filename);
2766 ptr = strstr(data,".node");
2767 if ( ptr ) {
2768 *ptr = '\0';
2769 }
2770
2771 /* Add .node ext */
2772 strcat(data,".node");
2773 if( !(inm = fopen(data,"wb")) ) {
2774 fprintf(stderr," ** UNABLE TO OPEN %s.\n",data);
2775 MMG5_SAFE_FREE(data);
2776 return 0;
2777 }
2778
2779 fprintf(stdout," %%%% %s OPENED\n",data);
2780 MMG5_SAFE_FREE(data);
2781
2782 /* Write vertices */
2783 np = 0;
2784 for (k=1; k<=mesh->np; k++) {
2785 ppt = &mesh->point[k];
2786 if ( MG_VOK(ppt) ) {
2787 ++np;
2788 ppt->tmp = np;
2789 }
2790 }
2791
2792 /* Save node number, dim, no attributes, 1 bdy marker */
2793 fprintf(inm, "%" MMG5_PRId " %d %d %d\n\n",np,mesh->dim,0,1);
2794
2795 for ( k=1; k<=mesh->np; ++k ) {
2796 /* Save node idx */
2797 ppt = &mesh->point[k];
2798 if ( MG_VOK(ppt) ) {
2799 fprintf(inm, "%" MMG5_PRId " ",ppt->tmp);
2800
2801 /* Save coordinates */
2802 for ( i=0; i<mesh->dim; ++i ) {
2803 fprintf(inm, " %.15lf",ppt->c[i]);
2804 }
2805
2806 /* Save bdy marker */
2807 fprintf(inm, " %" MMG5_PRId "\n",ppt->ref);
2808 }
2809 }
2810
2811 fprintf(stdout," NUMBER OF VERTICES %8" MMG5_PRId "\n",np);
2812
2813 fclose(inm);
2814
2815 return 1;
2816}
2817
2818int MMG5_saveEdge(MMG5_pMesh mesh,const char *filename,const char *ext) {
2819 FILE* inm;
2820 MMG5_pEdge pt;
2821 size_t na_tot;
2822 int polyfile;
2823 MMG5_int k;
2824 char *ptr_c = (char*)mesh->edge;
2825 char *ptr,*data;
2826
2827 if ( !mesh->edge ) {
2828 return 1;
2829 }
2830 if ( !mesh->na ) {
2831 return 1;
2832 }
2833
2834 if ( (!filename) || !(*filename) ) {
2836 }
2837 if ( (!filename) || !(*filename) ) {
2838 printf("\n ## Error: %s: unable to save a file without a valid filename\n.",
2839 __func__);
2840 return 0;
2841 }
2842
2843 /* Name of file */
2844 MMG5_SAFE_CALLOC(data,strlen(filename)+strlen(ext),char,return 0);
2845 strcpy(data,filename);
2846 ptr = strstr(data,".node");
2847 if ( ptr ) {
2848 *ptr = '\0';
2849 }
2850
2851 /* Add file ext */
2852 strcat(data,ext);
2853 if( !(inm = fopen(data,"wb")) ) {
2854 fprintf(stderr," ** UNABLE TO OPEN %s.\n",data);
2855 MMG5_SAFE_FREE(data);
2856 return 0;
2857 }
2858
2859 fprintf(stdout," %%%% %s OPENED\n",data);
2860 MMG5_SAFE_FREE(data);
2861
2862 /* For .poly file, add header */
2863 if ( !strcmp(ext,".poly") ) {
2864 polyfile = 1;
2865 }
2866 else {
2867 polyfile = 0;
2868 }
2869
2870 if ( polyfile ) {
2871 /* Save 0 nodes (saved in a separated .node file), dim, 0 attributes, 1 bdy
2872 * marker */
2873 fprintf(inm, "0 %d 0 1\n",mesh->dim);
2874 }
2875
2876 /* Get either the number of boundary edges or the total number of edges
2877 * (depending if they have been append to the bdy edges, if yes, edges 1->na
2878 * are bdy, na->na_tot are internal. */
2879
2880 /* Get size of the array in octets */
2881 ptr_c = ptr_c-sizeof(size_t);
2882 na_tot = (*((size_t*)ptr_c));
2883 /* Recover number of edges allocated */
2884 na_tot /= sizeof(MMG5_Edge);
2885 /* Array is allocated at size na+1, recover na */
2886 --na_tot;
2887
2888 /* Save node number, dim, no attributes, 1 bdy marker */
2889 fprintf(inm, "%zu %d\n",na_tot,1);
2890
2891 for ( k=1; k<=na_tot; ++k ) {
2892 /* Save edge idx */
2893 fprintf(inm, "%" MMG5_PRId " ",k);
2894
2895 pt = &mesh->edge[k];
2896
2897 /* Save connectivity */
2898 fprintf(inm,"%" MMG5_PRId " %" MMG5_PRId " %" MMG5_PRId "\n",mesh->point[pt->a].tmp,mesh->point[pt->b].tmp,pt->ref);
2899
2900 }
2901
2902 /* For .poly file, add last line: 0 holes */
2903 if ( polyfile ) {
2904 fprintf(inm, "0 \n");
2905 }
2906
2907 fprintf(stdout," NUMBER OF EDGES %8zu\n",na_tot);
2908
2909 fclose(inm);
2910
2911 return 1;
2912}
char * MMG5_Get_basename(char *path)
int MMG5_Set_inputSolName(MMG5_pMesh mesh, MMG5_pSol sol, const char *solin)
int ier
tmp[*strlen0]
MMG5_pMesh MMG5_pSol * sol
if(!ier) exit(EXIT_FAILURE)
MMG5_pMesh * mesh
MMG5_pMesh char * filename
int MMG5_readDoubleSol3D(MMG5_pSol sol, FILE *inm, int bin, int iswp, MMG5_int pos)
Definition: inout.c:2271
int MMG5_chkMetricType(MMG5_pMesh mesh, int *type, int *entities, FILE *inm)
Definition: inout.c:2663
void MMG5_build3DMetric(MMG5_pMesh mesh, MMG5_pSol sol, MMG5_int ip, double dbuf[6])
Definition: inout.c:1524
void MMG5_printSolStats(MMG5_pMesh mesh, MMG5_pSol *sol)
Definition: inout.c:2725
float MMG5_swapf(float sbin)
Definition: inout.c:80
int MMG5_check_readedMesh(MMG5_pMesh mesh, MMG5_int nref)
Definition: inout.c:526
static int MMG5_countBinaryElts(FILE **inm, const int nelts, const int iswp, int *np, int *na, int *nt, int *nq, int *ne, int *npr)
Definition: inout.c:127
int MMG5_saveSolAtTrianglesHeader(MMG5_pMesh mesh, FILE *inm, int ver, int bin, MMG5_int *bpos, int nsols, int nsolsAtTriangles, int *entities, int *type, int *size)
Definition: inout.c:2526
int MMG5_saveNode(MMG5_pMesh mesh, const char *filename)
Definition: inout.c:2743
int MMG5_saveEdge(MMG5_pMesh mesh, const char *filename, const char *ext)
Definition: inout.c:2818
int MMG5_saveSolHeader(MMG5_pMesh mesh, const char *filename, FILE **inm, int ver, int *bin, MMG5_int *bpos, MMG5_int np, int dim, int nsols, int *entities, int *type, int *size)
Definition: inout.c:2389
int MMG5_loadMshMesh_part1(MMG5_pMesh mesh, const char *filename, FILE **inm, long *posNodes, long *posElts, long **posNodeData, int *bin, int *iswp, MMG5_int *nelts, int *nsols)
Definition: inout.c:278
void MMG5_writeDoubleSol3D(MMG5_pMesh mesh, MMG5_pSol sol, FILE *inm, int bin, MMG5_int pos, int metricData)
Definition: inout.c:2320
MMG5_int MMG5_swapbin_int(MMG5_int sbin)
Definition: inout.c:61
int MMG5_saveSolAtTetrahedraHeader(MMG5_pMesh mesh, FILE *inm, int ver, int bin, MMG5_int *bpos, int nsols, int nsolsAtTetra, int *entities, int *type, int *size)
Definition: inout.c:2595
int MMG5_readFloatSol3D(MMG5_pSol sol, FILE *inm, int bin, int iswp, int pos)
Definition: inout.c:2222
double MMG5_swapd(double sbin)
Definition: inout.c:97
int MMG5_loadMshMesh_part2(MMG5_pMesh mesh, MMG5_pSol *sol, FILE **inm, const long posNodes, const long posElts, const long *posNodeData, const int bin, const int iswp, const MMG5_int nelts, const int nsols)
Definition: inout.c:664
int MMG5_saveMshMesh(MMG5_pMesh mesh, MMG5_pSol *sol, const char *filename, int metricData)
Definition: inout.c:1583
void MMG5_printMetStats(MMG5_pMesh mesh, MMG5_pSol met)
Definition: inout.c:2707
int MMG5_loadSolHeader(const char *filename, int meshDim, FILE **inm, int *ver, int *bin, int *iswp, MMG5_int *np, int *dim, int *nsols, int **type, long *posnp, int imprim)
Definition: inout.c:2076
int MMG5_swapbin(int sbin)
Definition: inout.c:42
@ MMG5_Noentity
Definition: libmmgtypes.h:229
@ MMG5_Vertex
Definition: libmmgtypes.h:230
@ MMG5_Tetrahedron
Definition: libmmgtypes.h:233
@ MMG5_Triangle
Definition: libmmgtypes.h:232
#define MG_GEO
#define MMG5_SAFE_CALLOC(ptr, size, type, law)
double MMG2D_quickarea(double a[2], double b[2], double c[2])
Definition: tools.c:971
#define MG_EOK(pt)
#define MG_NUL
#define MMG5_SD
#define MMG5_ADD_MEM(mesh, size, message, law)
#define MG_SIN(tag)
#define MMG_FREAD(ptr, size, count, stream)
#define MMG5_SW
#define MG_VOK(ppt)
double MMG5_orvol(MMG5_pPoint point, MMG5_int *v)
Definition: tools.c:951
#define MG_NOSURF
#define MG_NOM
#define MMG5_FILESTR_LGTH
#define MG_REF
#define MMG5_SAFE_FREE(ptr)
#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 am MMG mesh.
Definition: libmmgtypes.h:311
MMG5_int b
Definition: libmmgtypes.h:312
uint16_t tag
Definition: libmmgtypes.h:316
MMG5_int ref
Definition: libmmgtypes.h:313
MMG5_int a
Definition: libmmgtypes.h:312
int8_t iso
Definition: libmmgtypes.h:541
MMG5_int isoref
Definition: libmmgtypes.h:528
uint8_t metRidTyp
Definition: libmmgtypes.h:554
int8_t lag
Definition: libmmgtypes.h:547
MMG mesh structure.
Definition: libmmgtypes.h:613
MMG5_pQuad quadra
Definition: libmmgtypes.h:656
MMG5_Info info
Definition: libmmgtypes.h:659
MMG5_int xt
Definition: libmmgtypes.h:628
MMG5_int ne
Definition: libmmgtypes.h:620
MMG5_pPoint point
Definition: libmmgtypes.h:649
char * nameout
Definition: libmmgtypes.h:661
MMG5_pPrism prism
Definition: libmmgtypes.h:653
MMG5_int nquad
Definition: libmmgtypes.h:621
MMG5_int npmax
Definition: libmmgtypes.h:620
MMG5_pxPoint xpoint
Definition: libmmgtypes.h:650
MMG5_int xp
Definition: libmmgtypes.h:628
MMG5_int nei
Definition: libmmgtypes.h:620
MMG5_pTetra tetra
Definition: libmmgtypes.h:651
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 nti
Definition: libmmgtypes.h:620
MMG5_int npi
Definition: libmmgtypes.h:620
MMG5_int nai
Definition: libmmgtypes.h:620
MMG5_int nprism
Definition: libmmgtypes.h:621
MMG5_int na
Definition: libmmgtypes.h:620
Structure to store vertices of an MMG mesh.
Definition: libmmgtypes.h:276
double n[3]
Definition: libmmgtypes.h:278
MMG5_int tmp
Definition: libmmgtypes.h:286
double c[3]
Definition: libmmgtypes.h:277
uint16_t tag
Definition: libmmgtypes.h:290
MMG5_int xp
Definition: libmmgtypes.h:285
MMG5_int ref
Definition: libmmgtypes.h:284
Structure to store prsim of a MMG mesh.
Definition: libmmgtypes.h:469
MMG5_int v[6]
Definition: libmmgtypes.h:470
MMG5_int ref
Definition: libmmgtypes.h:471
Structure to store quadrangles of an MMG mesh.
Definition: libmmgtypes.h:372
MMG5_int ref
Definition: libmmgtypes.h:374
MMG5_int v[4]
Definition: libmmgtypes.h:373
MMG5_int npi
Definition: libmmgtypes.h:676
int entities
Definition: libmmgtypes.h:679
MMG5_int npmax
Definition: libmmgtypes.h:675
char * namein
Definition: libmmgtypes.h:682
double * m
Definition: libmmgtypes.h:680
MMG5_int np
Definition: libmmgtypes.h:674
Structure to store tetrahedra of an MMG mesh.
Definition: libmmgtypes.h:407
MMG5_int v[4]
Definition: libmmgtypes.h:409
MMG5_int ref
Definition: libmmgtypes.h:410
Structure to store triangles of a MMG mesh.
Definition: libmmgtypes.h:338
MMG5_int edg[3]
Definition: libmmgtypes.h:345
MMG5_int ref
Definition: libmmgtypes.h:341
MMG5_int v[3]
Definition: libmmgtypes.h:340
double n1[3]
Definition: libmmgtypes.h:301