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