LORENE
dyneos_tab.C
1/*
2 * Methods of class Dyn_eos_tab
3 *
4 * (see file dyneos.h for documentation).
5 *
6 */
7
8/*
9 * Copyright (c) 2019 Jerome Novak
10 * (c) 2000 Eric Gourgoulhon for Eos classes
11 *
12 * This file is part of LORENE.
13 *
14 * LORENE is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * LORENE is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with LORENE; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 *
28 */
29
30
31
32/*
33 * $Id: dyneos_tab.C,v 1.4 2022/12/15 14:38:27 j_novak Exp $
34 * $Log: dyneos_tab.C,v $
35 * Revision 1.4 2022/12/15 14:38:27 j_novak
36 * Change in the call to fread, to avoid compilation warnings
37 *
38 * Revision 1.3 2022/03/22 13:36:00 j_novak
39 * Added declaration of compute_derivative to utilitaires.h
40 *
41 * Revision 1.2 2020/12/17 17:00:27 j_novak
42 * Output of sound speed squared, instead of sound speed.
43 *
44 * Revision 1.1 2019/12/06 14:30:50 j_novak
45 * New classes Dyn_eos... for cold Eos's with baryon density as input.
46 *
47 *
48 *
49 * $Header: /cvsroot/Lorene/C++/Source/Eos/dyneos_tab.C,v 1.4 2022/12/15 14:38:27 j_novak Exp $
50 *
51 */
52
53// Headers Lorene
54#include "dyneos.h"
55#include "tbl.h"
56#include "utilitaires.h"
57#include "unites.h"
58
59
60namespace Lorene {
61 void interpol_herm(const Tbl& , const Tbl&, const Tbl&, double, int&,
62 double&, double& ) ;
63
64 void interpol_linear(const Tbl&, const Tbl&, double, int&, double&) ;
65
66
67
68 //----------------------------//
69 // Constructors //
70 //----------------------------//
71
72// Standard constructor
73// --------------------
74 Dyn_eos_tab::Dyn_eos_tab(const string& name_i, const string& tablename_i,
75 bool compose) : Dyn_eos(name_i), tablename(tablename_i),
76 compose_format(compose), lognb(0x0),
77 loge(0x0), dlesdlnb(0x0), c_sound2(0x0)
78 {
81 else
83 }
84
85// Default constructor (protected, to be used by derived classes)
86// ---------------------------------------------------------------
90
91// Constructor from binary file
92// ----------------------------
93 Dyn_eos_tab::Dyn_eos_tab(FILE* fich) : Dyn_eos(fich), lognb(0x0),
94 loge(0x0), dlesdlnb(0x0), c_sound2(0x0)
95 {
96 const int nc = 160 ;
97 char tmp_string[nc] ;
98 size_t ret = fread(tmp_string, sizeof(char), nc, fich) ;
99 if (int(ret) == nc)
100 tablename = tmp_string ;
101 else {
102 cerr << "Dyn_eos_tab: constructor from a binary file:" << endl ;
103 cerr << "Problems in reading the table name." << endl ;
104 cerr << "Aborting..." << endl ;
105 abort() ;
106 }
107 int comp ;
108 fread_be(&comp, sizeof(int), 1, fich) ;
109 compose_format = comp ;
110
111 if (compose_format)
113 else
115 }
116
117
118// Constructor from a formatted file
119// ---------------------------------
120 Dyn_eos_tab::Dyn_eos_tab(ifstream& fich) : Dyn_eos(fich), lognb(0x0),
121 loge(0x0), dlesdlnb(0x0), c_sound2(0x0)
122 {
123 fich.seekg(0, fich.beg) ;
124 fich.ignore(1000, '\n') ;
125 fich >> compose_format ;
126 fich.ignore(1000, '\n') ;
127 getline(fich, name, '\n') ;
128 fich >> tablename ;
129
130 if (compose_format)
132 else
134 }
135
136 //--------------//
137 // Destructor //
138 //--------------//
139
141 {
142 if (lognb != 0x0) delete lognb ;
143 if (loge != 0x0) delete loge ;
144 if (dlesdlnb != 0x0) delete dlesdlnb ;
145 if (c_sound2 != 0x0) delete c_sound2 ;
146 }
147
148 //------------------------//
149 // Comparison operators //
150 //------------------------//
151
152
153 bool Dyn_eos_tab::operator==(const Dyn_eos& eos_i) const {
154
155 bool resu = true ;
156
157 if ( eos_i.identify() != identify() ) {
158 cout << "The second EOS is not of type Dyn_eos_tab !" << endl ;
159 resu = false ;
160 }
161
162 return resu ;
163
164 }
165
166 bool Dyn_eos_tab::operator!=(const Dyn_eos& eos_i) const {
167
168 return !(operator==(eos_i)) ;
169
170 }
171
172 //------------//
173 // Outputs //
174 //------------//
175
176 void Dyn_eos_tab::sauve(FILE* fich) const
177 {
178 Dyn_eos::sauve(fich) ;
179
180 char tmp_string[160] ;
181 strcpy(tmp_string, tablename.c_str()) ;
182 fwrite(tmp_string, sizeof(char), 160, fich) ;
183 int comp = int(compose_format) ;
184 fwrite_be(&comp, sizeof(int), 1, fich) ;
185 }
186
187 ostream& Dyn_eos_tab::operator>>(ostream & ost) const
188 {
189 ost << "EOS of class Dyn_eos_tab." << endl ;
190 ost << "Built from file " << tablename << endl ;
191 ost << ((compose_format == 0) ? "Old LORENE format" : "CompOSE format") << endl ;
192 ost << "Authors : " << authors << endl ;
193 ost << "Number of points in file : " << lognb->get_taille() << endl ;
194 return ost ;
195 }
196 //------------------------//
197 // Reading of the table //
198 //------------------------//
199
200 // LORENE format
201 //---------------
203
204 using namespace Unites ;
205
206 ifstream fich(tablename.data()) ;
207
208 if (!fich) {
209 cerr << "Dyn_eos_tab::read_table_lorene(): " << endl ;
210 cerr << "Problem in opening the EOS file!" << endl ;
211 cerr << "While trying to open " << tablename << endl ;
212 cerr << "Aborting..." << endl ;
213 abort() ;
214 }
215
216 fich.ignore(1000, '\n') ; // Jump over the first header
217 fich.ignore(1) ;
218 getline(fich, authors, '\n') ;
219 for (int i=0; i<3; i++) { // jump over the file
220 fich.ignore(1000, '\n') ; // header
221 } //
222
223 int nbp ;
224 fich >> nbp ; fich.ignore(1000, '\n') ; // number of data
225 if (nbp<=0) {
226 cerr << "Dyn_eos_tab::read_table_lorene(): " << endl ;
227 cerr << "Wrong value for the number of lines!" << endl ;
228 cerr << "nbp = " << nbp << endl ;
229 cerr << "Aborting..." << endl ;
230 abort() ;
231 }
232
233 for (int i=0; i<3; i++) { // jump over the table
234 fich.ignore(1000, '\n') ; // description
235 }
236
237 Tbl press(nbp) ; press.set_etat_qcq() ;
238 Tbl nb(nbp) ; nb.set_etat_qcq() ;
239 Tbl ro(nbp) ; ro.set_etat_qcq() ;
240
241 lognb = new Tbl(nbp) ;
242 loge = new Tbl(nbp) ;
243 dlesdlnb = new Tbl(nbp) ;
244
245 lognb->set_etat_qcq() ;
246 loge->set_etat_qcq() ;
247 dlesdlnb->set_etat_qcq() ;
248
249 double rhonuc_cgs = rhonuc_si * 1e-3 ;
250 double c2_cgs = c_si * c_si * 1e4 ;
251
252 int no ;
253 double nb_fm3, rho_cgs, p_cgs ;
254
255 cout << "Dyn_eos_tab: reading Lorene format table from the file "
256 << tablename << endl ;
257 for (int i=0; i<nbp; i++) {
258
259 fich >> no ;
260 fich >> nb_fm3 ;
261 fich >> rho_cgs ;
262 fich >> p_cgs ; fich.ignore(1000,'\n') ;
263 if ( (nb_fm3<0) || (rho_cgs<0) || (p_cgs < 0) ){
264 cout << "Dyn_eos_tab::read_table_lorene(): " << endl ;
265 cout << "Negative value in table!" << endl ;
266 cout << "nb = " << nb_fm3 << ", rho = " << rho_cgs <<
267 ", p = " << p_cgs << endl ;
268 cout << "Aborting..." << endl ;
269 abort() ;
270 }
271
272 press.set(i) = p_cgs / (c2_cgs*rhonuc_cgs) ;
273 nb.set(i) = 10.*nb_fm3 ; // Units 0.1 fm^-3
274 ro.set(i) = rho_cgs / rhonuc_cgs ;
275 }
276
277 *lognb = log10(nb) ;
278 *loge = log10(ro) ;
279 *dlesdlnb = (ro + press) / ro ;
280 Tbl tmp(nbp) ; tmp.set_etat_qcq() ;
281 compute_derivative(ro, press, tmp) ;
282 c_sound2 = new Tbl(tmp) ; // c_s^2 = dp/de
283
284 nbmin = pow( double(10), (*lognb)(0) ) ;
285 nbmax = pow( double(10), (*lognb)(nbp-1) ) ;
286
287 cout << "nbmin, nbmax : " << nbmin << " " << nbmax << endl ;
288
289 fich.close();
290 }
291
292 // CompOSE format
293 //----------------
295 {
296 using namespace Unites ;
297
298 // Files containing data and a test
299 //---------------------------------
300 string file_nb = tablename + ".nb" ;
301 string file_thermo = tablename + ".thermo" ;
302
303 ifstream in_nb(file_nb.data()) ;
304 if (!in_nb) {
305 cerr << "Dyn_eos_tab::read_table_compose(): " << endl ;
306 cerr << "Problem in opening the EOS file!" << endl ;
307 cerr << "While trying to open " << file_nb << endl ;
308 cerr << "Aborting..." << endl ;
309 abort() ;
310 }
311
312 // obtaining the size of the tables for memory allocation
313 //-------------------------------------------------------
314 int index1, index2 ;
315 in_nb >> index1 >> index2 ;
316 int nbp = index2 - index1 + 1 ;
317 assert(nbp > 0) ;
318
319 Tbl press(nbp) ; press.set_etat_qcq() ;
320 Tbl nb(nbp) ; nb.set_etat_qcq() ;
321 Tbl ro(nbp) ; ro.set_etat_qcq() ;
322
323 lognb = new Tbl(nbp) ;
324 loge = new Tbl(nbp) ;
325 dlesdlnb = new Tbl(nbp) ;
326
327 lognb->set_etat_qcq() ;
328 loge->set_etat_qcq() ;
329 dlesdlnb->set_etat_qcq() ;
330
331 // Variables and conversion
332 //-------------------------
333 double nb_fm3, rho_cgs, p_cgs, p_over_nb_comp, eps_comp ;
334 double dummy_x ;
335 int dummy_n ;
336
337 double rhonuc_cgs = rhonuc_si * 1e-3 ;
338 double c2_cgs = c_si * c_si * 1e4 ;
339 double m_neutron_MeV, m_proton_MeV ;
340
341 ifstream in_p_rho (file_thermo.data()) ;
342 if (!in_p_rho) {
343 cerr << "Dyn_eos_tab::read_table_compose(): " << endl ;
344 cerr << "Problem in opening the EOS file!" << endl ;
345 cerr << "While trying to open " << file_thermo << endl ;
346 cerr << "Aborting..." << endl ;
347 abort() ;
348 }
349 in_p_rho >> m_neutron_MeV >> m_proton_MeV ; //Neutron and proton masses
350 in_p_rho.ignore(1000, '\n') ;
351
352 double p_convert = mev_si * 1.e45 * 10. ; // Conversion from MeV/fm^3 to cgs
353 double eps_convert = mev_si * 1.e42 / (c_si*c_si) ; //From meV/fm^3 to g/cm^3
354
355 // Main loop reading the table
356 //----------------------------
357 cout << "Dyn_eos_tab: reading CompOSE format table from the file "
358 << tablename << ".thermo" << endl ;
359 for (int i=0; i<nbp; i++) {
360 in_nb >> nb_fm3 ;
361 in_p_rho >> dummy_n >> dummy_n >> dummy_n >> p_over_nb_comp ;
362 in_p_rho >> dummy_x >> dummy_x >> dummy_x >> dummy_x >> dummy_x >> eps_comp ;
363 in_p_rho.ignore(1000, '\n') ;
364 p_cgs = p_over_nb_comp * nb_fm3 * p_convert ;
365 rho_cgs = ( eps_comp + 1. ) * m_neutron_MeV * nb_fm3 * eps_convert ;
366
367 if ( (nb_fm3<0) || (rho_cgs<0) || (p_cgs < 0) ){
368 cout << "Dyn_eos_tab::read_table_compose(): " << endl ;
369 cout << "Negative value in table!" << endl ;
370 cout << "nb = " << nb_fm3 << ", rho = " << rho_cgs <<
371 ", p = " << p_cgs << endl ;
372 cout << "Aborting..." << endl ;
373 abort() ;
374 }
375
376 press.set(i) = (p_cgs / c2_cgs) / rhonuc_cgs ;
377 nb.set(i) = 10. * nb_fm3 ; // Units : 0.1 fm^-3
378 ro.set(i) = rho_cgs / rhonuc_cgs ;
379 }
380
381 *lognb = log10(nb) ;
382 *loge = log10(ro) ;
383 *dlesdlnb = (ro + press) / ro ;
384 Tbl tmp(nbp) ; tmp.set_etat_qcq() ;
385 compute_derivative(ro, press, tmp) ;
386 c_sound2 = new Tbl(tmp) ; // c_s^2 = dp/de
387
388 nbmin = pow( double(10), (*lognb)(0) ) ;
389 nbmax = pow( double(10), (*lognb)(nbp-1) ) ;
390
391 cout << "nbmin, nbmax : " << nbmin << " " << nbmax << endl ;
392 }
393 //------------------------------//
394 // Computational routines //
395 //------------------------------//
396
397 // Enthalpy from baryon density
398 //------------------------------
399 double Dyn_eos_tab::ent_nbar_p(double nbar, const Param* ) const
400 {
401 static int i_near = lognb->get_taille() / 2 ;
402
403 if ( nbar > nbmin ) {
404 if (nbar > nbmax) {
405 cout << "Dyn_eos_tab::ent_nbar_p : nbar > nbmax !" << endl ;
406 abort() ;
407 }
408 double lognb0 = log10( nbar ) ;
409 double loge0 ;
410 double dlesdlnb0 ;
411 interpol_herm(*lognb, *loge, *dlesdlnb, lognb0, i_near, loge0,
412 dlesdlnb0) ;
413 double ee = pow(double(10), loge0) ;
414 double resu = dlesdlnb0*ee / nbar ;
415 return log(resu) ;
416 }
417 else
418 return log((*dlesdlnb)(0)*pow(10.,(*loge)(0)) / nbmin) ;
419 }
420
421 // Energy density from baryon density
422 //------------------------------------
423
424 double Dyn_eos_tab::ener_nbar_p(double nbar, const Param* ) const
425 {
426 static int i_near = lognb->get_taille() / 2 ;
427
428 if ( nbar > nbmin ) {
429 if (nbar > nbmax) {
430 cout << "Dyn_eos_tab::ener_nbar_p : nbar > nbmax !" << endl ;
431 abort() ;
432 }
433 double lognb0 = log10( nbar ) ;
434 double loge0 ;
435 double dlesdlnb0 ;
436 interpol_herm(*lognb, *loge, *dlesdlnb, lognb0, i_near, loge0,
437 dlesdlnb0) ;
438 return pow(double(10), loge0) ;
439 }
440 else
441 return pow(10.,(*loge)(0)) ;
442 }
443
444 // Pressure from baryon density
445 //------------------------------
446
447 double Dyn_eos_tab::press_nbar_p(double nbar, const Param* ) const
448 {
449 static int i_near = lognb->get_taille() / 2 ;
450
451 if ( nbar > nbmin ) {
452 if (nbar > nbmax) {
453 cout << "Dyn_eos_tab::press_nbar_p : nbar > nbmax !" << endl ;
454 abort() ;
455 }
456 double lognb0 = log10( nbar ) ;
457 double loge0 ;
458 double dlesdlnb0 ;
459 interpol_herm(*lognb, *loge, *dlesdlnb, lognb0, i_near, loge0,
460 dlesdlnb0) ;
461 double ee = pow(double(10), loge0) ;
462 double hnb = ee * dlesdlnb0 ;
463 return hnb - ee ;
464 }
465 else{
466 return pow(10.,(*loge)(0))*((*dlesdlnb)(0) - 1.) ;
467 }
468 }
469
470
471 // Sound speed from baryon density
472 //---------------------------------
473
474 double Dyn_eos_tab::csound_square_nbar_p(double nbar, const Param*) const {
475
476 static int i_near = lognb->get_taille() / 2 ;
477
478 if ( nbar > nbmin ) {
479 if (nbar > nbmax) {
480 cout << "Dyn_eos_tab::press_nbar_p : nbar > nbmax !" << endl ;
481 abort() ;
482 }
483 double lognb0 = log10( nbar ) ;
484 double csound0 ;
485
486 interpol_linear(*lognb, *c_sound2, lognb0, i_near, csound0) ;
487
488 return csound0 ;
489 }
490 else
491 {
492 return (*c_sound2)(0) ;
493 }
494
495
496 }
497}
string authors
Authors - reference for the table.
Definition dyneos.h:657
virtual void read_table_lorene()
Reads the file containing the table in LORENE format and initializes the arrays lognb ,...
Definition dyneos_tab.C:202
virtual int identify() const
Returns a number to identify the sub-classe of Dyn_eos the object belongs to.
Definition dyneos.C:315
virtual ostream & operator>>(ostream &) const
Operator >>.
Definition dyneos_tab.C:187
Tbl * c_sound2
Table of .
Definition dyneos.h:677
Tbl * dlesdlnb
Table of .
Definition dyneos.h:674
Dyn_eos_tab()
Default constructor to be called by derived classes.
Definition dyneos_tab.C:87
virtual double press_nbar_p(double nbar, const Param *par=0x0) const
Computes the pressure from the baryon density and extra parameters (virtual function implemented in t...
Definition dyneos_tab.C:447
string tablename
Name of the file containing the tabulated data.
Definition dyneos.h:655
virtual bool operator!=(const Dyn_eos &) const
Comparison operator (difference).
Definition dyneos_tab.C:166
virtual void read_table_compose()
Reads the files .nb and .thermo containing the table in CompOSE format and initializes the arrays log...
Definition dyneos_tab.C:294
virtual double ent_nbar_p(double nbar, const Param *par=0x0) const
Computes the log-enthalpy from the baryon density and extra parameters (virtual function implemented ...
Definition dyneos_tab.C:399
virtual void sauve(FILE *) const
Save in a file.
Definition dyneos_tab.C:176
bool compose_format
Are(is) the table(s) in CompOSE format?
Definition dyneos.h:659
virtual ~Dyn_eos_tab()
Destructor.
Definition dyneos_tab.C:140
Tbl * lognb
Table of .
Definition dyneos.h:668
Tbl * loge
Table of .
Definition dyneos.h:671
virtual bool operator==(const Dyn_eos &) const
Comparison operator (egality).
Definition dyneos_tab.C:153
double nbmax
Upper boundary of the baryon density interval.
Definition dyneos.h:665
virtual double ener_nbar_p(double nbar, const Param *par=0x0) const
Computes the total energy density from the baryon density and extra parameters (virtual function impl...
Definition dyneos_tab.C:424
virtual double csound_square_nbar_p(double nbar, const Param *par=0x0) const
Computes the sound speed squared from the baryon density with extra parameters.
Definition dyneos_tab.C:474
double nbmin
Lower boundary of the baryon density interval.
Definition dyneos.h:662
virtual void sauve(FILE *) const
Save in a file.
Definition dyneos.C:178
string name
EOS name.
Definition dyneos.h:81
virtual int identify() const =0
Returns a number to identify the sub-classe of Dyn_eos the object belongs to.
Dyn_eos()
Standard constructor.
Definition dyneos.C:67
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 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
int fread_be(int *aa, int size, int nb, FILE *fich)
Reads integer(s) from a binary file according to the big endian convention.
Definition fread_be.C:72
int fwrite_be(const int *aa, int size, int nb, FILE *fich)
Writes integer(s) into a binary file according to the big endian convention.
Definition fwrite_be.C:73
Lorene prototypes.
Definition app_hor.h:67
Standard units of space, time and mass.