PLUTO
init.c File Reference

RMHD rotor test problem in 2 or 3 dimensions. More...

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

Go to the source code of this file.

Functions

void Init (double *v, double x1, double x2, double x3)
 
void Analysis (const Data *d, Grid *grid)
 
void UserDefBoundary (const Data *d, RBox *box, int side, Grid *grid)
 

Detailed Description

RMHD rotor test problem in 2 or 3 dimensions.

The 2D rotor problem [dZBL03][Mig12] consists of a rapidly spinning disk embedded in a uniform background medium treaded by a costant magnetic field. The initial conditin reads as

\[ \left(\rho, p, v_x, v_y, B_x\right) = \left\{\begin{array}{ll} \left(10, 1,-\omega y,\,\omega x,\, 1\right) & \quad\mathrm{for}\quad r < 0.1 \\ \noalign{\medskip} \left(1,\, 1,\, 0,\, 0,\, 1\right) & \quad\mathrm{otherwise} \end{array}\right. \]

where $\omega = 9.95$ is the angular frequency of rotation. The computational domain is the unit square and outflow boundary conditions are imposed everywhere.

As the disk rotates, strong torsional Alfven waves form and propagate outward carrying angular momentum from the disk to the ambient. The emerging flow structure is enclosed by a circular fast forward shock traveling into the surrounding medium. An inward fast shock bounds the innermost oval region where density has been depleted to lower values. The presence of the magnetic field slows down the rotor, and the maximum Lorentz factor decreases from the nominal value of 10 to 2.2 (approx).

A list of tested configurations is given in the following table:

Conf.GEOMETRYDIM T. STEPPINGRECONSTRUCTIONdivB AMR
#01 CARTESIAN2 RK3 LINEAR CT NO
#02 CARTESIAN2 RK2 LINEAR CT NO
#03 CARTESIAN2 HANCOCK LINEAR 8W NO
#04 CARTESIAN2 HANCOCK LINEAR CT NO
#05 CARTESIAN3 RK2 LINEAR GLM NO
#06 CARTESIAN3 RK2 LINEAR GLM NO
#07 CARTESIAN3 HANCOCK LINEAR CT NO
#08 CARTESIAN3 RK3 LimO3 GLM NO

The final solutin at t = 0.4 on a grid of 400x400 grid points is shown below.

rmhd_rotor.03.jpg
Density map (in log scale) at t = 0.4 in Cartesian coordinates using 400 x 400 grid zones (configuration #03). Field lines are super-imposed.

The three dimensional version extends the current configuration to a spinning sphere and it is described in [MUB09].

Author
A. Mignone (migno.nosp@m.ne@p.nosp@m.h.uni.nosp@m.to.i.nosp@m.t)
Date
Aug 6, 2015

Reference:

  • [dZBL03] "An efficient shock-capturing central-type scheme for multidimensional relativistic flows" Del Zanna, Bucciantini, Londrillo, A&A (2003) 400, 397
  • [MUB09] "A five-wave Harten-Lax-van Leer Riemann solver for relativistic magnetohydrodynamics" Mignone, Ugliano & Bodo, MNRAS (2009) 393, 1141.
  • [Mig12] "The PLUTO Code for Adaptive Mesh Computations in Astrophysical Fluid Dynamics" Mignone et al., ApJS (2012) 198, 7 (see Sect. 6.3)

Definition in file init.c.

Function Documentation

void Analysis ( const Data d,
Grid grid 
)

Perform runtime data analysis.

Parameters
[in]dthe PLUTO Data structure
[in]gridpointer to array of Grid structures

Compute volume-integrated magnetic pressure, Maxwell and Reynolds stresses. Save them to "averages.dat"

Definition at line 126 of file init.c.

131 {
132 
133 }
void Init ( double *  v,
double  x1,
double  x2,
double  x3 
)

The Init() function can be used to assign initial conditions as as a function of spatial position.

Parameters
[out]va pointer to a vector of primitive variables
[in]x1coordinate point in the 1st dimension
[in]x2coordinate point in the 2nd dimension
[in]x3coordinate point in the 3rdt dimension

The meaning of x1, x2 and x3 depends on the geometry:

\[ \begin{array}{cccl} x_1 & x_2 & x_3 & \mathrm{Geometry} \\ \noalign{\medskip} \hline x & y & z & \mathrm{Cartesian} \\ \noalign{\medskip} R & z & - & \mathrm{cylindrical} \\ \noalign{\medskip} R & \phi & z & \mathrm{polar} \\ \noalign{\medskip} r & \theta & \phi & \mathrm{spherical} \end{array} \]

Variable names are accessed by means of an index v[nv], where nv = RHO is density, nv = PRS is pressure, nv = (VX1, VX2, VX3) are the three components of velocity, and so forth.

Definition at line 68 of file init.c.

74 {
75  double r, r0, Bx, omega;
76 
77  g_gamma = 5./3.;
78  omega = 0.995;
79  Bx = 1.0;
80  r0 = 0.1;
81 
82  #if GEOMETRY == CARTESIAN
83 
84  r = D_EXPAND(x1*x1, + x2*x2, + x3*x3);
85  r = sqrt(r);
86 
87  v[RHO] = 1.0;
88  v[VX1] = 0.0;
89  v[VX2] = 0.0;
90  v[PRS] = 1.0;
91  v[BX1] = Bx;
92  v[BX2] = 0.0;
93 
94  if (r <= r0) {
95  v[RHO] = 10.0;
96  v[VX1] = -omega*x2/r0;
97  v[VX2] = omega*x1/r0;
98  }
99 
100  v[AX1] = v[AX2] = 0.0;
101  v[AX3] = v[BX1]*x2;
102 
103  #elif GEOMETRY == POLAR
104 
105  r = x1;
106 
107  v[RHO] = 1.0;
108  v[VX2] = 0.0;
109  v[VX1] = 0.0;
110  v[BX1] = Bx*cos(x2);
111  v[BX2] = -Bx*sin(x2);
112  v[PRS] = 1.0;
113 
114  if (r <= r0) {
115  v[RHO] = 10.0;
116  v[VX2] = omega*r/r0;
117  }
118 
119  v[AX1] = v[AX2] = 0.0;
120  v[AX3] = - r*sin(x2)*Bx;
121 
122  #endif
123 
124 }
double g_gamma
Definition: globals.h:112
#define VX2
Definition: mod_defs.h:29
#define RHO
Definition: mod_defs.h:19
#define AX2
Definition: mod_defs.h:86
#define VX1
Definition: mod_defs.h:28
#define AX3
Definition: mod_defs.h:87
static double Bx
Definition: hlld.c:62
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 AX1
Definition: mod_defs.h:85
#define BX1
Definition: mod_defs.h:25
#define BX2
Definition: mod_defs.h:26

Here is the call graph for this function:

void UserDefBoundary ( const Data d,
RBox box,
int  side,
Grid grid 
)

Assign user-defined boundary conditions.

Parameters
[in,out]dpointer to the PLUTO data structure containing cell-centered primitive quantities (d->Vc) and staggered magnetic fields (d->Vs, when used) to be filled.
[in]boxpointer to a RBox structure containing the lower and upper indices of the ghost zone-centers/nodes or edges at which data values should be assigned.
[in]sidespecifies the boundary side where ghost zones need to be filled. It can assume the following pre-definite values: X1_BEG, X1_END, X2_BEG, X2_END, X3_BEG, X3_END. The special value side == 0 is used to control a region inside the computational domain.
[in]gridpointer to an array of Grid structures.

Assign user-defined boundary conditions in the lower boundary ghost zones. The profile is top-hat:

\[ V_{ij} = \left\{\begin{array}{ll} V_{\rm jet} & \quad\mathrm{for}\quad r_i < 1 \\ \noalign{\medskip} \mathrm{Reflect}(V) & \quad\mathrm{otherwise} \end{array}\right. \]

where $ V_{\rm jet} = (\rho,v,p)_{\rm jet} = (1,M,1/\Gamma)$ and M is the flow Mach number (the unit velocity is the jet sound speed, so $ v = M$).

Assign user-defined boundary conditions:

  • left side (x beg): constant shocked values
  • bottom side (y beg): constant shocked values for x < 1/6 and reflective boundary otherwise.
  • top side (y end): time-dependent boundary: for $ x < x_s(t) = 10 t/\sin\alpha + 1/6 + 1.0/\tan\alpha $ we use fixed (post-shock) values. Unperturbed values otherwise.

Assign user-defined boundary conditions at inner and outer radial boundaries. Reflective conditions are applied except for the azimuthal velocity which is fixed.

Assign user-defined boundary conditions.

Parameters
[in/out]d pointer to the PLUTO data structure containing cell-centered primitive quantities (d->Vc) and staggered magnetic fields (d->Vs, when used) to be filled.
[in]boxpointer to a RBox structure containing the lower and upper indices of the ghost zone-centers/nodes or edges at which data values should be assigned.
[in]sidespecifies on which side boundary conditions need to be assigned. side can assume the following pre-definite values: X1_BEG, X1_END, X2_BEG, X2_END, X3_BEG, X3_END. The special value side == 0 is used to control a region inside the computational domain.
[in]gridpointer to an array of Grid structures.

Set the injection boundary condition at the lower z-boundary (X2-beg must be set to userdef in pluto.ini). For $ R \le 1 $ we set constant input values (given by the GetJetValues() function while for $ R > 1 $ the solution has equatorial symmetry with respect to the z=0 plane. To avoid numerical problems with a "top-hat" discontinuous jump, we smoothly merge the inlet and reflected value using a profile function Profile().

Provide inner radial boundary condition in polar geometry. Zero gradient is prescribed on density, pressure and magnetic field. For the velocity, zero gradient is imposed on v/r (v = vr, vphi).

The user-defined boundary is used to impose stress-free boundary and purely vertical magnetic field at the top and bottom boundaries, as done in Bodo et al. (2012). In addition, constant temperature and hydrostatic balance are imposed. For instance, at the bottom boundary, one has:

\[ \left\{\begin{array}{lcl} \DS \frac{dp}{dz} &=& \rho g_z \\ \noalign{\medskip} p &=& \rho c_s^2 \end{array}\right. \qquad\Longrightarrow\qquad \frac{p_{k+1}-p_k}{\Delta z} = \frac{p_{k} + p_{k+1}}{2c_s^2}g_z \]

where $g_z$ is the value of gravity at the lower boundary. Solving for $p_k$ at the bottom boundary where $k=k_b-1$ gives:

\[ \left\{\begin{array}{lcl} p_k &=& \DS p_{k+1} \frac{1-a}{1+a} \\ \noalign{\medskip} \rho_k &=& \DS \frac{p_k}{c_s^2} \end{array}\right. \qquad\mathrm{where}\qquad a = \frac{\Delta z g_z}{2c_s^2} > 0 \]

where, for simplicity, we keep constant temperature in the ghost zones rather than at the boundary interface (this seems to give a more stable behavior and avoids negative densities). A similar treatment holds at the top boundary.

Assign user-defined boundary conditions. At the inner boundary we use outflow conditions, except for velocity which we reset to zero when there's an inflow

Definition at line 135 of file init.c.

139 {
140  int i, j, k, nv;
141  double *r, slp;
142 
143  if (side == X1_BEG){
144  r = grid[IDIR].x;
145  if (box->vpos == CENTER){
146  BOX_LOOP(box,k,j,i){
147  slp = r[i]/r[IBEG];
148  d->Vc[RHO][k][j][i] = d->Vc[RHO][k][j][IBEG];
149  d->Vc[VX1][k][j][i] = slp*d->Vc[VX1][k][j][IBEG];
150  d->Vc[VX2][k][j][i] = slp*d->Vc[VX2][k][j][IBEG];
151  d->Vc[PRS][k][j][i] = d->Vc[PRS][k][j][IBEG];
152  d->Vc[BX1][k][j][i] = d->Vc[BX1][k][j][IBEG];
153  d->Vc[BX2][k][j][i] = d->Vc[BX2][k][j][IBEG];
154  }
155  }else if (box->vpos == X2FACE){
156  #ifdef STAGGERED_MHD
157  BOX_LOOP(box,k,j,i) d->Vs[BX2s][k][j][i] = d->Vs[BX2s][k][j][IBEG];
158  #endif
159  }
160  }
161 }
#define X1_BEG
Boundary region at X1 beg.
Definition: pluto.h:146
#define VX2
Definition: mod_defs.h:29
#define CENTER
Definition: pluto.h:200
int vpos
Location of the variable inside the cell.
Definition: structs.h:359
#define RHO
Definition: mod_defs.h:19
#define BOX_LOOP(B, k, j, i)
Definition: macros.h:70
double **** Vc
The main four-index data array used for cell-centered primitive variables.
Definition: structs.h:31
#define VX1
Definition: mod_defs.h:28
#define IDIR
Definition: pluto.h:193
int j
Definition: analysis.c:2
int k
Definition: analysis.c:2
double * x
Definition: structs.h:80
int i
Definition: analysis.c:2
#define BX1
Definition: mod_defs.h:25
#define BX2s
Definition: ct.h:28
#define BX2
Definition: mod_defs.h:26
#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