PLUTO
boundary.c File Reference

Set boundary conditions. More...

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

Go to the source code of this file.

Functions

void Boundary (const Data *d, int idim, Grid *grid)
 
void OutflowBound (double ***q, int side, int vpos, Grid *grid)
 
void FlipSign (int side, int type, int *vsign)
 
void ReflectiveBound (double ***q, int s, int side, int vpos)
 
void PeriodicBound (double ***q, int side, int vpos)
 

Detailed Description

Set boundary conditions.

The Boundary() function sets both internal and physical boundary conditions on one or more sides of the computational domain. It is used to fill ghost zones of both cell-centered and face-centered data arrays.
The type of boundary conditions at the leftmost or rightmost side of a given grid is specified by the integers grid[dir].lbound or grid[dir].rbound , respectively. When this value is different from zero, the local processor borders the physical boundary and the admissible values for lbound or rbound are OUTFLOW, REFLECTIVE, AXISYMMETRIC, EQTSYMMETRIC, PERIODIC, SHEARING or USERDEF. Conversely, when this value is zero (internal boundary), two neighboring processors that share the same side need to fill ghost zones by exchanging data values. This step is done here only for parallel computations on static grids.

Predefined physical boundary conditions are handled by the following functions:

Author
A. Mignone (migno.nosp@m.ne@p.nosp@m.h.uni.nosp@m.to.i.nosp@m.t)
Date
Dec 18, 2014

Definition in file boundary.c.

Function Documentation

void Boundary ( const Data d,
int  idim,
Grid grid 
)

Set boundary conditions on one or more sides of the computational domain.

Parameters
[in,out]dpointer to PLUTO Data structure containing the solution array (including centered and staggered fields)
[in]idimspecifies on which side(s) of the computational domain boundary conditions must be set. Possible values are
  • idim = IDIR first dimension (x1)
  • idim = JDIR second dimenson (x2)
  • idim = KDIR third dimension (x3)
  • idim = ALL_DIR all dimensions
[in]gridpointer to an array of grid structures.

Definition at line 36 of file boundary.c.

