PLUTO
vec_pot_update.c
Go to the documentation of this file.
1 /* ///////////////////////////////////////////////////////////////////// */
2 /*!
3  \file
4  \brief Function to handle vector potential.
5 
6  Update the cell-centered vector potential by integrating
7  \f[
8  \pd{\vec{A}}{t} + \vec{E} = 0
9  \f]
10  Depending on the time-stepping algorithm, we advance the solution
11  in time using the following increments
12  \f[
13  \begin{array}{ll}
14  \rm{RK2:}\quad &\DS A^{n+1} = A^n + \frac{\Delta t^n}{2} (E^n + E^*)
15  \\ \noalign{\medskip}
16  \rm{RK3:}\quad &\DS A^{n+1} = A^n + \frac{\Delta t^n}{6} (E^n + E^* + 4E^{**})
17  \\ \noalign{\medskip}
18  \rm{CTU:}\quad &\DS A^{n+1} = A^n + \Delta t^nE^{n+\HALF}
19  \end{array}
20  \f]
21  The cell-centered electric field \b E is computed by averaging values
22  available at faces or edges, depending on the MHD formulation:
23  - staggered_mhd: we average the electric field values
24  available at cell edges and previously computed
25  . In this
26  case the function does the job only
27  if called from CT;
28  - Cell-cent. mhd: we average the face values using upwind fluxes.
29  In this case the function does the job only
30  if called from time stepping algorithms.
31  The flux components of induction equation
32  contain the emf:
33  \f$ F_{i+\HALF} = ( 0,-E_z, E_y)_{i+\HALF}\f$,
34  \f$ F_{j+\HALF} = ( E_z, 0,-E_x)_{j+\HALF}\f$,
35  \f$ F_{k+\HALF} = (-E_y, E_x, 0)_{k+\HALF}\f$,
36 
37 
38  Note that the vector potential is NOT used in the rest
39  of the code and serves solely as a diagnostic tool.
40 
41  \param [in,out] d pointer to PLUTO Data structure
42  \param [in] vp pointer to an EMF structure, used only with CT
43  \param [in] state pointer to State_1D structure containing the
44  electric field components (cell-centered MHD)
45  \param [in] grid pointer to an array of Grid structures
46 
47  \attention In cylindrical coordinates:
48  PLUTO treats cylindrical (but not polar) coordinates as
49  Cartesian so that \f$ (x_1,x_2) = (R,z) \f$ .
50  Nevertheless, the correct right-handed cylindrical system is
51  defined by \f$ (x_1,x_2,x_3) = (R,\phi,z)\f$.
52  The fact that the \f$ \phi \f$ coordinate is missing causes an
53  ambiguity when computing the third component of the EMF in 2.5 D:
54  \f[
55  E_3 = v_2B_1 - v_1B_2
56  \f]
57  which is (wrongly) called \f$ E_z \f$ but is, indeed,
58  \f$ -E_\phi \f$ .
59  This is not a problem in the update of the magnetic field, since
60  the contribution coming from \f$ E_3 \f$ is also reversed:
61  \f[
62  \Delta B_1 = -\Delta t dE_3/dx_2 \quad\Longrightarrow\quad
63  \Delta B_r = \Delta t dE_\phi/dz
64  \f]
65  as it should be.
66  However, it is a problem in the definition of the vector potential
67  which is consistently computed using its physical definition.
68  Therefore, to correctly update the phi component of the vector
69  potential we change sign to \f$ E_z \f$ (\f$ = -E_\phi \f$).
70 
71  \authors A. Mignone (mignone@ph.unito.it)\n
72  P. Tzeferacos (petros.tzeferacos@ph.unito.it)
73  \date Sep 24, 2012
74 */
75 /* ///////////////////////////////////////////////////////////////////// */
76 #include "pluto.h"
77 
78 #if (PHYSICS == MHD || PHYSICS == RMHD) && (UPDATE_VECTOR_POTENTIAL == YES)
79 /* ********************************************************************* */
80 void VectorPotentialUpdate (const Data *d, const void *vp,
81  const State_1D *state, const Grid *grid)
82 /*!
83  *
84  *********************************************************************** */
85 {
86  int i,j,k;
87  double scrh, dt, sEz = 0.25;
88  double Ex, Ey, Ez;
89 
90 /* ---------------------------------------------------------
91  When this function is called from Time stepping
92  routines and CT is used, do nothing.
93  --------------------------------------------------------- */
94 
95  #ifdef STAGGERED_MHD
96  if (vp == NULL) return;
97  #endif
98 
99  #if GEOMETRY == CYLINDRICAL
100  sEz = -0.25;
101  #endif
102 
103 /* ------------------------------------------------------
104  Determine dt according to the integration step
105  ------------------------------------------------------ */
106 
107  dt = g_dt;
108  #if TIME_STEPPING == RK2
109  dt *= 0.5;
110  #elif TIME_STEPPING == RK3
111  dt /= 6.0;
112  if (g_intStage == 3) dt *= 4.0;
113  #endif
114 
115  #ifdef CTU
116  if (g_intStage == 1) return;
117  #endif
118 
119  #ifdef STAGGERED_MHD
120 /* -----------------------------------------------------
121  If staggered fields are used, we average the
122  EMF available at cell edges:
123 
124  A-----------B
125  | |
126  | |
127  | o | o = (A+B+C+D)/4
128  | |
129  | |
130  D-----------C
131  ----------------------------------------------------- */
132  {
133  EMF *emf;
134  emf = (EMF *) vp;
135 
136  DOM_LOOP(k,j,i){
137  Ez = sEz*(emf->ez[k][j][i] + emf->ez[k][j-1][i] +
138  emf->ez[k][j-1][i-1] + emf->ez[k][j][i-1]);
139 
140  #if DIMENSIONS == 3
141  Ex = 0.25*(emf->ex[k][j][i] + emf->ex[k][j-1][i] +
142  emf->ex[k-1][j-1][i] + emf->ex[k-1][j][i]);
143 
144  Ey = 0.25*(emf->ey[k][j][i] + emf->ey[k][j][i-1] +
145  emf->ey[k-1][j][i-1] + emf->ey[k-1][j][i]);
146  #endif
147 
148  d->Ax3[k][j][i] -= dt*Ez;
149  #if DIMENSIONS == 3
150  d->Ax1[k][j][i] -= dt*Ex;
151  d->Ax2[k][j][i] -= dt*Ey;
152  #endif
153 
154  }
155  }
156  #else
157 /* ------------------------------------------------------------
158  If cell-center is used, we average the
159  EMF available at cell faces:
160 
161  +-----B-----+
162  | |
163  | |
164  A o C o = (A+B+C+D)/4
165  | |
166  | |
167  +-----D-----+
168 
169  The components of the flux in the induction equation give
170  the emf:
171 
172  when g_dir == IDIR we have F(i+1/2) = (0,-Ez, Ey)
173  when g_dir == JDIR we have F(j+1/2) = (Ez,0,-Ex)
174  when g_dir == KDIR we have F(k+1/2) = (-Ey,Ex,0)
175 
176  ------------------------------------------------------------ */
177  {
178  double **f;
179 
180  f = state->flux;
181  if (g_dir == IDIR){
182 
183  IDOM_LOOP(i){
184  d->Ax3[g_k][g_j][i] -= -sEz*dt*(f[i][BX2] + f[i-1][BX2]); /* -Ez */
185  #if DIMENSIONS == 3
186  d->Ax2[g_k][g_j][i] -= 0.25*dt*(f[i][BX3] + f[i-1][BX3]); /* Ey */
187  #endif
188  }
189  }else if (g_dir == JDIR){
190 
191  JDOM_LOOP(j) {
192  #if DIMENSIONS == 3
193  d->Ax1[g_k][j][g_i] -= -0.25*dt*(f[j][BX3] + f[j-1][BX3]); /* -Ex */
194  #endif
195  d->Ax3[g_k][j][g_i] -= sEz*dt*(f[j][BX1] + f[j-1][BX1]); /* Ez */
196  }
197 
198  }else if (g_dir == KDIR){
199  KDOM_LOOP(k){
200  d->Ax1[k][g_j][g_i] -= 0.25*dt*(f[k][BX2] + f[k-1][BX2]);
201  d->Ax2[k][g_j][g_i] -= -0.25*dt*(f[k][BX1] + f[k-1][BX1]);
202  }
203  }
204  }
205  #endif /* STAGGERED_MHD */
206 }
207 #endif /* UPDATE_VECTOR_POTENTIAL == YES */
static EMF emf
Definition: ct_emf.c:27
#define KDOM_LOOP(k)
Definition: macros.h:36
DOM_LOOP(k, j, i)
Definition: analysis.c:22
double ** flux
upwind flux computed with the Riemann solver
Definition: structs.h:149
double *** ex
Definition: ct.h:103
tuple scrh
Definition: configure.py:200
int g_intStage
Gives the current integration stage of the time stepping method (predictor = 0, 1st corrector = 1...
Definition: globals.h:98
double g_dt
The current integration time step.
Definition: globals.h:118
double *** Ax3
Vector potential component in the direction.
Definition: structs.h:53
#define KDIR
Definition: pluto.h:195
#define JDOM_LOOP(j)
Definition: macros.h:35
int g_i
x1 grid index when sweeping along the x2 or x3 direction.
Definition: globals.h:82
double *** ez
Definition: ct.h:105
#define IDIR
Definition: pluto.h:193
int g_dir
Specifies the current sweep or direction of integration.
Definition: globals.h:86
int g_j
x2 grid index when sweeping along the x1 or x3 direction.
Definition: globals.h:83
Definition: structs.h:78
int j
Definition: analysis.c:2
int k
Definition: analysis.c:2
int g_k
x3 grid index when sweeping along the x1 or x2 direction.
Definition: globals.h:84
#define BX3
Definition: mod_defs.h:27
PLUTO main header file.
Definition: structs.h:30
int i
Definition: analysis.c:2
#define BX1
Definition: mod_defs.h:25
#define BX2
Definition: mod_defs.h:26
void VectorPotentialUpdate(const Data *d, const void *vp, const State_1D *state, const Grid *grid)
double *** ey
Definition: ct.h:104
#define JDIR
Definition: pluto.h:194
double *** Ax1
Vector potential component in the direction.
Definition: structs.h:51
double *** Ax2
Vector potential component in the direction.
Definition: structs.h:52
#define IDOM_LOOP(i)
Definition: macros.h:34