PLUTO
PatchEuler.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 /* ********************************************************************* */
9 void PatchPluto::advanceStep(FArrayBox& a_U,
10  FArrayBox& a_Utmp,
11  const FArrayBox& a_dV,
12  FArrayBox& split_tags,
13  BaseFab<unsigned char>& a_Flags,
14  FluxBox& a_F,
15  Time_Step *Dts,
16  const Box& UBox,
17  Grid *grid)
18 /*
19  *
20  *
21  *
22  *
23  *********************************************************************** */
24 {
25  CH_assert(isDefined());
26  CH_assert(UBox == m_currentBox);
27 
28  int nv, in;
29  int nxf, nyf, nzf, indf;
30  int nxb, nyb, nzb;
31  int i, j, k;
32 
33  double ***UU[NVAR];
34  double *inv_dl, dl2, cylr;
35  static Data d;
36 #ifdef SKIP_SPLIT_CELLS
37  double ***splitcells;
38 #endif
39 #if (PARABOLIC_FLUX & EXPLICIT)
40  static double **dcoeff;
41 #endif
42  Index indx;
43  static State_1D state;
44 
45  Riemann_Solver *Riemann;
46  Riemann = rsolver;
47 #if TIME_STEPPING == RK2
48  double wflux = 0.5;
49 #else
50  double wflux = 1.;
51 #endif
52  RBox *rbox = GetRBox(DOM, CENTER);
53 
54 /* -----------------------------------------------------------------
55  Check algorithm compatibilities
56  ----------------------------------------------------------------- */
57 
59  print ("! advanceStep(): need to re-allocate matrix\n");
60  QUIT_PLUTO(1);
61  }
62 
63 /* -----------------------------------------------------------------
64  Allocate memory
65  ----------------------------------------------------------------- */
66 
67 #if GEOMETRY != CARTESIAN
68  for (nv = 0; nv < NVAR; nv++) a_U.divide(a_dV,0,nv);
69  #if CHOMBO_CONS_AM == YES
70  #if ROTATING_FRAME == YES
71  Box curBox = a_U.box();
72  for(BoxIterator bit(curBox); bit.ok(); ++bit) {
73  const IntVect& iv = bit();
74  a_U(iv,iMPHI) /= a_dV(iv,1);
75  a_U(iv,iMPHI) -= a_U(iv,RHO)*a_dV(iv,1)*g_OmegaZ;
76  }
77  #else
78  a_U.divide(a_dV,1,iMPHI);
79  #endif
80  #endif
81 #else
82  if (g_stretch_fact != 1.) a_U /= g_stretch_fact;
83 #endif
84 
85  for (nv = 0; nv < NVAR; nv++){
86  UU[nv] = ArrayMap(NX3_TOT, NX2_TOT, NX1_TOT, a_U.dataPtr(nv));
87  }
88 #ifdef SKIP_SPLIT_CELLS
89  splitcells = ArrayBoxMap(KBEG, KEND, JBEG, JEND, IBEG, IEND,
90  split_tags.dataPtr(0));
91 #endif
92 #if (TIME_STEPPING == RK2)
93  d.flag = ArrayCharMap(NX3_TOT, NX2_TOT, NX1_TOT,a_Flags.dataPtr(0));
94 #endif
95 #if RESISTIVITY != NO
96  if (d.J == NULL) d.J = ARRAY_4D(3,NX3_MAX, NX2_MAX, NX1_MAX, double);
97 #endif
98 
99 /* -----------------------------------------------------------
100  Allocate static memory areas
101  ----------------------------------------------------------- */
102 
103  if (state.flux == NULL){
104  MakeState (&state);
105  nxf = nyf = nzf = 1;
106  D_EXPAND(nxf = NMAX_POINT; ,
107  nyf = NMAX_POINT; ,
108  nzf = NMAX_POINT;)
109 
110  d.Vc = ARRAY_4D(NVAR, nzf, nyf, nxf, double);
111 #if (TIME_STEPPING != RK2)
112  d.flag = ARRAY_3D(nzf, nyf, nxf, unsigned char);
113 #endif
114 #if (PARABOLIC_FLUX & EXPLICIT)
115  dcoeff = ARRAY_2D(NMAX_POINT, NVAR, double);
116 #endif
117  }
118 
119  if (g_intStage == 1) TOT_LOOP(k,j,i) d.flag[k][j][i] = 0;
120 
121  getPrimitiveVars (UU, &d, grid);
122 #if (SHOCK_FLATTENING == MULTID) || ENTROPY_SWITCH
123  if (g_intStage == 1) FlagShock (&d, grid); /* Do it only at predictor */
124 #endif
125 
126 #ifdef SKIP_SPLIT_CELLS
127  if (g_intStage == 1) {
128  DOM_LOOP(k,j,i){
129  if (splitcells[k][j][i] < 0.5) d.flag[k][j][i] |= FLAG_SPLIT_CELL;
130  }
131  }
132 #endif
133 
134 /* ----------------------------------------------------
135  Reset arrays
136  ---------------------------------------------------- */
137 
138 #if (TIME_STEPPING == RK2)
139  if (g_intStage == 1) a_Utmp.copy(a_U); //Temporary copy of old conserved variables
140 #endif
141 
142 /* ----------------------------------------------------
143  Loop on directions
144  ---------------------------------------------------- */
145 
146  int numFlux = numFluxes();
147  a_F.resize(UBox,numFlux);
148  a_F.setVal(0.0);
149 
150  static double *aflux[3];
151  for (in = 0; in < DIMENSIONS; in++) aflux[in] = a_F[in].dataPtr(0);
152 
153  UpdateStage(&d, UU, aflux, Riemann, g_dt, Dts, grid);
154 
155 // Compute advective/diffusive timestep (predictor only)
156 
157 #ifdef GLM_MHD
158  if (g_intStage == 1) glm_ch_max_loc = MAX(glm_ch_max_loc, Dts->inv_dta*m_dx);
159 // if (g_intStage == 1) glm_ch_max_loc = MAX(glm_ch_max_loc, Dts->inv_dta); /* If subcycling is turned off */
160 #endif
161 
162 // Final update: average old and new conservative variables
163 
164 #if (TIME_STEPPING == RK2)
165  if (g_intStage == 2) {
166  a_U.plus(a_Utmp);
167  a_U *= 0.5;
168 #endif
169 
170 /* ----------------------------------------------
171  Source terms included via operator splitting
172  ---------------------------------------------- */
173 
174 #ifdef GLM_MHD
175  double dtdx = g_dt/g_coeff_dl_min/m_dx;
176 // double dtdx = g_dt/g_coeff_dl_min; /* If subcycling is turned off */
177  GLM_Source (UU, dtdx, grid);
178 #endif
179 
180 
181 #if COOLING != NO
182  ConsToPrim3D(UU, d.Vc, d.flag, rbox);
183  SplitSource (&d, g_dt, Dts, grid);
184  PrimToCons3D(d.Vc, UU, rbox);
185 #endif
186 
187 #if (TIME_STEPPING == RK2)
188  }
189 #endif
190 
191 #if ENTROPY_SWITCH
192 
193 /* -------------------------------------------------------------------
194  At this point we have U^(n+1) that contains both total energy (E)
195  and entropy (sigma_c) although they have evolved differently.
196  To synchronize them we convert UU to primitive and then again
197  to conservative. This will ensure that in every cell
198  E and sigma_c can be mapped one into another consistently.
199  This step is *essential* when, at then next step,
200  primitive variables will be computed in every zone from entropy
201  rather than selectively from energy and entropy.
202  ------------------------------------------------------------------- */
203 
204  ConsToPrim3D(UU, d.Vc, d.flag, rbox);
205  PrimToCons3D(d.Vc, UU, rbox);
206 #endif
207 
208 
209 /* ---------------------------------------------------------------
210  We pass U*dV/m_dx^3 back to Chombo rather than U.
211  --------------------------------------------------------------- */
212 
213 #if GEOMETRY != CARTESIAN
214  #if CHOMBO_CONS_AM == YES
215  #if ROTATING_FRAME == YES
216  for(BoxIterator bit(curBox); bit.ok(); ++bit) {
217  const IntVect& iv = bit();
218  a_U(iv,iMPHI) += a_U(iv,RHO)*a_dV(iv,1)*g_OmegaZ;
219  a_U(iv,iMPHI) *= a_dV(iv,1);
220  }
221  #else
222  a_U.mult(a_dV,1,iMPHI);
223  #endif
224  #endif
225  for (nv = 0; nv < NVAR; nv++) a_U.mult(a_dV,0,nv);
226  #else
227  if (g_stretch_fact != 1.) a_U *= g_stretch_fact;
228  #endif
229 
230 /* -------------------------------------------------
231  Free memory
232  ------------------------------------------------- */
233 
234  for (nv = 0; nv < NVAR; nv++) FreeArrayMap(UU[nv]);
235 
236  #ifdef SKIP_SPLIT_CELLS
237  FreeArrayBoxMap (splitcells, KBEG, KEND, JBEG, JEND, IBEG, IEND);
238  #endif
239 
240  #if (TIME_STEPPING == RK2)
241  FreeArrayCharMap(d.flag);
242  #endif
243 }
#define MAX(a, b)
Definition: macros.h:101
#define iMPHI
Definition: mod_defs.h:71
DOM_LOOP(k, j, i)
Definition: analysis.c:22
double **** J
Electric current defined as curl(B).
Definition: structs.h:54
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 Riemann_Solver(const State_1D *, int, int, double *, Grid *)
Definition: pluto.h:489
void PrimToCons3D(Data_Arr V, Data_Arr U, RBox *box)
Definition: mappers3D.c:86
#define RHO
Definition: mod_defs.h:19
long int NX2_TOT
Total number of zones in the X2 direction (boundaries included) for the local processor.
Definition: globals.h:57
int g_intStage
Gives the current integration stage of the time stepping method (predictor = 0, 1st corrector = 1...
Definition: globals.h:98
double **** Vc
The main four-index data array used for cell-centered primitive variables.
Definition: structs.h:31
double g_dt
The current integration time step.
Definition: globals.h:118
#define g_OmegaZ
Definition: init.c:64
#define DOM
Computational domain (interior)
Definition: pluto.h:152
#define ARRAY_3D(nx, ny, nz, type)
Definition: prototypes.h:172
void FreeArrayMap(double ***t)
Definition: arrays.c:518
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
void MakeState(State_1D *)
Definition: tools.c:51
#define FLAG_SPLIT_CELL
Zone is covered by a finer level (AMR only).
Definition: pluto.h:183
#define NX3_MAX
Definition: pluto.h:743
double inv_dta
Inverse of advection (hyperbolic) time step, .
Definition: structs.h:215
#define NX2_MAX
Definition: pluto.h:742
#define TOT_LOOP(k, j, i)
Definition: macros.h:44
unsigned char *** ArrayCharMap(int nx, int ny, int nz, unsigned char *uptr)
Definition: arrays.c:476
void FreeArrayCharMap(unsigned char ***t)
Definition: arrays.c:530
Definition: structs.h:78
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
#define ARRAY_4D(nx, ny, nz, nv, type)
Definition: prototypes.h:173
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
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
Definition: structs.h:317
void SplitSource(const Data *, double, Time_Step *, Grid *)
Definition: split_source.c:25
void UpdateStage(const Data *, Data_Arr, double **, Riemann_Solver *, double, Time_Step *, Grid *)
Definition: update_stage.c:38
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
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
void FlagShock(const Data *, Grid *)
long int KEND
Upper grid index of the computational domain in the the X3 direction for the local processor...
Definition: globals.h:45
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 QUIT_PLUTO(e_code)
Definition: macros.h:125
void GLM_Source(const Data_Arr Q, double dt, Grid *grid)
Definition: glm.c:139
#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 NX1_TOT
Total number of zones in the X1 direction (boundaries included) for the local processor.
Definition: globals.h:55
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