Streamer fluid modeling - An overview of ARCoS  1.0
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
rz_array.c
Go to the documentation of this file.
1 
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <string.h>
7 
8 #include "parameters.h"
9 #include "proto.h"
10 #include "rz_array.h"
11 #include "species.h"
12 
13 long int used_disk_space = 0;
19 static void check_disk_space(void);
20 
22 rz_array_t *
23 rz_new_3d_a (int r0, int z0, int r1, int z1, int ntheta)
24 {
25  int rmax, zmax;
26  rz_array_t *array;
27 
28  debug (3, "rz_new_3d_a (%d, %d, %d, %d, %d)\n", r0, z0, r1, z1, ntheta);
29 
30  /* We allow a margin of two cells to set the boundary conditions (see below)*/
31  r0 -= 2; z0 -= 2; r1 += 2; z1 += 2;
32 
33  rmax = r1 - r0;
34  zmax = z1 - z0;
35 
36  assert (rmax > 0 && zmax > 0 && ntheta > 0);
37 
38  debug (3, "r0 = %d, z0 = %d, r1 = %d, z1 = %d\n", r0, z0, r1, z1);
39 
40  array = (rz_array_t *) xmalloc (sizeof(rz_array_t));
41 
42  if (ntheta != 1) {
43  array->len = rmax * zmax * (ntheta + 4);
44  array->theta0 = -2;
45  } else {
46  array->len = rmax * zmax;
47  array->theta0 = 0;
48  }
49 
50  /* Initially all arrays are zeroed. */
51  array->data = (REAL *) xcalloc (array->len, sizeof(REAL));
52 
53 
54  /* These strides are to make the array compatible with array(ir, iz)
55  in FORTRAN. */
56  array->strides[R_INDX] = 1;
57  array->strides[Z_INDX] = rmax;
58  array->strides[THETA_INDX] = rmax * zmax;
59 
60  array->dim = ntheta == 1? 2: 3;
61 
62  debug (3, "rmax = %d\n", rmax);
63  debug (3, "strides = {%d, %d}\n", array->strides[0], array->strides[1]);
64 
65  array->r0 = r0;
66  array->z0 = z0;
67  /* Note that these are NOT the r0, z0 we received. The idea here is that
68  RZ(array, r0, z0) will produce the correct result, where the allocated
69  array looks like (in the picture, r0, z0 ARE the received ones).
70  Note: in the picture there is only one buffer cell, while we actually
71  allocate two.
72 
73  +--------------+--------------+...+--------------+--------------+
74  |r0 - 1, z0 - 1| | | | |
75  +--------------+--------------+...+--------------+--------------+
76  | | r0, z0 | | | |
77  +--------------+--------------+...+--------------+--------------+
78  ... |...| ...
79  +--------------+--------------+...+--------------+--------------+
80  | | | |r1 - 1, z1 - 1| |
81  +--------------+--------------+...+--------------+--------------+
82  | | | | | r1, z1 |
83  +--------------+--------------+...+--------------+--------------+
84 
85  but the rows z0 +/- 1 and the columns r0 +/- 1 do not belong to the
86  physical space and are used only to specify boundary conditions.
87  */
88 
89  array->nr = r1 - r0 - 4;
90  array->nz = z1 - z0 - 4;
91  array->ntheta = ntheta;
92 
93  array->host = NULL;
94 
95  return array;
96 }
97 
104 rz_array_t *
105 rz_guest (rz_array_t *host, int r0, int z0, int r1, int z1)
106 {
107  int ntheta, rmax, zmax;
108  rz_array_t *array;
109 
110  ntheta = host->ntheta;
111  array = (rz_array_t *) xmalloc (sizeof(rz_array_t));
112 
113  rmax = r1 - r0;
114  zmax = z1 - z0;
115 
116  if (ntheta != 1) {
117  array->len = rmax * zmax * (ntheta + 4);
118  } else {
119  array->len = rmax * zmax;
120  }
121 
122  array->r0 = r0;
123  array->z0 = z0;
124 
125  array->theta0 = host->theta0;
126 
127  array->strides[R_INDX] = host->strides[R_INDX];
128  array->strides[Z_INDX] = host->strides[Z_INDX];
129  array->strides[THETA_INDX] = host->strides[THETA_INDX];
130 
131  array->dim = host->dim;
132 
133  array->nr = r1 - r0 - 4;
134  array->nz = z1 - z0 - 4;
135  array->ntheta = host->ntheta;
136 
137  array->data = RZTP (host, r0, z0, array->theta0);
138  array->host = host;
139 
140  return array;
141 }
142 
144 void
146 {
147  debug (3, "rz_set_zero\n");
148  memset (array->data, 0, array->len * sizeof(REAL));
149 }
150 
152 void
154 {
155  /* If the array is 2D, we do nothing. */
156  if (array->ntheta == 1) return;
157 
158  rz_copy_modes (array, array->r0, array->z0,
159  array, array->r0, array->z0,
160  array->nr + 4, array->nz + 4, array->ntheta - 1, -1);
161 
162  rz_copy_modes (array, array->r0, array->z0,
163  array, array->r0, array->z0,
164  array->nr + 4, array->nz + 4, array->ntheta - 2, -2);
165 
166  rz_copy_modes (array, array->r0, array->z0,
167  array, array->r0, array->z0,
168  array->nr + 4, array->nz + 4, 0, array->ntheta);
169 
170  rz_copy_modes (array, array->r0, array->z0,
171  array, array->r0, array->z0,
172  array->nr + 4, array->nz + 4, 1, array->ntheta + 1);
173 
174 }
175 
176 
195 void
197  int sign, REAL *start_from, REAL *start_to,
198  int dim0, int inout_from, int inout_to,
199  int dim1, int dim1_0, int dim1_1,
200  int dim2, int dim2_0, int dim2_1)
201 {
202  int i, j;
203  REAL *pfrom, *pto;
204 
205  for (i = dim1_0; i < dim1_1; i++) {
206  for (j = dim2_0; j < dim2_1; j++) {
207  pfrom = start_from + i * from->strides[dim1] + j * from->strides[dim2];
208  pto = start_to + i * to->strides[dim1] + j * to->strides[dim2];
209 
210  *(pto + inout_to * to->strides[dim0]) = sign * (*pfrom);
211 
212  *(pto + 2 * inout_to * to->strides[dim0]) =
213  sign * (*(pfrom + inout_from * from->strides[dim0]));
214  }
215  }
216 }
217 
218 
228 void
229 rz_set_bnd (rz_array_t *array, int sign, REAL *astart, int dim0, int inout,
230  int dim1, int dim1_0, int dim1_1,
231  int dim2, int dim2_0, int dim2_1)
232 {
233  rz_copy_bnd (array, array, sign, astart, astart, dim0, -inout, inout,
234  dim1, dim1_0, dim1_1, dim2, dim2_0, dim2_1);
235 }
236 
237 
239 void
241 {
242  debug (3, "rz_free\n");
243 
244  if (NULL == array->host) free (array->data);
245  free (array);
246 }
247 
251 void
252 rz_copy (rz_array_t *fro, int rfro, int zfro,
253  rz_array_t *to, int rto, int zto,
254  int rn, int zn)
255 {
256  int i;
257  REAL *pfro, *pto;
258 
259  debug (3, "rz_copy\n");
260 
261  pfro = RZP (fro, rfro, zfro);
262  pto = RZP (to, rto, zto);
263 
264  for (i = 0; i < zn; i++) {
265  memcpy (pto, pfro, sizeof(REAL) * rn);
266 
267  pfro += fro->strides[Z_INDX];
268  pto += to->strides[Z_INDX];
269  }
270 }
271 
276 void
277 rz_copy_modes (rz_array_t *fro, int rfro, int zfro,
278  rz_array_t *to, int rto, int zto,
279  int rn, int zn, int nmode_fro, int nmode_to)
280 {
281  int i, j;
282  REAL *pfro, *pto;
283 
284  debug (3, "rz_copy\n");
285 
286  pfro = RZTP (fro, rfro, zfro, nmode_fro);
287  pto = RZTP (to, rto, zto, nmode_to);
288 
289  for (i = 0; i < zn; i++) {
290  /* memcpy (pto, pfro, sizeof(REAL) * rn); Maybe not thread safe? */
291  for (j = 0; j < rn; j++ ) *(pto + j) = *(pfro + j);
292 
293  pfro += fro->strides[Z_INDX];
294  pto += to->strides[Z_INDX];
295  }
296 }
297 
298 
304 void
305 rz_dump (rz_array_t *rz_array, const char *fname, const char *mode,
306  int r0, int z0, int r1, int z1)
307 {
308  FILE *fp;
309  int ir, iz;
310  int writing;
311  double f;
312 
313  debug (3, "rz_dump(\"%s\", \"%s\", %d, %d, %d, %d)\n", fname, mode,
314  r0, z0, r1, z1);
315 
316  if (0 == strcmp (mode, "w")) {
317  writing = TRUE;
318  } else if (0 == strcmp (mode, "r")) {
319  writing = FALSE;
320  } else {
321  fatal ("Unknown mode for rz_dump\n");
322  }
323 
324  fp = fopen (fname, mode);
325 
326  if (fp == NULL) {
327  warning("Unable to open %s for %s\n", fname,
328  writing? "writing": "reading");
329  return;
330  }
331 
332  for (ir = r0; ir < r1; ir++)
333  for (iz = z0; iz < z1; iz++) {
334  if (writing)
335  fprintf (fp, "%15.5e\n", RZ(rz_array, ir, iz));
336  else {
337  if (fscanf (fp, "%lf", &f) != 1) {
338  warning ("Error reading file %s, at line %d, (ir, iz) = (%d, %d)\n",
339  fname, iz + ir * (z1 - z0), ir, iz);
340  f = 0.0;
341  }
342  *RZP (rz_array, ir, iz) = f;
343  }
344  }
345 
346  used_disk_space += ftell (fp);
347  fclose(fp);
348 
349  check_disk_space ();
350 }
351 
353 void
354 rz_dump_3d (rz_array_t *rz_array, const char *fname, const char *mode,
355  int r0, int z0, int r1, int z1, int ntheta)
356 {
357  FILE *fp;
358  int ir, iz, itheta;
359  int writing;
360  double f;
361 
362  debug (3, "rz_dump_3d(\"%s\", \"%s\", %d, %d, %d, %d, %d)\n",
363  fname, mode, r0, z0, r1, z1, ntheta);
364 
365  if (0 == strcmp (mode, "w")) {
366  writing = TRUE;
367  } else if (0 == strcmp (mode, "r")) {
368  writing = FALSE;
369  } else {
370  fatal ("Unknown mode for rz_dump_3d\n");
371  }
372 
373  fp = fopen (fname, mode);
374 
375  if (fp == NULL) {
376  warning ("Unable to open %s for %s\n", fname,
377  writing? "writing": "reading");
378  return;
379  }
380 
381  for (itheta = 0; itheta < ntheta; itheta++) {
382  for (ir = r0; ir < r1; ir++) {
383  for (iz = z0; iz < z1; iz++) {
384  if (writing)
385  fprintf (fp, "%15.5e\n", RZT (rz_array, ir, iz, itheta));
386  else {
387  if (fscanf (fp, "%lf", &f) != 1) {
388  warning ("Error reading file %s, at line %d, "
389  "(ir, iz, itheta) = (%d, %d, %d)\n",
390  fname, iz + (ir + itheta * (r1 - r0)) * (z1 - z0),
391  ir, iz, itheta);
392  f = 0.0;
393  }
394  *RZTP (rz_array, ir, iz, itheta) = f;
395  }
396  }
397  }
398  }
399 
400  /* Add the disk space used to the total disk space that we have used so far
401  */
402 
403  used_disk_space += ftell (fp);
404  fclose(fp);
405 
406  check_disk_space ();
407 }
408 
410 void
411  rz_axis_dump (const char *fname, int x0, int x1, double delta)
412 {
413  FILE *fp;
414  int i;
415 
416  debug (3, "rz_axis_dump(\"%s\", %d, %d, %f)\n", fname, x0, x1, delta);
417 
418  fp = fopen (fname, "w");
419 
420  if (fp == NULL) {
421  warning ("Unable to open %s\n", fname);
422  return;
423  }
424 
425  for (i = x0; i < x1; i++)
426  fprintf (fp, "%15.5e\n", ((double) i + 0.5) * delta);
427 
428 
429  used_disk_space += ftell (fp);
430  fclose(fp);
431 
432  check_disk_space ();
433 }
434 
436 static void
438 {
439  if (used_disk_space > (((long int) max_disk_space_mb) << 20)) {
440  fatal ("The disk space limit has been surpassed. "
441  "Increase max_disk_space_mb if you really need more space\n");
442  }
443 }
444