54 {
55  int is, nv, fargo_velocity_has_changed;
56  int side[6] = {X1_BEG, X1_END, X2_BEG, X2_END, X3_BEG, X3_END};
57  int type[6], sbeg, send, vsign[NVAR];
58  int par_dim[3] = {0, 0, 0};
59  double ***q;
60 
61 /* ---------------------------------------------------
62  Check the number of processors in each direction
63  --------------------------------------------------- */
64 
65  D_EXPAND(par_dim[0] = grid[IDIR].nproc > 1; ,
66  par_dim[1] = grid[JDIR].nproc > 1; ,
67  par_dim[2] = grid[KDIR].nproc > 1;)
68 
69 /* -------------------------------------------------
70  With FARGO, boundary conditions must be set on
71  total velocity.
72  We temporarily add the background motion if
73  the input array contains the deviation only.
74  ------------------------------------------------- */
75 
76  #ifdef FARGO
77  fargo_velocity_has_changed = NO;
78  if (FARGO_HasTotalVelocity() == NO) {
79  FARGO_AddVelocity (d,grid);
80  fargo_velocity_has_changed = YES;
81  }
82  #endif
83 
84 /* -------------------------------------------------
85  Call userdef internal boundary with side == 0
86  ------------------------------------------------- */
87 
88  #if INTERNAL_BOUNDARY == YES
89  UserDefBoundary (d, NULL, 0, grid);
90  #endif
91 
92 /* -------------------------------------
93  Exchange data between processors
94  ------------------------------------- */
95 
96  #ifdef PARALLEL
97  MPI_Barrier (MPI_COMM_WORLD);
98  for (nv = 0; nv < NVAR; nv++) {
99  AL_Exchange_dim ((char *)d->Vc[nv][0][0], par_dim, SZ);
100  }
101  #ifdef STAGGERED_MHD
102  D_EXPAND(
103  AL_Exchange_dim ((char *)(d->Vs[BX1s][0][0] - 1), par_dim, SZ_stagx); ,
104  AL_Exchange_dim ((char *)d->Vs[BX2s][0][-1] , par_dim, SZ_stagy); ,
105  AL_Exchange_dim ((char *)d->Vs[BX3s][-1][0] , par_dim, SZ_stagz);)
106  #endif
107  MPI_Barrier (MPI_COMM_WORLD);
108  #endif
109 
110 /* ----------------------------------------------------------------
111  When idim == ALL_DIR boundaries are imposed on ALL sides:
112  a loop from sbeg = 0 to send = 2*DIMENSIONS - 1 is performed.
113  When idim = n, boundaries are imposed at the beginning and
114  the end of the i-th direction.
115  ---------------------------------------------------------------- */
116 
117  if (idim == ALL_DIR) {
118  sbeg = 0;
119  send = 2*DIMENSIONS - 1;
120  } else {
121  sbeg = 2*idim;
122  send = 2*idim + 1;
123  }
124 
125 /* --------------------------------------------------------
126  Main loop on computational domain sides
127  -------------------------------------------------------- */
128 
129  type[0] = grid[IDIR].lbound; type[1] = grid[IDIR].rbound;
130  type[2] = grid[JDIR].lbound; type[3] = grid[JDIR].rbound;
131  type[4] = grid[KDIR].lbound; type[5] = grid[KDIR].rbound;
132 
133  for (is = sbeg; is <= send; is++){
134 
135  if (type[is] == 0) continue; /* no physical boundary: skip */
136 
137  if (type[is] == OUTFLOW) {
138 
139  /* -------------------------------
140  OUTFLOW boundary condition
141  ------------------------------- */
142 
143  for (nv = 0; nv < NVAR; nv++){
144  OutflowBound (d->Vc[nv], side[is], CENTER, grid + (is/2));
145  }
146  #ifdef STAGGERED_MHD
147  D_EXPAND(OutflowBound (d->Vs[BX1s], side[is], X1FACE, grid+(is/2)); ,
148  OutflowBound (d->Vs[BX2s], side[is], X2FACE, grid+(is/2)); ,
149  OutflowBound (d->Vs[BX3s], side[is], X3FACE, grid+(is/2));)
150 
151  /* ---------------------------------------------------------
152  average normal field only since transverse components
153  are assigned consistently with cell-centered quantities.
154  --------------------------------------------------------- */
155 
156  CT_AverageNormalMagField (d, side[is], grid);
157  #endif
158 
159  }else if ( (type[is] == REFLECTIVE)
160  || (type[is] == AXISYMMETRIC)
161  || (type[is] == EQTSYMMETRIC)){
162 
163  /* -------------------------------------
164  REFLECTIVE-type boundary conditions
165  ------------------------------------- */
166 
167  FlipSign (side[is], type[is], vsign);
168  for (nv = 0; nv < NVAR; nv++){
169  ReflectiveBound (d->Vc[nv], vsign[nv], side[is], CENTER);
170  }
171  #ifdef STAGGERED_MHD
172  D_EXPAND(ReflectiveBound(d->Vs[BX1s], vsign[BX1], side[is], X1FACE); ,
173  ReflectiveBound(d->Vs[BX2s], vsign[BX2], side[is], X2FACE); ,
174  ReflectiveBound(d->Vs[BX3s], vsign[BX3], side[is], X3FACE);)
175  #endif
176 
177  }else if (type[is] == PERIODIC) {
178 
179  /* ----------------------------------------
180  PERIODIC boundary condition (only for
181  one processor in the direction)
182  ---------------------------------------- */
183 
184  if (!par_dim[is/2]) {
185  for (nv = 0; nv < NVAR; nv++){
186  PeriodicBound (d->Vc[nv], side[is], CENTER);
187  }
188  #ifdef STAGGERED_MHD
189  D_EXPAND(PeriodicBound (d->Vs[BX1s], side[is], X1FACE); ,
190  PeriodicBound (d->Vs[BX2s], side[is], X2FACE); ,
191  PeriodicBound (d->Vs[BX3s], side[is], X3FACE);)
192  #endif
193 
194  }
195 
196  }else if (type[is] == SHEARING) { /* -- shearingbox boundary -- */
197 
198  /* ---------------------------------------------------------
199  SHEARING-BOX boundary condition is implemented as
200 
201  1) apply periodic boundary conditions for all variables
202  (except staggered BX)
203  2) Perform spatial shift in the y-direction
204  --------------------------------------------------------- */
205 
206  #ifdef SHEARINGBOX
207  if (side[is] != X1_BEG && side[is] != X1_END){
208  print1 ("! BOUNDARY: shearingbox can only be assigned at an X1 boundary\n");
209  QUIT_PLUTO(1);
210  }
211  if (grid[IDIR].nproc == 1){
212  for (nv = 0; nv < NVAR; nv++) {
213  PeriodicBound (d->Vc[nv], side[is], CENTER);
214  }
215  #ifdef STAGGERED_MHD
216  D_EXPAND( ; ,
217  PeriodicBound (d->Vs[BX2s], side[is], X2FACE); ,
218  PeriodicBound (d->Vs[BX3s], side[is], X3FACE);)
219  #endif
220  }
221  SB_Boundary (d, side[is], grid);
222 
223  /* -- assign normal component of staggered B
224  using the div.B = 0 condition -- */
225 
226  #ifdef STAGGERED_MHD
227  FillMagneticField (d, side[is], grid);
228  CT_AverageNormalMagField (d, side[is], grid);
229  CT_AverageTransverseMagField (d, side[is], grid);
230  #endif
231  #endif /* def SHEARINGBOX */
232 
233  }else if (type[is] == USERDEF) {
234 
235  /* --------------------------------------------------------------
236  USER-DEFINED boundary condition
237  -------------------------------------------------------------- */
238 
239  #ifdef GLM_MHD
240  {int i,j,k;
241  switch(side[is]){
242  case X1_BEG: X1_BEG_LOOP(k,j,i) d->Vc[PSI_GLM][k][j][i] = 0.0; break;
243  case X1_END: X1_END_LOOP(k,j,i) d->Vc[PSI_GLM][k][j][i] = 0.0; break;
244  case X2_BEG: X2_BEG_LOOP(k,j,i) d->Vc[PSI_GLM][k][j][i] = 0.0; break;
245  case X2_END: X2_END_LOOP(k,j,i) d->Vc[PSI_GLM][k][j][i] = 0.0; break;
246  case X3_BEG: X3_BEG_LOOP(k,j,i) d->Vc[PSI_GLM][k][j][i] = 0.0; break;
247  case X3_END: X3_END_LOOP(k,j,i) d->Vc[PSI_GLM][k][j][i] = 0.0; break;
248  }
249  }
250  #endif
251 
252  RBox *box = GetRBox(side[is], CENTER);
253  UserDefBoundary (d, box, side[is], grid);
254  #ifdef STAGGERED_MHD
255  D_EXPAND(box = GetRBox(side[is], X1FACE);
256  UserDefBoundary (d, box, side[is], grid); ,
257  box = GetRBox(side[is], X2FACE);
258  UserDefBoundary (d, box, side[is], grid); ,
259  box = GetRBox(side[is], X3FACE);
260  UserDefBoundary (d, box, side[is], grid);)
261 
262  /* -- assign normal component of staggered B
263  using the div.B = 0 condition -- */
264 
265  FillMagneticField (d, side[is], grid);
266  CT_AverageNormalMagField (d, side[is], grid);
267  CT_AverageTransverseMagField (d, side[is], grid);
268  #endif
269  }
270  }
271 
272 /* --------------------------------------------------
273  With FARGO, restore velocity deviation if the
274  original input array to Boundary() did not
275  contain the background velocity.
276  -------------------------------------------------- */
277 
278  #ifdef FARGO
279  if (fargo_velocity_has_changed){
281  }
282  #endif
283 
284 /* -------------------------------------------------------
285  Compute entropy for the next time level
286  ------------------------------------------------------- */
287 
288  #if ENTROPY_SWITCH
289  ComputeEntropy (d, grid);
290  #endif
291 
292 }
#define X3_BEG
Boundary region at X3 beg.
Definition: pluto.h:150
#define SHEARING
Definition: pluto.h:138
int AL_Exchange_dim(char *buf, int *dims, int sz_ptr)
#define X1_BEG
Boundary region at X1 beg.
Definition: pluto.h:146
int lbound
When different from zero, it specifies the boundary condition to be applied at leftmost grid side whe...
Definition: structs.h:105
double **** Vs
The main four-index data array used for face-centered staggered magnetic fields.
Definition: structs.h:43
RBox * GetRBox(int, int)
Definition: rbox.c:232
void OutflowBound(double ***q, int side, int vpos, Grid *grid)
Definition: boundary.c:295
#define CENTER
Definition: pluto.h:200
void FillMagneticField(const Data *d, int side, Grid *grid)
Assign the normal component of the staggered magnetic field in the ghost zone-faces.
void print1(const char *fmt,...)
Definition: amrPluto.cpp:511
#define X3FACE
Definition: pluto.h:203
void SB_Boundary(const Data *d, int side, Grid *grid)
Definition: sb_boundary.c:27
#define YES
Definition: pluto.h:25
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
void FlipSign(int side, int type, int *vsign)
Definition: boundary.c:408
void PeriodicBound(double ***q, int side, int vpos)
Definition: boundary.c:568
#define PSI_GLM
Definition: mod_defs.h:34
#define X3_END_LOOP(k, j, i)
Definition: macros.h:52
#define BX3s
Definition: ct.h:29
#define X1_END
Boundary region at X1 end.
Definition: pluto.h:147
void FARGO_AddVelocity(const Data *, Grid *)
#define X2_BEG_LOOP(k, j, i)
Definition: macros.h:47
#define KDIR
Definition: pluto.h:195
int FARGO_HasTotalVelocity()
int SZ_stagx
Definition: globals.h:24
void ComputeEntropy(const Data *, Grid *)
int SZ_stagy
Definition: globals.h:25
#define X1FACE
Definition: pluto.h:201
void FARGO_SubtractVelocity(const Data *, Grid *)
#define X2_END_LOOP(k, j, i)
Definition: macros.h:51
#define IDIR
Definition: pluto.h:193
#define USERDEF
Definition: pluto.h:139
#define X2_END
Boundary region at X2 end.
Definition: pluto.h:149
int j
Definition: analysis.c:2
int SZ_stagz
Definition: globals.h:26
int k
Definition: analysis.c:2
void CT_AverageNormalMagField(const Data *d, int side, Grid *grid)
Compute the normal component of the volume-average magnetic field from the staggered components in th...
#define BX1s
Definition: ct.h:27
#define X1_END_LOOP(k, j, i)
Definition: macros.h:50
void CT_AverageTransverseMagField(const Data *d, int side, Grid *grid)
Compute the transverse component of the volume-average magnetic field from the staggered components i...
#define BX3
Definition: mod_defs.h:27
#define X3_END
Boundary region at X3 end.
Definition: pluto.h:151
#define OUTFLOW
Definition: pluto.h:133
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
#define X1_BEG_LOOP(k, j, i)
Definition: macros.h:46
#define REFLECTIVE
Definition: pluto.h:134
int i
Definition: analysis.c:2
#define BX1
Definition: mod_defs.h:25
void ReflectiveBound(double ***q, int s, int side, int vpos)
Definition: boundary.c:501
#define BX2s
Definition: ct.h:28
#define X2_BEG
Boundary region at X2 beg.
Definition: pluto.h:148
#define AXISYMMETRIC
Definition: pluto.h:135
#define BX2
Definition: mod_defs.h:26
#define PERIODIC
Definition: pluto.h:137
Definition: al_hidden.h:38
#define EQTSYMMETRIC
Definition: pluto.h:136
#define JDIR
Definition: pluto.h:194
#define NVAR
Definition: pluto.h:609
Definition: structs.h:346
static Runtime q
#define QUIT_PLUTO(e_code)
Definition: macros.h:125
#define X2FACE
Definition: pluto.h:202
void UserDefBoundary(const Data *, RBox *, int, Grid *)
Definition: init.c:98
#define X3_BEG_LOOP(k, j, i)
Definition: macros.h:48
int nproc
number of processors for this grid.
Definition: structs.h:120
#define DIMENSIONS
Definition: definitions_01.h:2
#define NO
Definition: pluto.h:26
#define ALL_DIR
Definition: pluto.h:196

