PLUTO
sb_flux.c File Reference

Enforce conservation at the X1 boundaries in the shearing-box module. More...

#include "pluto.h"
Include dependency graph for sb_flux.c:

Go to the source code of this file.

Macros

#define NVLAST   (NVAR-1)
 
#define swL   0.0
 
#define swR   (1.0 - swL)
 

Functions

void SB_SaveFluxes (State_1D *state, Grid *grid)
 
void SB_CorrectFluxes (Data_Arr U, double t, double dt, Grid *grid)
 

Variables

static double *** FluxL
 Array of fluxes at the left x-boundary. More...
 
static double *** FluxR
 Array of fluxes at the right x-boundary. More...
 

Detailed Description

Enforce conservation at the X1 boundaries in the shearing-box module.

This file provides functions to store and then modify the upwind fluxes computed during the Riemann solver at the leftmost and righmost physical boundaries. These tasks are performed only when either SB_SYMMETRIZE_HYDRO, SB_SYMMETRIZE_EY, SB_SYMMETRIZE_EZ flags are set to YES in Src/MHD/shearingbox.h and are useful to avoid loss of conservation in the hydrodynamical variables (density, momentum, energy) and/or magnetic fields.

This is first achieved by calling the SB_SaveFluxes() function during the time stepping scheme, with the purpose of storing the leftmost and rightmost conservative fluxes in the x-direction into the static arrays FluxL[] and FluxR[].

These fluxes are then subsequently used by SB_CorrectFluxes() which interpolates the fluxes and properly correct leftmost and rightmost cell-centered flow quantities to ensure conservation.

The treatment of staggered magnetic field is done similarly by SB_CorrectEMF().

References

  • "??"
    Mignone et al, in preparation
Authors
A. Mignone (migno.nosp@m.ne@p.nosp@m.h.uni.nosp@m.to.i.nosp@m.t)
G. Muscianisi (g.mus.nosp@m.ican.nosp@m.isi@c.nosp@m.inec.nosp@m.a.it)
G. Bodo (bodo@.nosp@m.oato.nosp@m..inaf.nosp@m..it)
Date
Feb 14, 2014

Definition in file sb_flux.c.

Macro Definition Documentation

#define NVLAST   (NVAR-1)

Definition at line 44 of file sb_flux.c.

#define swL   0.0

Sets the weight coefficient in the range [0,1] used during flux symmetrization at the left and right boundaries,

FL -> swL*FL    + swR*I(FR)
FR -> swL*I(FL) + swR*FR 

where swR=1-swL and I() stands for conservative interpolation.

Definition at line 53 of file sb_flux.c.

#define swR   (1.0 - swL)

Definition at line 54 of file sb_flux.c.

Function Documentation

void SB_CorrectFluxes ( Data_Arr  U,
double  t,
double  dt,
Grid grid 
)

Interpolate x-fluxes FLuxL and FluxR and properly correct leftmost and rightmost cells to ensure conservation.

Parameters
[in,out]Udata array containing cell-centered quantities
[in]tthe time step at which fluxes have been computed
[in]dtthe time step being used in the integrator stage
[in]gridpointer to array of Grid structures
Note
Modify the values of FluxR (on the left) and FluxL (on the right) to properly account for the shift induced by the moving boundaries. For safety reason (avoid overwriting arrays when a processor owns both the left and the right side) we first copy, then interpolate and finally average:
  • On the left boundary:

    FluxR -> FluxLR -> I(FluxLR) -> fL = wL*FluxL + wR*FluxLR

  • On the right boundary:

    FluxL -> FluxLR -> I(FluxLR) -> fR = wL*FluxLR + wR*FluxR


Definition at line 105 of file sb_flux.c.

