et_bin_bhns_extr_velpot.C

00001 /*
00002  *  Method of class Et_bin_bhns_extr to compute the velocity scalar
00003  *  potential $\psi$ by solving the continuity equation
00004  *  in the Kerr-Schild background metric or in the conformally flat one
00005  *  with extreme mass ratio
00006  *
00007  *    (see file et_bin_bhns_extr.h for documentation).
00008  *
00009  */
00010 
00011 /*
00012  *   Copyright (c) 2004-2005 Keisuke Taniguchi
00013  *
00014  *   This file is part of LORENE.
00015  *
00016  *   LORENE is free software; you can redistribute it and/or modify
00017  *   it under the terms of the GNU General Public License version 2
00018  *   as published by the Free Software Foundation.
00019  *
00020  *   LORENE is distributed in the hope that it will be useful,
00021  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00022  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023  *   GNU General Public License for more details.
00024  *
00025  *   You should have received a copy of the GNU General Public License
00026  *   along with LORENE; if not, write to the Free Software
00027  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00028  *
00029  */
00030 
00031 char et_bin_bhns_extr_velpot_C[] = "$Header: /cvsroot/Lorene/C++/Source/Etoile/et_bin_bhns_extr_velpot.C,v 1.2 2005/02/28 23:17:18 k_taniguchi Exp $" ;
00032 
00033 /*
00034  * $Id: et_bin_bhns_extr_velpot.C,v 1.2 2005/02/28 23:17:18 k_taniguchi Exp $
00035  * $Log: et_bin_bhns_extr_velpot.C,v $
00036  * Revision 1.2  2005/02/28 23:17:18  k_taniguchi
00037  * Modification to include the case of the conformally flat background metric
00038  *
00039  * Revision 1.1  2004/11/30 20:51:56  k_taniguchi
00040  * *** empty log message ***
00041  *
00042  *
00043  * $Header: /cvsroot/Lorene/C++/Source/Etoile/et_bin_bhns_extr_velpot.C,v 1.2 2005/02/28 23:17:18 k_taniguchi Exp $
00044  *
00045  */
00046 
00047 // C headers
00048 //#include <math.h>
00049 
00050 // Lorene headers
00051 #include "et_bin_bhns_extr.h"
00052 #include "scalar.h"
00053 #include "metrique.h"
00054 #include "etoile.h"
00055 #include "eos.h"
00056 #include "param.h"
00057 #include "coord.h"
00058 #include "unites.h"
00059 
00060 // Local prototype
00061 Cmp raccord_c1(const Cmp& uu, int l1) ;
00062 
00063 double Et_bin_bhns_extr::velocity_pot_extr(const double& mass,
00064                        const double& sepa,
00065                        int mermax, double precis,
00066                        double relax) {
00067 
00068   using namespace Unites ;
00069 
00070     if (kerrschild) {
00071 
00072         if (eos.identify() == 5 || eos.identify() == 4 ||
00073         eos.identify() == 3) {
00074 
00075         cout << "Etoile_bin::velocity_pot_extr" << endl ;
00076         cout << "The code has not prepared for this kind of EOS!!!"
00077          << endl;
00078         abort() ;
00079 
00080     }  // End of strange stars case
00081     else {
00082 
00083         int nzm1 = mp.get_mg()->get_nzone() - 1 ;
00084 
00085         //--------------------------------
00086         // Specific relativistic enthalpy           ---> hhh
00087         //--------------------------------
00088 
00089         Tenseur hhh = exp(unsurc2 * ent) ;  // = 1 at the Newtonian limit
00090         hhh.set_std_base() ;
00091 
00092         //--------------------------------------------
00093         // Computation of W^i = - A^2 h Gamma_n B^i/N
00094         //--------------------------------------------
00095 
00096         Tenseur www = - a_car * hhh * gam_euler * bsn ;
00097 
00098         www.change_triad( mp.get_bvect_cart() ) ;
00099                             // components on the mapping Cartesian basis
00100 
00101         //-------------------------------------------------
00102         // Constant value of W^i at the center of the star
00103         //-------------------------------------------------
00104 
00105         Tenseur v_orb(mp, 1, CON, mp.get_bvect_cart()) ;
00106 
00107         v_orb.set_etat_qcq() ;
00108         for (int i=0; i<3; i++) {
00109             v_orb.set(i) = www(i)(0, 0, 0, 0) ;
00110         }
00111 
00112         v_orb.set_triad( *(www.get_triad()) ) ;
00113         v_orb.set_std_base() ;
00114 
00115         // Some auxiliary terms
00116         // --------------------
00117 
00118         const Coord& xx = mp.x ;
00119         const Coord& yy = mp.y ;
00120         const Coord& zz = mp.z ;
00121 
00122         Tenseur r_bh(mp) ;
00123         r_bh.set_etat_qcq() ;
00124         r_bh.set() = pow( (xx+sepa)*(xx+sepa) + yy*yy + zz*zz, 0.5) ;
00125         r_bh.set_std_base() ;
00126 
00127         Tenseur msr(mp) ;
00128         msr = ggrav * mass / r_bh ;
00129         msr.set_std_base() ;
00130 
00131         Tenseur lapse_bh2(mp) ;  // lapse_bh * lapse_bh
00132         lapse_bh2 = 1. / (1.+2.*msr) ;
00133         lapse_bh2.set_std_base() ;
00134 
00135         Tenseur lapse_bh3(mp) ;  // lapse_bh * lapse_bh * lapse_bh 
00136         lapse_bh3 = 1./pow(1.+2.*msr, 1.5) ;
00137         lapse_bh3.set_std_base() ;
00138 
00139         Tenseur xx_con(mp, 1, CON, mp.get_bvect_cart()) ;
00140         xx_con.set_etat_qcq() ;
00141         xx_con.set(0) = xx + sepa ;
00142         xx_con.set(1) = yy ;
00143         xx_con.set(2) = zz ;
00144         xx_con.set_std_base() ;
00145 
00146         Tenseur xsr_con(mp, 1, CON, mp.get_bvect_cart()) ;
00147         xsr_con = xx_con / r_bh ;
00148         xsr_con.set_std_base() ;
00149 
00150         Tenseur xx_cov(mp, 1, COV, mp.get_bvect_cart()) ;
00151         xx_cov.set_etat_qcq() ;
00152         xx_cov.set(0) = xx + sepa ;
00153         xx_cov.set(1) = yy ;
00154         xx_cov.set(2) = zz ;
00155         xx_cov.set_std_base() ;
00156 
00157         Tenseur xsr_cov(mp, 1, COV, mp.get_bvect_cart()) ;
00158         xsr_cov = xx_cov / r_bh ;
00159         xsr_cov.set_std_base() ;
00160 
00161         // X_i/r_bh in the spherical coordinate
00162         const Coord& rr = mp.r ;
00163         const Coord& st = mp.sint ;
00164         const Coord& ct = mp.cost ;
00165         const Coord& sp = mp.sinp ;
00166         const Coord& cp = mp.cosp ;
00167 
00168         Tenseur rr_spher_cov(mp, 1, COV, mp.get_bvect_spher()) ;
00169         rr_spher_cov.set_etat_qcq() ;
00170         rr_spher_cov.set(0) = rr + sepa*st*cp ;
00171         rr_spher_cov.set(1) = sepa*ct*cp ;
00172         rr_spher_cov.set(2) = - sepa*sp ;
00173         rr_spher_cov.set_std_base() ;
00174 
00175         Tenseur xsr_spher_cov(mp, 1, COV, mp.get_bvect_spher()) ;
00176         xsr_spher_cov = rr_spher_cov / r_bh ;
00177         xsr_spher_cov.set_std_base() ;
00178 
00179         // l^j D_j H_ent
00180         Tenseur ldent = flat_scalar_prod(xsr_con, ent.gradient()) ;
00181 
00182         // l^j D_j beta_auto
00183         Tenseur ldbeta = flat_scalar_prod(xsr_con, beta_auto.gradient()) ;
00184 
00185         // l^j D_j psi0
00186         Tenseur ldpsi0 = flat_scalar_prod(xsr_con, psi0.gradient()) ;
00187 
00188         // l^i D_i (l^j D_j psi0)
00189         Tenseur ldldpsi0 = flat_scalar_prod(xsr_con, ldpsi0.gradient()) ;
00190 
00191         //-------------------------------------------------
00192         // Source and coefficients a,b for poisson_compact
00193         // (idenpendent from psi0)
00194         //-------------------------------------------------
00195 
00196         Cmp dndh_log = eos.der_nbar_ent(ent(), nzet) ;
00197 
00198         // In order to avoid any division by zero in the computation of
00199         //  zeta_h the value of dndh_log is set to 1
00200         //  in the external domains:
00201         for (int l=nzet; l <= nzm1; l++) {
00202             dndh_log.set(l) = 1 ;
00203         }
00204 
00205         double erreur ;
00206 
00207         Tenseur zeta_h( ent() / dndh_log ) ;
00208         zeta_h.set_std_base() ;
00209 
00210         Tenseur tmp_zeta = 1 - unsurc2 * zeta_h ;
00211         tmp_zeta.set_std_base() ;
00212 
00213         Tenseur bb = tmp_zeta * (ent.gradient_spher()
00214                      - 2.*lapse_bh2 * msr * ldent
00215                      * xsr_spher_cov)
00216           + unsurc2 * zeta_h * (beta_auto.gradient_spher()
00217                     - 2.*lapse_bh2 * msr * ldbeta
00218                     * xsr_spher_cov)
00219           - unsurc2 * 2. * zeta_h * lapse_bh2 * lapse_bh2 * msr / r_bh
00220           * (1.+4.*msr) * xsr_spher_cov ;
00221 
00222         Tenseur entmb = ent - beta_auto ;
00223 
00224         Tenseur source = flat_scalar_prod(www - v_orb, ent.gradient())
00225           + unsurc2*zeta_h*( flat_scalar_prod(v_orb, entmb.gradient())
00226                  + flat_scalar_prod(www, gam_euler.gradient())
00227                  / gam_euler )
00228           + 2.*lapse_bh2 * msr * flat_scalar_prod(xsr_cov, v_orb)
00229           * flat_scalar_prod(xsr_con, ent.gradient())
00230           + unsurc2 * 2. * zeta_h
00231           * (lapse_bh2*msr*(ldldpsi0
00232                 - flat_scalar_prod(xsr_cov, v_orb)
00233                 * (flat_scalar_prod(xsr_con, entmb.gradient())
00234                    - lapse_bh2 * (1.+4.*msr) / r_bh))
00235          + a_car * hhh * gam_euler * lapse_bh3 * msr * (1.+3.*msr)
00236          / r_bh) ;
00237 
00238         source.annule(nzet, nzm1) ;
00239 
00240         //----------------------------------------------------
00241         // Resolution by means of Map_radial::poisson_compact
00242         //----------------------------------------------------
00243 
00244         Param par ;
00245         int niter ;
00246         par.add_int(mermax) ;
00247         par.add_double(precis, 0) ;
00248         par.add_double(relax, 1) ;
00249         par.add_int_mod(niter) ;
00250 
00251         if (psi0.get_etat() == ETATZERO) {
00252             psi0.set_etat_qcq() ;
00253         psi0.set() = 0 ;
00254         }
00255 
00256         source.set().va.ylm() ;
00257 
00258         mp.poisson_compact(source(), zeta_h(), bb, par, psi0.set() ) ;
00259 
00260         //-----------------------
00261         // Check of the solution
00262         //-----------------------
00263 
00264         Tenseur bb_dpsi0 = flat_scalar_prod( bb, psi0.gradient_spher() ) ;
00265 
00266         Cmp oper = zeta_h() * psi0().laplacien() + bb_dpsi0() ;
00267 
00268         source.set().va.ylm_i() ;
00269 
00270         erreur = diffrel(oper, source())(0) ;
00271 
00272         cout << "Check of the resolution of the continuity equation : "
00273          << endl ;
00274         cout << "norme(source) : " << norme(source())(0)
00275          << "    diff oper/source : " << erreur << endl ;
00276 
00277         //--------------------------
00278         // Computation of grad(psi)
00279         //--------------------------
00280 
00281         // The computation is done component by component because
00282         // psi0.gradient() is a covariant vector, whereas v_orb is a
00283         // contravariant one.
00284 
00285         d_psi.set_etat_qcq() ;
00286 
00287         for (int i=0; i<3; i++) {
00288             d_psi.set(i) = (psi0.gradient())(i) + v_orb(i) ;
00289         }
00290 
00291         d_psi.set_triad( *(v_orb.get_triad()) ) ;
00292 
00293         // C^1 continuation of d_psi outside the star
00294         //  (to ensure a smooth enthalpy field accross the stellar surface)
00295         // ----------------------------------------------------------------
00296 
00297         d_psi.annule(nzet, nzm1) ;
00298         for (int i=0; i<3; i++) {
00299             d_psi.set(i) = raccord_c1(d_psi(i), nzet) ;
00300         }
00301 
00302         assert( d_psi.get_triad() == &(mp.get_bvect_cart()) ) ;
00303 
00304         d_psi.change_triad(ref_triad) ;
00305 
00306         return erreur ;
00307 
00308     }
00309 
00310     }
00311     else {
00312 
00313         if (eos.identify() == 5 || eos.identify() == 4 ||
00314         eos.identify() == 3) {
00315 
00316         cout << "Etoile_bin::velocity_pot_extr" << endl ;
00317         cout << "The code has not prepared for this kind of EOS!!!"
00318          << endl;
00319         abort() ;
00320 
00321     }  // End of strange stars case
00322     else {
00323 
00324         int nzm1 = mp.get_mg()->get_nzone() - 1 ;
00325 
00326         //--------------------------------
00327         // Specific relativistic enthalpy           ---> hhh
00328         //--------------------------------
00329 
00330         Tenseur hhh = exp(unsurc2 * ent) ;  // = 1 at the Newtonian limit
00331         hhh.set_std_base() ;
00332 
00333         //--------------------------------------------
00334         // Computation of W^i = - A^2 h Gamma_n B^i/N
00335         //--------------------------------------------
00336 
00337         Tenseur www = - a_car * hhh * gam_euler * bsn ;
00338 
00339         www.change_triad( mp.get_bvect_cart() ) ;
00340                             // components on the mapping Cartesian basis
00341 
00342         //-------------------------------------------------
00343         // Constant value of W^i at the center of the star
00344         //-------------------------------------------------
00345 
00346         Tenseur v_orb(mp, 1, CON, mp.get_bvect_cart()) ;
00347 
00348         v_orb.set_etat_qcq() ;
00349         for (int i=0; i<3; i++) {
00350             v_orb.set(i) = www(i)(0, 0, 0, 0) ;
00351         }
00352 
00353         v_orb.set_triad( *(www.get_triad()) ) ;
00354         v_orb.set_std_base() ;
00355 
00356         // Some auxiliary terms
00357         // --------------------
00358 
00359         const Coord& xx = mp.x ;
00360         const Coord& yy = mp.y ;
00361         const Coord& zz = mp.z ;
00362 
00363         Tenseur r_bh(mp) ;
00364         r_bh.set_etat_qcq() ;
00365         r_bh.set() = pow( (xx+sepa)*(xx+sepa) + yy*yy + zz*zz, 0.5) ;
00366         r_bh.set_std_base() ;
00367 
00368         Tenseur msr(mp) ;
00369         msr = ggrav * mass / r_bh ;
00370         msr.set_std_base() ;
00371 
00372         Tenseur xx_cov(mp, 1, COV, mp.get_bvect_cart()) ;
00373         xx_cov.set_etat_qcq() ;
00374         xx_cov.set(0) = xx + sepa ;
00375         xx_cov.set(1) = yy ;
00376         xx_cov.set(2) = zz ;
00377         xx_cov.set_std_base() ;
00378 
00379         // X_i in the spherical coordinate
00380         const Coord& rr = mp.r ;
00381         const Coord& st = mp.sint ;
00382         const Coord& ct = mp.cost ;
00383         const Coord& sp = mp.sinp ;
00384         const Coord& cp = mp.cosp ;
00385 
00386         Tenseur rr_spher_cov(mp, 1, COV, mp.get_bvect_spher()) ;
00387         rr_spher_cov.set_etat_qcq() ;
00388         rr_spher_cov.set(0) = rr + sepa*st*cp ;
00389         rr_spher_cov.set(1) = sepa*ct*cp ;
00390         rr_spher_cov.set(2) = - sepa*sp ;
00391         rr_spher_cov.set_std_base() ;
00392 
00393         Tenseur tmp_bh(mp) ;
00394         tmp_bh = 0.5 * msr * msr / (1.-0.25*msr*msr) / r_bh / r_bh ;
00395         tmp_bh.set_std_base() ;
00396 
00397         //-------------------------------------------------
00398         // Source and coefficients a,b for poisson_compact
00399         // (idenpendent from psi0)
00400         //-------------------------------------------------
00401 
00402         Cmp dndh_log = eos.der_nbar_ent(ent(), nzet) ;
00403 
00404         // In order to avoid any division by zero in the computation of
00405         //  zeta_h the value of dndh_log is set to 1
00406         //  in the external domains:
00407         for (int l=nzet; l <= nzm1; l++) {
00408             dndh_log.set(l) = 1 ;
00409         }
00410 
00411         double erreur ;
00412 
00413         Tenseur zeta_h( ent() / dndh_log ) ;
00414         zeta_h.set_std_base() ;
00415 
00416         Tenseur tmp_zeta = 1 - unsurc2 * zeta_h ;
00417         tmp_zeta.set_std_base() ;
00418 
00419         Tenseur bb = tmp_zeta * ent.gradient_spher()
00420           + unsurc2 * zeta_h * (beta_auto.gradient_spher()
00421                     + tmp_bh * rr_spher_cov) ;
00422 
00423         Tenseur entmb = ent - beta_auto ;
00424 
00425         Tenseur source = flat_scalar_prod(www - v_orb, ent.gradient())
00426           + unsurc2*zeta_h*( flat_scalar_prod(v_orb, entmb.gradient())
00427                  - tmp_bh * flat_scalar_prod(v_orb, xx_cov)
00428                  + flat_scalar_prod(www, gam_euler.gradient())
00429                  / gam_euler ) ;
00430 
00431         source.annule(nzet, nzm1) ;
00432 
00433         //----------------------------------------------------
00434         // Resolution by means of Map_radial::poisson_compact
00435         //----------------------------------------------------
00436 
00437         Param par ;
00438         int niter ;
00439         par.add_int(mermax) ;
00440         par.add_double(precis, 0) ;
00441         par.add_double(relax, 1) ;
00442         par.add_int_mod(niter) ;
00443 
00444         if (psi0.get_etat() == ETATZERO) {
00445             psi0.set_etat_qcq() ;
00446         psi0.set() = 0 ;
00447         }
00448 
00449         source.set().va.ylm() ;
00450 
00451         mp.poisson_compact(source(), zeta_h(), bb, par, psi0.set() ) ;
00452 
00453         //-----------------------
00454         // Check of the solution
00455         //-----------------------
00456 
00457         Tenseur bb_dpsi0 = flat_scalar_prod( bb, psi0.gradient_spher() ) ;
00458 
00459         Cmp oper = zeta_h() * psi0().laplacien() + bb_dpsi0() ;
00460 
00461         source.set().va.ylm_i() ;
00462 
00463         erreur = diffrel(oper, source())(0) ;
00464 
00465         cout << "Check of the resolution of the continuity equation : "
00466          << endl ;
00467         cout << "norme(source) : " << norme(source())(0)
00468          << "    diff oper/source : " << erreur << endl ;
00469 
00470         //--------------------------
00471         // Computation of grad(psi)
00472         //--------------------------
00473 
00474         // The computation is done component by component because
00475         // psi0.gradient() is a covariant vector, whereas v_orb is a
00476         // contravariant one.
00477 
00478         d_psi.set_etat_qcq() ;
00479 
00480         for (int i=0; i<3; i++) {
00481             d_psi.set(i) = (psi0.gradient())(i) + v_orb(i) ;
00482         }
00483 
00484         d_psi.set_triad( *(v_orb.get_triad()) ) ;
00485 
00486         // C^1 continuation of d_psi outside the star
00487         //  (to ensure a smooth enthalpy field accross the stellar surface)
00488         // ----------------------------------------------------------------
00489 
00490         d_psi.annule(nzet, nzm1) ;
00491         for (int i=0; i<3; i++) {
00492             d_psi.set(i) = raccord_c1(d_psi(i), nzet) ;
00493         }
00494 
00495         assert( d_psi.get_triad() == &(mp.get_bvect_cart()) ) ;
00496 
00497         d_psi.change_triad(ref_triad) ;
00498 
00499         return erreur ;
00500 
00501     }
00502 
00503     }
00504 
00505 }

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