PLUTO
TagCells.cpp
Go to the documentation of this file.
1 #include <cstdio>
2 #include <string>
3 using std::string;
4 
5 #include "PatchPluto.H"
6 #include "LoHiSide.H"
7 
8 static void computeRefVar(double ***UU[], double ***q, double, RBox *Ubox);
9 
10 #if (EOS != ISOTHERMAL) && (CHOMBO_EN_SWITCH == NO)
11  #ifndef CHOMBO_REF_VAR
12  #define CHOMBO_REF_VAR ENG
13  #endif
14 #else
15  #ifndef CHOMBO_REF_VAR
16  #define CHOMBO_REF_VAR RHO
17  #endif
18 #endif
19 
20 // #define CHOMBO_REF_VAR -1 /* means user-defined */
21 
22 #define REF_CRIT 2 /* 1 == first derivative, 2 == second derivative */
23 
24 /* ************************************************************************* */
25 void PatchPluto::computeRefGradient(FArrayBox& gFab, FArrayBox& UFab,
26  const FArrayBox& a_dV, const Box& b)
27 /*!
28  * Tag zones for refinement using gradient of the conservative
29  * variables.
30  * The gradient is computed by standard finite differences using
31  *
32  * - REF_CRIT equal to 1 --> compute (normalized) gradient using 1st
33  * derivative of the solution;
34  * - REF_CRIT equal to 2 --> compute (normalized) gradient using 2nd
35  * derivative of the solution (default);
36  * This approach is based on Lohner (1987).
37  *
38  * Zones will be flagged for refinement whenever grad[k][j][i] exceeds
39  * the threshold value specified by the 'Refine_thresh' parameter read in
40  * pluto.ini.
41  *
42  * Derivatives are computed using the conserved variable
43  * U[CHOMBO_REF_VAR]
44  * where CHOMBO_REF_VAR is taken to be energy density (default).
45  * However, by setting CHOMBO_REF_VAR = -1, you can provide your own
46  * physical variable through the function computeRefVar().
47  *
48  * \authors C. Zanni (zanni@oato.inaf.it)\n
49  * A. Mignone (mignone@ph.unito.it)
50  * \date Oct 11, 2012
51  *************************************************************************** */
52 {
53  CH_assert(m_isDefined);
54 
55  int nv, i, j, k;
56  double x1, dqx_p, dqx_m, dqx, d2qx, den_x;
57  double x2, dqy_p, dqy_m, dqy, d2qy, den_y;
58  double x3, dqz_p, dqz_m, dqz, d2qz, den_z;
59  double gr1, gr2, eps = 0.01;
60  #if CHOMBO_REF_VAR == -1
61  double ***UU[NVAR];
62  #endif
63  double ***q, ***grad;
64  RBox Ubox, Gbox;
65 
66 /* -- check ref criterion -- */
67 
68  #if REF_CRIT != 1 && REF_CRIT != 2
69  print ("! TagCells.cpp: Refinement criterion not valid\n");
70  QUIT_PLUTO(1);
71  #endif
72 
73 /* -----------------------------------------------------
74  1. The solution array U is defined on the box
75  [Uib, Uie] x [Ujb, Uje] x [Ukb, Uke], which
76  differs from that of gFab ([Gib,...Gke]),
77  typically one point larger in each direction.
78  ----------------------------------------------------- */
79 
80  Ubox.jb = Ubox.je = Ubox.kb = Ubox.ke = 0;
81  Gbox.jb = Gbox.je = Gbox.kb = Gbox.ke = 0;
82 
83  D_EXPAND(Ubox.ib = UFab.loVect()[IDIR]; Ubox.ie = UFab.hiVect()[IDIR]; ,
84  Ubox.jb = UFab.loVect()[JDIR]; Ubox.je = UFab.hiVect()[JDIR]; ,
85  Ubox.kb = UFab.loVect()[KDIR]; Ubox.ke = UFab.hiVect()[KDIR]; );
86 
87  D_EXPAND(Gbox.ib = gFab.loVect()[IDIR]; Gbox.ie = gFab.hiVect()[IDIR]; ,
88  Gbox.jb = gFab.loVect()[JDIR]; Gbox.je = gFab.hiVect()[JDIR]; ,
89  Gbox.kb = gFab.loVect()[KDIR]; Gbox.ke = gFab.hiVect()[KDIR]; );
90 
91 /* --------------------------------------------------------
92  2. Input solution array (UFab.dataPtr(nv)) is defined
93  as dV*U/dx, where U is an array of conservative
94  variables and dV is the zone volume.
95  To obtain U we must divide by volume.
96  -------------------------------------------------------- */
97 
98  #if GEOMETRY != CARTESIAN
99 
100  #if CHOMBO_REF_VAR >= 0
101  UFab.divide(a_dV,0,CHOMBO_REF_VAR);
102  #else
103  for (nv = 0; nv < NVAR; nv++) UFab.divide(a_dV,0,nv);
104  #endif
105 
106  #if (CHOMBO_CONS_AM == YES) && \
107  ((CHOMBO_REF_VAR == iMPHI) || (CHOMBO_REF_VAR == -1))
108  #if ROTATING_FRAME == YES
109  Box curBox = UFab.box();
110  for(BoxIterator bit(curBox); bit.ok(); ++bit) {
111  const IntVect& iv = bit();
112  UFab(iv,iMPHI) /= a_dV(iv,1);
113  UFab(iv,iMPHI) -= UFab(iv,RHO)*a_dV(iv,1)*g_OmegaZ;
114  }
115  #else
116  UFab.divide(a_dV,1,iMPHI);
117  #endif
118  #endif
119 
120  #else
121 
122  #if CHOMBO_REF_VAR >= 0
123  if (ch_vol != 1.) UFab.divide(ch_vol,CHOMBO_REF_VAR);
124  #else
125  if (ch_vol != 1.) UFab.divide(ch_vol);
126  #endif
127 
128  #endif
129 
130 /* ---------------------------------------------
131  3. Set refinement variable
132  --------------------------------------------- */
133 
134  #if CHOMBO_REF_VAR >= 0
135  q = ArrayBoxMap(Ubox.kb, Ubox.ke,
136  Ubox.jb, Ubox.je,
137  Ubox.ib, Ubox.ie, UFab.dataPtr(CHOMBO_REF_VAR));
138  #else
139  for (nv = 0; nv < NVAR; nv++)
140  UU[nv] = ArrayBoxMap(Ubox.kb, Ubox.ke,
141  Ubox.jb, Ubox.je,
142  Ubox.ib, Ubox.ie, UFab.dataPtr(nv));
143  q = ArrayBox(Ubox.kb, Ubox.ke, Ubox.jb, Ubox.je, Ubox.ib, Ubox.ie);
144  computeRefVar(UU, q, m_dx, &Ubox);
145  #endif
146 
147  grad = ArrayBoxMap(Gbox.kb, Gbox.ke,
148  Gbox.jb, Gbox.je,
149  Gbox.ib, Gbox.ie, gFab.dataPtr(0));
150 
151 /* ----------------------------------------------------------------
152  4. Main spatial loop for zone tagging based on 1st
153  (REF_CRIT = 1) or 2nd (REF_CRIT = 2) derivative error norm.
154  ---------------------------------------------------------------- */
155 
156  BOX_LOOP(&Gbox, k, j, i){
157  x3 = (k + 0.5)*m_dx*zstretch + g_domBeg[KDIR];
158  x2 = (j + 0.5)*m_dx*ystretch + g_domBeg[JDIR];
159  #if CHOMBO_LOGR == NO
160  x1 = (i + 0.5)*m_dx + g_domBeg[IDIR];
161  #else
162  double xl = g_domBeg[IDIR] + i*m_dx;
163  double xr = xl + m_dx;
164  x1 = g_domBeg[IDIR]*0.5*(exp(xr)+exp(xl));
165  #endif
166 
167  D_EXPAND(dqx_p = q[k][j][i+1] - q[k][j][i];
168  dqx_m = - (q[k][j][i-1] - q[k][j][i]); ,
169  dqy_p = q[k][j+1][i] - q[k][j][i];
170  dqy_m = - (q[k][j-1][i] - q[k][j][i]); ,
171  dqz_p = q[k+1][j][i] - q[k][j][i];
172  dqz_m = - (q[k-1][j][i] - q[k][j][i]);)
173 
174  /* --------------------------------------------------------------
175  Physical boundary values are not up to date and should be
176  excluded from gradient computation.
177  In this case, left and right derivatives are set equal to
178  each other. This will not trigger refinement in the leftmost
179  and rightmost internal zones (using 2nd derivative) but we
180  really don't care since buffer size will do the job.
181  -------------------------------------------------------------- */
182 
183  D_EXPAND(if (i == 0) dqx_m = dqx_p; ,
184  if (j == 0) dqy_m = dqy_p; ,
185  if (k == 0) dqz_m = dqz_p;)
186 
187  D_EXPAND(if (i == m_domain.size(IDIR)-1) dqx_p = dqx_m; ,
188  if (j == m_domain.size(JDIR)-1) dqy_p = dqy_m; ,
189  if (k == m_domain.size(KDIR)-1) dqz_p = dqz_m;)
190 
191  /* -----------------------------------------------
192  Compute gradient using 1st derivative
193  ---------------------------------------------- */
194 
195  #if REF_CRIT == 1
196  D_EXPAND(dqx = dqx_p + dqx_m; ,
197  dqy = dqy_p + dqy_m; ,
198  dqz = dqz_p + dqz_m;)
199 
200  D_EXPAND(den_x = fabs(q[k][j][i+1]) + fabs(q[k][j][i-1]); ,
201  den_y = fabs(q[k][j+1][i]) + fabs(q[k][j-1][i]); ,
202  den_z = fabs(q[k+1][j][i]) + fabs(q[k-1][j][i]);)
203 
204  gr1 = D_EXPAND(dqx*dqx, + dqy*dqy, + dqz*dqz);
205  gr1 /= D_EXPAND(den_x*den_x, + den_y*den_y, + den_z*den_z);
206 
207  grad[k][j][i] = sqrt(gr1);
208  #endif
209 
210  /* -----------------------------------------------
211  Compute gradient using 2nd derivative
212  ---------------------------------------------- */
213 
214  #if REF_CRIT == 2
215  D_EXPAND(d2qx = dqx_p - dqx_m; ,
216  d2qy = dqy_p - dqy_m; ,
217  d2qz = dqz_p - dqz_m;)
218 
219  D_EXPAND(
220  den_x = 2.0*fabs(q[k][j][i]) + fabs(q[k][j][i+1]) + fabs(q[k][j][i-1]);
221  den_x = fabs(dqx_p) + fabs(dqx_m) + eps*den_x; ,
222 
223  den_y = 2.0*fabs(q[k][j][i]) + fabs(q[k][j+1][i]) + fabs(q[k][j-1][i]);
224  den_y = fabs(dqy_p) + fabs(dqy_m) + eps*den_y; ,
225 
226  den_z = 2.0*fabs(q[k][j][i]) + fabs(q[k+1][j][i]) + fabs(q[k-1][j][i]);
227  den_z = fabs(dqz_p) + fabs(dqz_m) + eps*den_z;
228  )
229 
230  gr2 = D_EXPAND(d2qx*d2qx, + d2qy*d2qy, + d2qz*d2qz);
231  gr2 /= D_EXPAND(den_x*den_x, + den_y*den_y, + den_z*den_z);
232 
233  grad[k][j][i] = sqrt(gr2);
234  #endif
235 if (x1 < 0.5 && m_level <= 15) grad[k][j][i] = 1.0;
236 if (x1 > 1.8 && m_level <= 15) grad[k][j][i] = 1.0;
237 
238  }
239 
240 /* --------------------------------------------------------------
241  5. Multiply U times volume again.
242  -------------------------------------------------------------- */
243 
244  #if GEOMETRY != CARTESIAN
245 
246  #if (CHOMBO_CONS_AM == YES) && ((CHOMBO_REF_VAR == iMPHI) || (CHOMBO_REF_VAR == -1))
247  #if ROTATING_FRAME == YES
248  for(BoxIterator bit(curBox); bit.ok(); ++bit) {
249  const IntVect& iv = bit();
250  UFab(iv,iMPHI) += UFab(iv,RHO)*a_dV(iv,1)*g_OmegaZ;
251  UFab(iv,iMPHI) *= a_dV(iv,1);
252  }
253  #else
254  UFab.mult(a_dV,1,iMPHI);
255  #endif
256  #endif
257 
258  #if CHOMBO_REF_VAR >= 0
259  UFab.mult(a_dV,0,CHOMBO_REF_VAR);
260  #else
261  for (nv = 0; nv < NVAR; nv++) UFab.mult(a_dV,0,nv);
262  #endif
263 
264  #else
265 
266  #if CHOMBO_REF_VAR >= 0
267  if (ch_vol != 1.) UFab.mult(ch_vol,CHOMBO_REF_VAR);
268  #else
269  if (ch_vol != 1.) UFab.mult(ch_vol);
270  #endif
271 
272  #endif
273 
274 /* --------------------------------------------------------------
275  6. Free array
276  -------------------------------------------------------------- */
277 
278  FreeArrayBoxMap(grad, Gbox.kb, Gbox.ke, Gbox.jb, Gbox.je, Gbox.ib, Gbox.ie);
279 
280  #if CHOMBO_REF_VAR >= 0
281  FreeArrayBoxMap(q, Ubox.kb, Ubox.ke, Ubox.jb, Ubox.je, Ubox.ib, Ubox.ie);
282  #else
283  for (nv = 0; nv < NVAR; nv++){
284  FreeArrayBoxMap(UU[nv], Ubox.kb, Ubox.ke,
285  Ubox.jb, Ubox.je, Ubox.ib, Ubox.ie);
286  }
287  FreeArrayBox(q, Ubox.kb, Ubox.jb, Ubox.ib);
288  #endif
289 
290 }
291 
292 /* ********************************************************************* */
293 void computeRefVar(double ***UU[], double ***q, double dx, RBox *Ubox)
294 /*!
295  * Compute a user-defined array q(U) function of the conserved
296  * variables.
297  *
298  *
299  *********************************************************************** */
300 {
301  int nv, i, j, k;
302  double us[NVAR], vs[NVAR];
303 
304  BOX_LOOP(Ubox, k, j, i) {
305  VAR_LOOP(nv) us[nv] = UU[nv][k][j][i];
306  q[k][j][i] = us[RHO];
307  }
308 
309 }
310 #undef REF_CRIT
#define iMPHI
Definition: mod_defs.h:71
int jb
Lower corner index in the x2 direction.
Definition: structs.h:349
double * xr
Definition: structs.h:81
#define RHO
Definition: mod_defs.h:19
#define BOX_LOOP(B, k, j, i)
Definition: macros.h:70
int kb
Lower corner index in the x3 direction.
Definition: structs.h:351
void FreeArrayBox(double ***t, long nrl, long ncl, long ndl)
Definition: arrays.c:403
#define g_OmegaZ
Definition: init.c:64
#define REF_CRIT
Definition: TagCells.cpp:22
double *** ArrayBox(long int nrl, long int nrh, long int ncl, long int nch, long int ndl, long int ndh)
Definition: arrays.c:341
double * dx
Definition: structs.h:83
#define KDIR
Definition: pluto.h:195
int ib
Lower corner index in the x1 direction.
Definition: structs.h:347
double * xl
Definition: structs.h:82
#define eps
#define VAR_LOOP(n)
Definition: macros.h:226
#define IDIR
Definition: pluto.h:193
int j
Definition: analysis.c:2
int k
Definition: analysis.c:2
void print(const char *fmt,...)
Definition: amrPluto.cpp:497
double g_domBeg[3]
Lower limits of the computational domain.
Definition: globals.h:125
D_EXPAND(tot/[n]=(double) grid[IDIR].np_int_glob;, tot/[n]=(double) grid[JDIR].np_int_glob;, tot/[n]=(double) grid[KDIR].np_int_glob;)
Definition: analysis.c:27
int i
Definition: analysis.c:2
int ie
Upper corner index in the x1 direction.
Definition: structs.h:348
int ke
Upper corner index in the x3 direction.
Definition: structs.h:352
int je
Upper corner index in the x2 direction.
Definition: structs.h:350
#define CHOMBO_REF_VAR
Definition: TagCells.cpp:16
double *** ArrayBoxMap(int nrl, int nrh, int ncl, int nch, int ndl, int ndh, double *uptr)
Definition: arrays.c:537
void FreeArrayBoxMap(double ***t, int nrl, int nrh, int ncl, int nch, int ndl, int ndh)
Definition: arrays.c:586
#define JDIR
Definition: pluto.h:194
#define NVAR
Definition: pluto.h:609
Definition: structs.h:346
static Runtime q
static void computeRefVar(double ***UU[], double ***q, double, RBox *Ubox)
Definition: TagCells.cpp:293
#define QUIT_PLUTO(e_code)
Definition: macros.h:125