5 #include "PatchPluto.H"
9 void PatchPluto::advanceStep(FArrayBox& a_U,
11 const FArrayBox& a_dV,
12 FArrayBox& split_tags,
13 BaseFab<unsigned char>& a_Flags,
25 CH_assert(isDefined());
26 CH_assert(UBox == m_currentBox);
29 int nxf, nyf, nzf, indf;
34 double ***UU[
NVAR], *du;
35 #ifdef SKIP_SPLIT_CELLS
38 double inv_dtp, *inv_dl;
42 static double **u, ***
T;
43 #if (PARABOLIC_FLUX & EXPLICIT)
44 static double **dcoeff;
49 static unsigned char *flagp, *flagm;
57 #if !(GEOMETRY == CARTESIAN || GEOMETRY == CYLINDRICAL)
58 print1 (
"! CTU only works in cartesian or cylindrical coordinates\n");
63 print (
"! advanceStep(): need to re-allocate matrix\n");
71 #if GEOMETRY != CARTESIAN
72 for (nv = 0; nv <
NVAR; nv++) a_U.divide(a_dV,0,nv);
73 #if CHOMBO_CONS_AM == YES
74 #if ROTATING_FRAME == YES
75 Box curBox = a_U.box();
76 for(BoxIterator bit(curBox); bit.ok(); ++bit) {
77 const IntVect& iv = bit();
78 a_U(iv,
iMPHI) /= a_dV(iv,1);
82 a_U.divide(a_dV,1,
iMPHI);
86 if (g_stretch_fact != 1.) a_U /= g_stretch_fact;
89 for (nv = 0; nv <
NVAR; nv++){
92 #ifdef SKIP_SPLIT_CELLS
94 split_tags.dataPtr(0));
104 if (state.
flux == NULL){
120 UH =
ARRAY_4D(nzf, nyf, nxf, NVAR,
double);
121 dU =
ARRAY_4D(nzf, nyf, nxf, NVAR,
double);
135 #if THERMAL_CONDUCTION == EXPLICIT
136 T =
ARRAY_3D(nzf, nyf, nxf,
double);
141 TOT_LOOP(k,j,i) d.flag[k][j][i] = 0;
143 #ifdef SKIP_SPLIT_CELLS
145 if (splitcells[k][j][i] < 0.5){
150 getPrimitiveVars (UU, &d, grid);
151 #if (SHOCK_FLATTENING == MULTID) || (ENTROPY_SWITCH)
154 #if THERMAL_CONDUCTION == EXPLICIT
155 TOT_LOOP(k,j,i) T[k][j][i] = d.Vc[PRS][k][j][i]/d.Vc[
RHO][k][j][i];
166 #if (RESISTIVITY == EXPLICIT)
175 for ((*in) = 0; (*in) < indx.
ntot; (*in)++) {
176 NVAR_LOOP(nv) state.v[*in][nv] = d.Vc[nv][k][j][i];
177 state.flag[*in] = d.flag[k][j][i];
183 #if !(PARABOLIC_FLUX & EXPLICIT)
185 Riemann (&state, indx.
beg-1, indx.
end, Dts->
cmax, grid);
189 for (nv = NVAR; nv--; ){
190 state.
rhs[indx.
beg-1][nv] = 0.0;
191 state.
rhs[indx.
end+1][nv] = 0.0;
193 for ((*in) = indx.
beg-1; (*in) <= indx.
end+1; (*in)++){
194 for (nv = NVAR; nv--; ){
195 UU[nv][
k][
j][
i] = u[*in][nv];
196 UH[
k][
j][
i][nv] = u[*in][nv] + state.
rhs[*in][nv];
197 dU[
k][
j][
i][nv] = state.
rhs[*in][nv];
198 state.
up[*in][nv] -= state.
rhs[*in][nv];
199 state.
um[*in][nv] -= state.
rhs[*in][nv];
202 for ((*in) = indx.
beg; (*in) <= indx.
end; (*in)++){
203 for (nv = NVAR; nv--; ){
204 dU[
k][
j][
i][nv] += state.
rhs[*in][nv];
205 UH[
k][
j][
i][nv] += state.
rhs[*in][nv];
206 state.
up[*in][nv] -= state.
rhs[*in][nv];
207 state.
um[*in][nv] -= state.
rhs[*in][nv];
211 for ((*in) = 0; (*in) < indx.
ntot; (*in)++) {
212 for (nv = NVAR; nv--; ) {
213 state.
vp[*in][nv] = state.
vm[*in][nv] = state.
vh[*in][nv] = state.
v[*in][nv];
218 Riemann (&state, indx.
beg-1, indx.
end, Dts->
cmax, grid);
224 #if (VISCOSITY == EXPLICIT)
225 for ((*in) = 0; (*in) < indx.
ntot; (*in)++)
for (nv = NVAR; nv--; )
226 state.par_src[*in][nv] = 0.0;
241 for ((*in) = indx.
beg; (*in) <= indx.
end; (*in)++) {
242 for (nv = NVAR; nv--; ){
243 state.
up[*in][nv] -= state.
rhs[*in][nv];
244 state.
um[*in][nv] -= state.
rhs[*in][nv];
253 for ((*in) = indx.
beg; (*in) <= indx.
end; (*in)++) {
254 for (nv = NVAR; nv--; ){
255 dU[
k][
j][
i][nv] = state.
rhs[*in][nv];
256 UH[
k][
j][
i][nv] = u[*in][nv] + state.
rhs[*in][nv];
259 for ((*in) = indx.
beg; (*in) <= indx.
end; (*in)++) {
260 for (nv = NVAR; nv--; ){
261 dU[
k][
j][
i][nv] += state.
rhs[*in][nv];
262 UH[
k][
j][
i][nv] += state.
rhs[*in][nv];
282 if (errp != 0)
print(
"! PatchUnsplit: error recovering U^{n+1/2}\n");
284 for ((*in) = indx.
beg; (*in) <= indx.
end; (*in)++) {
285 NVAR_LOOP(nv) d.Vc[nv][k][j][i] = state.v[*in][nv];
287 #if THERMAL_CONDUCTION == EXPLICIT
288 for ((*in) = indx.
beg; (*in) <= indx.
end; (*in)++){
298 int numFlux = numFluxes();
299 a_F.resize(UBox,numFlux);
316 #if (RESISTIVITY == EXPLICIT)
331 for ((*in) = indx.
beg-1; (*in) <= indx.
end+1; (*in)++){
332 for (nv = NVAR; nv--; ) {
333 state.
up[*in][nv] += dU[
k][
j][
i][nv];
334 state.
um[*in][nv] += dU[
k][
j][
i][nv];
335 state.
vh[*in][nv] = d.
Vc[nv][
k][
j][
i];
337 flagp[*in] = flagm[*in] = state.
flag[*in] = d.
flag[
k][
j][
i];
353 print (
"! Corner coupled states not physical: reverting to 1st order (level=%d)\n",
357 for ((*in) = indx.
beg-1; (*in) <= indx.
end+1; (*in)++){
360 for (nv = 0; nv <
NVAR; nv++) state.
v[*in][nv] = d.
Vc[nv][k][j][i];
362 for (nv = 0; nv <
NVAR; nv++) {
363 state.
vm[*in][nv] = state.
vp[*in][nv] = state.
vh[*in][nv] = state.
v[*in][nv];
373 Riemann (&state, indx.
beg-1, indx.
end, Dts->
cmax, grid);
374 #if (PARABOLIC_FLUX & EXPLICIT)
377 for ((*in) = indx.
beg-1; (*in) <= indx.
end; (*in)++) {
379 #if VISCOSITY == EXPLICIT
380 inv_dtp =
MAX(inv_dtp, dcoeff[*in][
MX1]);
382 #if RESISTIVITY == EXPLICIT
383 EXPAND(inv_dtp =
MAX(inv_dtp, dcoeff[*in][
BX1]); ,
384 inv_dtp =
MAX(inv_dtp, dcoeff[*in][
BX2]); ,
385 inv_dtp =
MAX(inv_dtp, dcoeff[*in][
BX3]);)
388 inv_dtp =
MAX(inv_dtp, dcoeff[*in][ENG]);
390 inv_dtp *= inv_dl[*in]*inv_dl[*in];
397 saveFluxes (&state, indx.
beg-1, indx.
end, grid);
399 for ((*in) = indx.
beg; (*in) <= indx.
end; (*in)++) {
400 for (nv = 0; nv <
NVAR; nv++) {
401 UU[nv][
k][
j][
i] += state.
rhs[*in][nv];
406 for ((*in) = indx.
beg-1; (*in) <= indx.
end; (*in)++) {
407 #if HAVE_ENERGY && ENTROPY_SWITCH
408 state.
flux[*in][ENG] = 0.0;
409 state.
flux[*in][ENTR] = 0.0;
411 for (nv = 0; nv <
NVAR; nv++) {
412 indf = nv*nzf*nyf*nxf + (k - nzb)*nyf*nxf
415 a_F[
g_dir].dataPtr(0)[indf] = state.
flux[*in][nv];
422 glm_ch_max_loc =
MAX(glm_ch_max_loc, Dts->
inv_dta*m_dx);
424 double dtdx =
g_dt/g_coeff_dl_min/m_dx;
459 #if GEOMETRY != CARTESIAN
460 #if CHOMBO_CONS_AM == YES
461 #if ROTATING_FRAME == YES
462 for(BoxIterator bit(curBox); bit.ok(); ++bit) {
463 const IntVect& iv = bit();
465 a_U(iv,
iMPHI) *= a_dV(iv,1);
468 a_U.mult(a_dV,1,
iMPHI);
471 for (nv = 0; nv <
NVAR; nv++) a_U.mult(a_dV,0,nv);
473 if (g_stretch_fact != 1.) a_U *= g_stretch_fact;
482 #ifdef SKIP_SPLIT_CELLS
double ** v
Cell-centered primitive varables at the base time level, v[i] = .
void ResetState(const Data *, State_1D *, Grid *)
int end
Global end index for the local array.
double ** vh
Primitive state at n+1/2 (only for one step method)
double **** J
Electric current defined as curl(B).
void GetCurrent(const Data *d, int dir, Grid *grid)
double ** flux
upwind flux computed with the Riemann solver
void print1(const char *fmt,...)
void Riemann_Solver(const State_1D *, int, int, double *, Grid *)
void PrimToCons3D(Data_Arr V, Data_Arr U, RBox *box)
double ** rhs
Conservative right hand side.
void States(const State_1D *, int, int, Grid *)
long int NX2_TOT
Total number of zones in the X2 direction (boundaries included) for the local processor.
int g_intStage
Gives the current integration stage of the time stepping method (predictor = 0, 1st corrector = 1...
double **** Vc
The main four-index data array used for cell-centered primitive variables.
double g_dt
The current integration time step.
int lbeg
Local start index for the local array.
double * GetInverse_dl(const Grid *)
#define DOM
Computational domain (interior)
#define ARRAY_3D(nx, ny, nz, type)
double * cmax
Maximum signal velocity for hyperbolic eqns.
void FreeArrayMap(double ***t)
unsigned char *** flag
Pointer to a 3D array setting useful integration flags that are retrieved during integration.
#define FLAG_CONS2PRIM_FAIL
void ConsToPrim3D(Data_Arr U, Data_Arr V, unsigned char ***flag, RBox *box)
void MakeState(State_1D *)
double inv_dtp
Inverse of diffusion (parabolic) time step .
#define FLAG_SPLIT_CELL
Zone is covered by a finer level (AMR only).
double ** vp
prim vars at i+1/2 edge, vp[i] = vL(i+1/2)
double inv_dta
Inverse of advection (hyperbolic) time step, .
int g_i
x1 grid index when sweeping along the x2 or x3 direction.
int CheckNaN(double **, int, int, int)
#define THERMAL_CONDUCTION
#define TOT_LOOP(k, j, i)
int g_dir
Specifies the current sweep or direction of integration.
int beg
Global start index for the local array.
int ConsToPrim(double **ucons, double **uprim, int ibeg, int iend, unsigned char *flag)
int g_j
x2 grid index when sweeping along the x1 or x3 direction.
long int NX3_TOT
Total number of zones in the X3 direction (boundaries included) for the local processor.
#define ARRAY_4D(nx, ny, nz, nv, type)
long int IEND
Upper grid index of the computational domain in the the X1 direction for the local processor...
void print(const char *fmt,...)
void SetIndexes(Index *indx, Grid *grid)
void RightHandSide(const State_1D *state, Time_Step *Dts, int beg, int end, double dt, Grid *grid)
int g_k
x3 grid index when sweeping along the x1 or x2 direction.
double ** vm
prim vars at i-1/2 edge, vm[i] = vR(i-1/2)
double ** uR
same as vR, in conservative vars
#define ARRAY_1D(nx, type)
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;)
long int NMAX_POINT
Maximum number of points among the three directions, boundaries excluded.
void PrimToCons(double **uprim, double **ucons, int ibeg, int iend)
void SplitSource(const Data *, double, Time_Step *, Grid *)
double ** um
same as vm, in conservative vars
void ParabolicFlux(Data_Arr V, Data_Arr J, double ***T, const State_1D *state, double **dcoeff, int beg, int end, Grid *grid)
double *** ArrayBoxMap(int nrl, int nrh, int ncl, int nch, int ndl, int ndh, double *uptr)
void FreeArrayBoxMap(double ***t, int nrl, int nrh, int ncl, int nch, int ndl, int ndh)
long int KBEG
Lower grid index of the computational domain in the the X3 direction for the local processor...
double ** up
same as vp, in conservative vars
#define ARRAY_2D(nx, ny, type)
void FlagShock(const Data *, Grid *)
long int KEND
Upper grid index of the computational domain in the the X3 direction for the local processor...
long int JBEG
Lower grid index of the computational domain in the the X2 direction for the local processor...
#define QUIT_PLUTO(e_code)
void GLM_Source(const Data_Arr Q, double dt, Grid *grid)
long int JEND
Upper grid index of the computational domain in the the X2 direction for the local processor...
#define TRANSVERSE_LOOP(indx, ip, i, j, k)
long int NX1_TOT
Total number of zones in the X1 direction (boundaries included) for the local processor.
long int IBEG
Lower grid index of the computational domain in the the X1 direction for the local processor...
double *** ArrayMap(int nx, int ny, int nz, double *uptr)
int np_int
Total number of points in the local domain (boundaries excluded).
double ** uL
same as vL, in conservative vars