PLUTO
arrays.c
Go to the documentation of this file.
1 /* ///////////////////////////////////////////////////////////////////// */
2 /*!
3  \file
4  \brief Memory allocation functions.
5 
6  Provides essential functions for allocating and deallocating
7  multi-dimensional arrays.
8  The functions Array1D(), Array2D(), Array3D(), Array4D() can be
9  used to allocate storage for 1-D, 2-D, 3-D and 4-D arrays
10  of any data type with indices starting at 0.
11  They are typically invoked from within a corresponding macros
12  that handles type casting automatically, e.g.,
13  \code
14  char *s;
15  double **q;
16  s = ARRAY_1D(20, char);
17  q = ARRAY_2D(30,40,double);
18  \endcode
19  will allocate memory for a 1D char array with \c 20 elements and a
20  2D double arrays of \c 30x40 elements
21 
22  The function ArrayBox() can be used to allocate memory for
23  a double precision array with specified index range.
24 
25  The functions ArrayMap() can be used to convert a one-dimensional
26  array into a 3D array.
27 
28  \author A. Mignone (mignone@ph.unito.it)
29  \date Sep 18, 2012
30 */
31 /* ///////////////////////////////////////////////////////////////////// */
32 #include "pluto.h"
33 #define NONZERO_INITIALIZE YES /* Fill arrays to nonsense values to catch
34  uninitialized values later in the code */
35 
36 /* ********************************************************************* */
37 void FreeArray1D (void *v)
38 /*!
39  * Free memory allocated by the pointer *v.
40  *
41  *********************************************************************** */
42 {
43  free ((char *)v);
44 }
45 /* ********************************************************************* */
46 void FreeArray2D (void **m)
47 /*!
48  * Free memory allocated by the double pointer **v.
49  *
50  *********************************************************************** */
51 {
52  free ((char *) m[0]);
53  free ((char *) m);
54 }
55 /* ********************************************************************* */
56 void FreeArray3D (void ***m)
57 /*!
58  * Free memory allocated by the pointer ***v.
59  *
60  *********************************************************************** */
61 {
62  free ((char *) m[0][0]);
63  free ((char *) m[0]);
64  free ((char *) m);
65 }
66 /* ********************************************************************* */
67 void FreeArray4D (void ****m)
68 /*!
69  * Free memory allocated by the pointer ****v.
70  *
71  *********************************************************************** */
72 {
73  free ((char *) m[0][0][0]);
74  free ((char *) m[0][0]);
75  free ((char *) m[0]);
76  free ((char *) m);
77 }
78 
79 /* ********************************************************************* */
80 char *Array1D (int nx, size_t dsize)
81 /*!
82  * Allocate memory for a 1-D array of any basic data type starting
83  * at 0.
84  *
85  * \param [in] nx number of elements to be allocated
86  * \param [in] dsize data-type of the array to be allocated
87  *
88  * \return A pointer of type (char *) to the allocated memory area.
89  *********************************************************************** */
90 {
91  char *v;
92  v = (char *) malloc (nx*dsize);
93  PlutoError (!v, "Allocation failure in Array1D");
94  g_usedMemory += nx*dsize;
95 
96  #if NONZERO_INITIALIZE == YES
97  if (dsize==sizeof(double)){
98  int i;
99  double *q;
100  q = (double *) v;
101  for (i = nx; i--; ) q[i] = i*1.e18 - 1.e16;
102  }
103  #endif
104  return v;
105 }
106 
107 /* ********************************************************************* */
108 char **Array2D (int nx, int ny, size_t dsize)
109 /*!
110  * Allocate memory for a 2-D array of any basic data type.
111  *
112  * \param [in] nx number of elements in the 2nd dimension
113  * \param [in] ny number of elements in the 1st dimension
114  * \param [in] dsize data-type of the array to be allocated
115  *
116  * \return A pointer of type (char **) to the allocated memory area
117  * with index range [0...nx-1][0...ny-1]
118  *
119  *********************************************************************** */
120 {
121  int i;
122  char **m;
123 
124  m = (char **)malloc ((size_t) nx*sizeof(char *));
125  PlutoError (!m, "Allocation failure in Array2D (1)");
126  m[0] = (char *) malloc ((size_t) nx*ny*dsize);
127  PlutoError (!m[0],"Allocation failure in Array2D (2)");
128 
129  for (i = 1; i < nx; i++) m[i] = m[(i - 1)] + ny*dsize;
130 
131  g_usedMemory += nx*ny*dsize;
132 
133  #if NONZERO_INITIALIZE == YES
134  if (dsize==sizeof(double)){
135  int j;
136  double **q;
137  q = (double **)m;
138  for (i = nx; i--; ){
139  for (j = ny; j--; ){
140  q[i][j] = i*j*1.e18 + 1.e16*j;
141  }}
142  }
143  #endif
144 
145  return m;
146 }
147 
148 /* ********************************************************************* */
149 char ***Array3D (int nx, int ny, int nz, size_t dsize)
150 /*!
151  * Allocate memory for a 3-D array of any basic data type.
152  *
153  * \param [in] nx number of elements in the 3rd dimension
154  * \param [in] ny number of elements in the 2nd dimension
155  * \param [in] nz number of elements in the 1st dimension
156  * \param [in] dsize data-type of the array to be allocated
157  *
158  * \return A pointer of type (char ***) to the allocated memory area
159  * with index range [0...nx-1][0...ny-1][0...nz-1]
160  *
161  *********************************************************************** */
162 {
163  int i, j;
164  char ***m;
165 
166  m = (char ***) malloc ((size_t) nx*sizeof (char **));
167  PlutoError (!m, "Allocation failure in Array3D (1)");
168 
169  m[0] = (char **) malloc ((size_t) nx*ny*sizeof(char *));
170  PlutoError (!m[0],"Allocation failure in Array3D (2)");
171 
172  m[0][0] = (char *) malloc ((size_t) nx*ny*nz*dsize);
173  PlutoError (!m[0][0],"Allocation failure in Array3D (3)");
174 
175 /* ---------------------------
176  single subscript: i
177  --------------------------- */
178 
179  for (i = 1; i < nx; i++) m[i] = m[i - 1] + ny;
180 
181 /* ---------------------------
182  double subscript:
183 
184  (i,0) (0,j)
185  (i,j)
186  --------------------------- */
187 
188  for (j = 1; j < ny; j++) m[0][j] = m[0][j - 1] + nz*dsize;
189  for (i = 1; i < nx; i++) m[i][0] = m[i - 1][0] + ny*nz*dsize;
190 
191  for (i = 1; i < nx; i++) {
192  for (j = 1; j < ny; j++) {
193  m[i][j] = m[i][j - 1] + nz*dsize;
194  }}
195 
196  for (j = 0; j < ny; j++){
197  for (i = 0; i < nx; i++){
198  if (m[i][j] == NULL){
199  print ("! Allocation failure in Array3D\n");
200  QUIT_PLUTO(1);
201  }
202  }}
203 
204  g_usedMemory += nx*ny*nz*dsize;
205 
206  #if NONZERO_INITIALIZE == YES
207  if (dsize==sizeof(double)){
208  double ***q;
209  int k;
210  q = (double ***)m;
211  for (i = nx; i--; ){
212  for (j = ny; j--; ){
213  for (k = nz; k--; ){
214  q[i][j][k] = 1.e18*i + 1.e17*j + 1.e16*k + 1.e15;
215  }}}
216  }
217  #endif
218 
219  return m;
220 }
221 /* ********************************************************************* */
222 char ****Array4D (int nx, int ny, int nz, int nv, size_t dsize)
223 /*!
224  * Allocate memory for a 4-D array of any basic data type.
225  *
226  * \param [in] nx number of elements in the 4th dimension
227  * \param [in] ny number of elements in the 3rd dimension
228  * \param [in] nz number of elements in the 2nd dimension
229  * \param [in] nv number of elements in the 1st dimension
230  * \param [in] dsize data-type of the array to be allocated
231  *
232  * \return A pointer of type (char ****) to the allocated memory area
233  * with index range [0...nx-1][0...ny-1][0...nz-1][0...nv-1]
234  *
235  *********************************************************************** */
236 {
237  int i, j, k;
238  char ****m;
239 
240  m = (char ****) malloc ((size_t) nx*sizeof (char ***));
241  PlutoError (!m, "Allocation failure in Array4D (1)");
242 
243  m[0] = (char ***) malloc ((size_t) nx*ny*sizeof (char **));
244  PlutoError (!m[0], "Allocation failure in Array4D (2)");
245 
246  m[0][0] = (char **) malloc ((size_t) nx*ny*nz*sizeof (char *));
247  PlutoError (!m[0][0], "Allocation failure in Array4D (3)");
248 
249  m[0][0][0] = (char *) malloc ((size_t) nx*ny*nz*nv*dsize);
250  PlutoError (!m[0][0][0], "Allocation failure in Array4D (4)");
251 
252 /* ---------------------------
253  single subscript: i
254  --------------------------- */
255 
256  for (i = 1; i < nx; i++) m[i] = m[i - 1] + ny;
257 
258 /* ---------------------------
259  double subscript:
260 
261  (i,0) (0,j)
262  (i,j)
263  --------------------------- */
264 
265  for (i = 1; i < nx; i++) {
266  m[i][0] = m[i - 1][0] + ny*nz;
267  }
268  for (j = 1; j < ny; j++) {
269  m[0][j] = m[0][j - 1] + nz;
270  }
271 
272  for (i = 1; i < nx; i++) {
273  for (j = 1; j < ny; j++) {
274  m[i][j] = m[i][j - 1] + nz;
275  }}
276 
277 /* ---------------------------
278  triple subscript:
279 
280  (i,0,0) (0,j,0) (0,0,k)
281  (i,j,0) (i,0,k) (0,j,k)
282  (i,j,k)
283  --------------------------- */
284 
285  for (i = 1; i < nx; i++) {
286  m[i][0][0] = m[i - 1][0][0] + ny*nz*nv*dsize;
287  }
288  for (j = 1; j < ny; j++) {
289  m[0][j][0] = m[0][j - 1][0] + nz*nv*dsize;
290  }
291 
292  for (k = 1; k < nz; k++) {
293  m[0][0][k] = m[0][0][k - 1] + nv*dsize;
294  }
295 
296 
297  for (i = 1; i < nx; i++) {
298  for (j = 1; j < ny; j++) {
299  m[i][j][0] = m[i][j - 1][0] + nz*nv*dsize;
300  }}
301 
302  for (i = 1; i < nx; i++) {
303  for (k = 1; k < nz; k++) {
304  m[i][0][k] = m[i][0][k - 1] + nv*dsize;
305  }}
306 
307  for (j = 1; j < ny; j++) {
308  for (k = 1; k < nz; k++) {
309  m[0][j][k] = m[0][j][k - 1] + nv*dsize;
310  }}
311 
312  for (i = 1; i < nx; i++) {
313  for (j = 1; j < ny; j++) {
314  for (k = 1; k < nz; k++) {
315  m[i][j][k] = m[i][j][k - 1] + nv*dsize;
316  }
317  }
318  }
319 
320  g_usedMemory += nx*ny*nz*nv*dsize;
321 
322  #if NONZERO_INITIALIZE == YES
323  if (dsize==sizeof(double)){
324  int l;
325  double ****q;
326  q = (double ****)m;
327  for (i = nx; i--; ){
328  for (j = ny; j--; ){
329  for (k = nz; k--; ){
330  for (l = nv; l--; ){
331  q[i][j][k][l] = l*1.e18*i + 1.e17*i*j - 1.e16*k*j + 1.e17;
332  }}}}
333  }
334  #endif
335 
336  return m;
337 }
338 #undef NONZERO_INITIALIZE
339 
340 /* ********************************************************************* */
341 double ***ArrayBox(long int nrl, long int nrh,
342  long int ncl, long int nch,
343  long int ndl, long int ndh)
344 /*!
345  * Allocate memory for a 3-D array in double precision with given
346  * subscript range [low...high] for each direction.
347  * Useful for staggered arrays which do not start at [0].
348  *
349  * \param [in] nrl lower bound index for the 3rd dimension
350  * \param [in] nrh upper bound index for the 3rd dimension
351  * \param [in] ncl lower bound index for the 2nd dimension
352  * \param [in] nch upper bound index for the 2nd dimension
353  * \param [in] ndl lower bound index for the 1st dimension
354  * \param [in] ndh upper bound index for the 1st dimension
355  *
356  * \return A pointer of type (double ***) to the allocated memory area
357  * with index range [nrl...nhl][ncl...nch][ndl...ndh].
358  *
359  *********************************************************************** */
360 {
361  long i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1,ndep=ndh-ndl+1;
362  double ***t;
363 
364 /* allocate pointers to pointers to rows */
365 
366  t=(double ***) malloc((unsigned int)(nrow*sizeof(double**)));
367  if (!t) {
368  print ("! ArrayBox: allocation failure (1)\n");
369  QUIT_PLUTO(1);
370  }
371  t -= nrl;
372 
373 /* allocate pointers to rows and set pointers to them */
374 
375  t[nrl]=(double **) malloc((unsigned int)(nrow*ncol*sizeof(double*)));
376  if (!t[nrl]) {
377  print ("! ArrayBox: allocation failure (2)\n");
378  QUIT_PLUTO(1);
379  }
380  t[nrl] -= ncl;
381 
382 /* allocate rows and set pointers to them */
383 
384  t[nrl][ncl]=(double *) malloc((unsigned int)(nrow*ncol*ndep*sizeof(double)));
385  if (!t[nrl][ncl]) {
386  print ("! ArrayBox: allocation failure (3)\n");
387  QUIT_PLUTO(1);
388  }
389  t[nrl][ncl] -= ndl;
390 
391  for(j=ncl+1;j<=nch;j++) t[nrl][j]=t[nrl][j-1]+ndep;
392  for(i=nrl+1;i<=nrh;i++) {
393  t[i]=t[i-1]+ncol;
394  t[i][ncl]=t[i-1][ncl]+ncol*ndep;
395  for(j=ncl+1;j<=nch;j++) t[i][j]=t[i][j-1]+ndep;
396  }
397 
398 /* return pointer to array of pointers to rows */
399 
400  return t;
401 }
402 /* ********************************************************************* */
403 void FreeArrayBox(double ***t, long nrl, long ncl, long ndl)
404 /*!
405  * Free memory allocated by the ::ArrayBox function.
406  *
407  * \param [in] t pointer to an allocated memory area
408  * \param [in] nrl starting index of the array for the 3rd dimension
409  * \param [in] ncl starting index of the array for the 2nd dimension
410  * \param [in] ndl starting index of the array for the 1st dimension
411  *
412  *********************************************************************** */
413 {
414  free((char *) (t[nrl][ncl]+ndl));
415  free((char *) (t[nrl]+ncl));
416  free((char *) (t+nrl));
417 }
418 
419 
420 /* ********************************************************************* */
421 double ***ArrayMap(int nx, int ny, int nz, double *uptr)
422 /*!
423  * Convert a one dimensional array with (nx*ny*nz) elements into
424  * a 3D array with index range [0..nx-1][0..ny-1][0..nz-1].
425  * This function is similar, conceptually, to Array3D() except that
426  * the memory area is already allocated.
427  *
428  * \param [in] uptr pointer to 1D array
429  * \param [in] nx number of elements in the 3rd dimension
430  * \param [in] ny number of elements in the 2nd dimensions
431  * \param [in] nz number of elements in the 1st dimensions
432  *
433  * \return A pointer to the 3D array.
434  *
435  *********************************************************************** */
436 {
437  int i,j;
438  double ***t;
439 
440 /* -- allocate pointers to pointers to rows -- */
441 
442  t = (double ***) malloc((size_t)((nx)*sizeof(double**)));
443  if (!t) {
444  print ("! ArrayMap: allocation failure (1) \n");
445  QUIT_PLUTO (1);
446  }
447 
448 /* -- allocate pointers to rows and set pointers to them -- */
449 
450  t[0] = (double **) malloc((size_t)((nx*ny)*sizeof(double*)));
451  if (!t[0]) {
452  print ("! ArrayMap: allocation failure (2) \n");
453  QUIT_PLUTO(1);
454  }
455 
456 /* -- make the 3D array point to uptr -- */
457 
458  t[0][0] = uptr;
459  if (!t[0][0]) {
460  print ("! ArrayMap: allocation failure (3) \n");
461  QUIT_PLUTO (1);
462  }
463 
464  for(j = 1; j < ny; j++) t[0][j]=t[0][j-1] + nz;
465 
466  for(i = 1; i < nx; i++) {
467  t[i] = t[i-1] + ny;
468  t[i][0] = t[i-1][0] + ny*nz;
469  for(j = 1; j < ny; j++) t[i][j] = t[i][j-1] + nz;
470  }
471 
472  return t;
473 }
474 
475 /* ********************************************************************* */
476 unsigned char ***ArrayCharMap(int nx, int ny, int nz, unsigned char *uptr)
477 /* ********************************************************************* */
478 {
479  int i,j;
480  unsigned char ***t;
481 
482 /* -- allocate pointers to pointers to rows -- */
483 
484  t = (unsigned char ***) malloc((size_t)((nx)*sizeof(unsigned char**)));
485  if (!t) {
486  print ("! ArrayCharMap: allocation failure (1) \n");
487  QUIT_PLUTO (1);
488  }
489 
490 /* -- allocate pointers to rows and set pointers to them -- */
491 
492  t[0] = (unsigned char **) malloc((size_t)((nx*ny)*sizeof(unsigned char*)));
493  if (!t[0]) {
494  print ("! ArrayCharMap: allocation failure (2) \n");
495  QUIT_PLUTO(1);
496  }
497 
498 /* -- make the 3D array point to uptr -- */
499 
500  t[0][0] = uptr;
501  if (!t[0][0]) {
502  print ("! ArrayCharMap: allocation failure (3) \n");
503  QUIT_PLUTO (1);
504  }
505 
506  for(j = 1; j < ny; j++) t[0][j]=t[0][j-1] + nz;
507 
508  for(i = 1; i < nx; i++) {
509  t[i] = t[i-1] + ny;
510  t[i][0] = t[i-1][0] + ny*nz;
511  for(j = 1; j < ny; j++) t[i][j] = t[i][j-1] + nz;
512  }
513 
514  return t;
515 }
516 
517 /* ********************************************************************* */
518 void FreeArrayMap(double ***t)
519 /*!
520  * Free memory allocate with ArrayMap()
521  *
522  *
523  *********************************************************************** */
524 {
525  free((char*) t[0]);
526  free((char*) t);
527 }
528 
529 /* ********************************************************************* */
530 void FreeArrayCharMap(unsigned char ***t)
531 {
532  free((char*) t[0]);
533  free((char*) t);
534 }
535 
536 /* ********************************************************************* */
537 double ***ArrayBoxMap(int nrl, int nrh,
538  int ncl, int nch,
539  int ndl, int ndh, double *uptr)
540 /*!
541  * Convert a one-dimensional array into a 3D array with given
542  * subscript range [low...high] for each direction.
543  *
544  *
545  *********************************************************************** */
546 {
547  int i,j,nrow=nrh-nrl+1,ncol=nch-ncl+1,ndep=ndh-ndl+1;
548  double ***t;
549 
550 /* -- allocate pointers to pointers to rows -- */
551 
552  t = (double ***) malloc((size_t)((nrow)*sizeof(double**)));
553  if (!t) {
554  print ("! ArrayBoxMap: allocation failure (1) \n");
555  QUIT_PLUTO (1);
556  }
557  t -= nrl;
558 
559 /* -- allocate pointers to rows and set pointers to them -- */
560 
561  t[nrl] = (double **) malloc((size_t)((nrow*ncol)*sizeof(double*)));
562  if (!t[nrl]) {
563  print ("! ArrayBoxMap: allocation failure (2) \n");
564  QUIT_PLUTO (1);
565  }
566  t[nrl] -= ncl;
567 
568  t[nrl][ncl] = uptr;
569  if (!t[nrl][ncl]) {
570  print ("! ArrayBoxMap: allocation failure (3) \n");
571  QUIT_PLUTO (1);
572  }
573  t[nrl][ncl] -= ndl;
574 
575  for(j = ncl+1; j <= nch; j++) t[nrl][j] = t[nrl][j-1] + ndep;
576  for(i = nrl+1; i <= nrh; i++) {
577  t[i] = t[i-1] + ncol;
578  t[i][ncl] = t[i-1][ncl] + ncol*ndep;
579  for(j = ncl+1; j <= nch; j++) t[i][j] = t[i][j-1] + ndep;
580  }
581 
582  return t;
583 }
584 
585 /* ********************************************************************* */
586 void FreeArrayBoxMap(double ***t, int nrl, int nrh,
587  int ncl, int nch,
588  int ndl,int ndh)
589 /*!
590  * Free memory allocated with the ::ArrayBoxMap () function
591  *
592  *********************************************************************** */
593 {
594  free((char*) (t[nrl]+ncl));
595  free((char*) (t+nrl));
596 }
597 
598 
void FreeArray1D(void *v)
Definition: arrays.c:37
char **** Array4D(int nx, int ny, int nz, int nv, size_t dsize)
Definition: arrays.c:222
void FreeArrayBox(double ***t, long nrl, long ncl, long ndl)
Definition: arrays.c:403
double *** ArrayBox(long int nrl, long int nrh, long int ncl, long int nch, long int ndl, long int ndh)
Definition: arrays.c:341
void FreeArrayMap(double ***t)
Definition: arrays.c:518
char * Array1D(int nx, size_t dsize)
Definition: arrays.c:80
unsigned char *** ArrayCharMap(int nx, int ny, int nz, unsigned char *uptr)
Definition: arrays.c:476
void FreeArrayCharMap(unsigned char ***t)
Definition: arrays.c:530
int j
Definition: analysis.c:2
int k
Definition: analysis.c:2
void print(const char *fmt,...)
Definition: amrPluto.cpp:497
PLUTO main header file.
void PlutoError(int, char *)
Definition: tools.c:115
char ** Array2D(int nx, int ny, size_t dsize)
Definition: arrays.c:108
int i
Definition: analysis.c:2
double *** ArrayBoxMap(int nrl, int nrh, int ncl, int nch, int ndl, int ndh, double *uptr)
Definition: arrays.c:537
void FreeArray3D(void ***m)
Definition: arrays.c:56
void FreeArrayBoxMap(double ***t, int nrl, int nrh, int ncl, int nch, int ndl, int ndh)
Definition: arrays.c:586
void FreeArray4D(void ****m)
Definition: arrays.c:67
char *** Array3D(int nx, int ny, int nz, size_t dsize)
Definition: arrays.c:149
void FreeArray2D(void **m)
Definition: arrays.c:46
static Runtime q
#define QUIT_PLUTO(e_code)
Definition: macros.h:125
long int g_usedMemory
Amount of used memory in bytes.
Definition: globals.h:96
double *** ArrayMap(int nx, int ny, int nz, double *uptr)
Definition: arrays.c:421