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 
60 namespace 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  {
79  if (compose_format)
81  else
83  }
84 
85 // Default constructor (protected, to be used by derived classes)
86 // ---------------------------------------------------------------
88  {
89  }
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() ;
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() ;
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 }
Cmp log(const Cmp &)
Neperian logarithm.
Definition: cmp_math.C:299
virtual void sauve(FILE *) const
Save in a file.
Definition: dyneos.C:178
virtual int identify() const =0
Returns a number to identify the sub-classe of Dyn_eos the object belongs to.
Lorene prototypes.
Definition: app_hor.h:67
Standard units of space, time and mass.
double & set(int i)
Read/write of a particular element (index i) (1D case)
Definition: tbl.h:301
string tablename
Name of the file containing the tabulated data.
Definition: dyneos.h:655
Tbl * loge
Table of .
Definition: dyneos.h:671
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
Tbl * dlesdlnb
Table of .
Definition: dyneos.h:674
Tbl * c_sound2
Table of .
Definition: dyneos.h:677
virtual int identify() const
Returns a number to identify the sub-classe of Dyn_eos the object belongs to.
Definition: dyneos.C:315
double nbmin
Lower boundary of the baryon density interval.
Definition: dyneos.h:662
void set_etat_qcq()
Sets the logical state to ETATQCQ (ordinary state).
Definition: tbl.C:364
Equation of state for use in dynamical code base class.
Definition: dyneos.h:75
virtual void sauve(FILE *) const
Save in a file.
Definition: dyneos_tab.C:176
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
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
Parameter storage.
Definition: param.h:125
Tbl * lognb
Table of .
Definition: dyneos.h:668
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
virtual bool operator==(const Dyn_eos &) const
Comparison operator (egality)
Definition: dyneos_tab.C:153
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
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
Cmp pow(const Cmp &, int)
Power .
Definition: cmp_math.C:351
string name
EOS name.
Definition: dyneos.h:81
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
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
string authors
Authors - reference for the table.
Definition: dyneos.h:657
Cmp log10(const Cmp &)
Basis 10 logarithm.
Definition: cmp_math.C:325
int get_taille() const
Gives the total size (ie dim.taille)
Definition: tbl.h:417
Dyn_eos_tab()
Default constructor to be called by derived classes.
Definition: dyneos_tab.C:87
virtual ~Dyn_eos_tab()
Destructor.
Definition: dyneos_tab.C:140
Basic array class.
Definition: tbl.h:164
virtual bool operator!=(const Dyn_eos &) const
Comparison operator (difference)
Definition: dyneos_tab.C:166
bool compose_format
Are(is) the table(s) in CompOSE format?
Definition: dyneos.h:659
double nbmax
Upper boundary of the baryon density interval.
Definition: dyneos.h:665
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 ostream & operator>>(ostream &) const
Operator >>
Definition: dyneos_tab.C:187