PLUTO
init.c
Go to the documentation of this file.
1 /* ///////////////////////////////////////////////////////////////////// */
2 /*!
3  \file
4  \brief Circularly polarized Alfven waves.
5 
6  This is a rotated version of a 1D setup where
7 
8  \f[
9  \rho = 1 \,,\quad
10  v_x = V_0 \,,\quad
11  v_y = |\epsilon|\cos(\phi) \,,\quad
12  v_z = |\epsilon|\sin(\phi) \,,\quad
13  B_x = 1 \,,\quad
14  B_y = \epsilon\cos(\phi) \,,\quad
15  B_z = \epsilon\cos(\phi) \,,\quad
16  P = P_0 \,,
17  \f]
18 
19  where \f$V_0\f$ is the translation velocity in the 1D \f$x\f$ direction,
20  \f$\psi\f$ is the phase (\f$k_xx\f$ in 1D and
21  (\f$k_xx + k_yy\f$) in 2D), and \f$\epsilon\f$ is the wave amplitude
22  (\f$\epsilon > 0\f$ implies right going waves;
23  \f$\epsilon < 0\f$ implies left going waves).
24 
25  With this normalization, the Alfven velocity \f$V_A = B_x/\sqrt{\rho}\f$
26  is always one.
27 
28  Rotations are specified by \f$t_a = k_y/k_x\f$ and \f$t_b = k_z/k_x\f$
29  expressing the ratios between the \f$y\f$- and \f$z\f$- components of
30  the wave vector with the \f$x\f$ component.
31  We choose the wavelength in \f$x\f$-direction to be always 1, so that
32  \f$k_x = 2\pi/l_x = 2\pi\f$, \f$k_y = 2\pi/l_y\f$, \f$k_z = 2\pi/l_z\f$
33  so that \f$t_z = 1/l_y\f$, \f$t_y = 1/l_z\f$.
34  By choosing the domain in the \f$x\f$-direction to be 1, the extent in
35  \f$y\f$ and \f$z\f$ should be adjusted so that \f$L_y/l_y = 1,2,3,4...\f$
36  (and similarly for \f$L_z/l_z\f$) becomes an integer number to ensure
37  periodicity. If one wants 1 wave length in both directions than
38  \f$L_x = 1\f$, \f$L_y = 1/t_a\f$, \f$L_z = 1/t_b\f$.
39 
40  If \f$N\f$ wavelengths are specified in the \f$y\f$-direction than
41  \f$L_x = 1\f$, \f$L_y = N/t_a\f$, \f$L_z = N/t_b\f$
42 
43  1D is recovered by specifying \f$t_z = t_y = 0\f$.
44 
45  The final time step is one period and is found from
46 
47  \f$V_A = \omega/|k|\f$ --> \f$1/T = \sqrt{1 + t_a^2 + t_b^2}\f$
48 
49  The runtime parameters that are read from \c pluto.ini are
50  - <tt>g_inputParam[EPS]</tt>: sets the wave amplitude \f$\epsilon\f$;
51  - <tt>g_inputParam[VEL0]</tt>: sets \f$V_0\f$;
52  - <tt>g_inputParam[PR0]</tt>: sets the pressure of the 1D solution;
53  - <tt>g_inputParam[ALPHA_GLM]</tt>: ;
54 
55  Configurations:
56  - #01-05, 08-09: 2D cartesian;
57  - #06-07: 3D cartesian;
58 
59  \author A. Mignone (mignone@ph.unito.it)
60  \date July 09, 2014
61 
62  \b References:
63  - "High-order conservative finite difference GLM-MHD
64  schemes for cell-centered MHD"
65  Mignone, Tzeferacos & Bodo JCP (2010)
66 */
67 /* ///////////////////////////////////////////////////////////////////// */
68 #include "pluto.h"
69 
70 static double AX_VEC (double x, double y, double z);
71 static double AY_VEC (double x, double y, double z);
72 static double AZ_VEC (double x, double y, double z);
73 
74 static double ta = 0.0, tb = 0.0;
75 static double ca, sa, cg, sg;
76 
77 /* ********************************************************************* */
78 void Init (double *us, double x1, double x2, double x3)
79 /*
80  *
81  *********************************************************************** */
82 {
83  static int first_call = 1;
84  double tg, eps;
85  double x, y, z, kx, ky,kz;
86  double phi, cb, sb;
87  double vx, vy, vz, Bx, By, Bz, rho, pr;
88  double Lx, Ly, Lz;
89 
90  Lx = g_domEnd[IDIR] - g_domBeg[IDIR];
91  Ly = g_domEnd[JDIR] - g_domBeg[JDIR];
92  Lz = g_domEnd[KDIR] - g_domBeg[KDIR];
93 
94  if (first_call == 1){
95  D_EXPAND( ,
96  ta = Lx/Ly; ,
97  tb = Lx/Lz;)
98 
99  if (prank == 0) printf ("ta = %f; tb = %f\n",ta, tb);
100  first_call = 0;
101  }
102  x = x1; y = x2; z = x3;
103 
104  eps = g_inputParam[EPS]; /* wave amplitude */
105  kx = 2.0*CONST_PI/1.0;
106  ky = ta*kx;
107  kz = tb*kx;
108 
109  ca = 1.0/sqrt(ta*ta + 1.0);
110  cb = 1.0/sqrt(tb*tb + 1.0);
111  sa = ta*ca;
112  sb = tb*cb;
113 
114  phi = D_EXPAND(kx*x, + ky*y, + kz*z);
115 
116 /* -- define the 1-D solution -- */
117 
118  rho = 1.0;
119  pr = g_inputParam[PR0];
120  vx = g_inputParam[VEL0]; /* translational velocity */
121  vy = fabs(eps)*sin(phi);
122  vz = fabs(eps)*cos(phi);
123  Bx = 1.0;
124  By = eps*sqrt(rho)*sin(phi);
125  Bz = eps*sqrt(rho)*cos(phi);
126 
127 /* -- rotate solution -- */
128 
129  us[RHO] = rho;
130  us[PRS] = pr;
131 
132  tg = tb*ca;
133  cg = 1.0/sqrt(tg*tg + 1.0); sg = cg*tg;
134 
135  us[VX1] = vx*cg*ca - vy*sa - vz*sg*ca;
136  us[VX2] = vx*cg*sa + vy*ca - vz*sg*sa;
137  us[VX3] = vx*sg + vz*cg;
138  us[TRC] = 0.0;
139 
140  us[BX1] = Bx*cg*ca - By*sa - Bz*sg*ca;
141  us[BX2] = Bx*cg*sa + By*ca - Bz*sg*sa;
142  us[BX3] = Bx*sg + Bz*cg;
143 
144  #ifdef STAGGERED_MHD
145  us[AX1] = AX_VEC(x,y,z);
146  us[AX2] = AY_VEC(x,y,z);
147  us[AX3] = AZ_VEC(x,y,z);
148  #endif
149 }
150 /* ********************************************************************* */
151 void Analysis (const Data *d, Grid *grid)
152 /*
153  *
154  *
155  *********************************************************************** */
156 {
157  int i,j,k;
158  double bmag, err[3], gerr[3], Vtot, dV;
159  double ***Bx, ***By, ***Bz;
160  double *dx, *dy, *dz;
161  static double ***Bx0, ***By0, ***Bz0;
162  FILE *fp;
163 
164  Bx = d->Vc[BX1]; By = d->Vc[BX2]; Bz = d->Vc[BX3];
165  dx = grid[IDIR].dx; dy = grid[JDIR].dx; dz = grid[KDIR].dx;
166 
167  if (Bx0 == NULL){
168  Bx0 = ARRAY_3D(NX3_TOT, NX2_TOT, NX1_TOT, double);
169  By0 = ARRAY_3D(NX3_TOT, NX2_TOT, NX1_TOT, double);
170  Bz0 = ARRAY_3D(NX3_TOT, NX2_TOT, NX1_TOT, double);
171  print1 ("ANALYSIS: Initializing bmag\n");
172  DOM_LOOP(k,j,i){
173  Bx0[k][j][i] = Bx[k][j][i];
174  By0[k][j][i] = By[k][j][i];
175  Bz0[k][j][i] = Bz[k][j][i];
176  }
177  return;
178  }
179 
180  for (i = 0; i < 3; i++) err[i] = 0.0;
181  DOM_LOOP(k,j,i){
182  dV = D_EXPAND(dx[i], *dy[j], *dz[k]);
183  err[0] += fabs(Bx[k][j][i] - Bx0[k][j][i])*dV;
184  err[1] += fabs(By[k][j][i] - By0[k][j][i])*dV;
185  err[2] += fabs(Bz[k][j][i] - Bz0[k][j][i])*dV;
186  }
187 
188  Vtot = D_EXPAND(
189  (g_domEnd[IDIR] - g_domBeg[IDIR]),
190  *(g_domEnd[JDIR] - g_domBeg[JDIR]),
191  *(g_domEnd[KDIR] - g_domBeg[KDIR]));
192 
193  for (i = 0; i < 3; i++) err[i] /= Vtot;
194 
195  #ifdef PARALLEL
196  MPI_Allreduce (err, gerr, 3, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
197  for (i = 0; i < 3; i++) err[i] = gerr[i];
198  MPI_Barrier (MPI_COMM_WORLD);
199  #endif
200 
201  if (prank == 0){
202  double errtot;
203  errtot = sqrt(err[0]*err[0] + err[1]*err[1] + err[2]*err[2]);
204  fp = fopen("bmag.dat","w");
205  printf ("analysis: writing to disk...\n");
206  fprintf (fp,"%d %10.3e\n", (int)(1.0/dx[IBEG]), errtot);
207  fclose (fp);
208  }
209 }
210 /* ********************************************************************* */
211 void UserDefBoundary (const Data *d, RBox *box, int side, Grid *grid)
212 /*
213  *
214  *********************************************************************** */
215 { }
216 
217 
218 double AX_VEC (double x, double y, double z)
219 {
220  double xn, yn, zn, eps;
221  double kx, ky, kz, phi;
222  double kxn, kyn, kzn;
223  double Axn, Ayn, Azn;
224 
225  eps = g_inputParam[EPS];
226  kx = 2.0*CONST_PI/1.0;
227  ky = ta*kx;
228  kz = tb*kx;
229 
230  phi = D_EXPAND(kx*x, + ky*y, + kz*z);
231 
232  xn = ca*cg*x + sa*cg*y + sg*z;
233  yn = -sa*x + ca*y;
234  zn = -ca*sg*x - sa*sg*y + cg*z;
235 
236  kxn = ca*cg*kx + sa*cg*ky + sg*kz;
237  kyn = -sa*kx + ca*ky;
238  kzn = -ca*sg*kx - sa*sg*ky + cg*kz;
239 
240  Axn = 0.0;
241  Ayn = eps*sin(phi)/kxn;
242  Azn = eps*cos(phi)/kxn + yn;
243 
244  return(Axn*cg*ca - Ayn*sa - Azn*sg*ca);
245 }
246 
247 double AY_VEC (double x, double y, double z)
248 {
249  double xn, yn, zn, eps;
250  double kx, ky, kz, phi;
251  double kxn, kyn, kzn;
252  double Axn, Ayn, Azn;
253 
254  eps = g_inputParam[EPS];
255  kx = 2.0*CONST_PI/1.0;
256  ky = ta*kx;
257  kz = tb*kx;
258 
259  phi = D_EXPAND(kx*x, + ky*y, + kz*z);
260 
261  xn = ca*cg*x + sa*cg*y + sg*z;
262  yn = -sa*x + ca*y;
263  zn = -ca*sg*x - sa*sg*y + cg*z;
264 
265  kxn = ca*cg*kx + sa*cg*ky + sg*kz;
266  kyn = -sa*kx + ca*ky;
267  kzn = -ca*sg*kx - sa*sg*ky + cg*kz;
268 
269  Axn = 0.0;
270  Ayn = eps*sin(phi)/kxn;
271  Azn = eps*cos(phi)/kxn + yn;
272 
273  return(Axn*cg*sa + Ayn*ca - Azn*sg*sa);
274 }
275 double AZ_VEC (double x, double y, double z)
276 {
277  double xn, yn, zn, eps;
278  double kx, ky, kz, phi;
279  double kxn, kyn, kzn;
280  double Axn, Ayn, Azn;
281 
282  eps = g_inputParam[EPS];
283  kx = 2.0*CONST_PI/1.0;
284  ky = ta*kx;
285  kz = tb*kx;
286 
287  phi = D_EXPAND(kx*x, + ky*y, + kz*z);
288 
289  xn = ca*cg*x + sa*cg*y + sg*z;
290  yn = -sa*x + ca*y;
291  zn = -ca*sg*x - sa*sg*y + cg*z;
292 
293  kxn = ca*cg*kx + sa*cg*ky + sg*kz;
294  kyn = -sa*kx + ca*ky;
295  kzn = -ca*sg*kx - sa*sg*ky + cg*kz;
296 
297  Axn = 0.0;
298  Ayn = eps*sin(phi)/kxn;
299  Azn = eps*cos(phi)/kxn + yn;
300 
301  return(Axn*sg + Azn*cg);
302 }
void UserDefBoundary(const Data *d, RBox *box, int side, Grid *grid)
Definition: init.c:98
DOM_LOOP(k, j, i)
Definition: analysis.c:22
#define VX2
Definition: mod_defs.h:29
#define VEL0
void print1(const char *fmt,...)
Definition: amrPluto.cpp:511
#define EPS
#define RHO
Definition: mod_defs.h:19
static double cg
Definition: init.c:75
static double ca
Definition: init.c:75
long int NX2_TOT
Total number of zones in the X2 direction (boundaries included) for the local processor.
Definition: globals.h:57
double **** Vc
The main four-index data array used for cell-centered primitive variables.
Definition: structs.h:31
#define PR0
static double ta
Definition: init.c:74
#define AX2
Definition: mod_defs.h:86
#define TRC
Definition: pluto.h:581
#define ARRAY_3D(nx, ny, nz, type)
Definition: prototypes.h:172
double * dx
Definition: structs.h:83
static double AX_VEC(double x, double y, double z)
Definition: init.c:218
int prank
Processor rank.
Definition: globals.h:33
#define VX1
Definition: mod_defs.h:28
#define KDIR
Definition: pluto.h:195
static double tb
Definition: init.c:74
#define eps
#define IDIR
Definition: pluto.h:193
Definition: structs.h:78
#define AX3
Definition: mod_defs.h:87
static double Bx
Definition: hlld.c:62
double g_inputParam[32]
Array containing the user-defined parameters.
Definition: globals.h:131
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
int k
Definition: analysis.c:2
static double AZ_VEC(double x, double y, double z)
Definition: init.c:275
double g_domBeg[3]
Lower limits of the computational domain.
Definition: globals.h:125
static double sg
Definition: init.c:75
#define BX3
Definition: mod_defs.h:27
PLUTO main header file.
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
int i
Definition: analysis.c:2
#define AX1
Definition: mod_defs.h:85
FILE * fp
Definition: analysis.c:7
#define BX1
Definition: mod_defs.h:25
#define VX3
Definition: mod_defs.h:30
#define CONST_PI
.
Definition: pluto.h:269
static double sa
Definition: init.c:75
#define BX2
Definition: mod_defs.h:26
double g_domEnd[3]
Upper limits of the computational domain.
Definition: globals.h:126
#define JDIR
Definition: pluto.h:194
Definition: structs.h:346
static double AY_VEC(double x, double y, double z)
Definition: init.c:247
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
void Analysis(const Data *d, Grid *grid)
Definition: init.c:66
void Init(double *v, double x1, double x2, double x3)
Definition: init.c:17