Here is the call graph for this function:

Here is the caller graph for this function:

void FlipSign ( int  side,
int  type,
int *  vsign 
)

Reverse the sign of vector components with respect to axis side. Depending on type, one needs to symmetrize or anti-symmetrize:

  • REFLECTIVE:
    o Vn -> -Vn, Bn -> -Bn
    o Vp -> Vp, Bp -> Bp
    o Vt -> Vt, Bt -> Bt
  • AXISYMMETRIC:
    o Vn -> -Vn, Bn -> -Bn
    o Vp -> Vp, Bp -> Bp
    o Vt -> -Vt, Bt -> -Bt
  • EQTSYMMETRIC:
    o Vn -> -Vn, Bn -> Bn
    o Vp -> Vp, Bp -> -Bp
    o Vt -> Vt, Bt -> -Bt

where (n) is the normal components, (p) and (t) are the transverse (or poloidal and toroidal for cylindrical and spherical coordinates) components.

Parameters
[in]sideboundary side
[in]typeboundary condition type
[out]vsignan array of values (+1 or -1) giving the sign

Definition at line 408 of file boundary.c.

436 {
437  int nv;
438  int Vn, Vp, Vt;
439  int Bn, Bp, Bt;
440 
441  #if PHYSICS == ADVECTION
442  for (nv = 0; nv < NVAR; nv++) vsign[nv] = 1.0;
443  return;
444  #endif
445 
446 /* ----------------------------------------------------------
447  get normal (n), poloidal (p) and toroidal (t) vector
448  components. The ordering is the same as in SetIndexes()
449  ---------------------------------------------------------- */
450 
451  if (side == X1_BEG || side == X1_END){
452  Vn = VX1; Vp = VX2; Vt = VX3;
453  #if PHYSICS == MHD || PHYSICS == RMHD
454  Bn = BX1; Bp = BX2; Bt = BX3;
455  #endif
456  }else if (side == X2_BEG || side == X2_END){
457  Vn = VX2; Vp = VX1; Vt = VX3;
458  #if PHYSICS == MHD || PHYSICS == RMHD
459  Bn = BX2; Bp = BX1; Bt = BX3;
460  #endif
461  }else if (side == X3_BEG || side == X3_END){
462  Vn = VX3; Vp = VX1; Vt = VX2;
463  #if PHYSICS == MHD || PHYSICS == RMHD
464  Bn = BX3; Bp = BX1; Bt = BX2;
465  #endif
466  }
467 
468 /* ---------------------------------------
469  decide which variable flips sign
470  --------------------------------------- */
471 
472  for (nv = 0; nv < NVAR; nv++) vsign[nv] = 1.0;
473 
474  vsign[Vn] = -1.0;
475  #if PHYSICS == MHD || PHYSICS == RMHD
476  vsign[Bn] = -1.0;
477  #endif
478 
479  #if COMPONENTS == 3
480  if (type == AXISYMMETRIC){
481  vsign[Vt] = -1.0;
482  #if PHYSICS == MHD || PHYSICS == RMHD
483  vsign[Bt] = -1.0;
484  #endif
485  }
486  #endif
487 
488  #if PHYSICS == MHD || PHYSICS == RMHD
489  if (type == EQTSYMMETRIC){
490  EXPAND(vsign[Bn] = 1.0; ,
491  vsign[Bp] = -1.0; ,
492  vsign[Bt] = -1.0;)
493  #ifdef GLM_MHD
494  vsign[PSI_GLM] = -1.0;
495  #endif
496  }
497  #endif
498 }
#define X3_BEG
Boundary region at X3 beg.
Definition: pluto.h:150
#define X1_BEG
Boundary region at X1 beg.
Definition: pluto.h:146
#define VX2
Definition: mod_defs.h:29
#define PSI_GLM
Definition: mod_defs.h:34
#define X1_END
Boundary region at X1 end.
Definition: pluto.h:147
#define VX1
Definition: mod_defs.h:28
#define X2_END
Boundary region at X2 end.
Definition: pluto.h:149
#define BX3
Definition: mod_defs.h:27
#define X3_END
Boundary region at X3 end.
Definition: pluto.h:151
#define BX1
Definition: mod_defs.h:25
#define VX3
Definition: mod_defs.h:30
#define X2_BEG
Boundary region at X2 beg.
Definition: pluto.h:148
#define AXISYMMETRIC
Definition: pluto.h:135
#define BX2
Definition: mod_defs.h:26
#define EQTSYMMETRIC
Definition: pluto.h:136
#define NVAR
Definition: pluto.h:609
#define GLM_MHD
Definition: glm.h:25

