PLUTO
PatchTools.cpp
Go to the documentation of this file.
1 /* ///////////////////////////////////////////////////////////////////// */
2 /*!
3  \file
4  \brief Contains some implementation of the PatchPluto class.
5 
6  PatchTools.cpp contains a number of function used by PatchUnsplit.
7  Most of them are simple wrappers to other functions employed by the
8  static version of the code.
9 
10  \authors C. Zanni (zanni@oato.inaf.it)\n
11  A. Mignone (mignone@ph.unito.it)
12  \date June 25, 2015
13 */
14 /* ///////////////////////////////////////////////////////////////////// */
15 #include <cstdio>
16 #include <string>
17 using std::string;
18 
19 #include "PatchPluto.H"
20 #include "LoHiSide.H"
21 
22 /* ********************************************************************* */
23 void PatchPluto::saveFluxes (const State_1D *state, int beg, int end,
24  Grid *grid)
25 /*!
26  * Rebuild fluxes in a way suitable for AMR operation
27  * by adding pressure and multiplying by area.
28  *
29  *********************************************************************** */
30 {
31  int i, nv;
32  double **f, *p, r, area;
33 
34  f = state->flux;
35  p = state->press;
36 
37  for (i = beg; i <= end; i++) f[i][MXn] += p[i];
38 
39  #if (GEOMETRY == CARTESIAN) && (CH_SPACEDIM > 1)
40  if ((g_dir == IDIR) && (g_stretch_fact != 1.)) {
41  for (i = beg; i <= end; i++) {
42  VAR_LOOP(nv) f[i][nv] *= g_stretch_fact;
43  }
44  }
45  #if (CH_SPACEDIM == 3)
46  if ((g_dir == JDIR) && (g_x3stretch != 1.)) {
47  for (i = beg; i <= end; i++) {
48  VAR_LOOP(nv) f[i][nv] *= g_x3stretch;
49  }
50  }
51  if ((g_dir == KDIR) && (g_x2stretch != 1.)) {
52  for (i = beg; i <= end; i++) {
53  VAR_LOOP(nv) f[i][nv] *= g_x2stretch;
54  }
55  }
56  #endif
57  #endif
58 
59  #if GEOMETRY == CYLINDRICAL
60  if (g_dir == IDIR){
61  for (i = beg; i <= end; i++) {
62  for (nv = 0; nv < NVAR; nv++) {
63  f[i][nv] *= grid[IDIR].A[i];
64  #if CH_SPACEDIM > 1
65  f[i][nv] *= g_x2stretch;
66  #endif
67  }}
68  }else{
69  area = fabs(grid[IDIR].x[g_i]);
70  for (i = beg; i <= end; i++) {
71  for (nv = 0; nv < NVAR; nv++) {
72  f[i][nv] *= area;
73  }}
74  }
75  #endif
76 
77  #if GEOMETRY == SPHERICAL
78  if (g_dir == IDIR){
79  #if CH_SPACEDIM > 1
80  area = grid[JDIR].dV[g_j]/m_dx;
81  #if CH_SPACEDIM == 3
82  area *= g_x3stretch;
83  #endif
84  #endif
85  for (i = beg; i <= end; i++) {
86  for (nv = 0; nv < NVAR; nv++) {
87  f[i][nv] *= grid[IDIR].A[i];
88  #if CH_SPACEDIM > 1
89  f[i][nv] *= area;
90  #endif
91  }
92  #if (COMPONENTS == 3) && (ENTROPY_SWITCH)
93  f[i][iMPHI] *= grid[IDIR].xr[i]*sin(grid[JDIR].x[g_j]);
94  #endif
95  }
96  }
97  if (g_dir == JDIR){
98  area = fabs(grid[IDIR].x[g_i]);
99  #if CHOMBO_LOGR == YES
100  area *= grid[IDIR].dx[g_i]/m_dx;
101  #endif
102  #if CH_SPACEDIM == 3
103  area *= g_x3stretch;
104  #endif
105  for (i = beg; i <= end; i++) {
106  for (nv = 0; nv < NVAR; nv++) {
107  f[i][nv] *= grid[JDIR].A[i]*area;
108  }
109  #if (COMPONENTS == 3) && (ENTROPY_SWITCH)
110  f[i][iMPHI] *= grid[IDIR].x[g_i]*sin(grid[JDIR].xr[i]);
111  #endif
112  }
113  }
114  if (g_dir == KDIR){
115  area = g_x2stretch*fabs(grid[IDIR].x[g_i]);
116  #if CHOMBO_LOGR == YES
117  area *= grid[IDIR].dx[g_i]/m_dx;
118  #endif
119  for (i = beg; i <= end; i++) {
120  for (nv = 0; nv < NVAR; nv++) {
121  f[i][nv] *= area;
122  }
123  #if (COMPONENTS == 3) && (ENTROPY_SWITCH)
124  f[i][iMPHI] *= grid[IDIR].x[g_i]*sin(grid[JDIR].x[g_j]);
125  #endif
126  }
127  }
128  #endif
129 
130  #if GEOMETRY == POLAR
131  if (g_dir == IDIR){
132  for (i = beg; i <= end; i++) {
133  for (nv = 0; nv < NVAR; nv++) {
134  f[i][nv] *= grid[IDIR].A[i];
135  #if CH_SPACEDIM > 1
136  f[i][nv] *= g_x2stretch;
137  #endif
138  #if CH_SPACEDIM == 3
139  f[i][nv] *= g_x3stretch;
140  #endif
141  }
142  #if (COMPONENTS > 1) && (ENTROPY_SWITCH)
143  f[i][iMPHI] *= grid[IDIR].xr[i];
144  #endif
145  }
146  }
147  if (g_dir == JDIR) {
148  area = g_x3stretch;
149  #if CHOMBO_LOGR == YES
150  area *= grid[IDIR].dx[g_i]/m_dx;
151  #endif
152  if (area != 1.) {
153  for (i = beg; i <= end; i++) {
154  for (nv = 0; nv < NVAR; nv++) {
155  f[i][nv] *= area;
156  }}}
157  #if (COMPONENTS > 1) && (ENTROPY_SWITCH)
158  for (i = beg; i <= end; i++) f[i][iMPHI] *= grid[IDIR].x[g_i];
159  #endif
160  }
161  if (g_dir == KDIR) {
162  area = g_x2stretch*fabs(grid[IDIR].x[g_i]);
163  #if CHOMBO_LOGR == YES
164  area *= grid[IDIR].dx[g_i]/m_dx;
165  #endif
166  for (i = beg; i <= end; i++) {
167  for (nv = 0; nv < NVAR; nv++) {
168  f[i][nv] *= area;
169  }
170  #if (COMPONENTS > 1) && (ENTROPY_SWITCH)
171  f[i][iMPHI] *= grid[IDIR].x[g_i];
172  #endif
173  }
174  }
175  #endif
176 }
177 /* ********************************************************************* */
178 void PatchPluto::getPrimitiveVars (Data_Arr U, Data *d, Grid *grid)
179 /*!
180  * - Recover primitive variables from the input conservative array \c U
181  * - Set physical boundary conditions and convert
182  *
183  * \date June 25, 2015
184  *********************************************************************** */
185 {
186  int i,j,k;
187  int dir, err;
188  int nx, ny, nz;
189  int lft_side[3] = {0,0,0}, rgt_side[3]={0,0,0};
190  static unsigned char ***flagEntr;
191  RBox cbox, *box;
192 
193  nx = grid[IDIR].np_tot;
194  ny = grid[JDIR].np_tot;
195  nz = grid[KDIR].np_tot;
196 
197 /* -------------------------------------------------------
198  Check whether the patch touches a physical boundary
199  ------------------------------------------------------- */
200 
201  for (dir = 0; dir < DIMENSIONS; dir++){
202  lft_side[dir] = (grid[dir - IDIR].lbound != 0);
203  rgt_side[dir] = (grid[dir - IDIR].rbound != 0);
204  }
205 
206 /* ---------------------------------------------------
207  Extract the portion of the domain where U
208  is defined (i.e. NOT in the physical boundary).
209  --------------------------------------------------- */
210 
211  cbox.ib = 0; cbox.ie = nx - 1;
212  cbox.jb = 0; cbox.je = ny - 1;
213  cbox.kb = 0; cbox.ke = nz - 1;
214 
215 /* -------------------------------------------------
216  Exclude physical boundaries since the
217  conservative vector U is not yet defined.
218  ------------------------------------------------- */
219 
220  D_EXPAND(if (lft_side[IDIR]) cbox.ib = IBEG; ,
221  if (lft_side[JDIR]) cbox.jb = JBEG; ,
222  if (lft_side[KDIR]) cbox.kb = KBEG;)
223 
224  D_EXPAND(if (rgt_side[IDIR]) cbox.ie = IEND; ,
225  if (rgt_side[JDIR]) cbox.je = JEND; ,
226  if (rgt_side[KDIR]) cbox.ke = KEND;)
227 
228 /* ----------------------------------------------------------
229  Convert conservative variables into primitive variables.
230  Normally this operation is performed by using total
231  energy density.
232  However, when the ENTROPY_SWITCH is enabled, we force
233  conversion to be done from the entropy by artificially
234  setting flagEntr.
235  ---------------------------------------------------------- */
236 
237 #if ENTROPY_SWITCH
238  if (flagEntr == NULL) {
239  flagEntr = ARRAY_3D(NX3_MAX, NX2_MAX, NX1_MAX, unsigned char);
240  for (k = 0; k < NX3_MAX; k++){
241  for (j = 0; j < NX2_MAX; j++){
242  for (i = 0; i < NX1_MAX; i++){
243  flagEntr[k][j][i] = 0;
244  flagEntr[k][j][i] |= FLAG_ENTROPY;
245  }}}
246  }
247 /*
248  BOX_LOOP(&cbox,k,j,i){
249  flagEntr[k][j][i] = 0;
250  flagEntr[k][j][i] |= FLAG_ENTROPY;
251  }
252 */
253  ConsToPrim3D(U, d->Vc, flagEntr, &cbox);
254 #else
255  ConsToPrim3D(U, d->Vc, d->flag, &cbox);
256 #endif
257  Boundary (d, ALL_DIR, grid);
258 
259 /* --------------------------------------------------------------
260  Convert primitive variables to conservative in the ghost
261  zones.
262  -------------------------------------------------------------- */
263 
264 #if INTERNAL_BOUNDARY == YES
265  box = GetRBox(TOT, CENTER);
266  PrimToCons3D(d->Vc, U, box);
267 #else
268  if (lft_side[IDIR]) {
269  box = GetRBox(X1_BEG, CENTER);
270  PrimToCons3D(d->Vc, U, box);
271  }
272 
273  if (lft_side[JDIR]) {
274  box = GetRBox(X2_BEG, CENTER);
275  PrimToCons3D(d->Vc, U, box);
276  }
277 
278  if (lft_side[KDIR]) {
279  box = GetRBox(X3_BEG, CENTER);
280  PrimToCons3D(d->Vc, U, box);
281  }
282 
283  if (rgt_side[IDIR]) {
284  box = GetRBox(X1_END, CENTER);
285  PrimToCons3D(d->Vc, U, box);
286  }
287 
288  if (rgt_side[JDIR]) {
289  box = GetRBox(X2_END, CENTER);
290  PrimToCons3D(d->Vc, U, box);
291  }
292 
293  if (rgt_side[KDIR]) {
294  box = GetRBox(X3_END, CENTER);
295  PrimToCons3D(d->Vc, U, box);
296  }
297 
298 #endif
299 }
300 
301 /* ************************************************************ */
302 void PatchPluto::showPatch (Grid *grid)
303 /*
304  *
305  *
306  *
307  ************************************************************** */
308 {
309  char pb[4]="*"; /* -- physical boundary -- */
310  char ib[4]="o"; /* -- internal boundary -- */
311 
312  Grid *Gx, *Gy, *Gz;
313 
314  D_EXPAND(Gx = grid + IDIR; ,
315  Gy = grid + JDIR; ,
316  Gz = grid + KDIR;)
317 
318  print ("+-----------------------------------------------------------+\n");
319  print ("| Level = %d \n", grid[IDIR].level);
320  print ("| ib,ie = [%d, %d], xb,xe = %s[%f, %f]%s\n",
321  IBEG, IEND, (Gx->lbound != 0 ? pb:ib),
322  Gx->xr[IBEG-1], Gx->xr[IEND],(Gx->rbound != 0 ? pb:ib));
323  print ("| jb,je = [%d, %d], yb,ye = %s[%f, %f]%s\n",
324  JBEG, JEND, (Gy->lbound != 0 ? pb:ib),
325  Gy->xr[JBEG-1], Gy->xr[JEND], (Gy->rbound != 0 ? pb:ib));
326  print ("+-----------------------------------------------------------+\n");
327 
328 }
329 
330 /* ********************************************************************* */
331 void PatchPluto::convertFArrayBox(FArrayBox& U)
332 /*!
333  * Convert a conservative array to primitive for
334  * plotfile data.
335  * Called from AMRLevelPluto::writePlotLevel
336  *
337  *
338  *********************************************************************** */
339 {
340  int ibeg, jbeg, kbeg;
341  int iend, jend, kend;
342  int i,j,k, nv;
343  double ***UU[NVAR];
344  static unsigned char *flag;
345  static double **u, **v;
346  RBox box;
347 
348  if (u == NULL){
349  u = ARRAY_2D(NMAX_POINT, NVAR, double);
350  v = ARRAY_2D(NMAX_POINT, NVAR, double);
351  flag = ARRAY_1D(NMAX_POINT, unsigned char);
352  }
353 
354  jbeg = jend = kbeg = kend = 0;
355  D_EXPAND(ibeg = U.loVect()[IDIR];
356  iend = U.hiVect()[IDIR]; ,
357  jbeg = U.loVect()[JDIR];
358  jend = U.hiVect()[JDIR]; ,
359  kbeg = U.loVect()[KDIR];
360  kend = U.hiVect()[KDIR]; );
361 
362  for (nv=0; nv<NVAR; nv++) {
363  UU[nv] = ArrayBoxMap(kbeg,kend,jbeg,jend,ibeg,iend,U.dataPtr(nv));
364  }
365 
366  box.ib = ibeg+IOFFSET; box.ie = iend-IOFFSET;
367  box.jb = jbeg+JOFFSET; box.je = jend-JOFFSET;
368  box.kb = kbeg+KOFFSET; box.ke = kend-KOFFSET;
369 
370 /* --------------------------------------------------------
371  Conversion is done in the interior points only.
372  For this reason we exclude from (ibeg, iend, ...) one
373  boundary zone in each direction.
374  -------------------------------------------------------- */
375 
376  for (k = kbeg + KOFFSET; k <= kend - KOFFSET; k++){
377  for (j = jbeg + JOFFSET; j <= jend - JOFFSET; j++){
378  for (i = ibeg + IOFFSET; i <= iend - IOFFSET; i++){
379  flag[i-ibeg] = 0;
380  NVAR_LOOP(nv) u[i-ibeg][nv] = UU[nv][k][j][i];
381  }
382  ConsToPrim (u, v, IOFFSET, iend-ibeg-IOFFSET, flag);
383  for (i = ibeg; i <= iend; i++){
384  NVAR_LOOP(nv) UU[nv][k][j][i] = v[i-ibeg][nv];
385  }
386  }}
387 
388  for (nv = 0; nv < NVAR; nv++)
389  FreeArrayBoxMap(UU[nv], kbeg, kend, jbeg, jend, ibeg, iend);
390 }
391 
#define X3_BEG
Boundary region at X3 beg.
Definition: pluto.h:150
void Boundary(const Data *d, int idim, Grid *grid)
Definition: boundary.c:36
#define X1_BEG
Boundary region at X1 beg.
Definition: pluto.h:146
#define iMPHI
Definition: mod_defs.h:71
int lbound
When different from zero, it specifies the boundary condition to be applied at leftmost grid side whe...
Definition: structs.h:105
int level
The current refinement level (chombo only).
Definition: structs.h:122
int end
Global end index for the local array.
Definition: structs.h:116
int jb
Lower corner index in the x2 direction.
Definition: structs.h:349
double **** Data_Arr
Definition: pluto.h:492
double ** flux
upwind flux computed with the Riemann solver
Definition: structs.h:149
RBox * GetRBox(int, int)
Definition: rbox.c:232
#define CENTER
Definition: pluto.h:200
void PrimToCons3D(Data_Arr V, Data_Arr U, RBox *box)
Definition: mappers3D.c:86
double * xr
Definition: structs.h:81
int rbound
Same as lbound, but for the right edge of the grid.
Definition: structs.h:112
double **** Vc
The main four-index data array used for cell-centered primitive variables.
Definition: structs.h:31
int kb
Lower corner index in the x3 direction.
Definition: structs.h:351
double * dV
Cell volume.
Definition: structs.h:86
#define X1_END
Boundary region at X1 end.
Definition: pluto.h:147
#define ARRAY_3D(nx, ny, nz, type)
Definition: prototypes.h:172
double * dx
Definition: structs.h:83
#define KDIR
Definition: pluto.h:195
#define TOT
Computational domain (total)
Definition: pluto.h:153
unsigned char *** flag
Pointer to a 3D array setting useful integration flags that are retrieved during integration.
Definition: structs.h:55
void ConsToPrim3D(Data_Arr U, Data_Arr V, unsigned char ***flag, RBox *box)
Definition: mappers3D.c:16
int ib
Lower corner index in the x1 direction.
Definition: structs.h:347
#define NX3_MAX
Definition: pluto.h:743
int g_i
x1 grid index when sweeping along the x2 or x3 direction.
Definition: globals.h:82
#define VAR_LOOP(n)
Definition: macros.h:226
#define NX2_MAX
Definition: pluto.h:742
#define FLAG_ENTROPY
Update pressure using entropy equation.
Definition: pluto.h:182
#define IDIR
Definition: pluto.h:193
int g_dir
Specifies the current sweep or direction of integration.
Definition: globals.h:86
int beg
Global start index for the local array.
Definition: structs.h:115
#define NVAR_LOOP(n)
Definition: pluto.h:618
int ConsToPrim(double **ucons, double **uprim, int ibeg, int iend, unsigned char *flag)
Definition: mappers.c:89
int g_j
x2 grid index when sweeping along the x1 or x3 direction.
Definition: globals.h:83
#define X2_END
Boundary region at X2 end.
Definition: pluto.h:149
Definition: structs.h:78
int j
Definition: analysis.c:2
if(divB==NULL)
Definition: analysis.c:10
long int IEND
Upper grid index of the computational domain in the the X1 direction for the local processor...
Definition: globals.h:37
int k
Definition: analysis.c:2
void print(const char *fmt,...)
Definition: amrPluto.cpp:497
int MXn
Definition: globals.h:74
double * x
Definition: structs.h:80
#define X3_END
Boundary region at X3 end.
Definition: pluto.h:151
#define ARRAY_1D(nx, type)
Definition: prototypes.h:170
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
Definition: structs.h:30
long int NMAX_POINT
Maximum number of points among the three directions, boundaries excluded.
Definition: globals.h:62
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
double * press
Upwind pressure term computed with the Riemann solver.
Definition: structs.h:164
void FreeArrayBoxMap(double ***t, int nrl, int nrh, int ncl, int nch, int ndl, int ndh)
Definition: arrays.c:586
long int KBEG
Lower grid index of the computational domain in the the X3 direction for the local processor...
Definition: globals.h:43
#define X2_BEG
Boundary region at X2 beg.
Definition: pluto.h:148
#define ARRAY_2D(nx, ny, type)
Definition: prototypes.h:171
int np_tot
Total number of points in the local domain (boundaries included).
Definition: structs.h:100
long int KEND
Upper grid index of the computational domain in the the X3 direction for the local processor...
Definition: globals.h:45
#define JDIR
Definition: pluto.h:194
long int JBEG
Lower grid index of the computational domain in the the X2 direction for the local processor...
Definition: globals.h:39
#define NVAR
Definition: pluto.h:609
Definition: structs.h:346
#define NX1_MAX
Definition: pluto.h:741
long int JEND
Upper grid index of the computational domain in the the X2 direction for the local processor...
Definition: globals.h:41
long int IBEG
Lower grid index of the computational domain in the the X1 direction for the local processor...
Definition: globals.h:35
double * A
Right interface area, A[i] = .
Definition: structs.h:87
#define DIMENSIONS
Definition: definitions_01.h:2
#define ALL_DIR
Definition: pluto.h:196