bhole_with_ns.C

00001 /*
00002  *   Copyright (c) 2000-2001 Philippe Grandclement
00003  *
00004  *   This file is part of LORENE.
00005  *
00006  *   LORENE is free software; you can redistribute it and/or modify
00007  *   it under the terms of the GNU General Public License as published by
00008  *   the Free Software Foundation; either version 2 of the License, or
00009  *   (at your option) any later version.
00010  *
00011  *   LORENE is distributed in the hope that it will be useful,
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *   GNU General Public License for more details.
00015  *
00016  *   You should have received a copy of the GNU General Public License
00017  *   along with LORENE; if not, write to the Free Software
00018  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00021 
00022 
00023 char bhole_with_ns_C[] = "$Header: /cvsroot/Lorene/C++/Source/Bhole/bhole_with_ns.C,v 1.10 2007/04/24 20:14:04 f_limousin Exp $" ;
00024 
00025 /*
00026  * $Id: bhole_with_ns.C,v 1.10 2007/04/24 20:14:04 f_limousin Exp $
00027  * $Log: bhole_with_ns.C,v $
00028  * Revision 1.10  2007/04/24 20:14:04  f_limousin
00029  * Implementation of Dirichlet and Neumann BC for the lapse
00030  *
00031  * Revision 1.9  2007/02/03 07:46:30  p_grandclement
00032  * Addition of term kss for psi BC
00033  *
00034  * Revision 1.8  2006/04/27 09:12:31  p_grandclement
00035  * First try at irrotational black holes
00036  *
00037  * Revision 1.7  2006/04/25 07:21:57  p_grandclement
00038  * Various changes for the NS_BH project
00039  *
00040  * Revision 1.6  2005/08/29 15:10:13  p_grandclement
00041  * Addition of things needed :
00042  *   1) For BBH with different masses
00043  *   2) Provisory files for the mixted binaries (Bh and NS) : THIS IS NOT
00044  *   WORKING YET !!!
00045  *
00046  * Revision 1.5  2004/03/25 10:28:57  j_novak
00047  * All LORENE's units are now defined in the namespace Unites (in file unites.h).
00048  *
00049  * Revision 1.4  2003/11/25 07:11:09  k_taniguchi
00050  * Change some arguments from the class Etolie_bin to Et_bin_nsbh.
00051  *
00052  * Revision 1.3  2003/11/13 13:43:53  p_grandclement
00053  * Addition of things needed for Bhole::update_metric (const Etoile_bin&, double, double)
00054  *
00055  * Revision 1.2  2003/10/24 13:05:49  p_grandclement
00056  * correction of the equations for Bin_ns_bh...
00057  *
00058  * Revision 1.1  2003/02/13 16:40:25  p_grandclement
00059  * Addition of various things for the Bin_ns_bh project, non of them being
00060  * completely tested
00061  *
00062  *
00063  *
00064  * $Header: /cvsroot/Lorene/C++/Source/Bhole/bhole_with_ns.C,v 1.10 2007/04/24 20:14:04 f_limousin Exp $
00065  *
00066  */
00067 
00068 //standard
00069 #include <stdlib.h>
00070 #include <math.h>
00071 
00072 // Lorene
00073 #include "tenseur.h"
00074 #include "bhole.h"
00075 #include "proto.h"
00076 #include "utilitaires.h"
00077 #include "et_bin_nsbh.h"
00078 #include "graphique.h"
00079 #include "scalar.h"
00080 
00081 //Resolution pour le lapse pour 1 seul trou
00082 void Bhole::solve_lapse_with_ns (double relax, int bound_nn, double lim_nn) {
00083     
00084     assert ((relax>0) && (relax<=1)) ;
00085     
00086     cout << "Resolution LAPSE" << endl ;
00087         
00088     // Pour la relaxation ...
00089     Cmp lapse_old (n_auto()) ;
00090     Tenseur auxi (flat_scalar_prod(tkij_tot, tkij_auto)) ;
00091     Tenseur kk (mp) ;
00092     kk = 0 ;
00093     Tenseur work(mp) ;
00094     work.set_etat_qcq() ;
00095     for (int i=0 ; i<3 ; i++) {
00096     work.set() = auxi(i, i) ;
00097     kk = kk + work ;
00098     }
00099   
00100     // La source
00101     Cmp psiq (pow(psi_tot(), 4.)) ;
00102     psiq.std_base_scal() ;
00103     Cmp source 
00104     (-2*flat_scalar_prod(psi_auto.gradient(), grad_n_tot)()/psi_tot()
00105     +psiq*n_tot()*kk()) ;
00106     source.std_base_scal() ;    
00107       
00108     Cmp soluce(n_auto()) ;
00109     
00110     if (bound_nn == 0){
00111       // Dirichlet
00112       Valeur limite (mp.get_mg()->get_angu()) ;
00113       limite = -0.5 + lim_nn ;
00114       int np = mp.get_mg()->get_np(1) ;
00115       int nt = mp.get_mg()->get_nt(1) ;
00116       for (int k=0 ; k<np ; k++) 
00117     for (int j=0 ; j<nt ; j++)
00118     limite.set(0,k,j,0) -= n_comp() (1, k, j, 0) ;
00119       limite.std_base_scal() ;
00120 
00121       soluce = source.poisson_dirichlet(limite, 0) ;
00122     }
00123     else {
00124       assert(bound_nn == 1);
00125       // Neumann
00126       Valeur limite (mp.get_mg()->get_angu()) ;
00127       limite.annule_hard() ;
00128       int np = mp.get_mg()->get_np(1) ;
00129       int nt = mp.get_mg()->get_nt(1) ;
00130       for (int k=0 ; k<np ; k++) 
00131     for (int j=0 ; j<nt ; j++)
00132     limite.set(0,k,j,0) -= n_tot()(1, k, j, 0)/psi_tot()(1,k,j,0)*
00133       psi_tot().dsdr()(1,k,j,0) ;
00134       limite.std_base_scal() ;
00135       
00136       soluce = source.poisson_neumann(limite, 0) ;
00137     }
00138 
00139     soluce = soluce + 0.5 ;
00140 
00141     n_auto.set() = relax*soluce + (1-relax)*lapse_old ; 
00142     n_auto.set().raccord(3) ;
00143 }
00144 
00145 // Resolution sur Psi :
00146 void Bhole::solve_psi_with_ns (double relax) {
00147     
00148     assert ((relax>0) && (relax<=1)) ;
00149     
00150     cout << "Resolution PSI" << endl ;
00151     
00152     Cmp psi_old (psi_auto()) ;
00153     Tenseur auxi (flat_scalar_prod(tkij_auto, tkij_tot)) ;
00154     Tenseur kk (mp) ;
00155     kk = 0 ;
00156     Tenseur work(mp) ;
00157     work.set_etat_qcq() ;
00158     for (int i=0 ; i<3 ; i++) {
00159     work.set() = auxi(i, i) ;
00160     kk = kk + work ;
00161     }
00162     Cmp psic (pow(psi_tot(), 5.)) ;
00163     psic.std_base_scal() ;
00164 
00165     // La source :
00166     Cmp source (-psic*kk()/8.) ;
00167     source.std_base_scal() ;
00168     
00169     // Condition limite :
00170     Valeur limite (mp.get_mg()->get_angu()) ;
00171     limite = 1 ;
00172 
00173 
00174     int np = mp.get_mg()->get_np(1) ;
00175     int nt = mp.get_mg()->get_nt(1) ;
00176 
00177     double* vec_s = new double[3] ;
00178     Mtbl tet_mtbl (mp.get_mg()) ;
00179     tet_mtbl = mp.tet ;
00180     Mtbl phi_mtbl (mp.get_mg()) ;
00181     phi_mtbl = mp.phi ;
00182 
00183     for (int k=0 ; k<np ; k++) 
00184       for (int j=0 ; j<nt ; j++) {
00185     
00186     double tet = tet_mtbl(1,k,j,0) ;
00187         double phi = phi_mtbl(1,k,j,0) ;
00188         vec_s[0] = cos(phi)*sin(tet) ;
00189     vec_s[1] = sin(phi)*sin(tet) ;
00190     vec_s[2] = cos(tet) ;
00191     double part_ss = 0 ;
00192     if (tkij_tot.get_etat()==ETATQCQ) 
00193     for (int m=0 ; m<3 ; m++)
00194         for (int n=0 ; n<3 ; n++)
00195             part_ss += vec_s[m]*vec_s[n]*tkij_tot(m,n)(1,k,j,0) ;
00196     part_ss *= pow(psi_tot()(1,k,j,0),3.)/4. ;
00197 
00198 
00199     limite.set(0, k, j, 0) = -0.5/rayon*psi_tot()(1, k, j, 0) -
00200       psi_comp().dsdr()(1, k, j, 0) - part_ss ;
00201 }
00202 
00203 
00204     limite.std_base_scal() ;
00205     
00206     Cmp soluce (source.poisson_neumann(limite, 0)) ;
00207     soluce = soluce + 1./2. ;
00208     
00209     psi_auto.set() = relax*soluce + (1-relax)*psi_old ;    
00210     psi_auto.set().raccord(3) ;
00211 
00212 }
00213 
00214 // Le shift. Processus iteratif pour cause de CL.
00215 void Bhole::solve_shift_with_ns (const Et_bin_nsbh& ns, 
00216                  double precision, double relax,
00217                  int bound_nn, double lim_nn) {
00218     
00219     assert (precision > 0) ;
00220     assert ((relax>0) && (relax<=1)) ;
00221     
00222     cout << "resolution SHIFT" << endl ;
00223     
00224     Tenseur shift_old (shift_auto) ;
00225     
00226     Tenseur source (-6*flat_scalar_prod(taij_tot, psi_auto.gradient())/psi_tot
00227             + 2*flat_scalar_prod(tkij_tot, n_auto.gradient())) ;
00228     source.set_std_base() ;
00229     
00230     // On verifie si les 3 composantes ne sont pas nulles :
00231     if (source.get_etat() == ETATQCQ) {
00232     int indic = 0 ;
00233     for (int i=0 ; i<3 ; i++)
00234         if (source(i).get_etat() == ETATQCQ)
00235         indic = 1 ;
00236     if (indic ==0)
00237       for (int i=0 ; i<3 ; i++)
00238         source.set_etat_zero() ;
00239     }
00240  
00241 
00242     // On filtre les hautes frequences pour raison de stabilite :
00243     if (source.get_etat() == ETATQCQ)
00244     for (int i=0 ; i<3 ; i++)
00245             source.set(i).filtre(4) ;
00246     
00247     
00248     // On determine les conditions limites en fonction de omega et de NS :
00249     int np = mp.get_mg()->get_np(1) ;
00250     int nt = mp.get_mg()->get_nt(1) ;
00251     
00252     Mtbl x_mtbl (mp.get_mg()) ;
00253     x_mtbl.set_etat_qcq() ;
00254     Mtbl y_mtbl (mp.get_mg()) ;
00255     y_mtbl.set_etat_qcq() ;
00256     x_mtbl = mp.x ;
00257     y_mtbl = mp.y ;
00258 
00259     double air, theta, phi, xabs, yabs, zabs ;
00260     Mtbl Xabs (mp.get_mg()) ;
00261     Xabs = mp.xa ;
00262     Mtbl Yabs (mp.get_mg()) ;
00263     Yabs = mp.ya ;
00264     Mtbl Zabs (mp.get_mg()) ;
00265     Zabs = mp.za ;
00266     
00267     Mtbl tet_mtbl (mp.get_mg()) ;
00268     tet_mtbl = mp.tet ;
00269     Mtbl phi_mtbl (mp.get_mg()) ;
00270     phi_mtbl = mp.phi ;
00271 
00272     // Les bases pour les conditions limites :
00273     Base_val** bases = mp.get_mg()->std_base_vect_cart() ;
00274     
00275     Valeur lim_x (mp.get_mg()->get_angu()) ;
00276     lim_x = 1 ;
00277     Valeur lim_y (mp.get_mg()->get_angu()) ;
00278     lim_y = 1 ;
00279     Valeur lim_z (mp.get_mg()->get_angu()) ;
00280     lim_z = 1 ;
00281 
00282     for (int k=0 ; k<np ; k++)
00283       for (int j=0 ; j<nt ; j++) {
00284 
00285     double tet = tet_mtbl(1,k,j,0) ;
00286         double phy = phi_mtbl(1,k,j,0) ;
00287 
00288     xabs = Xabs (1, k, j, 0) ;
00289     yabs = Yabs (1, k, j, 0) ;
00290     zabs = Zabs (1, k, j, 0) ;
00291     
00292     ns.get_mp().convert_absolute (xabs, yabs, zabs, air, theta, phi) ;
00293     
00294     lim_x.set(0, k, j, 0) = omega*Yabs(0, 0, 0, 0) + 
00295       omega_local*y_mtbl(1,k,j,0) - 
00296       ns.get_shift_auto()(0).val_point(air, theta, phi) +
00297       n_tot()(1,k,j,0)/psi_tot()(1,k,j,0)/psi_tot()(1,k,j,0)*
00298       cos(phy)*sin(tet) ;
00299     lim_x.base = *bases[0] ;
00300     
00301     
00302     lim_y.set(0, k, j, 0) = -omega*Xabs(0, 0, 0, 0) - 
00303       omega_local*x_mtbl(1,k,j,0) - 
00304       ns.get_shift_auto()(1).val_point(air, theta, phi) +
00305       n_tot()(1,k,j,0)/psi_tot()(1,k,j,0)/psi_tot()(1,k,j,0)*
00306       sin(phy)*sin(tet) ;
00307     
00308     lim_z.set(0, k, j, 0) = - 
00309       ns.get_shift_auto()(2).val_point(air, theta, phi) +
00310       n_tot()(1,k,j,0)/psi_tot()(1,k,j,0)/psi_tot()(1,k,j,0)*cos(tet) ;
00311       }
00312 
00313     lim_x.base = *bases[0] ;
00314     lim_y.base = *bases[1] ;
00315     lim_z.base = *bases[2] ;
00316     
00317     // On n'en a plus besoin
00318     for (int i=0 ; i<3 ; i++)
00319       delete bases[i] ;
00320     delete [] bases ;
00321     
00322     // On resout :
00323     poisson_vect_frontiere(1./3., source, shift_auto, lim_x, lim_y, 
00324                lim_z, 0, precision, 20) ;
00325    
00326     shift_auto = relax*shift_auto + (1-relax)*shift_old ;
00327 
00328     for (int i=0; i<3; i++)
00329       shift_auto.set(i).raccord(3) ;
00330 
00331 
00332     // Regularisation of the shift if necessary
00333     // -----------------------------------------    
00334     if (bound_nn == 0 && lim_nn == 0)
00335       regul = regle (shift_auto, ns.get_shift_auto(), omega, omega_local) ;  
00336     else 
00337       regul = 0. ;
00338     
00339 }
00340 
00341 
00342 void Bhole::equilibrium (const Et_bin_nsbh& comp, 
00343              double precision, double relax,
00344              int bound_nn, double lim_nn) {
00345 
00346   // Solve for the lapse :
00347   solve_lapse_with_ns (relax, bound_nn, lim_nn) ;
00348 
00349   // Solve for the conformal factor :
00350   solve_psi_with_ns (relax) ;
00351 
00352   if (omega != 0) 
00353   // Solve for the shift vector :
00354     solve_shift_with_ns (comp, precision, relax, bound_nn, lim_nn) ;
00355   
00356 }
00357 
00358   
00359 void Bhole::update_metric (const Et_bin_nsbh& comp) {
00360 
00361     fait_n_comp(comp) ;
00362     fait_psi_comp(comp) ;
00363     /*  
00364     Scalar lapse_auto (n_auto()) ;
00365     Scalar lapse_tot (n_tot()) ;
00366     Scalar lapse_comp (n_comp()) ;
00367     des_meridian(lapse_auto, 0, 7, "n_auto", 0) ;
00368     des_meridian(lapse_comp, 0, 7, "n_comp", 11) ;
00369     des_meridian(lapse_tot, 0, 7, "n_tot", 1) ;
00370 
00371     Scalar psiauto (psi_auto()) ;
00372     Scalar psitot (psi_tot()) ;
00373     des_meridian(psiauto, 0, 7, "psi_auto", 2) ;
00374     des_meridian(psitot, 0, 7, "psi_tot", 3) ;
00375     */
00376 
00377 }
00378 
00379   

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