PLUTO
bin_io.c
Go to the documentation of this file.
1 /* ///////////////////////////////////////////////////////////////////// */
2 /*!
3  \file
4  \brief Functions for handling binary I/O.
5 
6  This file provides a number of handy functions for opening, reading
7  and writing binary files using single or double precision in serial
8  or parallel mode.
9  It is employed by the following output formats: .dbl, .flt and .vtk.
10 
11  In parallel mode these functions work as wrappers to the actual
12  parallel implementations contained in AL_io.c.
13 
14  Pointer to data array must be cast into (void *) and are assumed to
15  start with index 0 for both cell-centered and staggered data arrays.
16  This means that if V3D is a 3D array then:
17  - for a cell-centered array, <tt>V = (void *) V3D[0][0]</tt>
18  - for a x-staggered array, <tt>V = (void *)(V3D[0][0]-1)</tt>
19  - for a y-staggered array, <tt>V = (void *)(V3D[0][-1])</tt>
20  - for a z-staggered array, <tt>V = (void *)(V3D[-1][0])</tt>
21 
22  \authors A. Mignone (mignone@ph.unito.it)\n
23  G. Muscianisi (g.muscianisi@cineca.it)
24 
25  \date June 21, 2014
26 */
27 /* ///////////////////////////////////////////////////////////////////// */
28 #include "pluto.h"
29 
30 /* ********************************************************************* */
31 FILE *OpenBinaryFile (char *filename, int sz, char *mode)
32 /*!
33  * Open a file for write/reading in binary mode.
34  *
35  * \param [in] filename a valid file name
36  * \param [in] sz the distributed array descriptor. This parameter
37  * replaces dsize in parallel mode
38  * \param [in] mode a string giving the opening mode (only "w" or
39  * "r" are allowed)
40  *
41  * \return The pointer to the file.
42  *********************************************************************** */
43 {
44  FILE *fp;
45 
46 /* ----------------------------------------------
47  when reading, check if file exists
48  ---------------------------------------------- */
49 
50  if (strcmp(mode,"r") == 0 && prank == 0){
51  fp = fopen(filename, "rb");
52  if (fp == NULL){
53  print1 ("! OpenBinaryFile: file %s does not exists\n", filename);
54  QUIT_PLUTO(1);
55  }
56  fclose(fp);
57  }
58 
59 /* ------------------------------------------------
60  file exists, keep going
61  ------------------------------------------------ */
62 
63  #ifdef PARALLEL
64  AL_File_open(filename, sz);
65  return NULL;
66  #else
67  if (strcmp(mode,"w") == 0) fp = fopen(filename, "wb");
68  else if (strcmp(mode,"r") == 0) fp = fopen(filename, "rb");
69  if (fp == NULL){
70  print1 ("! Cannot find file %s\n",filename);
71  QUIT_PLUTO(1);
72  }
73  return (fp);
74  #endif
75 }
76 
77 /* ********************************************************************* */
78 int CloseBinaryFile (FILE *fbin, int sz)
79 /*!
80  * Close file.
81  *
82  * \param [in] fbin pointer to the FILE that needs to be closed (serial
83  * mode only)
84  * \param [in] sz the distributed array descriptor for parallel mode
85  *
86  * \return Returns 0 on success
87  *********************************************************************** */
88 {
89  #ifdef PARALLEL
90  AL_File_close(sz);
91  #else
92  fclose (fbin);
93  #endif
94  return(0);
95 }
96 
97 /* ********************************************************************* */
98 void WriteBinaryArray (void *V, size_t dsize, int sz, FILE *fl, int istag)
99 /*!
100  * Write an array to disk in binary format.
101  *
102  * \param [in] V single pointer to a 3D array,
103  * V[k][j][i] --> V[i + NX1*j + NX1*NX2*k]. Must
104  * start with index 0
105  * \param [in] dsize the size of the each buffer element
106  * (sizeof(double) or sizeof(float)). This
107  * parameter is used only in serial mode.
108  * \param [in] sz the distributed array descriptor. This parameter
109  * replaces dsize in parallel mode
110  * \param [in] fl a valid FILE pointer
111  * \param [in] istag a flag to identify cell-centered (istag = -1) or
112  * staggered field data (istag = 0,1 or 2 for staggering
113  * in the x1, x2 or x3 directions)
114  *
115  * \return This function has no return value.
116  *
117  * \remark The data array is assumed to start \a always with index 0 for
118  * both cell-centered and staggered arrays.
119  *********************************************************************** */
120 {
121  int i, j, k;
122  int ioff, joff, koff;
123  char *Vc;
124 
125  #ifdef PARALLEL
126  MPI_Barrier (MPI_COMM_WORLD);
127  AL_Write_array (V, sz, istag);
128  return;
129  #else
130  Vc = (char *) V;
131  ioff = (istag == 0);
132  joff = (istag == 1);
133  koff = (istag == 2);
134 
135  for (k = KBEG; k <= KEND + koff; k++) {
136  for (j = JBEG; j <= JEND + joff; j++) {
137  i = IBEG + (NX1_TOT + ioff)*(j + (NX2_TOT + joff)*k);
138  fwrite (Vc + i*dsize, dsize, NX1 + ioff, fl);
139  }}
140  #endif
141 }
142 /* ********************************************************************* */
143 void ReadBinaryArray (void *V, size_t dsize, int sz, FILE *fl, int istag,
144  int swap_endian)
145 /*!
146  * Read a double-precision array from binary file.
147  *
148  * \param [in] V pointer to a 3D array,
149  * V[k][j][i] --> V[i + NX1*j + NX1*NX2*k]. Must
150  * start with index 0
151  * \param [in] dsize the size of the each buffer element
152  * (sizeof(double) or sizeof(float)). This
153  * parameter is used only in serial mode.
154  * \param [in] sz the distributed array descriptor. This parameter
155  * replaces dsize in parallel mode
156  * \param [in] fl a valid FILE pointer
157  * \param [in] istag a flag to identify cell-centered (istag = -1) or
158  * staggered field data (istag = 0,1 or 2 for staggering
159  * in the x1, x2 or x3 directions)
160  * \param [in] swap_endian a flag for swapping endianity
161  *
162  * \return This function has no return value.
163  *
164  * \remark The data array V is assumed to start \a always with index 0
165  * for both cell-centered and staggered arrays.
166  *********************************************************************** */
167 {
168  int i, j, k;
169  int ioff, joff, koff;
170  char *Vc;
171 
172 /* ---------------------------------------
173  parallel reading handled by ArrayLib
174  --------------------------------------- */
175 
176  #ifdef PARALLEL
177  AL_Read_array (V, sz, istag);
178  #else
179 
180 /* ---------------------------------------
181  serial reading
182  --------------------------------------- */
183 
184  Vc = (char *) V;
185  ioff = (istag == 0);
186  joff = (istag == 1);
187  koff = (istag == 2);
188 
189  for (k = KBEG; k <= KEND + koff; k++) {
190  for (j = JBEG; j <= JEND + joff; j++) {
191  i = IBEG + (NX1_TOT + ioff)*(j + (NX2_TOT + joff)*k);
192  fread (Vc + i*dsize, dsize, NX1 + ioff, fl);
193  }}
194  #endif
195 
196 /* -----------------------------------
197  now swap endian if necessary
198  ----------------------------------- */
199 
200  if (swap_endian){
201  double *Vd;
202  Vd = (double *) V;
203  ioff = (istag == 0);
204  joff = (istag == 1);
205  koff = (istag == 2);
206 
207  for (k = KBEG-koff; k <= KEND + koff; k++) {
208  for (j = JBEG-joff; j <= JEND + joff; j++) {
209  for (i = IBEG-ioff; i <= IEND + ioff; i++) {
210  SWAP_VAR(Vd[i + (NX1_TOT + ioff)*(j + (NX2_TOT + joff)*k)]);
211  }}}
212  }
213 }
214 
215 /* ********************************************************************* */
216 float ***Convert_dbl2flt (double ***Vdbl, double unit, int swap_endian)
217 /*!
218  * Convert the a double-precision 3D array into single precision.
219  * Swap endianity if swap_endian == 1.
220  *
221  * \param [in] Vdbl pointer to a 3D double precision aray
222  * \param [in] unit a multiplicative constant typically used
223  * to write in c.g.s units.
224  * \param [in] swap_endian when set to 1, swap endianity during the
225  * conversion.
226  * \return a pointer to a 3D array in single precision.
227  *********************************************************************** */
228 {
229  int i, j, k;
230  float flt;
231  static float ***Vflt;
232 
233  if (Vflt == NULL) Vflt = ARRAY_3D(NX3_TOT, NX2_TOT, NX1_TOT, float);
234 
235  if (!swap_endian){
236  DOM_LOOP(k,j,i){
237  Vflt[k][j][i] = (float)(Vdbl[k][j][i]*unit);
238  }
239  }else{
240  DOM_LOOP(k,j,i){
241  flt = (float)(Vdbl[k][j][i]*unit);
242  SWAP_VAR(flt);
243  Vflt[k][j][i] = flt;
244  }
245  }
246 
247  return (Vflt);
248 }
DOM_LOOP(k, j, i)
Definition: analysis.c:22
long int NX1
Number of interior zones in the X1 directions (boundaries excluded) for the local processor...
Definition: globals.h:48
void print1(const char *fmt,...)
Definition: amrPluto.cpp:511
FILE * OpenBinaryFile(char *filename, int sz, char *mode)
Definition: bin_io.c:31
long int NX2_TOT
Total number of zones in the X2 direction (boundaries included) for the local processor.
Definition: globals.h:57
int AL_File_open(char *filename, int sz_ptr)
Definition: al_io.c:27
#define ARRAY_3D(nx, ny, nz, type)
Definition: prototypes.h:172
int prank
Processor rank.
Definition: globals.h:33
int AL_Write_array(void *va, int sz_ptr, int istag)
Definition: al_io.c:115
float *** Convert_dbl2flt(double ***Vdbl, double unit, int swap_endian)
Definition: bin_io.c:216
#define SWAP_VAR(x)
Definition: macros.h:115
void ReadBinaryArray(void *V, size_t dsize, int sz, FILE *fl, int istag, int swap_endian)
Definition: bin_io.c:143
long int NX3_TOT
Total number of zones in the X3 direction (boundaries included) for the local processor.
Definition: globals.h:59
int j
Definition: analysis.c:2
long int IEND
Upper grid index of the computational domain in the the X1 direction for the local processor...
Definition: globals.h:37
int k
Definition: analysis.c:2
int AL_File_close(int sz_ptr)
Definition: al_io.c:83
PLUTO main header file.
int i
Definition: analysis.c:2
FILE * fp
Definition: analysis.c:7
long int KBEG
Lower grid index of the computational domain in the the X3 direction for the local processor...
Definition: globals.h:43
long int KEND
Upper grid index of the computational domain in the the X3 direction for the local processor...
Definition: globals.h:45
long int JBEG
Lower grid index of the computational domain in the the X2 direction for the local processor...
Definition: globals.h:39
int CloseBinaryFile(FILE *fbin, int sz)
Definition: bin_io.c:78
#define QUIT_PLUTO(e_code)
Definition: macros.h:125
void WriteBinaryArray(void *V, size_t dsize, int sz, FILE *fl, int istag)
Definition: bin_io.c:98
long int JEND
Upper grid index of the computational domain in the the X2 direction for the local processor...
Definition: globals.h:41
long int NX1_TOT
Total number of zones in the X1 direction (boundaries included) for the local processor.
Definition: globals.h:55
long int IBEG
Lower grid index of the computational domain in the the X1 direction for the local processor...
Definition: globals.h:35
int AL_Read_array(void *va, int sz_ptr, int istag)
Definition: al_io.c:209