Here is the caller graph for this function:

void OutflowBound ( double ***  q,
int  side,
int  vpos,
Grid grid 
)

Impose zero-gradient boundary conditions on 'q' on the boundary side specified by box->side. The staggered component of magnetic field is assigned using the div.B = 0 condition in a different loop.

Parameters
[in,out]qa 3D array representing a flow variable
[in]boxpointer to a RBox structure defining the extent of the boundary region and the variable position inside the cell
[in]gridpointer to an array of Grid structures

Definition at line 295 of file boundary.c.

308 {
309  int i, j, k;
310  double dB, *A, *dV;
311  RBox *box = GetRBox (side, vpos);
312 
313  A = grid->A;
314  dV = grid->dV;
315 
316  if (side == X1_BEG) {
317  if (box->vpos != X1FACE){
318  BOX_LOOP(box,k,j,i) q[k][j][i] = q[k][j][IBEG];
319  }else{
320  BOX_LOOP(box,k,j,i){
321  #if GEOMETRY == CARTESIAN
322  q[k][j][i] = 2.0*q[k][j][i+1] - q[k][j][i+2];
323  #else
324  dB = (A[i+2]*q[k][j][i+2] - A[i+1]*q[k][j][i+1])/dV[i+2];
325  q[k][j][i] = (q[k][j][i+1]*A[i+1] - dV[i+1]*dB)/A[i];
326  #endif
327  }
328  }
329 
330  }else if (side == X1_END){
331 
332  if (box->vpos != X1FACE){
333  BOX_LOOP(box,k,j,i) q[k][j][i] = q[k][j][IEND];
334  }else{
335  BOX_LOOP(box,k,j,i){
336  #if GEOMETRY == CARTESIAN
337  q[k][j][i] = 2.0*q[k][j][i-1] - q[k][j][i-2];
338  #else
339  dB = (A[i-1]*q[k][j][i-1] - A[i-2]*q[k][j][i-2])/dV[i-1];
340  q[k][j][i] = (q[k][j][i-1]*A[i-1] + dV[i]*dB)/A[i];
341  #endif
342  }
343  }
344 
345  }else if (side == X2_BEG){
346 
347  if (box->vpos != X2FACE) {
348  BOX_LOOP(box,k,j,i) q[k][j][i] = q[k][JBEG][i];
349  }else{
350  BOX_LOOP(box,k,j,i) {
351  #if GEOMETRY == CARTESIAN
352  q[k][j][i] = 2.0*q[k][j+1][i] - q[k][j+2][i];
353  #else
354  dB = (A[j+2]*q[k][j+2][i] - A[j+1]*q[k][j+1][i])/dV[j+2];
355  q[k][j][i] = (q[k][j+1][i]*A[j+1] - dV[j+1]*dB)/A[j];
356  #endif
357  }
358  }
359 
360  }else if (side == X2_END){
361 
362  if (box->vpos != X2FACE) {
363  BOX_LOOP(box,k,j,i) q[k][j][i] = q[k][JEND][i];
364  }else{
365  BOX_LOOP(box,k,j,i){
366  #if GEOMETRY == CARTESIAN
367  q[k][j][i] = 2.0*q[k][j-1][i] - q[k][j-2][i];
368  #else
369  dB = (A[j-1]*q[k][j-1][i] - A[j-2]*q[k][j-2][i])/dV[j-1];
370  q[k][j][i] = (q[k][j-1][i]*A[j-1] + dV[j]*dB)/A[j];
371  #endif
372  }
373  }
374 
375  }else if (side == X3_BEG){
376 
377  if (box->vpos != X3FACE) {
378  BOX_LOOP(box,k,j,i) q[k][j][i] = q[KBEG][j][i];
379  }else{
380  BOX_LOOP(box,k,j,i) {
381  #if GEOMETRY == CARTESIAN
382  q[k][j][i] = 2.0*q[k+1][j][i] - q[k+2][j][i];
383  #else
384  dB = (A[k+2]*q[k+2][j][i] - A[k+1]*q[k+1][j][i])/dV[k+2];
385  q[k][j][i] = (q[k+1][j][i]*A[k+1] - dV[k+1]*dB)/A[k];
386  #endif
387  }
388  }
389 
390  }else if (side == X3_END){
391 
392  if (box->vpos != X3FACE) {
393  BOX_LOOP(box,k,j,i) q[k][j][i] = q[KEND][j][i];
394  }else{
395  BOX_LOOP(box,k,j,i) {
396  #if GEOMETRY == CARTESIAN
397  q[k][j][i] = 2.0*q[k-1][j][i] - q[k-2][j][i];
398  #else
399  dB = (A[k-1]*q[k-1][j][i] - A[k-2]*q[k-2][j][i])/dV[k-1];
400  q[k][j][i] = (q[k-1][j][i]*A[k-1] + dV[k]*dB)/A[k];
401  #endif
402  }
403  }
404  }
405 }
#define X3_BEG
Boundary region at X3 beg.
Definition: pluto.h:150
#define X1_BEG
Boundary region at X1 beg.
Definition: pluto.h:146
RBox * GetRBox(int, int)
Definition: rbox.c:232
int vpos
Location of the variable inside the cell.
Definition: structs.h:359
double dB
Definition: analysis.c:4
#define X3FACE
Definition: pluto.h:203
#define BOX_LOOP(B, k, j, i)
Definition: macros.h:70
double * dV
Cell volume.
Definition: structs.h:86
#define X1_END
Boundary region at X1 end.
Definition: pluto.h:147
#define X1FACE
Definition: pluto.h:201
#define X2_END
Boundary region at X2 end.
Definition: pluto.h:149
int j
Definition: analysis.c:2
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
#define X3_END
Boundary region at X3 end.
Definition: pluto.h:151
int i
Definition: analysis.c:2
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
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
Definition: structs.h:346
static Runtime q
#define X2FACE
Definition: pluto.h:202
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

