star_rot_global.C

00001 /*
00002  * Methods for computing global quantities within the class Star_rot
00003  *
00004  * (see file star_rot.h for documentation)
00005  */
00006 
00007 /*
00008  *   Copyright (c) 2010 Eric Gourgoulhon
00009  *
00010  *   This file is part of LORENE.
00011  *
00012  *   LORENE is free software; you can redistribute it and/or modify
00013  *   it under the terms of the GNU General Public License as published by
00014  *   the Free Software Foundation; either version 2 of the License, or
00015  *   (at your option) any later version.
00016  *
00017  *   LORENE is distributed in the hope that it will be useful,
00018  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020  *   GNU General Public License for more details.
00021  *
00022  *   You should have received a copy of the GNU General Public License
00023  *   along with LORENE; if not, write to the Free Software
00024  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025  *
00026  */
00027 
00028 
00029 char star_rot_global_C[] = "$Header: /cvsroot/Lorene/C++/Source/Star/star_rot_global.C,v 1.2 2010/01/25 22:33:35 e_gourgoulhon Exp $" ;
00030 
00031 /*
00032  * $Id: star_rot_global.C,v 1.2 2010/01/25 22:33:35 e_gourgoulhon Exp $
00033  * $Log: star_rot_global.C,v $
00034  * Revision 1.2  2010/01/25 22:33:35  e_gourgoulhon
00035  * Debugging...
00036  *
00037  * Revision 1.1  2010/01/25 18:15:52  e_gourgoulhon
00038  * First version.
00039  * 
00040  *
00041  *
00042  * $Header: /cvsroot/Lorene/C++/Source/Star/star_rot_global.C,v 1.2 2010/01/25 22:33:35 e_gourgoulhon Exp $
00043  *
00044  */
00045 
00046 // Headers C
00047 #include <stdlib.h>
00048 #include <math.h>
00049 
00050 // Headers Lorene
00051 #include "star_rot.h"
00052 #include "unites.h"
00053 
00054             //--------------------------//
00055             //  Stellar surface     //
00056             //--------------------------//
00057 
00058 const Itbl& Star_rot::l_surf() const {
00059 
00060     if (p_l_surf == 0x0) {    // a new computation is required
00061     
00062     assert(p_xi_surf == 0x0) ;  // consistency check
00063     
00064     int np = mp.get_mg()->get_np(0) ;   
00065     int nt = mp.get_mg()->get_nt(0) ;   
00066     
00067     p_l_surf = new Itbl(np, nt) ;
00068     p_xi_surf = new Tbl(np, nt) ;
00069     
00070     double ent0 = 0 ;   // definition of the surface
00071     double precis = 1.e-15 ; 
00072     int nitermax = 100 ; 
00073     int niter ; 
00074     
00075     (ent.get_spectral_va()).equipot(ent0, nzet, precis, nitermax, niter, *p_l_surf, 
00076             *p_xi_surf) ; 
00077     
00078     }
00079    
00080     return *p_l_surf ; 
00081     
00082 }
00083 
00084             //--------------------------//
00085             //  Baryon mass     //
00086             //--------------------------//
00087 
00088 double Star_rot::mass_b() const {
00089 
00090     if (p_mass_b == 0x0) {    // a new computation is required
00091     
00092     if (relativistic) {
00093 
00094         Scalar dens = a_car * bbb * gam_euler * nbar ;
00095         
00096         p_mass_b = new double( dens.integrale() ) ;
00097 
00098     }
00099     else{  // Newtonian case 
00100         assert(nbar.get_etat() == ETATQCQ) ; 
00101 
00102         p_mass_b = new double( nbar.integrale() ) ;
00103 
00104     }
00105 
00106     }
00107     
00108     return *p_mass_b ; 
00109 
00110 } 
00111 
00112 
00113             //----------------------------//
00114             //  Gravitational mass    //
00115             //----------------------------//
00116 
00117 double Star_rot::mass_g() const {
00118 
00119     if (p_mass_g == 0x0) {    // a new computation is required
00120     
00121     if (relativistic) {
00122 
00123         Scalar source = nn * (ener_euler + s_euler) 
00124                 + 2 * bbb * (ener_euler + press)
00125                     * tnphi * uuu ; 
00126         source = a_car * bbb * source ;
00127         source.std_spectral_base() ; 
00128 
00129         p_mass_g = new double( source.integrale() ) ;
00130 
00131 
00132     }
00133     else{  // Newtonian case 
00134         p_mass_g = new double( mass_b() ) ;   // in the Newtonian case
00135                             //  M_g = M_b
00136     }
00137     }
00138     
00139     return *p_mass_g ; 
00140 
00141 } 
00142         
00143             //----------------------------//
00144             //  Angular momentum      //
00145             //----------------------------//
00146 
00147 double Star_rot::angu_mom() const {
00148 
00149     if (p_angu_mom == 0x0) {    // a new computation is required
00150     
00151     Scalar dens = uuu ; 
00152 
00153     dens.mult_r() ;         //  Multiplication by
00154     dens.set_spectral_va() = (dens.get_spectral_va()).mult_st() ;   //    r sin(theta)
00155 
00156     if (relativistic) {
00157         dens = a_car * b_car * (ener_euler + press) * dens ; 
00158     }
00159     else {    // Newtonian case 
00160         dens = nbar * dens ; 
00161     }
00162 
00163     p_angu_mom = new double( dens.integrale() ) ;
00164 
00165     }
00166     
00167     return *p_angu_mom ; 
00168 
00169 }
00170 
00171 
00172             //----------------------------//
00173             //       T/W          //
00174             //----------------------------//
00175 
00176 double Star_rot::tsw() const {
00177 
00178     if (p_tsw == 0x0) {    // a new computation is required
00179     
00180     double tcin = 0.5 * omega * angu_mom() ;
00181     
00182     if (relativistic) {
00183         
00184         Scalar dens = a_car * bbb * gam_euler * ener ;
00185         double mass_p = dens.integrale() ; 
00186         
00187         p_tsw = new double( tcin / ( mass_p + tcin - mass_g() ) ) ;     
00188        
00189     }
00190     else {      // Newtonian case 
00191         Scalar dens = 0.5 * nbar * logn ;
00192         double wgrav = dens.integrale() ; 
00193         p_tsw = new double( tcin / fabs(wgrav) ) ;  
00194     }
00195 
00196     }
00197     
00198     return *p_tsw ; 
00199 
00200 }
00201 
00202 
00203             //----------------------------//
00204             //       GRV2         //
00205             //----------------------------//
00206 
00207 double Star_rot::grv2() const {
00208 
00209       using namespace Unites ;  
00210       if (p_grv2 == 0x0) {    // a new computation is required
00211     
00212     Scalar sou_m(mp) ; 
00213     if (relativistic) {
00214       sou_m =  2 * qpig * a_car * (press + (ener_euler+press)
00215                        * uuu*uuu ) ;
00216         }
00217     else {
00218       sou_m = 2 * qpig * (press + nbar * uuu*uuu ) ;
00219     }
00220     
00221     Vector dlogn = logn.derive_cov( mp.flat_met_spher() ) ; 
00222         Scalar sou_q =  1.5 * ak_car
00223       - dlogn(1)*dlogn(1) - dlogn(2)*dlogn(2) - dlogn(3)*dlogn(3) ; 
00224     
00225     p_grv2 = new double( double(1) - lambda_grv2(sou_m, sou_q) ) ; 
00226     
00227       }
00228     
00229       return *p_grv2 ; 
00230       
00231 }
00232 
00233 
00234             //----------------------------//
00235             //       GRV3         //
00236             //----------------------------//
00237 
00238 double Star_rot::grv3(ostream* ost) const {
00239 
00240   using namespace Unites ;  
00241   
00242   if (p_grv3 == 0x0) {    // a new computation is required
00243 
00244     Scalar source(mp) ; 
00245     
00246     // Gravitational term [cf. Eq. (43) of Gourgoulhon & Bonazzola
00247     // ------------------       Class. Quantum Grav. 11, 443 (1994)]
00248     
00249     Vector dlogn = logn.derive_cov( mp.flat_met_spher() ) ;
00250 
00251     if (relativistic) {
00252       Scalar alpha = dzeta - logn ; 
00253       Scalar bet = log( bbb ) ; 
00254       bet.std_spectral_base() ; 
00255       
00256       Vector dalpha = alpha.derive_cov( mp.flat_met_spher() ) ;
00257       Vector dbet = bet.derive_cov( mp.flat_met_spher() ) ;
00258 
00259       source = 0.75 * ak_car 
00260     - dlogn(1)*dlogn(1) - dlogn(2)*dlogn(2) - dlogn(3)*dlogn(3) 
00261     + 0.5 * ( dalpha(1)*dbet(1) + dalpha(2)*dbet(2) + dalpha(3)*dbet(3) ) ; 
00262       
00263       Scalar aa = alpha - 0.5 * bet ; 
00264       Scalar daadt = aa.srdsdt() ;  // 1/r d/dth
00265         
00266       // What follows is valid only for a mapping of class Map_radial : 
00267       const Map_radial* mpr = dynamic_cast<const Map_radial*>(&mp) ; 
00268       if (mpr == 0x0) {
00269     cout << "Star_rot::grv3: the mapping does not belong"
00270          << " to the class Map_radial !" << endl ; 
00271     abort() ; 
00272       }
00273       
00274       // Computation of 1/tan(theta) * 1/r daa/dtheta
00275       if (daadt.get_etat() == ETATQCQ) {
00276     Valeur& vdaadt = daadt.set_spectral_va() ; 
00277     vdaadt = vdaadt.ssint() ;   // division by sin(theta)
00278     vdaadt = vdaadt.mult_ct() ; // multiplication by cos(theta)
00279       }
00280       
00281       Scalar temp = aa.dsdr() + daadt ; 
00282       temp = ( bbb - a_car/bbb ) * temp ; 
00283       temp.std_spectral_base() ; 
00284       
00285       // Division by r 
00286       Valeur& vtemp = temp.set_spectral_va() ; 
00287       vtemp = vtemp.sx() ;    // division by xi in the nucleus
00288       // Id in the shells
00289       // division by xi-1 in the ZEC
00290       vtemp = (mpr->xsr) * vtemp ; // multiplication by xi/r in the nucleus
00291       //          by 1/r in the shells
00292       //          by r(xi-1) in the ZEC
00293       
00294       // In the ZEC, a multiplication by r has been performed instead
00295       //   of the division:             
00296       temp.set_dzpuis( temp.get_dzpuis() + 2 ) ;  
00297       
00298       source = bbb * source + 0.5 * temp ; 
00299       
00300     }
00301     else{
00302       source = - 0.5 * ( dlogn(1)*dlogn(1) + dlogn(2)*dlogn(2) + dlogn(3)*dlogn(3) ) ; 
00303     }
00304     
00305     source.std_spectral_base() ; 
00306     
00307     double int_grav = source.integrale() ; 
00308     
00309     // Matter term
00310     // -----------
00311     
00312     if (relativistic) {    
00313       source  = qpig * a_car * bbb * s_euler ;
00314     }
00315     else{
00316       source = qpig * ( 3 * press + nbar * uuu * uuu ) ; 
00317     }
00318     
00319     source.std_spectral_base() ; 
00320 
00321     double int_mat = source.integrale() ; 
00322     
00323     // Virial error
00324     // ------------
00325     if (ost != 0x0) {
00326       *ost << "Star_rot::grv3 : gravitational term : " << int_grav 
00327        << endl ;
00328       *ost << "Star_rot::grv3 : matter term :        " << int_mat 
00329        << endl ;
00330     }
00331     
00332     p_grv3 = new double( (int_grav + int_mat) / int_mat ) ;      
00333     
00334   }
00335   
00336   return *p_grv3 ; 
00337   
00338 }
00339 
00340 
00341             //----------------------------//
00342             //       R_circ       //
00343             //----------------------------//
00344 
00345 double Star_rot::r_circ() const {
00346 
00347     if (p_r_circ == 0x0) {    // a new computation is required
00348     
00349     // Index of the point at phi=0, theta=pi/2 at the surface of the star:
00350     const Mg3d* mg = mp.get_mg() ; 
00351     assert(mg->get_type_t() == SYM) ; 
00352     int l_b = nzet - 1 ; 
00353     int i_b = mg->get_nr(l_b) - 1 ; 
00354     int j_b = mg->get_nt(l_b) - 1 ; 
00355     int k_b = 0 ; 
00356     
00357     p_r_circ = new double( bbb.val_grid_point(l_b, k_b, j_b, i_b) * ray_eq() ) ; 
00358 
00359     }
00360     
00361     return *p_r_circ ; 
00362 
00363 }
00364 
00365 
00366             //----------------------------//
00367             //     Flattening         //
00368             //----------------------------//
00369 
00370 double Star_rot::aplat() const {
00371 
00372     if (p_aplat == 0x0) {    // a new computation is required
00373     
00374     p_aplat = new double( ray_pole() / ray_eq() ) ;      
00375 
00376     }
00377     
00378     return *p_aplat ; 
00379 
00380 }
00381 
00382 
00383             //----------------------------//
00384             //       Z_eq_f       //
00385             //----------------------------//
00386 
00387 double Star_rot::z_eqf() const {
00388 
00389     if (p_z_eqf == 0x0) {    // a new computation is required
00390     
00391     // Index of the point at phi=0, theta=pi/2 at the surface of the star:
00392     const Mg3d* mg = mp.get_mg() ; 
00393     assert(mg->get_type_t() == SYM) ; 
00394     int l_b = nzet - 1 ; 
00395     int i_b = mg->get_nr(l_b) - 1 ; 
00396     int j_b = mg->get_nt(l_b) - 1 ; 
00397     int k_b = 0 ; 
00398     
00399     double u_eq = uuu.val_grid_point(l_b, k_b, j_b, i_b) ; 
00400     double n_eq = nn.val_grid_point(l_b, k_b, j_b, i_b) ; 
00401     double nphi_eq = nphi.val_grid_point(l_b, k_b, j_b, i_b) ; 
00402     
00403     p_z_eqf = new double( sqrt((1.-u_eq)/(1.+u_eq)) 
00404                 / (n_eq + nphi_eq * r_circ() )
00405                   - 1. ) ;
00406     }
00407     
00408     return *p_z_eqf ; 
00409 
00410 }
00411             //----------------------------//
00412             //       Z_eq_b       //
00413             //----------------------------//
00414 
00415 double Star_rot::z_eqb() const {
00416 
00417     if (p_z_eqb == 0x0) {    // a new computation is required
00418     
00419     // Index of the point at phi=0, theta=pi/2 at the surface of the star:
00420     const Mg3d* mg = mp.get_mg() ; 
00421     assert(mg->get_type_t() == SYM) ; 
00422     int l_b = nzet - 1 ; 
00423     int i_b = mg->get_nr(l_b) - 1 ; 
00424     int j_b = mg->get_nt(l_b) - 1 ; 
00425     int k_b = 0 ; 
00426     
00427     double u_eq = uuu.val_grid_point(l_b, k_b, j_b, i_b) ; 
00428     double n_eq = nn.val_grid_point(l_b, k_b, j_b, i_b) ; 
00429     double nphi_eq = nphi.val_grid_point(l_b, k_b, j_b, i_b) ; 
00430     
00431     p_z_eqb = new double(  sqrt((1.+u_eq)/(1.-u_eq)) 
00432                 / (n_eq - nphi_eq * r_circ() )
00433                   - 1. )  ;
00434 
00435     }
00436     
00437     return *p_z_eqb ; 
00438 
00439 }
00440 
00441 
00442             //----------------------------//
00443             //       Z_pole       //
00444             //----------------------------//
00445 
00446 double Star_rot::z_pole() const {
00447 
00448     if (p_z_pole == 0x0) {    // a new computation is required
00449     
00450     double n_pole = nn.val_point(ray_pole(), 0., 0.) ; 
00451     
00452     p_z_pole = new double(  1. / n_pole - 1. ) ; 
00453 
00454     }
00455     
00456     return *p_z_pole ; 
00457 
00458 }
00459 
00460 
00461             //----------------------------//
00462             //     Quadrupole moment      //
00463             //----------------------------//
00464 
00465 double Star_rot::mom_quad() const {
00466 
00467   using namespace Unites ;
00468     if (p_mom_quad == 0x0) {    // a new computation is required
00469     
00470     // Source for of the Poisson equation for nu
00471     // -----------------------------------------
00472 
00473     Scalar source(mp) ; 
00474     
00475     if (relativistic) {
00476         Scalar bet = log(bbb) ; 
00477         bet.std_spectral_base() ; 
00478         
00479         Vector dlogn = logn.derive_cov( mp.flat_met_spher() ) ;
00480         Vector dlogn_bet = dlogn + bet.derive_cov( mp.flat_met_spher() ) ;
00481 
00482         source =  qpig * a_car *( ener_euler + s_euler ) + ak_car 
00483           - dlogn(1)*dlogn_bet(1) - dlogn(2)*dlogn_bet(2) - dlogn(3)*dlogn_bet(3)   ; 
00484     }
00485     else {
00486         source = qpig * nbar ; 
00487     }
00488     
00489     source.std_spectral_base() ;
00490 
00491     // Multiplication by -r^2 P_2(cos(theta))
00492     //  [cf Eq.(7) of Salgado et al. Astron. Astrophys. 291, 155 (1994) ]
00493     // ------------------------------------------------------------------
00494     
00495     // Multiplication by r^2 : 
00496     // ----------------------
00497     source.mult_r() ; 
00498     source.mult_r() ; 
00499     if (source.check_dzpuis(2)) {
00500         source.inc_dzpuis(2) ; 
00501     }
00502         
00503     // Muliplication by cos^2(theta) :
00504     // -----------------------------
00505     Scalar temp = source ; 
00506     
00507     // What follows is valid only for a mapping of class Map_radial : 
00508     assert( dynamic_cast<const Map_radial*>(&mp) != 0x0 ) ; 
00509         
00510     if (temp.get_etat() == ETATQCQ) {
00511         Valeur& vtemp = temp.set_spectral_va() ; 
00512         vtemp = vtemp.mult_ct() ;   // multiplication by cos(theta)
00513         vtemp = vtemp.mult_ct() ;   // multiplication by cos(theta)
00514     }
00515     
00516     // Muliplication by -P_2(cos(theta)) :
00517     // ----------------------------------
00518     source = 0.5 * source - 1.5 * temp ; 
00519     
00520     // Final result
00521     // ------------
00522 
00523     p_mom_quad = new double( source.integrale() / qpig ) ;   
00524 
00525     }
00526     
00527     return *p_mom_quad ; 
00528 
00529 }
00530 
00531 
00532 
00533 

Generated on Tue Feb 7 01:35:20 2012 for LORENE by  doxygen 1.4.6