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