Here is the call graph for this function:

Here is the caller graph for this function:

void PeriodicBound ( double ***  q,
int  side,
int  vpos 
)

Implements periodic boundary conditions in serial mode.

Definition at line 568 of file boundary.c.

573 {
574  int i, j, k;
575  RBox *box = GetRBox(side, vpos);
576 
577  if (side == X1_BEG){
578 
579  BOX_LOOP(box,k,j,i) q[k][j][i] = q[k][j][i + NX1];
580 
581  }else if (side == X1_END){
582 
583  BOX_LOOP(box,k,j,i) q[k][j][i] = q[k][j][i - NX1];
584 
585  }else if (side == X2_BEG){
586 
587  BOX_LOOP(box,k,j,i) q[k][j][i] = q[k][j + NX2][i];
588 
589  }else if (side == X2_END){
590 
591  BOX_LOOP(box,k,j,i) q[k][j][i] = q[k][j - NX2][i];
592 
593  }else if (side == X3_BEG){
594 
595  BOX_LOOP(box,k,j,i) q[k][j][i] = q[k + NX3][j][i];
596 
597  }else if (side == X3_END){
598 
599  BOX_LOOP(box,k,j,i) q[k][j][i] = q[k - NX3][j][i];
600 
601  }
602 }
#define X3_BEG
Boundary region at X3 beg.
Definition: pluto.h:150
#define X1_BEG
Boundary region at X1 beg.
Definition: pluto.h:146
RBox * GetRBox(int, int)
Definition: rbox.c:232
long int NX1
Number of interior zones in the X1 directions (boundaries excluded) for the local processor...
Definition: globals.h:48
#define BOX_LOOP(B, k, j, i)
Definition: macros.h:70
#define X1_END
Boundary region at X1 end.
Definition: pluto.h:147
long int NX2
Number of interior zones in the X2 directions (boundaries excluded) for the local processor...
Definition: globals.h:50
#define X2_END
Boundary region at X2 end.
Definition: pluto.h:149
int j
Definition: analysis.c:2
if(divB==NULL)
Definition: analysis.c:10
int k
Definition: analysis.c:2
#define X3_END
Boundary region at X3 end.
Definition: pluto.h:151
int i
Definition: analysis.c:2
#define X2_BEG
Boundary region at X2 beg.
Definition: pluto.h:148
Definition: structs.h:346
static Runtime q
long int NX3
Number of interior zones in the X3 directions (boundaries excluded) for the local processor...
Definition: globals.h:52

