PLUTO
ct_emf.c File Reference

Store or retrieve the Electromotive Force (EMF). More...

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

Go to the source code of this file.

Macros

#define eps_UCT_CONTACT   1.e-6
 
#define EX(k, j, i)   (vz[k][j][i]*By[k][j][i] - vy[k][j][i]*Bz[k][j][i])
 
#define EY(k, j, i)   (vx[k][j][i]*Bz[k][j][i] - vz[k][j][i]*Bx[k][j][i])
 
#define EZ(k, j, i)   (vy[k][j][i]*Bx[k][j][i] - vx[k][j][i]*By[k][j][i])
 

Functions

void CT_StoreEMF (const State_1D *state, int beg, int end, Grid *grid)
 
EMFCT_GetEMF (const Data *d, Grid *grid)
 

Variables

static EMF emf
 

Detailed Description

Store or retrieve the Electromotive Force (EMF).

This file provides a database functionality for storing or retrieving EMF components and related information at different points and times in the code.

The CT_StoreEMF() function is called immediately after a 1D Riemann solver during the hydro sweeps in order to save Fluxes and characteristic signal velocities into the emf structure for later reuse. The fluxes coming from different sweeps are the different components of the advective part (-v X B) part of the electric field.

The function CT_GetEMF() is used to obtain the edge-centered electric field by properly averaging the EMF components previously stored at the zone faces during the 1D sweeps.

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

Definition in file ct_emf.c.

Macro Definition Documentation

#define eps_UCT_CONTACT   1.e-6

Definition at line 29 of file ct_emf.c.

#define EX (   k,
  j,
  i 
)    (vz[k][j][i]*By[k][j][i] - vy[k][j][i]*Bz[k][j][i])

Definition at line 30 of file ct_emf.c.

#define EY (   k,
  j,
  i 
)    (vx[k][j][i]*Bz[k][j][i] - vz[k][j][i]*Bx[k][j][i])

Definition at line 31 of file ct_emf.c.

#define EZ (   k,
  j,
  i 
)    (vy[k][j][i]*Bx[k][j][i] - vx[k][j][i]*By[k][j][i])

Definition at line 32 of file ct_emf.c.

Function Documentation

EMF* CT_GetEMF ( const Data d,
Grid grid 
)

Retrieve EMF by suitable average of 1D face-centered fluxes.

Parameters
[in]d
[in]grid
Returns
a pointer to an edge-centered EMF.

Definition at line 205 of file ct_emf.c.

