PLUTO
PatchPluto.cpp
Go to the documentation of this file.
1 #ifdef CH_LANG_CC
2 /*
3  * _______ __
4  * / ___/ / ___ __ _ / / ___
5  * / /__/ _ \/ _ \/ V \/ _ \/ _ \
6  * \___/_//_/\___/_/_/_/_.__/\___/
7  * Please refer to Copyright.txt, in Chombo's root directory.
8  */
9 #endif
10 
11 #include <cstdio>
12 #include <string>
13 using std::string;
14 
15 #include "PatchPluto.H"
16 #include "LoHiSide.H"
17 
18 // Flag everything as not defined or set
19 PatchPluto::PatchPluto()
20 {
21  m_isDefined = false;
22  m_isBoundarySet = false;
23  m_isRiemannSet = false;
24  m_isCurrentTimeSet = false;
25  m_isCurrentBoxSet = false;
26 }
27 
28 PatchPluto::~PatchPluto()
29 {
30 }
31 
32 // Define this object and the boundary condition object
33 void PatchPluto::define(ProblemDomain& a_domain,
34  const Real& a_dx,
35  const int& a_level,
36  const int& a_numGhost)
37 {
38 
39  // Store the domain and grid spacing
40  m_domain = a_domain;
41  m_dx = a_dx;
42  m_level = a_level;
43  m_numGhost = a_numGhost;
44 
45  m_isDefined = true;
46 }
47 
48 // Factory method - this object is its own factory. It returns a pointer
49 // to new PatchPluto object with its boundary condtions defined.
50  PatchPluto* PatchPluto::new_patchPluto() const
51 {
52  // Make the new object
53  PatchPluto* retval =
54  static_cast<PatchPluto*>(new PatchPluto());
55 
56  // Set the boundary and Riemann solver values
57  retval->setBoundary(left_bound_side,
58  right_bound_side);
59  retval->setRiemann(rsolver);
60 
61  // Return the new object
62  return retval;
63 }
64 
65 // Set the current physical time - used for time dependent boundary conditions
66 void PatchPluto::setCurrentTime(const Real& a_currentTime)
67 {
68  m_currentTime = a_currentTime;
69  m_isCurrentTimeSet = true;
70 }
71 
72 // Set the current box for the advanceStep call
73 void PatchPluto::setCurrentBox(const Box& a_currentBox)
74 {
75  m_currentBox = a_currentBox;
76  m_isCurrentBoxSet = true;
77 }
78 
79 // Set the values corresponding to boundary conditions
80 void PatchPluto::setBoundary(const int *leftbound,
81  const int *rightbound)
82 {
83 
84  for (int i = 0; i < 3; i++)
85  {
86  left_bound_side[i] = leftbound[i];
87  right_bound_side[i] = rightbound[i];
88  }
89 
90  m_isBoundarySet = true;
91 
92 }
93 
94 // Set the riemann solver to be used
95 void PatchPluto::setRiemann(Riemann_Solver *solver)
96 {
97 
98  rsolver = solver;
99  m_isRiemannSet = true;
100 
101 }
102 
103 // Set the grid[3] structure to be passed to updateState
104 // (or advanceSolution and SWEEP in the next future)
105 void PatchPluto::setGrid(const Box& a_box, struct GRID *grid, FArrayBox& a_dV)
106 {
107  int i, j, k, idim;
109  double stretch, scrh, scrh1, scrh2, scrh3, dxmin[3];
110  double ***dV[CHOMBO_NDV];
111  struct GRID *G;
112 
113  for (int dir = 0; dir < SpaceDim; ++dir){
114  grid[dir].level = m_level;
115  grid[dir].np_tot = a_box.size()[dir]+2*m_numGhost;
116  grid[dir].np_int = a_box.size()[dir];
117  grid[dir].np_tot_glob = m_domain.domainBox().size()[dir]+2*m_numGhost;
118  grid[dir].np_int_glob = m_domain.domainBox().size()[dir];
119  grid[dir].nghost = m_numGhost;
120  grid[dir].beg = a_box.loVect()[dir]+m_numGhost;
121  grid[dir].end = a_box.hiVect()[dir]+m_numGhost;
122  grid[dir].gbeg = m_domain.domainBox().loVect()[dir]+m_numGhost;
123  grid[dir].gend = m_domain.domainBox().hiVect()[dir]+m_numGhost;
124  grid[dir].lbeg = m_numGhost;
125  grid[dir].lend = grid[dir].np_int+m_numGhost-1;
126 
127  grid[dir].lbound = 0;
128  grid[dir].rbound = 0;
129  // Set flags to compute boundary conditions
130  // is_gbeg (left boundary)
131  Box tmp = a_box;
132  tmp.shift(dir,-1);
133  tmp &= m_domain;
134  tmp.shift(dir,1);
135  if (tmp != a_box) grid[dir].lbound = 1;
136  // is_gend (right_boundary)
137  tmp = a_box;
138  tmp.shift(dir,1);
139  tmp &= m_domain;
140  tmp.shift(dir,-1);
141  if (tmp != a_box) grid[dir].rbound = 1;
142 
143  }
144 
145  for (int dir = 0; dir < 3; ++dir){
146  G = grid + dir;
147  if (dir >= SpaceDim) {
148  G->np_int = G->np_tot = G->np_int_glob = G->np_tot_glob = 1;
149  G->nghost = G->beg = G->end = G->gbeg = G->gend =
150  G->lbeg = G->lend = G->lbound = G->rbound = 0;
151  }
152  np_tot_glob = G->np_tot_glob;
153  np_int_glob = G->np_int_glob;
154  np_tot = G->np_tot;
155  np_int = G->np_int;
156 
157  G->x = ARRAY_1D(np_tot, double);
158  G->xr = ARRAY_1D(np_tot, double);
159  G->xl = ARRAY_1D(np_tot, double);
160  G->dx = ARRAY_1D(np_tot, double);
161 
162  stretch = 1.;
163  if (dir == JDIR) stretch = g_x2stretch;
164  if (dir == KDIR) stretch = g_x3stretch;
165 
166  for (i = 0; i < np_tot; i++){
167  #if (CHOMBO_LOGR == YES)
168  if (dir == IDIR) {
169  G->xl[i] = g_domBeg[IDIR]*exp(Real( i+grid[dir].beg-2*grid[dir].nghost )*m_dx);
170  G->xr[i] = g_domBeg[IDIR]*exp(Real(i+1+grid[dir].beg-2*grid[dir].nghost)*m_dx);
171  G->x[i] = 0.5*(G->xr[i]+G->xl[i]);
172  G->dx[i] = G->xr[i]-G->xl[i];
173  } else {
174  #endif
175  G->xl[i] = Real(i+grid[dir].beg-2*grid[dir].nghost)*m_dx*stretch;
176  G->xl[i] += g_domBeg[dir];
177  G->x[i] = G->xl[i]+0.5*m_dx*stretch;
178  G->xr[i] = G->xl[i]+m_dx*stretch;
179  G->dx[i] = m_dx*stretch;
180  #if (CHOMBO_LOGR == YES)
181  }
182  #endif
183  }
184  }
185 
186  CH_assert(m_isBoundarySet);
187  grid[IDIR].lbound *= left_bound_side[IDIR];
188  grid[IDIR].rbound *= right_bound_side[IDIR];
189  grid[JDIR].lbound *= left_bound_side[JDIR];
190  grid[JDIR].rbound *= right_bound_side[JDIR];
191  grid[KDIR].lbound *= left_bound_side[KDIR];
192  grid[KDIR].rbound *= right_bound_side[KDIR];
193  MakeGeometry(grid);
194 
195 // compute cell volumes (dV/m_dx^3) and cylindrical radius
196 
197  #if GEOMETRY != CARTESIAN
198 
199  NX1_TOT = grid[IDIR].np_tot;
200  NX2_TOT = grid[JDIR].np_tot;
201  NX3_TOT = grid[KDIR].np_tot;
202  for (i = 0; i < CHOMBO_NDV; i++) dV[i] = ArrayMap(NX3_TOT, NX2_TOT, NX1_TOT, a_dV.dataPtr(i));
203 
204  #if GEOMETRY == CYLINDRICAL
205  for (k = 0; k < NX3_TOT; k++) {
206  for (j = 0; j < NX2_TOT; j++) {
207  for (i = 0; i < NX1_TOT; i++) {
208  dV[0][k][j][i] = fabs(grid[IDIR].x[i]);
209  #if CH_SPACEDIM > 1
210  dV[0][k][j][i] *= g_x2stretch;
211  #endif
212 
213  #if CHOMBO_CONS_AM == YES
214  dV[1][k][j][i] = grid[IDIR].x[i];
215  #endif
216  }}}
217  #endif
218 
219  #if GEOMETRY == SPHERICAL
220  for (k = 0; k < NX3_TOT; k++) {
221  for (j = 0; j < NX2_TOT; j++) {
222  for (i = 0; i < NX1_TOT; i++) {
223  dV[0][k][j][i] = grid[IDIR].dV[i]/m_dx;
224  #if CH_SPACEDIM > 1
225  dV[0][k][j][i] *= grid[JDIR].dV[j]/m_dx;
226  #endif
227  #if CH_SPACEDIM == 3
228  dV[0][k][j][i] *= g_x3stretch;
229  #endif
230 
231  #if CHOMBO_CONS_AM == YES
232  dV[1][k][j][i] = grid[IDIR].x[i];
233  #if CH_SPACEDIM > 1
234  dV[1][k][j][i] *= sin(grid[JDIR].x[j]);
235  #endif
236  #endif
237  }}}
238  #endif
239 
240  #if GEOMETRY == POLAR
241  for (k = 0; k < NX3_TOT; k++) {
242  for (j = 0; j < NX2_TOT; j++) {
243  for (i = 0; i < NX1_TOT; i++) {
244  dV[0][k][j][i] = grid[IDIR].dV[i]/m_dx;
245  #if CH_SPACEDIM > 1
246  dV[0][k][j][i] *= g_x2stretch;
247  #endif
248  #if CH_SPACEDIM == 3
249  dV[0][k][j][i] *= g_x3stretch;
250  #endif
251 
252  #if CHOMBO_CONS_AM == YES
253  dV[1][k][j][i] = grid[IDIR].x[i];
254  #endif
255  }}}
256  #endif
257 
258  for (i = 0; i < CHOMBO_NDV; i++) FreeArrayMap(dV[i]);
259  #endif /* != CARTESIAN */
260 
261 // compute dl_min
262 
263  #if (GEOMETRY == CARTESIAN) || (GEOMETRY == CYLINDRICAL)
264 
265  grid[IDIR].dl_min = m_dx;
266  grid[JDIR].dl_min = m_dx*g_x2stretch;
267  grid[KDIR].dl_min = m_dx*g_x3stretch;
268 
269  #else
270 
271  IBEG = grid[IDIR].lbeg; IEND = grid[IDIR].lend;
272  JBEG = grid[JDIR].lbeg; JEND = grid[JDIR].lend;
273  KBEG = grid[KDIR].lbeg; KEND = grid[KDIR].lend;
274 
275  for (idim = 0; idim < 3; idim++) dxmin[idim] = 1.e30;
276 
277  for (i = IBEG; i <= IEND; i++) {
278  for (j = JBEG; j <= JEND; j++) {
279  for (k = KBEG; k <= KEND; k++) {
280 
281  #if (TIME_STEPPING == RK2)
282  D_EXPAND(scrh1 = Length_1(i, j, k, grid); ,
283  scrh2 = Length_2(i, j, k, grid); ,
284  scrh3 = Length_3(i, j, k, grid); )
285 
286  scrh = D_EXPAND(1./scrh1, +1./scrh2, +1./scrh3);
287  scrh = (double)DIMENSIONS/scrh;
288  D_EXPAND(dxmin[IDIR] = MIN (dxmin[IDIR], scrh); ,
289  dxmin[JDIR] = dxmin[IDIR]; ,
290  dxmin[KDIR] = dxmin[IDIR]; )
291  #else
292  scrh = Length_1(i, j, k, grid);
293  dxmin[IDIR] = MIN (dxmin[IDIR], scrh);
294 
295  scrh = Length_2(i, j, k, grid);
296  dxmin[JDIR] = MIN (dxmin[JDIR], scrh);
297 
298  scrh = Length_3(i, j, k, grid);
299  dxmin[KDIR] = MIN (dxmin[KDIR], scrh);
300  #endif
301 
302  }}}
303 
304  grid[IDIR].dl_min = dxmin[IDIR];
305  grid[JDIR].dl_min = dxmin[JDIR];
306  grid[KDIR].dl_min = dxmin[KDIR];
307 
308  #endif
309 
310 }
311 
312 // Loop over the patches of a level to assign initial conditions
313 
314 void PatchPluto::initialize(LevelData<FArrayBox>& a_U)
315 {
316 
317  CH_assert(m_isDefined);
318 
319  DataIterator dit = a_U.boxLayout().dataIterator();
320 
321  // Iterator of all grids in this level
322  for (dit.begin(); dit.ok(); ++dit)
323  {
324  // Storage for current grid
325  FArrayBox& U = a_U[dit()];
326  // Set up initial condition in this patch
327  startup(U);
328 
329  }
330 
331 }
332 
333 // Number of conserved variables
334 int PatchPluto::numConserved()
335 {
336  return NVAR;
337 }
338 
339 // Generate default names for the conserved variables, "variable#"
340 Vector<string> PatchPluto::ConsStateNames()
341 {
342  Vector<string> retval;
343  int nv;
344  char varNameChar[80];
345 
346  for (nv = 0; nv < NVAR; nv++){
347  if (nv == RHO) retval.push_back("Density");
348  if (nv == MX1) retval.push_back("X-momentum");
349  if (nv == MX2) retval.push_back("Y-momentum");
350  if (nv == MX3) retval.push_back("Z-momentum");
351 #if PHYSICS == MHD || PHYSICS == RMHD
352  if (nv == BX1) retval.push_back("X-magnfield");
353  if (nv == BX2) retval.push_back("Y-magnfield");
354  if (nv == BX3) retval.push_back("Z-magnfield");
355 #endif
356 #if EOS != ISOTHERMAL
357  if (nv == ENG) retval.push_back("energy-density");
358 #endif
359 
360 #if NTRACER > 0
361  if (nv >= TRC && nv < (TRC + NTRACER)){
362  sprintf(varNameChar,"rho*tracer%d",nv+1-TRC);
363  retval.push_back(string(varNameChar));
364  }
365 #endif
366 #if ENTROPY_SWITCH
367  if (nv == ENTR) retval.push_back("rho*entropy");
368 #endif
369 
370 #ifdef GLM_MHD
371  if (nv == PSI_GLM) retval.push_back("psi_glm");
372 #endif
373 
374 #if COOLING == SNEq
375  if (nv == X_HI) retval.push_back("rho*x_hi");
376 #endif
377 
378 #if COOLING == H2_COOL
379  if (nv >= X_HI && nv < NFLX+NIONS){
380  sprintf(varNameChar,"rho*fX%d",nv-NFLX);
381  retval.push_back(string(varNameChar));
382  }
383 #endif
384 
385 #if COOLING == MINEq
386  if (nv >= X_HI && nv < NFLX+NIONS){
387  sprintf(varNameChar,"rho*fX%d",nv-NFLX);
388  retval.push_back(string(varNameChar));
389  }
390 #endif
391  }
392  return retval;
393 }
394 
395 // Generate default names for the primitive variables, "variable#"
396 Vector<string> PatchPluto::PrimStateNames()
397 {
398  Vector<string> retval;
399  int nv;
400  static Output output;
401 
402  if (output.var_name == NULL){
403  for (nv = 0; nv < NVAR; nv++){
404  output.var_name = ARRAY_2D(64,128,char);
405  }
406  SetDefaultVarNames(&output);
407  }
408 
409  for (nv = 0; nv < NVAR; nv++){
410  retval.push_back(output.var_name[nv]);
411  }
412  return retval;
413 }
414 
415 // Number of flux variables
416 int PatchPluto::numFluxes()
417 {
418  // In some computations there may be more fluxes than conserved variables
419  return NVAR;
420 }
421 
422 // Number of primitive variables
423 int PatchPluto::numPrimitives()
424 {
425  // This doesn't equal the number of conserved variables because
426  // auxiliary/redundant variable may be computed and stored
427  return NVAR;
428 }
429 
430 // Component index within the primitive variables of the pressure
431 int PatchPluto::pressureIndex()
432 {
433  #if EOS != ISOTHERMAL
434  return PRS;
435  #else
436  return -1;
437  #endif
438 
439 }
440 
441 // Return true if everything is defined and setup
442 bool PatchPluto::isDefined() const
443 {
444  return m_isDefined &&
445  m_isBoundarySet &&
446  m_isRiemannSet &&
447  m_isCurrentTimeSet &&
448  m_isCurrentBoxSet;
449 }
double Length_2(int i, int j, int k, Grid *)
Definition: set_geometry.c:169
#define MX3
Definition: mod_defs.h:22
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
void MakeGeometry(Grid *)
Definition: set_geometry.c:16
int end
Global end index for the local array.
Definition: structs.h:116
#define MX1
Definition: mod_defs.h:20
void Riemann_Solver(const State_1D *, int, int, double *, Grid *)
Definition: pluto.h:489
double * xr
Definition: structs.h:81
int np_int_glob
Total number of points in the global domain (boundaries excluded).
Definition: structs.h:98
#define RHO
Definition: mod_defs.h:19
tuple scrh
Definition: configure.py:200
void SetDefaultVarNames(Output *)
Definition: var_names.c:4
int rbound
Same as lbound, but for the right edge of the grid.
Definition: structs.h:112
long int NX2_TOT
Total number of zones in the X2 direction (boundaries included) for the local processor.
Definition: globals.h:57
#define PSI_GLM
Definition: mod_defs.h:34
int lend
Local end index for the local array.
Definition: structs.h:118
int lbeg
Local start index for the local array.
Definition: structs.h:117
double * dV
Cell volume.
Definition: structs.h:86
#define TRC
Definition: pluto.h:581
int gend
Global end index for the global array.
Definition: structs.h:114
double * dx
Definition: structs.h:83
int np_tot_glob
Total number of points in the global domain (boundaries included).
Definition: structs.h:96
void FreeArrayMap(double ***t)
Definition: arrays.c:518
#define KDIR
Definition: pluto.h:195
#define MIN(a, b)
Definition: macros.h:104
double * xl
Definition: structs.h:82
#define NFLX
Definition: mod_defs.h:32
#define IDIR
Definition: pluto.h:193
double Length_1(int i, int j, int k, Grid *)
Definition: set_geometry.c:156
int beg
Global start index for the local array.
Definition: structs.h:115
#define NIONS
Definition: cooling.h:28
Definition: structs.h:78
int gbeg
Global start index for the global array.
Definition: structs.h:113
long int NX3_TOT
Total number of zones in the X3 direction (boundaries included) for the local processor.
Definition: globals.h:59
int j
Definition: analysis.c:2
Definition: cooling.h:110
#define MX2
Definition: mod_defs.h:21
int nghost
Number of ghost zones.
Definition: structs.h:104
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
double dl_min
minimum cell length (e.g.
Definition: structs.h:94
double g_domBeg[3]
Lower limits of the computational domain.
Definition: globals.h:125
double * x
Definition: structs.h:80
#define BX3
Definition: mod_defs.h:27
#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
int i
Definition: analysis.c:2
#define BX1
Definition: mod_defs.h:25
#define NTRACER
double Length_3(int i, int j, int k, Grid *)
Definition: set_geometry.c:186
long int KBEG
Lower grid index of the computational domain in the the X3 direction for the local processor...
Definition: globals.h:43
#define ARRAY_2D(nx, ny, type)
Definition: prototypes.h:171
#define BX2
Definition: mod_defs.h:26
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
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 NX1_TOT
Total number of zones in the X1 direction (boundaries included) for the local processor.
Definition: globals.h:55
char ** var_name
variable names - same for all
Definition: structs.h:242
long int IBEG
Lower grid index of the computational domain in the the X1 direction for the local processor...
Definition: globals.h:35
#define DIMENSIONS
Definition: definitions_01.h:2
double *** ArrayMap(int nx, int ny, int nz, double *uptr)
Definition: arrays.c:421
int np_int
Total number of points in the local domain (boundaries excluded).
Definition: structs.h:102