PLUTO
mappers.c
Go to the documentation of this file.
1 /* ///////////////////////////////////////////////////////////////////// */
2 /*!
3  \file
4  \brief Convert between primitive and conservative variables.
5 
6  The PrimToCons() converts an array of primitive quantities to
7  an array of conservative variables for the RMHD equations.
8 
9  The ConsToPrim() converts an array of conservative quantities to
10  an array of primitive quantities.
11  During the conversion, pressure is normally recovered from total
12  energy using the algorithm outlined in
13  - "Equation of state in relativistic magnetohydrodynamics: variable versus
14  constant adiabatic index"\n
15  Mignone \& Mc Kinney, MNRAS (2007) 378, 1118.
16 
17  However, if the zone has been tagged with FLAG_ENTROPY, primitive
18  variables are recovered by using the conserved entropy rather than
19  total energy.
20 
21  In other words:
22 
23  if (FLAG_ENTROPY is TRUE) --> p = p(S)
24  else --> p = p(E)
25 
26  If the inversion scheme fails and p cannot be obtained the
27  PressureFix() function is used.
28 
29  \author A. Mignone (mignone@ph.unito.it)
30  \date June 25, 2015
31 */
32 /* ///////////////////////////////////////////////////////////////////// */
33 #include "pluto.h"
34 
35 /* ********************************************************************* */
36 void PrimToCons (double **uprim, double **ucons, int beg, int end)
37 /*!
38  * Convert primitive variables to conservative variables.
39  *
40  * \param [in] uprim array of primitive variables
41  * \param [out] ucons array of conservative variables
42  * \param [in] beg starting index of computation
43  * \param [in] end final index of computation
44  *
45  *********************************************************************** */
46 {
47  int i, nv;
48  double vel2, usq, vB, Bmag2;
49  double vx1, vx2, vx3;
50  double g, g2, wt;
51  double *u, *v;
52  static double *h;
53  #if EOS == IDEAL
54  double gmmr = g_gamma/(g_gamma - 1.0);
55  #endif
56 
57  if (h == NULL) h = ARRAY_1D(NMAX_POINT, double);
58 
59  Enthalpy(uprim, h, beg, end);
60 
61  for (i = beg; i <= end; i++) {
62 
63  v = uprim[i];
64  u = ucons[i];
65 
66  EXPAND(vx1 = v[VX1]; ,
67  vx2 = v[VX2]; ,
68  vx3 = v[VX3];)
69  vel2 = EXPAND(vx1*vx1, + vx2*vx2, + vx3*vx3);
70  g2 = 1.0/(1.0 - vel2);
71  g = sqrt(g2);
72 
73  vB = EXPAND(vx1*v[BX1], + vx2*v[BX2], + vx3*v[BX3]);
74  Bmag2 = EXPAND(v[BX1]*v[BX1], + v[BX2]*v[BX2], + v[BX3]*v[BX3]);
75  wt = v[RHO]*h[i]*g2 + Bmag2;
76 
77  /* -------------------------------------------------------
78  Convert from primitive (v) to conservative (u)
79  ------------------------------------------------------- */
80 
81  u[RHO] = g*v[RHO];
82  EXPAND (u[MX1] = wt*vx1 - vB*v[BX1]; ,
83  u[MX2] = wt*vx2 - vB*v[BX2]; ,
84  u[MX3] = wt*vx3 - vB*v[BX3];)
85 
86  EXPAND (u[BX1] = v[BX1]; ,
87  u[BX2] = v[BX2]; ,
88  u[BX3] = v[BX3];)
89 
91  #if EOS == IDEAL
92  u[ENG] = v[PRS]*(g2*gmmr - 1.0) + u[RHO]*g2*vel2/(g + 1.0)
93  + 0.5*(Bmag2*(1.0 + vel2) - vB*vB);
94  #elif EOS == TAUB
95  wt = v[PRS]/v[RHO];
96  u[ENG] = v[PRS]*(g2*2.5 - 1.0)
97  + u[RHO]*g2*(2.25*wt*wt + vel2)/(g*sqrt(1.0 + 2.25*wt*wt) + 1.0)
98  + 0.5*(Bmag2*(1.0 + vel2) - vB*vB);
99  #endif
100  #else
101  u[ENG] = v[RHO]*h[i]*g2 - v[PRS] + 0.5*(Bmag2*(1.0 + vel2) - vB*vB);
102  #endif
103 
104 #if NSCL > 0
105  NSCL_LOOP(nv) u[nv] = u[RHO]*v[nv];
106 #endif
107 
108  #ifdef GLM_MHD
109  u[PSI_GLM] = v[PSI_GLM];
110  #endif
111  }
112 }
113 
114 /* ********************************************************************* */
115 int ConsToPrim (double **ucons, double **uprim, int beg, int end,
116  unsigned char *flag)
117 /*!
118  * Convert from conservative to primitive variables.
119  *
120  * \param [in] ucons array of conservative variables
121  * \param [out] uprim array of primitive variables
122  * \param [in] beg starting index of computation
123  * \param [in] end final index of computation
124  * \param [in,out] flag array of flags tagging, in input, zones
125  * where entropy must be used to recover pressure
126  * and, on output, zones where conversion was
127  * not successful.
128  *
129  * \return Return 0 if conversion was successful in all zones in the
130  * range [ibeg,iend].
131  * Return 1 if one or more zones could not be converted correctly
132  * and either pressure, density or energy took non-physical values.
133  *
134  *********************************************************************** */
135 {
136  int i, nv, err, ifail;
137  int use_entropy, use_energy=1;
138  double *u, *v, scrh, w_1;
139  Map_param par;
140 
141  ifail = 0;
142  for (i = beg; i <= end; i++) {
143 
144  u = ucons[i];
145  v = uprim[i];
146 
147  /* -----------------------------------------------------------
148  Define the input parameters of the parameter structure
149  ----------------------------------------------------------- */
150 
151  par.D = u[RHO];
152  par.E = u[ENG];
153  par.S = EXPAND(u[MX1]*u[BX1], + u[MX2]*u[BX2], + u[MX3]*u[BX3]);
154  par.m2 = EXPAND(u[MX1]*u[MX1], + u[MX2]*u[MX2], + u[MX3]*u[MX3]);
155  par.B2 = EXPAND(u[BX1]*u[BX1], + u[BX2]*u[BX2], + u[BX3]*u[BX3]);
156  par.S2 = par.S*par.S;
157 
158  /* -------------------------------------------
159  Check density and energy positivity
160  ------------------------------------------- */
161 
162  if (u[RHO] < 0.0) {
163  print("! ConsToPrim(): negative density (%8.2e), ", u[RHO]);
164  Where (i, NULL);
165  u[RHO] = g_smallDensity;
166  flag[i] |= FLAG_CONS2PRIM_FAIL;
167  ifail = 1;
168  }
169 
170  if (u[ENG] < 0.0) {
171  WARNING(
172  print("! ConsToPrim(): negative energy (%8.2e), ", u[ENG]);
173  Where (i, NULL);
174  )
175  u[ENG] = 1.e-5;
176  flag[i] |= FLAG_CONS2PRIM_FAIL;
177  ifail = 1;
178  }
179 
180  /* ---------------------------------------------------------
181  Attempt to recover pressure and velocity from energy or
182  entropy.
183  If an error occurs, use the PressureFix() function
184  ------------------------------------------------------- */
185 
186 #if ENTROPY_SWITCH
187  use_entropy = (flag[i] & FLAG_ENTROPY);
188  use_energy = !use_entropy;
189  par.sigma_c = u[ENTR];
190  if (use_entropy) {
191  err = EntropySolve(&par);
192  if (err) {
193  WARNING(Where (i, NULL);)
194  err = PressureFix(&par);
195  if (err){
196  Where(i,NULL);
197  QUIT_PLUTO(1);
198  }
199  flag[i] |= FLAG_CONS2PRIM_FAIL;
200  ifail = 1;
201  }
202  u[ENG] = par.E; /* Redefine energy */
203  }
204 #endif
205 
206  if (use_energy){
207  err = EnergySolve(&par);
208  if (err){
209  WARNING(Where(i,NULL);)
210  err = PressureFix(&par);
211  if (err){
212  Where(i,NULL);
213  QUIT_PLUTO(1);
214  }
215  u[ENG] = par.E;
216  flag[i] |= FLAG_CONS2PRIM_FAIL;
217  ifail = 1;
218  }
219 #if ENTROPY_SWITCH
220  u[ENTR] = par.sigma_c; /* Redefine entropy */
221 #endif
222  }
223 
224  /* -- W, p and lor have been found. Now complete conversion -- */
225 
226  v[RHO] = u[RHO]/par.lor;
227  v[PRS] = par.prs;
228 
229  w_1 = 1.0/(par.W + par.B2);
230  scrh = par.S/par.W;
231  EXPAND(v[VX1] = w_1*(u[MX1] + scrh*u[BX1]); ,
232  v[VX2] = w_1*(u[MX2] + scrh*u[BX2]); ,
233  v[VX3] = w_1*(u[MX3] + scrh*u[BX3]);)
234 
235  scrh = EXPAND(v[VX1]*v[VX1], + v[VX2]*v[VX2], + v[VX3]*v[VX3]);
236  if (scrh >= 1.0){
237  print ("! ConsToPrim(): v^2 = %f > 1 (p = %12.6e); ", scrh, par.prs);
238  Where (i, NULL);
239  print ("! Flag_Entropy = %d\n", (flag[i] & FLAG_ENTROPY));
240  QUIT_PLUTO(1);
241  }
242 
243  EXPAND(v[BX1] = u[BX1]; ,
244  v[BX2] = u[BX2]; ,
245  v[BX3] = u[BX3];)
246 
247 #if NSCL > 0
248  NSCL_LOOP(nv) v[nv] = u[nv]/u[RHO];
249 #endif
250 
251 #ifdef GLM_MHD
252  v[PSI_GLM] = u[PSI_GLM];
253 #endif
254 
255  }
256  return ifail;
257 }
#define IDEAL
Definition: pluto.h:45
#define RMHD_REDUCED_ENERGY
By turning RMHD_REDUCED_ENERGY to YES, we let PLUTO evolve the total energy minus the mass density co...
Definition: mod_defs.h:193
#define MX3
Definition: mod_defs.h:22
#define EOS
Definition: pluto.h:341
#define NSCL_LOOP(n)
Definition: pluto.h:616
double g_gamma
Definition: globals.h:112
#define MX1
Definition: mod_defs.h:20
double m2
Square of total momentum (input).
Definition: mod_defs.h:89
#define VX2
Definition: mod_defs.h:29
double D
Lab density (input).
Definition: mod_defs.h:86
double g_smallDensity
Small value for density fix.
Definition: globals.h:109
int PressureFix(Map_param *)
Definition: pressure_fix.c:22
#define RHO
Definition: mod_defs.h:19
tuple scrh
Definition: configure.py:200
#define WARNING(a)
Definition: macros.h:217
#define YES
Definition: pluto.h:25
void Enthalpy(double **v, real *h, int beg, int end)
Definition: eos.c:48
static double gmmr
Definition: two_shock.c:42
#define PSI_GLM
Definition: mod_defs.h:34
double v[NVAR]
Definition: eos.h:106
int EnergySolve(Map_param *par)
Definition: energy_solve.c:23
#define VX1
Definition: mod_defs.h:28
double S2
Square of S (input).
Definition: mod_defs.h:95
#define FLAG_CONS2PRIM_FAIL
Definition: pluto.h:189
#define FLAG_ENTROPY
Update pressure using entropy equation.
Definition: pluto.h:182
int ConsToPrim(double **ucons, double **uprim, int ibeg, int iend, unsigned char *flag)
Definition: mappers.c:89
int EntropySolve(Map_param *par)
Definition: entropy_solve.c:21
#define NSCL
Definition: pluto.h:572
double W
D*h*lor (output).
Definition: mod_defs.h:92
#define MX2
Definition: mod_defs.h:21
list vel2
Definition: Sph_disk.py:39
double S
mB (input).
Definition: mod_defs.h:94
void Where(int, Grid *)
Definition: tools.c:235
void print(const char *fmt,...)
Definition: amrPluto.cpp:497
#define BX3
Definition: mod_defs.h:27
PLUTO main header file.
#define ARRAY_1D(nx, type)
Definition: prototypes.h:170
double lor
Lorentz factor (output).
Definition: mod_defs.h:93
long int NMAX_POINT
Maximum number of points among the three directions, boundaries excluded.
Definition: globals.h:62
void PrimToCons(double **uprim, double **ucons, int ibeg, int iend)
Definition: mappers.c:26
int i
Definition: analysis.c:2
double prs
Thermal pressure (output).
Definition: mod_defs.h:94
#define BX1
Definition: mod_defs.h:25
#define VX3
Definition: mod_defs.h:30
#define BX2
Definition: mod_defs.h:26
double sigma_c
Conserved entropy (input).
Definition: mod_defs.h:87
double B2
Square of magnetic field (input).
Definition: mod_defs.h:96
#define QUIT_PLUTO(e_code)
Definition: macros.h:125
double E
Total energy (input).
Definition: mod_defs.h:88