xref: /phasta/M2N/src/new_interface.c (revision 1e99f302ca5103688ae35115c2fefb7cfa6714f1)
1 /* This file provides interface functions for 'partial ' random
2    access into the PHASTA input files
3 
4    Anil Karanam March 2001 */
5 
6 #include <stdio.h>
7 #include <string.h>
8 #include <ctype.h>
9 #include <stdlib.h>
10 #include <time.h>
11 #include <math.h>
12 #include <mpi.h>
13 #include "phastaIO.h"
14 #include <FCMangle.h>
15 #include "new_interfaceM2N.h"
16 
17 //MR CHANGE
18 #include "commonM2N_c.h"
19 //MR CHANGE END
20 
21 #ifdef intel
22 #include <winsock2.h>
23 #else
24 #include <unistd.h>
25 #include <strings.h>
26 #endif
27 
28 
29 void
30 Write_M2N(      int* pid,
31                 int* irankN,
32                 int* stepno,
33                 int* nshg,
34                 int* numVars,
35                 int* ndofybar,
36                 int* ndoferrors,
37                 double* array1,
38                 double* array2,
39                 double* array3,
40                 double* array4 ) {
41 
42     char fname[255];
43     char rfile[60];
44     char existingfile[30], linkfile[30];
45     int irstou;
46     int magic_number = 362436;
47     int* mptr = &magic_number;
48     double version=0.0;
49     int isize, nitems;
50     int iarray[10];
51     int nfiles;
52     int nfields;
53     int numparts;
54     int irank;
55     int nprocs;
56     MPI_Comm mpi_comm_local;
57     int ilocalrank;
58     int mustwrite;
59 
60 
61     irank = *pid;
62 
63     // Create the subcommunicator for myrank < irankN)
64     mustwrite = 0;
65     if (irank < *irankN) mustwrite = 1;
66     MPI_Comm_split(MPI_COMM_WORLD, mustwrite, irank, &mpi_comm_local);
67     MPI_Comm_rank(mpi_comm_local, &ilocalrank);
68 
69     if (irank < *irankN) { // Only these ranks write syncio files within mpi_comm_local
70       //  Retrieve and compute the parameters required for SyncIO
71       nfiles = outpar.nsynciofilesred; //We use the same number of files as for geombcRed
72       nfields = 4;
73       numparts = *irankN;
74       nprocs = *irankN;
75 
76       int nppf = numparts/nfiles;
77       int GPID;
78 
79       // Calculate number of parts each proc deal with and where it start and end ...
80       int nppp = numparts/nprocs;// nppp : Number of parts per proc ...
81       int startpart = irank * nppp +1;// Part id from which I (myrank) start ...
82       int endpart = startpart + nppp - 1;// Part id to which I (myrank) end ...
83 
84       int descriptor;
85       char filename[255],fieldtag_s[255];
86       bzero((void*)filename,255);
87       bzero((void*)fieldtag_s,255);
88 
89       sprintf(filename,"restartRedTmp-dat.%d.%d",*stepno,((int)(irank/(nprocs/nfiles))+1));
90       if (*pid==0) {
91         printf("Filename is %s \n",filename);
92       }
93 
94       initphmpiiosub(&nfields, &nppf, &nfiles, &f_descriptor, "write", mpi_comm_local);
95       openfile(filename, "write", &f_descriptor);
96 
97       // solution
98       int i;
99       for ( i = 0; i < nppp; i++) { //This loop is useful only if several parts per processor
100       // GPID : global part id, corresponds to rank ...
101         // e.g : (in this example)
102         // proc 0 : 1--4
103         // proc 1 : 5--8 ...
104         GPID = startpart + i;
105 
106         // Write solution field ...
107         sprintf(fieldtag_s,"solution@%d",GPID);
108 
109         isize = (*nshg)*(*numVars);
110         nitems = 3;
111         iarray[ 0 ] = (*nshg);
112         iarray[ 1 ] = (*numVars);
113         iarray[ 2 ] = (*stepno);
114         writeheader( &f_descriptor, fieldtag_s, (void*)iarray, &nitems, &isize, "double", phasta_iotype);
115         writedatablock( &f_descriptor, fieldtag_s, (void*)(array1), &isize, "double", phasta_iotype );
116       }
117 
118       // ybar
119       for ( i = 0; i < nppp; i++) { //This loop is useful only if several parts per processor
120       // GPID : global part id, corresponds to rank ...
121         // e.g : (in this example)
122         // proc 0 : 1--4
123         // proc 1 : 5--8 ...
124         GPID = startpart + i;
125 
126         // Write solution field ...
127         sprintf(fieldtag_s,"ybar@%d",GPID);
128 
129         isize = (*nshg)*(*ndofybar);
130         nitems = 3;
131         iarray[ 0 ] = (*nshg);
132         iarray[ 1 ] = (*ndofybar);
133         iarray[ 2 ] = (*stepno);
134         writeheader( &f_descriptor, fieldtag_s, (void*)iarray, &nitems, &isize, "double", phasta_iotype);
135         writedatablock( &f_descriptor, fieldtag_s, (void*)(array2), &isize, "double", phasta_iotype );
136       }
137 
138       // errors
139       for ( i = 0; i < nppp; i++) { //This loop is useful only if several parts per processor
140       // GPID : global part id, corresponds to rank ...
141         // e.g : (in this example)
142         // proc 0 : 1--4
143         // proc 1 : 5--8 ...
144         GPID = startpart + i;
145 
146         // Write solution field ...
147         sprintf(fieldtag_s,"errors@%d",GPID);
148 
149         isize = (*nshg)*(*ndoferrors);
150         nitems = 3;
151         iarray[ 0 ] = (*nshg);
152         iarray[ 1 ] = (*ndoferrors);
153         iarray[ 2 ] = (*stepno);
154         writeheader( &f_descriptor, fieldtag_s, (void*)iarray, &nitems, &isize, "double", phasta_iotype);
155         writedatablock( &f_descriptor, fieldtag_s, (void*)(array3), &isize, "double", phasta_iotype );
156       }
157 
158       // dwal
159       for ( i = 0; i < nppp; i++) { //This loop is useful only if several parts per processor
160       // GPID : global part id, corresponds to rank ...
161         // e.g : (in this example)
162         // proc 0 : 1--4
163         // proc 1 : 5--8 ...
164         GPID = startpart + i;
165 
166         // Write solution field ...
167         sprintf(fieldtag_s,"dwal@%d",GPID);
168 
169         isize = (*nshg)*1;
170         nitems = 3;
171         iarray[ 0 ] = (*nshg);
172         iarray[ 1 ] = 1;
173         iarray[ 2 ] = (*stepno);
174         writeheader( &f_descriptor, fieldtag_s, (void*)iarray, &nitems, &isize, "double", phasta_iotype);
175         writedatablock( &f_descriptor, fieldtag_s, (void*)(array4), &isize, "double", phasta_iotype );
176       }
177 
178       closefile(&f_descriptor, "write");
179       finalizephmpiio(&f_descriptor);
180 
181     }
182 
183     return;
184 }
185 
186 void
187 Write_M2N_SolOnly(     int* pid,
188                        int* irankN,
189                        int* stepno,
190                        int* nshg,
191                        int* numVars,
192                        double* array1 ) {
193 
194     char fname[255];
195     char rfile[60];
196     char existingfile[30], linkfile[30];
197     int irstou;
198     int magic_number = 362436;
199     int* mptr = &magic_number;
200     double version=0.0;
201     int isize, nitems;
202     int iarray[10];
203     int nfiles;
204     int nfields;
205     int numparts;
206     int irank;
207     int nprocs;
208     MPI_Comm mpi_comm_local;
209     int ilocalrank;
210     int mustwrite;
211 
212 
213     irank = *pid;
214 
215     // Create the subcommunicator for myrank < irankN)
216     mustwrite = 0;
217     if (irank < *irankN) mustwrite = 1;
218     MPI_Comm_split(MPI_COMM_WORLD, mustwrite, irank, &mpi_comm_local);
219     MPI_Comm_rank(mpi_comm_local, &ilocalrank);
220 
221     if (irank < *irankN) { // Only these ranks write syncio files within mpi_comm_local
222        //  Retrieve and compute the parameters required for SyncIO
223        nfiles = outpar.nsynciofilesred; //We use the same number of files as for geombcRed
224        nfields = outpar.nsynciofieldswriterestart;
225        numparts = *irankN;
226        nprocs = *irankN;
227 
228        int nppf = numparts/nfiles;
229        int GPID;
230 
231        // Calculate number of parts each proc deal with and where it start and end ...
232        int nppp = numparts/nprocs;// nppp : Number of parts per proc ...
233        int startpart = irank * nppp +1;// Part id from which I (myrank) start ...
234        int endpart = startpart + nppp - 1;// Part id to which I (myrank) end ...
235 
236        int descriptor;
237        char filename[255],fieldtag_s[255];
238        bzero((void*)filename,255);
239        bzero((void*)fieldtag_s,255);
240 
241        sprintf(filename,"restartRedTmp-dat.%d.%d",*stepno,((int)(irank/(nprocs/nfiles))+1));
242        if (*pid==0) {
243          printf("Filename is %s \n",filename);
244        }
245 
246        initphmpiiosub(&nfields, &nppf, &nfiles, &f_descriptor, "write", mpi_comm_local);
247        openfile(filename, "write", &f_descriptor);
248 
249        field_flag=0;
250 
251        // solution
252        int i;
253        for ( i = 0; i < nppp; i++) { //This loop is useful only if several parts per processor
254        // GPID : global part id, corresponds to rank ...
255          // e.g : (in this example)
256          // proc 0 : 1--4
257          // proc 1 : 5--8 ...
258          GPID = startpart + i;
259 
260          // Write solution field ...
261          sprintf(fieldtag_s,"solution@%d",GPID);
262 
263          isize = (*nshg)*(*numVars);
264          nitems = 3;
265          iarray[ 0 ] = (*nshg);
266          iarray[ 1 ] = (*numVars);
267          iarray[ 2 ] = (*stepno);
268          writeheader( &f_descriptor, fieldtag_s, (void*)iarray, &nitems, &isize, "double", phasta_iotype);
269          writedatablock( &f_descriptor, fieldtag_s, (void*)(array1), &isize, "double", phasta_iotype );
270        }
271        field_flag++;
272 
273        if (field_flag==nfields){
274          closefile(&f_descriptor, "write");
275          finalizephmpiio(&f_descriptor);
276          if (*pid==0) {
277            printf("\n");
278          }
279        }
280 
281     }
282 
283     return;
284 }
285 
286 void
287 Write_M2N_Field(  int* pid,
288                   int* irankN,
289                   char* filemode,
290                   char* fieldtag,
291                   int* tagsize,
292                   void* array,
293                   char* arraytype,
294                   int* nshg,
295                   int* numvars,
296                   int* stepno) {
297 
298     //printf("Rank is %d, field is %s, tagsize is %d, nshg is %d, numvars is %d\n",*pid,fieldtag,*tagsize,*nshg,*numvars);
299 
300 //     char rfile[32];
301     // assuming restart.sn.(pid+1)
302 //     sprintf(rfile,"restart.%d.%d",*stepno,*pid+1);
303 
304     char *fieldlabel = (char *)malloc((*tagsize+1)*sizeof(char));
305     strncpy(fieldlabel, fieldtag, *tagsize);
306     fieldlabel[*tagsize] = '\0';
307 
308     int irstou;
309     int magic_number = 362436;
310     int* mptr = &magic_number;
311     double version=0.0;
312     int isize, nitems;
313     int iarray[10];
314 
315     char fmode[10];
316     if(!strncmp(filemode,"w",1))
317       strcpy(fmode,"write");
318     else // default is append
319       strcpy(fmode,"append");
320 
321     char datatype[10];
322     if(!strncmp(arraytype,"i",1))
323       strcpy(datatype,"int");
324     else // default is double
325       strcpy(datatype,"double");
326 
327     /////////////////////////////// Start of writing using new-lib ////////////////////////////
328 
329     int nfiles;
330     int nfields;
331     int numparts;
332     int irank;
333     int nprocs;
334 
335     irank = *pid; //workfc.myrank;
336 
337     if (irank < *irankN) { // Only these ranks write syncio files within mpi_comm_local
338       //  Retrieve and compute the parameters required for SyncIO
339 
340       nfiles = outpar.nsynciofilesred;
341       nfields = outpar.nsynciofieldswriterestart;
342       numparts = workfc.numpe;
343       nprocs = workfc.numpe;
344 
345       int nppf = numparts/nfiles;
346       int GPID;
347 
348       // Calculate number of parts each  proc deal with and where it start and end ...
349       int nppp = numparts/nprocs;// nppp : Number of parts per proc ...
350       int startpart = irank * nppp +1;// Part id from which I (myrank) start ...
351       int endpart = startpart + nppp - 1;// Part id to which I (myrank) end ...
352 
353       char fieldtag_s[255];
354       bzero((void*)fieldtag_s,255);
355 
356       strncpy(fieldlabel, fieldtag, *tagsize);
357 
358       field_flag++;
359       if(*pid==0) {
360         printf("\n");
361         printf("The %d/%d th field to be written is '%s'\n",field_flag,nfields,fieldlabel);
362       }
363 
364       int i;
365       for ( i = 0; i < nppp; i++  ) {
366           GPID = startpart + i;
367 
368           // Write field ...
369           sprintf(fieldtag_s,"%s@%d",fieldlabel,GPID);
370 
371           isize = (*nshg)*(*numvars);
372           nitems = 3;
373           iarray[ 0 ] = (*nshg);
374           iarray[ 1 ] = (*numvars);
375           iarray[ 2 ] = (*stepno);
376           writeheader( &f_descriptor, fieldtag_s, (void*)iarray, &nitems, &isize, datatype, phasta_iotype);
377           writedatablock( &f_descriptor, fieldtag_s, array, &isize, datatype, phasta_iotype );
378       }
379 
380       if (field_flag==nfields){
381         closefile(&f_descriptor, "write");
382         finalizephmpiio(&f_descriptor);
383         if (*pid==0) {
384           printf("Last field %d '%s' finished! \n",nfields, fieldtag);
385           printf("\n");
386         }
387       }
388 
389       free(fieldlabel);
390     }
391 }
392 
393 void
394 Write_M2N_PhAvg2( int* pid,
395               int* irankN,
396               char* filemode,
397               char* fieldtag,
398               int* tagsize,
399               int* iphase,
400               int* nphasesincycle,
401               void* array,
402               char* arraytype,
403               int* nshg,
404               int* numvars,
405               int* stepno) {
406 
407     int addtagsize; // phase number is added to the name of the field
408     if(*iphase<10)
409       addtagsize=1;
410     else if(*iphase<100)
411       addtagsize=2;
412     else if(*iphase<1000)
413       addtagsize=3;
414 
415     int tagsize2;
416     tagsize2=*tagsize+addtagsize;
417 
418     char *fieldlabel = (char *)malloc((tagsize2+1)*sizeof(char));
419     strncpy(fieldlabel, fieldtag, *tagsize);
420     fieldlabel[tagsize2] = '\0';
421 
422     char straddtagsize[10];
423     sprintf(straddtagsize,"%d",*iphase);
424 
425     if(*iphase<10) {
426       fieldlabel[tagsize2-1]=straddtagsize[0];
427     }
428     else if(*iphase<100) {
429       fieldlabel[tagsize2-2]=straddtagsize[0];
430       fieldlabel[tagsize2-1]=straddtagsize[1];
431     }
432     else if(*iphase<1000) {
433       fieldlabel[tagsize2-3]=straddtagsize[0];
434       fieldlabel[tagsize2-2]=straddtagsize[1];
435       fieldlabel[tagsize2-1]=straddtagsize[2];
436     }
437 
438     int irstou;
439     int magic_number = 362436;
440     int* mptr = &magic_number;
441     double version=0.0;
442     int isize, nitems;
443     int iarray[10];
444 
445     char fmode[10];
446     if(!strncmp(filemode,"w",1))
447       strcpy(fmode,"write");
448     else // default is append
449       strcpy(fmode,"append");
450 
451     char datatype[10];
452     if(!strncmp(arraytype,"i",1))
453       strcpy(datatype,"int");
454     else // default is double
455       strcpy(datatype,"double");
456 
457     /////////////////////////////// Start of writing using new-lib ////////////////////////////
458 
459     int nfiles;
460     int nfields;
461     int numparts;
462     int irank;
463     int nprocs;
464 
465     irank = *pid; //workfc.myrank;
466     if (irank < *irankN) { // Only these ranks write syncio files within mpi_comm_local
467 
468        nfiles = outpar.nsynciofilesred;
469        nfields = outpar.nsynciofieldswriterestart;
470        numparts = workfc.numpe;
471        nprocs = workfc.numpe;
472 
473        int nppf = numparts/nfiles;
474        int GPID;
475 
476        // Calculate number of parts each  proc deal with and where it start and end ...
477        int nppp = numparts/nprocs;// nppp : Number of parts per proc ...
478        int startpart = irank * nppp +1;// Part id from which I (myrank) start ...
479        int endpart = startpart + nppp - 1;// Part id to which I (myrank) end ...
480 
481        char fieldtag_s[255];
482        bzero((void*)fieldtag_s,255);
483 
484        field_flag++;
485        if(*pid==0) {
486           printf("\n");
487           printf("The %d/%d th field to be written is '%s'\n",field_flag,nfields,fieldlabel);
488        }
489 
490        int i;
491        for ( i = 0; i < nppp; i++  ) {
492            GPID = startpart + i;
493 
494            // Write the field ...
495            sprintf(fieldtag_s,"%s@%d",fieldlabel,GPID);
496 
497            //printf("This is %d and fieldtag_s is %s \n",myrank,fieldtag_s);
498 
499            isize = (*nshg)*(*numvars);
500            nitems = 3;
501            iarray[ 0 ] = (*nshg);
502            iarray[ 1 ] = (*numvars);
503            iarray[ 2 ] = (*stepno);
504            writeheader( &f_descriptor, fieldtag_s, (void*)iarray, &nitems, &isize, "double", phasta_iotype);
505            writedatablock( &f_descriptor, fieldtag_s, array, &isize, "double", phasta_iotype );
506        }
507 
508        if (field_flag==nfields){
509          closefile(&f_descriptor, "write");
510          finalizephmpiio(&f_descriptor);
511          if (*pid==0) {
512            printf("\n");
513          }
514        }
515 
516        free(fieldlabel);
517     }
518 }
519 
520 void
521 Write_Restart(  int* pid,
522                 int* stepno,
523                 int* nshg,
524                 int* numVars,
525                 double* array1,
526                 double* array2 ) {
527 
528     char fname[255];
529     char rfile[60];
530     char existingfile[30], linkfile[30];
531     int irstou;
532     int magic_number = 362436;
533     int* mptr = &magic_number;
534     double version=0.0;
535     int isize, nitems;
536     int iarray[10];
537     int nfiles;
538     int nfields;
539     int numparts;
540     int irank;
541     int nprocs;
542 
543     //  First, count the number of fields to write and store the result in
544     //countfieldstowriterestart();
545 
546     //  Retrieve and compute the parameters required for SyncIO
547     nfiles = outpar.nsynciofiles;
548     nfields = outpar.nsynciofieldswriterestart;
549     numparts = workfc.numpe;
550     irank = *pid; //workfc.myrank;
551     nprocs = workfc.numpe;
552     int nppf = numparts/nfiles;
553     int GPID;
554 
555     // Calculate number of parts each proc deal with and where it start and end ...
556     int nppp = numparts/nprocs;// nppp : Number of parts per proc ...
557     int startpart = irank * nppp +1;// Part id from which I (myrank) start ...
558     int endpart = startpart + nppp - 1;// Part id to which I (myrank) end ...
559 
560     int descriptor;
561     char filename[255],fieldtag_s[255];
562     bzero((void*)filename,255);
563     bzero((void*)fieldtag_s,255);
564 
565     sprintf(filename,"restart-dat.%d.%d",*stepno,((int)(irank/(nprocs/nfiles))+1));
566 
567     initphmpiio(&nfields, &nppf, &nfiles, &f_descriptor, "write");
568 
569     if (*pid==0) {
570       printf("Filename is %s \n",filename);
571     }
572 
573     openfile(filename, "write", &f_descriptor);
574 
575     field_flag=0;
576 
577      int i;
578      for ( i = 0; i < nppp; i++) { //This loop is useful only if several parts per processor
579      // GPID : global part id, corresponds to rank ...
580         // e.g : (in this example)
581         // proc 0 : 1--4
582         // proc 1 : 5--8 ...
583         GPID = startpart + i;
584 
585         // Write solution field ...
586         sprintf(fieldtag_s,"solution@%d",GPID);
587 
588         isize = (*nshg)*(*numVars);
589         nitems = 3;
590         iarray[ 0 ] = (*nshg);
591         iarray[ 1 ] = (*numVars);
592         iarray[ 2 ] = (*stepno);
593         writeheader( &f_descriptor, fieldtag_s, (void*)iarray, &nitems, &isize, "double", phasta_iotype);
594         writedatablock( &f_descriptor, fieldtag_s, (void*)(array1), &isize, "double", phasta_iotype );
595      }
596      field_flag++;
597 
598      for ( i = 0; i < nppp; i++) {
599 
600         // GPID : global part id, corresponds to rank ...
601         // e.g : (in this example)
602         // proc 0 : 1--4
603         // proc 1 : 5--8 ...
604         GPID = startpart + i;
605 
606         // Write solution field ...
607         sprintf(fieldtag_s,"time derivative of solution@%d",GPID);
608 
609         isize = (*nshg)*(*numVars);
610         nitems = 3;
611         iarray[ 0 ] = (*nshg);
612         iarray[ 1 ] = (*numVars);
613         iarray[ 2 ] = (*stepno);
614         writeheader( &f_descriptor, fieldtag_s, (void*)iarray, &nitems, &isize, "double", phasta_iotype);
615         writedatablock( &f_descriptor, fieldtag_s, (void*)(array2), &isize, "double", phasta_iotype );
616      }
617      field_flag++;
618 
619      if (field_flag==nfields){
620        closefile(&f_descriptor, "write");
621        finalizephmpiio(&f_descriptor);
622        if (*pid==0) {
623          printf("\n");
624        }
625      }
626 }
627 
628 
629 void
630 Write_Error(  int* pid,
631               int* stepno,
632               int* nshg,
633               int* numVars,
634               double* array1 ) {
635 
636 
637     char fname[255];
638     char rfile[60];
639     int irstou;
640     int magic_number = 362436;
641     int* mptr = &magic_number;
642     double version=0.0;
643     int isize, nitems;
644     int iarray[10];
645 
646     /////////////////////////////// Start of writing using new-lib ////////////////////////////
647 
648     int nfiles;
649     int nfields;
650     int numparts;
651     int irank;
652     int nprocs;
653 
654     nfiles = outpar.nsynciofiles;
655     nfields = outpar.nsynciofieldswriterestart;
656     numparts = workfc.numpe;
657     irank = *pid; //workfc.myrank;
658     nprocs = workfc.numpe;
659 
660     int nppf = numparts/nfiles;
661     int GPID;
662 
663     // Calculate number of parts each  proc deal with and where it start and end ...
664     int nppp = numparts/nprocs;// nppp : Number of parts per proc ...
665     int startpart = irank * nppp +1;// Part id from which I (myrank) start ...
666     int endpart = startpart + nppp - 1;// Part id to which I (myrank) end ...
667 
668     field_flag++;
669 
670     char fieldtag[255];
671 
672     int i;
673     for ( i = 0; i < nppp; i++  ) {
674         GPID = startpart + i;
675         sprintf(fieldtag,"errors@%d",GPID);
676 
677         if(*pid==0) {
678           printf("\n");
679           printf("The %d/%d th field to be written is '%s'\n",field_flag,nfields,fieldtag);
680         }
681 
682         isize = (*nshg)*(*numVars);
683         nitems = 3;
684         iarray[ 0 ] = (*nshg);
685         iarray[ 1 ] = (*numVars);
686         iarray[ 2 ] = (*stepno);
687         writeheader( &f_descriptor, fieldtag, (void*)iarray, &nitems, &isize, "double", phasta_iotype);
688         writedatablock( &f_descriptor, fieldtag, (void*)array1, &isize, "double", phasta_iotype );
689     }
690 
691     if (field_flag==nfields){
692       closefile(&f_descriptor, "write");
693       finalizephmpiio(&f_descriptor);
694       if (*pid==0) {
695         printf("Last field %d '%s' finished! \n",nfields, fieldtag);
696         printf("\n");
697       }
698     }
699 
700 }
701 
702 void
703 Write_Displ(  int* pid,
704               int* stepno,
705               int* nshg,
706               int* numVars,
707               double* array1 ) { //TO BE UPDATED FOR SYNCIO
708 
709 
710     char fname[255];
711     char rfile[60];
712     int irstou;
713     int magic_number = 362436;
714     int* mptr = &magic_number;
715     time_t timenow = time ( &timenow);
716     double version=0.0;
717     int isize, nitems;
718     int iarray[10];
719 
720     sprintf(rfile,"restart.%d.%d",*stepno,*pid+1);
721     openfile(rfile,"append", &irstou);
722 
723     isize = (*nshg)*(*numVars);
724     nitems = 3;
725     iarray[ 0 ] = (*nshg);
726     iarray[ 1 ] = (*numVars);
727     iarray[ 2 ] = (*stepno);
728     writeheader( &irstou, "displacement", (void*)iarray, &nitems, &isize, "double", phasta_iotype );
729     writedatablock( &irstou, "displacement", (void*)(array1), &isize, "double", phasta_iotype );
730 
731     closefile( &irstou, "append" );
732 }
733 
734 void
735 Write_Field(  int *pid,
736               char* filemode,
737               char* fieldtag,
738               int* tagsize,
739               void* array,
740               char* arraytype,
741               int* nshg,
742               int* numvars,
743               int* stepno) {
744 
745     //printf("Rank is %d, field is %s, tagsize is %d, nshg is %d, numvars is %d\n",*pid,fieldtag,*tagsize,*nshg,*numvars);
746 
747     char *fieldlabel = (char *)malloc((*tagsize+1)*sizeof(char));
748     strncpy(fieldlabel, fieldtag, *tagsize);
749     fieldlabel[*tagsize] = '\0';
750 
751     int irstou;
752     int magic_number = 362436;
753     int* mptr = &magic_number;
754     double version=0.0;
755     int isize, nitems;
756     int iarray[10];
757 
758     char fmode[10];
759     if(!strncmp(filemode,"w",1))
760       strcpy(fmode,"write");
761     else // default is append
762       strcpy(fmode,"append");
763 
764     char datatype[10];
765     if(!strncmp(arraytype,"i",1))
766       strcpy(datatype,"int");
767     else // default is double
768       strcpy(datatype,"double");
769 
770 //   Old posix format
771 /*     openfile_(rfile, fmode, &irstou);
772 
773      nitems = 3; // assuming field will write 3 items in iarray
774      iarray[ 0 ] = (*nshg);
775      iarray[ 1 ] = (*numvars);
776      iarray[ 2 ] = (*stepno);
777 
778      isize = (*nshg)*(*numvars);
779      writeheader_( &irstou, fieldlabel, (void*)iarray, &nitems, &isize, datatype, phasta_iotype );
780 
781      nitems = (*nshg)*(*numvars);
782      writedatablock_( &irstou, fieldlabel, array, &nitems, datatype, phasta_iotype );
783      closefile_( &irstou, fmode);
784 */
785     /////////////////////////////// Start of writing using new-lib ////////////////////////////
786 
787     int nfiles;
788     int nfields;
789     int numparts;
790     int irank;
791     int nprocs;
792 
793 //    unsigned long long timer_start;
794 //    unsigned long long timer_end;
795 //    double time_span;
796 
797     nfiles = outpar.nsynciofiles;
798     nfields = outpar.nsynciofieldswriterestart;
799     numparts = workfc.numpe;
800     irank = *pid; //workfc.myrank;
801     nprocs = workfc.numpe;
802 
803     int nppf = numparts/nfiles;
804     int GPID;
805 
806     // Calculate number of parts each  proc deal with and where it start and end ...
807     int nppp = numparts/nprocs;// nppp : Number of parts per proc ...
808     int startpart = irank * nppp +1;// Part id from which I (myrank) start ...
809     int endpart = startpart + nppp - 1;// Part id to which I (myrank) end ...
810 
811     char fieldtag_s[255];
812     bzero((void*)fieldtag_s,255);
813 
814     strncpy(fieldlabel, fieldtag, *tagsize);
815 
816     field_flag++;
817     if(*pid==0) {
818       printf("\n");
819       printf("The %d/%d th field to be written is '%s'\n",field_flag,nfields,fieldlabel);
820     }
821 
822     int i;
823     for ( i = 0; i < nppp; i++  ) {
824         GPID = startpart + i;
825 
826         // Write solution field ...
827         sprintf(fieldtag_s,"%s@%d",fieldlabel,GPID);
828 
829         isize = (*nshg)*(*numvars);
830         nitems = 3;
831         iarray[ 0 ] = (*nshg);
832         iarray[ 1 ] = (*numvars);
833         iarray[ 2 ] = (*stepno);
834         writeheader( &f_descriptor, fieldtag_s, (void*)iarray, &nitems, &isize, datatype, phasta_iotype);
835         writedatablock( &f_descriptor, fieldtag_s, array, &isize, datatype, phasta_iotype );
836     }
837 
838     if (field_flag==nfields){
839       closefile(&f_descriptor, "write");
840       finalizephmpiio(&f_descriptor);
841       if (*pid==0) {
842         printf("Last field %d '%s' finished! \n",nfields, fieldtag);
843         printf("\n");
844       }
845     }
846 
847     free(fieldlabel);
848 }
849 
850 void
851 Write_PhAvg(  int* pid,
852               char* filemode,
853               char* fieldtag,
854               int* tagsize,
855               int* iphase,
856               void* array,
857               char* arraytype,
858               int* nshg,
859               int* numvars,
860               int* stepno) {
861 
862     char rfile[32];
863     // assuming restart_phase_avg_<sn>.<iphase>.<pid+1>
864     sprintf(rfile,"restart_phase_avg_%d.%d.%d",*stepno,*iphase,*pid+1);
865 
866     char *fieldlabel = (char *)malloc((*tagsize+1)*sizeof(char));
867     strncpy(fieldlabel, fieldtag, *tagsize);
868     fieldlabel[*tagsize] = '\0';
869 
870     int irstou;
871     int isize, nitems;
872     int iarray[10];
873 
874     char fmode[10];
875     if(!strncmp(filemode,"w",1))
876       strcpy(fmode,"write");
877     else // default is append
878       strcpy(fmode,"append");
879 
880     char datatype[10];
881     if(!strncmp(arraytype,"i",1))
882       strcpy(datatype,"int");
883     else // default is double
884       strcpy(datatype,"double");
885 
886     openfile(rfile, fmode, &irstou);
887 
888     if(!strcmp(fmode,"write")) {
889       // may be create a routine for 'top' portion under write mode
890       int magic_number = 362436;
891       int* mptr = &magic_number;
892       time_t timenow = time ( &timenow);
893       double version=0.0;
894 
895       /* writing the top ascii header for the restart file */
896 
897       writestring( &irstou,"# PHASTA Input File Version 2.0\n");
898       writestring( &irstou,
899                     "# format \"keyphrase : sizeofnextblock usual headers\"\n");
900 
901       char fname[255];
902       bzero( (void*)fname, 255 );
903       sprintf(fname,"# Output generated by phasta version (NOT YET CURRENT): %lf \n", version);
904       writestring( &irstou, fname );
905 
906       bzero( (void*)fname, 255 );
907       gethostname(fname,255);
908       writestring( &irstou,"# This result was produced on: ");
909       writestring( &irstou, fname );
910       writestring( &irstou,"\n");
911 
912       bzero( (void*)fname, 255 );
913       sprintf(fname,"# %s\n", ctime( &timenow ));
914       writestring( &irstou, fname );
915 
916       isize = 1;
917       nitems = 1;
918       iarray[ 0 ] = 1;
919       writeheader( &irstou, "byteorder magic number ",
920                     (void*)iarray, &nitems, &isize, "integer", phasta_iotype );
921       writedatablock( &irstou, "byteorder magic number ",
922                        (void*)mptr, &isize, "integer", phasta_iotype );
923     }
924 
925     isize = (*nshg)*(*numvars);
926     nitems = 3; // assuming field will write 3 items in iarray
927     iarray[ 0 ] = (*nshg);
928     iarray[ 1 ] = (*numvars);
929     iarray[ 2 ] = (*stepno);
930     writeheader( &irstou, fieldlabel, (void*)iarray, &nitems, &isize, datatype, phasta_iotype );
931     writedatablock( &irstou, fieldlabel, array, &isize, datatype, phasta_iotype );
932 
933     closefile( &irstou, fmode);
934 
935     free(fieldlabel);
936 }
937 
938 void
939 Write_PhAvg2( int* pid,
940               char* filemode,
941               char* fieldtag,
942               int* tagsize,
943               int* iphase,
944               int* nphasesincycle,
945               void* array,
946               char* arraytype,
947               int* nshg,
948               int* numvars,
949               int* stepno) {
950 
951     int addtagsize; // phase number is added to the name of the field
952     if(*iphase<10)
953       addtagsize=1;
954     else if(*iphase<100)
955       addtagsize=2;
956     else if(*iphase<1000)
957       addtagsize=3;
958 
959     int tagsize2;
960     tagsize2=*tagsize+addtagsize;
961 
962     char *fieldlabel = (char *)malloc((tagsize2+1)*sizeof(char));
963     strncpy(fieldlabel, fieldtag, *tagsize);
964     fieldlabel[tagsize2] = '\0';
965 
966     char straddtagsize[10];
967     sprintf(straddtagsize,"%d",*iphase);
968 
969     if(*iphase<10) {
970       fieldlabel[tagsize2-1]=straddtagsize[0];
971     }
972     else if(*iphase<100) {
973       fieldlabel[tagsize2-2]=straddtagsize[0];
974       fieldlabel[tagsize2-1]=straddtagsize[1];
975     }
976     else if(*iphase<1000) {
977       fieldlabel[tagsize2-3]=straddtagsize[0];
978       fieldlabel[tagsize2-2]=straddtagsize[1];
979       fieldlabel[tagsize2-1]=straddtagsize[2];
980     }
981 
982     int irstou;
983     int magic_number = 362436;
984     int* mptr = &magic_number;
985     double version=0.0;
986     int isize, nitems;
987     int iarray[10];
988 
989     char fmode[10];
990     if(!strncmp(filemode,"w",1))
991       strcpy(fmode,"write");
992     else // default is append
993       strcpy(fmode,"append");
994 
995     char datatype[10];
996     if(!strncmp(arraytype,"i",1))
997       strcpy(datatype,"int");
998     else // default is double
999       strcpy(datatype,"double");
1000 
1001     /////////////////////////////// Start of writing using new-lib ////////////////////////////
1002 
1003     int nfiles;
1004     int nfields;
1005     int numparts;
1006     int irank;
1007     int nprocs;
1008 
1009     nfiles = outpar.nsynciofiles;
1010     nfields = outpar.nsynciofieldswriterestart;
1011     numparts = workfc.numpe;
1012     irank = *pid; //workfc.myrank;
1013     nprocs = workfc.numpe;
1014 
1015     int nppf = numparts/nfiles;
1016     int GPID;
1017 
1018     // Calculate number of parts each  proc deal with and where it start and end ...
1019     int nppp = numparts/nprocs;// nppp : Number of parts per proc ...
1020     int startpart = irank * nppp +1;// Part id from which I (myrank) start ...
1021     int endpart = startpart + nppp - 1;// Part id to which I (myrank) end ...
1022 
1023     char fieldtag_s[255];
1024     bzero((void*)fieldtag_s,255);
1025 
1026     field_flag++;
1027     if(*pid==0) {
1028       printf("\n");
1029       printf("The %d/%d th field to be written is '%s'\n",field_flag,nfields,fieldlabel);
1030     }
1031 
1032     int i;
1033     for ( i = 0; i < nppp; i++  ) {
1034         GPID = startpart + i;
1035 
1036         // Write solution field ...
1037         sprintf(fieldtag_s,"%s@%d",fieldlabel,GPID);
1038 
1039         isize = (*nshg)*(*numvars);
1040         nitems = 3;
1041         iarray[ 0 ] = (*nshg);
1042         iarray[ 1 ] = (*numvars);
1043         iarray[ 2 ] = (*stepno);
1044         writeheader( &f_descriptor, fieldtag_s, (void*)iarray, &nitems, &isize, "double", phasta_iotype);
1045         writedatablock( &f_descriptor, fieldtag_s, array, &isize, "double", phasta_iotype );
1046     }
1047 
1048     if (field_flag==nfields){
1049       closefile(&f_descriptor, "write");
1050       finalizephmpiio(&f_descriptor);
1051       if (*pid==0) {
1052         printf("\n");
1053       }
1054     }
1055 
1056     free(fieldlabel);
1057 }
1058 
1059 
1060 void
1061 Write_d2wall(   int* pid,
1062                 int* numnp,
1063                 double* array1 ) {
1064 
1065     int isize, nitems;
1066     int iarray[10];
1067 
1068     /////////////////////////////// Start of writing using new-lib ////////////////////////////
1069 
1070     int nfiles;
1071     int nfields;
1072     int numparts;
1073     int irank;
1074     int nprocs;
1075 
1076     //  First, count the number of fields to write and store the result in
1077     //countfieldstowriterestart();
1078 
1079     //  Retrieve and compute the parameters required for SyncIO
1080     nfiles = outpar.nsynciofiles;
1081     nfields = 1; //outpar.nsynciofieldswriterestart;  // Only the distance to the walls in d2wall
1082     numparts = workfc.numpe;
1083     irank = *pid; //workfc.myrank;
1084     nprocs = workfc.numpe;
1085     int nppf = numparts/nfiles;
1086     int GPID;
1087 
1088     // Calculate number of parts each proc deal with and where it start and end ...
1089     int nppp = numparts/nprocs;// nppp : Number of parts per proc ...
1090     int startpart = irank * nppp +1;// Part id from which I (myrank) start ...
1091     int endpart = startpart + nppp - 1;// Part id to which I (myrank) end ...
1092 
1093     int descriptor;
1094     char filename[255],fieldtag_s[255];
1095     bzero((void*)filename,255);
1096     bzero((void*)fieldtag_s,255);
1097 
1098     sprintf(filename,"d2wall.%d",((int)(irank/(nprocs/nfiles))+1));
1099 
1100     if (irank==0) {
1101       printf("Filename is %s \n",filename);
1102     }
1103 
1104     initphmpiio(&nfields, &nppf, &nfiles, &f_descriptor, "write");
1105 
1106     openfile(filename, "write", &f_descriptor);
1107 
1108     field_flag=0;
1109 
1110      int i;
1111      for ( i = 0; i < nppp; i++) { //This loop is useful only if several parts per processor
1112      // GPID : global part id, corresponds to rank ...
1113         // e.g : (in this example)
1114         // proc 0 : 1--4
1115         // proc 1 : 5--8 ...
1116         GPID = startpart + i;
1117 
1118         // Write solution field ...
1119         sprintf(fieldtag_s,"d2wall@%d",GPID);
1120 
1121         isize = (*numnp);
1122         nitems = 2;
1123         iarray[ 0 ] = (*numnp);
1124         iarray[ 1 ] = 1; //numVars = 1
1125         writeheader( &f_descriptor, fieldtag_s, (void*)iarray, &nitems, &isize, "double", phasta_iotype);
1126         writedatablock( &f_descriptor, fieldtag_s, (void*)(array1), &isize, "double", phasta_iotype );
1127     }
1128     field_flag++;
1129 
1130     if (field_flag==nfields){
1131       closefile(&f_descriptor, "write");
1132       finalizephmpiio(&f_descriptor);
1133       if (irank==0) {
1134         printf("\n");
1135       }
1136     }
1137 }
1138 
1139