00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 char bin_ns_bh_glob_C[] = "$Header: /cvsroot/Lorene/C++/Source/Bin_ns_bh/bin_ns_bh_glob.C,v 1.6 2007/04/24 20:13:53 f_limousin Exp $" ;
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 #include <stdlib.h>
00058 #include <math.h>
00059
00060
00061 #include "nbr_spx.h"
00062 #include "tenseur.h"
00063 #include "bhole.h"
00064 #include "bin_ns_bh.h"
00065 #include "proto.h"
00066 #include "utilitaires.h"
00067 #include "graphique.h"
00068 #include "unites.h"
00069 #include "metrique.h"
00070
00071 double Bin_ns_bh::adm_systeme() const {
00072 Cmp der_un (hole.psi_auto().dsdr()) ;
00073
00074 Map_af auxi_mp (star.get_mp()) ;
00075 Cmp der_deux (star.confpsi_auto().dsdr()) ;
00076
00077 double masse = hole.mp.integrale_surface_infini(der_un) +
00078 auxi_mp.integrale_surface_infini(der_deux) ;
00079
00080 masse /= -2*M_PI ;
00081 return masse ;
00082 }
00083
00084 double Bin_ns_bh::adm_systeme_volume() const {
00085
00086 using namespace Unites ;
00087
00088 Tenseur auxi_bh (flat_scalar_prod(hole.tkij_tot, hole.tkij_auto)) ;
00089 Tenseur kk_bh (hole.mp) ;
00090 kk_bh = 0 ;
00091 Tenseur work_bh(hole.mp) ;
00092 work_bh.set_etat_qcq() ;
00093 for (int i=0 ; i<3 ; i++) {
00094 work_bh.set() = auxi_bh(i, i) ;
00095 kk_bh = kk_bh + work_bh ;
00096 }
00097 Cmp integ_bh (pow(hole.psi_tot(), 5.)*kk_bh()) ;
00098 integ_bh.annule(0) ;
00099 integ_bh.std_base_scal() ;
00100
00101 Cmp integ_hor1 (hole.psi_tot()) ;
00102
00103 Cmp tet (hole.mp) ;
00104 tet = hole.mp.tet ;
00105 Cmp phi (hole.mp) ;
00106 phi = hole.mp.phi ;
00107 Tenseur rad (hole.mp, 1, COV, hole.mp.get_bvect_cart()) ;
00108 rad.set_etat_qcq() ;
00109 rad.set(0) = cos(phi)*sin(tet) ;
00110 rad.set(1) = sin(phi)*sin(tet) ;
00111 rad.set(2) = cos(tet) ;
00112
00113 Cmp integ_hor2 (hole.mp) ;
00114 integ_hor2.annule_hard() ;
00115 integ_hor2.set_dzpuis(2) ;
00116 for (int m=0 ; m<3 ; m++)
00117 for (int n=0 ; n<3 ; n++)
00118 integ_hor2 += rad(m)*rad(n)*hole.tkij_tot(m,n) ;
00119 integ_hor2 *= pow(hole.psi_tot(),3.)/4. ;
00120 integ_hor2.std_base_scal() ;
00121
00122 Tenseur auxi_ns (flat_scalar_prod(star.tkij_tot, star.tkij_auto)) ;
00123 Tenseur kk_ns (star.mp) ;
00124 kk_ns = 0 ;
00125 Tenseur work_ns(star.mp) ;
00126 work_ns.set_etat_qcq() ;
00127 for (int i=0 ; i<3 ; i++) {
00128 work_ns.set() = auxi_ns(i, i) ;
00129 kk_ns = kk_ns + work_ns ;
00130 }
00131 Cmp integ_ns (pow(star.confpsi_comp() + star.confpsi_auto(), 5.)*kk_ns()) ;
00132 integ_ns.std_base_scal() ;
00133
00134 Cmp integ_matter (pow(star.confpsi_comp()+star.confpsi_auto(), 5.)*star.ener_euler()) ;
00135 integ_matter.std_base_scal() ;
00136
00137 double masse = (integ_bh.integrale()+integ_ns.integrale())/16/M_PI +
00138 hole.mp.integrale_surface(integ_hor1, hole.rayon)/hole.rayon/4/M_PI +
00139 hole.mp.integrale_surface(integ_hor2, hole.rayon)/2/M_PI
00140 + integ_matter.integrale()*ggrav ;
00141
00142 return masse ;
00143 }
00144
00145 double Bin_ns_bh::komar_systeme() const {
00146 Cmp der_un (hole.n_auto().dsdr()) ;
00147
00148 Map_af auxi_mp (star.get_mp()) ;
00149 Cmp der_deux (star.n_auto().dsdr()) ;
00150
00151 double masse = hole.mp.integrale_surface_infini(der_un) +
00152 auxi_mp.integrale_surface_infini(der_deux) ;
00153
00154 masse /= 4*M_PI ;
00155
00156 return masse ;
00157 }
00158
00159 double Bin_ns_bh::viriel() const {
00160 double adm = adm_systeme() ;
00161 double komar = komar_systeme() ;
00162
00163 return (adm-komar)/adm ;
00164 }
00165
00166 double Bin_ns_bh::moment_systeme_inf() const {
00167
00168 if (omega == 0)
00169 return 0 ;
00170 else {
00171
00172
00173 int nzones = hole.mp.get_mg()->get_nzone() ;
00174 double* bornes = new double [nzones+1] ;
00175 double courant = fabs(hole.mp.get_ori_x()-star.mp.get_ori_x())+1 ;
00176 for (int i=nzones-1 ; i>0 ; i--) {
00177 bornes[i] = courant ;
00178 courant /= 2. ;
00179 }
00180 bornes[0] = 0 ;
00181 bornes[nzones] = __infinity ;
00182
00183 Map_af mapping (*hole.mp.get_mg(), bornes) ;
00184
00185 delete [] bornes ;
00186
00187
00188 Tenseur_sym k_total (mapping, 2, CON, mapping.get_bvect_cart()) ;
00189 k_total.set_etat_qcq() ;
00190
00191 Tenseur shift_un (mapping, 1, CON, mapping.get_bvect_cart()) ;
00192 shift_un.set_etat_qcq() ;
00193
00194 Tenseur shift_deux (mapping, 1, CON, mapping.get_bvect_cart()) ;
00195 shift_deux.set_etat_qcq() ;
00196
00197 shift_un.set_triad (*hole.shift_auto.get_triad()) ;
00198 shift_un.set(0).import(hole.shift_auto(0)) ;
00199 shift_un.set(1).import(hole.shift_auto(1)) ;
00200 shift_un.set(2).import(hole.shift_auto(2)) ;
00201 shift_un.change_triad (mapping.get_bvect_cart()) ;
00202
00203 shift_deux.set_triad (*star.shift_auto.get_triad()) ;
00204 shift_deux.set(0).import(star.shift_auto(0)) ;
00205 shift_deux.set(1).import(star.shift_auto(1)) ;
00206 shift_deux.set(2).import(star.shift_auto(2)) ;
00207 shift_deux.change_triad(mapping.get_bvect_cart()) ;
00208
00209 Tenseur shift_tot (shift_un+shift_deux) ;
00210 shift_tot.set_std_base() ;
00211 shift_tot.annule(0, nzones-2) ;
00212
00213 shift_tot.inc2_dzpuis() ;
00214 shift_tot.dec2_dzpuis() ;
00215
00216 Tenseur grad (shift_tot.gradient()) ;
00217 Tenseur trace (grad(0, 0)+grad(1, 1)+grad(2, 2)) ;
00218 for (int i=0 ; i<3 ; i++) {
00219 k_total.set(i, i) = grad(i, i)-trace()/3. ;
00220 for (int j=i+1 ; j<3 ; j++)
00221 k_total.set(i, j) = (grad(i, j)+grad(j, i))/2. ;
00222 }
00223
00224 for (int lig=0 ; lig<3 ; lig++)
00225 for (int col=lig ; col<3 ; col++)
00226 k_total.set(lig, col).mult_r_zec() ;
00227
00228 Tenseur vecteur_un (mapping, 1, CON, mapping.get_bvect_cart()) ;
00229 vecteur_un.set_etat_qcq() ;
00230 for (int i=0 ; i<3 ; i++)
00231 vecteur_un.set(i) = k_total(0, i) ;
00232 vecteur_un.change_triad (mapping.get_bvect_spher()) ;
00233 Cmp integrant_un (vecteur_un(0)) ;
00234
00235 Tenseur vecteur_deux (mapping, 1, CON, mapping.get_bvect_cart()) ;
00236 vecteur_deux.set_etat_qcq() ;
00237 for (int i=0 ; i<3 ; i++)
00238 vecteur_deux.set(i) = k_total(1, i) ;
00239 vecteur_deux.change_triad (mapping.get_bvect_spher()) ;
00240 Cmp integrant_deux (vecteur_deux(0)) ;
00241
00242
00243 integrant_un.va = integrant_un.va.mult_st() ;
00244 integrant_un.va = integrant_un.va.mult_sp() ;
00245
00246 integrant_deux.va = integrant_deux.va.mult_st() ;
00247 integrant_deux.va = integrant_deux.va.mult_cp() ;
00248
00249 double moment = mapping.integrale_surface_infini (-integrant_un+integrant_deux) ;
00250
00251 moment /= 8*M_PI ;
00252 return moment ;
00253 }
00254 }
00255
00256 double Bin_ns_bh::moment_systeme_hor() const {
00257
00258 using namespace Unites ;
00259
00260 if (omega == 0)
00261 return 0 ;
00262 else {
00263
00264 Cmp xa_bh (hole.mp) ;
00265 xa_bh = hole.mp.xa ;
00266 xa_bh.std_base_scal() ;
00267
00268 Cmp ya_bh (hole.mp) ;
00269 ya_bh = hole.mp.ya ;
00270 ya_bh.std_base_scal() ;
00271
00272 Tenseur vecteur_bh (hole.mp, 1, CON, hole.mp.get_bvect_cart()) ;
00273 vecteur_bh.set_etat_qcq() ;
00274 for (int i=0 ; i<3 ; i++)
00275 vecteur_bh.set(i) = (-ya_bh*hole.tkij_tot(0, i)+
00276 xa_bh * hole.tkij_tot(1, i)) ;
00277 vecteur_bh.set_std_base() ;
00278 vecteur_bh.annule(hole.mp.get_mg()->get_nzone()-1) ;
00279 vecteur_bh.change_triad (hole.mp.get_bvect_spher()) ;
00280
00281 Cmp integrant_bh (pow(hole.psi_tot(), 6)*vecteur_bh(0)) ;
00282 integrant_bh.std_base_scal() ;
00283 double moment_bh = hole.mp.integrale_surface
00284 (integrant_bh, hole.rayon)/8/M_PI ;
00285
00286
00287 Cmp xa_ns (star.mp) ;
00288 xa_ns = star.mp.xa ;
00289 xa_ns.std_base_scal() ;
00290
00291 Cmp ya_ns (star.mp) ;
00292 ya_ns = star.mp.ya ;
00293 ya_ns.std_base_scal() ;
00294
00295 Cmp integrant_ns (pow(star.confpsi_auto()+star.confpsi_comp(), 10)*(star.ener_euler()+star.press())*
00296 (xa_ns*star.u_euler(1) - ya_ns*star.u_euler(0))) ;
00297 integrant_ns.std_base_scal() ;
00298
00299 double moment_ns = integrant_ns.integrale() * ggrav ;
00300 return moment_ns + moment_bh ;
00301 }
00302 }
00303
00304 Tbl Bin_ns_bh::linear_momentum_systeme_inf() const {
00305
00306 Tbl res (3) ;
00307 res.set_etat_qcq() ;
00308
00309
00310 int nzones = hole.mp.get_mg()->get_nzone() ;
00311 double* bornes = new double [nzones+1] ;
00312 double courant = fabs(hole.mp.get_ori_x()-star.mp.get_ori_x())+1 ;
00313 for (int i=nzones-1 ; i>0 ; i--) {
00314 bornes[i] = courant ;
00315 courant /= 2. ;
00316 }
00317 bornes[0] = 0 ;
00318 bornes[nzones] = __infinity ;
00319
00320 Map_af mapping (*hole.mp.get_mg(), bornes) ;
00321
00322 delete [] bornes ;
00323
00324
00325 Tenseur_sym k_total (mapping, 2, CON, mapping.get_bvect_cart()) ;
00326 k_total.set_etat_qcq() ;
00327
00328 Tenseur shift_un (mapping, 1, CON, mapping.get_bvect_cart()) ;
00329 shift_un.set_etat_qcq() ;
00330
00331 Tenseur shift_deux (mapping, 1, CON, mapping.get_bvect_cart()) ;
00332 shift_deux.set_etat_qcq() ;
00333
00334 shift_un.set_triad (*hole.shift_auto.get_triad()) ;
00335 shift_un.set(0).import(hole.shift_auto(0)) ;
00336 shift_un.set(1).import(hole.shift_auto(1)) ;
00337 shift_un.set(2).import(hole.shift_auto(2)) ;
00338 shift_un.change_triad (mapping.get_bvect_cart()) ;
00339
00340 shift_deux.set_triad (*star.shift_auto.get_triad()) ;
00341 shift_deux.set(0).import(star.shift_auto(0)) ;
00342 shift_deux.set(1).import(star.shift_auto(1)) ;
00343 shift_deux.set(2).import(star.shift_auto(2)) ;
00344 shift_deux.change_triad(mapping.get_bvect_cart()) ;
00345
00346 shift_un.set_std_base() ;
00347 shift_deux.set_std_base() ;
00348
00349 Tenseur shift_tot (shift_un+shift_deux) ;
00350 shift_tot.set_std_base() ;
00351 shift_tot.annule(0, nzones-2) ;
00352
00353 Cmp compy (shift_tot(1)) ;
00354 compy.mult_r_zec() ;
00355
00356 int nr = mapping.get_mg()->get_nr(nzones-1) ;
00357 int nt = mapping.get_mg()->get_nt(nzones-1) ;
00358 int np = mapping.get_mg()->get_np(nzones-1) ;
00359 Tbl val_inf (nt*np) ;
00360 val_inf.set_etat_qcq() ;
00361 for (int k=0 ; k<np ; k++)
00362 for (int j=0 ; j<nt ; j++)
00363 val_inf.set(k*nt + j) = fabs(compy (nzones-1, k, j, nr-1)) ;
00364
00365 Tenseur grad (shift_tot.gradient()) ;
00366 Tenseur trace (grad(0, 0)+grad(1, 1)+grad(2, 2)) ;
00367 for (int i=0 ; i<3 ; i++) {
00368 k_total.set(i, i) = grad(i, i)-trace()/3. ;
00369 for (int j=i+1 ; j<3 ; j++)
00370 k_total.set(i, j) = (grad(i, j)+grad(j, i))/2. ;
00371 }
00372
00373 for (int comp=0 ; comp<3 ; comp++) {
00374 Tenseur vecteur (mapping, 1, CON, mapping.get_bvect_cart()) ;
00375 vecteur.set_etat_qcq() ;
00376 for (int i=0 ; i<3 ; i++)
00377 vecteur.set(i) = k_total(i, comp) ;
00378 vecteur.change_triad (mapping.get_bvect_spher()) ;
00379 Cmp integrant (vecteur(0)) ;
00380
00381 res.set(comp) = mapping.integrale_surface_infini (integrant)/8/M_PI ;
00382 }
00383 return res ;
00384 }
00385
00386 double Bin_ns_bh::distance_propre_axe_bh (const int nr) const {
00387
00388 double x_bh = hole.mp.get_ori_x() + hole.rayon ;
00389
00390
00391 double pente = -2./x_bh ;
00392 double constante = - 1. ;
00393
00394 double ksi ;
00395 double xabs ;
00396 double air_un, theta_un, phi_un ;
00397 double air_deux, theta_deux, phi_deux ;
00398
00399 double* coloc = new double[nr] ;
00400 double* coef = new double[nr] ;
00401 int* deg = new int[3] ;
00402 deg[0] = 1 ; deg[1] = 1 ; deg[2] = nr ;
00403
00404 for (int i=0 ; i<nr ; i++) {
00405 ksi = -cos (M_PI*i/(nr-1)) ;
00406 xabs = (ksi+constante)/pente ;
00407
00408 hole.mp.convert_absolute (xabs, 0, 0, air_un, theta_un, phi_un) ;
00409 star.mp.convert_absolute (xabs, 0, 0, air_deux, theta_deux, phi_deux) ;
00410
00411 coloc[i] = pow (hole.psi_auto().val_point (air_un, theta_un, phi_un) +
00412 star.confpsi_auto().val_point (air_deux, theta_deux, phi_deux), 2.) ;
00413 }
00414
00415
00416 cfrcheb(deg, deg, coloc, deg, coef) ;
00417
00418
00419 double* som = new double[nr] ;
00420 som[0] = 2 ;
00421 for (int i=2 ; i<nr ; i+=2)
00422 som[i] = 1./(i+1)-1./(i-1) ;
00423 for (int i=1 ; i<nr ; i+=2)
00424 som[i] = 0 ;
00425
00426 double res = 0 ;
00427 for (int i=0 ; i<nr ; i++)
00428 res += som[i]*coef[i] ;
00429
00430 res /= pente ;
00431
00432 delete [] deg ;
00433 delete [] coef ;
00434 delete [] coloc ;
00435 delete [] som ;
00436
00437 return res ;
00438 }
00439
00440 double Bin_ns_bh::distance_propre_axe_ns (const int nr) const {
00441
00442 double x_ns = star.mp.get_ori_x() - star.mp.val_r (star.nzet, -1, M_PI/2, M_PI) ;
00443
00444
00445 double pente = 2./x_ns ;
00446 double constante = - 1. ;
00447
00448 double ksi ;
00449 double xabs ;
00450 double air_un, theta_un, phi_un ;
00451 double air_deux, theta_deux, phi_deux ;
00452
00453 double* coloc = new double[nr] ;
00454 double* coef = new double[nr] ;
00455 int* deg = new int[3] ;
00456 deg[0] = 1 ; deg[1] = 1 ; deg[2] = nr ;
00457
00458 for (int i=0 ; i<nr ; i++) {
00459 ksi = -cos (M_PI*i/(nr-1)) ;
00460 xabs = (ksi-constante)/pente ;
00461
00462 hole.mp.convert_absolute (xabs, 0, 0, air_un, theta_un, phi_un) ;
00463 star.mp.convert_absolute (xabs, 0, 0, air_deux, theta_deux, phi_deux) ;
00464
00465 coloc[i] = pow (hole.psi_auto().val_point (air_un, theta_un, phi_un) +
00466 star.confpsi_auto().val_point (air_deux, theta_deux, phi_deux), 2.) ;
00467 }
00468
00469
00470 cfrcheb(deg, deg, coloc, deg, coef) ;
00471
00472
00473 double* som = new double[nr] ;
00474 som[0] = 2 ;
00475 for (int i=2 ; i<nr ; i+=2)
00476 som[i] = 1./(i+1)-1./(i-1) ;
00477 for (int i=1 ; i<nr ; i+=2)
00478 som[i] = 0 ;
00479
00480 double res = 0 ;
00481 for (int i=0 ; i<nr ; i++)
00482 res += som[i]*coef[i] ;
00483
00484 res /= pente ;
00485
00486 delete [] deg ;
00487 delete [] coef ;
00488 delete [] coloc ;
00489 delete [] som ;
00490
00491 return res ;
00492 }
00493
00494 double Bin_ns_bh::smarr() const {
00495
00496 using namespace Unites ;
00497
00498
00499 Tenseur psiq_t (pow(star.get_confpsi()(), 4.)) ;
00500 psiq_t.set_std_base() ;
00501
00502 Tenseur_sym furmet (star.mp, 2, CON, star.mp.get_bvect_cart()) ;
00503 furmet.set_etat_qcq() ;
00504 for (int i=0 ; i< 3 ; i++) {
00505 furmet.set(i,i) = 1/psiq_t() ;
00506 for(int j=i+1 ; j<3 ; j++)
00507 furmet.set(i,j) = 0 ;
00508 }
00509 Metrique met (furmet, false) ;
00510
00511 Tenseur_sym kij (star.get_tkij_tot()/psiq_t) ;
00512 kij.change_triad(star.mp.get_bvect_cart()) ;
00513 kij.dec2_dzpuis() ;
00514 Tenseur_sym kij_cov (manipule (kij, met)) ;
00515 Tenseur shift (star.get_shift()) ;
00516 shift.change_triad(star.mp.get_bvect_cart()) ;
00517
00518 Tenseur aime (star.mp, 1, CON, star.mp.get_bvect_cart()) ;
00519 aime.set_etat_qcq() ;
00520 aime.set(0) = -omega*star.mp.ya ;
00521 aime.set(1) = omega*star.mp.xa ;
00522 aime.set(2) = 0 ;
00523 aime.annule(star.mp.get_mg()->get_nzone()-1) ;
00524 aime.set_std_base() ;
00525 shift = shift - aime ;
00526
00527
00528 Tenseur u_euler (star.get_u_euler()) ;
00529 u_euler.change_triad(star.mp.get_bvect_cart()) ;
00530 Tenseur u_i_bas (manipule(u_euler, met)) ;
00531 Tenseur mat (qpig*(star.get_nnn()*(star.get_ener_euler() + star.get_s_euler()) - 2*(star.get_ener_euler()+star.get_press())*contract(u_i_bas, 0, shift, 0))) ;
00532
00533
00534 Cmp psiq (pow(star.get_confpsi()(), 4.)) ;
00535
00536 Cmp integ_matter (star.get_nnn()()*(star.get_ener_euler()() + star.get_s_euler()())
00537 - 2*(star.get_ener_euler()()+star.get_press()())*psiq*flat_scalar_prod(u_euler, shift)()) ;
00538 integ_matter = integ_matter * pow(star.get_confpsi()(),6.) ;
00539 integ_matter.std_base_scal() ;
00540 integ_matter.annule(star.get_nzet(), star.get_mp().get_mg()->get_nzone()-1) ;
00541 double matter_term = integ_matter.integrale()*qpig/4/M_PI ;
00542
00543
00544 Cmp tet (hole.mp) ;
00545 tet = hole.mp.tet ;
00546 Cmp phi (hole.mp) ;
00547 phi = hole.mp.phi ;
00548 Tenseur rad (hole.mp, 1, COV, hole.mp.get_bvect_cart()) ;
00549 rad.set_etat_qcq() ;
00550 rad.set(0) = cos(phi)*sin(tet) ;
00551 rad.set(1) = sin(phi)*sin(tet) ;
00552 rad.set(2) = cos(tet) ;
00553
00554 Cmp temp (hole.mp) ;
00555 temp.annule_hard() ;
00556 temp.set_dzpuis(2) ;
00557 for (int m=0 ; m<3 ; m++)
00558 for (int n=0 ; n<3 ; n++)
00559 temp += rad(m)*rad(n)*hole.tkij_tot(m,n) ;
00560 temp *= pow(hole.psi_tot(),2.) ;
00561 temp.std_base_scal() ;
00562
00563 Cmp integ_hor ((hole.get_n_tot()().dsdr()-hole.get_n_tot()()*temp)
00564 *pow(hole.get_psi_tot()(), 2)) ;
00565 integ_hor.std_base_scal() ;
00566 integ_hor.raccord(1) ;
00567 double hor_term = hole.mp.integrale_surface(integ_hor, hole.get_rayon()) ;
00568 hor_term /= 4*M_PI ;
00569
00570 double m_test = hor_term + matter_term + 2*omega*moment_systeme_inf() +
00571 2*(hole.omega_local-omega)*hole.local_momentum() ;
00572
00573 return m_test ;
00574 }