LORENE
star_equil_spher.C
1/*
2 * Method of class Star to compute a static spherical configuration.
3 *
4 * (see file star.h for documentation).
5 *
6 */
7
8/*
9 * Copyright (c) 2004 Francois Limousin
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: star_equil_spher.C,v 1.17 2017/10/20 13:54:54 j_novak Exp $
34 * $Log: star_equil_spher.C,v $
35 * Revision 1.17 2017/10/20 13:54:54 j_novak
36 * Adaptation of the method to be used within nrotstar.
37 *
38 * Revision 1.16 2016/12/05 16:18:15 j_novak
39 * Suppression of some global variables (file names, loch, ...) to prevent redefinitions
40 *
41 * Revision 1.15 2014/10/13 08:53:39 j_novak
42 * Lorene classes and functions now belong to the namespace Lorene.
43 *
44 * Revision 1.14 2010/10/18 20:16:10 m_bejger
45 * Commented-out the reevaluation of the mapping for the case of many domains inside the star
46 *
47 * Revision 1.13 2010/10/18 18:56:33 m_bejger
48 * Changed to allow initial data with more than one domain in the star
49 *
50 * Revision 1.12 2005/09/14 12:30:52 f_limousin
51 * Saving of fields lnq and logn in class Star.
52 *
53 * Revision 1.11 2005/09/13 19:38:31 f_limousin
54 * Reintroduction of the resolution of the equations in cartesian coordinates.
55 *
56 * Revision 1.10 2005/02/17 17:32:35 f_limousin
57 * Change the name of some quantities to be consistent with other classes
58 * (for instance nnn is changed to nn, shift to beta, beta to lnq...)
59 *
60 * Revision 1.9 2004/06/22 12:45:31 f_limousin
61 * Improve the convergence
62 *
63 * Revision 1.8 2004/06/07 16:27:47 f_limousin
64 * Add the computation of virial error.
65 *
66 * Revision 1.6 2004/04/08 16:33:42 f_limousin
67 * The new variable is ln(Q) instead of Q=psi^2*N. It improves the
68 * convergence of the code.
69 *
70 * Revision 1.5 2004/03/25 10:29:26 j_novak
71 * All LORENE's units are now defined in the namespace Unites (in file unites.h).
72 *
73 * Revision 1.4 2004/02/27 09:57:55 f_limousin
74 * We now update the metric gamma at the end of this routine for
75 * the calculus of mass_b and mass_g.
76 *
77 * Revision 1.3 2004/02/21 17:05:13 e_gourgoulhon
78 * Method Scalar::point renamed Scalar::val_grid_point.
79 * Method Scalar::set_point renamed Scalar::set_grid_point.
80 *
81 * Revision 1.2 2004/01/20 15:20:35 f_limousin
82 * First version
83 *
84 *
85 * $Header: /cvsroot/Lorene/C++/Source/Star/star_equil_spher.C,v 1.17 2017/10/20 13:54:54 j_novak Exp $
86 *
87 */
88
89// Headers C
90#include "math.h"
91
92// Headers Lorene
93#include "tenseur.h"
94#include "star_rot.h"
95#include "param.h"
96#include "graphique.h"
97#include "nbr_spx.h"
98#include "unites.h"
99
100namespace Lorene {
101void Star::equilibrium_spher(double ent_c, double precis, const Tbl* pent_limit){
102
103 // Fundamental constants and units
104 // -------------------------------
105 using namespace Unites ;
106
107 // Initializations
108 // ---------------
109
110 const Mg3d* mg = mp.get_mg() ;
111 int nz = mg->get_nzone() ; // total number of domains
112
113 // Index of the point at phi=0, theta=pi/2 at the surface of the star:
114 int l_b = nzet - 1 ;
115 int i_b = mg->get_nr(l_b) - 1 ;
116 int j_b = mg->get_nt(l_b) - 1 ;
117 int k_b = 0 ;
118
119 // Value of the enthalpy defining the surface of the star
120 double ent_b = 0 ;
121
122 // Initialization of the enthalpy field to the constant value ent_c :
123
124 ent = ent_c ;
125 ent.annule(nzet, nz-1) ;
126
127
128 // Corresponding profiles of baryon density, energy density and pressure
129
131
132 Scalar a_car(mp) ;
133 a_car = 1 ;
134 lnq = 0 ;
135 lnq.std_spectral_base() ;
136
137 // Auxiliary quantities
138 // --------------------
139
140 // Affine mapping for solving the Poisson equations
141 Map_af mpaff(mp);
142
143 Param par_nul ; // Param (null) for Map_af::poisson.
144
145 Scalar ent_jm1(mp) ; // Enthalpy at previous step
146 ent_jm1 = 0 ;
147
148 Scalar source(mp) ;
149 Scalar logn_quad(mp) ;
150 Scalar logn_mat(mp) ;
151 logn_mat = 0 ;
152 logn = 0 ;
153 logn_quad = 0 ;
154
155 Scalar dlogn(mp) ;
156 Scalar dlnq(mp) ;
157
158 double diff_ent = 1 ;
159 int mermax = 200 ; // Max number of iterations
160
161 //=========================================================================
162 // Start of iteration
163 //=========================================================================
164
165 for(int mer=0 ; (diff_ent > precis) && (mer<mermax) ; mer++ ) {
166
167 double alpha_r = 1 ;
168
169 cout << "-----------------------------------------------" << endl ;
170 cout << "step: " << mer << endl ;
171 cout << "alpha_r: " << alpha_r << endl ;
172 cout << "diff_ent = " << diff_ent << endl ;
173
174 //-----------------------------------------------------
175 // Resolution of Poisson equation for ln(N)
176 //-----------------------------------------------------
177
178 // Matter part of ln(N)
179 // --------------------
180
181 source = a_car * (ener + 3.*press) ;
182
183 source.set_dzpuis(4) ;
184
185 Cmp source_logn_mat (source) ;
186 Cmp logn_mat_cmp (logn_mat) ;
187 logn_mat_cmp.set_etat_qcq() ;
188
189 mpaff.poisson(source_logn_mat, par_nul, logn_mat_cmp) ;
190
191 logn_mat = logn_mat_cmp ;
192
193 // NB: at this stage logn is in machine units, not in c^2
194
195 // Quadratic part of ln(N)
196 // -----------------------
197
198 mpaff.dsdr(logn, dlogn) ;
199 mpaff.dsdr(lnq, dlnq) ;
200
201 source = - dlogn * dlnq ;
202
203 Cmp source_logn_quad (source) ;
204 Cmp logn_quad_cmp (logn_quad) ;
205 logn_quad_cmp.set_etat_qcq() ;
206
207 mpaff.poisson(source_logn_quad, par_nul, logn_quad_cmp) ;
208
209 logn_quad = logn_quad_cmp ;
210
211
212 //-----------------------------------------------------
213 // Computation of the new radial scale
214 //-----------------------------------------------------
215
216 // alpha_r (r = alpha_r r') is determined so that the enthalpy
217 // takes the requested value ent_b at the stellar surface
218
219 double nu_mat0_b = logn_mat.val_grid_point(l_b, k_b, j_b, i_b) ;
220 double nu_mat0_c = logn_mat.val_grid_point(0, 0, 0, 0) ;
221
222 double nu_quad0_b = logn_quad.val_grid_point(l_b, k_b, j_b, i_b) ;
223 double nu_quad0_c = logn_quad.val_grid_point(0, 0, 0, 0) ;
224
225 double alpha_r2 = ( ent_c - ent_b - nu_quad0_b + nu_quad0_c )
226 / ( qpig*(nu_mat0_b - nu_mat0_c) ) ;
227
228 alpha_r = sqrt(alpha_r2) ;
229
230 // One domain inside the star:
231 // ---------------------------
232 if(nzet==1) mpaff.homothetie( alpha_r ) ;
233
234 //--------------------
235 // First integral
236 //--------------------
237
238 // Gravitation potential in units c^2 :
239 logn_mat = alpha_r2*qpig * logn_mat ;
240 logn = logn_mat + logn_quad ;
241
242 // Enthalpy in all space
243 double logn_c = logn.val_grid_point(0, 0, 0, 0) ;
244 ent = ent_c - logn + logn_c ;
245
246 // Two or more domains inside the star:
247 // ------------------------------------
248
249 if(nzet>1) {
250
251 // Parameters for the function Map_et::adapt
252 // -----------------------------------------
253
254 Param par_adapt ;
255 int nitermax = 100 ;
256 int niter ;
257 int adapt_flag = 1 ; // 1 = performs the full computation,
258 // 0 = performs only the rescaling by
259 // the factor alpha_r
260 int nz_search = nzet + 1 ; // Number of domains for searching the enthalpy
261 // isosurfaces
262
263 int nzadapt = nzet ;
264
265 //cout << "no. of domains where the ent adjustment will be done: " << nzet << endl ;
266 //cout << "ent limits: " << ent_limit << endl ;
267
268 double precis_adapt = 1.e-14 ;
269
270 double reg_map = 1. ; // 1 = regular mapping, 0 = contracting mapping
271
272 par_adapt.add_int(nitermax, 0) ; // maximum number of iterations to
273 // locate zeros by the secant method
274 par_adapt.add_int(nzadapt, 1) ; // number of domains where the adjustment
275 // to the isosurfaces of ent is to be
276 // performed
277 par_adapt.add_int(nz_search, 2) ; // number of domains to search for
278 // the enthalpy isosurface
279 par_adapt.add_int(adapt_flag, 3) ; // 1 = performs the full computation,
280 // 0 = performs only the rescaling by
281 // the factor alpha_r
282 par_adapt.add_int(j_b, 4) ; // theta index of the collocation point
283 // (theta_*, phi_*)
284 par_adapt.add_int(k_b, 5) ; // theta index of the collocation point
285 // (theta_*, phi_*)
286
287 par_adapt.add_int_mod(niter, 0) ; // number of iterations actually used in
288 // the secant method
289
290 par_adapt.add_double(precis_adapt, 0) ; // required absolute precision in
291 // the determination of zeros by
292 // the secant method
293 par_adapt.add_double(reg_map, 1) ; // 1. = regular mapping, 0 = contracting mapping
294
295 par_adapt.add_double(alpha_r, 2) ; // factor by which all the radial
296 // distances will be multiplied
297
298 // Enthalpy values for the adaptation
299 Tbl ent_limit(nzet) ;
300 if (pent_limit != 0x0) ent_limit = *pent_limit ;
301
302 par_adapt.add_tbl(ent_limit, 0) ; // array of values of the field ent
303 // to define the isosurfaces.
304
305 double* bornes = new double[nz+1] ;
306 bornes[0] = 0. ;
307
308 for(int l=0; l<nz; l++) {
309
310 bornes[l+1] = mpaff.get_alpha()[l] + mpaff.get_beta()[l] ;
311
312 }
313 bornes[nz] = __infinity ;
314
315 Map_et mp0(*mg, bornes) ;
316
317 mp0 = mpaff;
318 mp0.adapt(ent, par_adapt) ;
319
320 //Map_af mpaff_prev (mpaff) ;
321
322 double alphal, betal ;
323
324 for(int l=0; l<nz; l++) {
325
326 alphal = mp0.get_alpha()[l] ;
327 betal = mp0.get_beta()[l] ;
328
329 mpaff.set_alpha(alphal, l) ;
330 mpaff.set_beta(betal, l) ;
331
332 }
333
334
335 // testing printout
336 //int num_r1 = mg->get_nr(0) - 1;
337 //cout << "Pressure difference:" << press.val_grid_point(0,0,0,num_r1)
338 //- press.val_grid_point(1,0,0,0) << endl ;
339 //cout << "Difference in enthalpies at the domain boundary:" << endl ;
340 //cout << ent.val_grid_point(0,0,0,num_r1) << endl ;
341 //cout << ent.val_grid_point(1,0,0,0) << endl ;
342
343 //cout << "Enthalpy difference: " << ent.val_grid_point(0,0,0,num_r1)
344 //- ent.val_grid_point(1,0,0,0) << endl ;
345
346 // Computation of the enthalpy at the new grid points
347 //----------------------------------------------------
348 //mpaff.reevaluate(&mpaff_prev, nzet+1, ent) ;
349
350 }
351
352
353 //---------------------
354 // Equation of state
355 //---------------------
356
358
359 //---------------------
360 // Equation for lnq_auto
361 //---------------------
362
363 mpaff.dsdr(logn, dlogn) ;
364 mpaff.dsdr(lnq, dlnq) ;
365
366 source = 3 * qpig * a_car * press ;
367
368 source = source - 0.5 * ( dlnq * dlnq + dlogn * dlogn ) ;
369
370 source.std_spectral_base() ;
371 Cmp source_lnq (source) ;
372 Cmp lnq_cmp (logn_quad) ;
373 lnq_cmp.set_etat_qcq() ;
374
375 mpaff.poisson(source_lnq, par_nul, lnq_cmp) ;
376
377 lnq = lnq_cmp ;
378
379 // Metric coefficient psi4 update
380
381 nn = exp( logn ) ;
382 nn.std_spectral_base() ;
383
384 Scalar qq = exp( lnq ) ;
385 qq.std_spectral_base() ;
386
387 a_car = qq * qq / ( nn * nn ) ;
388 a_car.std_spectral_base() ;
389
390 // Relative difference with enthalpy at the previous step
391 // ------------------------------------------------------
392
393 diff_ent = norme( diffrel(ent, ent_jm1) ) / nzet ;
394
395 // Next step
396 // ---------
397
398 ent_jm1 = ent ;
399
400
401 } // End of iteration loop
402
403 //=========================================================================
404 // End of iteration
405 //=========================================================================
406
407 // The mapping is transfered to that of the star:
408 // ----------------------------------------------
409 mp = mpaff ;
410
411 // Sets value to all the Tenseur's of the star
412 // -------------------------------------------
413
414 nn = exp( logn ) ;
415 nn.std_spectral_base() ;
416
417 Scalar qq = exp( lnq ) ;
418 qq.std_spectral_base() ;
419
420 a_car = qq * qq / ( nn * nn ) ;
421
422 Sym_tensor gamma_cov(mp, COV, mp.get_bvect_cart()) ;
423 gamma_cov.set_etat_zero() ;
424
425 for (int i=1; i<=3; i++){
426 gamma_cov.set(i,i) = a_car ;
427 }
428 gamma = gamma_cov ;
429
430 // ... hydro
431 ent.annule(nzet, nz-1) ; // enthalpy set to zero at the exterior of
432 // the star
433 ener_euler = ener ;
434 s_euler = 3 * press ;
435 gam_euler = 1 ;
436 for(int i=1; i<=3; i++) u_euler.set(i) = 0 ;
437
438 Star_rot* p_star_rot = dynamic_cast<Star_rot*>(this) ;
439 if ( p_star_rot != 0x0) {
440 p_star_rot->a_car = a_car ;
441 p_star_rot->bbb = qq / nn ;
442 p_star_rot->b_car = p_star_rot->bbb * p_star_rot->bbb ;
443 p_star_rot->dzeta = lnq ;
444 }
445
446 // Info printing
447 // -------------
448
449 cout << endl
450 << "Characteristics of the star obtained by Etoile::equilibrium_spher : "
451 << endl
452 << "-----------------------------------------------------------------"
453 << endl ;
454
455 double ray = mp.val_r(l_b, 1., M_PI/2., 0) ;
456 cout << "Coordinate radius : " << ray / km << " km" << endl ;
457
458 double rcirc = ray * sqrt(a_car.val_grid_point(l_b, k_b, j_b, i_b) ) ;
459
460 double compact = qpig/(4.*M_PI) * mass_g() / rcirc ;
461
462 cout << "Circumferential radius R : " << rcirc/km << " km" << endl ;
463 cout << "Baryon mass : " << mass_b()/msol << " Mo" << endl ;
464 cout << "Gravitational mass M : " << mass_g()/msol << " Mo" << endl ;
465 cout << "Compacity parameter GM/(c^2 R) : " << compact << endl ;
466
467 //-----------------
468 // Virial theorem
469 //-----------------
470
471 //... Pressure term
472
473 source = qpig * a_car * sqrt(a_car) * s_euler ;
474 source.std_spectral_base() ;
475 double vir_mat = source.integrale() ;
476
477 //... Gravitational term
478
479 Scalar tmp = lnq - logn ;
480
481 source = - ( logn.dsdr() * logn.dsdr()
482 - 0.5 * tmp.dsdr() * tmp.dsdr() )
483 * sqrt(a_car) ;
484
485 source.std_spectral_base() ;
486 double vir_grav = source.integrale() ;
487
488 //... Relative error on the virial identity GRV3
489
490 double grv3 = ( vir_mat + vir_grav ) / vir_mat ;
491
492 cout << "Virial theorem GRV3 : " << endl ;
493 cout << " 3P term : " << vir_mat << endl ;
494 cout << " grav. term : " << vir_grav << endl ;
495 cout << " relative error : " << grv3 << endl ;
496
497 // To be compatible with class Etoile :
498 //logn = logn - logn_quad ;
499
500
501}
502}
Component of a tensorial field *** DEPRECATED : use class Scalar instead ***.
Definition cmp.h:446
void set_etat_qcq()
Sets the logical state to ETATQCQ (ordinary state).
Definition cmp.C:307
Affine radial mapping.
Definition map.h:2042
const double * get_beta() const
Returns the pointer on the array beta.
Definition map_af.C:608
const double * get_alpha() const
Returns the pointer on the array alpha.
Definition map_af.C:604
void set_beta(double beta0, int l)
Modifies the value of in domain no. l.
Definition map_af.C:768
virtual void homothetie(double lambda)
Sets a new radial scale.
Definition map_af.C:664
virtual void poisson(const Cmp &source, Param &par, Cmp &uu) const
Computes the solution of a scalar Poisson equation.
virtual void dsdr(const Cmp &ci, Cmp &resu) const
Computes of a Cmp.
void set_alpha(double alpha0, int l)
Modifies the value of in domain no. l.
Definition map_af.C:757
Radial mapping of rather general form.
Definition map.h:2770
const double * get_alpha() const
Returns a pointer on the array alpha (values of in each domain).
Definition map_et.C:1049
const double * get_beta() const
Returns a pointer on the array beta (values of in each domain).
Definition map_et.C:1053
virtual void adapt(const Cmp &ent, const Param &par, int nbr_filtre=0)
Adaptation of the mapping to a given scalar field.
Multi-domain grid.
Definition grilles.h:279
int get_nt(int l) const
Returns the number of points in the co-latitude direction ( ) in domain no. l.
Definition grilles.h:474
int get_nzone() const
Returns the number of domains.
Definition grilles.h:465
int get_nr(int l) const
Returns the number of points in the radial direction ( ) in domain no. l.
Definition grilles.h:469
Parameter storage.
Definition param.h:125
void add_double(const double &x, int position=0)
Adds the the address of a new double to the list.
Definition param.C:318
void add_int_mod(int &n, int position=0)
Adds the address of a new modifiable int to the list.
Definition param.C:388
void add_int(const int &n, int position=0)
Adds the address of a new int to the list.
Definition param.C:249
void add_tbl(const Tbl &ti, int position=0)
Adds the address of a new Tbl to the list.
Definition param.C:525
Tensor field of valence 0 (or component of a tensorial field).
Definition scalar.h:393
double integrale() const
Computes the integral over all space of *this .
virtual void std_spectral_base()
Sets the spectral bases of the Valeur va to the standard ones for a scalar field.
Definition scalar.C:790
double val_grid_point(int l, int k, int j, int i) const
Returns the value of the field at a specified grid point.
Definition scalar.h:643
const Scalar & dsdr() const
Returns of *this .
void set_dzpuis(int)
Modifies the dzpuis flag.
Definition scalar.C:814
Class for isolated rotating stars.
Definition star_rot.h:98
Scalar b_car
Square of the metric factor B.
Definition star_rot.h:122
Scalar bbb
Metric factor B.
Definition star_rot.h:119
Scalar dzeta
Metric potential .
Definition star_rot.h:146
Scalar a_car
Square of the metric factor A.
Definition star_rot.h:116
Scalar ener
Total energy density in the fluid frame.
Definition star.h:193
virtual double mass_g() const =0
Gravitational mass.
Scalar logn
Logarithm of the lapse N .
Definition star.h:222
Scalar nn
Lapse function N .
Definition star.h:225
virtual void equilibrium_spher(double ent_c, double precis=1.e-14, const Tbl *pent_limit=0x0)
Computes a spherical static configuration.
Scalar ener_euler
Total energy density in the Eulerian frame.
Definition star.h:198
void equation_of_state()
Computes the proper baryon and energy density, as well as pressure from the enthalpy.
Definition star.C:465
Scalar gam_euler
Lorentz factor between the fluid and Eulerian observers.
Definition star.h:204
Scalar s_euler
Trace of the stress scalar in the Eulerian frame.
Definition star.h:201
Metric gamma
3-metric
Definition star.h:235
Scalar press
Fluid pressure.
Definition star.h:194
Scalar ent
Log-enthalpy.
Definition star.h:190
Vector u_euler
Fluid 3-velocity with respect to the Eulerian observer.
Definition star.h:207
Map & mp
Mapping associated with the star.
Definition star.h:180
int nzet
Number of domains of *mp occupied by the star.
Definition star.h:183
virtual double mass_b() const =0
Baryon mass.
Class intended to describe valence-2 symmetric tensors.
Definition sym_tensor.h:226
Basic array class.
Definition tbl.h:161
Cmp sqrt(const Cmp &)
Square root.
Definition cmp_math.C:223
Cmp exp(const Cmp &)
Exponential.
Definition cmp_math.C:273
Tbl diffrel(const Cmp &a, const Cmp &b)
Relative difference between two Cmp (norme version).
Definition cmp_math.C:507
Tbl norme(const Cmp &)
Sums of the absolute values of all the values of the Cmp in each domain.
Definition cmp_math.C:484
virtual void set_etat_zero()
Sets the logical state of all components to ETATZERO (zero state).
Definition tensor.C:506
Scalar & set(const Itbl &ind)
Returns the value of a component (read/write version).
Definition tensor.C:663
Lorene prototypes.
Definition app_hor.h:67
Standard units of space, time and mass.