LORENE
pseudopolytrope_1D.C
1/*
2 * Methods of the class Pseudo_polytrope_1D.
3 *
4 * (see file eos.h for documentation).
5 */
6
7/*
8 * Copyright (c) 2023 Gaƫl Servignat
9 *
10 * This file is part of LORENE.
11 *
12 * LORENE is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * LORENE is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with LORENE; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 */
27
28
29
30
31/*
32
33 */
34
35// Headers C
36#include <cstdlib>
37#include <cstring>
38#include <cmath>
39
40// Headers Lorene
41#include "eos.h"
42#include "cmp.h"
43#include "unites.h"
44
45 //--------------//
46 // Constructors //
47 //--------------//
48
49// Standard constructor
50// --------------------
51namespace Lorene {
52Pseudo_polytrope_1D::Pseudo_polytrope_1D(const Tbl& coefs0, double n_lim0, double m_n0):
53 n_lim(n_lim0), m_n(m_n0) {
54
55 cerr << "Deprecated constructor, please do not use ! Aborting..." << endl; abort() ;
56 set_name("Pseudo-polytropic fit of cold, beta-equilibrated EoS") ;
57
58 assert(coefs0.get_ndim() == 1) ;
59 coefs = new Tbl(coefs0) ;
60 n_coefs = coefs->get_taille() ;
61
62 double x_lim = log(n_lim*0.1) ;
63 double alpha = (*coefs)(n_coefs-1) ;
64 double sum_poly = 0., sum_der_poly = 0. ;
65 for (int i=0; i<n_coefs-1; i++){
66 sum_poly += (*coefs)(i)*pow(x_lim, double(i)) ;
67 sum_der_poly += (i == 0) ? 0. : (*coefs)(i)*double(i)*pow(x_lim, double(i-1)) ;
68 }
69 ent_lim = log1p(mu_0 + exp(alpha*x_lim)*((alpha+1)*sum_poly + sum_der_poly)) ;
70
71}
72
73
74// Copy constructor
75// ----------------
76Pseudo_polytrope_1D::Pseudo_polytrope_1D(const Pseudo_polytrope_1D& eosi): Eos(eosi), coefs(eosi.coefs), gamma_low(eosi.gamma_low), kappa_low(eosi.kappa_low),
77 n_lim(eosi.n_lim), ent_lim(eosi.ent_lim), m_n(eosi.m_n), mu_0(eosi.mu_0), n_coefs(eosi.n_coefs) {}
78
79
80// Constructor from a binary file
81// ------------------------------
83
84 fread_be(&n_coefs, sizeof(int), 1, fich) ;
85 coefs = new Tbl(fich) ;
86 fread_be(&kappa_low, sizeof(double), 1, fich) ;
87 fread_be(&gamma_low, sizeof(double), 1, fich) ;
88 fread_be(&n_lim, sizeof(double), 1, fich) ;
89 fread_be(&ent_lim, sizeof(double), 1, fich) ;
90 fread_be(&m_n, sizeof(double), 1, fich) ;
91 fread_be(&mu_0, sizeof(double), 1, fich) ;
92 fread_be(&Lambda, sizeof(double), 1, fich) ;
93
94 eos_low = new Eos_poly(gamma_low, kappa_low) ;
95}
96
97// Constructor from a formatted file
98// ---------------------------------
100
101 fich >> n_coefs ; fich.ignore(1000, '\n') ;
102 coefs = new Tbl(n_coefs) ; coefs->set_etat_qcq() ;
103
104 for (int i=0; i < n_coefs; i++)
105 fich >> coefs->set(i) ;
106 fich.ignore(1000, '\n') ;
107
108 fich >> n_lim ; fich.ignore(1000, '\n') ;
109
110 fich >> kappa_low ; fich.ignore(1000, '\n') ;
111
112 fich >> gamma_low ; fich.ignore(1000, '\n') ;
113
114 fich >> m_n ; fich.ignore(1000, '\n') ;
115
116 fich >> mu_0 ; fich.ignore(1000, '\n') ;
117
118 fich >> Lambda ; fich.ignore(1000, '\n') ;
119
120 double x_lim = log(n_lim*0.1) ;
121 double alpha = (*coefs)(n_coefs-1) ;
122 double sum_poly = 0., sum_der_poly = 0. ;
123 for (int i=0; i<n_coefs-1; i++){
124 sum_poly += (*coefs)(i)*pow(x_lim, double(i)) ;
125 sum_der_poly += (i == 0) ? 0. : (*coefs)(i)*double(i)*pow(x_lim, double(i-1)) ;
126 }
127 ent_lim = log1p(mu_0 + exp(alpha*x_lim)*((alpha+1)*sum_poly + sum_der_poly)) ;
128
129
130 eos_low = new Eos_poly(gamma_low, kappa_low) ;
131
132}
133
134
135 //--------------//
136 // Destructor //
137 //--------------//
138
140
141 if (coefs != 0x0) delete coefs ;
142 if (eos_low != 0x0) delete eos_low ;
143
144}
145 //--------------//
146 // Assignment //
147 //--------------//
148
150
151 set_name(eosi.name) ;
152
153 coefs = eosi.coefs ;
154 n_lim = eosi.n_lim ;
155 n_coefs = eosi.n_coefs ;
156 gamma_low = eosi.gamma_low ;
157 kappa_low = eosi.kappa_low ;
158 m_n = eosi.m_n ;
159 ent_lim = eosi.ent_lim ;
160 mu_0 = eosi.mu_0 ;
161 Lambda = eosi.Lambda ;
162 eos_low = eosi.eos_low ;
163
164}
165 //------------------------//
166 // Comparison operators //
167 //------------------------//
168
169bool Pseudo_polytrope_1D::operator==(const Eos& eos_i) const {
170
171 bool resu = true ;
172
173 if ( eos_i.identify() != identify() ) {
174 cout << "The second EOS is not of type Pseudo_polytrope_1D !" << endl ;
175 resu = false ;
176 }
177 else{
178
179 const Pseudo_polytrope_1D& eos = dynamic_cast<const Pseudo_polytrope_1D&>( eos_i ) ;
180
181 for (int i=0; i < n_coefs; i++)
182 if ((*eos.coefs)(i) != (*coefs)(i)) {
183 cout
184 << "The two Pseudo_polytrope_1D have different coefficients: " << (*coefs)(i) << " <-> "
185 << (*eos.coefs)(i) << endl ;
186 resu = false ;
187 }
188
189 if (eos.n_lim != n_lim) {
190 cout
191 << "The two Pseudo_polytrope_1D have different limiting densities n_lim: " << n_lim << " <-> "
192 << eos.n_lim << endl ;
193 resu = false ;
194 }
195
196 if (eos.ent_lim != ent_lim) {
197 cout
198 << "The two Pseudo_polytrope_1D have different limiting enthalpies ent_lim: " << ent_lim << " <-> "
199 << eos.ent_lim << endl ;
200 resu = false ;
201 }
202
203 if (eos.n_coefs != n_coefs) {
204 cout
205 << "The two Pseudo_polytrope_1D have different number of coefficients: " << n_coefs << " <-> "
206 << eos.n_coefs << endl ;
207 resu = false ;
208 }
209
210 if (eos.kappa_low != kappa_low) {
211 cout
212 << "The two Pseudo_polytrope_1D have different kappa in low polytrope: " << kappa_low << " <-> "
213 << eos.kappa_low << endl ;
214 resu = false ;
215 }
216
217 if (eos.gamma_low != gamma_low) {
218 cout
219 << "The two Pseudo_polytrope_1D have different kappa in low polytrope: " << gamma_low << " <-> "
220 << eos.gamma_low << endl ;
221 resu = false ;
222 }
223
224 if (eos.mu_0!= mu_0) {
225 cout
226 << "The two Pseudo_polytrope_1D have different mu_0 in low polytrope: " << mu_0 << " <-> "
227 << eos.mu_0 << endl ;
228 resu = false ;
229 }
230
231 }
232
233 return resu ;
234
235}
236
237bool Pseudo_polytrope_1D::operator!=(const Eos& eos_i) const {
238
239 return !(operator==(eos_i)) ;
240
241}
242
243
244 //------------//
245 // Outputs //
246 //------------//
247
248void Pseudo_polytrope_1D::sauve(FILE* fich) const {
249
250 Eos::sauve(fich) ;
251
252 fwrite_be(&n_coefs, sizeof(int), 1, fich) ;
253 coefs->sauve(fich) ;
254 fwrite_be(&kappa_low, sizeof(double), 1, fich) ;
255 fwrite_be(&gamma_low, sizeof(double), 1, fich) ;
256 fwrite_be(&n_lim, sizeof(double), 1, fich) ;
257 fwrite_be(&ent_lim, sizeof(double), 1, fich) ;
258 fwrite_be(&m_n, sizeof(double), 1, fich) ;
259 fwrite_be(&mu_0, sizeof(double), 1, fich) ;
260 fwrite_be(&Lambda, sizeof(double), 1, fich) ;
261
262
263}
264
265ostream& Pseudo_polytrope_1D::operator>>(ostream & ost) const {
266
267 ost << setprecision(16) << "EOS of class Pseudo_polytrope_1D (analytical fit of cold EoS): " << '\n' ;
268 ost << " Coefficients: " << *coefs << '\n' ;
269 ost << setprecision(16) << " Baryon mass: " << m_n << " [MeV]" << '\n' ;
270 ost << setprecision(16) << " mu_0-1: " << mu_0 << " and Lambda: " << Lambda << '\n' ;
271 ost << "Low densities polytrope :" << '\n' ;
272 cout << *eos_low << '\n' ;
273 ost << setprecision(16) << " Limiting density n_lim: " << 0.1*n_lim << " [fm^-3]" << '\n' ;
274 ost << setprecision(16) << " Limiting enthalpy h_lim: " << ent_lim << " [c^2]" << endl;
275
276 return ost ;
277
278}
279
280
281 //------------------------------//
282 // Computational routines //
283 //------------------------------//
284
285// Baryon density from enthalpy
286//------------------------------
287
288double Pseudo_polytrope_1D::nbar_ent_p(double ent, const Param* ) const {
289
290 if (ent > ent_lim ) {
291
292 auto ent_nb_p = [&](double nbar) {
293 double xx = log(nbar*0.1) ;
294 double alpha = (*coefs)(n_coefs-1) ;
295 double sum_poly = 0.;
296 for (int i=0; i < n_coefs-1; i++){
297 double cc1 = (alpha+1.)*(*coefs)(i) ;
298 double cc2 = (i == n_coefs - 2) ? 0. : double(i+1)*(*coefs)(i+1) ;
299 sum_poly += (cc1 + cc2)*pow(xx, double(i));
300 }
301 double arg = exp(alpha*xx)*sum_poly + mu_0 ;
302 return log1p(arg) - ent ;
303 } ;
304
305 double a = n_lim/2., b = max(100.*ent, 50.*n_lim) ;
306 double f0 = ent_nb_p(a), f1 = ent_nb_p(b) ;
307 double c=1., c_old=2., f2 ;
308 double eps = 5e-16 ;
309 assert( f0 * f1 < 0.) ;
310 while(fabs((c-c_old)/c)>eps) {
311 c_old = c ;
312 c = (b*f0 - a*f1)/(f0 - f1) ;
313 f2 = ent_nb_p(c) ;
314
315 if (f2*f0 < 0.){
316 b = c ;
317 f1 = f2 ;
318 }
319 else{
320 a = c ;
321 f0 = f2 ;
322 }
323 }
324 return c ;
325 }
326 else if ( (0 < ent) && (ent < ent_lim)){
327
328 return eos_low->nbar_ent_p(ent) ;
329 }
330 else{
331 return 0 ;
332 }
333}
334
335// Energy density from enthalpy
336//------------------------------
337
338double Pseudo_polytrope_1D::ener_ent_p(double ent, const Param* ) const {
339 if (ent > ent_lim ) {
340
341 double nbar = nbar_ent_p(ent) ;
342 double xx = log(nbar*0.1) ;
343
344 double alpha = (*coefs)(n_coefs-1) ;
345 double sum_poly = 0.;
346 for (int i=0; i < n_coefs-1; i++)
347 sum_poly += (*coefs)(i)*pow(xx, double(i));
348 return m_n*Unites::mevpfm3*(exp(xx)*(1.+mu_0) + exp((alpha+1) * xx)*sum_poly) - Lambda ;
349 }
350 else if ( (0 < ent) && (ent < ent_lim)){
351
352 return eos_low->ener_ent_p(ent) ;
353 }
354 else{
355 return 0 ;
356 }
357}
358
359// Pressure from enthalpy
360//------------------------
361
362double Pseudo_polytrope_1D::press_ent_p(double ent, const Param* ) const {
363 if (ent > ent_lim ) {
364
365 double nbar = nbar_ent_p(ent) ;
366
367 double xx = log(nbar*0.1) ;
368
369 double alpha = (*coefs)(n_coefs-1) ;
370 double sum_poly = 0.;
371 for (int i=0; i < n_coefs-1; i++){
372 double cc1 = alpha*(*coefs)(i) ;
373 double cc2 = (i == n_coefs - 2) ? 0. : double(i+1)*(*coefs)(i+1) ;
374 sum_poly += (cc1 + cc2)*pow(xx, double(i));
375 }
376
377 return m_n*Unites::mevpfm3*(exp((alpha+1.)*xx) * sum_poly) + Lambda;
378 }
379 else if ( (0 < ent) && (ent < ent_lim)){
380 return eos_low->press_ent_p(ent) ;
381 }
382 else{
383 return 0 ;
384 }
385}
386
387// dln(n)/ln(h) from enthalpy
388//---------------------------
389
390double Pseudo_polytrope_1D::der_nbar_ent_p(double , const Param* ) const {
391 c_est_pas_fait("Pseudo_polytrope_1D::der_nbar_ent_p") ;
392 return 0.;
393}
394
395// dln(e)/ln(h) from enthalpy
396//---------------------------
397
398double Pseudo_polytrope_1D::der_ener_ent_p(double, const Param* ) const {
399 c_est_pas_fait("Pseudo_polytrope_1D::der_ener_ent_p") ;
400 return 0.;
401}
402
403// dln(p)/ln(h) from enthalpy
404//---------------------------
405
406double Pseudo_polytrope_1D::der_press_ent_p(double, const Param* ) const {
407 c_est_pas_fait("Pseudo_polytrope_1D::der_press_ent_p") ;
408 return 0. ;
409}
410
411double Pseudo_polytrope_1D::csound_square_ent_p(double ent, const Param*) const {
412 if (ent > ent_lim ) {
413 double nbar = nbar_ent_p(ent) ;
414 double xx = log(nbar*0.1) ;
415
416 double alpha = (*coefs)(n_coefs-1) ;
417 double sum_poly = 0., sum_der_poly = 0., sum_der2_poly = 0.;
418 for (int i=0; i < n_coefs-1; i++){
419 sum_poly += (*coefs)(i)*pow(xx, double(i));
420 sum_der_poly += (i == 0) ? 0. : double(i) * (*coefs)(i) * pow(xx, double(i-1)) ;
421 sum_der2_poly += (i < 2) ? 0. : double(i) * double(i-1) * (*coefs)(i) * pow(xx, double(i-2)) ;
422 }
423 double num = (alpha*(alpha+1.) * sum_poly + (2.*alpha+1.) * sum_der_poly + sum_der2_poly)*exp(alpha*xx) ;
424 double denom = 1. + mu_0 + ((alpha+1.) * sum_poly + sum_der_poly)*exp(alpha*xx) ;
425
426 return num/denom ;
427 }
428 else if ( (0 < ent) && (ent < ent_lim)){
429
430 return eos_low->csound_square_ent_p(ent) ;
431 }
432 else{
433 return 0 ;
434 }
435}
436
437}
Polytropic equation of state (relativistic case).
Definition eos.h:809
virtual int identify() const =0
Returns a number to identify the sub-classe of Eos the object belongs to.
virtual void sauve(FILE *) const
Save in a file.
Definition eos.C:189
Eos()
Standard constructor.
Definition eos.C:118
char name[100]
EOS name.
Definition eos.h:212
void set_name(const char *name_i)
Sets the EOS name.
Definition eos.C:173
Parameter storage.
Definition param.h:125
virtual double der_ener_ent_p(double ent, const Param *par=0x0) const
Computes the logarithmic derivative from the specific enthalpy.
virtual double der_nbar_ent_p(double ent, const Param *par=0x0) const
Computes the logarithmic derivative from the specific enthalpy.
virtual double der_press_ent_p(double ent, const Param *par=0x0) const
Computes the logarithmic derivative from the specific enthalpy.
virtual double csound_square_ent_p(double, const Param *) const
Computes the sound speed squared from the enthapy with extra parameters (virtual function implemente...
virtual ostream & operator>>(ostream &) const
Operator >>.
virtual double press_ent_p(double ent, const Param *par=0x0) const
Computes the pressure from the specific enthalpy.
void operator=(const Pseudo_polytrope_1D &)
Assignment to another Pseudo_polytrope_1D.
Pseudo_polytrope_1D(const Tbl &, double, double)
Standard constructor.
virtual bool operator==(const Eos &) const
Comparison operator (egality).
virtual void sauve(FILE *) const
Save in a file.
virtual double ener_ent_p(double ent, const Param *par=0x0) const
Computes the total energy density from the specific enthalpy.
virtual double nbar_ent_p(double ent, const Param *par=0x0) const
Computes the baryon density from the specific enthalpy.
virtual bool operator!=(const Eos &) const
Comparison operator (difference).
virtual ~Pseudo_polytrope_1D()
Destructor.
virtual int identify() const
Returns a number to identify the sub-classe of Eos the object belongs to.
Basic array class.
Definition tbl.h:161
int get_ndim() const
Gives the number of dimensions (ie dim.ndim).
Definition tbl.h:400
Cmp exp(const Cmp &)
Exponential.
Definition cmp_math.C:273
Tbl max(const Cmp &)
Maximum values of a Cmp in each domain.
Definition cmp_math.C:438
Cmp pow(const Cmp &, int)
Power .
Definition cmp_math.C:351
Cmp log(const Cmp &)
Neperian logarithm.
Definition cmp_math.C:299
void c_est_pas_fait(const char *)
Helpful function to say something is not implemented yet.
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