binaire_orbite.C

00001  /*
00002  * Method of class Binaire to compute the orbital angular velocity {\tt omega}
00003  * and the position of the rotation axis {\tt x_axe}.
00004  *
00005  * (See file binaire.h for documentation)
00006  *
00007  */
00008 
00009 /*
00010  *   Copyright (c) 2000-2003 Eric Gourgoulhon
00011  *   Copyright (c) 2000-2001 Keisuke Taniguchi
00012  *
00013  *   This file is part of LORENE.
00014  *
00015  *   LORENE is free software; you can redistribute it and/or modify
00016  *   it under the terms of the GNU General Public License as published by
00017  *   the Free Software Foundation; either version 2 of the License, or
00018  *   (at your option) any later version.
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 
00032 char binaire_orbite_C[] = "$Header: /cvsroot/Lorene/C++/Source/Binaire/binaire_orbite.C,v 1.5 2011/03/27 16:42:21 e_gourgoulhon Exp $" ;
00033 
00034 /*
00035  * $Id: binaire_orbite.C,v 1.5 2011/03/27 16:42:21 e_gourgoulhon Exp $
00036  * $Log: binaire_orbite.C,v $
00037  * Revision 1.5  2011/03/27 16:42:21  e_gourgoulhon
00038  * Added output via new function save_profile for graphics.
00039  *
00040  * Revision 1.4  2009/06/18 18:40:57  k_taniguchi
00041  * Added a slightly modified code to determine
00042  * the orbital angular velocity.
00043  *
00044  * Revision 1.3  2004/03/25 10:28:59  j_novak
00045  * All LORENE's units are now defined in the namespace Unites (in file unites.h).
00046  *
00047  * Revision 1.2  2003/09/16 13:41:27  e_gourgoulhon
00048  * Search of sub-intervals containing the zero(s) via zero_list
00049  * Selection of the sub-interval as the closest one to previous value of omega.
00050  * Replaced zerosec by zerosec_b.
00051  *
00052  * Revision 1.1.1.1  2001/11/20 15:19:30  e_gourgoulhon
00053  * LORENE
00054  *
00055  * Revision 2.9  2001/08/14  12:36:45  keisuke
00056  * Change of the minimum and maximum values for searching a new position
00057  *  of the rotation axis.
00058  *
00059  * Revision 2.8  2001/03/20  16:06:55  keisuke
00060  * Addition of the method directly to calculate
00061  *  the orbital angular velocity (we do not use this method!).
00062  *
00063  * Revision 2.7  2001/03/19  17:10:28  keisuke
00064  * Change of the definition of the canter of mass.
00065  *
00066  * Revision 2.6  2001/03/19  13:37:04  keisuke
00067  * Set x_axe to be zero for the case of identical stars.
00068  *
00069  * Revision 2.5  2001/03/17  16:17:20  keisuke
00070  * Input a subroutine to determine the position of the rotation axis
00071  *  in the case of binary systems composed of different stars.
00072  *
00073  * Revision 2.4  2000/10/02  08:29:34  keisuke
00074  * Change the method to construct d_logn_auto in the calculation of dnulg[i].
00075  *
00076  * Revision 2.3  2000/09/22  15:56:32  keisuke
00077  * *** empty log message ***
00078  *
00079  * Revision 2.2  2000/09/22  15:52:12  keisuke
00080  * Changement calcul de dlogn (prise en compte d'une partie divergente
00081  * dans logn_auto par l'appel a d_logn_auto).
00082  *
00083  * Revision 2.1  2000/02/12  18:36:09  eric
00084  * *** empty log message ***
00085  *
00086  * Revision 2.0  2000/02/12  17:09:21  eric
00087  * *** empty log message ***
00088  *
00089  *
00090  * $Header: /cvsroot/Lorene/C++/Source/Binaire/binaire_orbite.C,v 1.5 2011/03/27 16:42:21 e_gourgoulhon Exp $
00091  *
00092  */
00093 
00094 // Headers C
00095 #include <math.h>
00096 
00097 // Headers Lorene 
00098 #include "binaire.h"
00099 #include "eos.h"
00100 #include "param.h"
00101 #include "utilitaires.h"
00102 #include "unites.h"
00103 
00104 #include "scalar.h"
00105 #include "graphique.h"
00106 
00107 double  fonc_binaire_axe(double , const Param& ) ;
00108 double  fonc_binaire_orbit(double , const Param& ) ;
00109 
00110 //******************************************************************************
00111 
00112 void Binaire::orbit(double fact_omeg_min, double fact_omeg_max, double& xgg1, 
00113              double& xgg2) {
00114 
00115   using namespace Unites ;
00116     
00117     //-------------------------------------------------------------
00118     // Evaluation of various quantities at the center of each star
00119     //-------------------------------------------------------------
00120 
00121     double dnulg[2], asn2[2], dasn2[2], ny[2], dny[2], npn[2], dnpn[2], xgg[2] ;     
00122     double nyso[2], dnyso[2], npnso2[2], dnpnso2[2], ori_x[2] ;
00123 
00124     for (int i=0; i<2; i++) {
00125     
00126     const Map& mp = et[i]->get_mp() ; 
00127 
00128     const Cmp& logn_auto_regu = et[i]->get_logn_auto_regu()() ; 
00129     const Cmp& logn_comp = et[i]->get_logn_comp()() ; 
00130     const Cmp& loggam = et[i]->get_loggam()() ; 
00131     const Cmp& nnn = et[i]->get_nnn()() ; 
00132     const Cmp& a_car = et[i]->get_a_car()() ; 
00133     const Tenseur& shift = et[i]->get_shift() ; 
00134     const Tenseur& d_logn_auto_div = et[i]->get_d_logn_auto_div() ; 
00135 
00136     Tenseur dln_auto_div = d_logn_auto_div ;
00137 
00138     if ( *(dln_auto_div.get_triad()) != ref_triad ) {
00139 
00140       // Change the basis from spherical coordinate to Cartesian one
00141       dln_auto_div.change_triad( mp.get_bvect_cart() ) ;
00142 
00143       // Change the basis from mapping coordinate to absolute one
00144       dln_auto_div.change_triad( ref_triad ) ;
00145 
00146     }
00147 
00148     //----------------------------------
00149     // Calcul de d/dX( nu + ln(Gamma) ) au centre de l'etoile ---> dnulg[i]
00150     //----------------------------------
00151     
00152     // Facteur de passage x --> X :
00153     double factx ;
00154     if (fabs(mp.get_rot_phi()) < 1.e-14) {
00155         factx = 1. ; 
00156     }
00157     else {
00158         if (fabs(mp.get_rot_phi() - M_PI) < 1.e-14) {
00159         factx = - 1. ; 
00160         }
00161         else {
00162         cout << "Binaire::orbit : unknown value of rot_phi !" << endl ;
00163         abort() ; 
00164         }
00165     }
00166         
00167     Cmp tmp = logn_auto_regu + logn_comp + loggam ;
00168     
00169     // ... gradient suivant X :         
00170     dnulg[i] = dln_auto_div(0)(0, 0, 0, 0)
00171       + factx * tmp.dsdx()(0, 0, 0, 0) ; 
00172     
00173     tmp = logn_auto_regu + logn_comp ; 
00174     cout << "dlnndx_div_c : " <<  dln_auto_div(0)(0, 0, 0, 0)  << endl ; 
00175     cout << "dlnndx_c : " <<  dln_auto_div(0)(0, 0, 0, 0) + factx*tmp.dsdx()(0, 0, 0, 0) << endl ; 
00176                   
00177     cout << "dloggamdx_c : " <<  factx*loggam.dsdx()(0, 0, 0, 0) << endl ; 
00178     Scalar stmp(logn_comp) ; 
00179         save_profile(stmp, 0., 10., 0.5*M_PI, 0., "prof_logn.d") ; 
00180     stmp = loggam ; 
00181         save_profile(stmp, 0., 1.8, 0.5*M_PI, 0., "prof_loggam.d") ; 
00182   
00183     //----------------------------------
00184     // Calcul de A^2/N^2 au centre de l'etoile ---> asn2[i]
00185     //----------------------------------
00186 
00187     double nc = nnn(0, 0, 0, 0) ;
00188     double a2c = a_car(0, 0, 0, 0) ;
00189     asn2[i] = a2c / (nc * nc) ;
00190      
00191     if ( et[i]->is_relativistic() ) {
00192 
00193         //----------------------------------
00194         // Calcul de d/dX(A^2/N^2) au centre de l'etoile ---> dasn2[i]
00195         //----------------------------------
00196 
00197         double da2c = factx * a_car.dsdx()(0, 0, 0, 0) ; 
00198         double dnc =  factx * nnn.dsdx()(0, 0, 0, 0) ;
00199 
00200         dasn2[i] = ( da2c - 2 * a2c / nc * dnc ) / (nc*nc) ; 
00201 
00202         //----------------------------------
00203         // Calcul de N^Y au centre de l'etoile ---> ny[i]
00204         //----------------------------------
00205 
00206         ny[i] = shift(1)(0, 0, 0, 0) ; 
00207         nyso[i] = ny[i] / omega ;
00208         
00209         //----------------------------------
00210         // Calcul de dN^Y/dX au centre de l'etoile ---> dny[i]
00211         //----------------------------------
00212         
00213         dny[i] = factx * shift(1).dsdx()(0, 0, 0, 0) ; 
00214         dnyso[i] = dny[i] / omega ;
00215 
00216         //----------------------------------
00217         // Calcul de (N^X)^2 + (N^Y)^2 + (N^Z)^2 
00218         //                   au centre de l'etoile ---> npn[i]
00219         //----------------------------------
00220 
00221         tmp = flat_scalar_prod(shift, shift)() ; 
00222 
00223         npn[i] = tmp(0, 0, 0, 0) ; 
00224         npnso2[i] = npn[i] / omega / omega ;
00225 
00226         //----------------------------------
00227         // Calcul de d/dX( (N^X)^2 + (N^Y)^2 + (N^Z)^2 )
00228         //                   au centre de l'etoile ---> dnpn[i]
00229         //----------------------------------
00230         
00231         dnpn[i] = factx * tmp.dsdx()(0, 0, 0, 0) ; 
00232         dnpnso2[i] = dnpn[i] / omega / omega ;
00233 
00234     }       // fin du cas relativiste 
00235     else {
00236         dasn2[i] = 0 ; 
00237         ny[i] = 0 ; 
00238         nyso[i] = 0 ;
00239         dny[i] = 0 ; 
00240         dnyso[i] = 0 ;
00241         npn[i] = 0 ; 
00242         npnso2[i] = 0 ;
00243         dnpn[i] = 0 ; 
00244         dnpnso2[i] = 0 ;
00245     }
00246 
00247     cout << "Binaire::orbit: central d(nu+log(Gam))/dX : " 
00248          << dnulg[i] << endl ; 
00249     cout << "Binaire::orbit: central A^2/N^2 : " << asn2[i] << endl ; 
00250     cout << "Binaire::orbit: central d(A^2/N^2)/dX : " << dasn2[i] << endl ; 
00251     cout << "Binaire::orbit: central N^Y : " << ny[i] << endl ; 
00252     cout << "Binaire::orbit: central dN^Y/dX : " << dny[i] << endl ; 
00253     cout << "Binaire::orbit: central N.N : " << npn[i] << endl ; 
00254     cout << "Binaire::orbit: central d(N.N)/dX : " << dnpn[i] << endl ; 
00255 
00256     //----------------------
00257     // Pour information seulement : 1/ calcul des positions des "centres de
00258     //                  de masse"
00259     //              2/ calcul de dH/dX en r=0
00260     //-----------------------
00261 
00262         ori_x[i] = (et[i]->get_mp()).get_ori_x() ;
00263 
00264     xgg[i] = factx * (et[i]->xa_barycenter() - ori_x[i]) ;
00265          
00266     } // fin de la boucle sur les etoiles 
00267 
00268     xgg1 = xgg[0] ;
00269     xgg2 = xgg[1] ;
00270     
00271 //---------------------------------
00272 //  Position de l'axe de rotation   
00273 //---------------------------------
00274 
00275     int relat = ( et[0]->is_relativistic() ) ? 1 : 0 ;
00276     double ori_x1 = ori_x[0] ;
00277     double ori_x2 = ori_x[1] ;
00278 
00279     if ( et[0]->get_eos() == et[1]->get_eos() &&
00280      et[0]->get_ent()()(0,0,0,0) == et[1]->get_ent()()(0,0,0,0) ) {
00281 
00282         x_axe = 0. ;
00283 
00284     }
00285     else {
00286 
00287     Param paraxe ;
00288     paraxe.add_int(relat) ;
00289     paraxe.add_double( ori_x1, 0) ;
00290     paraxe.add_double( ori_x2, 1) ;
00291     paraxe.add_double( dnulg[0], 2) ;
00292     paraxe.add_double( dnulg[1], 3) ;
00293     paraxe.add_double( asn2[0], 4) ;
00294     paraxe.add_double( asn2[1], 5) ;
00295     paraxe.add_double( dasn2[0], 6) ;
00296     paraxe.add_double( dasn2[1], 7) ;
00297     paraxe.add_double( nyso[0], 8) ;
00298     paraxe.add_double( nyso[1], 9) ;
00299     paraxe.add_double( dnyso[0], 10) ;
00300     paraxe.add_double( dnyso[1], 11) ;
00301     paraxe.add_double( npnso2[0], 12) ;
00302     paraxe.add_double( npnso2[1], 13) ;
00303     paraxe.add_double( dnpnso2[0], 14) ;
00304     paraxe.add_double( dnpnso2[1], 15) ;
00305 
00306     int nitmax_axe = 200 ; 
00307     int nit_axe ; 
00308     double precis_axe = 1.e-13 ;
00309 
00310     x_axe = zerosec(fonc_binaire_axe, paraxe, 0.9*ori_x1, 0.9*ori_x2,
00311             precis_axe, nitmax_axe, nit_axe) ;
00312 
00313     cout << "Binaire::orbit : Number of iterations in zerosec for x_axe : "
00314          << nit_axe << endl ;
00315     }
00316 
00317     cout << "Binaire::orbit : x_axe [km] : " << x_axe / km << endl ; 
00318 
00319 //-------------------------------------
00320 //  Calcul de la vitesse orbitale    
00321 //-------------------------------------
00322 
00323     Param parf ; 
00324     parf.add_int(relat) ; 
00325     parf.add_double( (et[0]->get_mp()).get_ori_x(), 0) ; 
00326     parf.add_double( dnulg[0], 1) ;  
00327     parf.add_double( asn2[0], 2) ;    
00328     parf.add_double( dasn2[0], 3) ;    
00329     parf.add_double( ny[0], 4) ;    
00330     parf.add_double( dny[0], 5) ;    
00331     parf.add_double( npn[0], 6) ;    
00332     parf.add_double( dnpn[0], 7) ;    
00333     parf.add_double( x_axe, 8) ; 
00334 
00335     double omega1 = fact_omeg_min * omega  ; 
00336     double omega2 = fact_omeg_max * omega ; 
00337     cout << "Binaire::orbit: omega1,  omega2 [rad/s] : " 
00338      << omega1 * f_unit << "  " << omega2 * f_unit << endl ; 
00339 
00340     // Search for the various zeros in the interval [omega1,omega2]
00341     // ------------------------------------------------------------
00342     int nsub = 50 ;  // total number of subdivisions of the interval
00343     Tbl* azer = 0x0 ;
00344     Tbl* bzer = 0x0 ; 
00345     zero_list(fonc_binaire_orbit, parf, omega1, omega2, nsub,
00346           azer, bzer) ; 
00347     
00348     // Search for the zero closest to the previous value of omega
00349     // ----------------------------------------------------------
00350     double omeg_min, omeg_max ; 
00351     int nzer = azer->get_taille() ; // number of zeros found by zero_list
00352     cout << "Binaire:orbit : " << nzer << 
00353          " zero(s) found in the interval [omega1,  omega2]." << endl ; 
00354     cout << "omega, omega1, omega2 : " << omega << "  " << omega1
00355         << "  " << omega2 << endl ; 
00356     cout << "azer : " << *azer << endl ;
00357     cout << "bzer : " << *bzer << endl ;
00358     
00359     if (nzer == 0) {
00360         cout << 
00361         "Binaire::orbit: WARNING : no zero detected in the interval"
00362         << endl << "   [" << omega1 * f_unit << ", " 
00363         << omega2 * f_unit << "]  rad/s  !" << endl ; 
00364         omeg_min = omega1 ; 
00365         omeg_max = omega2 ; 
00366     }
00367     else {
00368         double dist_min = fabs(omega2 - omega1) ;  
00369         int i_dist_min = -1 ;       
00370         for (int i=0; i<nzer; i++) {
00371             // Distance of previous value of omega from the center of the
00372             //  interval [azer(i), bzer(i)] 
00373             double dist = fabs( omega - 0.5 * ( (*azer)(i) + (*bzer)(i) ) ) ; 
00374             if (dist < dist_min) {
00375                 dist_min = dist ; 
00376                 i_dist_min = i ; 
00377             } 
00378         }
00379         omeg_min = (*azer)(i_dist_min) ;
00380         omeg_max = (*bzer)(i_dist_min) ;
00381     }
00382 
00383     delete azer ; // Tbl allocated by zero_list
00384     delete bzer ; //  
00385     
00386     cout << "Binaire:orbit : interval selected for the search of the zero : "
00387         << endl << "  [" << omeg_min << ", " << omeg_max << "]  =  [" 
00388          << omeg_min * f_unit << ", " << omeg_max * f_unit << "] rad/s " << endl ; 
00389     
00390     // Computation of the zero in the selected interval by the secant method
00391     // ---------------------------------------------------------------------
00392     int nitermax = 200 ; 
00393     int niter ; 
00394     double precis = 1.e-13 ;
00395     omega = zerosec_b(fonc_binaire_orbit, parf, omeg_min, omeg_max,
00396             precis, nitermax, niter) ;
00397     
00398     cout << "Binaire::orbit : Number of iterations in zerosec for omega : "
00399      << niter << endl ; 
00400     
00401     cout << "Binaire::orbit : omega [rad/s] : "
00402      << omega * f_unit << endl ; 
00403           
00404 
00405     /* We do not use the method below.
00406     // Direct calculation
00407     //--------------------
00408 
00409     double om2_et1 ;
00410     double om2_et2 ;
00411 
00412     double x_et1 = ori_x1 - x_axe ;
00413     double x_et2 = ori_x2 - x_axe ;
00414 
00415     if (relat == 1) {
00416 
00417       double andan_et1 = 0.5 * dasn2[0] + asn2[0] * dnulg[0] ;
00418       double andan_et2 = 0.5 * dasn2[1] + asn2[1] * dnulg[1] ;
00419 
00420       double bpb_et1 = x_et1 * x_et1 - 2. * nyso[0] * x_et1 + npnso2[0] ;
00421       double bpb_et2 = x_et2 * x_et2 - 2. * nyso[1] * x_et2 + npnso2[1] ;
00422 
00423       double cpc_et1 = 0.5 * dnpnso2[0] + x_et1 * (1. - dnyso[0]) - nyso[0] ;
00424       double cpc_et2 = 0.5 * dnpnso2[1] + x_et2 * (1. - dnyso[1]) - nyso[1] ;
00425 
00426       om2_et1 = dnulg[0] / (andan_et1 * bpb_et1 + asn2[0] * cpc_et1) ;
00427       om2_et2 = dnulg[1] / (andan_et2 * bpb_et2 + asn2[1] * cpc_et2) ;
00428 
00429     }
00430     else {
00431 
00432       om2_et1 = dnulg[0] / x_et1 ;
00433       om2_et2 = dnulg[1] / x_et2 ;
00434 
00435     }
00436 
00437     double ome_et1 = sqrt( om2_et1 ) ;
00438     double ome_et2 = sqrt( om2_et2 ) ;
00439 
00440     double diff_om1 = 1. - ome_et1 / ome_et2 ;
00441     double diff_om2 = 1. - ome_et1 / omega ;
00442 
00443     cout << "Binaire::orbit : omega (direct) [rad/s] : "
00444      << ome_et1 * f_unit << endl ;
00445 
00446     cout << "Binaire::orbit : relative difference between " << endl
00447      << " omega_star1 and omega_star2 (direct) : " << diff_om1 << endl
00448      << " omega (direct) and omega (iretation) : " << diff_om2 << endl ;
00449      */
00450 
00451 }
00452 
00453 
00454 void Binaire::orbit_eqmass(double fact_omeg_min, double fact_omeg_max,
00455                double mass1, double mass2,
00456                double& xgg1, double& xgg2) {
00457 
00458   using namespace Unites ;
00459     
00460     //-------------------------------------------------------------
00461     // Evaluation of various quantities at the center of each star
00462     //-------------------------------------------------------------
00463 
00464     double dnulg[2], asn2[2], dasn2[2], ny[2], dny[2], npn[2], dnpn[2], xgg[2] ;     
00465     double nyso[2], dnyso[2], npnso2[2], dnpnso2[2], ori_x[2] ;
00466 
00467     for (int i=0; i<2; i++) {
00468     
00469     const Map& mp = et[i]->get_mp() ; 
00470 
00471     const Cmp& logn_auto_regu = et[i]->get_logn_auto_regu()() ; 
00472     const Cmp& logn_comp = et[i]->get_logn_comp()() ; 
00473     const Cmp& loggam = et[i]->get_loggam()() ; 
00474     const Cmp& nnn = et[i]->get_nnn()() ; 
00475     const Cmp& a_car = et[i]->get_a_car()() ; 
00476     const Tenseur& shift = et[i]->get_shift() ; 
00477     const Tenseur& d_logn_auto_div = et[i]->get_d_logn_auto_div() ; 
00478 
00479     Tenseur dln_auto_div = d_logn_auto_div ;
00480 
00481     if ( *(dln_auto_div.get_triad()) != ref_triad ) {
00482 
00483       // Change the basis from spherical coordinate to Cartesian one
00484       dln_auto_div.change_triad( mp.get_bvect_cart() ) ;
00485 
00486       // Change the basis from mapping coordinate to absolute one
00487       dln_auto_div.change_triad( ref_triad ) ;
00488 
00489     }
00490 
00491     //----------------------------------
00492     // Calcul de d/dX( nu + ln(Gamma) ) au centre de l'etoile ---> dnulg[i]
00493     //----------------------------------
00494     
00495     // Facteur de passage x --> X :
00496     double factx ;
00497     if (fabs(mp.get_rot_phi()) < 1.e-14) {
00498         factx = 1. ; 
00499     }
00500     else {
00501         if (fabs(mp.get_rot_phi() - M_PI) < 1.e-14) {
00502         factx = - 1. ; 
00503         }
00504         else {
00505         cout << "Binaire::orbit : unknown value of rot_phi !" << endl ;
00506         abort() ; 
00507         }
00508     }
00509         
00510     Cmp tmp = logn_auto_regu + logn_comp + loggam ;
00511     
00512     // ... gradient suivant X :         
00513     dnulg[i] = dln_auto_div(0)(0, 0, 0, 0)
00514       + factx * tmp.dsdx()(0, 0, 0, 0) ; 
00515     
00516     //----------------------------------
00517     // Calcul de A^2/N^2 au centre de l'etoile ---> asn2[i]
00518     //----------------------------------
00519 
00520     double nc = nnn(0, 0, 0, 0) ;
00521     double a2c = a_car(0, 0, 0, 0) ;
00522     asn2[i] = a2c / (nc * nc) ;
00523      
00524     if ( et[i]->is_relativistic() ) {
00525 
00526         //----------------------------------
00527         // Calcul de d/dX(A^2/N^2) au centre de l'etoile ---> dasn2[i]
00528         //----------------------------------
00529 
00530         double da2c = factx * a_car.dsdx()(0, 0, 0, 0) ; 
00531         double dnc =  factx * nnn.dsdx()(0, 0, 0, 0) ;
00532 
00533         dasn2[i] = ( da2c - 2 * a2c / nc * dnc ) / (nc*nc) ; 
00534 
00535         //----------------------------------
00536         // Calcul de N^Y au centre de l'etoile ---> ny[i]
00537         //----------------------------------
00538 
00539         ny[i] = shift(1)(0, 0, 0, 0) ; 
00540         nyso[i] = ny[i] / omega ;
00541         
00542         //----------------------------------
00543         // Calcul de dN^Y/dX au centre de l'etoile ---> dny[i]
00544         //----------------------------------
00545         
00546         dny[i] = factx * shift(1).dsdx()(0, 0, 0, 0) ; 
00547         dnyso[i] = dny[i] / omega ;
00548 
00549         //----------------------------------
00550         // Calcul de (N^X)^2 + (N^Y)^2 + (N^Z)^2 
00551         //                   au centre de l'etoile ---> npn[i]
00552         //----------------------------------
00553 
00554         tmp = flat_scalar_prod(shift, shift)() ; 
00555 
00556         npn[i] = tmp(0, 0, 0, 0) ; 
00557         npnso2[i] = npn[i] / omega / omega ;
00558 
00559         //----------------------------------
00560         // Calcul de d/dX( (N^X)^2 + (N^Y)^2 + (N^Z)^2 )
00561         //                   au centre de l'etoile ---> dnpn[i]
00562         //----------------------------------
00563         
00564         dnpn[i] = factx * tmp.dsdx()(0, 0, 0, 0) ; 
00565         dnpnso2[i] = dnpn[i] / omega / omega ;
00566 
00567     }       // fin du cas relativiste 
00568     else {
00569         dasn2[i] = 0 ; 
00570         ny[i] = 0 ; 
00571         nyso[i] = 0 ;
00572         dny[i] = 0 ; 
00573         dnyso[i] = 0 ;
00574         npn[i] = 0 ; 
00575         npnso2[i] = 0 ;
00576         dnpn[i] = 0 ; 
00577         dnpnso2[i] = 0 ;
00578     }
00579 
00580     cout << "Binaire::orbit: central d(nu+log(Gam))/dX : " 
00581          << dnulg[i] << endl ; 
00582     cout << "Binaire::orbit: central A^2/N^2 : " << asn2[i] << endl ; 
00583     cout << "Binaire::orbit: central d(A^2/N^2)/dX : " << dasn2[i] << endl ; 
00584     cout << "Binaire::orbit: central N^Y : " << ny[i] << endl ; 
00585     cout << "Binaire::orbit: central dN^Y/dX : " << dny[i] << endl ; 
00586     cout << "Binaire::orbit: central N.N : " << npn[i] << endl ; 
00587     cout << "Binaire::orbit: central d(N.N)/dX : " << dnpn[i] << endl ; 
00588 
00589     //----------------------
00590     // Pour information seulement : 1/ calcul des positions des "centres de
00591     //                  de masse"
00592     //              2/ calcul de dH/dX en r=0
00593     //-----------------------
00594 
00595         ori_x[i] = (et[i]->get_mp()).get_ori_x() ;
00596 
00597     xgg[i] = factx * (et[i]->xa_barycenter() - ori_x[i]) ;
00598          
00599     } // fin de la boucle sur les etoiles 
00600 
00601     xgg1 = xgg[0] ;
00602     xgg2 = xgg[1] ;
00603     
00604 //---------------------------------
00605 //  Position de l'axe de rotation   
00606 //---------------------------------
00607 
00608     int relat = ( et[0]->is_relativistic() ) ? 1 : 0 ;
00609     double ori_x1 = ori_x[0] ;
00610     double ori_x2 = ori_x[1] ;
00611 
00612     if ( et[0]->get_eos() == et[1]->get_eos() && mass1 == mass2 ) {
00613 
00614         x_axe = 0. ;
00615 
00616     }
00617     else {
00618 
00619     Param paraxe ;
00620     paraxe.add_int(relat) ;
00621     paraxe.add_double( ori_x1, 0) ;
00622     paraxe.add_double( ori_x2, 1) ;
00623     paraxe.add_double( dnulg[0], 2) ;
00624     paraxe.add_double( dnulg[1], 3) ;
00625     paraxe.add_double( asn2[0], 4) ;
00626     paraxe.add_double( asn2[1], 5) ;
00627     paraxe.add_double( dasn2[0], 6) ;
00628     paraxe.add_double( dasn2[1], 7) ;
00629     paraxe.add_double( nyso[0], 8) ;
00630     paraxe.add_double( nyso[1], 9) ;
00631     paraxe.add_double( dnyso[0], 10) ;
00632     paraxe.add_double( dnyso[1], 11) ;
00633     paraxe.add_double( npnso2[0], 12) ;
00634     paraxe.add_double( npnso2[1], 13) ;
00635     paraxe.add_double( dnpnso2[0], 14) ;
00636     paraxe.add_double( dnpnso2[1], 15) ;
00637 
00638     int nitmax_axe = 200 ; 
00639     int nit_axe ; 
00640     double precis_axe = 1.e-13 ;
00641 
00642     x_axe = zerosec(fonc_binaire_axe, paraxe, 0.9*ori_x1, 0.9*ori_x2,
00643             precis_axe, nitmax_axe, nit_axe) ;
00644 
00645     cout << "Binaire::orbit : Number of iterations in zerosec for x_axe : "
00646          << nit_axe << endl ;
00647     }
00648 
00649     cout << "Binaire::orbit : x_axe [km] : " << x_axe / km << endl ; 
00650 
00651 //-------------------------------------
00652 //  Calcul de la vitesse orbitale    
00653 //-------------------------------------
00654 
00655     Param parf ; 
00656     parf.add_int(relat) ; 
00657     parf.add_double( (et[0]->get_mp()).get_ori_x(), 0) ; 
00658     parf.add_double( dnulg[0], 1) ;  
00659     parf.add_double( asn2[0], 2) ;    
00660     parf.add_double( dasn2[0], 3) ;    
00661     parf.add_double( ny[0], 4) ;    
00662     parf.add_double( dny[0], 5) ;    
00663     parf.add_double( npn[0], 6) ;    
00664     parf.add_double( dnpn[0], 7) ;    
00665     parf.add_double( x_axe, 8) ; 
00666 
00667     double omega1 = fact_omeg_min * omega  ; 
00668     double omega2 = fact_omeg_max * omega ; 
00669     cout << "Binaire::orbit: omega1,  omega2 [rad/s] : " 
00670      << omega1 * f_unit << "  " << omega2 * f_unit << endl ; 
00671 
00672     // Search for the various zeros in the interval [omega1,omega2]
00673     // ------------------------------------------------------------
00674     int nsub = 50 ;  // total number of subdivisions of the interval
00675     Tbl* azer = 0x0 ;
00676     Tbl* bzer = 0x0 ; 
00677     zero_list(fonc_binaire_orbit, parf, omega1, omega2, nsub,
00678           azer, bzer) ; 
00679     
00680     // Search for the zero closest to the previous value of omega
00681     // ----------------------------------------------------------
00682     double omeg_min, omeg_max ; 
00683     int nzer = azer->get_taille() ; // number of zeros found by zero_list
00684     cout << "Binaire:orbit : " << nzer << 
00685          " zero(s) found in the interval [omega1,  omega2]." << endl ; 
00686     cout << "omega, omega1, omega2 : " << omega << "  " << omega1
00687         << "  " << omega2 << endl ; 
00688     cout << "azer : " << *azer << endl ;
00689     cout << "bzer : " << *bzer << endl ;
00690     
00691     if (nzer == 0) {
00692         cout << 
00693         "Binaire::orbit: WARNING : no zero detected in the interval"
00694         << endl << "   [" << omega1 * f_unit << ", " 
00695         << omega2 * f_unit << "]  rad/s  !" << endl ; 
00696         omeg_min = omega1 ; 
00697         omeg_max = omega2 ; 
00698     }
00699     else {
00700         double dist_min = fabs(omega2 - omega1) ;  
00701         int i_dist_min = -1 ;       
00702         for (int i=0; i<nzer; i++) {
00703             // Distance of previous value of omega from the center of the
00704             //  interval [azer(i), bzer(i)] 
00705             double dist = fabs( omega - 0.5 * ( (*azer)(i) + (*bzer)(i) ) ) ; 
00706             if (dist < dist_min) {
00707                 dist_min = dist ; 
00708                 i_dist_min = i ; 
00709             } 
00710         }
00711         omeg_min = (*azer)(i_dist_min) ;
00712         omeg_max = (*bzer)(i_dist_min) ;
00713     }
00714 
00715     delete azer ; // Tbl allocated by zero_list
00716     delete bzer ; //  
00717     
00718     cout << "Binaire:orbit : interval selected for the search of the zero : "
00719         << endl << "  [" << omeg_min << ", " << omeg_max << "]  =  [" 
00720          << omeg_min * f_unit << ", " << omeg_max * f_unit << "] rad/s " << endl ; 
00721     
00722     // Computation of the zero in the selected interval by the secant method
00723     // ---------------------------------------------------------------------
00724     int nitermax = 200 ; 
00725     int niter ; 
00726     double precis = 1.e-13 ;
00727     omega = zerosec_b(fonc_binaire_orbit, parf, omeg_min, omeg_max,
00728             precis, nitermax, niter) ;
00729     
00730     cout << "Binaire::orbit : Number of iterations in zerosec for omega : "
00731      << niter << endl ; 
00732     
00733     cout << "Binaire::orbit : omega [rad/s] : "
00734      << omega * f_unit << endl ; 
00735           
00736 
00737     /* We do not use the method below.
00738     // Direct calculation
00739     //--------------------
00740 
00741     double om2_et1 ;
00742     double om2_et2 ;
00743 
00744     double x_et1 = ori_x1 - x_axe ;
00745     double x_et2 = ori_x2 - x_axe ;
00746 
00747     if (relat == 1) {
00748 
00749       double andan_et1 = 0.5 * dasn2[0] + asn2[0] * dnulg[0] ;
00750       double andan_et2 = 0.5 * dasn2[1] + asn2[1] * dnulg[1] ;
00751 
00752       double bpb_et1 = x_et1 * x_et1 - 2. * nyso[0] * x_et1 + npnso2[0] ;
00753       double bpb_et2 = x_et2 * x_et2 - 2. * nyso[1] * x_et2 + npnso2[1] ;
00754 
00755       double cpc_et1 = 0.5 * dnpnso2[0] + x_et1 * (1. - dnyso[0]) - nyso[0] ;
00756       double cpc_et2 = 0.5 * dnpnso2[1] + x_et2 * (1. - dnyso[1]) - nyso[1] ;
00757 
00758       om2_et1 = dnulg[0] / (andan_et1 * bpb_et1 + asn2[0] * cpc_et1) ;
00759       om2_et2 = dnulg[1] / (andan_et2 * bpb_et2 + asn2[1] * cpc_et2) ;
00760 
00761     }
00762     else {
00763 
00764       om2_et1 = dnulg[0] / x_et1 ;
00765       om2_et2 = dnulg[1] / x_et2 ;
00766 
00767     }
00768 
00769     double ome_et1 = sqrt( om2_et1 ) ;
00770     double ome_et2 = sqrt( om2_et2 ) ;
00771 
00772     double diff_om1 = 1. - ome_et1 / ome_et2 ;
00773     double diff_om2 = 1. - ome_et1 / omega ;
00774 
00775     cout << "Binaire::orbit : omega (direct) [rad/s] : "
00776      << ome_et1 * f_unit << endl ;
00777 
00778     cout << "Binaire::orbit : relative difference between " << endl
00779      << " omega_star1 and omega_star2 (direct) : " << diff_om1 << endl
00780      << " omega (direct) and omega (iretation) : " << diff_om2 << endl ;
00781      */
00782 
00783 }
00784 
00785 
00786 //*************************************************
00787 //  Function used for search of the rotation axis
00788 //*************************************************
00789 
00790 double  fonc_binaire_axe(double x_rot, const Param& paraxe) {
00791 
00792     int relat = paraxe.get_int() ;
00793 
00794     double ori_x1 = paraxe.get_double(0) ;
00795     double ori_x2 = paraxe.get_double(1) ;
00796     double dnulg_1 = paraxe.get_double(2) ;
00797     double dnulg_2 = paraxe.get_double(3) ;
00798     double asn2_1 = paraxe.get_double(4) ;
00799     double asn2_2 = paraxe.get_double(5) ;
00800     double dasn2_1 = paraxe.get_double(6) ;
00801     double dasn2_2 = paraxe.get_double(7) ;
00802     double nyso_1 = paraxe.get_double(8) ;
00803     double nyso_2 = paraxe.get_double(9) ;
00804     double dnyso_1 = paraxe.get_double(10) ;
00805     double dnyso_2 = paraxe.get_double(11) ;
00806     double npnso2_1 = paraxe.get_double(12) ;
00807     double npnso2_2 = paraxe.get_double(13) ;
00808     double dnpnso2_1 = paraxe.get_double(14) ;
00809     double dnpnso2_2 = paraxe.get_double(15) ;
00810 
00811     double om2_star1 ;
00812     double om2_star2 ;
00813 
00814     double x1 = ori_x1 - x_rot ;
00815     double x2 = ori_x2 - x_rot ;
00816 
00817     if (relat == 1) {
00818 
00819       double andan_1 = 0.5 * dasn2_1 + asn2_1 * dnulg_1 ;
00820       double andan_2 = 0.5 * dasn2_2 + asn2_2 * dnulg_2 ;
00821 
00822       double bpb_1 = x1 * x1 - 2. * nyso_1 * x1 + npnso2_1 ;
00823       double bpb_2 = x2 * x2 - 2. * nyso_2 * x2 + npnso2_2 ;
00824 
00825       double cpc_1 = 0.5 * dnpnso2_1 + x1 * (1. - dnyso_1) - nyso_1 ;
00826       double cpc_2 = 0.5 * dnpnso2_2 + x2 * (1. - dnyso_2) - nyso_2 ;
00827 
00828       om2_star1 = dnulg_1 / (andan_1 * bpb_1 + asn2_1 * cpc_1) ;
00829       om2_star2 = dnulg_2 / (andan_2 * bpb_2 + asn2_2 * cpc_2) ;
00830 
00831     }
00832     else {
00833 
00834       om2_star1 = dnulg_1 / x1 ;
00835       om2_star2 = dnulg_2 / x2 ;
00836 
00837     }
00838 
00839     return om2_star1 - om2_star2 ;
00840 
00841 }
00842 
00843 //*****************************************************************************
00844 //  Fonction utilisee pour la recherche de omega par la methode de la secante
00845 //*****************************************************************************
00846 
00847 double fonc_binaire_orbit(double om, const Param& parf) {
00848 
00849     int relat = parf.get_int() ;
00850 
00851     double xc = parf.get_double(0) ; 
00852     double dnulg = parf.get_double(1) ;
00853     double asn2 = parf.get_double(2) ;
00854     double dasn2 = parf.get_double(3) ;
00855     double ny = parf.get_double(4) ;
00856     double dny = parf.get_double(5) ;
00857     double npn = parf.get_double(6) ;
00858     double dnpn = parf.get_double(7) ;
00859     double x_axe = parf.get_double(8) ;
00860 
00861     double xx = xc - x_axe ; 
00862     double om2 = om*om ; 
00863     
00864     double dphi_cent ;
00865     
00866     if (relat == 1) {
00867     double bpb = om2 * xx*xx - 2*om * ny * xx + npn ; 
00868     
00869     dphi_cent = ( asn2* ( om* (ny + xx*dny) - om2*xx - 0.5*dnpn )
00870              - 0.5*bpb* dasn2 ) 
00871                / ( 1 - asn2 * bpb ) ; 
00872     }
00873     else {
00874     dphi_cent =  - om2*xx  ; 
00875     }
00876             
00877     return dnulg + dphi_cent ; 
00878        
00879 }
00880 
00881 

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