LORENE
eos_mag.C
1  /* Methods of class Eos_mag
2  *
3  * (see file eos_mag.h for documentation).
4  *
5  */
6 
7 /*
8  * Copyright (c) 2011 Thomas Elghozi & Jerome Novak
9  * Copyright (c) 2013 Debarati Chatterjee
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_mag.C,v 1.14 2016/12/05 16:17:51 j_novak Exp $
34  * $Log: eos_mag.C,v $
35  * Revision 1.14 2016/12/05 16:17:51 j_novak
36  * Suppression of some global variables (file names, loch, ...) to prevent redefinitions
37  *
38  * Revision 1.13 2014/10/13 08:52:53 j_novak
39  * Lorene classes and functions now belong to the namespace Lorene.
40  *
41  * Revision 1.12 2014/09/22 16:13:10 j_novak
42  * Minor modif.
43  *
44  * Revision 1.11 2014/05/27 12:32:28 j_novak
45  * Added possibility to converge to a given magnetic moment.
46  *
47  * Revision 1.10 2014/05/13 15:37:12 j_novak
48  * Updated to new magnetic units.
49  *
50  * Revision 1.9 2014/04/28 12:48:13 j_novak
51  * Minor modifications.
52  *
53  * Revision 1.8 2014/03/11 14:27:26 j_novak
54  * Corrected a missing 4pi term.
55  *
56  * Revision 1.7 2014/03/03 16:23:08 j_novak
57  * Updated error message
58  *
59  * Revision 1.6 2013/12/12 16:07:30 j_novak
60  * interpol_herm_2d outputs df/dx, used to get the magnetization.
61  *
62  * Revision 1.5 2013/11/25 15:00:52 j_novak
63  * Correction of memory error.
64  *
65  * Revision 1.4 2013/11/14 16:12:55 j_novak
66  * Corrected a mistake in the units.
67  *
68  * Revision 1.2 2011/10/04 16:05:19 j_novak
69  * Update of Eos_mag class. Suppression of loge, re-definition of the derivatives
70  * and use of interpol_herm_2d.
71  *
72  * Revision 1.1 2011/06/16 10:49:18 j_novak
73  * New class Eos_mag for EOSs depending on density and magnetic field.
74  *
75  *
76  * $Header: /cvsroot/Lorene/C++/Source/Eos/eos_mag.C,v 1.14 2016/12/05 16:17:51 j_novak Exp $
77  *
78  */
79 
80 // headers C
81 #include <cmath>
82 
83 // Headers Lorene
84 #include "eos.h"
85 #include "cmp.h"
86 #include "param.h"
87 #include "utilitaires.h"
88 #include "unites.h"
89 
90 
91 namespace Lorene {
92 void interpol_herm_2d(const Tbl&, const Tbl&, const Tbl&, const Tbl&, const Tbl&, const Tbl&, double, double, double&, double&, double&) ;
93 
94 
95  //----------------------------//
96  // Constructors //
97  //----------------------------//
98 
99 // Standard constructor
100 // --------------------
101 Eos_mag::Eos_mag(const char* name_i, const char* table,
102  const char* path) : Eos(name_i), tablename(path) {
103 
104  tablename += '/' ;
105  tablename += table ;
106 
107  read_table() ;
108 
109 }
110 
111 // Standard constructor with full filename
112 // ---------------------------------------
113 Eos_mag::Eos_mag(const char* name_i, const char* file_name)
114  : Eos(name_i), tablename(file_name) {
115 
116  read_table() ;
117 
118 }
119 
120 
121 // Constructor from binary file
122 // ----------------------------
123 Eos_mag::Eos_mag(FILE* fich) : Eos(fich) {
124 
125  char tmp_name[160] ;
126 
127  fread(tmp_name, sizeof(char), 160, fich) ;
128  tablename += tmp_name ;
129 
130  read_table() ;
131 
132 }
133 
134 
135 
136 // Constructor from a formatted file
137 // ---------------------------------
138 Eos_mag::Eos_mag(ifstream& fich, const char* table) : Eos(fich) {
139 
140  fich >> tablename ;
141  tablename += '/' ;
142  tablename += table ;
143 
144  read_table() ;
145 
146 }
147 
148 Eos_mag::Eos_mag(ifstream& fich) : Eos(fich) {
149 
150  fich >> tablename ;
151 
152  read_table() ;
153 
154 }
155 
156 
157  //--------------//
158  // Destructor //
159  //--------------//
160 
162  delete d2lp ;
163  delete dlpsdB ;
164  delete dlpsdlh ;
165  delete Bfield ;
166  delete logh ;
167  delete logp ;
168 }
169 
170  //------------//
171  // Outputs //
172  //------------//
173 
174 void Eos_mag::sauve(FILE* fich) const {
175 
176  Eos::sauve(fich) ;
177 
178  fwrite(tablename.c_str(), sizeof(char), tablename.size(), fich) ;
179 
180 }
181  //------------------------//
182  // Comparison operators //
183  //------------------------//
184 
185 
186 bool Eos_mag::operator==(const Eos& eos_i) const {
187 
188  bool resu = true ;
189 
190  if ( eos_i.identify() != identify() ) {
191  cerr << "The second EOS is not of type Eos_mag !" << endl ;
192  resu = false ;
193  }
194 
195  return resu ;
196 
197 }
198 
199 bool Eos_mag::operator!=(const Eos& eos_i) const {
200 
201  return !(operator==(eos_i)) ;
202 
203 }
204 
205  //------------//
206  // Outputs //
207  //------------//
208 
209 
210 ostream& Eos_mag::operator>>(ostream & ost) const {
211 
212  ost <<
213  "EOS of class Eos_mag : tabulated EOS depending on two variables: enthalpy and magnetic field."
214  << '\n' ;
215  ost << "Table read from " << tablename << endl ;
216 
217  return ost ;
218 
219 }
220 
221 
222 
223  //------------------------//
224  // Reading of the table //
225  //------------------------//
226 
228 
229  using namespace Unites_mag ;
230 
231  ifstream fich(tablename.data()) ;
232 
233  if (!fich) {
234  cerr << "Eos_mag::read_table(): " << endl ;
235  cerr << "Problem in opening the EOS file!" << endl ;
236  cerr << "Aborting..." << endl ;
237  abort() ;
238  }
239 
240  for (int i=0; i<5; i++) { // jump over the file
241  fich.ignore(1000, '\n') ; // header
242  } //
243 
244  int nbp1, nbp2 ;
245  fich >> nbp1 >> nbp2 ; fich.ignore(1000, '\n') ; // number of data
246  if ((nbp1<=0) || (nbp2<=0)) {
247  cerr << "Eos_mag::read_table(): " << endl ;
248  cerr << "Wrong value for the number of lines!" << endl ;
249  cerr << "nbp1 = " << nbp1 << ", nbp2 = " << nbp2 << endl ;
250  cerr << "Aborting..." << endl ;
251  abort() ;
252  }
253 
254  for (int i=0; i<3; i++) { // jump over the table
255  fich.ignore(1000, '\n') ;
256  }
257 
258  logp = new Tbl(nbp2, nbp1) ;
259  logh = new Tbl(nbp2, nbp1) ;
260  Bfield = new Tbl(nbp2, nbp1) ;
261  dlpsdlh = new Tbl(nbp2, nbp1) ;
262  dlpsdB = new Tbl(nbp2, nbp1) ;
263  d2lp = new Tbl(nbp2, nbp1) ;
264 
265  logp->set_etat_qcq() ;
266  logh->set_etat_qcq() ;
267  Bfield->set_etat_qcq() ;
268  dlpsdlh->set_etat_qcq() ;
269  dlpsdB->set_etat_qcq() ;
270  d2lp->set_etat_qcq() ;
271 
272  double c2 = c_si * c_si ;
273  double B_unit = mag_unit / 1.e11 ;
274  double M_unit = B_unit*mu0/(4*M_PI) ;
275 
276  int no1 ;
277  double nb_fm3, rho_cgs, p_cgs, mu_MeV, magB_PG, magM_PG, chi_PGpMeV ;
278 
279  double ww = 0. ;
280 
281  for (int j=0; j<nbp2; j++) {
282 
283  for (int i=0; i<nbp1; i++) {
284  fich >> no1 >> nb_fm3 >> rho_cgs >> p_cgs >> mu_MeV
285  >> magB_PG >> magM_PG >> chi_PGpMeV ;
286  fich.ignore(1000,'\n') ;
287  if ( (nb_fm3<0) || (rho_cgs<0)) { // || (p_cgs < 0) ){
288  cerr << "Eos_mag::read_table(): " << endl ;
289  cerr << "Negative value in table!" << endl ;
290  cerr << "nb = " << nb_fm3 << ", rho = " << rho_cgs <<
291  ", p = " << p_cgs << endl ;
292  cerr << "Aborting..." << endl ;
293  abort() ;
294  }
295 
296  double psc2 = 0.1*p_cgs/c2 ; // in kg m^-3
297  double rho_si = rho_cgs*1000. ; // in kg m^-3
298 
299  double h_read = log(mu_MeV) ;
300  if ( (i==0) && (j==0) ) ww = h_read ;
301  double h_new = h_read - ww ;
302 
303  logp->set(j, i) = psc2/rhonuc_si ;
304  logh->set(j, i) = h_new ;
305  Bfield->set(j, i) = magB_PG / B_unit ; // in Lorene units
306  dlpsdlh->set(j, i) = (rho_si + psc2)/rhonuc_si ;
307  dlpsdB->set(j, i) = magM_PG / M_unit ;
308  d2lp->set(j, i) = mu_MeV*chi_PGpMeV / (M_unit) ;
309 
310  }
311  }
312 
313  hmin = (*logh)(0, 0) ;
314  hmax = (*logh)(0, nbp1-1) ;
315 
316  Bmax = (*Bfield)(nbp2-1, 0) ;
317 
318  // cout << "hmin: " << hmin << ", hmax: " << hmax << endl ;
319  // cout << "Bmax: " << Bmax << endl ;
320 
321  fich.close();
322 
323 }
324 
325 
326  //------------------------------//
327  // Computational routines //
328  //------------------------------//
329 
330 // Baryon density from enthalpy
331 //------------------------------
332 
333 double Eos_mag::nbar_ent_p(double ent, const Param* par ) const {
334 
335  using namespace Unites_mag ;
336 
337  if ((ent > hmin - 1.e-12) && (ent < hmin))
338  ent = hmin ;
339 
340  if ( ent >= hmin) {
341  if (ent > hmax) {
342  cerr << "Eos_tabul::nbar_ent_p : ent > hmax !" << endl ;
343  abort() ;
344  }
345  // recuperer magB0 (input)
346  double magB0 = 0. ;
347  if (par != 0x0)
348  if (par->get_n_double_mod() > 0) {
349  magB0 = par->get_double_mod() ;
350  }
351 
352  if ( magB0 > Bmax) {
353  cerr << "Eos_tabul::nbar_ent_p : B > Bmax !" << endl ;
354  cerr << "B = " << magB0*mag_unit << ", Bmax = " << Bmax*mag_unit << endl ;
355  abort() ;
356  }
357 
358  double p_int, dpdb_int, dpdh_int ;
359 
360  interpol_herm_2d(*Bfield, *logh, *logp, *dlpsdB, *dlpsdlh, *d2lp, magB0, ent,
361  p_int, dpdb_int, dpdh_int) ;
362 
363  double nbar_int = dpdh_int * exp(-ent) ;
364 
365  return nbar_int ;
366  }
367  else{
368  return 0 ;
369  }
370 }
371 
372 
373 // Energy density from enthalpy
374 //------------------------------
375 
376 double Eos_mag::ener_ent_p(double ent, const Param* par ) const {
377 
378  using namespace Unites_mag ;
379 
380  if ((ent > hmin - 1.e-12) && (ent < hmin))
381  ent = hmin ;
382 
383  if ( ent >= hmin ) {
384  if (ent > hmax) {
385  cerr << "Eos_tabul::ener_ent_p : ent > hmax !" << endl ;
386  abort() ;
387  }
388 
389  // recuperer magB0 (input)
390  double magB0 = 0. ;
391  if (par != 0x0)
392  if (par->get_n_double_mod() > 0) {
393  magB0 = par->get_double_mod() ;
394  }
395 
396  if ( magB0 > Bmax) {
397  cerr << "Eos_tabul::ener_ent_p : B > Bmax !" << endl ;
398  cerr << "B = " << magB0*mag_unit << ", Bmax = " << Bmax*mag_unit << endl ;
399  abort() ;
400  }
401 
402 
403  double p_int, dpdb_int, dpdh_int ;
404 
405  interpol_herm_2d(*Bfield, *logh, *logp, *dlpsdB, *dlpsdlh, *d2lp, magB0, ent,
406  p_int, dpdb_int, dpdh_int) ;
407 
408  double nbar_int = dpdh_int * exp(-ent) ;
409 
410  double f_int = - p_int + exp(ent) * nbar_int;
411 
412  return f_int ;
413  }
414  else{
415  return 0 ;
416  }
417 }
418 
419 // Pressure from enthalpy
420 //------------------------
421 
422 double Eos_mag::press_ent_p(double ent, const Param* par ) const {
423 
424  using namespace Unites_mag ;
425 
426  if ((ent > hmin - 1.e-12) && (ent < hmin))
427  ent = hmin ;
428 
429  if ( ent >= hmin ) {
430  if (ent > hmax) {
431  cout << "Eos_mag::press_ent_p : ent > hmax !" << endl ;
432  abort() ;
433  }
434 
435  // recuperer magB0 (input)
436  double magB0 = 0. ;
437  if (par != 0x0)
438  if (par->get_n_double_mod() > 0) {
439  magB0 = par->get_double_mod() ;
440  }
441 
442  if ( magB0 > Bmax) {
443  cerr << "Eos_tabul::press_ent_p : B > Bmax !" << endl ;
444  cerr << "B = " << magB0*mag_unit << ", Bmax = " << Bmax*mag_unit << endl ;
445  abort() ;
446  }
447 
448  double p_int, dpdb_int, dpdh_int ;
449 
450  interpol_herm_2d(*Bfield, *logh, *logp, *dlpsdB, *dlpsdlh, *d2lp, magB0, ent,
451  p_int, dpdb_int, dpdh_int) ;
452 
453  return p_int;
454  }
455  else{
456  return 0 ;
457  }
458 }
459 
460 // Magnetization from enthalpy
461 //----------------------------
462 
463 double Eos_mag::mag_ent_p(double ent, const Param* par) const {
464 
465  using namespace Unites_mag ;
466 
467  if ((ent > hmin - 1.e-12) && (ent < hmin))
468  ent = hmin ;
469 
470  if ( ent >= hmin ) {
471  if (ent > hmax) {
472  cout << "Eos_mag::mag_ent_p : ent > hmax !" << endl ;
473  abort() ;
474  }
475 
476  // recuperer magB0 (input)
477  double magB0 = 0. ;
478  if (par != 0x0)
479  if (par->get_n_double_mod() > 0) {
480  magB0 = par->get_double_mod() ;
481  }
482 
483  if ( magB0 > Bmax) {
484  cerr << "Eos_tabul::mag_ent_p : B > Bmax !" << endl ;
485  cerr << "B = " << magB0*mag_unit << ", Bmax = " << Bmax*mag_unit << endl ;
486  abort() ;
487  }
488 
489  double p_int, dpdb_int, dpdh_int ;
490 
491  interpol_herm_2d(*Bfield, *logh, *logp, *dlpsdB, *dlpsdlh, *d2lp, magB0, ent,
492  p_int, dpdb_int, dpdh_int) ;
493 
494  double magnetization = dpdb_int ;
495 
496  if (magB0 == 0.)
497  return 0 ;
498  else
499  return mu0*magnetization / magB0 ;
500  }
501 
502  else
503  return 0. ;
504 
505 }
506 
507 
508 // dln(n)/ln(H) from enthalpy
509 //---------------------------
510 
511 double Eos_mag::der_nbar_ent_p(double ent, const Param* ) const {
512 
513  c_est_pas_fait("Eos_mag::der_nbar_ent_p" ) ;
514 
515  return ent ;
516 
517 }
518 
519 
520 // dln(e)/ln(H) from enthalpy
521 //---------------------------
522 
523 double Eos_mag::der_ener_ent_p(double ent, const Param* ) const {
524 
525 
526  c_est_pas_fait("Eos_mag::der_ener_enr_p" ) ;
527 
528  return ent ;
529 
530 }
531 
532 
533 // dln(p)/ln(H) from enthalpy
534 //---------------------------
535 
536 double Eos_mag::der_press_ent_p(double ent, const Param* ) const {
537 
538  c_est_pas_fait("Eos_mag::" ) ;
539 
540  return ent ;
541 
542 }
543 
544 
545 // dln(p)/dln(n) from enthalpy
546 //---------------------------
547 
548 double Eos_mag::der_press_nbar_p(double ent, const Param*) const {
549 
550  c_est_pas_fait("Eos_mag::der_press_nbar_p" ) ;
551 
552  return ent ;
553 
554 }
555 }
double Bmax
Upper boundary of the magnetic field interval.
Definition: eos_mag.h:97
virtual int identify() const
Returns a number to identify the sub-classe of Eos the object belongs to.
Cmp log(const Cmp &)
Neperian logarithm.
Definition: cmp_math.C:299
virtual double nbar_ent_p(double ent, const Param *par=0x0) const
Computes the baryon density from the log-enthalpy.
Definition: eos_mag.C:333
double & get_double_mod(int position=0) const
Returns the reference of a stored modifiable double .
Definition: param.C:501
Cmp exp(const Cmp &)
Exponential.
Definition: cmp_math.C:273
virtual double der_press_nbar_p(double ent, const Param *par=0x0) const
Computes the logarithmic derivative from the log-enthalpy.
Definition: eos_mag.C:548
virtual void sauve(FILE *) const
Save in a file.
Definition: eos_mag.C:174
Tbl * dlpsdB
Table of .
Definition: eos_mag.h:112
Lorene prototypes.
Definition: app_hor.h:67
string tablename
Name of the file containing the tabulated data.
Definition: eos_mag.h:88
Equation of state base class.
Definition: eos.h:209
double & set(int i)
Read/write of a particular element (index i) (1D case)
Definition: tbl.h:301
virtual int identify() const =0
Returns a number to identify the sub-classe of Eos the object belongs to.
Tbl * d2lp
Table of .
Definition: eos_mag.h:115
double hmax
Upper boundary of the log-enthalpy interval.
Definition: eos_mag.h:94
double hmin
Lower boundary of the log-enthalpy interval.
Definition: eos_mag.h:91
virtual void sauve(FILE *) const
Save in a file.
Definition: eos.C:189
void set_etat_qcq()
Sets the logical state to ETATQCQ (ordinary state).
Definition: tbl.C:364
virtual double press_ent_p(double ent, const Param *par=0x0) const
Computes the pressure from the log-enthalpy.
Definition: eos_mag.C:422
virtual ostream & operator>>(ostream &) const
Operator >>
Definition: eos_mag.C:210
double mag_ent_p(double ent, const Param *par=0x0) const
Computes the magnetisation.
Definition: eos_mag.C:463
Parameter storage.
Definition: param.h:125
int get_n_double_mod() const
Returns the number of stored modifiable double &#39;s addresses.
Definition: param.C:449
void read_table()
Reads the file containing the table and initializes in the arrays logh , logp and dlpsdlh ...
Definition: eos_mag.C:227
Tbl * Bfield
Table of .
Definition: eos_mag.h:106
Eos_mag(const char *name_i, const char *table, const char *path)
Standard constructor.
Definition: eos_mag.C:101
virtual ~Eos_mag()
Destructor.
Definition: eos_mag.C:161
Tbl * logp
Table of .
Definition: eos_mag.h:100
virtual double der_press_ent_p(double ent, const Param *par=0x0) const
Computes the logarithmic derivative from the log-enthalpy.
Definition: eos_mag.C:536
virtual bool operator!=(const Eos &) const
Comparison operator (difference)
Definition: eos_mag.C:199
void c_est_pas_fait(const char *)
Helpful function to say something is not implemented yet.
virtual bool operator==(const Eos &) const
Comparison operator (egality)
Definition: eos_mag.C:186
virtual double ener_ent_p(double ent, const Param *par=0x0) const
Computes the total energy density from the log-enthalpy.
Definition: eos_mag.C:376
virtual double der_nbar_ent_p(double ent, const Param *par=0x0) const
Computes the logarithmic derivative from the log-enthalpy.
Definition: eos_mag.C:511
Basic array class.
Definition: tbl.h:164
Tbl * logh
Table of .
Definition: eos_mag.h:103
virtual double der_ener_ent_p(double ent, const Param *par=0x0) const
Computes the logarithmic derivative from the log-enthalpy.
Definition: eos_mag.C:523
Standard electro-magnetic units.
Tbl * dlpsdlh
Table of .
Definition: eos_mag.h:109