LORENE
eos_tabul.C
1/*
2 * Methods of class Eos_tabul
3 *
4 * (see file eos.h for documentation).
5 *
6 */
7
8/*
9 * Copyright (c) 2000-2001 Eric Gourgoulhon
10 *
11 * This file is part of LORENE.
12 *
13 * LORENE is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * LORENE is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with LORENE; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 *
27 */
28
29
30
31
32/*
33 * $Id: eos_tabul.C,v 1.25 2022/03/22 13:36:00 j_novak Exp $
34 * $Log: eos_tabul.C,v $
35 * Revision 1.25 2022/03/22 13:36:00 j_novak
36 * Added declaration of compute_derivative to utilitaires.h
37 *
38 * Revision 1.24 2022/03/22 13:18:47 g_servignat
39 * Corrected treatment for h<hmin
40 *
41 * Revision 1.23 2022/03/10 16:38:39 j_novak
42 * log(cs^2) is tabulated instead of cs^2.
43 *
44 * Revision 1.22 2021/05/31 11:31:23 g_servignat
45 * Added csound_square_ent routine to calculate the sound speed from enthalpy to Eos_consistent and corrected error outputs
46 *
47 * Revision 1.21 2021/05/14 15:39:22 g_servignat
48 * Added sound speed computation from enthalpy to Eos class and tabulated+polytropic derived classes
49 *
50 * Revision 1.20 2019/12/02 14:51:36 j_novak
51 * Moved piecewise parabolic computation of dpdnb to a separate function.
52 *
53 * Revision 1.19 2019/03/28 13:41:02 j_novak
54 * Improved managed of saved EoS (functions sauve and constructor form FILE*)
55 *
56 * Revision 1.18 2017/12/15 15:36:38 j_novak
57 * Improvement of the MEos class. Implementation of automatic offset computation accross different EoSs/domains.
58 *
59 * Revision 1.17 2016/12/05 16:17:52 j_novak
60 * Suppression of some global variables (file names, loch, ...) to prevent redefinitions
61 *
62 * Revision 1.16 2015/08/04 14:41:29 j_novak
63 * Back to previous version for Eos_CompOSE. Enthalpy-consistent EoS can be accessed using Eos_consistent class (derived from Eos_CompOSE).
64 *
65 * Revision 1.15 2015/01/27 14:22:38 j_novak
66 * New methods in Eos_tabul to correct for EoS themro consistency (optional).
67 *
68 * Revision 1.14 2014/10/13 08:52:54 j_novak
69 * Lorene classes and functions now belong to the namespace Lorene.
70 *
71 * Revision 1.13 2014/06/30 16:13:18 j_novak
72 * New methods for reading directly from CompOSE files.
73 *
74 * Revision 1.12 2014/03/06 15:53:35 j_novak
75 * Eos_compstar is now Eos_compOSE. Eos_tabul uses strings and contains informations about authors.
76 *
77 * Revision 1.11 2012/11/09 10:32:44 m_bejger
78 * Implementing der_ener_ent_p
79 *
80 * Revision 1.10 2010/02/16 11:14:50 j_novak
81 * More verbose opeining of the file.
82 *
83 * Revision 1.9 2010/02/02 13:22:16 j_novak
84 * New class Eos_Compstar.
85 *
86 * Revision 1.8 2004/03/25 10:29:02 j_novak
87 * All LORENE's units are now defined in the namespace Unites (in file unites.h).
88 *
89 * Revision 1.7 2003/11/25 13:42:50 m_bejger
90 * read_table written in more ordered way
91 *
92 * Revision 1.6 2003/11/21 16:11:16 m_bejger
93 * added the computation dlnp/dlnn_b, dlnn/dlnH
94 *
95 * Revision 1.5 2003/05/30 07:50:06 e_gourgoulhon
96 *
97 * Reformulate the computation of der_nbar_ent
98 * Added computation of der_press_ent_p.
99 *
100 * Revision 1.4 2003/05/15 09:42:47 e_gourgoulhon
101 *
102 * Now computes d ln / dln H.
103 *
104 * Revision 1.3 2002/10/16 14:36:35 j_novak
105 * Reorganization of #include instructions of standard C++, in order to
106 * use experimental version 3 of gcc.
107 *
108 * Revision 1.2 2002/04/09 14:32:15 e_gourgoulhon
109 * 1/ Added extra parameters in EOS computational functions (argument par)
110 * 2/ New class MEos for multi-domain EOS
111 *
112 * Revision 1.1.1.1 2001/11/20 15:19:27 e_gourgoulhon
113 * LORENE
114 *
115 * Revision 2.3 2001/09/13 13:35:49 eric
116 * Suppression des affichages dans read_table().
117 *
118 * Revision 2.2 2001/02/07 09:48:05 eric
119 * Suppression de la fonction derent_ent_p.
120 * Ajout des fonctions donnant les derivees de l'EOS:
121 * der_nbar_ent_p
122 * der_ener_ent_p
123 * der_press_ent_p
124 *
125 * Revision 2.1 2000/11/23 00:10:20 eric
126 * Enthalpie minimale fixee a 1e-14.
127 *
128 * Revision 2.0 2000/11/22 19:31:30 eric
129 * *** empty log message ***
130 *
131 *
132 * $Header: /cvsroot/Lorene/C++/Source/Eos/eos_tabul.C,v 1.25 2022/03/22 13:36:00 j_novak Exp $
133 *
134 */
135
136// headers C
137#include <cstdlib>
138#include <cstring>
139#include <cmath>
140
141// Headers Lorene
142#include "eos.h"
143#include "tbl.h"
144#include "utilitaires.h"
145#include "unites.h"
146
147
148namespace Lorene {
149 void interpol_herm(const Tbl& , const Tbl&, const Tbl&, double, int&,
150 double&, double& ) ;
151
152 void interpol_linear(const Tbl&, const Tbl&, double, int&, double&) ;
153
154 void interpol_quad(const Tbl&, const Tbl&, double, int&, double&) ;
155
156
157
158 //----------------------------//
159 // Constructors //
160 //----------------------------//
161
162// Standard constructor
163// --------------------
164Eos_tabul::Eos_tabul(const char* name_i, const char* table,
165 const char* path) : Eos(name_i)
166{
167 tablename = path ;
168 tablename += "/" ;
169 tablename += table ;
170
171 read_table() ;
172}
173
174// Standard constructor with full filename
175// ---------------------------------------
176 Eos_tabul::Eos_tabul(const char* name_i, const char* file_name)
177 : Eos(name_i) {
178
179 tablename = file_name ;
180
181 read_table() ;
182
183}
184
185
186// Constructor from binary file
187// ----------------------------
188 Eos_tabul::Eos_tabul(FILE* fich) : Eos(fich) {
189
190 char tmp_string[160] ;
191 fread(tmp_string, sizeof(char), 160, fich) ;
192 tablename = tmp_string ;
193
194 read_table() ;
195
196}
197
198
199
200// Constructor from a formatted file
201// ---------------------------------
202 Eos_tabul::Eos_tabul(ifstream& fich, const char* table) :
203 Eos(fich) {
204
205 fich >> tablename ;
206 tablename += "/" ;
207 tablename += table ;
208
209 read_table() ;
210
211}
212
213 Eos_tabul::Eos_tabul(ifstream& fich) : Eos(fich)
214{
215 fich >> tablename ;
216
217 read_table() ;
218}
219
220// Standard constructor with a name
221// ---------------------------------
222 Eos_tabul::Eos_tabul(const char* name_i) : Eos(name_i),
223 logh(0x0), logp(0x0), dlpsdlh(0x0),
224 lognb(0x0), dlpsdlnb(0x0), log_cs2(0x0)
225{}
226
227
228 //--------------//
229 // Destructor //
230 //--------------//
231
233 if (logh != 0x0) delete logh ;
234 if (logp != 0x0) delete logp ;
235 if (dlpsdlh != 0x0) delete dlpsdlh ;
236 if (lognb != 0x0) delete lognb ;
237 if (dlpsdlnb != 0x0) delete dlpsdlnb ;
238 if (log_cs2 != 0x0) delete log_cs2 ;
239}
240
241 //------------//
242 // Outputs //
243 //------------//
244
245void Eos_tabul::sauve(FILE* fich) const {
246
247 Eos::sauve(fich) ;
248
249 char tmp_string[160] ;
250 strcpy(tmp_string, tablename.c_str()) ;
251 fwrite(tmp_string, sizeof(char), 160, fich) ;
252}
253
254 //------------------------//
255 // Reading of the table //
256 //------------------------//
257
259
260 using namespace Unites ;
261
262 ifstream is_meos("meos_is_being_built.d") ;
263
264 ifstream fich(tablename.data()) ;
265
266 if (!fich) {
267 cerr << "Eos_tabul::read_table(): " << endl ;
268 cerr << "Problem in opening the EOS file!" << endl ;
269 cerr << "While trying to open " << tablename << endl ;
270 cerr << "Aborting..." << endl ;
271 abort() ;
272 }
273
274 fich.ignore(1000, '\n') ; // Jump over the first header
275 fich.ignore(1) ;
276 getline(fich, authors, '\n') ;
277 for (int i=0; i<3; i++) { // jump over the file
278 fich.ignore(1000, '\n') ; // header
279 } //
280
281 int nbp ;
282 fich >> nbp ; fich.ignore(1000, '\n') ; // number of data
283 if (nbp<=0) {
284 cerr << "Eos_tabul::read_table(): " << endl ;
285 cerr << "Wrong value for the number of lines!" << endl ;
286 cerr << "nbp = " << nbp << endl ;
287 cerr << "Aborting..." << endl ;
288 abort() ;
289 }
290
291 for (int i=0; i<3; i++) { // jump over the table
292 fich.ignore(1000, '\n') ; // description
293 }
294
295 press = new double[nbp] ;
296 nb = new double[nbp] ;
297 ro = new double[nbp] ;
298
299 Tbl press_tbl(nbp) ; press_tbl.set_etat_qcq() ;
300 Tbl nb_tbl(nbp) ; nb_tbl.set_etat_qcq() ;
301 Tbl ro_tbl(nbp) ; ro_tbl.set_etat_qcq() ;
302
303 logh = new Tbl(nbp) ;
304 logp = new Tbl(nbp) ;
305 dlpsdlh = new Tbl(nbp) ;
306 lognb = new Tbl(nbp) ;
307 dlpsdlnb = new Tbl(nbp) ;
308
309 logh->set_etat_qcq() ;
310 logp->set_etat_qcq() ;
311 dlpsdlh->set_etat_qcq() ;
312 lognb->set_etat_qcq() ;
313 dlpsdlnb->set_etat_qcq() ;
314
315 double rhonuc_cgs = rhonuc_si * 1e-3 ;
316 double c2_cgs = c_si * c_si * 1e4 ;
317
318 int no ;
319 double nb_fm3, rho_cgs, p_cgs ;
320
321 for (int i=0; i<nbp; i++) {
322
323 fich >> no ;
324 fich >> nb_fm3 ;
325 fich >> rho_cgs ;
326 fich >> p_cgs ; fich.ignore(1000,'\n') ;
327 if ( (nb_fm3<0) || (rho_cgs<0) || (p_cgs < 0) ){
328 cout << "Eos_tabul::read_table(): " << endl ;
329 cout << "Negative value in table!" << endl ;
330 cout << "nb = " << nb_fm3 << ", rho = " << rho_cgs <<
331 ", p = " << p_cgs << endl ;
332 cout << "Aborting..." << endl ;
333 abort() ;
334 }
335
336 press[i] = p_cgs / c2_cgs ;
337 nb[i] = nb_fm3 ;
338 ro[i] = rho_cgs ;
339
340 press_tbl.set(i) = press[i] ;
341 nb_tbl.set(i) = nb[i] ;
342 ro_tbl.set(i) = ro[i] ;
343 }
344
345 double ww = 0. ;
346 bool store_offset = false ;
347 bool compute_offset = true ;
348 if (is_meos) {
349 string temp ;
350 string ok("ok") ;
351 is_meos >> temp ;
352 if (temp.find(ok) != string::npos) {
353 is_meos >> ww ;
354 compute_offset = false ;
355 }
356 else {
357 is_meos.close() ;
358 store_offset = true ;
359 }
360 }
361
362 for (int i=0; i<nbp; i++) {
363 double h = log( (ro[i] + press[i]) /
364 (10 * nb[i] * rhonuc_cgs) ) ;
365
366 if ((i==0) && compute_offset) { ww = h ; }
367 h = h - ww + 1.e-14 ;
368
369 logh->set(i) = log10( h ) ;
370 logp->set(i) = log10( press[i] / rhonuc_cgs ) ;
371 dlpsdlh->set(i) = h * (ro[i] + press[i]) / press[i] ;
372 lognb->set(i) = log10(nb[i]) ;
373 }
374
375 if (store_offset == true) {
376 ofstream write_meos("meos_is_being_built.d", ios_base::app) ;
377 write_meos << "ok" << endl ;
378 write_meos << setprecision(16) << ww << endl ;
379 }
380
381 // Computation of dpdnb
382 //---------------------
383 Tbl logn0 = *lognb * log(10.) ;
384 Tbl logp0 = ((*logp) + log10(rhonuc_cgs)) * log(10.) ;
385 compute_derivative(logn0, logp0, *dlpsdlnb) ;
386
387 // Computation of the sound speed
388 //-------------------------------
389 Tbl tmp(nbp) ; tmp.set_etat_qcq() ;
390 compute_derivative(ro_tbl,press_tbl,tmp) ; // tmp = c_s^2 = dp/de
391 for (int i=0; i<nbp; i++) {
392 if (tmp(i) < 0.) {
393 tmp.set(i) = - tmp(i) ;
394 }
395 }
396 log_cs2 = new Tbl(log10(tmp)) ;
397
398 hmin = pow( double(10), (*logh)(0) ) ;
399 hmax = pow( double(10), (*logh)(nbp-1) ) ;
400 cout << "hmin, hmax : " << hmin << " " << hmax << endl ;
401
402 fich.close();
403
404 delete [] press ;
405 delete [] nb ;
406 delete [] ro ;
407
408
409}
410
411
412 //------------------------------//
413 // Computational routines //
414 //------------------------------//
415
416// Baryon density from enthalpy
417//------------------------------
418
419double Eos_tabul::nbar_ent_p(double ent, const Param* ) const {
420
421 static int i_near = logh->get_taille() / 2 ;
422
423 if ( ent > hmin ) {
424 if (ent > hmax) {
425 cout << "Eos_tabul::nbar_ent_p : ent > hmax !" << endl ;
426 abort() ;
427 }
428 double logh0 = log10( ent ) ;
429 double logp0 ;
430 double dlpsdlh0 ;
431 interpol_herm(*logh, *logp, *dlpsdlh, logh0, i_near, logp0,
432 dlpsdlh0) ;
433
434 double pp = pow(double(10), logp0) ;
435
436 double resu = pp / ent * dlpsdlh0 * exp(-ent) ;
437 return resu ;
438 }
439 else{
440 return 0 ;
441 }
442}
443
444// Energy density from enthalpy
445//------------------------------
446
447double Eos_tabul::ener_ent_p(double ent, const Param* ) const {
448
449 static int i_near = logh->get_taille() / 2 ;
450
451 if ( ent > hmin ) {
452 if (ent > hmax) {
453 cout << "Eos_tabul::ener_ent_p : ent > hmax !" << endl ;
454 abort() ;
455 }
456 double logh0 = log10( ent ) ;
457 double logp0 ;
458 double dlpsdlh0 ;
459 interpol_herm(*logh, *logp, *dlpsdlh, logh0, i_near, logp0,
460 dlpsdlh0) ;
461
462 double pp = pow(double(10), logp0) ;
463
464 double resu = pp / ent * dlpsdlh0 - pp ;
465 return resu ;
466 }
467 else{
468 return 0 ;
469 }
470}
471
472// Pressure from enthalpy
473//------------------------
474
475double Eos_tabul::press_ent_p(double ent, const Param* ) const {
476
477 static int i_near = logh->get_taille() / 2 ;
478
479 if ( ent > hmin ) {
480 if (ent > hmax) {
481 cout << "Eos_tabul::press_ent_p : ent > hmax !" << endl ;
482 abort() ;
483 }
484
485 double logh0 = log10( ent ) ;
486 double logp0 ;
487 double dlpsdlh0 ;
488 interpol_herm(*logh, *logp, *dlpsdlh, logh0, i_near, logp0,
489 dlpsdlh0) ;
490 return pow(double(10), logp0) ;
491 }
492 else{
493 return 0 ;
494 }
495}
496
497// dln(n)/ln(H) from enthalpy
498//---------------------------
499
500double Eos_tabul::der_nbar_ent_p(double ent, const Param* ) const {
501
502 if ( ent > hmin ) {
503 if (ent > hmax) {
504 cout << "Eos_tabul::der_nbar_ent_p : ent > hmax !" << endl ;
505 abort() ;
506 }
507
508 double zeta = der_press_ent_p(ent) / der_press_nbar_p(ent) ;
509
510 return zeta ;
511
512 }
513 else
514
515 return 1./(der_press_nbar_p(hmin)-1.) ; // to ensure continuity
516
517}
518
519
520// dln(e)/ln(H) from enthalpy
521//---------------------------
522
523double Eos_tabul::der_ener_ent_p(double ent, const Param* ) const {
524
525 if ( ent > hmin ) {
526
527 if (ent > hmax) {
528 cout << "Eos_tabul::der_ener_ent_p : ent > hmax !" << endl ;
529 abort() ;
530 }
531
532 return ( der_nbar_ent_p(ent)
533 *( double(1.) + press_ent_p(ent)/ener_ent_p(ent) )) ;
534
535 } else return der_nbar_ent_p(hmin) ;
536
537}
538
539
540// dln(p)/ln(H) from enthalpy
541//---------------------------
542
543double Eos_tabul::der_press_ent_p(double ent, const Param* ) const {
544
545 static int i_near = logh->get_taille() / 2 ;
546
547 if ( ent > hmin ) {
548 if (ent > hmax) {
549 cout << "Eos_tabul::der_press_ent_p : ent > hmax !" << endl ;
550 abort() ;
551 }
552
553 double logh0 = log10( ent ) ;
554 double logp0 ;
555 double dlpsdlh0 ;
556 interpol_herm(*logh, *logp, *dlpsdlh, logh0, i_near, logp0,
557 dlpsdlh0) ;
558
559 return dlpsdlh0 ;
560
561 }
562 else{
563
564 return 0 ;
565 // return der_press_ent_p(hmin) ; // to ensure continuity
566 }
567}
568
569
570// dln(p)/dln(n) from enthalpy
571//---------------------------
572
573double Eos_tabul::der_press_nbar_p(double ent, const Param*) const {
574
575 static int i_near = logh->get_taille() / 2 ;
576
577 if ( ent > hmin ) {
578 if (ent > hmax) {
579 cout << "Eos_tabul::der_press_nbar_p : ent > hmax !" << endl ;
580 abort() ;
581 }
582
583 double logh0 = log10( ent ) ;
584 double dlpsdlnb0 ;
585
586 interpol_linear(*logh, *dlpsdlnb, logh0, i_near, dlpsdlnb0) ;
587
588 return dlpsdlnb0 ;
589
590 }
591 else{
592
593 return (*dlpsdlnb)(0) ;
594 // return der_press_nbar_p(hmin) ; // to ensure continuity
595
596 }
597}
598
599double Eos_tabul::csound_square_ent_p(double ent, const Param*) const {
600 static int i_near = lognb->get_taille() / 2 ;
601
602 if ( ent > hmin ) {
603 if (ent > hmax) {
604 cout << "Eos_tabul::csound_square_ent_p : ent>hmax !" << endl ;
605 abort() ;
606 }
607 double log_ent0 = log10( ent ) ;
608 double log_csound0 ;
609
610 interpol_linear(*logh, *log_cs2, log_ent0, i_near, log_csound0) ;
611
612 return pow(10., log_csound0) ;
613 }
614 else
615 {
616 return pow(10., (*log_cs2)(0)) ;
617 }
618}
619}
virtual double press_ent_p(double ent, const Param *par=0x0) const
Computes the pressure from the log-enthalpy.
Definition eos_tabul.C:475
virtual double ener_ent_p(double ent, const Param *par=0x0) const
Computes the total energy density from the log-enthalpy.
Definition eos_tabul.C:447
virtual double der_press_ent_p(double ent, const Param *par=0x0) const
Computes the logarithmic derivative from the log-enthalpy.
Definition eos_tabul.C:543
virtual void read_table()
Reads the file containing the table and initializes in the arrays logh , logp and dlpsdlh .
Definition eos_tabul.C:258
virtual ~Eos_tabul()
Destructor.
Definition eos_tabul.C:232
Tbl * lognb
Table of .
Definition eos_tabul.h:212
Eos_tabul(const char *name_i, const char *table, const char *path)
Standard constructor.
Definition eos_tabul.C:164
Tbl * dlpsdlh
Table of .
Definition eos_tabul.h:209
Tbl * dlpsdlnb
Table of .
Definition eos_tabul.h:215
virtual double nbar_ent_p(double ent, const Param *par=0x0) const
Computes the baryon density from the log-enthalpy.
Definition eos_tabul.C:419
virtual double der_nbar_ent_p(double ent, const Param *par=0x0) const
Computes the logarithmic derivative from the log-enthalpy.
Definition eos_tabul.C:500
virtual double der_ener_ent_p(double ent, const Param *par=0x0) const
Computes the logarithmic derivative from the log-enthalpy.
Definition eos_tabul.C:523
virtual void sauve(FILE *) const
Save in a file.
Definition eos_tabul.C:245
virtual double csound_square_ent_p(double, const Param *) const
Computes the sound speed squared from the enthapy with extra parameters (virtual function implemente...
Definition eos_tabul.C:599
Tbl * logh
Table of .
Definition eos_tabul.h:203
Tbl * log_cs2
Table of .
Definition eos_tabul.h:218
string tablename
Name of the file containing the tabulated data.
Definition eos_tabul.h:192
double hmin
Lower boundary of the enthalpy interval.
Definition eos_tabul.h:197
Tbl * logp
Table of .
Definition eos_tabul.h:206
virtual double der_press_nbar_p(double ent, const Param *par=0x0) const
Computes the logarithmic derivative from the log-enthalpy.
Definition eos_tabul.C:573
string authors
Authors - reference for the table.
Definition eos_tabul.h:194
double hmax
Upper boundary of the enthalpy interval.
Definition eos_tabul.h:200
virtual void sauve(FILE *) const
Save in a file.
Definition eos.C:189
Eos()
Standard constructor.
Definition eos.C:118
Parameter storage.
Definition param.h:125
Basic array class.
Definition tbl.h:161
void set_etat_qcq()
Sets the logical state to ETATQCQ (ordinary state).
Definition tbl.C:364
double & set(int i)
Read/write of a particular element (index i) (1D case).
Definition tbl.h:281
Cmp log10(const Cmp &)
Basis 10 logarithm.
Definition cmp_math.C:325
Cmp exp(const Cmp &)
Exponential.
Definition cmp_math.C:273
Cmp pow(const Cmp &, int)
Power .
Definition cmp_math.C:351
Cmp log(const Cmp &)
Neperian logarithm.
Definition cmp_math.C:299
void compute_derivative(const Tbl &xx, const Tbl &ff, Tbl &dfdx)
Derives a function defined on an unequally-spaced grid, approximating it by piecewise parabolae.
Definition misc.C:64
Lorene prototypes.
Definition app_hor.h:67
Standard units of space, time and mass.