HARM
harm and utilities
 All Data Structures Files Functions Variables Typedefs Macros Pages
idealgaseos.c
Go to the documentation of this file.
1 
11 #define GAMMA (gamideal)
12 
13 // 1/\Gamma_r
14 #define GAMMAM1 (GAMMA-1.0)
15 #define IGAMMAR (GAMMAM1/GAMMA)
16 
17 
18 static FTYPE compute_inside_entropy_wmrho0_idealgas(FTYPE *EOSextra, FTYPE rho0, FTYPE wmrho0);
19 
20 
22 FTYPE pressure_rho0_u_idealgas(FTYPE *EOSextra, FTYPE rho0, FTYPE u)
23 {
24 #if(OLDCALC)
25  return(GAMMAM1*u) ;
26 #else
27  return((GAMMA - 1.)*u) ;
28 #endif
29 
30 }
31 
33 FTYPE u_rho0_p_idealgas(FTYPE *EOSextra, FTYPE rho0, FTYPE p)
34 {
35  return(p/GAMMAM1) ;
36 }
37 
38 // anywhere T or entropy are involved, really want number density, not mass density, so involves rho0/MUMEAN
39 
41 FTYPE u_rho0_T_idealgas(FTYPE *EOSextra, FTYPE rho0, FTYPE T)
42 {
43  return(((rho0/MUMEAN)*T)/GAMMAM1) ;
44 }
45 
47 FTYPE dpdu_rho0_u_idealgas(FTYPE *EOSextra, FTYPE rho0, FTYPE u)
48 {
49  return(GAMMAM1) ;
50 }
51 
53 FTYPE dpdrho0_rho0_u_idealgas(FTYPE *EOSextra, FTYPE rho0, FTYPE u)
54 {
55  return(0.0) ;
56 }
57 
59 FTYPE cs2_compute_idealgas(FTYPE *EOSextra, FTYPE rho0, FTYPE u)
60 {
61  FTYPE pressure;
62  FTYPE h;
63  FTYPE cs2;
64 
65  pressure = pressure_rho0_u_idealgas(EOSextra,rho0,u);
66  h=rho0+u+pressure+SMALL;
67 
68  cs2=GAMMA*pressure/h;
69  if(cs2<SMALL) cs2=SMALL;
70 
71  return(cs2);
72 
73 }
74 
83 FTYPE compute_entropy_idealgas(FTYPE *EOSextra, FTYPE rho0, FTYPE u)
84 {
85  FTYPE pressure_rho0_u_idealgas(FTYPE *EOSextra, FTYPE rho0, FTYPE u);
86  FTYPE pressure,indexn,entropy;
87 
88 
89  pressure=pressure_rho0_u_idealgas(EOSextra,rho0,u);
90  indexn=1.0/GAMMAM1;
91 
92  // Entropy will be wrong when rho0 or pressure are non-positive
93  if(rho0<SMALL && pressure<SMALL*1E-10){
94  rho0=SMALL;
95  pressure=SMALL*1E-10;
96  }
97  else if(rho0<SMALL){
98  rho0=SMALL;
99  }
100  else if(pressure<SMALL*1E-10){
101  pressure=SMALL*1E-10;
102  // entropy=-BIG; // so not -inf
103  // Too small entropy can cause precision/Newton inversion step issues, so implement floor on specific entropy
104  }
105 
106  // normal:
107  entropy=(rho0/MUMEAN)*log(pow(pressure,indexn)/pow(rho0/MUMEAN,indexn+1.0));
108 
109  // if p>>1 and rho0~0, then argument to log() could be out of range (i.e. inf).
110  // if(!isfinite(entropy)) entropy=0.0;
111 
112  // OPTMARK: Note that above and below ideal gas pow() shows up as expensive in pfmon (didn't appear in gprof!)
113  // 2nd most expensive function is these two pow() calls after get_state_uconucovonly()
114  // OPTMARK: log is bit less of a concern apparently, even though shows up in pfmon it's small %.
115 
116  return(entropy);
117 
118 }
119 
121 FTYPE compute_u_from_entropy_idealgas(FTYPE *EOSextra, FTYPE rho0, FTYPE entropy)
122 {
123  FTYPE rho,ie,pressure;
124  FTYPE indexn;
125  FTYPE u;
126 
127  indexn=1.0/GAMMAM1;
128 
129  // u will be wrong when density is non-positive
130  if(rho0<SMALL) rho0=SMALL;
131 
132  // entropy version of ie
133  u=pow(pow(rho0/MUMEAN,indexn+1.0)*exp(entropy/(rho0/MUMEAN)),1.0/indexn)/GAMMAM1;
134 
135 
136  return(u);
137 
138 }
139 
140 
141 
143 static FTYPE compute_inside_entropy_wmrho0_idealgas(FTYPE *EOSextra, FTYPE rho0, FTYPE wmrho0)
144 {
145  FTYPE pressure,indexn,insideentropy;
146  FTYPE pressure_wmrho0_idealgas(FTYPE *EOSextra, FTYPE rho0, FTYPE wmrho0);
147 
148 
149  pressure=pressure_wmrho0_idealgas(EOSextra,rho0,wmrho0);
150  indexn=1.0/GAMMAM1;
151 
152  // Don't limit rho0 and pressure since this is used for iterative scheme that requires to know if beyond valid domain or not. Nan will be terminated during inversion.
153  // if(rho0<SMALL) rho0=SMALL;
154  // if(pressure<SMALL) pressure=SMALL;
155 
156  insideentropy=pow(pressure,indexn)/pow(rho0/MUMEAN,indexn+1.0);
157 
158  return(insideentropy);
159 }
160 
161 
162 
165 FTYPE compute_dSdrho_idealgas(FTYPE *EOSextra, FTYPE rho0, FTYPE u)
166 {
167  FTYPE indexn;
168  FTYPE entropy;
169  FTYPE dSdrho;
170  FTYPE compute_entropy_idealgas(FTYPE *EOSextra, FTYPE rho0, FTYPE u);
171 
172  entropy=compute_entropy_idealgas(EOSextra,rho0,u);
173 
174  // ideal gas
175  indexn=1.0/GAMMAM1;
176 
177  dSdrho=(entropy/(rho0/MUMEAN)-(indexn+1.0))/MUMEAN;
178 
179  return(dSdrho);
180 
181 }
182 
183 
186 FTYPE compute_dSdu_idealgas(FTYPE *EOSextra, FTYPE rho0, FTYPE u)
187 {
188  FTYPE indexn;
189  FTYPE dSdu;
190 
191  // ideal gas
192  indexn=1.0/GAMMAM1;
193 
194  dSdu=indexn*(rho0/MUMEAN)/u;
195 
196  return(dSdu);
197 
198 }
199 
204 {
205  FTYPE insideentropy,entropy;
206 
207  insideentropy=compute_inside_entropy_wmrho0_idealgas(EOSextra, rho0, wmrho0);
208 
209  entropy=(rho0/MUMEAN)*log(insideentropy);
210 
211  // if(!isfinite(entropy)) entropy=0.0;
212 
213 
214  return(entropy);
215 
216 }
217 
221 FTYPE compute_specificentropy_wmrho0_idealgas(FTYPE *EOSextra, FTYPE rho0, FTYPE wmrho0)
222 {
223  FTYPE insideentropy,specificentropy;
224 
225  insideentropy=compute_inside_entropy_wmrho0_idealgas(EOSextra, rho0, wmrho0);
226 
227  specificentropy=log(insideentropy)/MUMEAN; // because Sspecific = S/rho alone by choice/definition.
228 
229  // if(!isfinite(specificentropy)) specificentropy=0.0;
230 
231 
232  return(specificentropy);
233 
234 }
235 
240 {
241  FTYPE dSdrho;
242  FTYPE insideentropy;
243 
244 
245  insideentropy=compute_inside_entropy_wmrho0_idealgas(EOSextra, rho0, wmrho0);
246 
247  dSdrho=(GAMMA/(1.0-GAMMA) + log(insideentropy))/MUMEAN;
248 
249  // if(!isfinite(dSdrho)) dSdrho=0.0;
250 
251  // Note that it makes no sense to speak of entropy changes with isothermal (GAMMA=1.0) gas since in the limit GAMMA->1, dSdrho->-\infty
252 
253  return(dSdrho);
254 
255 }
256 
258 FTYPE compute_dspecificSdrho_wmrho0_idealgas(FTYPE *EOSextra, FTYPE rho0, FTYPE wmrho0)
259 {
260  FTYPE dSdrho;
261 
262  // Don't limit rho0 and pressure since this is used for iterative scheme that requires to know if beyond valid domain or not. Nan will be terminated during inversion.
263  // if(rho0<SMALL) rho0=SMALL;
264 
265  dSdrho=GAMMA/((1.0-GAMMA)*(rho0*MUMEAN)); // yes, really *MUMEAN because we define specific as S/rho and not S/(mu*rho)
266 
267  // Note that it makes no sense to speak of entropy changes with isothermal (GAMMA=1.0) gas since in the limit GAMMA->1, dSdrho->-\infty
268 
269  return(dSdrho);
270 
271 }
272 
273 
276 FTYPE compute_dSdwmrho0_wmrho0_idealgas_unused(FTYPE *EOSextra, FTYPE rho0, FTYPE wmrho0)
277 {
278  FTYPE dSdchi;
279 
280  dSdchi = (rho0/MUMEAN)/(GAMMAM1*wmrho0);
281 
282  // Again, GAMMA->1 means dSdchi->\infty unless \chi->0 or rho0->0
283 
284  return(dSdchi);
285 
286 }
287 
290 FTYPE compute_dspecificSdwmrho0_wmrho0_idealgas(FTYPE *EOSextra, FTYPE rho0, FTYPE wmrho0)
291 {
292  FTYPE dSdchi;
293 
294  dSdchi = 1.0/(GAMMAM1*wmrho0)/MUMEAN;
295 
296  // Again, GAMMA->1 means dSdchi->\infty unless \chi->0 or rho0->0
297 
298  return(dSdchi);
299 
300 }
301 
302 
303 
305 FTYPE pressure_wmrho0_idealgas(FTYPE *EOSextra, FTYPE rho0, FTYPE wmrho0)
306 {
307  return(IGAMMAR*wmrho0) ;
308 }
309 
311 FTYPE compute_idwmrho0dp_idealgas(FTYPE *EOSextra, FTYPE rho0, FTYPE wmrho0)
312 {
313  return(GAMMAM1/GAMMA);
314 }
315 
316 
318 FTYPE compute_idrho0dp_idealgas(FTYPE *EOSextra, FTYPE rho0, FTYPE wmrho0)
319 {
320  return(0.0);
321 }
322 
323 
325 FTYPE compute_qdot_idealgas(FTYPE *EOSextra, FTYPE rho0, FTYPE u)
326 {
327  return(0.0);
328 }
329 
330 int compute_sources_EOS_idealgas(FTYPE *EOSextra, FTYPE *pr, struct of_geom *geom, struct of_state *q, FTYPE *Ui, FTYPE *dUother, FTYPE(*dUcomp)[NPR])
331 {
332  int sc,pl,pliter;
333 
334  SCPHYSICSLOOP(sc) PLOOP(pliter,pl) dUcomp[sc][pl]=0.0;
335  return(0);
336 }
337 
338 
339 void compute_allextras_idealgas(int justnum, FTYPE *EOSextra, FTYPE rho0, FTYPE u, int *numextrasreturn, FTYPE *extras)
340 {
341  int i;
342 
343  if(justnum==0){
344 
345  // set rest to 0
346  for(i=0;i<MAXNUMEXTRAS;i++){
347  extras[i] = 0.0;
348  }
349  }
350 
351  *numextrasreturn=0;
352 }
353 
354 int get_extrasprocessed_idealgas(int doall, FTYPE *EOSextra, FTYPE *pr, FTYPE *extras, FTYPE *processed)
355 {
356  int pi;
357  int numextrasreturn;
358  FTYPE rho0,u;
359  rho0=pr[RHO];
360  u=pr[UU];
361  compute_allextras_idealgas(0, EOSextra, rho0, u, &numextrasreturn, extras);
362  for(pi=0;pi<MAXPROCESSEDEXTRAS;pi++){
363  processed[pi] = 0.0;
364  }
365  return(0);
366 }
367 
368 
369 
371 FTYPE compute_temp_idealgas(FTYPE *EOSextra, FTYPE rho0, FTYPE u)
372 {
373  FTYPE temp;
374 
375  temp = GAMMAM1*u/(SMALL+fabs(rho0/MUMEAN));
376  // can't let temp go negative because have T^2 or T^4 terms in lambda or other functions
377  if(temp<SMALL) temp=SMALL;
378 
379  return(temp);
380 
381 }
382 
383 void compute_EOS_parms_idealgas(FTYPE (*EOSextra)[NSTORE2][NSTORE3][NUMEOSGLOBALS], FTYPE (*prim)[NSTORE2][NSTORE3][NPR])
384 {
385  return; // do nothing
386 }
387 
388 
389 
390 void store_EOS_parms_idealgas(int numparms, FTYPE *EOSextra, FTYPE *parlist)
391 {
392  return; // do nothing
393 }
394 
395 
396 void get_EOS_parms_idealgas(int*numparms, FTYPE *EOSextra, FTYPE *parlist)
397 {
398 
399  *numparms=0;
400  return; // do nothing
401 }
402 
403 void fix_primitive_eos_scalars_idealgas(FTYPE *EOSextra, FTYPE *pr)
404 {
405  return; // do nothing
406 }
407 
408 
411 void getall_forinversion_idealgas(int eomtype, int whichd, FTYPE *EOSextra, FTYPE quant1, FTYPE quant2, FTYPE *fun, FTYPE *dfunofrho, FTYPE *dfunofu)
412 {
413 
414  if(eomtype==EOMGRMHD){
415  if(whichd==CHIDIFF){
416  // PofRHOCHI
417  *fun=pressure_wmrho0_idealgas(EOSextra, quant1, quant2);
418  *dfunofrho=compute_idrho0dp_idealgas(EOSextra, quant1, quant2);
419  *dfunofu=compute_idwmrho0dp_idealgas(EOSextra, quant1, quant2);
420  }
421  else if(whichd==UTOTDIFF){
422  *fun=pressure_rho0_u_idealgas(EOSextra, quant1, quant2);
423  *dfunofrho=dpdrho0_rho0_u_idealgas(EOSextra, quant1, quant2);
424  *dfunofu=dpdu_rho0_u_idealgas(EOSextra, quant1, quant2);
425  }
426  }
427  else if(eomtype==EOMENTROPYGRMHD){
428  // NOTE: for \chi version it's specific entropy and for u version it's entropy density
429  if(whichd==CHIDIFF){
430  *fun=compute_specificentropy_wmrho0_idealgas(EOSextra, quant1, quant2);
431  *dfunofrho=compute_dspecificSdrho_wmrho0_idealgas(EOSextra, quant1, quant2);
432  *dfunofu=compute_dspecificSdwmrho0_wmrho0_idealgas(EOSextra, quant1, quant2);
433  }
434  else if(whichd==UTOTDIFF){
435  *fun=compute_entropy_idealgas(EOSextra, quant1, quant2);
436  *dfunofrho=compute_dSdrho_idealgas(EOSextra, quant1, quant2);
437  *dfunofu=compute_dSdu_idealgas(EOSextra, quant1, quant2);
438  }
439  }
440  else if(eomtype==EOMCOLDGRMHD || eomtype==EOMFFDE || eomtype==EOMFFDE2){
441  *fun=*dfunofrho=*dfunofu=0.0;
442  }
443 
444  return; // done!
445 }
446 
447 #undef GAMMA
448 #undef GAMMAM1
449 #undef IGAMMAR