PLUTO
init.c
Go to the documentation of this file.
1 /* ///////////////////////////////////////////////////////////////////// */
2 /*!
3  \file
4  \brief Diffusion of a linear force-free magnetic field in
5  cylindrical coordinates.
6 
7  Solve the diffusion equation for a linear force-free magnetic field
8  in cylindrical coordinates.
9  A force-free field satisfies
10  \f[
11  \vec{J} \times \vec{B} = 0
12  \qquad\Longrightarrow\qquad
13  \vec{J} = \nabla\times\vec{B} = \mu \vec{B}
14  \f]
15  which means that \f$\vec{J}\f$ and \f$\vec{B}\f$ must be parallel.
16  If \f$ \mu \f$ is constant then the solution is given by the Bessel
17  functions:
18  \f[
19  B_z(r) = B_0 J_1(r) \,,\qquad
20  B_\phi(r) = B_0 J_0(r)
21  \f]
22  For constant resistivity and zero velocity the induction equation
23  simplifies as follows:
24  \f[
25  \frac{d\vec{B}}{dt} = - \nabla\times (\eta \vec{J})
26  = - \nabla\times (\eta \mu \vec{B}) = -\eta \mu^2 \vec{B}
27  \f]
28  which admits the exact analytical solution
29  \f$\vec{B}(r,t) = \vec{B}(r,0) \exp(-\eta\mu^2 t)\f$ meaning that
30  the field remains force free also at subsequent times.
31 
32  Note that if pressure and density are initially constant and the
33  velocity is also initially zero everywhere, the previous solution
34  is also an exact solution of the isothermal MHD equations but not
35  of the adiabatic MHD equations because of the Ohmic dissipation term
36  (magnetic energy transforms into heat).
37  However, using a large density makes pressure effects negligible.
38 
39  - Configurations #01-03 solve the problem on a cylindrical domain
40  away from the origin.
41  - Configurations #04-06 extends the integration up to the origin
42  and tests the quality of the discretization at r = 0
43 
44  \author T. Matsakos\n
45  A. Mignone (mignone@ph.unito.it)
46  \date April 13, 2014
47 */
48 /* ///////////////////////////////////////////////////////////////////// */
49 #include "pluto.h"
50 
51 /* ********************************************************************* */
52 void Init (double *us, double x1, double x2, double x3)
53 /*
54  *
55  *********************************************************************** */
56 {
57  us[RHO] = g_inputParam[DENSITY];
58  us[VX1] = 0.0;
59  us[VX2] = 0.0;
60  us[VX3] = 0.0;
61  #if HAVE_ENERGY
62  us[PRS] = 1.0;
63  #endif
64  us[TRC] = 0.0;
65 
66  us[BX1] = 0.0;
67  us[BX2] = BesselJ0(x1);
68  us[BX3] = BesselJ1(x1);
69  #ifdef GLM_MHD
70  us[PSI_GLM] = 0.0;
71  #endif
72 }
73 /* ********************************************************************* */
74 void UserDefBoundary (const Data *d, RBox *box, int side, Grid *grid)
75 /*
76  *
77  *********************************************************************** */
78 {
79  int i, j, k, nv;
80  double *r, e_t;
81  double t, dt, vin[256];
82  static float *j0, *j1; /* store bessel function to avoid overhead */
83 
84  t = g_time;
85  r = grid[IDIR].x;
86  e_t = exp(-t*1.0);
87 
88 /* -------------------------------------------------
89  Pre-compute Bessel functions to avoid overhead
90  ------------------------------------------------- */
91 
92  if (j0 == NULL){
93  j0 = ARRAY_1D(NX1_TOT, float);
94  j1 = ARRAY_1D(NX1_TOT, float);
95  ITOT_LOOP(i) {
96  j0[i] = BesselJ0(r[i]);
97  j1[i] = BesselJ1(r[i]);
98  }
99  }
100 
101 /* ----------------------------------------------------
102  Set default boundary values
103  ---------------------------------------------------- */
104 
105  vin[RHO] = g_inputParam[DENSITY];
106  vin[VX1] = vin[VX2] = vin[VX3] = 0.0;
107  vin[BX1] = vin[BX2] = vin[BX3] = 0.0;
108  #if HAVE_ENERGY
109  vin[PRS] = 1.0;
110  #endif
111  #ifdef GLM_MHD
112  vin[PSI_GLM] = 0.0;
113  #endif
114 
115 /* ---------------------------------------------------
116  Set boundary conditions
117  --------------------------------------------------- */
118 
119  if (side == X1_BEG){ /* -- X1_BEG boundary -- */
120  if (box->vpos == CENTER){
121  BOX_LOOP(box,k,j,i){
122  VAR_LOOP(nv) d->Vc[nv][k][j][i] = vin[nv];
123  d->Vc[BX2][k][j][i] = j0[i]*e_t;
124  d->Vc[BX3][k][j][i] = j1[i]*e_t;
125  }
126  }else if (box->vpos == X2FACE){
127  #ifdef STAGGERED_MHD
128  BOX_LOOP(box,k,j,i) d->Vs[BX2s][k][j][i] = j0[i]*e_t;
129  #endif
130  }
131  }
132 
133  if (side == X1_END){ /* -- X1_END boundary -- */
134  if (box->vpos == CENTER){
135  BOX_LOOP(box,k,j,i){
136  VAR_LOOP(nv) d->Vc[nv][k][j][i] = vin[nv];
137  d->Vc[BX2][k][j][i] = j0[i]*e_t;
138  d->Vc[BX3][k][j][i] = j1[i]*e_t;
139  }
140  }else if (box->vpos == X2FACE){
141  #ifdef STAGGERED_MHD
142  BOX_LOOP(box,k,j,i) d->Vs[BX2s][k][j][i] = j0[i]*e_t;
143  #endif
144  }
145  }
146 }
147 
148 /* ********************************************************************* */
149 void Analysis (const Data *d, Grid *grid)
150 /*
151  *
152  *
153  *********************************************************************** */
154 {
155 }
#define X1_BEG
Boundary region at X1 beg.
Definition: pluto.h:146
double **** Vs
The main four-index data array used for face-centered staggered magnetic fields.
Definition: structs.h:43
void UserDefBoundary(const Data *d, RBox *box, int side, Grid *grid)
Definition: init.c:98
#define VX2
Definition: mod_defs.h:29
#define DENSITY
#define CENTER
Definition: pluto.h:200
double BesselJ0(double x)
Definition: math_misc.c:13
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 PSI_GLM
Definition: mod_defs.h:34
#define TRC
Definition: pluto.h:581
#define X1_END
Boundary region at X1 end.
Definition: pluto.h:147
#define VX1
Definition: mod_defs.h:28
#define VAR_LOOP(n)
Definition: macros.h:226
#define IDIR
Definition: pluto.h:193
Definition: structs.h:78
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
double BesselJ1(double x)
Definition: math_misc.c:45
#define BX3
Definition: mod_defs.h:27
PLUTO main header file.
#define ARRAY_1D(nx, type)
Definition: prototypes.h:170
#define ITOT_LOOP(i)
Definition: macros.h:38
Definition: structs.h:30
int i
Definition: analysis.c:2
double g_time
The current integration time.
Definition: globals.h:117
#define BX1
Definition: mod_defs.h:25
#define VX3
Definition: mod_defs.h:30
#define BX2s
Definition: ct.h:28
#define BX2
Definition: mod_defs.h:26
Definition: structs.h:346
#define X2FACE
Definition: pluto.h:202
long int NX1_TOT
Total number of zones in the X1 direction (boundaries included) for the local processor.
Definition: globals.h:55
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