32 #define FARGO_MOD(s) ((s) < SBEG ? (s)+NS:((s) > SEND ? (s)-NS:(s)))
33 #define MAX_BUF_SIZE 64
35 static void FARGO_Flux (
double *,
double *,
double);
38 double ***rbl[],
RBox *,
39 double ***rbu[],
RBox *,
Grid *grid);
54 #if GEOMETRY != SPHERICAL
60 int i,
j,
k, nv, ngh, nvar_c;
62 static int mmax, mmin;
63 int nbuf_lower, nbuf_upper, nproc_s = 1;
64 double *dx, *dy, *dz, dphi;
65 double *x, *xp, *y, *yp, *z, *zp, w, Lphi, dL,
eps;
67 static double *q00, *flux00;
69 static double ***Ez, ***Ex;
71 double ***upper_buf[
NVAR];
72 double ***lower_buf[
NVAR];
76 #if GEOMETRY == CYLINDRICAL
77 print1 (
"! FARGO cannot be used in this geometry\n");
95 #if GEOMETRY == SPHERICAL && DIMENSIONS == 3
142 #if (HAVE_ENERGY) && (defined SHEARINGBOX)
168 nbuf_lower = abs(mmin) + ngh + 1;
169 nbuf_upper = mmax + ngh + 1;
173 if (nbuf_upper >
NS || nbuf_lower >
NS){
174 print (
"! FARGO_ShiftSolution: buffer size exceeds processsor size\n");
180 if (nbuf_upper > MAX_BUF_SIZE || nbuf_lower > MAX_BUF_SIZE){
181 print (
"! FARGO_ShiftSolution: buffer size exceeds maximum length\n");
187 #if GEOMETRY == CARTESIAN || GEOMETRY == POLAR
191 lbox.
di = lbox.
dj = lbox.
dk = 1;
195 ubox.
di = ubox.
dj = ubox.
dk = 1;
200 lbox.
kb--; ubox.
kb--;)
203 #elif GEOMETRY == SPHERICAL
207 lbox.
di = lbox.
dj = lbox.
dk = 1;
211 ubox.
di = ubox.
dj = ubox.
dk = 1;
215 lbox.
jb--; ubox.
jb--; ,
223 for (nv = 0; nv <
NVAR; nv++){
243 #if GEOMETRY == CARTESIAN || GEOMETRY == POLAR
249 #if GEOMETRY == CARTESIAN
251 #elif GEOMETRY == POLAR
253 #elif GEOMETRY == SPHERICAL
254 w = wA[
j][
i]/(x[
i]*sin(y[j]));
271 m = (int)floor(dL/dphi + 0.5);
277 if (w > 0.0 && (m + ngh) > nbuf_upper){
278 print1 (
"! FARGO_ShiftSolution: positive shift too large\n");
281 if (w < 0.0 && (-m + ngh) > nbuf_lower){
282 print1 (
"! FARGO_ShiftSolution: negative shift too large\n");
294 for (nv =
NVAR; nv--; ){
298 if (nv ==
BX2)
continue; ,
299 if (nv ==
BX3)
continue;)
317 for (
s = 1;
s <= ngh;
s++) {
330 U[
k][
j][
i][nv] = q[sm] - eps*(flux[sm] - flux[sm-1]);
336 U[
k][
j][
i][nv] = q[sm] - eps*(flux[sm] - flux[sm-1]);
349 double *Ar, *Ath, *dr, *r;
350 double ***bx1, ***bx2, ***bx3;
367 #if GEOMETRY == CARTESIAN || GEOMETRY == POLAR
373 #if GEOMETRY == CARTESIAN
374 w = 0.5*(wA[
k][
i] + wA[
k][i+1]);
375 #elif GEOMETRY == POLAR
376 w = 0.5*(wA[
k][
i] + wA[
k][i+1])/xp[i];
377 #elif GEOMETRY == SPHERICAL
378 w = 0.5*(wA[
j][
i] + wA[
j][i+1])/(xp[i]*sin(y[j]));
388 m = (int)floor(dL/dphi + 0.5);
405 for (
s = 1;
s <= ngh;
s++) {
419 Ez[
k][
j][
i] = eps*flux[sm];
420 for (ss =
s; ss > (
s-m); ss--) Ez[k][j][i] += q[ss];
426 Ez[
k][
j][
i] = eps*flux[sm];
427 for (ss =
s+1; ss < (
s-m+1); ss++) Ez[k][j][i] -= q[ss];
436 Ez[
k][
j][
i] = eps*flux[sm];
437 for (ss =
s; ss > (
s-m); ss--) Ez[k][j][i] += q[
FARGO_MOD(ss)];
443 Ez[
k][
j][
i] = eps*flux[sm];
444 for (ss =
s+1; ss < (
s-m+1); ss++) Ez[k][j][i] -= q[
FARGO_MOD(ss)];
458 #if GEOMETRY == CARTESIAN || GEOMETRY == POLAR
461 double ***bs = Us[
BX3s];
465 double ***bs = Us[
BX2s];
468 #if GEOMETRY == CARTESIAN
469 w = 0.5*(wA[
k][
i] + wA[k+1][
i]);
470 #elif GEOMETRY == POLAR
471 w = 0.5*(wA[
k][
i] + wA[k+1][
i])/x[i];;
472 #elif GEOMETRY == SPHERICAL
473 w = 0.5*(wA[
j][
i] + wA[j+1][
i])/(x[i]*sin(yp[j]));
483 m = (int)floor(dL/dphi + 0.5);
500 for (
s = 1;
s <= ngh;
s++) {
514 Ex[
k][
j][
i] = eps*flux[sm];
515 for (ss =
s; ss > (
s-m); ss--) Ex[k][j][i] += q[ss];
521 Ex[
k][
j][
i] = eps*flux[sm];
522 for (ss =
s+1; ss < (
s-m+1); ss++) Ex[k][j][i] -= q[ss];
531 Ex[
k][
j][
i] = eps*flux[sm];
532 for (ss =
s; ss > (
s-m); ss--) Ex[k][j][i] += q[
FARGO_MOD(ss)];
538 Ex[
k][
j][
i] = eps*flux[sm];
539 for (ss =
s+1; ss < (
s-m+1); ss++) Ex[k][j][i] -= q[
FARGO_MOD(ss)];
552 #if GEOMETRY == CARTESIAN || GEOMETRY == POLAR
553 bx1[
k][
j][
i] -= (Ez[
k][
j][
i] - Ez[
k][j-1][
i])/dphi;
554 #elif GEOMETRY == SPHERICAL
555 bx1[
k][
j][
i] -= (Ez[
k][
j][
i] - Ez[k-1][
j][
i])/dphi;
564 #if GEOMETRY == CARTESIAN
566 (Ez[k][j][i] - Ez[k][j][i-1])/dx[i] ,
567 - (Ex[k][j][i] - Ex[k-1][j][i])/dz[k]);
568 #elif GEOMETRY == POLAR
570 (Ar[i]*Ez[k][j][i] - Ar[i-1]*Ez[k][j][i-1])/dr[i] ,
571 - x[i]*(Ex[k][j][i] - Ex[k-1][j][i])/dz[k]);
573 #elif GEOMETRY == SPHERICAL
574 bx2[
k][
j][
i] += (Ex[
k][
j][
i] - Ex[k-1][
j][
i])/dphi;
584 #if GEOMETRY == CARTESIAN || GEOMETRY == POLAR
585 bx3[
k][
j][
i] += (Ex[
k][
j][
i] - Ex[
k][j-1][
i])/dphi;
586 #elif GEOMETRY == SPHERICAL
587 bx3[
k][
j][
i] += sin(y[j])*( Ar[
i]*Ez[
k][
j][
i]
588 - Ar[i-1]*Ez[
k][
j][i-1])/(r[i]*dr[i])
589 - (Ath[
j]*Ex[
k][
j][
i] - Ath[j-1]*Ex[
k][j-1][
i])/dy[j];
598 U[k][j][i][
BX1] = 0.5*(Us[
BX1s][k][j][i] + Us[
BX1s][k][j][i-1]); ,
608 for (nv = 0; nv <
NVAR; nv++){
619 double ***recv_buf_lower[],
RBox *lbox,
620 double ***recv_buf_upper[],
RBox *ubox,
645 int coords[3], dst, src;
648 double ***send_buf[
NVAR], *sbuf, *rbuf;
657 for (i = 0; i <
DIMENSIONS; i++) coords[i] = grid[i].rank_coord;
659 MPI_Cart_rank(cartcomm, coords, &dst);
661 for (i = 0; i <
DIMENSIONS; i++) coords[i] = grid[i].rank_coord;
663 MPI_Cart_rank(cartcomm, coords, &src);
671 ib = ubox->
ib; jb = ubox->
jb; kb = ubox->
kb;
672 ie = ubox->
ie; je = ubox->
je; ke = ubox->
ke;
674 ntot = (ie - ib + 1)*(je - jb + 1)*(ke - kb + 1);
675 for (nv = 0; nv <
NVAR; nv++){
676 send_buf[nv] =
ArrayBox(kb, ke, jb, je, ib, ie);
682 #if GEOMETRY == CARTESIAN || GEOMETRY == POLAR
685 for (nv = NVAR; nv--; ) send_buf[nv][k][j][i] = U[k][
JEND-j][i][nv];
694 for (nv = NVAR; nv--; ) send_buf[nv][k][j][i] = U[
KEND-k][j][i][nv];
706 for (nv = 0; nv <
NVAR; nv++){
707 sbuf = &(send_buf[nv][kb][jb][ib]);
708 rbuf = &(recv_buf_upper[nv][kb][jb][ib]);
709 MPI_Sendrecv(sbuf, ntot, MPI_DOUBLE, dst, 1,
710 rbuf, ntot, MPI_DOUBLE, src, 1, cartcomm, &status);
723 ib = lbox->
ib; jb = lbox->
jb; kb = lbox->
kb;
724 ie = lbox->
ie; je = lbox->
je; ke = lbox->
ke;
726 ntot = (ie - ib + 1)*(je - jb + 1)*(ke - kb + 1);
728 for (nv = 0; nv <
NVAR; nv++){
729 send_buf[nv] =
ArrayBox(kb, ke, jb, je, ib, ie);
733 #if GEOMETRY == CARTESIAN || GEOMETRY == POLAR
735 for (nv = NVAR; nv--; ) send_buf[nv][k][j][i] = U[k][
JBEG+j][i][nv];
744 for (nv = NVAR; nv--; ) send_buf[nv][k][j][i] = U[
KBEG+k][j][i][nv];
756 for (nv = 0; nv <
NVAR; nv++){
757 sbuf = &(send_buf[nv][kb][jb][ib]);
758 rbuf = &(recv_buf_lower[nv][kb][jb][ib]);
759 MPI_Sendrecv(sbuf, ntot, MPI_DOUBLE, src, 100,
760 rbuf, ntot, MPI_DOUBLE, dst, 100, cartcomm, &status);
799 double dqc, d2q, dqp, dqm;
800 static double *dq, *dql, *qp, *qm;
810 for (s = 1; s <
NS_TOT-1; s++){
811 dq[
s] = q[s+1] - q[
s];
812 if (dq[s]*dq[s-1] > 0.0){
813 dqc = 0.5*(dq[
s] + dq[s-1]);
814 d2q = 2.0*(fabs(dq[s]) < fabs(dq[s-1]) ? dq[
s]:dq[s-1]);
815 dql[
s] = fabs(d2q) < fabs(dqc) ? d2q: dqc;
823 for (s=
SBEG-1; s<=
SEND; s++) flx[s] = q[s] + 0.5*dql[s]*(1.0 - eps);
825 for (s=
SBEG-1; s<=
SEND; s++) flx[s] = q[s+1] - 0.5*dql[s+1]*(1.0 + eps);
827 #elif FARGO_ORDER == 3
833 dqp = 0.5*dq[
s] - (dql[s+1] - dql[
s])/6.0;
834 dqm = -0.5*dq[s-1] + (dql[s-1] - dql[
s])/6.0;
835 if (dqp*dqm > 0.0) dqp = dqm = 0.0;
837 if (fabs(dqp) >= 2.0*fabs(dqm)) dqp = -2.0*dqm;
838 if (fabs(dqm) >= 2.0*fabs(dqp)) dqm = -2.0*dqp;
847 d2q = qp[
s] - 2.0*q[
s] + qm[
s];
848 flx[
s] = qp[
s] - 0.5*eps*(dqc + d2q*(3.0 - 2.0*
eps));
852 dqc = qp[s+1] - qm[s+1];
853 d2q = qp[s+1] - 2.0*q[s+1] + qm[s+1];
854 flx[
s] = qm[s+1] - 0.5*eps*(dqc - d2q*(3.0 + 2.0*
eps));
858 print1 (
"! FARGO_ORDER should be either 2 or 3\n");
#define FARGO_ARRAY_INDEX(A, s, k, j, i)
int jb
Lower corner index in the x2 direction.
void print1(const char *fmt,...)
#define BOX_LOOP(B, k, j, i)
long int NX2_TOT
Total number of zones in the X2 direction (boundaries included) for the local processor.
int kb
Lower corner index in the x3 direction.
void FreeArrayBox(double ***t, long nrl, long ncl, long ndl)
double g_dt
The current integration time step.
int dk
Directional increment (+1 or -1) when looping over the 3rd dimension of the box.
double *** ArrayBox(long int nrl, long int nrh, long int ncl, long int nch, long int ndl, long int ndh)
void FARGO_ShiftSolution(Data_Arr U, Data_Arr Us, Grid *grid)
#define ARRAY_3D(nx, ny, nz, type)
int ib
Lower corner index in the x1 direction.
int AL_Get_cart_comm(int, MPI_Comm *)
int dj
Directional increment (+1 or -1) when looping over the 2nd dimension of the box.
void FARGO_Source(Data_Arr, double, Grid *)
long int NX3_TOT
Total number of zones in the X3 direction (boundaries included) for the local processor.
int nghost
Number of ghost zones.
long int IEND
Upper grid index of the computational domain in the the X1 direction for the local processor...
void print(const char *fmt,...)
double g_domBeg[3]
Lower limits of the computational domain.
static void FARGO_Flux(double *, double *, double)
static void FARGO_ParallelExchange(Data_Arr U, Data_Arr Us, double ***rbl[], RBox *, double ***rbu[], RBox *, Grid *grid)
#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.
double ** FARGO_GetVelocity(void)
int ie
Upper corner index in the x1 direction.
int ke
Upper corner index in the x3 direction.
int je
Upper corner index in the x2 direction.
long int KBEG
Lower grid index of the computational domain in the the X3 direction for the local processor...
long int KEND
Upper grid index of the computational domain in the the X3 direction for the local processor...
int di
Directional increment (+1 or -1) when looping over the 1st dimension of the box.
double g_domEnd[3]
Upper limits of the computational domain.
long int JBEG
Lower grid index of the computational domain in the the X2 direction for the local processor...
#define QUIT_PLUTO(e_code)
long int JEND
Upper grid index of the computational domain in the the X2 direction for the local processor...
long int NX1_TOT
Total number of zones in the X1 direction (boundaries included) for the local processor.
int nproc
number of processors for this grid.
long int IBEG
Lower grid index of the computational domain in the the X1 direction for the local processor...
double * A
Right interface area, A[i] = .