116 {
117  int i, j, k, nv;
118  double dtdx;
119  static double **fL, **fR;
120  static double ****Ftmp;
121 
122  #if SB_SYMMETRIZE_HYDRO == NO
123  return;
124  #endif
125 
126  if (fL == NULL){
127  fL = ARRAY_2D(NVAR, NMAX_POINT, double);
128  fR = ARRAY_2D(NVAR, NMAX_POINT, double);
129  Ftmp = ARRAY_4D(NVAR, NX3_TOT, NX2_TOT, 1, double);
130  }
131 
132  dtdx = dt/grid[IDIR].dx[IBEG];
133 
134 {
135 t = g_time;
136 #if TIME_STEPPING == RK2
137  if (g_intStage == 2) t += g_dt;
138 #elif TIME_STEPPING == RK3
139  if (g_intStage == 2) t += 0.5*g_dt;
140  if (g_intStage == 3) t += g_dt;
141 #endif
142 #ifdef CTU
143  if (g_intStage == 2) t += 0.5*g_dt;
144 #endif
145 }
146 
147 /* -----------------------------------------------------------------------
148  Exchange left and right fluxes if they were initially computed on
149  different processors.
150  After this step, both the left- and right- processor- will share
151  the same fluxes FluxL[] and FluxR[].
152  ----------------------------------------------------------------------- */
153 
154  #ifdef PARALLEL
155  ExchangeX (FluxL[0][0], FluxR[0][0], NVAR*NX2_TOT*NX3_TOT, grid);
156  #endif
157 
158 /* --------------------------------------------------------------------- */
159 /*! \note
160  Modify the values of FluxR (on the left) and FluxL (on the right)
161  to properly account for the shift induced by the moving boundaries.
162  For safety reason (avoid overwriting arrays when a processor owns
163  both the left and the right side) we first copy, then interpolate and
164  finally average:
165 
166  - On the left boundary:
167 
168  FluxR -> FluxLR -> I(FluxLR) -> fL = wL*FluxL + wR*FluxLR
169 
170  - On the right boundary:
171 
172  FluxL -> FluxLR -> I(FluxLR) -> fR = wL*FluxLR + wR*FluxR
173 
174  --------------------------------------------------------------------- */
175 
176  if (grid[IDIR].lbound != 0){ /* ---- Left x-boundary ---- */
177 
178  RBox box;
179 
180  /* -- set grid ranges of FluxR and exchange b.c. -- */
181 
182  box.ib = 0; box.ie = 0;
183  box.jb = 0; box.je = NX2_TOT-1;
184  box.kb = 0; box.ke = NX3_TOT-1;
185 
186  /* -- copy FluxR on temporary storage and shift -- */
187 
188  for (nv = 0; nv <= NVLAST; nv++) {
189  BOX_LOOP((&box), k, j, i) Ftmp[nv][k][j][i] = FluxR[nv][k][j];
190  SB_SetBoundaryVar(Ftmp[nv], &box, X1_BEG, t, grid);
191  }
192 
193  /* -- symmetrize fluxes -- */
194 
195  for (k = KBEG; k <= KEND; k++){
196  for (nv = 0; nv <= NVLAST; nv++){
197  for (j = JBEG; j <= JEND; j++){
198  fL[nv][j] = swL*FluxL[nv][k][j] + swR*Ftmp[nv][k][j][0];
199  }}
200  for (j = JBEG; j <= JEND; j++){
201  #if HAVE_ENERGY
202  fL[ENG][j] += swR*sb_vy*(fL[MX2][j] + 0.5*sb_vy*fL[RHO][j]);
203  #endif
204  #ifdef GLM_MHD
205  fL[BX2][j] -= swR*sb_vy*fL[PSI_GLM][j]/glm_ch/glm_ch;
206 /* fL[BX2][j] -= 0.5*sb_vy*FluxL[PSI_GLM][k][j]/glm_ch/glm_ch; */
207  #endif
208  fL[MX2][j] += swR*sb_vy*fL[RHO][j];
209 
210  /* -- update solution vector -- */
211 
212  for (nv = 0; nv <= NVLAST; nv++){
213  U[k][j][IBEG][nv] += dtdx*(fL[nv][j] - FluxL[nv][k][j]);
214  }
215  }
216  }
217  }
218 
219  if (grid[IDIR].rbound != 0){ /* ---- Right x-boundary ---- */
220 
221  /* -- set grid ranges of FluxL and exchange b.c. -- */
222 
223  RBox box;
224  box.ib = 0; box.ie = 0;
225  box.jb = 0; box.je = NX2_TOT-1;
226  box.kb = 0; box.ke = NX3_TOT-1;
227 
228  /* -- copy FluxL on temporary storage and shift -- */
229 
230  for (nv = 0; nv <= NVLAST; nv++) {
231  BOX_LOOP((&box), k, j, i) Ftmp[nv][k][j][i] = FluxL[nv][k][j];
232  SB_SetBoundaryVar(Ftmp[nv], &box, X1_END, t, grid);
233  }
234 
235  /* -- symmetrize fluxes -- */
236 
237  for (k = KBEG; k <= KEND; k++){
238  for (nv = 0; nv <= NVLAST; nv++){
239  for (j = JBEG; j <= JEND; j++){
240  fR[nv][j] = swL*Ftmp[nv][k][j][0] + swR*FluxR[nv][k][j];
241  }}
242  for (j = JBEG; j <= JEND; j++){
243  #if HAVE_ENERGY
244  fR[ENG][j] += swL*sb_vy*(-fR[MX2][j] + 0.5*sb_vy*fR[RHO][j]);
245  #endif
246  #ifdef GLM_MHD
247  fR[BX2][j] += swL*sb_vy*fR[PSI_GLM][j]/glm_ch/glm_ch;
248 /* fR[BX2][j] += 0.5*sb_vy*FluxR[PSI_GLM][k][j]/glm_ch/glm_ch; */
249  #endif
250  fR[MX2][j] -= swL*sb_vy*fR[RHO][j];
251 
252  for (nv = 0; nv <= NVLAST; nv++){
253  U[k][j][IEND][nv] -= dtdx*(fR[nv][j] - FluxR[nv][k][j]);
254  }
255  }
256  }
257  }
258 }
#define X1_BEG
Boundary region at X1 beg.
Definition: pluto.h:146
int jb
Lower corner index in the x2 direction.
Definition: structs.h:349
#define NVLAST
Definition: sb_flux.c:44
static int rbound
Definition: jet_domain.c:25
#define RHO
Definition: mod_defs.h:19
#define BOX_LOOP(B, k, j, i)
Definition: macros.h:70
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
int kb
Lower corner index in the x3 direction.
Definition: structs.h:351
double g_dt
The current integration time step.
Definition: globals.h:118
#define PSI_GLM
Definition: mod_defs.h:34
#define X1_END
Boundary region at X1 end.
Definition: pluto.h:147
double * dx
Definition: structs.h:83
#define swR
Definition: sb_flux.c:54
int ib
Lower corner index in the x1 direction.
Definition: structs.h:347
#define IDIR
Definition: pluto.h:193
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 MX2
Definition: mod_defs.h:21
#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
double sb_vy
Velocity offset (>0), in SB_Boundary().
Definition: sb_boundary.c:24
void SB_SetBoundaryVar(double ***U, RBox *box, int side, double t, Grid *grid)
Definition: sb_tools.c:36
#define swL
Definition: sb_flux.c:53
long int NMAX_POINT
Maximum number of points among the three directions, boundaries excluded.
Definition: globals.h:62
int i
Definition: analysis.c:2
double g_time
The current integration time.
Definition: globals.h:117
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
static double *** FluxL
Array of fluxes at the left x-boundary.
Definition: sb_flux.c:41
static double *** FluxR
Array of fluxes at the right x-boundary.
Definition: sb_flux.c:42
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
long int KEND
Upper grid index of the computational domain in the the X3 direction for the local processor...
Definition: globals.h:45
double glm_ch
The propagation speed of divergence error.
Definition: glm.c:21
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
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

