PLUTO
init.c
Go to the documentation of this file.
1 /* ///////////////////////////////////////////////////////////////////// */
2 /*!
3  \file
4  \brief Magnetized accretion torus.
5 
6  Magnetized accretion torus in 2D spherical coordinates in a
7  radially stratified atmosphere.
8  The accretion torus is determined by the equilibrium condition
9  \f[
10  -\frac{1}{R} + \frac{1}{2(1-a)}\frac{L_k^2}{r^{2-2a}}
11  +(n+1)\frac{p}{\rho} = const
12  \f]
13  where \f$p = K\rho^\gamma \f$, \c R is the spherical radius, \c r
14  is the cylindrical radius.
15  Since \f$ n = 1/(\gamma-1) \f$ then \f$ 1+n = \gamma/(\gamma-1) \f$
16  we can also write using \f$ a = 0 \f$ (constant angular momentum
17  distribution, Kuwabara Eq [8]):
18  \f[
19  -\frac{1}{R} + \frac{1}{2}\frac{L_k^2}{r^2}
20  + \frac{\gamma}{\gamma-1}K\rho^{\gamma-1} = c
21  = -\frac{1}{r_{\min}} + \frac{1}{2}\frac{L_k^2}{r_{\min}^2}
22  \f]
23  where the constant on the right hand side is determined at the
24  zero pressure surface.
25  The previous equation is used to compute \c K at the point where
26  the density is maximum and then again to obtain the density
27  distribution:
28  \f[
29  K = \frac{\gamma-1}{\gamma}\left[
30  c + \frac{1}{r_{\max}} - \frac{1}{2}\frac{L_k^2}{r_{\max}^2}
31  \right]\frac{1}{\rho_{\max}^{\gamma-1}}\,;\qquad
32  \rho = \left[\frac{\gamma-1}{K\gamma}\left(c + \frac{1}{R}
33  - \frac{1}{2}\frac{L_k^2}{r^2}\right)\right]^{1/(\gamma-1)}
34  \f]
35  Thus, specifying \f$ r_{\min} \f$, \f$ r_{\max} \f$ and \f$ \rho_{\max}\f$
36  determine the torus structure completely.
37  The torus azimuthal velocity is compute from \f$v_\phi = L_k/r\f$.
38 
39  The atmosphere is assumed to be isothermal and it is given by the
40  condition of hydrostatic balance:
41  \f[
42  \rho_a(R) = \eta\rho_{\max}
43  \exp\left[\left(\frac{1}{R}-\frac{1}{r_{\min}}\right)
44  \frac{GM}{a^2}\right]
45  \f]
46  where \f$\eta\f$ is the density contrast between the (maximum) torus
47  density and the atmosphere density at \f$(r_{\min},0)\f$.
48 
49  The torus surface is defined by the condition \f$p_t > p_a\f$.
50 
51  The dimensionless form of the equation employs on the following units:
52 
53  - \f$ [\rho] = \rho_{\max}\f$: reference density;
54  - \f$ [L] = R_{*} \f$: star radius;
55  - \f$ [v^2] = GM/L \f$: reference (squared) velocity.
56 
57  The user defined parameters of this problem, as they appear
58  in pluto.ini, allows for control in the Torus shape and the
59  contrast of physical values:
60 
61  -# <tt>g_inputParam[RMIN]</tt>: minimum cylindrical radius for the torus
62  (inner rim)
63  -# <tt>g_inputParam[RMAX]</tt>: radius of the Torus where pressure is maximum
64  -# <tt>g_inputParam[RHO_CUT]</tt>: minimum density to define the last
65  contour of the magnetic vec. pot.
66  -# <tt>g_inputParam[BETA]</tt>: plasma beta
67  -# <tt>g_inputParam[ETA]</tt> density contrast between atmosphere and Torus
68  -# <tt>g_inputParam[SCALE_HEIGHT]</tt>: atmosphere scale height \f$ H=GM/a^2\f$
69 
70  The magnetic field can be specified to be inside the torus or as a
71  large-scale dipole field.
72  In the first case, we give the vector potential:
73  \f[
74  A_\phi = B_0(\rho_t - \rho_{\rm cut})
75  \f]
76  In the second case, a dipole field is specified in the function
77  ::DipoleField().
78  The user-defined constant \c USE_DIPOLE can be used to select between the
79  two configurations.
80 
81  \author A. Mignone (mignone@ph.unito.it) \n
82  T. Matsakos (titos@oddjob.uchicago.edu)
83  \date Aug 16, 2012
84 
85  \b References
86  - "Global Magnetohydrodynamical Simulations of Accretion Tori",
87  Hawley, J.F., ApJ (2000) 528 462.
88  - "The dynamical stability of differentially rotating discs with
89  constant specific angular momentum"
90  Papaloizou, J.C.B, Pringle, J.E, MNRAS (1984) 208 721
91  - "The Acceleration Mechanism of Resistive Magnetohydrodynamic Jets
92  Launched from Accretion Disks."
93  Kuwabara, T., Shibata, K., Kudoh, T., Matsumoto, R. ApJ (2005) 621 921
94 */
95 /* ///////////////////////////////////////////////////////////////////// */
96 #include "pluto.h"
97 
98 static void DipoleField(double x1, double x2, double x3,
99  double *Bx1, double *Bx2, double *A);
100 
101 static double kappa;
102 
103 /* ********************************************************************* */
104 void Init (double *v, double x1, double x2, double x3)
105 /*
106  *
107  *********************************************************************** */
108 {
109  double rmin, rmax, beta;
110  double r, R, z, A_phi, gmmr, H;
111  double a,c, l_k, l_k2;
112  double Bo, Vo;
113  double prt, pra, phi;
114  double rhot, rhoa, rhocut;
115 
116  gmmr = g_gamma/(g_gamma - 1.0);
117  #if GEOMETRY == CYLINDRICAL
118  r = x1; /* cylindrical radius */
119  z = x2;
120  R = sqrt(x1*x1 + x2*x2); /* spherical radius */
121  #elif GEOMETRY == SPHERICAL
122  r = x1*sin(x2); /* cylindrical radius */
123  z = x1*cos(x2);
124  R = x1; /* spherical radius */
125  #endif
126 
127  phi = 0.0;
128 
129  rmax = g_inputParam[RMAX];
130  rmin = g_inputParam[RMIN];
131  beta = g_inputParam[BETA];
132  rhocut = g_inputParam[RHO_CUT];
134 
135  l_k = sqrt(rmax);
136  l_k2 = l_k*l_k;
137  Vo = l_k;
138 
139 /* ----------------------------------------
140  Solve for kappa and c assuming pra=0
141  ---------------------------------------- */
142 
143  c = - 1.0/rmin + 0.5*l_k2/(rmin*rmin);
144  kappa = (c + 1.0/rmax - 0.5*l_k2/(rmax*rmax))/gmmr;
145 
146 /* ----------------------------
147  Torus density + pressure
148  ---------------------------- */
149 
150  a = c + 1.0/R - 0.5*l_k2/(r*r);
151  a = MAX(a, 0.0);
152  rhot = pow(a/(gmmr*kappa), 1.0/(g_gamma-1));
153  prt = kappa*pow(rhot,g_gamma);
154 
155 /* -------------------------------------
156  Atmospheric density + pressure
157  (force equilibrium Fg and \nabla P)
158  ------------------------------------- */
159 
160  rhoa = g_inputParam[ETA]*exp((1./R - 1./rmin)/H);
161  pra = rhoa*H;
162 
163  Bo = sqrt(2.0*kappa/beta);
164 
165  if (prt > pra && r > 2.0) { /* Torus */
166  v[RHO] = rhot;
167  v[PRS] = prt;
168  v[VX1] = 0.0;
169  v[VX2] = 0.0;
170  v[VX3] = Vo/r;
171  v[TRC] = 1.0;
172  }else{ /* Atmosphere */
173  v[RHO] = rhoa;
174  v[PRS] = pra;
175  v[VX1] = 0.0;
176  v[VX2] = 0.0;
177  v[VX3] = 0.0;
178  v[TRC] = 0.0;
179  }
180 
181  #if PHYSICS == MHD || PHYSICS == RMHD
182  v[BX1] = 0.0;
183  v[BX2] = 0.0;
184  v[BX3] = 0.0;
185 
186  A_phi = 0.0;
187  #if USE_DIPOLE == NO
188  if (rhot > rhocut && r > 2.0) A_phi = Bo*(rhot - rhocut);
189  #endif
190 
191  v[AX1] = 0.0;
192  v[AX2] = 0.0;
193  v[AX3] = A_phi;
194  #endif
195 
196  #if (USE_DIPOLE == YES) && (BACKGROUND_FIELD == NO)
197  DipoleField (x1,x2,x3,v+BX1, v+BX2, v+AX3);
198  #endif
199 
200  g_smallPressure = 1.e-8;
201 }
202 /* ********************************************************************* */
203 void Analysis (const Data *d, Grid *grid)
204 /*
205  *
206  *
207  *********************************************************************** */
208 {
209 }
210 #if PHYSICS == MHD
211 /* ********************************************************************* */
212 void BackgroundField (double x1, double x2, double x3, double *B0)
213 /*!
214  * Define the component of a static, curl-free background
215  * magnetic field.
216  *
217  *********************************************************************** */
218 {
219  double A;
220 
221  B0[0] = 0.0;
222  B0[1] = 0.0;
223  B0[2] = 0.0;
224  #if USE_DIPOLE == YES
225  DipoleField (x1,x2,x3,B0, B0+1, &A);
226  #endif
227 }
228 #endif
229 /* ********************************************************************* */
230 void UserDefBoundary (const Data *d, RBox *box, int side, Grid *grid)
231 /*!
232  * Assign user-defined boundary conditions.
233  * At the inner boundary we use outflow conditions, except for
234  * velocity which we reset to zero when there's an inflow
235  *
236  *********************************************************************** */
237 {
238  int i, j, k, nv;
239  double *x1, *x2, *x3;
240  static double vR1[NVAR];
241  double R;
242 
243  x1 = grid[IDIR].x;
244  x2 = grid[JDIR].x;
245  x3 = grid[KDIR].x;
246 
247  if (side == X1_BEG){
248  if (box->vpos == CENTER){
249  BOX_LOOP(box,k,j,i){
250  for (nv = 0; nv < NVAR; nv++){
251  d->Vc[nv][k][j][i] = d->Vc[nv][k][j][IBEG];
252  }
253  d->Vc[VX1][k][j][i] = MIN(d->Vc[VX1][k][j][i],0.0);
254  }
255  }else if (box->vpos == X2FACE){
256  #ifdef STAGGERED_MHD
257 // BOX_LOOP(box,k,j,i) d->Vs[BX2s][k][j][i] = d->Vs[BX2s][k][j][IBEG];
258  #endif
259  }
260  }
261 }
262 
263 #if (BODY_FORCE & VECTOR)
264 /* ********************************************************************* */
265 void BodyForceVector(double *v, double *g, double x1, double x2, double x3)
266 /*
267  *
268  *
269  *********************************************************************** */
270 {
271  double R;
272 
273  #if GEOMETRY == CYLINDRICAL
274  R = sqrt(x1*x1 + x2*x2);
275  g[IDIR] = -1.0/(R*R*R)*x1;
276  g[JDIR] = -1.0/(R*R*R)*x2;
277  g[KDIR] = 0.0;
278  #elif GEOMETRY == SPHERICAL
279  R = x1;
280  g[IDIR] = -1.0/(R*R);
281  g[JDIR] = 0.0;
282  g[KDIR] = 0.0;
283  #endif
284 }
285 #endif
286 
287 #if (BODY_FORCE & POTENTIAL)
288 /* ********************************************************************* */
289 double BodyForcePotential(double x1, double x2, double x3)
290 /*
291  *
292  *
293  *********************************************************************** */
294 {
295  return 0.0;
296 }
297 #endif
298 
299 /* ********************************************************************* */
300 void DipoleField(double x1, double x2, double x3,
301  double *Bx1, double *Bx2, double *A)
302 /*!
303  * Assign the polodial component of magnetic fields and vector
304  * potential for a dipole.
305  *
306  *********************************************************************** */
307 {
308  double R, z, r, r2, r3, Bmag;
309  double a;
310 
311  Bmag = sqrt(2.0*kappa/g_inputParam[BETA]);
312 
313  #if GEOMETRY == CYLINDRICAL
314  R = x1; z = x2; r = sqrt(x1*x1 + x2*x2);
315  r2 = r*r;
316  r3 = r2*r;
317  *Bx1 = 3.0*Bmag*z*R/(r2*r3);
318  *Bx2 = -Bmag*(R*R - 3.0*z*z)/(r2*r3);
319  *A = Bmag*R/r3;
320  #elif GEOMETRY == SPHERICAL
321  r = x1;
322  r2 = r*r;
323  r3 = r2*r;
324  *Bx1 = 2.0*Bmag*cos(x2)/r3;
325  *Bx2 = Bmag*sin(x2)/r3;
326  *A = Bmag*sin(x2)/r2;
327  #endif
328 }
static double a
Definition: init.c:135
#define MAX(a, b)
Definition: macros.h:101
#define X1_BEG
Boundary region at X1 beg.
Definition: pluto.h:146
double g_gamma
Definition: globals.h:112
void UserDefBoundary(const Data *d, RBox *box, int side, Grid *grid)
Definition: init.c:98
#define VX2
Definition: mod_defs.h:29
#define BETA
#define CENTER
Definition: pluto.h:200
int vpos
Location of the variable inside the cell.
Definition: structs.h:359
void BackgroundField(double x1, double x2, double x3, double *B0)
Definition: init.c:79
#define RHO
Definition: mod_defs.h:19
#define BOX_LOOP(B, k, j, i)
Definition: macros.h:70
static double gmmr
Definition: two_shock.c:42
double **** Vc
The main four-index data array used for cell-centered primitive variables.
Definition: structs.h:31
static void DipoleField(double x1, double x2, double x3, double *Bx1, double *Bx2, double *A)
Definition: init.c:300
#define AX2
Definition: mod_defs.h:86
#define TRC
Definition: pluto.h:581
double g_smallPressure
Small value for pressure fix.
Definition: globals.h:110
#define RHO_CUT
#define SCALE_HEIGHT
#define VX1
Definition: mod_defs.h:28
#define RMAX
#define KDIR
Definition: pluto.h:195
static double kappa
Definition: init.c:101
#define MIN(a, b)
Definition: macros.h:104
#define IDIR
Definition: pluto.h:193
Definition: structs.h:78
#define AX3
Definition: mod_defs.h:87
double g_inputParam[32]
Array containing the user-defined parameters.
Definition: globals.h:131
int j
Definition: analysis.c:2
int k
Definition: analysis.c:2
double * x
Definition: structs.h:80
tuple c
Definition: menu.py:375
#define BX3
Definition: mod_defs.h:27
PLUTO main header file.
Definition: structs.h:30
int i
Definition: analysis.c:2
double BodyForcePotential(double x, double y, double z)
Definition: init.c:479
#define ETA
#define AX1
Definition: mod_defs.h:85
#define BX1
Definition: mod_defs.h:25
#define VX3
Definition: mod_defs.h:30
#define BX2
Definition: mod_defs.h:26
#define RMIN
#define JDIR
Definition: pluto.h:194
#define NVAR
Definition: pluto.h:609
Definition: structs.h:346
#define X2FACE
Definition: pluto.h:202
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
void BodyForceVector(double *v, double *g, double x, double y, double z)
Definition: init.c:441