PLUTO
macros.h
Go to the documentation of this file.
1 /* ///////////////////////////////////////////////////////////////////// */
2 /*!
3  \file
4  \brief PLUTO header file for function-like macros.
5 
6  \author A. Mignone (mignone@ph.unito.it)
7  \date July 31, 2014
8 */
9 /* ///////////////////////////////////////////////////////////////////// */
10 
11 /* #####################################################################
12  1. Macros that can be placed at any point in the code
13  ##################################################################### */
14 
15 /*! \name Spatial loop macros.
16  The following macros provide a compact way to perform 1D or multi-D
17  loops in selected regions of the (local) computational domain.
18  The \c *BEG_LOOP and \c *END_LOOP macros are used to loop in the
19  leftmost or rightmost boundary ghost zones in the corresponding
20  direction \c I, \c J or \c K.
21  The \c *DOM_LOOP macros are used to loop inside the computational
22  domain (boundaries excluded) while the \c *TOT_LOOP macros are
23  used to loop across the entire domain (inside+boundary).
24 */
25 /**@{ */
26 #define IBEG_LOOP(i) for ((i) = IBEG; (i)--; )
27 #define JBEG_LOOP(j) for ((j) = JBEG; (j)--; )
28 #define KBEG_LOOP(k) for ((k) = KBEG; (k)--; )
29 
30 #define IEND_LOOP(i) for ((i) = IEND + 1; (i) < NX1_TOT; (i)++)
31 #define JEND_LOOP(j) for ((j) = JEND + 1; (j) < NX2_TOT; (j)++)
32 #define KEND_LOOP(k) for ((k) = KEND + 1; (k) < NX3_TOT; (k)++)
33 
34 #define IDOM_LOOP(i) for ((i) = IBEG; (i) <= IEND; (i)++)
35 #define JDOM_LOOP(j) for ((j) = JBEG; (j) <= JEND; (j)++)
36 #define KDOM_LOOP(k) for ((k) = KBEG; (k) <= KEND; (k)++)
37 
38 #define ITOT_LOOP(i) for ((i) = 0; (i) < NX1_TOT; (i)++)
39 #define JTOT_LOOP(j) for ((j) = 0; (j) < NX2_TOT; (j)++)
40 #define KTOT_LOOP(k) for ((k) = 0; (k) < NX3_TOT; (k)++)
41 
42 #define DOM_LOOP(k,j,i) KDOM_LOOP(k) JDOM_LOOP(j) IDOM_LOOP(i)
43 
44 #define TOT_LOOP(k,j,i) KTOT_LOOP(k) JTOT_LOOP(j) ITOT_LOOP(i)
45 
46 #define X1_BEG_LOOP(k,j,i) KTOT_LOOP(k) JTOT_LOOP(j) IBEG_LOOP(i)
47 #define X2_BEG_LOOP(k,j,i) KTOT_LOOP(k) JBEG_LOOP(j) ITOT_LOOP(i)
48 #define X3_BEG_LOOP(k,j,i) KBEG_LOOP(k) JTOT_LOOP(j) ITOT_LOOP(i)
49 
50 #define X1_END_LOOP(k,j,i) KTOT_LOOP(k) JTOT_LOOP(j) IEND_LOOP(i)
51 #define X2_END_LOOP(k,j,i) KTOT_LOOP(k) JEND_LOOP(j) ITOT_LOOP(i)
52 #define X3_END_LOOP(k,j,i) KEND_LOOP(k) JTOT_LOOP(j) ITOT_LOOP(i)
53 
54 #define TRANSVERSE_LOOP(indx, ip, i,j,k) \
55  if (g_dir == IDIR) {ip = &i; indx.pt1 = &j; indx.pt2 = &k;} \
56  if (g_dir == JDIR) {ip = &j; indx.pt1 = &i; indx.pt2 = &k;} \
57  if (g_dir == KDIR) {ip = &k; indx.pt1 = &i; indx.pt2 = &j;} \
58  for (*(indx.pt2) = indx.t2_beg; *(indx.pt2) <= indx.t2_end; *(indx.pt2) += 1) \
59  for (*(indx.pt1) = indx.t1_beg; *(indx.pt1) <= indx.t1_end; *(indx.pt1) += 1)
60 /**@} */
61 
62 /*! The BOX_LOOP() macro implements a loop over (i,j,k) in a rectangular
63  portion of the domain with indices defined by the (pointer to)
64  RBox structure B.
65  The loop increments (di,dj,dk) are members of the structure which
66  are here initialized to either 1 or -1 depending on whether the
67  lower corner index lies below or above the upper index
68  (e.g. B->ib <= B->ie or not).
69 */
70 #define BOX_LOOP(B,k,j,i) \
71  for ((B)->dk = ((k=(B)->kb) <= (B)->ke ? 1:-1); k != (B)->ke+(B)->dk; k += (B)->dk)\
72  for ((B)->dj = ((j=(B)->jb) <= (B)->je ? 1:-1); j != (B)->je+(B)->dj; j += (B)->dj)\
73  for ((B)->di = ((i=(B)->ib) <= (B)->ie ? 1:-1); i != (B)->ie+(B)->di; i += (B)->di)
74 
75 /*! The FOR_EACH(p, beg, intList) macro implements a loop over the
76  elements of the array \c intList->indx starting at \c beg (in a
77  similar way to Python lists).
78 
79  Example:
80  \code
81  intList list;
82  list.nvar = 3;
83  list.indx[0] = 2;
84  list.indx[1] = 5;
85  list.indx[2] = 17;
86  FOR_EACH(nv, 0, list) printf ("value is = %d\n",nv);
87  \endcode
88 */
89 #define FOR_EACH(nv, beg, list) \
90  for ((list)->i = beg, nv = (list)->indx[beg]; \
91  (list)->i < (list)->nvar; \
92  nv = (list)->indx[++((list)->i)])
93 
94 
95 /*! Faster implementation than stdlib floor() function.
96  It returns the largest integer value less than or equal to z.
97 */
98 #define INT_FLOOR(z) ((int)((z) + 32768.) - 32768)
99 
100 /*! Return the maximum between two numbers. */
101 #define MAX(a,b) ( (a) >= (b) ? (a) : (b) )
102 
103 /*! Return the minimum between two numbers. */
104 #define MIN(a,b) ( (a) <= (b) ? (a) : (b) )
105 
106 /*! Return the number with the smaller absolute value. */
107 #define ABS_MIN(a,b) (fabs(a) < fabs(b) ? (a):(b))
108 
109 /*! Return the sign of x. */
110 #define DSIGN(x) ( (x) >= 0.0 ? (1.0) : (-1.0))
111 
112 #define MINMOD(a,b) ((a)*(b) > 0.0 ? (fabs(a) < fabs(b) ? (a):(b)):0.0)
113 #define VAN_LEER(a,b) ((a)*(b) > 0.0 ? 2.0*(a)*(b)/((a)+(b)):0.0)
114 #define MC(a,b) (MINMOD(0.5*((a)+(b)), 2.0*MINMOD((a),(b))))
115 #define SWAP_VAR(x) SwapEndian(&x, sizeof(x));
116 
117 /*! Exit macro. For Chombo it is defined elsewhere. */
118 #ifdef PARALLEL
119  #define QUIT_PLUTO(e_code) \
120  {MPI_Abort(MPI_COMM_WORLD, e_code);MPI_Finalize(); exit(e_code);}
121 #elif (defined CH_MPI)
122  #define QUIT_PLUTO(e_code) \
123  {MPI_Abort(MPI_COMM_WORLD, e_code); exit(e_code);}
124 #else
125  #define QUIT_PLUTO(e_code) exit(e_code);
126 #endif
127 
128 /* #####################################################################
129  2. Macros that must be placed only *AFTER* definitions.h has been
130  included
131  ##################################################################### */
132 
133 /* *******************************************************
134  Expand dimension- or component-dependent expressions
135  ******************************************************* */
136 
137 /*! \def EXPAND(a,b,c)
138  Allows to write component-independent expressions involving vectors
139  by evaluating as many arguments as the value of COMPONENTS.
140  The result is that only the first argument will be compiled in 1D,
141  the first two arguments in 2D and all of them in 3D.
142  As an example:
143  \code
144  EXPAND( v[VX1] = 1.0; ,
145  v[VX2] = 5.0; ,
146  v[VX3] = -4.0; )
147  \endcode
148  becomes
149  \code
150  v[VX1] = 1.0;
151  \endcode
152  when \c COMPONENTS is equal to 1 or
153  \code
154  v[VX1] = 1.0;
155  v[VX2] = 5.0;
156  \endcode
157  when \c COMPONENTS is equal to 2 or
158  \code
159  v[VX1] = 1.0;
160  v[VX2] = 5.0;
161  v[VX3] = -4.0;
162  \endcode
163  when \c COMPONENTS is equal to 3.
164 */
165 
166 /*! \def D_EXPAND(a,b,c)
167  Similar to the EXPAND() macro but the expansion depends on DIMENSIONS. */
168 
169 /*! \def SELECT(a,b,c)
170  Expand only the 1st, 2nd or 3rd argument based on the value of
171  COMPONENTS. */
172 
173 /*! \def D_SELECT(a,b,c)
174  Expand only the 1st, 2nd or 3rd argument based on the value of
175  DIMENSIONS. */
176 
177 #if COMPONENTS == 1
178  #define EXPAND(a,b,c) a
179  #define SELECT(a,b,c) a
180 #endif
181 
182 #if COMPONENTS == 2
183  #define EXPAND(a,b,c) a b
184  #define SELECT(a,b,c) b
185 #endif
186 
187 #if COMPONENTS == 3
188  #define EXPAND(a,b,c) a b c
189  #define SELECT(a,b,c) c
190 #endif
191 
192 #if DIMENSIONS == 1
193  #define D_EXPAND(a,b,c) a
194  #define D_SELECT(a,b,c) a
195  #define IOFFSET 1 /* ** so we know when to loop in boundary zones ** */
196  #define JOFFSET 0
197  #define KOFFSET 0
198 #endif
199 
200 #if DIMENSIONS == 2
201  #define D_EXPAND(a,b,c) a b
202  #define D_SELECT(a,b,c) b
203  #define IOFFSET 1 /* ** so we know when to loop in boundary zones ** */
204  #define JOFFSET 1
205  #define KOFFSET 0
206 #endif
207 
208 #if DIMENSIONS == 3
209  #define D_EXPAND(a,b,c) a b c
210  #define D_SELECT(a,b,c) c
211  #define IOFFSET 1 /* ** so we know when to loop in boundary zones ** */
212  #define JOFFSET 1
213  #define KOFFSET 1
214 #endif
215 
216 #if WARNING_MESSAGES == YES
217  #define WARNING(a) a
218 #else
219  #define WARNING(a)
220 #endif
221 
222 #define DOT_PRODUCT(a,b) (EXPAND((a)[0]*(b)[0], + (a)[1]*(b)[1], + (a)[2]*(b)[2]))
223 
224 
225 
226 #define VAR_LOOP(n) for ((n) = NVAR; (n)--; )
227 #define DIM_LOOP(d) for ((d) = 0; (d) < DIMENSIONS; (d)++)
228 
229 
230 
231 /* -- some new macros.
232  CDIFF: Central DIFFerencing
233  FDIFF: Forward DIFFerencing
234 
235 */
236  #define FDIFF_X1(b,k,j,i) (b[k][j][i+1] - b[k][j][i])
237  #define FDIFF_X2(b,k,j,i) (b[k][j+1][i] - b[k][j][i])
238  #define FDIFF_X3(b,k,j,i) (b[k+1][j][i] - b[k][j][i])
239 
240  #define CDIFF_X1(b,k,j,i) 0.5*(b[k][j][i+1] - b[k][j][i-1])
241  #define CDIFF_X2(b,k,j,i) 0.5*(b[k][j+1][i] - b[k][j-1][i])
242  #define CDIFF_X3(b,k,j,i) 0.5*(b[k+1][j][i] - b[k-1][j][i])
243 
244 /* -- in 2D we set the derivative with respect to the third coordinate = 0 */
245 
246 #if DIMENSIONS == 2
247  #undef CDIFF_X3
248  #undef FDIFF_X3
249 
250  #define CDIFF_X3(b,i,j,k) 0.0
251  #define FDIFF_X3(b,i,j,k) 0.0
252 #endif
253 
254 /* ---- define average macros ---- */
255 
256 #define AVERAGE_X(q,k,j,i) 0.5*(q[k][j][i] + q[k][j][i+1])
257 #define AVERAGE_Y(q,k,j,i) 0.5*(q[k][j][i] + q[k][j+1][i])
258 #define AVERAGE_Z(q,k,j,i) 0.5*(q[k][j][i] + q[k+1][j][i])
259 
260 #define AVERAGE_XY(q,k,j,i) 0.25*( q[k][j][i] + q[k][j][i+1] \
261  + q[k][j+1][i] + q[k][j+1][i+1])
262 #define AVERAGE_XZ(q,k,j,i) 0.25*( q[k][j][i] + q[k][j][i+1] \
263  + q[k+1][j][i] + q[k+1][j][i+1])
264 #define AVERAGE_YZ(q,k,j,i) 0.25*( q[k][j][i] + q[k][j+1][i] \
265  + q[k+1][j][i] + q[k+1][j+1][i])
266 
267 /* -- re-define the macros for 1 or 2 dimensions -- */
268 
269 #if DIMENSIONS == 1
270 
271  #undef AVERAGE_Y
272  #undef AVERAGE_Z
273 
274  #undef AVERAGE_XY
275  #undef AVERAGE_XZ
276  #undef AVERAGE_YZ
277 
278  #define AVERAGE_Y(q,k,j,i) (q[0][0][i])
279  #define AVERAGE_Z(q,k,j,i) (q[0][0][i])
280 
281  #define AVERAGE_XY(q,k,j,i) AVERAGE_X(q,0,0,i)
282  #define AVERAGE_XZ(q,k,j,i) AVERAGE_X(q,0,0,i)
283  #define AVERAGE_YZ(q,k,j,i) (q[0][0][i])
284 
285 #elif DIMENSIONS == 2
286 
287  #undef AVERAGE_Z
288  #undef AVERAGE_XZ
289  #undef AVERAGE_YZ
290 
291  #define AVERAGE_Z(q,k,j,i) (q[0][j][i])
292  #define AVERAGE_XZ(q,k,j,i) 0.5*(q[0][j][i] + q[0][j][i+1])
293  #define AVERAGE_YZ(q,k,j,i) 0.5*(q[0][j][i] + q[0][j+1][i])
294 
295 #endif
296