Here is the call graph for this function:

Here is the caller graph for this function:

void ReflectiveBound ( double ***  q,
int  s,
int  side,
int  vpos 
)

Make symmetric (s = 1) or anti-symmetric (s=-1) profiles with respect to the boundary plane specified by box->side. The sign is set by the FlipSign() function.

Parameters
[in,out]qa 3D flow quantity
[in]boxpointer to box structure
[in]san integer taking only the values +1 (symmetric profile) or -1 (antisymmetric profile)

Definition at line 501 of file boundary.c.

513 {
514  int i, j, k;
515  RBox *box = GetRBox(side, vpos);
516 
517  if (side == X1_BEG) {
518 
519  if (box->vpos != X1FACE){
520  BOX_LOOP(box,k,j,i) q[k][j][i] = s*q[k][j][2*IBEG-i-1];
521  }else{
522  BOX_LOOP(box,k,j,i) q[k][j][i] = s*q[k][j][2*IBEG-i-2];
523  }
524 
525  }else if (side == X1_END){
526 
527  if (box->vpos != X1FACE){
528  BOX_LOOP(box,k,j,i) q[k][j][i] = s*q[k][j][2*IEND-i+1];
529  }else{
530  BOX_LOOP(box,k,j,i) q[k][j][i] = s*q[k][j][2*IEND-i];
531  }
532 
533  }else if (side == X2_BEG){
534 
535  if (box->vpos != X2FACE){
536  BOX_LOOP(box,k,j,i) q[k][j][i] = s*q[k][2*JBEG-j-1][i];
537  }else{
538  BOX_LOOP(box,k,j,i) q[k][j][i] = s*q[k][2*JBEG-j-2][i];
539  }
540 
541  }else if (side == X2_END){
542 
543  if (box->vpos != X2FACE){
544  BOX_LOOP(box,k,j,i) q[k][j][i] = s*q[k][2*JEND-j+1][i];
545  }else{
546  BOX_LOOP(box,k,j,i) q[k][j][i] = s*q[k][2*JEND-j][i];
547  }
548  }else if (side == X3_BEG){
549 
550  if (box->vpos != X3FACE){
551  BOX_LOOP(box,k,j,i) q[k][j][i] = s*q[2*KBEG-k-1][j][i];
552  }else{
553  BOX_LOOP(box,k,j,i) q[k][j][i] = s*q[2*KBEG-k-2][j][i];
554  }
555 
556  }else if (side == X3_END){
557 
558  if (box->vpos != X3FACE){
559  BOX_LOOP(box,k,j,i) q[k][j][i] = s*q[2*KEND-k+1][j][i];
560  }else{
561  BOX_LOOP(box,k,j,i) q[k][j][i] = s*q[2*KEND-k][j][i];
562  }
563 
564  }
565 }
#define X3_BEG
Boundary region at X3 beg.
Definition: pluto.h:150
#define X1_BEG
Boundary region at X1 beg.
Definition: pluto.h:146
RBox * GetRBox(int, int)
Definition: rbox.c:232
int vpos
Location of the variable inside the cell.
Definition: structs.h:359
#define X3FACE
Definition: pluto.h:203
#define BOX_LOOP(B, k, j, i)
Definition: macros.h:70
#define X1_END
Boundary region at X1 end.
Definition: pluto.h:147
#define X1FACE
Definition: pluto.h:201
#define X2_END
Boundary region at X2 end.
Definition: pluto.h:149
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
#define s
#define X3_END
Boundary region at X3 end.
Definition: pluto.h:151
int i
Definition: analysis.c:2
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
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
Definition: structs.h:346
static Runtime q
#define X2FACE
Definition: pluto.h:202
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: