PLUTO
internal_energy.c File Reference

Thermodynamic relations for the caloric EoS, e=e(T,rho) and T=T(e,rho). More...

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

Go to the source code of this file.

Macros

#define TV_ENERGY_TABLE_NX   1024
 
#define TV_ENERGY_TABLE_NY   512
 

Functions

static double rhoeFunc (double, void *)
 
static double InternalEnergyDeriv (double rho, double T)
 
void MakeInternalEnergyTable ()
 
void MakeEV_TemperatureTable ()
 
double InternalEnergy (double *v, double T)
 
int GetEV_Temperature (double rhoe, double *v, double *T)
 
void SoundSpeed2 (double **v, double *cs2, double *h, int beg, int end, int pos, Grid *grid)
 

Variables

static Table2D rhoe_tab
 A 2D table containing pre-computed values of internal energy stored at equally spaced node values of Log(T) and Log(rho) . More...
 
static Table2D Trhoe_tab
 A 2D table containing pre-computed values of temperature by inverting e=e(T,rho) at equally spaced node values of Log(rhoe) and Log(rho). More...
 

Detailed Description

Thermodynamic relations for the caloric EoS, e=e(T,rho) and T=T(e,rho).

Collect various functions involving computations between internal energy, density and temperature,

\[ e = e(T,\vec{X})\,,\qquad T = T(e,\vec{X}) \]

where e is the specific internal energy, T is the temperature and X are the ionization fractions. The first relation is used to retrieve e as a function of T and X by calling InternalEnergy() while the second one computes T from internal energy and fractions and it is handled by the function GetEV_Temperature():

If no chemistry is used (NIONS==0 ), ionization fractions are computed assuming equilibrium conditions and X=X(T,rho). This requires the numerical inversion of the second equation T=(e,X(T,rho)) which can be carried out using either a root finder algorithm (typically Brent's method) or, alternatively, lookup table together with cubic/linear (default) or bilinear interpolation.

For the root-finder version, a 2D table (Trhoe_tab) giving T=T(rhoe,rho) is pre-computed in the function MakeEV_TemperatureTable() and lookup table is used to narrow down the root interval using the values stored inside this table.

In the tabulated EOS version, a different table (rhoe_tab) rhoe=rhoe(T,rho) giving the internal energy at predefined values of temperature and density is pre-calculated in the function MakeInternalEnergyTable() so that internal energy and temperature can be found by a combination of lookup table and bilinear (direct or inverse) interpolation.

Author
A. Mignone (migno.nosp@m.ne@p.nosp@m.h.uni.nosp@m.to.i.nosp@m.t)
B. Vaidya
Date
7 Jan, 2015

Definition in file internal_energy.c.

Macro Definition Documentation

#define TV_ENERGY_TABLE_NX   1024

Definition at line 47 of file internal_energy.c.

#define TV_ENERGY_TABLE_NY   512

Definition at line 50 of file internal_energy.c.

Function Documentation

int GetEV_Temperature ( double  rhoe,
double *  v,
double *  T 
)

Compute temperature from internal energy, density and fractions by solving either

\[ \begin{array}{ll} \rho e - \rho e(T,\vec{X}) = 0 & \quad{(\rm with\; chemistry)} \\ \noalign{\medskip} \rho e - \rho e(T,\vec{X}(T,\rho)) = 0 & \quad{(\rm without\; chemistry)} \end{array} \]

The previous equations are solved using a root finder algorithm (default is Brent or Ridder) or by lookup table / interpolation methods.

Parameters
[in]rhoeInternal energy of gas in code units.
[in]v1D array of primitive variables (only density and species need to be set).
[out]TTemperature in K
Returns
0 on success, 1 on failure.

Definition at line 290 of file internal_energy.c.

312 {
313 #if TV_ENERGY_TABLE == YES
314  int status;
315  double rho;
316 
317  if (rhoe < 0.0) return 1;
318 
319  rho = v[RHO];
320  status = InverseLookupTable2D(&rhoe_tab, rho, rhoe, T);
321  if (status != 0){
322  WARNING(
323  print ("! GetEV_Temperature(): table interpolation failure");
324  print (" [rho = %12.6e, rhoe = %12.6e]\n",rho,rhoe);
325  )
326  return 1;
327  }
328 
329  if (*T < T_CUT_RHOE) return 1;
330  return 0;
331 #else
332 
333  int nv, status, i, j;
334  double Tmin, Tmax,rho, lnx, lny;
335  struct func_param param;
336 
337  if (rhoe < 0.0) return 1;
338 
339 /* ---------------------------------------------------
340  Constrain species to lie between [0,1]
341  --------------------------------------------------- */
342 
343 #if NIONS > 0
344  NIONS_LOOP(nv) {
345  v[nv] = MAX(v[nv],0.0);
346  v[nv] = MIN(v[nv],1.0);
347  }
348  #if COOLING == H2_COOL
349  v[X_H2] = MIN(v[X_H2], 0.5);
350  #endif
351 #endif
352 
353  param.v[RHO] = v[RHO]; /* maybe set param.v to point to v ?? */
354  param.rhoe = rhoe;
355  NSCL_LOOP(nv) param.v[nv] = v[nv];
356 
357  #if NIONS == 0 /* No chemistry */
358 
359  rho = v[RHO];
360  lnx = log10(rhoe);
361  lny = log10(rho);
364 
365 /* ------------------------------------------------------------------
366  Since Trhoe_tab[j][i] increases with i but decrease with j,
367  the min and max between four adjacent node values are the two
368  opposite points of the secondary diagonal (i,j+1) and (i+1,j),
369  respectively.
370  ------------------------------------------------------------------ */
371 
372  Tmin = Trhoe_tab.f[j+1][i];
373  Tmax = Trhoe_tab.f[j][i+1];
374 
375  #else /* Chemistry */
376  InternalEnergyBracket(rhoe, v, &Tmin, &Tmax);
377  #endif
378 
379  if (Tmin < 0.0 || Tmax < 0.0) return 1;
380 
381 /* status = Ridder(rhoeFunc, &param, Tmin, Tmax,-1, 1.0e-7, &T); */
382  status = Brent(rhoeFunc, &param, Tmin, Tmax, -1, 1.e-7, T);
383 
384  if (*T < T_CUT_RHOE || status != 0) return 1;
385  return 0;
386 
387 #endif /* TV_ENERGY_TABLE == NO */
388 }
#define MAX(a, b)
Definition: macros.h:101
tuple T
Definition: Sph_disk.py:33
#define NIONS_LOOP(n)
Definition: pluto.h:614
#define NSCL_LOOP(n)
Definition: pluto.h:616
#define T_CUT_RHOE
Sets the lowest cut-off temperature used in the PVTE_LAW equation of state.
Definition: eos.h:69
#define RHO
Definition: mod_defs.h:19
#define WARNING(a)
Definition: macros.h:217
double rhoe
Definition: eos.h:107
double dlny_1
Definition: structs.h:205
double v[NVAR]
Definition: eos.h:106
double ** f
Definition: structs.h:186
#define MIN(a, b)
Definition: macros.h:104
int Brent(double(*Func)(double, void *), void *param, double x1, double x2, double abs_acc, double rel_acc, double *xroot)
double dlnx_1
Definition: structs.h:204
int InverseLookupTable2D(Table2D *tab, double y, double f, double *x)
Definition: math_table2D.c:196
#define INT_FLOOR(z)
Definition: macros.h:98
static Table2D Trhoe_tab
A 2D table containing pre-computed values of temperature by inverting e=e(T,rho) at equally spaced no...
int j
Definition: analysis.c:2
static Table2D rhoe_tab
A 2D table containing pre-computed values of internal energy stored at equally spaced node values of ...
static double rhoeFunc(double, void *)
void print(const char *fmt,...)
Definition: amrPluto.cpp:497
int i
Definition: analysis.c:2
double lnxmin
lower limit (in log10) in the x-direction
Definition: structs.h:198
#define X_H2
Definition: cooling.h:30
double lnymin
lower limit (in log10) in the y-direction
Definition: structs.h:200

Here is the call graph for this function:

Here is the caller graph for this function:

double InternalEnergy ( double *  v,
double  T 
)

Compute and return the gas internal energy as a function of temperature and density or fractions: rhoe = rhoe(T,rho) or rhoe = rhoe(T,X) .

Parameters
[in]v1D Array of primitive variables containing density and species. Other variables are ignored.
[in]TGas temperature
Returns
The gas internal energy (rhoe) in code units.

Definition at line 255 of file internal_energy.c.

268 {
269 #if TV_ENERGY_TABLE == YES
270 
271  int status;
272  double rho, rhoe;
273 
274  rho = v[RHO];
275  status = Table2DInterpolate(&rhoe_tab, T, rho, &rhoe);
276  if (status != 0){
277  print ("! InternalEnergy(): table interpolation failure (bound exceeded)\n");
278  QUIT_PLUTO(1);
279  }
280  return rhoe;
281 
282 #else
283 
284  return InternalEnergyFunc (v,T);
285 
286 #endif /* TV_ENERGY_TABLE == NO */
287 }
tuple T
Definition: Sph_disk.py:33
#define RHO
Definition: mod_defs.h:19
double rhoe
Definition: eos.h:107
double v[NVAR]
Definition: eos.h:106
static Table2D rhoe_tab
A 2D table containing pre-computed values of internal energy stored at equally spaced node values of ...
int Table2DInterpolate(Table2D *tab, double x, double y, double *f)
Definition: math_table2D.c:430
void print(const char *fmt,...)
Definition: amrPluto.cpp:497
#define QUIT_PLUTO(e_code)
Definition: macros.h:125
double InternalEnergyFunc(double *v, double T)
Definition: pvte_law.c:47

Here is the call graph for this function:

Here is the caller graph for this function:

double InternalEnergyDeriv ( double  rho,
double  T 
)
static

Compute derivative of internal energy using numerical differentiation

Definition at line 147 of file internal_energy.c.

153 {
154  double Epp, Emm, Ep, Em, dEdT;
155  double dT = 1.e-3, v[256];
156 
157  v[RHO] = rho;
158  Epp = InternalEnergyFunc(v,T*(1.0 + 2.0*dT));
159  Ep = InternalEnergyFunc(v,T*(1.0 + 1.0*dT));
160  Em = InternalEnergyFunc(v,T*(1.0 - 1.0*dT));
161  Emm = InternalEnergyFunc(v,T*(1.0 - 2.0*dT));
162 
163  dEdT = (-Epp + 8.0*Ep - 8.0*Em + Emm)/(12.0*T*dT);
164  return dEdT;
165 }
tuple T
Definition: Sph_disk.py:33
#define RHO
Definition: mod_defs.h:19
double v[NVAR]
Definition: eos.h:106
double InternalEnergyFunc(double *v, double T)
Definition: pvte_law.c:47

Here is the call graph for this function:

Here is the caller graph for this function:

void MakeEV_TemperatureTable ( )

Pre-calculate a 2D table of temperature T(rhoe,rho) by inverting, at specified values of p and rho, the nonlinear equation

\[ f(T) = \rho e - \rho e(T,\rho) = 0 \qquad\Longrightarrow\qquad T_{ij} = T(x_i, y_j) \qquad \left(x=\log_{10}\rho e\,,\quad y=\log_{10}\rho\right) \]

For convenience, the table is constructed using equally spaced bins of x=Log(rhoe) and y=Log(rho) where rhoe and rho are in code units. This function must be called only once to initialize the table Trhoe_tab which is private to this file only.

This table is required only by the root-finder methods and it is useless for the tabulated version (default).

Definition at line 178 of file internal_energy.c.

199 {
200  int i,j, status;
201  double rhoe, rho, Tlo, Thi, T;
202  struct func_param par;
203 
204  print1 ("> MakeEV_TemperatureTable(): Generating table...\n");
205 
206  InitializeTable2D(&Trhoe_tab, 1.e-9, 1.e9, 1200, 1.e-12, 1.e12, 1200);
207  Tlo = 1.0;
208  Thi = 1.e12;
209 
210  for (j = 0; j < Trhoe_tab.ny; j++){
211  for (i = 0; i < Trhoe_tab.nx; i++){
212 
213  par.rhoe = rhoe = Trhoe_tab.x[i];
214  par.v[RHO] = rho = Trhoe_tab.y[j];
215 
216 /* status = Ridder(rhoeFunc, &param, Tlo, Thi, -1, 1.0e-12, &T); */
217  status = Brent(rhoeFunc, &par, Tlo, Thi, -1, 1.e-12, &T);
218 
219  if (status != 0) T = -1.0;
220 
221  Trhoe_tab.f[j][i] = T;
222  }}
223 
224 
225 /* let's plot the exact solution and the fundamental derivative */
226 #if 0
227 int ii;
228 double G, lnT, v[256];
229 FILE *fp;
230 
231 /* -- write exact internal energy, rhoe(T) -- */
232 fp = fopen("rhoe.dat","w");
233 v[RHO] = rho = 1.245197084735e+00;
234 for (lnT = 2.0; lnT < 4.5; lnT += 1.e-3){
235  T = pow(10.0, lnT);
236  rhoe = InternalEnergyFunc(v,T);
237  G = FundamentalDerivative(v,T);
238  fprintf (fp,"%12.6e %12.6e %12.6e\n",T,rhoe,G);
239 }
240 fclose(fp);
241 #endif
242 
243 /* -------------------------------------------------------
244  Compute forward differences
245  ------------------------------------------------------- */
246 
248  if (prank == 0) WriteBinaryTable2D("Trhoe_tab.bin",&Trhoe_tab);
249 }
tuple T
Definition: Sph_disk.py:33
double * y
array of y-values (not uniform)
Definition: structs.h:181
double FundamentalDerivative(double *v, double T)
void print1(const char *fmt,...)
Definition: amrPluto.cpp:511
int nx
Number of columns or points in the x direction.
Definition: structs.h:174
#define RHO
Definition: mod_defs.h:19
double rhoe
Definition: eos.h:107
double v[NVAR]
Definition: eos.h:106
double ** f
Definition: structs.h:186
int prank
Processor rank.
Definition: globals.h:33
void WriteBinaryTable2D(char *fname, Table2D *tab)
Definition: math_table2D.c:528
int Brent(double(*Func)(double, void *), void *param, double x1, double x2, double abs_acc, double rel_acc, double *xroot)
static Table2D Trhoe_tab
A 2D table containing pre-computed values of temperature by inverting e=e(T,rho) at equally spaced no...
int j
Definition: analysis.c:2
int ny
Number of rows or points in the y direction.
Definition: structs.h:175
static double rhoeFunc(double, void *)
void InitializeTable2D(Table2D *tab, double xmin, double xmax, int nx, double ymin, double ymax, int ny)
Definition: math_table2D.c:15
int i
Definition: analysis.c:2
FILE * fp
Definition: analysis.c:7
void FinalizeTable2D(Table2D *tab)
Definition: math_table2D.c:121
double * x
array of x-values (not uniform)
Definition: structs.h:180
double InternalEnergyFunc(double *v, double T)
Definition: pvte_law.c:47

Here is the call graph for this function:

Here is the caller graph for this function:

void MakeInternalEnergyTable ( )

Compute a 2D table of the internal energy rhoe(T,rho) as function of temperature and density. The grid is equally spaced in log10(T) (=x) and log10(rho) (=y). Values are stored in the static table rhoe_tab.

Definition at line 62 of file internal_energy.c.

71 {
72  int i,j;
73  double x, y, q;
74  double T, rho, v[NVAR];
75 
76  print1 ("> MakeInternalEnergyTable(): Generating table (%d x %d points)\n",
78 
80  1.e-6, 1.e6, TV_ENERGY_TABLE_NY);
81  for (j = 0; j < rhoe_tab.ny; j++){
82  for (i = 0; i < rhoe_tab.nx; i++){
83  T = rhoe_tab.x[i];
84  rho = rhoe_tab.y[j];
85  v[RHO] = rho;
86  rhoe_tab.f[j][i] = InternalEnergyFunc(v,T);
87  }}
88 
90 
91 /* ----------------------------------------------------------------
92  Compute cubic spline coefficients
93  ---------------------------------------------------------------- */
94 
95  static double *dfdx;
96 
97  if (dfdx == NULL) dfdx = ARRAY_1D(TV_ENERGY_TABLE_NX, double);
98 
99  for (j = 0; j < rhoe_tab.ny; j++){
100  rho = rhoe_tab.y[j];
101  for (i = 0; i < rhoe_tab.nx; i++){
102  T = rhoe_tab.x[i];
103  dfdx[i] = InternalEnergyDeriv(rho, T);
104  }
107  rhoe_tab.a[j], rhoe_tab.b[j], rhoe_tab.c[j],
108  rhoe_tab.d[j]);
109  }else if (rhoe_tab.interpolation == SPLINE2){
111  dfdx[0], dfdx[rhoe_tab.nx-1], rhoe_tab.nx,
112  rhoe_tab.a[j], rhoe_tab.b[j], rhoe_tab.c[j], rhoe_tab.d[j]);
113  }
114  }
115 
116 /* let's plot the exact solutin and the spline using 20 points between
117  adjacent nodes */
118 #if 0
119 int ii;
120 double G, lnT, rhoe, rhoe_ex;
121 FILE *fp;
122 
123 j = TV_ENERGY_TABLE_NY/2;
124 
125 /* -- write exact internal energy, rhoe(T) -- */
126 
127 fp = fopen("rhoe.dat","w");
128 v[RHO] = rho = rhoe_tab.y[j];
129 for (i = 10; i < rhoe_tab.nx-11; i++){
130  for (ii = 0; ii < 20; ii++){ // Sub grid
131  T = rhoe_tab.x[i] + ii*rhoe_tab.dx[i]/20.0;
132  rhoe_ex = InternalEnergyFunc(v,T);
133  G = FundamentalDerivative(v,T);
134  Table2DInterpolate(&rhoe_tab, T, rho, &rhoe);
135  fprintf (fp, "%12.6e %12.6e %12.6e %12.6e\n",T,rhoe_ex, rhoe, G);
136  }
137 }
138 fclose(fp);
139 #endif
140 
141 
143  if (prank == 0) WriteBinaryTable2D("rhoe_tab.bin",&rhoe_tab);
144 }
tuple T
Definition: Sph_disk.py:33
double * y
array of y-values (not uniform)
Definition: structs.h:181
#define SPLINE2
Definition: pluto.h:220
double FundamentalDerivative(double *v, double T)
void print1(const char *fmt,...)
Definition: amrPluto.cpp:511
#define SPLINE1
Definition: pluto.h:219
int nx
Number of columns or points in the x direction.
Definition: structs.h:174
#define RHO
Definition: mod_defs.h:19
double rhoe
Definition: eos.h:107
double v[NVAR]
Definition: eos.h:106
double ** f
Definition: structs.h:186
#define TV_ENERGY_TABLE_NX
double ** a
Spline coefficient (x^3)
Definition: structs.h:188
double ** c
Spline coefficient (x)
Definition: structs.h:190
int prank
Processor rank.
Definition: globals.h:33
double ** b
Spline coefficient (x^2)
Definition: structs.h:189
void SplineCoeffs(double *x, double *f, double dfL, double dfR, int n, double *a, double *b, double *c, double *d)
Definition: math_interp.c:95
void WriteBinaryTable2D(char *fname, Table2D *tab)
Definition: math_table2D.c:528
void MonotoneSplineCoeffs(double *x, double *y, double *dydx, int n, double *a, double *b, double *c, double *d)
Definition: math_interp.c:13
int j
Definition: analysis.c:2
static Table2D rhoe_tab
A 2D table containing pre-computed values of internal energy stored at equally spaced node values of ...
int ny
Number of rows or points in the y direction.
Definition: structs.h:175
int Table2DInterpolate(Table2D *tab, double x, double y, double *f)
Definition: math_table2D.c:430
static double InternalEnergyDeriv(double rho, double T)
int interpolation
LINEAR/SPLINE1.
Definition: structs.h:177
#define ARRAY_1D(nx, type)
Definition: prototypes.h:170
void InitializeTable2D(Table2D *tab, double xmin, double xmax, int nx, double ymin, double ymax, int ny)
Definition: math_table2D.c:15
int i
Definition: analysis.c:2
FILE * fp
Definition: analysis.c:7
void FinalizeTable2D(Table2D *tab)
Definition: math_table2D.c:121
double ** d
Spline coefficiten (1)
Definition: structs.h:191
double * dx
grid spacing array in the x direction (not uniform)
Definition: structs.h:182
#define NVAR
Definition: pluto.h:609
#define TV_ENERGY_TABLE_NY
static Runtime q
double * x
array of x-values (not uniform)
Definition: structs.h:180
double InternalEnergyFunc(double *v, double T)
Definition: pvte_law.c:47

Here is the call graph for this function:

Here is the caller graph for this function:

double rhoeFunc ( double  T,
void *  par 
)
static

Return the nonlinear function f(T)=rhoe(T,rho)-rhoe used by the root finder to find temperature T.

Parameters
[in]TThe temperature in Kelvin
[in]parA pointer to a func_param structure containing quantities required for the computation.
Returns
f(T)

Definition at line 390 of file internal_energy.c.

400 {
401  double func, rhoe;
402  struct func_param *p = (struct func_param *) par;
403 
404  if (T < 0.0){
405  printf ("! rhoeFunc: T = %12.6e\n",T);
406  exit(1);
407  }
408  rhoe = InternalEnergyFunc(p->v, T);
409  func = rhoe - p->rhoe;
410  return func;
411 }
tuple T
Definition: Sph_disk.py:33
double rhoe
Definition: eos.h:107
double v[NVAR]
Definition: eos.h:106
double InternalEnergyFunc(double *v, double T)
Definition: pvte_law.c:47

Here is the call graph for this function:

Here is the caller graph for this function:

void SoundSpeed2 ( double **  v,
double *  cs2,
double *  h,
int  beg,
int  end,
int  pos,
Grid grid 
)

Define the square of the sound speed.

Parameters
[in]v1D array of primitive quantities
[out]cs21D array containing the square of the sound speed
[in]h1D array of enthalpy values
[in]beginitial index of computation
[in]endfinal index of computation
[in]posan integer specifying the spatial position inside the cell (only for spatially-dependent EOS)
[in]gridpointer to an array of Grid structures
Returns
This function has no return value.

Definition at line 414 of file internal_energy.c.

430 {
431  int i;
432 
433  for (i = beg; i <= end; i++){
434  cs2[i] = Gamma1(v[i])*v[i][PRS]/v[i][RHO];
435 /* cs2[i] = 1.6667*v[i][PRS]/v[i][RHO]; */
436  }
437 }
#define RHO
Definition: mod_defs.h:19
double v[NVAR]
Definition: eos.h:106
double Gamma1(double *v)
Definition: pvte_law.c:231
int i
Definition: analysis.c:2

Here is the call graph for this function:

Variable Documentation

Table2D rhoe_tab
static

A 2D table containing pre-computed values of internal energy stored at equally spaced node values of Log(T) and Log(rho) .

Definition at line 57 of file internal_energy.c.

Table2D Trhoe_tab
static

A 2D table containing pre-computed values of temperature by inverting e=e(T,rho) at equally spaced node values of Log(rhoe) and Log(rho).

This is used only in conjunction with a root finder to bracket the zero in a narrower interval.

Definition at line 171 of file internal_energy.c.