hole_bhns_killing.C

00001 /*
00002  *  Methods of class Hole_bhns to compute Killing vectors
00003  *
00004  *    (see file hole_bhns.h for documentation).
00005  *
00006  */
00007 
00008 /*
00009  *   Copyright (c) 2006-2007 Keisuke Taniguchi
00010  *
00011  *   This file is part of LORENE.
00012  *
00013  *   LORENE is free software; you can redistribute it and/or modify
00014  *   it under the terms of the GNU General Public License version 2
00015  *   as published by the Free Software Foundation.
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 char hole_bhns_killing_C[] = "$Header: /cvsroot/Lorene/C++/Source/Hole_bhns/hole_bhns_killing.C,v 1.2 2008/07/02 21:01:11 k_taniguchi Exp $" ;
00029 
00030 /*
00031  * $Id: hole_bhns_killing.C,v 1.2 2008/07/02 21:01:11 k_taniguchi Exp $
00032  * $Log: hole_bhns_killing.C,v $
00033  * Revision 1.2  2008/07/02 21:01:11  k_taniguchi
00034  * A bug removed.
00035  *
00036  * Revision 1.1  2008/05/15 19:09:53  k_taniguchi
00037  * *** empty log message ***
00038  *
00039  *
00040  * $Header: /cvsroot/Lorene/C++/Source/Hole_bhns/hole_bhns_killing.C,v 1.2 2008/07/02 21:01:11 k_taniguchi Exp $
00041  *
00042  */
00043 
00044 // C++ headers
00045 //#include <>
00046 
00047 // C headers
00048 #include <math.h>
00049 
00050 // Lorene headers
00051 #include "hole_bhns.h"
00052 #include "unites.h"
00053 #include "utilitaires.h"
00054 
00055                //---------------------------------------------//
00056                //          Killing vectors on the AH          //
00057                //---------------------------------------------//
00058 
00059 Vector Hole_bhns::killing_vect(const Tbl& xi_i, const double& phi_i,
00060                    const double& theta_i, const int& nrk_phi,
00061                    const int& nrk_theta) const {
00062 
00063     using namespace Unites ;
00064 
00065     assert(xi_i.get_ndim() == 1) ;
00066     assert(xi_i.get_dim(0) == 3) ;
00067 
00068     const Mg3d* mg = mp.get_mg() ;
00069     int nr = mg->get_nr(1) ;
00070     int nt = mg->get_nt(1) ;
00071     int np = mg->get_np(1) ;
00072 
00073     // Vector which is returned to the main code
00074     // Spherical basis, covariant
00075     Vector killing(mp, COV, mp.get_bvect_spher()) ;
00076 
00077     if (kerrschild) {
00078 
00079       cout << "Not yet prepared!!!" << endl ;
00080       abort() ;
00081 
00082     }
00083     else {  // Isotropic coordinates
00084 
00085         // Solution of the Killing vector on the equator
00086         // ---------------------------------------------
00087 
00088         double dp = 2. * M_PI / double(np) ;  // Angular step
00089 
00090     // Killing vector on the equator
00091     // np+1 is for the check of xi(phi=0)= xi(phi=2pi)
00092     Tbl xi_t(np+1) ;
00093     xi_t.set_etat_qcq() ;
00094     Tbl xi_p(np+1) ;
00095     xi_p.set_etat_qcq() ;
00096     Tbl xi_l(np+1) ;
00097     xi_l.set_etat_qcq() ;
00098 
00099     xi_t.set(0) = xi_i(0) ;
00100     xi_p.set(0) = xi_i(1) ;
00101     xi_l.set(0) = xi_i(2) ;
00102 
00103     Tbl xi(3) ;
00104     xi.set_etat_qcq() ;
00105 
00106     Tbl xi_ini(3) ;
00107     xi_ini.set_etat_qcq() ;
00108     xi_ini.set(0) = xi_i(0) ;
00109     xi_ini.set(1) = xi_i(1) ;
00110     xi_ini.set(2) = xi_i(2) ;
00111 
00112     double pp_0 = phi_i ;  // azimuthal angle phi
00113 
00114     for (int i=1; i<np+1; i++) {
00115 
00116         xi = runge_kutta_phi(xi_ini, pp_0, nrk_phi) ;
00117 
00118         xi_t.set(i) = xi(0) ;
00119         xi_p.set(i) = xi(1) ;
00120         xi_l.set(i) = xi(2) ;
00121 
00122         // New data for the next step
00123         //  -------------------------
00124         pp_0 += dp ;  // New angle
00125         xi_ini = xi ;
00126 
00127     }
00128 
00129     cout << "Hole_bhns::killing_vect :" << endl ;
00130     cout.precision(16) ;
00131     cout << "   xi_p(0) :  " << xi_p(0) << endl ;
00132     cout << "   xi_p(np) : " << xi_p(np) << endl ;
00133 
00134     // Normalization of the Killing vector
00135     // -----------------------------------
00136 
00137     // Initialization of the Killing vector to the phi direction
00138     Scalar xi_phi(mp) ;
00139     xi_phi = 0.5 ;  // If we use "1." for the initialization value,
00140                     // the state flag becomes "ETATUN" which does not
00141                     // work for "set_grid_point".
00142 
00143     for (int k=0; k<np; k++) {
00144       xi_phi.set_grid_point(0, k, nt-1, nr-1) = xi_p(k) ;
00145       xi_phi.set_grid_point(1, k, nt-1, 0) = xi_p(k) ;
00146     }
00147     xi_phi.std_spectral_base() ;
00148 
00149     // Normalization of the Killing vector
00150     Scalar rr(mp) ;
00151     rr = mp.r ;
00152     rr.std_spectral_base() ;
00153 
00154     Scalar st(mp) ;
00155     st = mp.sint ;
00156     st.std_spectral_base() ;
00157 
00158     Scalar source_phi(mp) ;
00159     source_phi = pow(confo_tot, 2.) * rr * st / xi_phi ;
00160     source_phi.std_spectral_base() ;
00161 
00162     double rah = rad_ah() ;
00163 
00164     int nn = 1000 ;
00165     double hh = 2. * M_PI / double(nn) ;
00166     double integ = 0. ;
00167 
00168     int mm ;
00169     double t1, t2, t3, t4, t5 ;
00170 
00171     // Boole's Rule (Newton-Cotes Integral) for integration
00172     // ----------------------------------------------------
00173 
00174     assert(nn%4 == 0) ;
00175     mm = nn/4 ;
00176 
00177     for (int i=0; i<mm; i++) {
00178 
00179         t1 = hh * double(4*i) ;
00180         t2 = hh * double(4*i+1) ;
00181         t3 = hh * double(4*i+2) ;
00182         t4 = hh * double(4*i+3) ;
00183         t5 = hh * double(4*i+4) ;
00184 
00185         integ += (hh/45.) * (14.*source_phi.val_point(rah,M_PI/2.,t1)
00186                  + 64.*source_phi.val_point(rah,M_PI/2.,t2)
00187                  + 24.*source_phi.val_point(rah,M_PI/2.,t3)
00188                  + 64.*source_phi.val_point(rah,M_PI/2.,t4)
00189                  + 14.*source_phi.val_point(rah,M_PI/2.,t5)
00190                  ) ;
00191 
00192     }
00193 
00194     cout << "Hole_bhns:: t_f = " << integ << endl ;
00195     double ratio = 0.5 * integ / M_PI ;
00196 
00197     cout << "Hole_bhns:: t_f / 2M_PI = " << ratio << endl ;
00198 
00199     for (int k=0; k<np; k++) {
00200       xi_p.set(k) = xi_phi.val_grid_point(1, k, nt-1, 0) * ratio ;
00201     }
00202 
00203 
00204         // Solution of the Killing vector to the pole angle
00205         // ------------------------------------------------
00206 
00207     double dt = 0.5 * M_PI / double(nt-1) ;  // Angular step
00208 
00209     // Killing vector to the polar angle
00210     Tbl xi_th(nt, np) ;
00211     xi_th.set_etat_qcq() ;
00212     Tbl xi_ph(nt, np) ;
00213     xi_ph.set_etat_qcq() ;
00214     Tbl xi_ll(nt, np) ;
00215     xi_ll.set_etat_qcq() ;
00216 
00217     // Values on the equator
00218     for (int i=0; i<np; i++) {
00219 
00220         xi_th.set(nt-1, i) = xi_t(i) ;
00221         xi_ph.set(nt-1, i) = xi_p(i) ;
00222         xi_ll.set(nt-1, i) = xi_l(i) ;
00223 
00224     }
00225 
00226     for (int i=0; i<np; i++) {
00227 
00228         // Value at theta=pi/2, phi=phi_i
00229         xi_ini.set(0) = xi_t(i) ;
00230         xi_ini.set(1) = xi_p(i) ;
00231         xi_ini.set(2) = xi_l(i) ;
00232 
00233         double pp = double(i) * dp ;
00234         double tt_0 = theta_i ;  // polar angle theta
00235 
00236         for (int j=1; j<nt; j++) {
00237 
00238             xi = runge_kutta_theta(xi_ini, tt_0, pp, nrk_theta) ;
00239 
00240         xi_th.set(nt-1-j, i) = xi(0) ;
00241         xi_ph.set(nt-1-j, i) = xi(1) ;
00242         xi_ll.set(nt-1-j, i) = xi(2) ;
00243 
00244         // New data for the nxt step
00245         // -------------------------
00246         tt_0 -= dt ;  // New angle
00247         xi_ini = xi ;
00248 
00249         }  // End of the loop to the polar direction
00250 
00251     }  // End of the loop to the azimuhtal direction
00252 
00253     cout << "Hole_bhns::killing_vect :" << endl ;
00254     cout.precision(16) ;
00255     cout << "   xi_ph(nt-1,0) :  " << xi_ph(nt-1,0) << endl ;
00256     cout << "   xi_ph(0,0) :     " << xi_ph(0,0) << endl ;
00257     cout << "   xi_ph(0,np/4) :  " << xi_ph(0,np/4) << endl ;
00258     cout << "   xi_ph(0,np/2) :  " << xi_ph(0,np/2) << endl ;
00259     cout << "   xi_ph(0,3np/4) : " << xi_ph(0,3*np/4) << endl ;
00260 
00261 
00262     // Construction of the Killing vector
00263     // ----------------------------------
00264 
00265     // Definition of the vector is at the top of this code
00266     killing.set_etat_qcq() ;
00267     killing.set(1) = 0.5 ;  // initialization of L instead of
00268                             //  the r component
00269     killing.set(2) = 0.5 ;  // initialization of the theta component
00270     killing.set(3) = 0.5 ;  // initialization of the phi component
00271 
00272     for (int l=0; l<2; l++) {
00273       for (int i=0; i<nr; i++) {
00274         for (int j=0; j<nt; j++) {
00275           for (int k=0; k<np; k++) {
00276         (killing.set(1)).set_grid_point(l, k, j, i) = xi_ll(j, k) ;
00277         (killing.set(2)).set_grid_point(l, k, j, i) = xi_th(j, k) ;
00278         (killing.set(3)).set_grid_point(l, k, j, i) = xi_ph(j, k) ;
00279           }
00280         }
00281       }
00282     }
00283     killing.std_spectral_base() ;
00284 
00285     // Check the normalization
00286     // -----------------------
00287 
00288     double check_norm1 = 0. ;
00289     double check_norm2 = 0. ;
00290     source_phi = pow(confo_tot, 2.) * rr * st / killing(3) ;
00291     source_phi.std_spectral_base() ;
00292 
00293     for (int i=0; i<mm; i++) {
00294 
00295         t1 = hh * double(4*i) ;
00296         t2 = hh * double(4*i+1) ;
00297         t3 = hh * double(4*i+2) ;
00298         t4 = hh * double(4*i+3) ;
00299         t5 = hh * double(4*i+4) ;
00300 
00301         check_norm1 += (hh/45.) *
00302           ( 14.*source_phi.val_point(rah,M_PI/4.,t1)
00303         + 64.*source_phi.val_point(rah,M_PI/4.,t2)
00304         + 24.*source_phi.val_point(rah,M_PI/4.,t3)
00305         + 64.*source_phi.val_point(rah,M_PI/4.,t4)
00306         + 14.*source_phi.val_point(rah,M_PI/4.,t5) ) ;
00307 
00308         check_norm2 += (hh/45.) *
00309           ( 14.*source_phi.val_point(rah,M_PI/8.,t1)
00310         + 64.*source_phi.val_point(rah,M_PI/8.,t2)
00311         + 24.*source_phi.val_point(rah,M_PI/8.,t3)
00312         + 64.*source_phi.val_point(rah,M_PI/8.,t4)
00313         + 14.*source_phi.val_point(rah,M_PI/8.,t5) ) ;
00314 
00315     }
00316 
00317     cout.precision(16) ;
00318     cout << "Hole_bhns:: t_f for M_PI/4 = " << check_norm1 / M_PI
00319          << " M_PI" << endl ;
00320     cout << "Hole_bhns:: t_f for M_PI/8 = " << check_norm2 / M_PI
00321          << " M_PI" << endl ;
00322 
00323     // Checking the accuracy of the Killing vector
00324     // -------------------------------------------
00325 
00326     // xi^i D_i L = 0
00327     Scalar dldt(mp) ;
00328     dldt = killing(1).dsdt() ;
00329 
00330     Scalar dldp(mp) ;
00331     dldp = killing(1).stdsdp() ;
00332 
00333     Scalar xidl(mp) ;
00334     xidl = killing(2) * dldt + killing(3) * dldp ;
00335     xidl.std_spectral_base() ;
00336 
00337     double xidl_error1 = 0. ;
00338     double xidl_error2 = 0. ;
00339     double xidl_norm = 0. ;
00340 
00341     for (int j=0; j<nt; j++) {
00342       for (int k=0; k<np/2; k++) {
00343         xidl_error1 += xidl.val_grid_point(1, k, j, 0) ;
00344       }
00345     }
00346 
00347     for (int j=0; j<nt; j++) {
00348       for (int k=np/2; k<np; k++) {
00349         xidl_error2 += xidl.val_grid_point(1, k, j, 0) ;
00350       }
00351     }
00352 
00353     for (int j=0; j<nt; j++) {
00354       for (int k=0; k<np; k++) {
00355         xidl_norm += fabs(xidl.val_grid_point(1, k, j, 0)) ;
00356       }
00357     }
00358 
00359     cout.precision(6) ;
00360     cout << "Relative error in the 1st condition : "
00361          << xidl_error1 / xidl_norm / double(nt) / double(np) * 2.
00362          << "  "
00363          << xidl_error2 / xidl_norm / double(nt) / double(np) * 2.
00364          << "  "
00365          << (xidl_error1+xidl_error2)/xidl_norm/double(nt)/double(np)
00366          << endl ;
00367 
00368     // D_i xi^i = 0
00369     Scalar xitst(mp) ;
00370     xitst = pow(confo_tot, 2.) * rr * st * killing(2) ;
00371     xitst.std_spectral_base() ;
00372 
00373     Scalar dxitstdt(mp) ;
00374     dxitstdt = xitst.dsdt() ;
00375 
00376     Scalar xip(mp) ;
00377     xip = pow(confo_tot, 2.) * rr * killing(3) ;
00378     xip.std_spectral_base() ;
00379 
00380     Scalar dxipdp(mp) ;
00381     dxipdp = xip.stdsdp() ;
00382 
00383     Scalar dxi(mp) ;
00384     dxi = dxitstdt + st * dxipdp ;
00385     dxi.std_spectral_base() ;
00386 
00387     double dxi_error1 = 0. ;
00388     double dxi_error2 = 0. ;
00389     double dxi_norm = 0. ;
00390 
00391     for (int j=0; j<nt; j++) {
00392       for (int k=0; k<np/2; k++) {
00393         dxi_error1 += dxi.val_grid_point(1, k, j, 0) ;
00394       }
00395     }
00396 
00397     for (int j=0; j<nt; j++) {
00398       for (int k=np/2; k<np; k++) {
00399         dxi_error2 += dxi.val_grid_point(1, k, j, 0) ;
00400       }
00401     }
00402 
00403     for (int j=0; j<nt; j++) {
00404       for (int k=0; k<np; k++) {
00405         dxi_norm += fabs(dxi.val_grid_point(1, k, j, 0)) ;
00406       }
00407     }
00408 
00409     cout << "Relative error in the 2nd condition : "
00410          << dxi_error1 / dxi_norm / double(nt) / double(np) * 2.
00411          << "  "
00412          << dxi_error2 / dxi_norm / double(nt) / double(np) * 2.
00413          << "  "
00414          << (dxi_error1+dxi_error2)/dxi_norm/double(nt)/double(np)
00415          << endl ;
00416 
00417     // e^{ij} D_i \xi_j = 2L
00418     Scalar xipst(mp) ;
00419     xipst = pow(confo_tot, 2.) * rr * st * killing(3) ;
00420     xipst.std_spectral_base() ;
00421 
00422     Scalar dxipstdt(mp) ;
00423     dxipstdt = xipst.dsdt() ;
00424 
00425     Scalar xit(mp) ;
00426     xit = pow(confo_tot, 2.) * rr * killing(2) ;
00427     xit.std_spectral_base() ;
00428 
00429     Scalar dxitdp(mp) ;
00430     dxitdp = xit.stdsdp() ;
00431 
00432     Scalar dxi2l(mp) ;
00433     dxi2l = dxipstdt - st * dxitdp
00434       - 2. * killing(1) * pow(confo_tot, 4.) * rr * rr * st ;
00435     dxi2l.std_spectral_base() ;
00436 
00437     double dxi2l_error1 = 0. ;
00438     double dxi2l_error2 = 0. ;
00439     double dxi2l_norm = 0. ;
00440 
00441     for (int j=0; j<nt; j++) {
00442       for (int k=0; k<np/2; k++) {
00443         dxi2l_error1 += dxi2l.val_grid_point(1, k, j, 0) ;
00444       }
00445     }
00446 
00447     for (int j=0; j<nt; j++) {
00448       for (int k=np/2; k<np; k++) {
00449         dxi2l_error2 += dxi2l.val_grid_point(1, k, j, 0) ;
00450       }
00451     }
00452 
00453     for (int j=0; j<nt; j++) {
00454       for (int k=0; k<np; k++) {
00455         dxi2l_norm += fabs(dxi2l.val_grid_point(1, k, j, 0)) ;
00456       }
00457     }
00458 
00459     cout << "Relative error in the 3rd condition : "
00460          << dxi2l_error1 / dxi2l_norm / double(nt) / double(np) * 2.
00461          << "  "
00462          << dxi2l_error2 / dxi2l_norm / double(nt) / double(np) * 2.
00463          << "  "
00464          << (dxi2l_error1+dxi2l_error2)/dxi2l_norm/double(nt)/double(np)
00465          << endl ;
00466 
00467     cout.precision(4) ;
00468 
00469     }  // End of the loop for isotropic coordinates
00470 
00471     return killing ;
00472 
00473 }

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