spheroid.C

00001 /*
00002  *  Definition of methods for the class Spheroid and its subclass App_hor
00003  *
00004  */
00005 
00006 /*
00007  *   Copyright (c) 2006  Nicolas Vasset, Jerome Novak & Jose-Luis Jaramillo
00008  *
00009  *   This file is part of LORENE.
00010  *
00011  *   LORENE is free software; you can redistribute it and/or modify
00012  *   it under the terms of the GNU General Public License version 2
00013  *   as published by the Free Software Foundation.
00014  *
00015  *   LORENE is distributed in the hope that it will be useful,
00016  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *   GNU General Public License for more details.
00019  *
00020  *   You should have received a copy of the GNU General Public License
00021  *   along with LORENE; if not, write to the Free Software
00022  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  *
00024  */
00025 
00026 char spheroid_C[] = "$Header: /cvsroot/Lorene/C++/Source/App_hor/spheroid.C,v 1.16 2009/12/01 08:44:24 j_novak Exp $" ;
00027 
00028 /*
00029  * $Id: spheroid.C,v 1.16 2009/12/01 08:44:24 j_novak Exp $
00030  * $Log: spheroid.C,v $
00031  * Revision 1.16  2009/12/01 08:44:24  j_novak
00032  * Added the missing operator=().
00033  *
00034  * Revision 1.15  2008/12/10 13:55:55  jl_jaramillo
00035  * versions developed at Meudon in November 2008
00036  *
00037  * Revision 1.14  2008/11/17 08:30:01  jl_jaramillo
00038  * Nicolas's changes on multipoles. Sign correction in outgoing shear expression
00039  *
00040  * Revision 1.13  2008/11/12 15:17:47  n_vasset
00041  * Bug-hunting, and new definition for computation of the Ricci scalar
00042  * (instead of Ricci tensor previously)
00043  *
00044  * Revision 1.12  2008/07/09 08:47:33  n_vasset
00045  * new version for multipole calculation. Function zeta implemented.
00046  * Revision 1.11  2008/06/04 12:31:23  n_vasset
00047  * New functions multipole_mass and multipole_angu. first version.
00048  *
00049  * Revision 1.9  2006/09/07 08:39:45  j_novak
00050  * Minor changes.
00051  *
00052  * Revision 1.8  2006/07/03 10:13:48  n_vasset
00053  *  More efficient method for calculation of ricci tensor. Adding of flag issphere
00054  *
00055  * Revision 1.4  2006/06/01 11:47:50  j_novak
00056  * Memory error hunt.
00057  *
00058  * Revision 1.3  2006/06/01 08:18:16  n_vasset
00059  * Further implementation of Spheroid class definitions
00060  *
00061  * $Header: /cvsroot/Lorene/C++/Source/App_hor/spheroid.C,v 1.16 2009/12/01 08:44:24 j_novak Exp $
00062  *
00063  */
00064 
00065 // C headers
00066 #include <math.h>
00067 
00068 // Lorene headers
00069 #include "metric.h"
00070 #include "spheroid.h"
00071 #include "utilitaires.h"
00072 #include "param.h"
00073 #include "itbl.h"
00074 #include "map.h"
00075 #include <assert.h>
00076 #include "nbr_spx.h"
00077 #include "math.h"
00078 #include "param_elliptic.h"
00079 #include "tensor.h"
00080 #include "sym_tensor.h"
00081 #include "diff.h"
00082 #include "proto.h"
00083 #include "param.h"
00084 
00085 
00086  
00087 
00088 
00089 //---------------//
00090 //  Constructors //
00091 //--------------// 
00092  
00093 Spheroid::Spheroid(const Map_af& map, double radius):
00094   h_surf(map), 
00095   jac2d(map, 2, COV, map.get_bvect_spher()),
00096   proj(map, 2, COV, map.get_bvect_spher()), 
00097   qq(map, COV, map.get_bvect_spher()),
00098   ss ( map, COV, map.get_bvect_spher ()),
00099   ephi(map, CON, map.get_bvect_spher()), 
00100   qab(map.flat_met_spher()), 
00101   ricci(map),
00102   hh(map, COV, map.get_bvect_spher()),
00103   trk(map),
00104   ll(map, COV, map.get_bvect_spher()), 
00105   jj(map, COV, map.get_bvect_spher()),    
00106   fff(map),
00107   ggg(map), 
00108   zeta(map),
00109   issphere(true)
00110 {    
00111 
00112   //    Itbl type (2) ; 
00113   //     type.set(1) = CON ; 
00114   //     type.set(2) = COV ;
00115   //    Tensor proj(map, 2, type, map.get_bvect_spher());
00116 
00117 
00118   assert(radius > 1.e-15) ;
00119   assert(map.get_mg()->get_nzone() == 1) ; // one domain
00120   assert(map.get_mg()->get_nr(0) == 1) ; // angular grid
00121   assert(map.get_mg()->get_type_r(0) == FIN) ; //considered as a shell
00122 
00123   // Setting of real index types for jacobian and projector (first contravariant, second covariant)
00124   jac2d.set_index_type(0) = CON ;
00125   proj.set_index_type(0) = CON ; 
00126  
00127   jac2d.set_etat_zero() ; 
00128 
00129  
00130   h_surf = radius ;
00131   ss.set_etat_zero();
00132   ephi.set_etat_zero();
00133   proj.set_etat_zero();
00134   hh.set_etat_zero() ;
00135   for (int i=1; i<=3; i++)
00136     hh.set(i,i) = 2./radius ; // WTF?
00137   trk.set_etat_zero() ;
00138   ll.set_etat_zero() ;
00139   jj.set_etat_zero() ;
00140   fff.set_etat_zero();
00141   ggg.set_etat_zero();
00142   zeta.set_etat_zero();
00143   set_der_0x0() ;
00144 }
00145 
00146 Spheroid::Spheroid(const Scalar& h_in, const Metric& gamij, const Sym_tensor& Kij):
00147   h_surf(h_in),
00148   jac2d(h_in.get_mp(),2, COV, h_in.get_mp().get_bvect_spher()),
00149   proj(h_in.get_mp(),2, COV, h_in.get_mp().get_bvect_spher()),
00150   qq(h_in.get_mp(), COV, h_in.get_mp().get_bvect_spher()),
00151   ss (h_in.get_mp(), COV, h_in.get_mp().get_bvect_spher()),
00152   ephi(h_in.get_mp(), CON, h_in.get_mp().get_bvect_spher()),
00153   qab(h_in.get_mp().flat_met_spher()),
00154   ricci(h_in.get_mp()),
00155   hh(h_in.get_mp(), COV, h_in.get_mp().get_bvect_spher()),
00156   trk(h_in.get_mp()), 
00157   ll(h_in.get_mp(), COV, h_in.get_mp().get_bvect_spher()), 
00158   jj(h_in.get_mp(), COV, h_in.get_mp().get_bvect_spher()),
00159   fff(h_in.get_mp()),
00160   ggg(h_in.get_mp()),
00161   zeta(h_in.get_mp()),
00162   issphere(true)
00163 
00164 {
00165   const Map& map = h_in.get_mp() ; // The 2-d 1-domain map
00166   const Map& map3 = Kij.get_mp(); // The 3-d map
00167   const Mg3d& gri2d = *map.get_mg() ;
00168 
00169   const Map_radial* mp_rad = dynamic_cast<const Map_radial*>(&Kij.get_mp()) ;
00170   assert(mp_rad != 0x0) ; 
00171     
00172   const Mg3d& gri3d = *map3.get_mg();
00173   assert(&gri2d == Kij.get_mp().get_mg()->get_angu_1dom()) ;
00174 
00175  
00176 
00177   int np = gri2d.get_np(0) ;
00178   int nt = gri2d.get_nt(0) ;
00179 
00180   int nr3 = gri3d.get_nr(0) ;
00181   int nt3 = gri3d.get_nt(0) ;    
00182   int np3 = gri3d.get_np(0) ;
00183   int nz = gri3d.get_nzone() ;
00184   assert( nt == nt3 ) ; 
00185   assert ( np == np3 ); 
00186   assert ( nr3 != 1 );  
00187  
00188 
00189   Param pipo ;
00190   double xi = 0. ;
00191   int lz = 0 ;
00192 
00193   if(nz >2){
00194     lz =1;
00195   }
00196 
00197   // Setting of real index types forjacobian and projector(first contravariant, other covariant)
00198   proj.set_index_type(0) = CON; 
00199   jac2d.set_index_type(0) = CON; 
00200 
00201   // Copy of the 2-dimensional h_surf to a 3_d h_surf (calculus commodity, in order to match grids)
00202   Scalar h_surf3 (map3); 
00203  
00204   h_surf3.allocate_all();
00205   h_surf3.std_spectral_base();
00206   for (int f= 0; f<nz; f++)
00207     for (int k=0; k<np3; k++)
00208       for (int j=0; j<nt3; j++) {
00209     for (int l=0; l<nr3; l++) {
00210         
00211       h_surf3.set_grid_point(f,k,j,l) = h_surf.val_grid_point(0,k,j,0);
00212     
00213     }
00214       }
00215   if (nz >2){
00216      h_surf3.annule_domain(0);
00217     h_surf3.annule_domain(nz - 1);
00218   }
00219    //  h_surf3.std_spectral_base();
00220 
00221  
00222 
00223 
00224   /* Computation of the jacobian projector linked to the mapping from the
00225      spheroid to a coordinate sphere. All quantities will then be calculated
00226      as from a real coordinate sphere 
00227   */
00228 
00229   Itbl type (2); 
00230   type.set(0) = CON ; 
00231   type.set(1) = COV ;
00232 
00233 
00234   Tensor jac (Kij.get_mp(),2,type, Kij.get_mp().get_bvect_spher());
00235     
00236   jac.set_etat_zero(); 
00237   jac.std_spectral_base();
00238   jac.set(1,1) = 1. ;
00239   jac.set(2,2)= 1. ;
00240   jac.set(3,3) = 1. ; 
00241   jac.set(1,2) = -h_surf3.srdsdt() ; 
00242   jac.set(1,3) = -h_surf3.srstdsdp() ;
00243  
00244   jac.std_spectral_base() ; 
00245 
00246   // Copy on the 2-d grid
00247 
00248   jac2d.allocate_all() ; 
00249   jac2d.std_spectral_base();
00250   for (int l=1; l<4; l++)
00251     for (int m=1; m<4; m++)     
00252       for (int k=0; k<np; k++)
00253     for (int j=0; j<nt; j++)
00254       {
00255         mp_rad->val_lx_jk((h_surf.val_grid_point(0, k, j, 0))*1.00000000001, j, k, pipo,
00256                   lz, xi) ;
00257         jac2d.set(l,m).set_grid_point(0, k, j, 0) = 
00258           jac(l,m).get_spectral_va().val_point_jk(lz, xi, j, k) ;
00259 
00260       }
00261 
00262 
00263 
00264 
00265   // Inverse jacobian (on 3-d grid)
00266   Tensor jac_inv = jac ;
00267   jac_inv.set(1,2) = - jac_inv(1,2);  
00268   jac_inv.set(1,3) = - jac_inv(1,3) ;
00269     
00270  
00271 
00272 
00273   // Scalar field which annulation characterizes the 2-surface
00274   Scalar carac = Kij.get_mp().r - h_surf3; 
00275   carac.std_spectral_base();
00276  // Computation of the normal vector (covariant form) on both grids
00277 
00278   Vector ss3d= carac.derive_cov(gamij) ;
00279   Vector ss3dcon=  carac.derive_con(gamij) ;
00280   Scalar ssnorm =  contract (ss3d.up(0, gamij), 0, ss3d, 0); 
00281   ssnorm.std_spectral_base() ;
00282   ss3d =  ss3d / sqrt (ssnorm) ; 
00283   ss3dcon =  ss3dcon / sqrt (ssnorm) ;
00284   if (nz >2){
00285     ss3d.annule_domain(0);
00286     ss3dcon.annule_domain(0);
00287     ss3d.annule_domain(nz-1);
00288     ss3dcon.annule_domain(nz -1);
00289   }
00290   ss3d.std_spectral_base();
00291   ss3dcon.std_spectral_base();
00292 
00293 
00294   // Provisory handling of dzpuis problems 
00295   if (nz >2){
00296    h_surf3.annule_domain(nz-1);
00297   }
00298   for (int ii=1; ii <=3; ii++){
00299     ss3d.set(ii).dec_dzpuis(ss3d(ii).get_dzpuis());
00300     ss3dcon.set(ii).dec_dzpuis(ss3dcon(ii).get_dzpuis());
00301   }
00302 
00303   for (int ii=1; ii <=3; ii++)
00304     for (int jjy = 1; jjy <=3; jjy ++){
00305       jac_inv.set(ii, jjy).dec_dzpuis(jac_inv(ii, jjy).get_dzpuis());
00306       jac.set(ii, jjy).dec_dzpuis(jac(ii, jjy).get_dzpuis());
00307     }
00308 
00309   // End of dzpuis handling.
00310 
00311 
00312   Sym_tensor sxss3d = ss3d * ss3d ;
00313   Sym_tensor sxss3dcon = ss3dcon * ss3dcon ; 
00314   Vector ss3 (Kij.get_mp(), COV, Kij.get_mp().get_bvect_spher()) ;
00315   Vector ss3con(Kij.get_mp(), CON, Kij.get_mp().get_bvect_spher()) ;
00316 
00317 
00318   ss3 = contract(jac_inv, 0, ss3d, 0); 
00319   ss.allocate_all() ; 
00320   ss.std_spectral_base();
00321 
00322   for (int l=1; l<4; l++)
00323     for (int k=0; k<np; k++)
00324       for (int j=0; j<nt; j++)
00325     {
00326       mp_rad->val_lx_jk(h_surf.val_grid_point(0, k, j, 0)*1.00000000001, j, k, pipo,
00327                 lz, xi) ;
00328       ss.set(l).set_grid_point(0, k, j, 0) = 
00329         ss3(l).get_spectral_va().val_point_jk(lz, xi, j, k) ;
00330     }
00331 
00332   // The vector field associated with Kiling conformal symmetry
00333   
00334   Vector ephi3(gamij.get_mp(), CON, gamij.get_mp().get_bvect_spher()); 
00335   ephi3.set(1).annule_hard();
00336   ephi3.set(2).annule_hard();
00337   Scalar ephi33(gamij.get_mp()); ephi33 = 1.; ephi33.std_spectral_base();
00338   ephi33.mult_r(); ephi33.mult_sint();
00339   ephi3.set(3) = ephi33;
00340   ephi3.std_spectral_base();
00341   ephi3 = contract (jac, 1, ephi3,0);
00342 
00343 
00344       ephi.allocate_all() ; 
00345   ephi.std_spectral_base();
00346   
00347      for (int l=1; l<4; l++)
00348     for (int k=0; k<np; k++)
00349       for (int j=0; j<nt; j++)
00350     {
00351       mp_rad->val_lx_jk(h_surf.val_grid_point(0, k, j, 0)*1.00000000001, j, k, pipo,
00352                 lz, xi) ;
00353       ephi.set(l).set_grid_point(0, k, j, 0) = 
00354         ephi3(l).get_spectral_va().val_point_jk(lz, xi, j, k) ;
00355     }  
00356        
00357 
00358 
00359 
00360   // Computation of the 3-d projector on the 2-sphere
00361    
00362    
00363   Tensor proj3d(Kij.get_mp(),2,  type, Kij.get_mp().get_bvect_spher());
00364   Tensor proj_prov = gamij.con().down(1, gamij) - ss3dcon*ss3d;
00365   proj.allocate_all();
00366   proj.std_spectral_base();
00367   proj3d.allocate_all();
00368   proj3d = contract(jac, 1, contract( jac_inv, 0, proj_prov , 1), 1 ); 
00369        
00370   proj3d.std_spectral_base();
00371   
00372   for (int l=1; l<4; l++)
00373     for (int m=1; m<4; m++)
00374       for (int k=0; k<np; k++)
00375     for (int j=0; j<nt; j++)
00376       {
00377         mp_rad->val_lx_jk(h_surf.val_grid_point(0, k, j, 0)*1.000000000001, j, k, pipo,
00378                   lz, xi) ;
00379         proj.set(l,m).set_grid_point(0, k, j, 0) = 
00380           proj3d(l,m).get_spectral_va().val_point_jk(lz, xi, j, k) ;
00381        
00382       
00383       }   
00384 
00385 
00386 
00387   /* Computation of the metric linked to the 2-surface (linked to covariant form 
00388      of the degenerated 2-metric). 
00389      It will be designed as a block-diagonal 3-metric, with 1 for 
00390      the first coordinate and the concerned 2-d  metric as a 
00391      second block */
00392 
00393   Sym_tensor qq3d (Kij.get_mp(), COV, Kij.get_mp().get_bvect_spher());
00394   Sym_tensor qab2 (h_in.get_mp(), COV, h_in.get_mp().get_bvect_spher());
00395   qq3d.set_etat_zero();
00396   qq3d.set(1,1) = 1;
00397   qq3d.set(2,2)= gamij.cov()(1,1) * (h_surf3.srdsdt())* (h_surf3.srdsdt()) + 2*  gamij.cov()(1,2)* (h_surf3.srdsdt()) +  gamij.cov()(2,2);
00398   qq3d.set(3,3)= gamij.cov()(1,1)* (h_surf3.srstdsdp())*(h_surf3.srstdsdp())+2*gamij.cov()(1,3)* (h_surf3.srstdsdp()) +gamij.cov()(3,3);
00399   qq3d.set(2,3)= gamij.cov()(1,1)* (h_surf3.srdsdt())* (h_surf3.srstdsdp())+
00400     gamij.cov()(1,2)* (h_surf3.srstdsdp())+gamij.cov()(1,3)* (h_surf3.srdsdt()) + gamij.cov()(2,3) ; 
00401   qq3d.set(3,2)= gamij.cov()(1,1)* (h_surf3.srdsdt())* (h_surf3.srstdsdp())+
00402     gamij.cov()(1,2)* (h_surf3.srstdsdp())+gamij.cov()(1,3)* (h_surf3.srdsdt()) + gamij.cov()(2,3) ; 
00403   qq3d.std_spectral_base();
00404   qab2.allocate_all() ;
00405   qab2.std_spectral_base(); 
00406   for (int l=1; l<4; l++)
00407     for (int m=1; m<4; m++) 
00408       for (int k=0; k<np; k++)
00409     for (int j=0; j<nt; j++)
00410       {
00411         mp_rad->val_lx_jk(h_surf.val_grid_point(0, k, j, 0)*1.000000000001, j, k, pipo,
00412                   lz, xi) ;
00413         qab2.set(l,m).set_grid_point(0, k, j, 0) = 
00414           qq3d(l,m).get_spectral_va().val_point_jk(lz, xi, j, k) ;
00415       }
00416   qab= qab2;
00417 
00418 
00419 
00420   // Computation of the degenerated 3d degenerated covariant metric on the 2-surface 
00421 
00422 
00423   Sym_tensor qqq = contract(jac_inv, 0, contract( jac_inv, 0, (gamij.cov() - ss3d * ss3d) , 0), 1) ; 
00424  
00425 
00426   qq.allocate_all() ; 
00427   qq.std_spectral_base();
00428   for (int l=1; l<4; l++)
00429     for (int m=1; m<4; m++)     
00430       for (int k=0; k<np; k++)
00431     for (int j=0; j<nt; j++)
00432       {
00433         mp_rad->val_lx_jk(h_surf.val_grid_point(0, k, j, 0)*1.000000000001, j, k, pipo,
00434                   lz, xi) ;
00435         qq.set(l,m).set_grid_point(0, k, j, 0) = 
00436           qqq(l,m).get_spectral_va().val_point_jk(lz, xi, j, k) ;
00437   
00438 
00439       }
00440        
00441 
00442   
00443   
00444 
00445 
00446 
00447 
00448 
00449   // Computation of the trace of the extrinsic curvature of 3-slice
00450   Scalar trk3d = Kij.trace(gamij) ;
00451   trk.allocate_all() ; 
00452   for (int k=0; k<np; k++)
00453     for (int j=0; j<nt; j++) {
00454       mp_rad->val_lx_jk(h_surf.val_grid_point(0, k, j, 0)*1.000000000001, j, k, pipo,
00455             lz, xi) ;
00456       trk.set_grid_point(0, k, j, 0) = 
00457     trk3d.get_spectral_va().val_point_jk(lz, xi, j, k) ;
00458     }
00459 
00460 
00461 
00462 
00463 
00464 
00465 
00466          
00467   // Computation of the normalization factor of the outgoing null vector.
00468 
00469   Scalar fff3d (map3);
00470   fff3d = 1. ; 
00471   fff.allocate_all() ; 
00472   fff3d.std_spectral_base();
00473   for (int k=0; k<np; k++)
00474     for (int j=0; j<nt; j++) {
00475       mp_rad->val_lx_jk(h_surf.val_grid_point(0, k, j, 0)*1.000000000001, j, k, pipo,
00476             lz, xi) ;
00477       fff.set_grid_point(0, k, j, 0) = 
00478     fff3d.get_spectral_va().val_point_jk(lz, xi, j, k) ;
00479     }
00480 
00481 
00482 
00483 
00484 
00485 
00486 
00487 
00488   // Computation of the normalization factor of the ingoing null vector.
00489 
00490   Scalar ggg3d (map3);
00491   ggg3d = 1. ; 
00492   ggg.allocate_all() ; 
00493   ggg3d.std_spectral_base();
00494   for (int k=0; k<np; k++)
00495     for (int j=0; j<nt; j++) {
00496       mp_rad->val_lx_jk(h_surf.val_grid_point(0, k, j, 0)*1.000000000001, j, k, pipo,
00497             lz, xi) ;
00498       ggg.set_grid_point(0, k, j, 0) = 
00499     ggg3d.get_spectral_va().val_point_jk(lz, xi, j, k) ;
00500     }
00501 
00502 
00503   //Computation of function zeta, changing spheroid coordinates to get a round measure.
00504 
00505   Scalar ftilde = sqrt_q();
00506     double rayon = sqrt(area()/(4.*M_PI));
00507     ftilde = -ftilde/(rayon*rayon);
00508     ftilde = ftilde*h_surf*h_surf;
00509   ftilde.set_spectral_va().ylm();
00510 
00511 
00512   Base_val base = ftilde.get_spectral_base() ;
00513 
00514   Mtbl_cf *coefftilde = ftilde.get_spectral_va().c_cf;  int nombre = 2*nt; // Doubled in SYM base!!
00515 
00516   double *a_tilde = new double[nombre];
00517   
00518 
00519   lz = 0; // Now we work with 2d map associated with sqrt(q)
00520 
00521   
00522  
00523  
00524          for (int k=0; k<np+1; k++)
00525              for (int j=0; j<nt; j++) {
00526                 int l_q, m_q, base_r ;
00527         base.give_quant_numbers(lz, k, j, m_q, l_q, base_r) ;
00528                  if (nullite_plm(j, nt, k, np, base) == 1) {
00529            donne_lm(1, lz, j, k, base, m_q, l_q,base_r) ;
00530                if (m_q ==0) {
00531             a_tilde[l_q] = (*coefftilde)(0, k, j, 0);
00532     
00533                }}}
00534 
00535      Scalar zeta2(map); zeta2= 3.; zeta2.std_spectral_base(); zeta2.mult_cost();
00536     zeta2.set_spectral_va().ylm();
00537 
00538         Base_val base2 = zeta2.get_spectral_base() ; 
00539         Mtbl_cf *dzeta = zeta2.set_spectral_va().c_cf;
00540 
00541         for (int k=0; k<np+1; k++)
00542           for (int j=0; j<nt; j++) {
00543             int l_q2, m_q2, base_r2 ;
00544         base.give_quant_numbers(lz, k, j, m_q2, l_q2, base_r2) ;
00545                  if (nullite_plm(j, nt, k, np, base2) == 1) {
00546                 donne_lm(1, lz, j, k, base2, m_q2, l_q2,base_r2) ;
00547         if (m_q2 ==0){
00548           if(l_q2 ==0){
00549             (*dzeta).set(0,k,j,0) = a_tilde[0] + (a_tilde[1]/3.)*sqrt(2.*1. + 1.);
00550             } 
00551           if (l_q2 >0){ 
00552             (*dzeta).set(0,k,j,0) =  (a_tilde[l_q2 +1]/(2.*l_q2 + 3.))*sqrt((2.*(l_q2 +1.)+1.)/(2.*l_q2 + 1.)) -  (a_tilde[l_q2 -1]/(2.*l_q2 - 1.))*sqrt((2.*(l_q2 - 1.)+1.)/(2.*l_q2 + 1.));
00553                }
00554                 }
00555          }
00556           }
00557            
00558     
00559         zeta2.set_spectral_va().coef();
00560         zeta = zeta2;
00561 
00562      
00563   /* Computation of the tangent part of the extrinsic curvature of
00564    * the 2 surface embedded in the 3 slice. The reference vector
00565    used is the vector field s */
00566 
00567   Vector ll3d = contract( proj_prov, 0, contract(Kij, 1, ss3dcon, 0), 0) ; 
00568 
00569   Vector ll3 = contract( jac_inv, 0, ll3d, 0) ; 
00570 
00571   ll.allocate_all() ;
00572   ll.std_spectral_base(); 
00573   for (int l=1; l<4; l++)      
00574     for (int k=0; k<np; k++)
00575       for (int j=0; j<nt; j++)
00576     {
00577       mp_rad->val_lx_jk(h_surf.val_grid_point(0, k, j, 0)*1.000000000001, j, k, pipo,
00578                 lz, xi) ;
00579       ll.set(l).set_grid_point(0, k, j, 0) = 
00580         ll3(l).get_spectral_va().val_point_jk(lz, xi, j, k) ;
00581 
00582     } 
00583  
00584 
00585 
00586 
00587 
00588 
00589 
00590     
00591   /* computation of the tangent components of the extrinsic curvature 
00592    *of the 3-slice 
00593    *(extracted from the curvature of the timeslice)
00594    * Note: this is not the actual 2d_ extrinsic curvature, but the 
00595    *tangent part of the time-slice extrinsic curvature */
00596  
00597   Tensor jj3d = Kij - ss3d*ll3d - ll3d*ss3d - contract(Kij, 0 , 1, sxss3dcon , 0, 1)* sxss3d ;
00598   Tensor jj3 =contract(jac_inv, 0 , contract(jac_inv,0 , jj3d,1),1);
00599   jj.allocate_all() ; 
00600   jj.std_spectral_base();
00601   for (int l=1; l<4; l++)
00602     for (int m=1; m<4; m++)     
00603       for (int k=0; k<np; k++)
00604     for (int j=0; j<nt; j++)
00605       {
00606         mp_rad->val_lx_jk(h_surf.val_grid_point(0, k, j, 0)*1.000000000001, j, k, pipo,
00607                   lz, xi) ;
00608         jj.set(l,m).set_grid_point(0, k, j, 0) = 
00609           jj3(l,m).get_spectral_va().val_point_jk(lz, xi, j, k) ;
00610         
00611       } 
00612   
00613   
00614   
00615   
00616   
00617   // Computation of 2d extrinsic curvature in the 3-slice
00618     
00619 
00620   Tensor hh3d = contract(proj_prov, 0, contract(proj_prov, 0,ss3d.derive_cov(gamij),1), 1 ) ;
00621 
00622   Tensor hh3 =contract(jac_inv, 0 , contract(jac_inv,0 , hh3d,1),1);
00623 
00624   hh.allocate_all() ; 
00625   hh.std_spectral_base();
00626   for (int l=1; l<4; l++)
00627     for (int m=1; m<4; m++)     
00628       for (int k=0; k<np; k++)
00629     for (int j=0; j<nt; j++)
00630       {
00631         mp_rad->val_lx_jk(h_surf.val_grid_point(0, k, j, 0)*1.000000000001, j, k, pipo,
00632                   lz, xi) ;
00633         hh.set(l,m).set_grid_point(0, k, j, 0) = 
00634           hh3(l,m).get_spectral_va().val_point_jk(lz, xi, j, k) ;
00635 
00636       }
00637 
00638 
00639  
00640  Tensor hh3dupdown = hh3d.up(0, gamij);
00641 
00642  Scalar ricciscal3 = gamij.ricci().trace(gamij);
00643  if (nz>2){
00644  ricciscal3.annule_domain(nz-1); ricciscal3.std_spectral_base(); // Ricci scalar on the 3-surface.
00645  }
00646  Tensor hh3dupup = hh3dupdown.up(1,gamij);
00647  if (nz>2){
00648  hh3dupup.annule_domain(nz-1); hh3dupup.std_spectral_base();
00649  }
00650 
00651  Scalar ricci22 = ricciscal3 - 2.*contract(contract(gamij.ricci(), 1, ss3dcon, 0),0, ss3dcon, 0);
00652  if (nz >2){
00653  ricci22.annule_domain(nz-1);
00654  
00655  ricci22.std_spectral_base();
00656  }
00657  ricci22 += (hh3d.trace(gamij)*hh3d.trace(gamij)) - contract(contract(hh3dupup,0, hh3d,0),0,1);
00658 
00659  if (nz >2){
00660  ricci22.annule_domain(nz-1);
00661  }
00662   ricci22.std_spectral_base();
00663 
00664 
00665  
00666   ricci.allocate_all();
00667   ricci.std_spectral_base();
00668       for (int k=0; k<np; k++)
00669         for (int j=0; j<nt; j++)
00670      {
00671        mp_rad->val_lx_jk(h_surf.val_grid_point(0, k, j, 0)*1.000000000001, j, k, pipo,
00672                  lz, xi) ;
00673        ricci.set_grid_point(0, k, j, 0) = 
00674          ricci22.get_spectral_va().val_point_jk(lz, xi, j, k) ;
00675 
00676      }
00677  
00678  
00679  set_der_0x0() ;
00680 
00681 }
00682 
00683 
00684 
00685 
00686 
00687 //Copy constructor//
00688 
00689 Spheroid::Spheroid (const Spheroid &sph_in) :h_surf(sph_in.h_surf),
00690                          jac2d(sph_in.jac2d),
00691                          proj(sph_in.proj),                          
00692                          qq(sph_in.qq),
00693                          ss (sph_in.ss),
00694                          ephi (sph_in.ephi),
00695                          qab(sph_in.qab),
00696                          ricci(sph_in.ricci),
00697                          hh(sph_in.hh),
00698                          trk(sph_in.trk),
00699                          ll(sph_in.ll),
00700                          jj(sph_in.jj),
00701                          fff(sph_in.fff),
00702                          ggg(sph_in.ggg),
00703                          zeta(sph_in.zeta),
00704                          issphere(sph_in.issphere)
00705   
00706 {
00707   set_der_0x0() ; 
00708   
00709 }
00710 
00711 // Assignment to another Spheroid
00712 void Spheroid::operator=(const Spheroid& sph_in)
00713 {
00714 
00715   h_surf = sph_in.h_surf ;
00716   jac2d = sph_in.jac2d ;
00717   proj = sph_in.proj ;
00718   qq = sph_in.qq ;
00719   ss  = sph_in.ss ;
00720   ephi = sph_in.ephi ;
00721   qab = sph_in.qab ;
00722   ricci = sph_in.ricci ;
00723   hh = sph_in.hh ;
00724   trk = sph_in.trk ;
00725   ll = sph_in.ll ;
00726   jj = sph_in.jj ;
00727   fff = sph_in.fff ;
00728   ggg = sph_in.ggg ;
00729   zeta = sph_in.zeta ;
00730   issphere = sph_in.issphere ;
00731 
00732   del_deriv() ;  // Deletes all derived quantities
00733 
00734 }
00735 
00736 //------------//
00737 //Destructor //
00738 //-----------//
00739 
00740 Spheroid::~Spheroid()
00741 {
00742   del_deriv() ;
00743 }
00744 
00745 // -----------------//
00746 // Memory management//
00747 //------------------//
00748 void Spheroid::del_deriv() const {
00749   if (p_sqrt_q != 0x0) delete p_sqrt_q ;
00750   if (p_area != 0x0) delete p_area ;
00751   if (p_angu_mom != 0x0) delete p_angu_mom ;
00752   if (p_mass != 0x0) delete p_mass ;
00753   if (p_multipole_mass != 0x0) delete p_multipole_mass ;
00754   if (p_multipole_angu != 0x0) delete p_multipole_angu ;
00755   if (p_epsilon_A_minus_one != 0x0) delete p_epsilon_A_minus_one ;
00756   if (p_epsilon_P_minus_one != 0x0) delete p_epsilon_P_minus_one ;
00757   if (p_theta_plus != 0x0) delete p_theta_plus ;
00758   if (p_theta_minus != 0x0) delete p_theta_minus ;
00759   if (p_shear != 0x0) delete p_shear ;
00760   if (p_delta != 0x0) delete p_delta ;
00761   set_der_0x0() ;
00762 }
00763 
00764 void Spheroid::set_der_0x0() const {
00765   p_sqrt_q = 0x0 ;
00766   p_area = 0x0 ;
00767   p_angu_mom = 0x0 ;
00768   p_mass = 0x0 ;
00769   p_multipole_mass = 0x0;
00770   p_multipole_angu = 0x0;
00771   p_epsilon_A_minus_one = 0x0;
00772   p_epsilon_P_minus_one = 0x0;
00773   p_theta_plus = 0x0 ;
00774   p_theta_minus = 0x0 ;
00775   p_shear = 0x0 ;
00776   p_delta = 0x0;
00777 
00778 } 
00779 
00780 
00781  
00782 //---------//
00783 //Accessors//
00784 //---------//
00785 
00786 
00787 
00788 
00789 
00790 // Computation of the 2-dimensional Jacobian amplitude for the surface
00791 const  Scalar& Spheroid::sqrt_q() const { 
00792   if (p_sqrt_q == 0x0) {
00793     p_sqrt_q = new Scalar(sqrt((get_qq()(2,2)*get_qq()(3,3))- (get_qq()(2,3)*get_qq()(2,3)))) ;
00794     p_sqrt_q->std_spectral_base() ;
00795   }
00796   return *p_sqrt_q ; 
00797 }
00798 
00799 
00800 
00801 
00802 
00803 // Computation of the 2-dimensional area of the surface
00804 
00805   
00806 double  Spheroid::area() const {
00807   if (p_area == 0x0) {
00808     const Map_af& mp_ang = dynamic_cast<const Map_af&>(h_surf.get_mp()) ;
00809     p_area = new double (mp_ang.integrale_surface((sqrt_q()) * h_surf *h_surf, 1)) ;
00810   } 
00811   return *p_area;
00812 } 
00813 
00814 
00815 
00816 // Computation of the angular momentum of the surface (G is set to be identically one)
00817 
00818 double Spheroid::angu_mom() const {
00819   if (p_angu_mom == 0x0) { 
00820     const Map_af& mp_ang = dynamic_cast<const Map_af&>(h_surf.get_mp()) ;
00821     Vector phi(mp_ang, CON, mp_ang.get_bvect_spher());
00822     phi = get_ephi();
00823     Scalar tmp = contract(ll,0, contract (jac2d, 1,phi,0), 0 );
00824     p_angu_mom = new double (mp_ang.integrale_surface((sqrt_q()*h_surf*h_surf*tmp),1)) ;
00825     *p_angu_mom = *p_angu_mom /(8. * M_PI) ; 
00826   }
00827 
00828   return *p_angu_mom;
00829 
00830 }
00831 
00832 
00833 double Spheroid::mass() const {
00834   if (p_mass == 0x0) {
00835     double rayon = sqrt(area()/(4.*M_PI));
00836     p_mass = new double ((1/(2.*rayon))*sqrt(rayon*rayon*rayon*rayon + 4.*angu_mom()*angu_mom()));
00837 
00838   }
00839   return *p_mass;
00840 
00841 }
00842 
00843 
00844 
00845 double Spheroid::multipole_mass(const int order) const{
00846     const Map_af& mp_ang = dynamic_cast<const Map_af&>(h_surf.get_mp()) ;
00847     double rayon = sqrt(area()/(4.*M_PI));
00848     // Multiplicative factor before integral.
00849     double factor = mass()/(8. * M_PI); // To check later
00850     if (order >0)
00851       { for (int compte=0; compte <=order -1; compte++)
00852     factor = factor*rayon;
00853       }
00854     // Calculus of legendre polynomial of order n, as function of cos(theta)
00855     Scalar Pn(mp_ang); Pn=1; Pn.std_spectral_base(); Pn.set_spectral_va().ylm();
00856     if (order >0)
00857       { Pn = Pn*zeta;     
00858       }
00859     if (order >1)
00860       { Scalar Pnold(mp_ang); Pnold = 1; Pnold.std_spectral_base(); Pnold.set_spectral_va().ylm();
00861 
00862       for (int nn=1; nn<order; nn++){
00863   
00864     Scalar Pnnew = (2.*nn +1.)*Pn;
00865     Pnnew = Pnnew*zeta;
00866     Pnnew = Pnnew - nn*Pnold;
00867     Pnnew = Pnnew/(double(nn) + 1.);
00868  
00869     Pnold = Pn;
00870     Pn = Pnnew;
00871 
00872       }
00873       }
00874  
00875     // Calculus of Ricci Scalar over the surface
00876     Scalar ricciscal(mp_ang);
00877     ricciscal = get_ricci();
00878     ricciscal.set_spectral_va().ylm();
00879   
00880     Scalar rayyon = h_surf;
00881     rayyon.std_spectral_base();
00882     rayyon.set_spectral_va().ylm();
00883 
00884     Scalar sqq = sqrt_q();
00885     Scalar integrande = sqq * rayyon *rayyon*ricciscal*Pn; integrande.std_spectral_base();
00886 
00887     
00888     p_multipole_mass = new double (factor*mp_ang.integrale_surface(integrande, 1)) ;
00889     
00890   
00891  
00892 
00893   return *p_multipole_mass;
00894 }
00895 
00896 
00897 
00898 double Spheroid::multipole_angu(const int order) const{
00899 
00900     assert (order >=1) ;
00901     const Map_af& mp_ang = dynamic_cast<const Map_af&>(h_surf.get_mp()) ;
00902     Vector phi(mp_ang, CON, mp_ang.get_bvect_spher());
00903     phi = get_ephi();
00904   double rayon = sqrt(area()/(4.*M_PI));
00905 
00906     double factor = 1./(8. * M_PI);
00907     if (order >1)
00908       { for (int compte=0; compte <=order -2; compte++)
00909     factor = factor*rayon;
00910       }
00911 
00912     // Calculus of legendre polynomial of order n, as function of cos(theta)
00913     Scalar Pn(mp_ang); Pn=1; Pn.std_spectral_base(); Pn.set_spectral_va().ylm();
00914     Scalar dPn = Pn;
00915 
00916     Pn = Pn*zeta;     
00917   
00918     if (order >1)
00919    
00920       { Scalar Pnold(mp_ang); Pnold = 1; Pnold.std_spectral_base(); Pnold.set_spectral_va().ylm();
00921 
00922       for (int nn=1; nn<order; nn++){
00923   
00924     Scalar Pnnew = (2.*nn +1.)*Pn;
00925     Pnnew = Pnnew*zeta;
00926     Pnnew = Pnnew - nn*Pnold;
00927     Pnnew = Pnnew/(double(nn) + 1.);
00928  
00929     Pnold = Pn;
00930     Pn = Pnnew; // Pn is now P(n+1)
00931 
00932       }
00933 
00934       //  Calculus of functional derivative of order N legendre polynomial.
00935     
00936       dPn = Pn* zeta; dPn = dPn - Pnold; dPn = double(order)*dPn;
00937     
00938       Scalar quotient(mp_ang); quotient = 1.; quotient.std_spectral_base();
00939       quotient = quotient*zeta*zeta; quotient = quotient -1.;
00940     
00941       dPn = dPn/quotient; 
00942 
00943       }
00944 
00945     // Computation of the multipole;
00946     Scalar tmp = contract(ll,0, contract (jac2d, 1,phi,0), 0 ); tmp.std_spectral_base();
00947     Scalar tmp2 = (sqrt_q()) * h_surf *h_surf*tmp*dPn; tmp2.std_spectral_base();
00948 
00949      
00950 
00951     p_multipole_angu = new double (factor*mp_ang.integrale_surface(tmp2, 1)) ;  
00952    
00953 
00954   return *p_multipole_angu;
00955   
00956 }
00957 
00958 
00959 // Computation of the refined Penrose parameter for axisymmetric spacetimes, and its difference wrt one.
00960 
00961 double Spheroid::epsilon_A_minus_one() const {
00962   if (p_epsilon_A_minus_one == 0x0) { 
00963      assert (pow(mass(),4) - pow (angu_mom(),2) > 0.);
00964     p_epsilon_A_minus_one = new double(area()/(8.*M_PI*(mass()*mass() + sqrt(pow(mass(),4) - pow (angu_mom(),2)))) - 1.);
00965   }
00966 
00967   return *p_epsilon_A_minus_one;
00968 
00969 }
00970 
00971 // Computation of the classical Penrose parameter, and its difference wrt one.
00972 // To use in replacement of epsilon_A_minus_one when the computed spacetime is not axisymmetric.
00973 double Spheroid::epsilon_P_minus_one() const {
00974   if (p_epsilon_P_minus_one == 0x0) { 
00975     assert (pow(mass(),4) - pow (angu_mom(),2) > 0.);
00976     p_epsilon_P_minus_one = new double(area()/(16.*M_PI*mass()*mass()) - 1.);
00977   }
00978 
00979   return *p_epsilon_P_minus_one;
00980 
00981 }
00982 
00983 
00984 // Outgoing null expansion of 2-surface
00985 
00986 const Scalar &Spheroid::theta_plus() const {
00987 
00988   if (p_theta_plus == 0x0) {
00989     p_theta_plus = new Scalar(fff*(hh.trace(qab) - jj.trace(qab))) ;
00990     p_theta_plus->std_spectral_base() ;
00991   }
00992 
00993   return *p_theta_plus; 
00994 }
00995 
00996 
00997 
00998 
00999 
01000 
01001 
01002 
01003 // ingoing null expansion of 2-surface
01004 
01005 const Scalar& Spheroid::theta_minus() const {
01006 
01007   if (p_theta_minus == 0x0) {
01008     p_theta_minus = new Scalar(ggg*(-hh.trace(qab) - jj.trace(qab))) ;
01009     p_theta_minus->std_spectral_base() ;
01010   }
01011 
01012   return *p_theta_minus; 
01013  
01014 }
01015 
01016 
01017 
01018 
01019 //outer null-oriented shear of 2-surface
01020 
01021 const Sym_tensor& Spheroid::shear() const { 
01022   
01023   if (p_shear == 0x0) {
01024      p_shear = new Sym_tensor( fff*(hh - jj) - (qab.cov()/2) *(hh.trace(qab) - jj.trace(qab))) ;  
01025 // This is associated with the null vector: "l = n + s";
01026 // For a null vector, "l = f (n + s)", multiply by the global factor "f" (e.g. the lapse "N" for "l=N(n+s)".  
01027                                                                                                 
01028  
01029     p_shear->std_spectral_base() ;
01030   }
01031 
01032   return *p_shear; 
01033  
01034 }
01035 
01036 
01037 
01038 
01039 
01040 
01041 
01042 
01043 
01044 
01045 
01046 //-------------------------------------------//
01047 // Covariant flat derivative, returning a pointer.//
01048 //-------------------------------------------//
01049 
01050 Tensor Spheroid::derive_cov2dflat(const Tensor& uu) const{
01051 
01052   // Notations: suffix 0 in name <=> input tensor
01053   //            suffix 1 in name <=> output tensor
01054 
01055   int valence0 = uu.get_valence() ; 
01056   int valence1 = valence0 + 1 ; 
01057   int valence1m1 = valence1 - 1 ; // same as valence0, but introduced for 
01058   // the sake of clarity
01059 
01060 
01061   // Protections
01062   // -----------
01063   if (valence0 >= 1) {
01064 
01065   }
01066 
01067   // Creation of the result (pointer)
01068   // --------------------------------
01069   Tensor *resu ;
01070 
01071   // If uu is a Scalar, the result is a vector
01072   if (valence0 == 0) {
01073     resu = new Vector(uu.get_mp(), COV, uu.get_mp().get_bvect_spher()) ;
01074   }
01075   else {
01076 
01077     // Type of indices of the result :
01078     Itbl tipe(valence1) ; 
01079     const Itbl& tipeuu = uu.get_index_type() ;  
01080     for (int id = 0; id<valence0; id++) {
01081       tipe.set(id) = tipeuu(id) ;   // First indices = same as uu
01082     }
01083     tipe.set(valence1m1) = COV ;  // last index is the derivation index
01084 
01085     // if uu is a Tensor_sym, the result is also a Tensor_sym:
01086     const Tensor* puu = &uu ; 
01087     const Tensor_sym* puus = dynamic_cast<const Tensor_sym*>(puu) ; 
01088     if ( puus != 0x0 ) {    // the input tensor is symmetric
01089       resu = new Tensor_sym(uu.get_mp(), valence1, tipe, *uu.get_triad(),
01090                 puus->sym_index1(), puus->sym_index2()) ;
01091     }
01092     else {  
01093       resu = new Tensor(uu.get_mp(), valence1, tipe, *uu.get_triad()) ;  // no symmetry  
01094     }
01095 
01096   }
01097 
01098   int ncomp1 = resu->get_n_comp() ; 
01099     
01100   Itbl ind1(valence1) ; // working Itbl to store the indices of resu
01101   Itbl ind0(valence0) ; // working Itbl to store the indices of uu
01102   Itbl ind(valence0) ;  // working Itbl to store the indices of uu
01103     
01104   Scalar tmp(uu.get_mp()) ; // working scalar
01105 
01106   // Determination of the dzpuis parameter of the result  --> dz_resu
01107   // --------------------------------------------------
01108         
01109   int dz_resu = 0;
01110 
01111   // (We only work here on a non-compactified shell) // 
01112 
01113 
01114 
01115 
01116   // Loop on all the components of the output tensor
01117   // -----------------------------------------------
01118   /* Note: we have here preserved all the non-useful terms in this case(typically christoffel symbols) for the sake of understandng what's going on... 
01119    */
01120  
01121  
01122   for (int ic=0; ic<ncomp1; ic++) {
01123     
01124     // indices corresponding to the component no. ic in the output tensor
01125     ind1 = resu->indices(ic) ; 
01126     
01127     // Component no. ic:
01128     Scalar& cresu = resu->set(ind1) ; 
01129         
01130     // Indices of the input tensor
01131     for (int id = 0; id < valence0; id++) {
01132       ind0.set(id) = ind1(id) ; 
01133     }
01134          
01135     // Value of last index (derivation index)
01136     int k = ind1(valence1m1) ; 
01137         
01138     switch (k) {
01139         
01140     case 1 : {  // Derivation index = r
01141       //---------------------
01142     
01143       cresu = 0; //(uu(ind0)).dsdr() ;  // d/dr
01144         
01145       // all the connection coefficients Gamma^i_{jk} are zero for k=1
01146       break ; 
01147     }   
01148 
01149     case 2 : {  // Derivation index = theta
01150       //-------------------------
01151             
01152       cresu = (uu(ind0)).srdsdt() ;  // 1/r d/dtheta 
01153         
01154       // Loop on all the indices of uu
01155       for (int id=0; id<valence0; id++) {
01156         
01157     switch ( ind0(id) ) {
01158                 
01159     case 1 : {  // Gamma^r_{l theta} V^l 
01160       // or -Gamma^l_{r theta} V_l 
01161       /*   ind = ind0 ; 
01162            ind.set(id) = 2 ;   // l = theta
01163 
01164            // Division by r :
01165            tmp = uu(ind) ; 
01166            tmp.div_r_dzpuis(dz_resu) ;
01167 
01168            cresu -= tmp ; */
01169       break ; 
01170     }
01171                     
01172     case 2 : {  // Gamma^theta_{l theta} V^l 
01173       // or -Gamma^l_{theta theta} V_l
01174       /*  ind = ind0 ; 
01175           ind.set(id) = 1 ;   // l = r
01176           tmp = uu(ind) ; 
01177           tmp.div_r_dzpuis(dz_resu) ;
01178 
01179           cresu += tmp ; */
01180       break ; 
01181     }
01182                 
01183     case 3 : {  // Gamma^phi_{l theta} V^l 
01184       // or -Gamma^l_{phi theta} V_l
01185       break ; 
01186     }
01187                 
01188     default : {
01189       cerr << "Connection_fspher::p_derive_cov : index problem ! "
01190            << endl ; 
01191       abort() ;  
01192     }
01193     }
01194 
01195       }
01196       break ; 
01197     }
01198 
01199 
01200     case 3 : {  // Derivation index = phi
01201       //-----------------------
01202                     
01203       cresu = (uu(ind0)).srstdsdp() ;  // 1/(r sin(theta)) d/dphi   
01204         
01205       // Loop on all the indices of uu
01206       for (int id=0; id<valence0; id++) {
01207         
01208     switch ( ind0(id) ) {
01209                 
01210     case 1 : {  // Gamma^r_{l phi} V^l 
01211       // or -Gamma^l_{r phi} V_l 
01212       /* ind = ind0 ; 
01213          ind.set(id) = 3 ;   // l = phi
01214          tmp = uu(ind) ; 
01215          tmp.div_r_dzpuis(dz_resu) ;
01216 
01217          cresu -= tmp ; */
01218       break ; 
01219     }
01220                 
01221     case 2 : {  // Gamma^theta_{l phi} V^l 
01222       // or -Gamma^l_{theta phi} V_l
01223       ind = ind0 ; 
01224       ind.set(id) = 3 ;   // l = phi
01225       tmp = uu(ind) ; 
01226       tmp.div_r_dzpuis(dz_resu) ;
01227 
01228       tmp.div_tant() ;  // division by tan(theta)
01229                     
01230       cresu -= tmp ; 
01231       break ; 
01232     }
01233                 
01234     case 3 : {  // Gamma^phi_{l phi} V^l 
01235       // or -Gamma^l_{phi phi} V_l
01236                         
01237       ind = ind0 ; 
01238       //                ind.set(id) = 1 ;   // l = r
01239       //                tmp = uu(ind) ; 
01240       //            tmp.div_r_dzpuis(dz_resu) ;
01241 
01242       //                cresu += tmp ; 
01243 
01244       ind.set(id) = 2 ;   // l = theta
01245       tmp = uu(ind) ; 
01246       tmp.div_r_dzpuis(dz_resu) ;
01247 
01248       tmp.div_tant() ;  // division by tan(theta)
01249 
01250       cresu += tmp ; 
01251       break ; 
01252     }
01253                 
01254     default : {
01255       cerr << "Connection_fspher::p_derive_cov : index problem ! \n"
01256            << endl ; 
01257       abort() ;  
01258     }
01259     }
01260 
01261       }
01262             
01263       break ; 
01264     }
01265 
01266     default : {
01267       cerr << "Connection_fspher::p_derive_cov : index problem ! \n" ;
01268       abort() ;  
01269     }
01270 
01271     } // End of switch on the derivation index
01272 
01273 
01274   } // End of loop on all the components of the output tensor
01275 
01276     // C'est fini !
01277     // -----------
01278   return *resu ; 
01279 
01280 }
01281 
01282 void Spheroid::sauve(FILE* ) const {
01283 
01284   cout << "c'est pas fait!" << endl ;
01285   return ; 
01286 
01287 }
01288 
01289 
01290 
01291 
01292 
01293 
01294 
01295 
01296 // Computation of the delta coefficients
01297  
01298  
01299 const Tensor& Spheroid::delta() const {
01300 
01301   // Tensor tg 
01302   if (p_delta == 0x0) {
01303    
01304     Tensor christoflat(qab.get_mp(), 3, COV, qab.get_mp().get_bvect_spher()); 
01305     christoflat.set_index_type(0) = CON; 
01306     christoflat.set_etat_zero() ;
01307 
01308     // assert(flat_met != 0x0) ; 
01309     Tensor dgam = derive_cov2dflat(qab.cov()) ; 
01310  
01311     for (int k=1; k<=3; k++) {
01312       for (int i=1; i<=3; i++) {
01313     for (int j=1; j<=i; j++) {
01314       Scalar& cc= christoflat.set(k,i,j); 
01315       for (int l=1; l<=3; l++) {
01316         cc += qab.con()(k,l) * ( 
01317                     dgam(l,j,i) + dgam(i,l,j) - dgam(i,j,l) ) ; 
01318                         
01319       }
01320       cc = 0.5 * cc ; 
01321     }
01322       }
01323     }
01324 
01325     p_delta = new Tensor (christoflat) ;
01326     
01327   }
01328   return *p_delta; 
01329 }
01330 
01331 
01332 
01333 
01334 
01335 
01336 // Computation of global derivative on 2-sphere 
01337 Tensor Spheroid::derive_cov2d(const Tensor& uu) const {
01338   
01339   if(uu.get_valence()>=1){
01340     int nbboucle =  uu.get_valence(); 
01341     Tensor resu = derive_cov2dflat(uu);
01342     for (int y=1; y<=nbboucle; y++){
01343            
01344       int df = uu.get_index_type(y-1); 
01345       if (df == COV) {
01346     resu -= contract(delta(),0, uu, y-1);
01347       }
01348       else {resu += contract(delta(),1,  uu, y-1);}
01349    
01350       return resu;
01351     }
01352   }
01353   else return derive_cov2dflat(uu);  
01354 
01355   return derive_cov2dflat(uu); // to avoid warnings...
01356 }
01357    
01358 
01359 
01360 
01361 
01362 
01363 
01364 
01365 
01366 // // COmputation of the ricci tensor  
01367 
01368 // const Sym_tensor& Spheroid::ricci() const {
01369 
01370 //   if (p_ricci == 0x0) {  // a new computation is necessary
01371     
01372 //     assert( issphere == true ) ;
01373 //     Sym_tensor riccia(h_surf.get_mp(), CON, h_surf.get_mp().get_bvect_spher()) ;
01374 //     riccia.set_etat_zero(); 
01375         
01376 //     const Tensor& d_delta = derive_cov2dflat(delta()) ; 
01377                 
01378 //     for (int i=1; i<=3; i++) {
01379         
01380 //       int jmax = 3 ; 
01381             
01382 //       for (int j=1; j<=jmax; j++) {
01383 
01384 //  Scalar tmp1(h_surf.get_mp()) ;
01385 //  tmp1.set_etat_zero() ; 
01386 //  for (int k=1; k<=3; k++) {
01387 //    tmp1 += d_delta(k,i,j,k) ; 
01388 //  } 
01389                 
01390 //  Scalar tmp2(h_surf.get_mp()) ;
01391 //  tmp2.set_etat_zero() ; 
01392 //  for (int k=1; k<=3; k++) {
01393 //    tmp2 += d_delta(k,i,k,j) ; 
01394 //  } 
01395                 
01396 //  Scalar tmp3(h_surf.get_mp()) ;
01397 //  tmp3.set_etat_zero() ; 
01398 //  for (int k=1; k<=3; k++) {
01399 //    for (int m=1; m<=3; m++) {
01400 //      tmp3 += delta()(k,k,m) * delta()(m,i,j) ; 
01401 //    }
01402 //  } 
01403 //  tmp3.dec_dzpuis() ;  // dzpuis 4 -> 3
01404                 
01405 //  Scalar tmp4(h_surf.get_mp()) ;
01406 //  tmp4.set_etat_zero() ; 
01407 //  for (int k=1; k<=3; k++) {
01408 //    for (int m=1; m<=3; m++) {
01409 //      tmp4 += delta()(k,j,m) * delta()(m,i,k) ; 
01410 //    }
01411 //  } 
01412 //  tmp4.dec_dzpuis() ;  // dzpuis 4 -> 3
01413               
01414 
01415 //  riccia.set(i,j) = tmp1 - tmp2 + tmp3 - tmp4 ; 
01416                   
01417         
01418 //       }
01419 //     }
01420 //     /* Note: Here we must take into account the fact that a round metric on a spheroid doesn't give zero as "flat" ricci part. Then a diagonal scalar term must be added. 
01421 //        WARNING: this only works with "round" horizons!! */ 
01422  
01423 //     double rayon = sqrt(area()/(4.*M_PI));
01424 //     Scalar rayon2  = h_surf;
01425 //     rayon2 = rayon;
01426 //     rayon2.std_spectral_base();
01427     
01428 //     for (int hi=1; hi<=3; hi++){
01429  
01430 //       riccia.set(hi,hi) += 2/(rayon2 * rayon2) ; // Plutot 1/hsurf^2, non? 
01431 //     }
01432 //     p_ricci = new Sym_tensor(riccia);
01433 //   }
01434     
01435 //   return *p_ricci ; 
01436     
01437 // }
01438 
01439 
01440 
01441 
01442 // COmputation of the ricci tensor  
01443 
01444 // const Sym_tensor& Spheroid::ricci() const {
01445 
01446 //   if (p_ricci == 0x0) {  // a new computation is necessary
01447 //     Sym_tensor riccia(h_surf.get_mp(), CON, h_surf.get_mp().get_bvect_spher()) ;
01448 //     Sym_tensor ricci3 = gamij.ricci();
01449     
01450 //     Sym_tensor ricci3-2d(h_surf.get_mp(), COV, h_surf.get_mp().get_bvect_spher());
01451 //       ricci3-2d.allocate_all() ; 
01452 //   ricci3-2d.std_spectral_base();
01453 //   for (int l=1; l<4; l++)
01454 //     for (int m=1; m<4; m++)     
01455 //       for (int k=0; k<np; k++)
01456 //  for (int j=0; j<nt; j++)
01457 //    {
01458 //      mp_rad->val_lx_jk(h_surf.val_grid_point(0, k, j, 0)*1.000000000001, j, k, pipo,
01459 //                lz, xi) ;
01460 //      ricci3-2d.set(l,m).set_grid_point(0, k, j, 0) = 
01461 //        ricci3(l,m).get_spectral_va().val_point_jk(lz, xi, j, k) ;
01462 
01463 //    }
01464        
01465 
01466 
01467 //   }
01468 //   return *p_ricci ; 
01469   
01470 // }
01471 
01472 
01473 
01474 
01475 

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