sym_tensor_aux.C

00001 /*
00002  *  Methods of class Sym_tensor linked with auxiliary members (eta, mu, W, X...)
00003  *
00004  *   (see file sym_tensor.h for documentation)
00005  *
00006  */
00007 
00008 /*
00009  *   Copyright (c) 2005 Jerome Novak
00010  *
00011  *   This file is part of LORENE.
00012  *
00013  *   LORENE is free software; you can redistribute it and/or modify
00014  *   it under the terms of the GNU General Public License as published by
00015  *   the Free Software Foundation; either version 2 of the License, or
00016  *   (at your option) any later version.
00017  *
00018  *   LORENE is distributed in the hope that it will be useful,
00019  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021  *   GNU General Public License for more details.
00022  *
00023  *   You should have received a copy of the GNU General Public License
00024  *   along with LORENE; if not, write to the Free Software
00025  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00026  *
00027  */
00028 
00029 
00030 char sym_tensor__aux_C[] = "$Header: /cvsroot/Lorene/C++/Source/Tensor/sym_tensor_aux.C,v 1.13 2007/11/27 15:49:51 n_vasset Exp $" ;
00031 
00032 /*
00033  * $Id: sym_tensor_aux.C,v 1.13 2007/11/27 15:49:51 n_vasset Exp $
00034  * $Log: sym_tensor_aux.C,v $
00035  * Revision 1.13  2007/11/27 15:49:51  n_vasset
00036  * new function compute_tilde_C in class sym_tensor
00037  *
00038  * Revision 1.12  2006/10/24 14:52:38  j_novak
00039  * The Mtbl corresponding to the physical space is destroyed after the
00040  * calculation of tilde_B(tt), to get the updated result.
00041  *
00042  * Revision 1.11  2006/10/24 13:03:19  j_novak
00043  * New methods for the solution of the tensor wave equation. Perhaps, first
00044  * operational version...
00045  *
00046  * Revision 1.10  2006/08/31 12:12:43  j_novak
00047  * Correction of a small mistake in a phi loop.
00048  *
00049  * Revision 1.9  2006/06/28 07:48:26  j_novak
00050  * Better treatment of some null cases.
00051  *
00052  * Revision 1.8  2006/06/12 11:40:07  j_novak
00053  * Better memory and spectral base handling for Sym_tensor::compute_tilde_B.
00054  *
00055  * Revision 1.7  2006/06/12 07:42:29  j_novak
00056  * Fields A and tilde{B} are defined only for l>1.
00057  *
00058  * Revision 1.6  2006/06/12 07:27:20  j_novak
00059  * New members concerning A and tilde{B}, dealing with the transverse part of the
00060  * Sym_tensor.
00061  *
00062  * Revision 1.5  2005/09/07 16:47:43  j_novak
00063  * Removed method Sym_tensor_trans::T_from_det_one
00064  * Modified Sym_tensor::set_auxiliary, so that it takes eta/r and mu/r as
00065  * arguments.
00066  * Modified Sym_tensor_trans::set_hrr_mu.
00067  * Added new protected method Sym_tensor_trans::solve_hrr
00068  *
00069  * Revision 1.4  2005/04/05 15:38:08  j_novak
00070  * Changed the formulas for W and X. There was an error before...
00071  *
00072  * Revision 1.3  2005/04/05 09:22:15  j_novak
00073  * Use of the right formula with poisson_angu(2) for the determination of W and
00074  * X.
00075  *
00076  * Revision 1.2  2005/04/04 15:25:24  j_novak
00077  * Added new members www, xxx, ttt and the associated methods.
00078  *
00079  * Revision 1.1  2005/04/01 14:39:57  j_novak
00080  * Methods dealing with auxilliary derived members of the symmetric
00081  * tensor (eta, mu, W, X, etc ...).
00082  *
00083  *
00084  *
00085  * $Header: /cvsroot/Lorene/C++/Source/Tensor/sym_tensor_aux.C,v 1.13 2007/11/27 15:49:51 n_vasset Exp $
00086  *
00087  */
00088 
00089 // Headers C
00090 #include <stdlib.h>
00091 #include <assert.h>
00092 #include <math.h>
00093 
00094 // Headers Lorene
00095 #include "metric.h"
00096 #include "proto.h"
00097 
00098     
00099             //--------------//
00100             //     eta      //
00101             //--------------//
00102             
00103             
00104 const Scalar& Sym_tensor::eta(Param* par) const {
00105 
00106   if (p_eta == 0x0) {   // a new computation is necessary
00107     
00108     // All this has a meaning only for spherical components:
00109     assert(dynamic_cast<const Base_vect_spher*>(triad) != 0x0) ; 
00110 
00111     // eta is computed from its definition (148) of Bonazzola et al. (2004)
00112     int dzp = operator()(1,1).get_dzpuis() ; 
00113     int dzp_resu = ((dzp == 0) ? 0 : dzp-1) ;
00114 
00115     Scalar source_eta = operator()(1,2) ;
00116     source_eta.div_tant() ;
00117     source_eta += operator()(1,2).dsdt() + operator()(1,3).stdsdp() ;
00118     source_eta.mult_r_dzpuis(dzp_resu) ;
00119     
00120     // Resolution of the angular Poisson equation for eta
00121     // --------------------------------------------------
00122     if (dynamic_cast<const Map_af*>(mp) != 0x0) {
00123       p_eta = new Scalar( source_eta.poisson_angu() ) ; 
00124     }
00125     else {
00126       Scalar resu (*mp) ;
00127       resu = 0. ;
00128       mp->poisson_angu(source_eta, *par, resu) ;
00129       p_eta = new Scalar( resu ) ;          
00130     }
00131     
00132   }
00133 
00134   return *p_eta ; 
00135 
00136 }
00137 
00138             
00139             //--------------//
00140             //     mu       //
00141             //--------------//
00142             
00143 
00144 const Scalar& Sym_tensor::mu(Param* par) const {
00145 
00146   if (p_mu == 0x0) {   // a new computation is necessary
00147         
00148     // All this has a meaning only for spherical components:
00149     assert(dynamic_cast<const Base_vect_spher*>(triad) != 0x0) ; 
00150 
00151     Scalar source_mu = operator()(1,3) ;    // h^{r ph}
00152     source_mu.div_tant() ;      // h^{r ph} / tan(th)
00153     
00154     // dh^{r ph}/dth + h^{r ph}/tan(th) - 1/sin(th) dh^{r th}/dphi 
00155     source_mu += operator()(1,3).dsdt() - operator()(1,2).stdsdp() ; 
00156     
00157     // Multiplication by r
00158     int dzp = operator()(1,2).get_dzpuis() ; 
00159     int dzp_resu = ((dzp == 0) ? 0 : dzp-1) ;
00160     source_mu.mult_r_dzpuis(dzp_resu) ; 
00161     
00162     // Resolution of the angular Poisson equation for mu
00163     // --------------------------------------------------
00164     if (dynamic_cast<const Map_af*>(mp) != 0x0) {
00165       p_mu = new Scalar( source_mu.poisson_angu() ) ;  
00166     }
00167     else {
00168       Scalar resu (*mp) ;
00169       resu = 0. ;
00170       mp->poisson_angu(source_mu, *par, resu) ;
00171       p_mu = new Scalar( resu ) ;       
00172     }
00173   }
00174   return *p_mu ; 
00175 
00176 }
00177 
00178             //-------------//
00179             //     T       //
00180             //-------------//
00181             
00182 
00183 const Scalar& Sym_tensor::ttt() const {
00184   
00185   if (p_ttt == 0x0) { // a new computation is necessary
00186 
00187     // All this has a meaning only for spherical components:
00188     assert(dynamic_cast<const Base_vect_spher*>(triad) != 0x0) ; 
00189 
00190     p_ttt = new Scalar( operator()(2,2) + operator()(3,3) ) ;
00191 
00192   }
00193   return *p_ttt ;
00194 
00195 }
00196 
00197             //------------//
00198             //     W      //
00199             //------------//
00200             
00201             
00202 const Scalar& Sym_tensor::www() const {
00203 
00204   if (p_www == 0x0) {   // a new computation is necessary
00205     
00206     // All this has a meaning only for spherical components:
00207     assert(dynamic_cast<const Base_vect_spher*>(triad) != 0x0) ; 
00208 
00209     Scalar ppp = 0.5*(operator()(2,2) - operator()(3,3)) ;
00210     Scalar tmp = ppp.dsdt() ;
00211     tmp.div_tant() ;
00212     Scalar source_w = ppp.dsdt().dsdt() +3*tmp - ppp.stdsdp().stdsdp() -2*ppp ;
00213     tmp = operator()(2,3) ;
00214     tmp.div_tant() ;
00215     tmp += operator()(2,3).dsdt() ;
00216     source_w += 2*tmp.stdsdp() ;
00217     
00218     // Resolution of the angular Poisson equation for W
00219     p_www = new Scalar( source_w.poisson_angu(2).poisson_angu() ) ; 
00220 
00221   }
00222 
00223   return *p_www ; 
00224 
00225 }
00226 
00227             
00228             //------------//
00229             //     X      //
00230             //------------//
00231             
00232             
00233 const Scalar& Sym_tensor::xxx() const {
00234 
00235   if (p_xxx == 0x0) {   // a new computation is necessary
00236     
00237     // All this has a meaning only for spherical components:
00238     assert(dynamic_cast<const Base_vect_spher*>(triad) != 0x0) ; 
00239 
00240     const Scalar& htp = operator()(2,3) ;
00241     Scalar tmp = htp.dsdt() ;
00242     tmp.div_tant() ;
00243     Scalar source_x = htp.dsdt().dsdt() + 3*tmp - htp.stdsdp().stdsdp() -2*htp ;
00244     Scalar ppp = 0.5*(operator()(2,2) - operator()(3,3)) ;
00245     tmp = ppp ;
00246     tmp.div_tant() ;
00247     tmp += ppp.dsdt() ;
00248     source_x -= 2*tmp.stdsdp() ;
00249     
00250     // Resolution of the angular Poisson equation for W
00251     p_xxx = new Scalar( source_x.poisson_angu(2).poisson_angu() ) ;
00252 
00253   }
00254 
00255   return *p_xxx ; 
00256 
00257 }
00258 
00259 void Sym_tensor::set_auxiliary(const Scalar& trr, const Scalar& eta_over_r, 
00260                    const Scalar& mu_over_r, const Scalar& w_in, 
00261                    const Scalar& x_in, const Scalar& t_in ) {
00262 
00263     // All this has a meaning only for spherical components:
00264     assert(dynamic_cast<const Base_vect_spher*>(triad) != 0x0) ; 
00265     int dzp = trr.get_dzpuis() ;
00266     int dzeta = (dzp == 0 ? 0 : dzp - 1) ;
00267 
00268     assert(eta_over_r.check_dzpuis(dzp)) ;
00269     assert(mu_over_r.check_dzpuis(dzp)) ;
00270     assert(w_in.check_dzpuis(dzp)) ;
00271     assert(x_in.check_dzpuis(dzp)) ;
00272     assert(t_in.check_dzpuis(dzp)) ;
00273 
00274     assert(&w_in != p_www) ;
00275     assert(&x_in != p_xxx) ;
00276     assert(&t_in != p_ttt) ;
00277 
00278     set(1,1) = trr ;
00279     set(1,2) = eta_over_r.dsdt() - mu_over_r.stdsdp() ;
00280     //   set(1,2).div_r_dzpuis(dzp) ;
00281     set(1,3) = eta_over_r.stdsdp() + mu_over_r.dsdt() ;
00282     //    set(1,3).div_r_dzpuis(dzp) ;
00283     Scalar tmp = w_in.lapang() ;
00284     tmp.set_spectral_va().ylm_i() ;
00285     Scalar ppp = 2*w_in.dsdt().dsdt() -  tmp - 2*x_in.stdsdp().dsdt() ;
00286     tmp = x_in.lapang() ;
00287     tmp.set_spectral_va().ylm_i() ;
00288     set(2,3) = 2*x_in.dsdt().dsdt() - tmp + 2*w_in.stdsdp().dsdt() ;
00289     set(2,2) = 0.5*t_in + ppp ;
00290     set(3,3) = 0.5*t_in - ppp ;
00291 
00292     // Deleting old derived quantities ...
00293     del_deriv() ; 
00294 
00295     // .. and affecting new ones.
00296     p_eta = new Scalar(eta_over_r) ; p_eta->mult_r_dzpuis(dzeta) ;
00297     p_mu = new Scalar(mu_over_r) ; p_mu->mult_r_dzpuis(dzeta) ;
00298     p_www = new Scalar(w_in) ;
00299     p_xxx = new Scalar(x_in) ;
00300     p_ttt = new Scalar(t_in) ;
00301 
00302 }
00303 
00304             //------------//
00305             //     A      //
00306             //------------//
00307             
00308             
00309 const Scalar& Sym_tensor::compute_A(bool output_ylm, Param* par) const {
00310 
00311   if (p_aaa == 0x0) {   // a new computation is necessary
00312     
00313     // All this has a meaning only for spherical components:
00314     assert(dynamic_cast<const Base_vect_spher*>(triad) != 0x0) ; 
00315 
00316     int dzp = xxx().get_dzpuis() ; 
00317     int dzp_resu = ((dzp == 0) ? 2 : dzp+1) ;
00318  
00319     Scalar source_mu = operator()(1,3) ;    // h^{r ph}
00320     source_mu.div_tant() ;      // h^{r ph} / tan(th)
00321     
00322     // dh^{r ph}/dth + h^{r ph}/tan(th) - 1/sin(th) dh^{r th}/dphi 
00323     source_mu += operator()(1,3).dsdt() - operator()(1,2).stdsdp() ; 
00324     
00325     // Resolution of the angular Poisson equation for mu / r
00326     // -----------------------------------------------------
00327     Scalar tilde_mu(*mp) ;
00328     tilde_mu = 0 ;
00329 
00330     if (dynamic_cast<const Map_af*>(mp) != 0x0) {
00331     tilde_mu = source_mu.poisson_angu()  ;  
00332     }
00333     else {
00334     assert(par != 0x0) ;
00335     mp->poisson_angu(source_mu, *par, tilde_mu) ;
00336     }
00337     tilde_mu.div_r_dzpuis(dzp_resu) ;
00338     
00339     p_aaa = new Scalar( xxx().dsdr() - tilde_mu) ;
00340     p_aaa->annule_l(0, 1, output_ylm) ;
00341   }
00342 
00343   if (output_ylm) p_aaa->set_spectral_va().ylm() ;
00344   else  p_aaa->set_spectral_va().ylm_i() ;
00345 
00346   return *p_aaa ; 
00347 
00348 }
00349 
00350             //--------------//
00351             //   tilde(B)   //
00352             //--------------//
00353             
00354             
00355 const Scalar& Sym_tensor::compute_tilde_B(bool output_ylm, Param* par) const {
00356 
00357   if (p_tilde_b == 0x0) {   // a new computation is necessary
00358     
00359     // All this has a meaning only for spherical components:
00360     assert(dynamic_cast<const Base_vect_spher*>(triad) != 0x0) ; 
00361 
00362     int dzp = operator()(1,1).get_dzpuis() ; 
00363     int dzp_resu = ((dzp == 0) ? 2 : dzp+1) ;
00364 
00365     p_tilde_b = new Scalar(*mp) ;
00366     p_tilde_b->set_etat_qcq() ;
00367 
00368     Scalar source_eta = operator()(1,2) ;
00369     source_eta.div_tant() ;
00370     source_eta += operator()(1,2).dsdt() + operator()(1,3).stdsdp() ;
00371     
00372     // Resolution of the angular Poisson equation for eta / r
00373     // ------------------------------------------------------
00374     Scalar tilde_eta(*mp) ;
00375     tilde_eta = 0 ;
00376 
00377     if (dynamic_cast<const Map_af*>(mp) != 0x0) {
00378     tilde_eta = source_eta.poisson_angu() ; 
00379     }
00380     else {
00381     assert (par != 0x0) ;
00382     mp->poisson_angu(source_eta, *par, tilde_eta) ;
00383     }
00384  
00385     Scalar dwdr = www().dsdr() ;
00386     dwdr.set_spectral_va().ylm() ;
00387     Scalar wsr = www() ;
00388     wsr.div_r_dzpuis(dzp_resu) ;
00389     wsr.set_spectral_va().ylm() ;
00390     Scalar etasr2 = tilde_eta ;
00391     etasr2.div_r_dzpuis(dzp_resu) ;
00392     etasr2.set_spectral_va().ylm() ;
00393     Scalar dtdr = ttt().dsdr() ;
00394     dtdr.set_spectral_va().ylm() ;
00395     Scalar tsr = ttt() ;
00396     tsr.div_r_dzpuis(dzp_resu) ;
00397     tsr.set_spectral_va().ylm() ;
00398     Scalar hrrsr = operator()(1,1) ;
00399     hrrsr.div_r_dzpuis(dzp_resu) ;
00400     hrrsr.set_spectral_va().ylm() ;
00401 
00402     int nz = mp->get_mg()->get_nzone() ;
00403 
00404     Base_val base(nz) ;
00405 
00406     if (wsr.get_etat() != ETATZERO) {
00407     base = wsr.get_spectral_base() ;
00408     }
00409     else {
00410     if (etasr2.get_etat() != ETATZERO) {
00411         base = etasr2.get_spectral_base() ;
00412     }
00413     else {
00414         if (tsr.get_etat() != ETATZERO) {
00415         base = tsr.get_spectral_base() ;
00416         }
00417         else {
00418         if (hrrsr.get_etat() != ETATZERO) {
00419             base = hrrsr.get_spectral_base() ;
00420         }
00421         else { //Everything is zero...
00422             p_tilde_b->set_etat_zero() ;
00423             return *p_tilde_b ;
00424         }
00425         }
00426     }
00427     }
00428     
00429     p_tilde_b->set_spectral_base(base) ;
00430     p_tilde_b->set_spectral_va().set_etat_cf_qcq() ;
00431     p_tilde_b->set_spectral_va().c_cf->annule_hard() ;
00432 
00433     if (dwdr.get_etat() == ETATZERO) dwdr.annule_hard() ;
00434     if (wsr.get_etat() == ETATZERO) wsr.annule_hard() ;
00435     if (etasr2.get_etat() == ETATZERO) etasr2.annule_hard() ;
00436     if (dtdr.get_etat() == ETATZERO) dtdr.annule_hard() ;
00437     if (tsr.get_etat() == ETATZERO) tsr.annule_hard() ;
00438     if (hrrsr.get_etat() == ETATZERO) hrrsr.annule_hard() ;
00439 
00440     int m_q, l_q, base_r ;
00441     for (int lz=0; lz<nz; lz++) {
00442     int np = mp->get_mg()->get_np(lz) ;
00443     int nt = mp->get_mg()->get_nt(lz) ;
00444     int nr = mp->get_mg()->get_nr(lz) ;
00445     for (int k=0; k<np+1; k++)
00446         for (int j=0; j<nt; j++) {
00447         base.give_quant_numbers(lz, k, j, m_q, l_q, base_r) ;
00448         if ( (nullite_plm(j, nt, k, np, base) == 1) && (l_q > 1))
00449         {
00450             for (int i=0; i<nr; i++) 
00451             p_tilde_b->set_spectral_va().c_cf->set(lz, k, j, i)
00452                 = (l_q+2)*(*dwdr.get_spectral_va().c_cf)(lz, k, j, i)
00453                 + l_q*(l_q+2)*(*wsr.get_spectral_va().c_cf)(lz, k, j, i)
00454                 - 2*(*etasr2.get_spectral_va().c_cf)(lz, k, j, i)
00455         + 0.5*double(l_q+2)/double(l_q+1)*(*tsr.get_spectral_va().c_cf)(lz, k, j, i)
00456         + 0.5/double(l_q+1)*(*dtdr.get_spectral_va().c_cf)(lz, k, j, i)
00457         - 1./double(l_q+1)*(*hrrsr.get_spectral_va().c_cf)(lz, k, j, i) ;
00458         }
00459         }
00460     }
00461     p_tilde_b->set_dzpuis(dzp_resu) ;
00462   } //End of p_tilde_b == 0x0    
00463 
00464   if (output_ylm) p_tilde_b->set_spectral_va().ylm() ;
00465   else  p_tilde_b->set_spectral_va().ylm_i() ;
00466 
00467   return *p_tilde_b ; 
00468 
00469 }
00470 
00471 Scalar Sym_tensor::compute_tilde_B_tt(bool output_ylm, Param* par) const {
00472 
00473     Scalar resu = compute_tilde_B(true, par) ;
00474     if (resu.get_etat() == ETATZERO) return resu ;
00475     else {
00476     assert(resu.get_etat() == ETATQCQ) ;
00477     assert(resu.get_spectral_va().c_cf != 0x0) ;
00478     int dzp = operator()(1,1).get_dzpuis() ; 
00479     int dzp_resu = ((dzp == 0) ? 2 : dzp+1) ;
00480     
00481     Scalar hsr = operator()(1,1) + ttt() ;
00482     if (hsr.get_etat() == ETATZERO) return resu ;
00483     Scalar dhdr = hsr.dsdr() ;
00484     dhdr.set_spectral_va().ylm() ;
00485     hsr.div_r_dzpuis(dzp_resu) ;
00486     hsr.set_spectral_va().ylm() ;
00487     
00488     int nz = mp->get_mg()->get_nzone() ;
00489 
00490     const Base_val& base = resu.get_spectral_base() ;
00491     
00492     if (dhdr.get_etat() == ETATZERO) dhdr.annule_hard() ;
00493 
00494     int m_q, l_q, base_r ;
00495     for (int lz=0; lz<nz; lz++) {
00496         int np = mp->get_mg()->get_np(lz) ;
00497     int nt = mp->get_mg()->get_nt(lz) ;
00498     int nr = mp->get_mg()->get_nr(lz) ;
00499     for (int k=0; k<np+1; k++)
00500         for (int j=0; j<nt; j++) {
00501         base.give_quant_numbers(lz, k, j, m_q, l_q, base_r) ;
00502         if ( (nullite_plm(j, nt, k, np, base) == 1) && (l_q > 1))
00503         {
00504             for (int i=0; i<nr; i++) 
00505             resu.set_spectral_va().c_cf->set(lz, k, j, i)
00506         -=  0.5*(*hsr.get_spectral_va().c_cf)(lz, k, j, i)
00507           + 0.5/double(l_q+1)*(*dhdr.get_spectral_va().c_cf)(lz, k, j, i);
00508         }
00509         }
00510     }
00511     resu.set_dzpuis(dzp_resu) ;
00512     if (resu.set_spectral_va().c != 0x0) 
00513         delete resu.set_spectral_va().c ;
00514     resu.set_spectral_va().c = 0x0 ;
00515     } //End of resu != 0    
00516 
00517   if (output_ylm) resu.set_spectral_va().ylm() ;
00518   else  resu.set_spectral_va().ylm_i() ;
00519 
00520   return resu ; 
00521 
00522 }
00523 
00524 Scalar Sym_tensor::get_tilde_B_from_TT_trace(const Scalar& tbtt, const Scalar&
00525     tras) const {
00526     
00527     // All this has a meaning only for spherical components:
00528     assert(dynamic_cast<const Base_vect_spher*>(triad) != 0x0) ; 
00529 
00530     Scalar resu = tbtt ;
00531     if (resu.get_etat() == ETATZERO) {
00532     if (tras.get_etat() == ETATZERO) return resu ;
00533     else {
00534         resu.annule_hard() ;
00535         Base_val base = tras.get_spectral_base() ;
00536         base.mult_x() ;
00537         resu.set_spectral_base(base) ;
00538     }
00539     }
00540     resu.set_spectral_va().ylm() ;
00541     int dzp = operator()(1,1).get_dzpuis() ; 
00542     int dzp_resu = ((dzp == 0) ? 2 : dzp+1) ;
00543     
00544     Scalar hsr = tras ;
00545     if (hsr.get_etat() == ETATZERO) return resu ;
00546     else {
00547     Scalar dhdr = hsr.dsdr() ;
00548     if (dhdr.get_etat() == ETATZERO) dhdr.annule_hard() ;
00549     dhdr.set_spectral_va().ylm() ;
00550     hsr.div_r_dzpuis(dzp_resu) ;
00551     hsr.set_spectral_va().ylm() ;
00552     
00553     int nz = mp->get_mg()->get_nzone() ;    
00554     const Base_val& base = resu.get_spectral_base() ;    
00555 
00556     int m_q, l_q, base_r ;
00557     for (int lz=0; lz<nz; lz++) {
00558         if ((*resu.get_spectral_va().c_cf)(lz).get_etat() == ETATZERO)
00559         resu.get_spectral_va().c_cf->set(lz).annule_hard() ;
00560         int np = mp->get_mg()->get_np(lz) ;
00561         int nt = mp->get_mg()->get_nt(lz) ;
00562         int nr = mp->get_mg()->get_nr(lz) ;
00563         for (int k=0; k<np+1; k++)
00564         for (int j=0; j<nt; j++) {
00565             base.give_quant_numbers(lz, k, j, m_q, l_q, base_r) ;
00566             if ( (nullite_plm(j, nt, k, np, base) == 1) && (l_q > 1))
00567             {
00568             for (int i=0; i<nr; i++) 
00569                 resu.set_spectral_va().c_cf->set(lz, k, j, i)
00570         +=  0.5*(*hsr.get_spectral_va().c_cf)(lz, k, j, i)
00571           + 0.5/double(l_q+1)*(*dhdr.get_spectral_va().c_cf)(lz, k, j, i);
00572             }
00573         }
00574     }
00575     resu.set_dzpuis(dzp_resu) ;
00576     if (resu.set_spectral_va().c != 0x0) 
00577         delete resu.set_spectral_va().c ;
00578     resu.set_spectral_va().c = 0x0 ;
00579     } //End of trace != 0    
00580     return resu ;
00581 }
00582 
00583 
00584             //--------------//
00585             //   tilde(C)   //
00586             //--------------//
00587             
00588             
00589 const Scalar& Sym_tensor::compute_tilde_C(bool output_ylm, Param* par) const {
00590 
00591   if (p_tilde_c == 0x0) {   // a new computation is necessary
00592     
00593     // All this has a meaning only for spherical components:
00594     assert(dynamic_cast<const Base_vect_spher*>(triad) != 0x0) ; 
00595 
00596     int dzp = operator()(1,1).get_dzpuis() ; 
00597     int dzp_resu = ((dzp == 0) ? 2 : dzp+1) ;
00598 
00599     p_tilde_c = new Scalar(*mp) ;
00600     p_tilde_c->set_etat_qcq() ;
00601 
00602     Scalar source_eta = operator()(1,2) ;
00603     source_eta.div_tant() ;
00604     source_eta += operator()(1,2).dsdt() + operator()(1,3).stdsdp() ;
00605     
00606     // Resolution of the angular Poisson equation for eta / r
00607     // ------------------------------------------------------
00608     Scalar tilde_eta(*mp) ;
00609     tilde_eta = 0 ;
00610 
00611     if (dynamic_cast<const Map_af*>(mp) != 0x0) {
00612     tilde_eta = source_eta.poisson_angu() ; 
00613     }
00614     else {
00615     assert (par != 0x0) ;
00616     mp->poisson_angu(source_eta, *par, tilde_eta) ;
00617     }
00618  
00619     Scalar dwdr = www().dsdr() ;
00620     dwdr.set_spectral_va().ylm() ;
00621     Scalar wsr = www() ;
00622     wsr.div_r_dzpuis(dzp_resu) ;
00623     wsr.set_spectral_va().ylm() ;
00624     Scalar etasr2 = tilde_eta ;
00625     etasr2.div_r_dzpuis(dzp_resu) ;
00626     etasr2.set_spectral_va().ylm() ;
00627     Scalar dtdr = ttt().dsdr() ;
00628     dtdr.set_spectral_va().ylm() ;
00629     Scalar tsr = ttt() ;
00630     tsr.div_r_dzpuis(dzp_resu) ;
00631     tsr.set_spectral_va().ylm() ;
00632     Scalar hrrsr = operator()(1,1) ;
00633     hrrsr.div_r_dzpuis(dzp_resu) ;
00634     hrrsr.set_spectral_va().ylm() ;
00635 
00636     int nz = mp->get_mg()->get_nzone() ;
00637 
00638     Base_val base(nz) ;
00639 
00640     if (wsr.get_etat() != ETATZERO) {
00641     base = wsr.get_spectral_base() ;
00642     }
00643     else {
00644     if (etasr2.get_etat() != ETATZERO) {
00645         base = etasr2.get_spectral_base() ;
00646     }
00647     else {
00648         if (tsr.get_etat() != ETATZERO) {
00649         base = tsr.get_spectral_base() ;
00650         }
00651         else {
00652         if (hrrsr.get_etat() != ETATZERO) {
00653             base = hrrsr.get_spectral_base() ;
00654         }
00655         else { //Everything is zero...
00656             p_tilde_c->set_etat_zero() ;
00657             return *p_tilde_c ;
00658         }
00659         }
00660     }
00661     }
00662     
00663     p_tilde_c->set_spectral_base(base) ;
00664     p_tilde_c->set_spectral_va().set_etat_cf_qcq() ;
00665     p_tilde_c->set_spectral_va().c_cf->annule_hard() ;
00666 
00667     if (dwdr.get_etat() == ETATZERO) dwdr.annule_hard() ;
00668     if (wsr.get_etat() == ETATZERO) wsr.annule_hard() ;
00669     if (etasr2.get_etat() == ETATZERO) etasr2.annule_hard() ;
00670     if (dtdr.get_etat() == ETATZERO) dtdr.annule_hard() ;
00671     if (tsr.get_etat() == ETATZERO) tsr.annule_hard() ;
00672     if (hrrsr.get_etat() == ETATZERO) hrrsr.annule_hard() ;
00673 
00674     int m_q, l_q, base_r ;
00675     for (int lz=0; lz<nz; lz++) {
00676     int np = mp->get_mg()->get_np(lz) ;
00677     int nt = mp->get_mg()->get_nt(lz) ;
00678     int nr = mp->get_mg()->get_nr(lz) ;
00679     for (int k=0; k<np+1; k++)
00680         for (int j=0; j<nt; j++) {
00681         base.give_quant_numbers(lz, k, j, m_q, l_q, base_r) ;
00682         if ( (nullite_plm(j, nt, k, np, base) == 1) && (l_q > 1))
00683         {
00684             for (int i=0; i<nr; i++) 
00685             p_tilde_c->set_spectral_va().c_cf->set(lz, k, j, i)
00686                 = - (l_q - 1)*(*dwdr.get_spectral_va().c_cf)(lz, k, j, i)
00687                 +  (l_q + 1)*(l_q - 1)*(*wsr.get_spectral_va().c_cf)(lz, k, j, i)
00688                 - 2*(*etasr2.get_spectral_va().c_cf)(lz, k, j, i)
00689         + 0.5*double(l_q-1)/double(l_q)*(*tsr.get_spectral_va().c_cf)(lz, k, j, i)
00690         - 0.5/double(l_q)*(*dtdr.get_spectral_va().c_cf)(lz, k, j, i)
00691         + 1./double(l_q)*(*hrrsr.get_spectral_va().c_cf)(lz, k, j, i) ;
00692         }
00693         }
00694     }
00695     p_tilde_c->set_dzpuis(dzp_resu) ;
00696   } //End of p_tilde_c == 0x0    
00697 
00698   if (output_ylm) p_tilde_c->set_spectral_va().ylm() ;
00699   else  p_tilde_c->set_spectral_va().ylm_i() ;
00700 
00701   return *p_tilde_c ; 
00702 
00703 }

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