214 {
215  int i, j, k;
216  double ***vx, ***vy, ***vz;
217  double ***Bx, ***By, ***Bz;
218 
219 /* -----------------------------------------------------
220  Return only the resistive part of emf when using
221  super time stepping.
222  ----------------------------------------------------- */
223 
224  #if RESISTIVITY == SUPER_TIME_STEPPING
226  TOT_LOOP(k,j,i) {
227  #if DIMENSIONS == 3
228  emf.ex[k][j][i] = emf.ey[k][j][i] = 0.0;
229  #endif
230  emf.ez[k][j][i] = 0.0;
231  }
232  CT_AddResistiveEMF(d, grid);
233  return (&emf);
234  }
235  #endif
236 
237 /* -------------------------------------
238  set boundary conditions on
239  face-centered electric fields
240  ------------------------------------- */
241 /*
242  #ifdef CTU
243  if (g_intStage == 2)
244  #endif
245  EMF_BOUNDARY (&emf, grid);
246 */
247 
248 /* ------------------------------------------------------
249  Compute slopes of staggered magnetic fields
250  ------------------------------------------------------ */
251 
252  #if CT_EMF_AVERAGE == UCT_HLL
253  #ifdef CTU
254  if (g_intStage == 1)
255  #endif
256  CT_GetStagSlopes(d->Vs, &emf, grid);
257  #endif
258 
259 /* -----------------------------------------------------
260  Select average
261  ----------------------------------------------------- */
262 
263  #if CT_EMF_AVERAGE == ARITHMETIC || CT_EMF_AVERAGE == RIEMANN_2D
264 
265  CT_EMF_ArithmeticAverage (&emf, 0.25);
266 
267  #elif CT_EMF_AVERAGE == UCT_CONTACT
268 
270  CT_EMF_IntegrateToCorner (d, &emf, grid);
271  for (k = emf.kbeg; k <= emf.kend; k++){
272  for (j = emf.jbeg; j <= emf.jend; j++){
273  for (i = emf.ibeg; i <= emf.iend; i++){
274  #if DIMENSIONS == 3
275  emf.ex[k][j][i] *= 0.25;
276  emf.ey[k][j][i] *= 0.25;
277  #endif
278  emf.ez[k][j][i] *= 0.25;
279  }}}
280 
281  #elif CT_EMF_AVERAGE == UCT_HLL
282  #ifdef CTU
283  if (g_intStage == 1) CT_EMF_CMUSCL_Average (d, &emf, grid);
284  else
285  #endif
286  CT_EMF_HLL_Solver (d, &emf, grid);
287 
288  #elif CT_EMF_AVERAGE == UCT0
289 
290 /* -- Subtract cell-centered contribution -- */
291 
292  EXPAND(vx = d->Vc[VX1]; Bx = d->Vc[BX1]; ,
293  vy = d->Vc[VX2]; By = d->Vc[BX2]; ,
294  vz = d->Vc[VX3]; Bz = d->Vc[BX3];)
295 
296  for (k = emf.kbeg; k <= emf.kend + KOFFSET; k++){
297  for (j = emf.jbeg; j <= emf.jend + JOFFSET; j++){
298  for (i = emf.ibeg; i <= emf.iend + IOFFSET; i++){
299  #if DIMENSIONS == 3
300  emf.exj[k][j][i] *= 2.0;
301  emf.exk[k][j][i] *= 2.0;
302  emf.eyi[k][j][i] *= 2.0;
303  emf.eyk[k][j][i] *= 2.0;
304 
305  emf.exj[k][j][i] -= 0.5*(EX(k,j,i) + EX(k,j+1,i));
306  emf.exk[k][j][i] -= 0.5*(EX(k,j,i) + EX(k+1,j,i));
307 
308  emf.eyi[k][j][i] -= 0.5*(EY(k,j,i) + EY(k,j,i+1));
309  emf.eyk[k][j][i] -= 0.5*(EY(k,j,i) + EY(k+1,j,i));
310  #endif
311  emf.ezi[k][j][i] *= 2.0;
312  emf.ezj[k][j][i] *= 2.0;
313  emf.ezi[k][j][i] -= 0.5*(EZ(k,j,i) + EZ(k,j,i+1));
314  emf.ezj[k][j][i] -= 0.5*(EZ(k,j,i) + EZ(k,j+1,i));
315  }}}
316 
317  CT_EMF_ArithmeticAverage (&emf, 0.25);
318 
319  #else
320  print1 ("! CT_GetEMF: unknown EMF average.\n");
321  QUIT_PLUTO(1);
322  #endif
323 
324 
325 /* ------------------------------------------------------
326  Add contributions from resistive terms with explicit
327  time stepping.
328  ------------------------------------------------------ */
329 
330  #if RESISTIVITY == EXPLICIT
331  CT_AddResistiveEMF(d, grid);
332  #endif
333 
334 /* -------------------------------------------------------------
335  Fine Tuning: EMF_USERDEF_BOUNDARY can be used to directly
336  set the edge-centered electric field
337  ------------------------------------------------------------- */
338 /*
339  #ifdef CTU
340  if (step == 2)
341  #endif
342  {
343  int lside[3] = {X1_BEG, X2_BEG, X3_BEG};
344  int rside[3] = {X1_END, X2_END, X3_END};
345  int dir;
346 
347  for (dir = 0; dir < DIMENSIONS; dir++){
348  if (grid[dir].lbound == USERDEF)
349  EMF_USERDEF_BOUNDARY (&emf, lside[dir], EDGE_EMF, grid);
350  if (grid[dir].rbound == USERDEF)
351  EMF_USERDEF_BOUNDARY (&emf, rside[dir], EDGE_EMF, grid);
352  }
353  }
354 */
355 
356  return (&emf);
357 }
static EMF emf
Definition: ct_emf.c:27
double **** Vs
The main four-index data array used for face-centered staggered magnetic fields.
Definition: structs.h:43
void CT_GetStagSlopes(const Data_Arr b, EMF *emf, Grid *grid)
#define VX2
Definition: mod_defs.h:29
void print1(const char *fmt,...)
Definition: amrPluto.cpp:511
double *** ex
Definition: ct.h:103
int g_intStage
Gives the current integration stage of the time stepping method (predictor = 0, 1st corrector = 1...
Definition: globals.h:98
double **** Vc
The main four-index data array used for cell-centered primitive variables.
Definition: structs.h:31
void CT_EMF_ArithmeticAverage(const EMF *Z1, const double w)
Compute arithmetic average of EMF at cell edges.
#define EZ(k, j, i)
Definition: ct_emf.c:32
#define VX1
Definition: mod_defs.h:28
void CT_EMF_HLL_Solver(const Data *d, const EMF *emf, Grid *grid)
Solve 2D Riemann problem for induction equation.
#define PARABOLIC_STEP
Definition: pluto.h:74
double *** ezi
Ez available at x-faces (i+1/2);.
Definition: ct.h:79
double *** ez
Definition: ct.h:105
#define TOT_LOOP(k, j, i)
Definition: macros.h:44
double *** exk
Ex available at z-faces (k+1/2);.
Definition: ct.h:76
static double Bx
Definition: hlld.c:62
int j
Definition: analysis.c:2
int k
Definition: analysis.c:2
void CT_EMF_CMUSCL_Average(const Data *d, const EMF *emf, Grid *grid)
#define BX3
Definition: mod_defs.h:27
double *** eyi
Ey available at x-faces (i+1/2);.
Definition: ct.h:77
void CT_EMF_IntegrateToCorner(const Data *d, const EMF *emf, Grid *grid)
double *** eyk
Ey available at z-faces (k+1/2);.
Definition: ct.h:78
#define EY(k, j, i)
Definition: ct_emf.c:31
int g_operatorStep
Gives the current operator step.
Definition: globals.h:101
int i
Definition: analysis.c:2
double *** ezj
Ez available at y-faces (j+1/2);.
Definition: ct.h:80
#define EX(k, j, i)
Definition: ct_emf.c:30
#define BX1
Definition: mod_defs.h:25
#define VX3
Definition: mod_defs.h:30
#define BX2
Definition: mod_defs.h:26
double *** ey
Definition: ct.h:104
double *** exj
Ex available at y-faces (j+1/2);.
Definition: ct.h:75
#define QUIT_PLUTO(e_code)
Definition: macros.h:125

Here is the call graph for this function:

Here is the caller graph for this function:

void CT_StoreEMF ( const State_1D state,
int  beg,
int  end,
Grid grid 
)

Store EMF components and related information available during 1D sweeps.

Parameters
[in]statepointer to State_1D structure
[in]beginitial index of computation
[in]endfinal index of computation
[in]gridpointer to Grid structure;
Returns
This function has no return value.

Definition at line 35 of file ct_emf.c.

47 {
48  int i, j, k, s;
49 
50 /* ----------------------------------------------------
51  Allocate memory for EMF structure and
52  check for incompatible combinations of algorithms
53  ---------------------------------------------------- */
54 
55  if (emf.ez == NULL){
56 
57  emf.ibeg = emf.iend = 0;
58  emf.jbeg = emf.jend = 0;
59  emf.kbeg = emf.kend = 0;
60 
61  /* -- memory allocation -- */
62 
63  D_EXPAND( ; ,
64  emf.ez = ARRAY_3D(NX3_TOT, NX2_TOT, NX1_TOT, double); ,
65  emf.ex = ARRAY_3D(NX3_TOT, NX2_TOT, NX1_TOT, double);
66  emf.ey = ARRAY_3D(NX3_TOT, NX2_TOT, NX1_TOT, double);
67  )
68 
70  D_EXPAND(
71  emf.svx = ARRAY_3D(NX3_TOT, NX2_TOT, NX1_TOT, signed char); ,
72  emf.svy = ARRAY_3D(NX3_TOT, NX2_TOT, NX1_TOT, signed char); ,
73  emf.svz = ARRAY_3D(NX3_TOT, NX2_TOT, NX1_TOT, signed char);
74  )
75  #endif
76 
77  D_EXPAND( ; ,
78  emf.ezi = ARRAY_3D(NX3_TOT, NX2_TOT, NX1_TOT, double);
79  emf.ezj = ARRAY_3D(NX3_TOT, NX2_TOT, NX1_TOT, double); ,
80 
81  emf.exj = ARRAY_3D(NX3_TOT, NX2_TOT, NX1_TOT, double);
82  emf.exk = ARRAY_3D(NX3_TOT, NX2_TOT, NX1_TOT, double);
83 
84  emf.eyi = ARRAY_3D(NX3_TOT, NX2_TOT, NX1_TOT, double);
85  emf.eyk = ARRAY_3D(NX3_TOT, NX2_TOT, NX1_TOT, double);
86  )
87 
88  #if CT_EMF_AVERAGE == UCT_HLL
89 
90  D_EXPAND(
91  emf.SxL = ARRAY_3D(NX3_TOT, NX2_TOT, NX1_TOT, double);
92  emf.SxR = ARRAY_3D(NX3_TOT, NX2_TOT, NX1_TOT, double); ,
93 
94  emf.SyL = ARRAY_3D(NX3_TOT, NX2_TOT, NX1_TOT, double);
95  emf.SyR = ARRAY_3D(NX3_TOT, NX2_TOT, NX1_TOT, double); ,
96 
97  emf.SzL = ARRAY_3D(NX3_TOT, NX2_TOT, NX1_TOT, double);
98  emf.SzR = ARRAY_3D(NX3_TOT, NX2_TOT, NX1_TOT, double);
99  )
100  #endif
101  }
102 
103 /* ------------------------------------------------------
104  Store emf components or other necessary 1-D data
105  ------------------------------------------------------ */
106 
107  if (g_dir == IDIR){
108 
109  emf.ibeg = beg; emf.iend = end;
110  for (i = beg; i <= end; i++) {
111 
112  D_EXPAND(emf.ezi[g_k][g_j][i] = -state->flux[i][BX2]; ,
113  ,
114  emf.eyi[g_k][g_j][i] = state->flux[i][BX3]; )
115 
116  #if CT_EMF_AVERAGE == UCT_CONTACT
117  if (state->flux[i][RHO] > eps_UCT_CONTACT) s = 1;
118  else if (state->flux[i][RHO] < -eps_UCT_CONTACT) s = -1;
119  else s = 0;
120 
121  emf.svx[g_k][g_j][i] = s;
122  #endif
123 
124  #if CT_EMF_AVERAGE == UCT_HLL
125  emf.SxL[g_k][g_j][i] = MAX(0.0, -state->SL[i]);
126  emf.SxR[g_k][g_j][i] = MAX(0.0, state->SR[i]);
127  #endif
128 
129  #if CT_EMF_AVERAGE == RIEMANN_2D
130  emf.ezi[g_k][g_j][i] = -2.0*(state->pnt_flx[i][BX2] +
131  state->dff_flx[i][BX2]);
132  #endif
133 
134  }
135 
136  }else if (g_dir == JDIR){
137 
138  emf.jbeg = beg; emf.jend = end;
139  for (j = beg; j <= end; j++) {
140 
141  D_EXPAND( ; ,
142  emf.ezj[g_k][j][g_i] = state->flux[j][BX1]; ,
143  emf.exj[g_k][j][g_i] = -state->flux[j][BX3]; )
144 
146  if (state->flux[j][RHO] > eps_UCT_CONTACT) s = 1;
147  else if (state->flux[j][RHO] < -eps_UCT_CONTACT) s = -1;
148  else s = 0;
149  emf.svy[g_k][j][g_i] = s;
150  #endif
151 
152  #if CT_EMF_AVERAGE == UCT_HLL
153  emf.SyL[g_k][j][g_i] = MAX(0.0, -state->SL[j]);
154  emf.SyR[g_k][j][g_i] = MAX(0.0, state->SR[j]);
155  #endif
156 
157  #if CT_EMF_AVERAGE == RIEMANN_2D
158 // emf.ezj[g_k][j][g_i] += state->dff_flx[j][BX1];
159  emf.ezj[g_k][j][g_i] = 2.0*(state->pnt_flx[j][BX1] +
160  state->dff_flx[j][BX1]);
161  #endif
162  }
163 
164  }else if (g_dir == KDIR){
165 
166  emf.kbeg = beg; emf.kend = end;
167  for (k = beg; k <= end; k++) {
168 
169  emf.eyk[k][g_j][g_i] = -state->flux[k][BX1];
170  emf.exk[k][g_j][g_i] = state->flux[k][BX2];
171 
172  #if CT_EMF_AVERAGE == UCT_CONTACT
173  if (state->flux[k][RHO] > eps_UCT_CONTACT) s = 1;
174  else if (state->flux[k][RHO] < -eps_UCT_CONTACT) s = -1;
175  else s = 0;
176  emf.svz[k][g_j][g_i] = s;
177  #endif
178 
179  #if CT_EMF_AVERAGE == UCT_HLL
180  emf.SzL[k][g_j][g_i] = MAX(0.0, -state->SL[k]);
181  emf.SzR[k][g_j][g_i] = MAX(0.0, state->SR[k]);
182  #endif
183 
184  }
185  }
186 
187 /* ------------------------------------------------------
188  Store velocity slopes if necessary
189  ------------------------------------------------------ */
190 
191  #if CT_EMF_AVERAGE == UCT_HLL
192  #ifdef CTU
193  if (g_intStage == 2) return;
194  #endif
195 
196  /* -- "end+1" needed to save dvx_dx -- */
197 
198  CT_StoreVelSlopes (&emf, state, beg, end + 1);
199 
200  #endif
201 
202 }
#define MAX(a, b)
Definition: macros.h:101
static EMF emf
Definition: ct_emf.c:27
double ** flux
upwind flux computed with the Riemann solver
Definition: structs.h:149
#define eps_UCT_CONTACT
Definition: ct_emf.c:29
double *** SxL
Definition: ct.h:93
double *** SzR
Definition: ct.h:98
double *** ex
Definition: ct.h:103
#define RHO
Definition: mod_defs.h:19
signed char *** svy
Definition: ct.h:83
long int NX2_TOT
Total number of zones in the X2 direction (boundaries included) for the local processor.
Definition: globals.h:57
double *** SxR
Definition: ct.h:94
int g_intStage
Gives the current integration stage of the time stepping method (predictor = 0, 1st corrector = 1...
Definition: globals.h:98
double * SR
Rightmost velocity in the Riemann fan at i+1/2.
Definition: structs.h:167
#define UCT_CONTACT
Definition: ct.h:21
#define ARRAY_3D(nx, ny, nz, type)
Definition: prototypes.h:172
#define KDIR
Definition: pluto.h:195
int g_i
x1 grid index when sweeping along the x2 or x3 direction.
Definition: globals.h:82
#define CT_EMF_AVERAGE
double *** ezi
Ez available at x-faces (i+1/2);.
Definition: ct.h:79
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
double *** exk
Ex available at z-faces (k+1/2);.
Definition: ct.h:76
int g_j
x2 grid index when sweeping along the x1 or x3 direction.
Definition: globals.h:83
double * SL
Leftmost velocity in the Riemann fan at i+1/2.
Definition: structs.h:166
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
if(divB==NULL)
Definition: analysis.c:10
int k
Definition: analysis.c:2
#define UCT_HLL
Definition: ct.h:22
double *** SyR
Definition: ct.h:96
int g_k
x3 grid index when sweeping along the x1 or x2 direction.
Definition: globals.h:84
signed char *** svz
Definition: ct.h:83
#define s
#define BX3
Definition: mod_defs.h:27
double *** eyi
Ey available at x-faces (i+1/2);.
Definition: ct.h:77
signed char *** svx
Definition: ct.h:83
void CT_StoreVelSlopes(EMF *emf, const State_1D *state, int beg, int end)
Definition: ct_stag_slopes.c:5
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
double *** eyk
Ey available at z-faces (k+1/2);.
Definition: ct.h:78
int i
Definition: analysis.c:2
double *** SzL
Definition: ct.h:97
double *** ezj
Ez available at y-faces (j+1/2);.
Definition: ct.h:80
#define BX1
Definition: mod_defs.h:25
#define BX2
Definition: mod_defs.h:26
double *** ey
Definition: ct.h:104
#define JDIR
Definition: pluto.h:194
double *** exj
Ex available at y-faces (j+1/2);.
Definition: ct.h:75
long int NX1_TOT
Total number of zones in the X1 direction (boundaries included) for the local processor.
Definition: globals.h:55
double *** SyL
Definition: ct.h:95

Here is the call graph for this function:

Here is the caller graph for this function:

Variable Documentation

EMF emf
static

Definition at line 27 of file ct_emf.c.