et_rot_global.C

00001 /*
00002  * Methods for computing global quantities within the class Etoile_rot
00003  *
00004  * (see file etoile.h for documentation)
00005  */
00006 
00007 /*
00008  *   Copyright (c) 2000-2001 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 et_rot_global_C[] = "$Header: /cvsroot/Lorene/C++/Source/Etoile/et_rot_global.C,v 1.4 2004/03/25 10:29:06 j_novak Exp $" ;
00030 
00031 /*
00032  * $Id: et_rot_global.C,v 1.4 2004/03/25 10:29:06 j_novak Exp $
00033  * $Log: et_rot_global.C,v $
00034  * Revision 1.4  2004/03/25 10:29:06  j_novak
00035  * All LORENE's units are now defined in the namespace Unites (in file unites.h).
00036  *
00037  * Revision 1.3  2003/11/03 16:47:13  e_gourgoulhon
00038  * Corrected error in grv2() in the Newtonian case.
00039  *
00040  * Revision 1.2  2002/04/05 09:09:37  j_novak
00041  * The inversion of the EOS for 2-fluids polytrope has been modified.
00042  * Some errors in the determination of the surface were corrected.
00043  *
00044  * Revision 1.1.1.1  2001/11/20 15:19:28  e_gourgoulhon
00045  * LORENE
00046  *
00047  * Revision 1.5  2000/11/19  18:52:09  eric
00048  * grv2() operationnelle.
00049  *
00050  * Revision 1.4  2000/10/12  15:34:55  eric
00051  * Calcul de la masse grav, de GRV3 et du moment quadrupolaire.
00052  *
00053  * Revision 1.3  2000/08/31  11:25:58  eric
00054  * *** empty log message ***
00055  *
00056  * Revision 1.2  2000/08/25  12:28:16  eric
00057  * *** empty log message ***
00058  *
00059  * Revision 1.1  2000/07/20  15:32:56  eric
00060  * Initial revision
00061  *
00062  *
00063  * $Header: /cvsroot/Lorene/C++/Source/Etoile/et_rot_global.C,v 1.4 2004/03/25 10:29:06 j_novak Exp $
00064  *
00065  */
00066 
00067 // Headers C
00068 #include <stdlib.h>
00069 #include <math.h>
00070 
00071 // Headers Lorene
00072 #include "etoile.h"
00073 #include "unites.h"
00074 
00075             //--------------------------//
00076             //  Stellar surface     //
00077             //--------------------------//
00078 
00079 const Itbl& Etoile_rot::l_surf() const {
00080 
00081     if (p_l_surf == 0x0) {    // a new computation is required
00082     
00083     assert(p_xi_surf == 0x0) ;  // consistency check
00084     
00085     int np = mp.get_mg()->get_np(0) ;   
00086     int nt = mp.get_mg()->get_nt(0) ;   
00087     
00088     p_l_surf = new Itbl(np, nt) ;
00089     p_xi_surf = new Tbl(np, nt) ;
00090     
00091     double ent0 = 0 ;   // definition of the surface
00092     double precis = 1.e-15 ; 
00093     int nitermax = 100 ; 
00094     int niter ; 
00095     
00096     (ent().va).equipot(ent0, nzet, precis, nitermax, niter, *p_l_surf, 
00097             *p_xi_surf) ; 
00098     
00099     }
00100    
00101     return *p_l_surf ; 
00102     
00103 }
00104 
00105             //--------------------------//
00106             //  Baryon mass     //
00107             //--------------------------//
00108 
00109 double Etoile_rot::mass_b() const {
00110 
00111     if (p_mass_b == 0x0) {    // a new computation is required
00112     
00113     if (relativistic) {
00114 
00115         Cmp dens = a_car() * bbb() * gam_euler() * nbar() ;
00116         
00117         dens.std_base_scal() ; 
00118 
00119         p_mass_b = new double( dens.integrale() ) ;
00120 
00121 
00122     }
00123     else{  // Newtonian case 
00124         assert(nbar.get_etat() == ETATQCQ) ; 
00125 
00126         p_mass_b = new double( nbar().integrale() ) ;
00127 
00128     }
00129 
00130     }
00131     
00132     return *p_mass_b ; 
00133 
00134 } 
00135 
00136 
00137             //----------------------------//
00138             //  Gravitational mass    //
00139             //----------------------------//
00140 
00141 double Etoile_rot::mass_g() const {
00142 
00143     if (p_mass_g == 0x0) {    // a new computation is required
00144     
00145     if (relativistic) {
00146 
00147         Tenseur source = nnn * (ener_euler + s_euler) 
00148                 + 2 * bbb * (ener_euler + press)
00149                     * tnphi * uuu ; 
00150         source = a_car * bbb * source ;
00151 
00152         source.set_std_base() ;
00153 
00154         p_mass_g = new double( source().integrale() ) ;
00155 
00156 
00157     }
00158     else{  // Newtonian case 
00159         p_mass_g = new double( mass_b() ) ;   // in the Newtonian case
00160                             //  M_g = M_b
00161     }
00162     }
00163     
00164     return *p_mass_g ; 
00165 
00166 } 
00167         
00168             //----------------------------//
00169             //  Angular momentum      //
00170             //----------------------------//
00171 
00172 double Etoile_rot::angu_mom() const {
00173 
00174     if (p_angu_mom == 0x0) {    // a new computation is required
00175     
00176     Cmp dens = uuu() ; 
00177 
00178     dens.mult_r() ;         //  Multiplication by
00179     dens.va = (dens.va).mult_st() ; //    r sin(theta)
00180 
00181     if (relativistic) {
00182         dens = a_car() * b_car() * (ener_euler() + press()) 
00183             * dens ; 
00184     }
00185     else {    // Newtonian case 
00186         dens = nbar() * dens ; 
00187     }
00188 
00189     dens.std_base_scal() ; 
00190 
00191     p_angu_mom = new double( dens.integrale() ) ;
00192 
00193     }
00194     
00195     return *p_angu_mom ; 
00196 
00197 }
00198 
00199 
00200             //----------------------------//
00201             //       T/W          //
00202             //----------------------------//
00203 
00204 double Etoile_rot::tsw() const {
00205 
00206     if (p_tsw == 0x0) {    // a new computation is required
00207     
00208     double tcin = 0.5 * omega * angu_mom() ;
00209     
00210     if (relativistic) {
00211         
00212         Cmp dens = a_car() * bbb() * gam_euler() * ener() ;
00213         dens.std_base_scal() ; 
00214         double mass_p = dens.integrale() ; 
00215         
00216         p_tsw = new double( tcin / ( mass_p + tcin - mass_g() ) ) ;     
00217        
00218     }
00219     else {      // Newtonian case 
00220         Cmp dens = 0.5 * nbar() * logn() ;
00221         dens.std_base_scal() ; 
00222         double wgrav = dens.integrale() ; 
00223         p_tsw = new double( tcin / fabs(wgrav) ) ;  
00224     }
00225 
00226 
00227     }
00228     
00229     return *p_tsw ; 
00230 
00231 }
00232 
00233 
00234             //----------------------------//
00235             //       GRV2         //
00236             //----------------------------//
00237 
00238 double Etoile_rot::grv2() const {
00239 
00240       using namespace Unites ;  
00241       if (p_grv2 == 0x0) {    // a new computation is required
00242     
00243     Tenseur sou_m(mp) ; 
00244     if (relativistic) {
00245       sou_m =  2 * qpig * a_car * (press + (ener_euler+press)
00246                        * uuu*uuu ) ;
00247         }
00248     else {
00249       sou_m = 2 * qpig * (press + nbar * uuu*uuu ) ;
00250     }
00251     
00252         Tenseur sou_q =  1.5 * ak_car
00253       - flat_scalar_prod(logn.gradient_spher(),
00254                  logn.gradient_spher() ) ;  
00255     
00256     p_grv2 = new double( double(1) - lambda_grv2(sou_m(), sou_q()) ) ; 
00257     
00258       }
00259     
00260       return *p_grv2 ; 
00261       
00262 }
00263 
00264 
00265             //----------------------------//
00266             //       GRV3         //
00267             //----------------------------//
00268 
00269 double Etoile_rot::grv3(ostream* ost) const {
00270 
00271   using namespace Unites ;  
00272   
00273   if (p_grv3 == 0x0) {    // a new computation is required
00274 
00275     Tenseur source(mp) ; 
00276     
00277     // Gravitational term [cf. Eq. (43) of Gourgoulhon & Bonazzola
00278     // ------------------       Class. Quantum Grav. 11, 443 (1994)]
00279     
00280     if (relativistic) {
00281       Tenseur alpha = dzeta - logn ; 
00282       Tenseur beta = log( bbb ) ; 
00283       beta.set_std_base() ; 
00284       
00285       source = 0.75 * ak_car 
00286     - flat_scalar_prod(logn.gradient_spher(),
00287                logn.gradient_spher() )
00288     + 0.5 * flat_scalar_prod(alpha.gradient_spher(),
00289                  beta.gradient_spher() ) ; 
00290       
00291       Cmp aa = alpha() - 0.5 * beta() ; 
00292       Cmp daadt = aa.srdsdt() ; // 1/r d/dth
00293         
00294       // What follows is valid only for a mapping of class Map_radial : 
00295       const Map_radial* mpr = dynamic_cast<const Map_radial*>(&mp) ; 
00296       if (mpr == 0x0) {
00297     cout << "Etoile_rot::grv3: the mapping does not belong"
00298          << " to the class Map_radial !" << endl ; 
00299     abort() ; 
00300       }
00301       
00302       // Computation of 1/tan(theta) * 1/r daa/dtheta
00303       if (daadt.get_etat() == ETATQCQ) {
00304     Valeur& vdaadt = daadt.va ; 
00305     vdaadt = vdaadt.ssint() ;   // division by sin(theta)
00306     vdaadt = vdaadt.mult_ct() ; // multiplication by cos(theta)
00307       }
00308       
00309       Cmp temp = aa.dsdr() + daadt ; 
00310       temp = ( bbb() - a_car()/bbb() ) * temp ; 
00311       temp.std_base_scal() ; 
00312       
00313       // Division by r 
00314       Valeur& vtemp = temp.va ; 
00315       vtemp = vtemp.sx() ;    // division by xi in the nucleus
00316       // Id in the shells
00317       // division by xi-1 in the ZEC
00318       vtemp = (mpr->xsr) * vtemp ; // multiplication by xi/r in the nucleus
00319       //          by 1/r in the shells
00320       //          by r(xi-1) in the ZEC
00321       
00322       // In the ZEC, a multiplication by r has been performed instead
00323       //   of the division:             
00324       temp.set_dzpuis( temp.get_dzpuis() + 2 ) ;  
00325       
00326       source = bbb() * source() + 0.5 * temp ; 
00327       
00328     }
00329     else{
00330       source = - 0.5 * flat_scalar_prod(logn.gradient_spher(),
00331                     logn.gradient_spher() ) ; 
00332     }
00333     
00334     source.set_std_base() ; 
00335     
00336     double int_grav = source().integrale() ; 
00337     
00338     // Matter term
00339     // -----------
00340     
00341     if (relativistic) {    
00342       source  = qpig * a_car * bbb * s_euler ;
00343     }
00344     else{
00345       source = qpig * ( 3 * press + nbar * uuu * uuu ) ; 
00346     }
00347     
00348     source.set_std_base() ; 
00349     
00350     double int_mat = source().integrale() ; 
00351     
00352     // Virial error
00353     // ------------
00354     if (ost != 0x0) {
00355       *ost << "Etoile_rot::grv3 : gravitational term : " << int_grav 
00356        << endl ;
00357       *ost << "Etoile_rot::grv3 : matter term :        " << int_mat 
00358        << endl ;
00359     }
00360     
00361     p_grv3 = new double( (int_grav + int_mat) / int_mat ) ;      
00362     
00363   }
00364   
00365   return *p_grv3 ; 
00366   
00367 }
00368 
00369 
00370             //----------------------------//
00371             //       R_circ       //
00372             //----------------------------//
00373 
00374 double Etoile_rot::r_circ() const {
00375 
00376     if (p_r_circ == 0x0) {    // a new computation is required
00377     
00378     // Index of the point at phi=0, theta=pi/2 at the surface of the star:
00379     const Mg3d* mg = mp.get_mg() ; 
00380     assert(mg->get_type_t() == SYM) ; 
00381     int l_b = nzet - 1 ; 
00382     int i_b = mg->get_nr(l_b) - 1 ; 
00383     int j_b = mg->get_nt(l_b) - 1 ; 
00384     int k_b = 0 ; 
00385     
00386     p_r_circ = new double( bbb()(l_b, k_b, j_b, i_b) * ray_eq() ) ; 
00387 
00388     }
00389     
00390     return *p_r_circ ; 
00391 
00392 }
00393 
00394 
00395             //----------------------------//
00396             //     Flattening         //
00397             //----------------------------//
00398 
00399 double Etoile_rot::aplat() const {
00400 
00401     if (p_aplat == 0x0) {    // a new computation is required
00402     
00403     p_aplat = new double( ray_pole() / ray_eq() ) ;      
00404 
00405     }
00406     
00407     return *p_aplat ; 
00408 
00409 }
00410 
00411 
00412             //----------------------------//
00413             //       Z_eq_f       //
00414             //----------------------------//
00415 
00416 double Etoile_rot::z_eqf() const {
00417 
00418     if (p_z_eqf == 0x0) {    // a new computation is required
00419     
00420     // Index of the point at phi=0, theta=pi/2 at the surface of the star:
00421     const Mg3d* mg = mp.get_mg() ; 
00422     assert(mg->get_type_t() == SYM) ; 
00423     int l_b = nzet - 1 ; 
00424     int i_b = mg->get_nr(l_b) - 1 ; 
00425     int j_b = mg->get_nt(l_b) - 1 ; 
00426     int k_b = 0 ; 
00427     
00428     double u_eq = uuu()(l_b, k_b, j_b, i_b) ; 
00429     double n_eq = nnn()(l_b, k_b, j_b, i_b) ; 
00430     double nphi_eq = nphi()(l_b, k_b, j_b, i_b) ; 
00431     
00432     p_z_eqf = new double( sqrt((1.-u_eq)/(1.+u_eq)) 
00433                 / (n_eq + nphi_eq * r_circ() )
00434                   - 1. ) ;
00435     }
00436     
00437     return *p_z_eqf ; 
00438 
00439 }
00440             //----------------------------//
00441             //       Z_eq_b       //
00442             //----------------------------//
00443 
00444 double Etoile_rot::z_eqb() const {
00445 
00446     if (p_z_eqb == 0x0) {    // a new computation is required
00447     
00448     // Index of the point at phi=0, theta=pi/2 at the surface of the star:
00449     const Mg3d* mg = mp.get_mg() ; 
00450     assert(mg->get_type_t() == SYM) ; 
00451     int l_b = nzet - 1 ; 
00452     int i_b = mg->get_nr(l_b) - 1 ; 
00453     int j_b = mg->get_nt(l_b) - 1 ; 
00454     int k_b = 0 ; 
00455     
00456     double u_eq = uuu()(l_b, k_b, j_b, i_b) ; 
00457     double n_eq = nnn()(l_b, k_b, j_b, i_b) ; 
00458     double nphi_eq = nphi()(l_b, k_b, j_b, i_b) ; 
00459     
00460     p_z_eqb = new double(  sqrt((1.+u_eq)/(1.-u_eq)) 
00461                 / (n_eq - nphi_eq * r_circ() )
00462                   - 1. )  ;
00463 
00464     }
00465     
00466     return *p_z_eqb ; 
00467 
00468 }
00469 
00470 
00471             //----------------------------//
00472             //       Z_pole       //
00473             //----------------------------//
00474 
00475 double Etoile_rot::z_pole() const {
00476 
00477     if (p_z_pole == 0x0) {    // a new computation is required
00478     
00479     double n_pole = nnn().val_point(ray_pole(), 0., 0.) ; 
00480     
00481     p_z_pole = new double(  1. / n_pole - 1. ) ; 
00482 
00483     }
00484     
00485     return *p_z_pole ; 
00486 
00487 }
00488 
00489 
00490             //----------------------------//
00491             //     Quadrupole moment      //
00492             //----------------------------//
00493 
00494 double Etoile_rot::mom_quad() const {
00495 
00496   using namespace Unites ;
00497     if (p_mom_quad == 0x0) {    // a new computation is required
00498     
00499     // Source for of the Poisson equation for nu
00500     // -----------------------------------------
00501 
00502     Tenseur source(mp) ; 
00503     
00504     if (relativistic) {
00505         Tenseur beta = log(bbb) ; 
00506         beta.set_std_base() ; 
00507         source =  qpig * a_car *( ener_euler + s_euler ) 
00508             + ak_car - flat_scalar_prod(logn.gradient_spher(), 
00509                 logn.gradient_spher() + beta.gradient_spher()) ; 
00510     }
00511     else {
00512         source = qpig * nbar ; 
00513     }
00514     source.set_std_base() ;     
00515 
00516     // Multiplication by -r^2 P_2(cos(theta))
00517     //  [cf Eq.(7) of Salgado et al. Astron. Astrophys. 291, 155 (1994) ]
00518     // ------------------------------------------------------------------
00519     
00520     // Multiplication by r^2 : 
00521     // ----------------------
00522     Cmp& csource = source.set() ; 
00523     csource.mult_r() ; 
00524     csource.mult_r() ; 
00525     if (csource.check_dzpuis(2)) {
00526         csource.inc2_dzpuis() ; 
00527     }
00528         
00529     // Muliplication by cos^2(theta) :
00530     // -----------------------------
00531     Cmp temp = csource ; 
00532     
00533     // What follows is valid only for a mapping of class Map_radial : 
00534     assert( dynamic_cast<const Map_radial*>(&mp) != 0x0 ) ; 
00535         
00536     if (temp.get_etat() == ETATQCQ) {
00537         Valeur& vtemp = temp.va ; 
00538         vtemp = vtemp.mult_ct() ;   // multiplication by cos(theta)
00539         vtemp = vtemp.mult_ct() ;   // multiplication by cos(theta)
00540     }
00541     
00542     // Muliplication by -P_2(cos(theta)) :
00543     // ----------------------------------
00544     source = 0.5 * source() - 1.5 * temp ; 
00545     
00546     // Final result
00547     // ------------
00548 
00549     p_mom_quad = new double( source().integrale() / qpig ) ;     
00550 
00551     }
00552     
00553     return *p_mom_quad ; 
00554 
00555 }
00556 
00557 
00558 
00559 

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