et_rot_mag_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  *   Copyright (c) 2002 Emmanuel Marcq
00010  *   Copyright (c) 2002 Jerome Novak
00011  *
00012  *   This file is part of LORENE.
00013  *
00014  *   LORENE is free software; you can redistribute it and/or modify
00015  *   it under the terms of the GNU General Public License as published by
00016  *   the Free Software Foundation; either version 2 of the License, or
00017  *   (at your option) any later version.
00018  *
00019  *   LORENE is distributed in the hope that it will be useful,
00020  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00021  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022  *   GNU General Public License for more details.
00023  *
00024  *   You should have received a copy of the GNU General Public License
00025  *   along with LORENE; if not, write to the Free Software
00026  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00027  *
00028  */
00029 
00030 
00031 char et_rot_mag_global_C[] = "$Header: /cvsroot/Lorene/C++/Source/Etoile/et_rot_mag_global.C,v 1.18 2006/01/31 15:54:57 j_novak Exp $" ;
00032 
00033 /*
00034  * $Id: et_rot_mag_global.C,v 1.18 2006/01/31 15:54:57 j_novak Exp $
00035  * $Log: et_rot_mag_global.C,v $
00036  * Revision 1.18  2006/01/31 15:54:57  j_novak
00037  * Corrected a missing '-' sign for the theta component of the magnetic field in
00038  * Et_rot_mag::Magn(). This had no influence in the calculations, only in the
00039  * display of B values.
00040  *
00041  * Revision 1.17  2004/03/25 10:29:06  j_novak
00042  * All LORENE's units are now defined in the namespace Unites (in file unites.h).
00043  *
00044  * Revision 1.16  2003/10/27 10:52:19  e_gourgoulhon
00045  * Suppressed the global #include "unites.h"
00046  * and made it local to each function.
00047  *
00048  * Revision 1.15  2002/10/17 11:30:54  j_novak
00049  * Corrected mistake in angu_mom()
00050  *
00051  * Revision 1.14  2002/06/03 13:00:45  e_marcq
00052  *
00053  * conduc parameter read in parmag.d
00054  *
00055  * Revision 1.12  2002/05/22 12:20:17  j_novak
00056  * *** empty log message ***
00057  *
00058  * Revision 1.11  2002/05/20 15:44:55  e_marcq
00059  *
00060  * Dimension errors corrected, parmag.d input file created and read
00061  *
00062  * Revision 1.10  2002/05/20 10:31:59  j_novak
00063  * *** empty log message ***
00064  *
00065  * Revision 1.9  2002/05/20 08:27:59  j_novak
00066  * *** empty log message ***
00067  *
00068  * Revision 1.8  2002/05/17 15:08:01  e_marcq
00069  *
00070  * Rotation progressive plug-in, units corrected, Q and a_j new member data
00071  *
00072  * Revision 1.7  2002/05/16 13:27:11  j_novak
00073  * *** empty log message ***
00074  *
00075  * Revision 1.6  2002/05/16 10:02:09  j_novak
00076  * Errors in stress energy tensor corrected
00077  *
00078  * Revision 1.5  2002/05/15 09:53:59  j_novak
00079  * First operational version
00080  *
00081  * Revision 1.4  2002/05/14 13:45:30  e_marcq
00082  *
00083  * Correction de la formule du rapport gyromagnetique
00084  *
00085  * Revision 1.1  2002/05/10 09:26:52  j_novak
00086  * Added new class Et_rot_mag for magnetized rotating neutron stars (under development)
00087  *
00088  *
00089  * $Header: /cvsroot/Lorene/C++/Source/Etoile/et_rot_mag_global.C,v 1.18 2006/01/31 15:54:57 j_novak Exp $
00090  *
00091  */
00092 
00093 // Headers C
00094 #include <stdlib.h>
00095 #include <math.h>
00096 
00097 // Headers Lorene
00098 #include "et_rot_mag.h"
00099 #include "unites.h"
00100 
00101 // Definition des fonctions membres differentes ou nouvelles
00102 
00103 void Et_rot_mag::MHD_comput() {
00104   // Calcule les grandeurs du tenseur impulsion-energie EM a partir des champs
00105 
00106   using namespace Unites_mag ;
00107   
00108   Tenseur ATTENS(A_t) ;
00109 
00110   Tenseur APTENS(A_phi) ;
00111   
00112   Tenseur ApAp ( flat_scalar_prod_desal(APTENS.gradient_spher(),
00113                     APTENS.gradient_spher())() );
00114   Tenseur ApAt ( flat_scalar_prod_desal(APTENS.gradient_spher(),
00115                     ATTENS.gradient_spher())() );
00116   Tenseur AtAt ( flat_scalar_prod_desal(ATTENS.gradient_spher(),
00117                     ATTENS.gradient_spher())() );
00118 
00119   if (ApAp.get_etat() != ETATZERO) {
00120     ApAp.set().div_rsint() ;
00121     ApAp.set().div_rsint() ;
00122   }
00123   if (ApAt.get_etat() != ETATZERO) 
00124     ApAt.set().div_rsint() ;
00125   
00126   E_em = 0.5*mu0 * ( 1/(a_car*nnn*nnn) * (AtAt + 2*tnphi*ApAt)
00127           + ( (tnphi*tnphi/(a_car*nnn*nnn)) + 1/(a_car*b_car) )*ApAp );
00128   Jp_em = -mu0 * (ApAt + tnphi*ApAp) /(a_car*nnn) ;
00129   if (Jp_em.get_etat() != ETATZERO) Jp_em.set().mult_rsint() ;
00130   Srr_em = 0 ;
00131   // Stt_em = -Srr_em
00132   Spp_em = E_em ;
00133 }
00134 
00135 Tenseur Et_rot_mag::Elec() const {
00136 
00137   using namespace Unites_mag ;
00138   if (mu0<0.) { //to avoid compilation warnings
00139     cout << qpig << f_unit << msol << km << mevpfm3 << endl ; 
00140     cout << mag_unit << elec_unit << endl ;
00141   }    
00142 
00143   Cmp E_r(mp); Cmp E_t(mp);
00144   E_r = 1/(sqrt(a_car())*nnn())*(A_t.dsdr()+nphi()*A_phi.dsdr()) ;
00145   E_t = 1/(sqrt(a_car())*nnn())*(A_t.srdsdt()+nphi()*A_phi.srdsdt()) ;
00146   E_r.va.set_base((A_t.dsdr()).va.base) ;
00147   E_t.va.set_base((A_t.srdsdt()).va.base) ;
00148   Tenseur Elect(mp, 1, CON, mp.get_bvect_spher()) ;
00149   Elect.set_etat_qcq() ;
00150   Elect.set(0) = E_r ;
00151   Elect.set(1) = E_t ;
00152   Elect.set(2) = 0. ;
00153   
00154     return Elect*elec_unit ;
00155 
00156 }
00157 
00158 Tenseur Et_rot_mag::Magn() const {
00159 
00160   using namespace Unites_mag ;
00161   if (mu0<0.) { //to avoid compilation warnings
00162     cout << qpig << f_unit << msol << km << mevpfm3 << endl ; 
00163     cout << mag_unit << elec_unit << endl ;
00164   }    
00165 
00166   Cmp B_r(mp); Cmp B_t(mp);
00167   B_r = 1/(sqrt(a_car())*bbb())*A_phi.srdsdt();
00168   B_r.va.set_base((A_phi.srdsdt()).va.base) ;
00169   B_r.div_rsint();
00170   B_t = 1/(sqrt(a_car())*bbb())*A_phi.dsdr();
00171   B_t.va.set_base((A_phi.dsdr()).va.base) ;
00172   B_t.div_rsint();
00173 
00174   Tenseur Bmag(mp, 1, CON, mp.get_bvect_spher()) ;
00175   Bmag.set_etat_qcq() ;
00176   Bmag.set(0) = B_r ;
00177   Bmag.set(1) = -B_t ;
00178   Bmag.set(2) = 0. ;
00179 
00180     return Bmag*mag_unit ;
00181 
00182 }
00183 
00184 double Et_rot_mag::MagMom() const {
00185 
00186   using namespace Unites_mag ;
00187   if (mu0<0.) { //to avoid compilation warnings
00188     cout << qpig << f_unit << msol << km << mevpfm3 << endl ; 
00189     cout << mag_unit << elec_unit << endl ;
00190   }    
00191 
00192   int Z = mp.get_mg()->get_nzone();   
00193   double mm ;
00194 
00195   if(A_phi.get_etat()==ETATZERO) {
00196 
00197     mm = 0 ;
00198   }else{
00199 
00200   Valeur** asymp = A_phi.asymptot(1) ;
00201   mm = 4*M_PI*(*asymp[1])(Z-1,0,mp.get_mg()->get_nt(Z-1)-1,0) ;
00202 
00203   delete asymp[0] ;
00204   delete asymp[1] ;
00205 
00206   delete [] asymp ;
00207   }
00208 
00209   return mm*mag_unit*r_unit*r_unit*r_unit/mu_si*1.e9 ;
00210 
00211 }
00212 
00213 double Et_rot_mag::Q_comput() const {
00214 
00215   using namespace Unites_mag ;
00216 
00217   int Z = mp.get_mg()->get_nzone();
00218 
00219   if(A_t.get_etat()==ETATZERO) {
00220     return 0 ;
00221   }else{
00222   Valeur** asymp = A_t.asymptot(1) ;
00223 
00224   double Q_c = -4*M_PI*(*asymp[1])(Z-1,0,0,0) ;
00225   delete asymp[0] ;
00226   delete asymp[1] ;
00227 
00228   delete [] asymp ;
00229 
00230   return Q_c *(j_unit/v_unit*pow(r_unit,3)) ;}
00231   }
00232 
00233 
00234 double Et_rot_mag::Q_int() const {
00235 
00236   using namespace Unites_mag ;
00237 
00238   double Qi = 0. ;
00239 
00240     if (relativistic) {
00241 
00242         Cmp dens = a_car() * bbb() * nnn() * j_t ;
00243         
00244         dens.std_base_scal() ; 
00245 
00246         Qi = dens.integrale() ;
00247 
00248 
00249     }
00250     else{  // Newtonian case 
00251         assert(nbar.get_etat() == ETATQCQ) ; 
00252 
00253         Qi = ( j_t.integrale() ) ;
00254 
00255     }
00256 
00257     
00258     
00259     return Qi * (j_unit/v_unit*pow(r_unit,3)) ; 
00260 
00261 }
00262 
00263 
00264 double Et_rot_mag::GyroMag() const {
00265 
00266   using namespace Unites_mag ;
00267 
00268   return 2*MagMom()*mass_g()/(Q_comput()*angu_mom()*v_unit*r_unit); 
00269 
00270 }
00271             //----------------------------//
00272             //  Gravitational mass    //
00273             //----------------------------//
00274 
00275 double Et_rot_mag::mass_g() const {
00276 
00277     if (p_mass_g == 0x0) {    // a new computation is required
00278     
00279     if (relativistic) {
00280 
00281         Tenseur source = nnn * (ener_euler + E_em + s_euler + Spp_em) + 
00282           nphi * Jp_em + 2 * bbb * (ener_euler + press) * tnphi * uuu ;
00283  
00284         source = a_car * bbb * source ;
00285 
00286         source.set_std_base() ;
00287 
00288         p_mass_g = new double( source().integrale() ) ;
00289 
00290 
00291     }
00292     else{  // Newtonian case 
00293         p_mass_g = new double( mass_b() ) ;   // in the Newtonian case
00294                             //  M_g = M_b
00295     }
00296     }
00297     
00298     return *p_mass_g ; 
00299 
00300 } 
00301         
00302             //----------------------------//
00303             //  Angular momentum      //
00304             //----------------------------//
00305 
00306 double Et_rot_mag::angu_mom() const {
00307 
00308     if (p_angu_mom == 0x0) {    // a new computation is required
00309     
00310     Cmp dens = uuu() ; 
00311 
00312     dens.mult_r() ;         //  Multiplication by
00313     dens.va = (dens.va).mult_st() ; //    r sin(theta)
00314 
00315     if (relativistic) {
00316         dens = a_car() * (b_car() * (ener_euler() + press()) 
00317             * dens + bbb() * Jp_em()) ; 
00318     }
00319     else {    // Newtonian case 
00320         dens = nbar() * dens ; 
00321     }
00322 
00323     dens.std_base_scal() ; 
00324 
00325     p_angu_mom = new double( dens.integrale() ) ;
00326 
00327     }
00328     
00329     return *p_angu_mom ; 
00330 
00331 }
00332 
00333 
00334             //----------------------------//
00335             //       T/W          //
00336             //----------------------------//
00337 
00338 // Redefini en virtual dans le .h : A CHANGER
00339 
00340 double Et_rot_mag::tsw() const {
00341 
00342     if (p_tsw == 0x0) {    // a new computation is required
00343     
00344     double tcin = 0.5 * omega * angu_mom() ;
00345     
00346     if (relativistic) {
00347         
00348         Cmp dens = a_car() * bbb() * gam_euler() * ener() ;
00349         dens.std_base_scal() ; 
00350         double mass_p = dens.integrale() ; 
00351         
00352         p_tsw = new double( tcin / ( mass_p + tcin - mass_g() ) ) ;     
00353        
00354     }
00355     else {      // Newtonian case 
00356         Cmp dens = 0.5 * nbar() * logn() ;
00357         dens.std_base_scal() ; 
00358         double wgrav = dens.integrale() ; 
00359         p_tsw = new double( tcin / fabs(wgrav) ) ;  
00360     }
00361 
00362 
00363     }
00364     
00365     return *p_tsw ; 
00366 
00367 }
00368 
00369 
00370             //----------------------------//
00371             //       GRV2         //
00372             //----------------------------//
00373 
00374 double Et_rot_mag::grv2() const {
00375 
00376     if (p_grv2 == 0x0) {    // a new computation is required
00377     
00378       // To get qpig:   
00379       using namespace Unites ;
00380 
00381       Tenseur sou_m =  2 * qpig * a_car * (press + (ener_euler+press)
00382                        * uuu*uuu ) ;
00383       
00384       Tenseur sou_q =   2 * qpig * a_car * Spp_em + 1.5 * ak_car
00385     - flat_scalar_prod(logn.gradient_spher(), logn.gradient_spher() ) ;
00386 
00387       p_grv2 = new double( double(1) - lambda_grv2(sou_m(), sou_q()) ) ; 
00388 
00389     }
00390     
00391     return *p_grv2 ; 
00392 
00393 }
00394 
00395 
00396             //----------------------------//
00397             //       GRV3         //
00398             //----------------------------//
00399 
00400 double Et_rot_mag::grv3(ostream* ost) const {
00401 
00402     if (p_grv3 == 0x0) {    // a new computation is required
00403 
00404     // To get qpig: 
00405       using namespace Unites ;
00406       
00407       Tenseur source(mp) ; 
00408     
00409     // Gravitational term [cf. Eq. (43) of Gourgoulhon & Bonazzola
00410     // ------------------       Class. Quantum Grav. 11, 443 (1994)]
00411 
00412     if (relativistic) {
00413         Tenseur alpha = dzeta - logn ; 
00414         Tenseur beta = log( bbb ) ; 
00415         beta.set_std_base() ; 
00416         
00417         source = 0.75 * ak_car 
00418              - flat_scalar_prod(logn.gradient_spher(),
00419                     logn.gradient_spher() )
00420              + 0.5 * flat_scalar_prod(alpha.gradient_spher(),
00421                           beta.gradient_spher() ) ; 
00422         
00423         Cmp aa = alpha() - 0.5 * beta() ; 
00424         Cmp daadt = aa.srdsdt() ;   // 1/r d/dth
00425         
00426         // What follows is valid only for a mapping of class Map_radial : 
00427         const Map_radial* mpr = dynamic_cast<const Map_radial*>(&mp) ; 
00428         if (mpr == 0x0) {
00429         cout << "Etoile_rot::grv3: the mapping does not belong"
00430              << " to the class Map_radial !" << endl ; 
00431         abort() ; 
00432         }
00433         
00434         // Computation of 1/tan(theta) * 1/r daa/dtheta
00435         if (daadt.get_etat() == ETATQCQ) {
00436         Valeur& vdaadt = daadt.va ; 
00437         vdaadt = vdaadt.ssint() ;   // division by sin(theta)
00438         vdaadt = vdaadt.mult_ct() ; // multiplication by cos(theta)
00439         }
00440         
00441         Cmp temp = aa.dsdr() + daadt ; 
00442         temp = ( bbb() - a_car()/bbb() ) * temp ; 
00443         temp.std_base_scal() ; 
00444         
00445         // Division by r 
00446         Valeur& vtemp = temp.va ; 
00447         vtemp = vtemp.sx() ;    // division by xi in the nucleus
00448                     // Id in the shells
00449                     // division by xi-1 in the ZEC
00450         vtemp = (mpr->xsr) * vtemp ; // multiplication by xi/r in the nucleus
00451                      //       by 1/r in the shells
00452                      //       by r(xi-1) in the ZEC
00453 
00454         // In the ZEC, a multiplication by r has been performed instead
00455         //   of the division:           
00456         temp.set_dzpuis( temp.get_dzpuis() + 2 ) ;  
00457         
00458         source = bbb() * source() + 0.5 * temp ; 
00459 
00460     }
00461     else{
00462         source = - 0.5 * flat_scalar_prod(logn.gradient_spher(),
00463                           logn.gradient_spher() ) ; 
00464     }
00465     
00466     source.set_std_base() ; 
00467 
00468     double int_grav = source().integrale() ; 
00469 
00470     // Matter term
00471     // -----------
00472     
00473     if (relativistic) {    
00474         source  = qpig * a_car * bbb * ( s_euler + Spp_em ) ;
00475     }
00476     else{
00477         source = qpig * ( 3 * press + nbar * uuu * uuu ) ; 
00478     }
00479 
00480     source.set_std_base() ; 
00481 
00482     double int_mat = source().integrale() ; 
00483 
00484     // Virial error
00485     // ------------
00486     if (ost != 0x0) {
00487         *ost << "Etoile_rot::grv3 : gravitational term : " << int_grav 
00488          << endl ;
00489         *ost << "Etoile_rot::grv3 : matter term :        " << int_mat 
00490          << endl ;
00491     }
00492 
00493     p_grv3 = new double( (int_grav + int_mat) / int_mat ) ;      
00494 
00495     }
00496     
00497     return *p_grv3 ; 
00498 
00499 }
00500 
00501             //----------------------------//
00502             //     Quadrupole moment      //
00503             //----------------------------//
00504 
00505 double Et_rot_mag::mom_quad() const {
00506 
00507     if (p_mom_quad == 0x0) {    // a new computation is required
00508     
00509     // To get qpig: 
00510       using namespace Unites ;
00511 
00512     // Source for of the Poisson equation for nu
00513     // -----------------------------------------
00514 
00515     Tenseur source(mp) ; 
00516     
00517     if (relativistic) {
00518         Tenseur beta = log(bbb) ; 
00519         beta.set_std_base() ; 
00520         source =  qpig * a_car *( ener_euler + s_euler + Spp_em ) 
00521             + ak_car - flat_scalar_prod(logn.gradient_spher(), 
00522                 logn.gradient_spher() + beta.gradient_spher()) ; 
00523     }
00524     else {
00525         source = qpig * nbar ; 
00526     }
00527     source.set_std_base() ;     
00528 
00529     // Multiplication by -r^2 P_2(cos(theta))
00530     //  [cf Eq.(7) of Salgado et al. Astron. Astrophys. 291, 155 (1994) ]
00531     // ------------------------------------------------------------------
00532     
00533     // Multiplication by r^2 : 
00534     // ----------------------
00535     Cmp& csource = source.set() ; 
00536     csource.mult_r() ; 
00537     csource.mult_r() ; 
00538     if (csource.check_dzpuis(2)) {
00539         csource.inc2_dzpuis() ; 
00540     }
00541         
00542     // Muliplication by cos^2(theta) :
00543     // -----------------------------
00544     Cmp temp = csource ; 
00545     
00546     // What follows is valid only for a mapping of class Map_radial : 
00547     assert( dynamic_cast<const Map_radial*>(&mp) != 0x0 ) ; 
00548         
00549     if (temp.get_etat() == ETATQCQ) {
00550         Valeur& vtemp = temp.va ; 
00551         vtemp = vtemp.mult_ct() ;   // multiplication by cos(theta)
00552         vtemp = vtemp.mult_ct() ;   // multiplication by cos(theta)
00553     }
00554     
00555     // Muliplication by -P_2(cos(theta)) :
00556     // ----------------------------------
00557     source = 0.5 * source() - 1.5 * temp ; 
00558     
00559     // Final result
00560     // ------------
00561 
00562     p_mom_quad = new double( source().integrale() / qpig ) ;     
00563 
00564     }
00565     
00566     return *p_mom_quad ; 
00567 
00568 }

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