Here is the call graph for this function:

Here is the caller graph for this function:

void SB_SaveFluxes ( State_1D state,
Grid grid 
)

Store leftmost and rightmost conservative fluxes in the x direction into FluxL and FluxR.

Parameters
[in]statepointer to a State_1D structure
[in]gridpointer to an array of Grid structures
Returns
This function has no return value.

Definition at line 57 of file sb_flux.c.

67 {
68  int nv;
69 
70  #if SB_SYMMETRIZE_HYDRO == NO
71  return;
72  #endif
73 
74  if (FluxL == NULL){
75  FluxL = ARRAY_3D(NVAR, NX3_TOT, NX2_TOT, double);
76  FluxR = ARRAY_3D(NVAR, NX3_TOT, NX2_TOT, double);
77  }
78 
79 /* ----------------------------------------------------
80  Save Fluxes on the LEFT physical boundary
81  ---------------------------------------------------- */
82 
83  if (g_dir == IDIR && grid[IDIR].lbound != 0){
84  state->flux[IBEG - 1][MX1] += state->press[IBEG - 1];
85  state->press[IBEG - 1] = 0.0;
86  for (nv = 0; nv <= NVLAST; nv++){
87  FluxL[nv][g_k][g_j] = state->flux[IBEG - 1][nv];
88  }
89  }
90 
91 /* ----------------------------------------------------
92  Save Fluxes on the RIGHT pysical boundary
93  ---------------------------------------------------- */
94 
95  if (g_dir == IDIR && grid[IDIR].rbound != 0){
96  state->flux[IEND][MX1] += state->press[IEND];
97  state->press[IEND] = 0.0;
98  for (nv = 0; nv <= NVLAST; nv++){
99  FluxR[nv][g_k][g_j] = state->flux[IEND][nv];
100  }
101  }
102 }
#define MX1
Definition: mod_defs.h:20
#define NVLAST
Definition: sb_flux.c:44
double ** flux
upwind flux computed with the Riemann solver
Definition: structs.h:149
static int rbound
Definition: jet_domain.c:25
long int NX2_TOT
Total number of zones in the X2 direction (boundaries included) for the local processor.
Definition: globals.h:57
#define ARRAY_3D(nx, ny, nz, type)
Definition: prototypes.h:172
#define IDIR
Definition: pluto.h:193
int g_dir
Specifies the current sweep or direction of integration.
Definition: globals.h:86
int g_j
x2 grid index when sweeping along the x1 or x3 direction.
Definition: globals.h:83
long int NX3_TOT
Total number of zones in the X3 direction (boundaries included) for the local processor.
Definition: globals.h:59
long int IEND
Upper grid index of the computational domain in the the X1 direction for the local processor...
Definition: globals.h:37
int g_k
x3 grid index when sweeping along the x1 or x2 direction.
Definition: globals.h:84
static double *** FluxL
Array of fluxes at the left x-boundary.
Definition: sb_flux.c:41
static double *** FluxR
Array of fluxes at the right x-boundary.
Definition: sb_flux.c:42
double * press
Upwind pressure term computed with the Riemann solver.
Definition: structs.h:164
#define NVAR
Definition: pluto.h:609
long int IBEG
Lower grid index of the computational domain in the the X1 direction for the local processor...
Definition: globals.h:35

Here is the caller graph for this function:

Variable Documentation

double*** FluxL
static

Array of fluxes at the left x-boundary.

Definition at line 41 of file sb_flux.c.

double*** FluxR
static

Array of fluxes at the right x-boundary.

Definition at line 42 of file sb_flux.c.