sym_tensor.C

00001 /*
00002  *  Methods of class Sym_tensor
00003  *
00004  *   (see file tensor.h for documentation)
00005  *
00006  */
00007 
00008 /*
00009  *   Copyright (c) 2003-2004 Eric Gourgoulhon & Jerome Novak
00010  *
00011  *   Copyright (c) 1999-2001 Philippe Grandclement (Cmp version)
00012  *   Copyright (c) 2000-2001 Eric Gourgoulhon (Cmp version)
00013  *
00014  *   This file is part of LORENE.
00015  *
00016  *   LORENE is free software; you can redistribute it and/or modify
00017  *   it under the terms of the GNU General Public License as published by
00018  *   the Free Software Foundation; either version 2 of the License, or
00019  *   (at your option) any later version.
00020  *
00021  *   LORENE is distributed in the hope that it will be useful,
00022  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00023  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00024  *   GNU General Public License for more details.
00025  *
00026  *   You should have received a copy of the GNU General Public License
00027  *   along with LORENE; if not, write to the Free Software
00028  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00029  *
00030  */
00031 
00032 
00033 char sym_tensor_C[] = "$Header: /cvsroot/Lorene/C++/Source/Tensor/sym_tensor.C,v 1.22 2007/12/21 16:07:08 j_novak Exp $" ;
00034 
00035 /*
00036  * $Id: sym_tensor.C,v 1.22 2007/12/21 16:07:08 j_novak Exp $
00037  * $Log: sym_tensor.C,v $
00038  * Revision 1.22  2007/12/21 16:07:08  j_novak
00039  * Methods to filter Tensor, Vector and Sym_tensor objects.
00040  *
00041  * Revision 1.21  2007/12/03 13:00:00  n_vasset
00042  * Adjusting memory management for new member p_tilde_c
00043  *
00044  * Revision 1.20  2006/06/12 07:27:20  j_novak
00045  * New members concerning A and tilde{B}, dealing with the transverse part of the
00046  * Sym_tensor.
00047  *
00048  * Revision 1.19  2005/04/04 15:25:24  j_novak
00049  * Added new members www, xxx, ttt and the associated methods.
00050  *
00051  * Revision 1.18  2005/04/01 14:28:32  j_novak
00052  * Members p_eta and p_mu are now defined in class Sym_tensor.
00053  *
00054  * Revision 1.17  2004/03/30 14:01:19  j_novak
00055  * Copy constructors and operator= now copy the "derived" members.
00056  *
00057  * Revision 1.16  2004/02/26 22:48:50  e_gourgoulhon
00058  * -- Method divergence: call to Tensor::divergence and cast of the
00059  *    result.
00060  * -- Added method derive_lie.
00061  *
00062  * Revision 1.15  2004/01/04 20:54:00  e_gourgoulhon
00063  * Sym_tensor is now a derived class of Tensor_sym.
00064  * Methods indices and position have been suppressed (they are now
00065  * implemented at the Tensor_sym level).
00066  *
00067  * Revision 1.14  2003/12/30 23:09:47  e_gourgoulhon
00068  * Change in methods derive_cov() and divergence() to take into account
00069  *  the change of name: Metric::get_connect() --> Metric::connect().
00070  *
00071  * Revision 1.13  2003/11/26 21:58:15  e_gourgoulhon
00072  * Added new data member p_transverse and p_longit_pot.
00073  * Modified the memory management consequently.
00074  *
00075  * Revision 1.12  2003/10/28 12:34:08  e_gourgoulhon
00076  * Corrected bug in the copy constructor and constructor from Tensor:
00077  * the cmp have already been created by the (special) Tensor constructor called
00078  * by these constructors.
00079  *
00080  * Revision 1.11  2003/10/20 14:26:03  j_novak
00081  * New assignement operators.
00082  *
00083  * Revision 1.10  2003/10/16 14:21:36  j_novak
00084  * The calculation of the divergence of a Tensor is now possible.
00085  *
00086  * Revision 1.9  2003/10/13 13:52:39  j_novak
00087  * Better managment of derived quantities.
00088  *
00089  * Revision 1.8  2003/10/11 16:47:10  e_gourgoulhon
00090  * Suppressed the call to Ibtl::set_etat_qcq() after the construction
00091  * of the Itbl's, thanks to the new property of the Itbl class.
00092  *
00093  * Revision 1.7  2003/10/07 09:56:59  j_novak
00094  * method Sym_tensor::inverse() implemented (but not tested!)
00095  *
00096  * Revision 1.6  2003/10/06 13:58:48  j_novak
00097  * The memory management has been improved.
00098  * Implementation of the covariant derivative with respect to the exact Tensor
00099  * type.
00100  *
00101  * Revision 1.5  2003/10/03 11:21:48  j_novak
00102  * More methods for the class Metric
00103  *
00104  * Revision 1.4  2003/10/02 15:45:51  j_novak
00105  * New class Metric
00106  *
00107  * Revision 1.3  2003/10/01 15:39:43  e_gourgoulhon
00108  * Added assert to insure that both indices have the same type.
00109  *
00110  * Revision 1.2  2003/09/26 08:05:31  j_novak
00111  * New class Vector.
00112  *
00113  * Revision 1.1  2003/09/25 13:37:40  j_novak
00114  * Symmetric tensors of valence 2 are now implemented (not tested yet).
00115  *
00116  *
00117  * $Header: /cvsroot/Lorene/C++/Source/Tensor/sym_tensor.C,v 1.22 2007/12/21 16:07:08 j_novak Exp $
00118  *
00119  */
00120 
00121 // Headers C
00122 #include <stdlib.h>
00123 #include <assert.h>
00124 #include <math.h>
00125 
00126 // Headers Lorene
00127 #include "metric.h"
00128 
00129             //--------------//
00130             // Constructors //
00131             //--------------//
00132 
00133 // Standard constructor 
00134 // --------------------
00135 Sym_tensor::Sym_tensor(const Map& map, const Itbl& tipe, 
00136                        const Base_vect& triad_i) 
00137             : Tensor_sym(map, 2, tipe, triad_i, 0, 1) {
00138         
00139     set_der_0x0() ;
00140 
00141 }
00142 
00143 // Standard constructor when all the indices are of the same type
00144 // --------------------------------------------------------------
00145 Sym_tensor::Sym_tensor(const Map& map, int tipe, const Base_vect& triad_i)  
00146             : Tensor_sym(map, 2, tipe, triad_i, 0, 1) {
00147 
00148     set_der_0x0() ;
00149 }
00150 
00151 // Copy constructor
00152 // ----------------
00153 Sym_tensor::Sym_tensor(const Sym_tensor& source) 
00154             : Tensor_sym( source ) {
00155 
00156     set_der_0x0() ;
00157 
00158     for (int i_met = 0; i_met < N_MET_MAX; i_met++) {
00159 
00160       if ( source.p_transverse[i_met] != 0x0 ) {
00161     set_dependance( *source.met_depend[i_met] ) ;
00162     int jp = get_place_met( *source.met_depend[i_met] ) ;
00163     assert ((jp>=0) && (jp<N_MET_MAX)) ;
00164     p_transverse[jp] = 
00165     new Sym_tensor_trans ( *source.p_transverse[i_met] ) ;
00166       }
00167 
00168       if ( source.p_longit_pot[i_met] != 0x0 ) {
00169     set_dependance( *source.met_depend[i_met] ) ;
00170     int jp = get_place_met( *source.met_depend[i_met] ) ;
00171     assert ((jp>=0) && (jp<N_MET_MAX)) ;
00172     p_longit_pot[jp] = 
00173     new Vector ( *source.p_longit_pot[i_met] ) ;
00174       }
00175     }
00176     if (source.p_eta != 0x0) p_eta = new Scalar( *(source.p_eta) ) ; 
00177     if (source.p_mu != 0x0) p_mu = new Scalar( *(source.p_mu) ) ; 
00178     if (source.p_www != 0x0) p_www = new Scalar( *(source.p_www) ) ; 
00179     if (source.p_xxx != 0x0) p_xxx = new Scalar( *(source.p_xxx) ) ; 
00180   
00181 }   
00182 
00183 
00184 // Constructor from a Tensor
00185 // --------------------------
00186 Sym_tensor::Sym_tensor(const Tensor& source) 
00187             : Tensor_sym(*source.mp, 2, source.type_indice, *(source.triad), 
00188                          0, 1) {
00189     
00190     assert(source.valence == 2) ;
00191     
00192     for (int ic=0 ; ic<n_comp ; ic++) {
00193         int posi = source.position(indices(ic)) ;
00194         *(cmp[ic]) = *(source.cmp[posi]) ;
00195     }
00196         
00197     set_der_0x0() ;
00198 }   
00199 
00200     
00201 // Constructor from a file
00202 // -----------------------
00203 Sym_tensor::Sym_tensor(const Map& map, const Base_vect& triad_i, FILE* fd)
00204             : Tensor_sym(map, triad_i, fd) {
00205     
00206     assert (valence == 2) ;
00207     assert (n_comp == 6) ;
00208     set_der_0x0() ;
00209 }
00210 
00211             //--------------//
00212             //  Destructor  //
00213             //--------------//
00214 
00215 Sym_tensor::~Sym_tensor() {
00216 
00217   Sym_tensor::del_deriv() ;
00218 
00219 }
00220 
00221 
00222 
00223             //--------------//
00224             //  Assignment  //
00225             //--------------//
00226 
00227 void Sym_tensor::operator=(const Sym_tensor& source) {
00228     
00229     Tensor_sym::operator=(source) ; 
00230     
00231     del_deriv() ;
00232 
00233     for (int i_met = 0; i_met < N_MET_MAX; i_met++) {
00234 
00235       if ( source.p_transverse[i_met] != 0x0 ) {
00236     set_dependance( *source.met_depend[i_met] ) ;
00237     int jp = get_place_met( *source.met_depend[i_met] ) ;
00238     assert ((jp>=0) && (jp<N_MET_MAX)) ;
00239     p_transverse[jp] = 
00240     new Sym_tensor_trans ( *source.p_transverse[i_met] ) ;
00241       }
00242 
00243       if ( source.p_longit_pot[i_met] != 0x0 ) {
00244     set_dependance( *source.met_depend[i_met] ) ;
00245     int jp = get_place_met( *source.met_depend[i_met] ) ;
00246     assert ((jp>=0) && (jp<N_MET_MAX)) ;
00247     p_longit_pot[jp] = 
00248     new Vector ( *source.p_longit_pot[i_met] ) ;
00249       }
00250 
00251     }
00252     if (source.p_eta != 0x0) p_eta = new Scalar( *(source.p_eta) ) ; 
00253     if (source.p_mu != 0x0) p_mu = new Scalar( *(source.p_mu) ) ; 
00254     if (source.p_www != 0x0) p_www = new Scalar( *(source.p_www) ) ; 
00255     if (source.p_xxx != 0x0) p_xxx = new Scalar( *(source.p_xxx) ) ; 
00256     
00257 }
00258 
00259 
00260 void Sym_tensor::operator=(const Tensor_sym& tt) {
00261     
00262     Tensor_sym::operator=(tt) ; 
00263 
00264     del_deriv() ;
00265 }
00266 
00267 
00268 void Sym_tensor::operator=(const Tensor& tt) {
00269     
00270     Tensor_sym::operator=(tt) ; 
00271 
00272     del_deriv() ;
00273 }
00274 
00275             //-------------------//
00276             // Memory managment  //
00277             //-------------------//
00278 
00279 void Sym_tensor::del_deriv() const {
00280 
00281     for (int i=0; i<N_MET_MAX; i++) 
00282         del_derive_met(i) ;
00283     
00284     if (p_eta != 0x0) delete p_eta ; 
00285     if (p_mu != 0x0) delete p_mu ; 
00286     if (p_www != 0x0) delete p_www ; 
00287     if (p_xxx != 0x0) delete p_xxx ; 
00288     if (p_ttt != 0x0) delete p_ttt ; 
00289     if (p_aaa != 0x0) delete p_aaa ;
00290     if (p_tilde_b != 0x0) delete p_tilde_b ;
00291     if (p_tilde_c != 0x0) delete p_tilde_c ;
00292         
00293     set_der_0x0() ;
00294     Tensor::del_deriv() ;
00295 
00296 }
00297 
00298 void Sym_tensor::set_der_0x0() const {
00299 
00300   for (int i=0; i<N_MET_MAX; i++) 
00301     set_der_met_0x0(i) ;
00302   p_eta = 0x0 ; 
00303   p_mu = 0x0 ; 
00304   p_www = 0x0 ; 
00305   p_xxx = 0x0 ; 
00306   p_ttt = 0x0 ; 
00307   p_aaa = 0x0 ;
00308   p_tilde_b = 0x0 ;
00309   p_tilde_c = 0x0 ;
00310 }
00311 
00312 
00313 void Sym_tensor::del_derive_met(int j) const {
00314 
00315     assert( (j>=0) && (j<N_MET_MAX) ) ;
00316 
00317     if (met_depend[j] != 0x0) {
00318         if ( p_transverse[j] != 0x0) delete p_transverse[j] ;
00319         if ( p_longit_pot[j] != 0x0) delete p_longit_pot[j] ;
00320     
00321         set_der_met_0x0(j) ;
00322     
00323         Tensor::del_derive_met(j) ;
00324     }
00325 }
00326 
00327 
00328 void Sym_tensor::set_der_met_0x0(int i) const {
00329 
00330   assert( (i>=0) && (i<N_MET_MAX) ) ;
00331 
00332   p_transverse[i] = 0x0 ;
00333   p_longit_pot[i] = 0x0 ;
00334 
00335 }
00336 
00337 
00338                 //----------------------------------//
00339                 //  Computation of derived members  //
00340                 //----------------------------------//
00341     
00342 const Vector& Sym_tensor::divergence(const Metric& gam) const {
00343   
00344     const Vector* pvect = 
00345         dynamic_cast<const Vector*>( &(Tensor::divergence(gam)) ) ;
00346 
00347     assert(pvect != 0x0) ;
00348 
00349     return *pvect ;
00350 }
00351 
00352 
00353 Sym_tensor Sym_tensor::derive_lie(const Vector& vv) const {
00354 
00355     Sym_tensor resu(*mp, type_indice, *triad) ; 
00356     
00357     compute_derive_lie(vv, resu) ;
00358     
00359     return resu ; 
00360     
00361 }
00362 
00363 
00364 
00365 Sym_tensor* Sym_tensor::inverse() const {
00366 
00367   //Le resultat :
00368   Sym_tensor* res = 
00369     new Sym_tensor(*mp, -type_indice(0), *triad) ;
00370     
00371   // le determinant :
00372   Scalar determ1(*mp) ;
00373   determ1 = double(1)/
00374     (operator()(1, 1)*operator()(2, 2)*operator()(3, 3) 
00375      + operator()(1, 2)*operator()(2, 3)*operator()(1, 3)
00376      + operator()(1, 3)*operator()(1, 2)*operator()(2, 3) 
00377      - operator()(1, 3)*operator()(2, 2)*operator()(1, 3)
00378      - operator()(2, 3)*operator()(2, 3)*operator()(1, 1) 
00379      - operator()(3, 3)*operator()(1, 2)*operator()(1, 2) ) ;
00380     
00381   int sgn ; // Le signe du co-facteur ...
00382   int l_up, l_down, c_left, c_right ;       // Coordonnees du cofacteur :
00383     
00384   Scalar cofacteur(*mp) ;
00385     
00386   for (int i=1 ; i<=3 ; i++) {
00387     sgn = 1 ;
00388     for (int j=i ; j<=3 ; j++) {
00389         
00390       switch (j) {
00391         
00392       case 1 : {
00393     c_left = 2 ;
00394     c_right = 3 ;
00395     break ;
00396       }
00397       case 2 : {
00398     c_left = 1 ;
00399     c_right = 3 ;
00400     break ;
00401       }
00402       default : {
00403     c_left = 1 ;
00404     c_right = 2 ;
00405     break ;
00406       }
00407       }
00408         
00409       switch (i) {
00410         
00411       case 1 : {
00412     l_up = 2 ;
00413     l_down = 3 ;
00414     break ;
00415       }
00416       case 2 : {
00417     l_up = 1 ;
00418     l_down = 3 ;
00419     break ;
00420       }
00421       default : {
00422     l_up = 1 ;
00423     l_down = 2 ;
00424     break ;
00425       } 
00426       }
00427         
00428       cofacteur = sgn*(operator()(l_up, c_left)*operator()(l_down, c_right)-
00429                operator()(l_up, c_right)*operator()(l_down, c_left))*determ1 ;
00430         
00431       res->set(i, j) = cofacteur ;
00432       sgn *= -1 ;
00433     }
00434   }
00435   return res ;
00436 
00437 }
00438 
00439 void Sym_tensor::exponential_filter_r(int lzmin, int lzmax, int p, 
00440               double alpha) {
00441     if( triad->identify() == (mp->get_bvect_cart()).identify() ) 
00442     for (int i=0; i<n_comp; i++)
00443         cmp[i]->exponential_filter_r(lzmin, lzmax, p, alpha) ;
00444     else {
00445     assert( triad->identify() == (mp->get_bvect_spher()).identify()) ;
00446     Scalar srr_tmp = operator()(1,1) ; 
00447     srr_tmp.exponential_filter_r(lzmin, lzmax, p, alpha) ;
00448     Scalar eta_tmp = eta() ;
00449     eta_tmp.div_r() ; //## to change one day...
00450     eta_tmp.exponential_filter_r(lzmin, lzmax, p, alpha) ;
00451     Scalar mu_tmp = mu() ;
00452     mu_tmp.div_r() ; //## to change one day...
00453     mu_tmp.exponential_filter_r(lzmin, lzmax, p, alpha) ;
00454     Scalar w_tmp = www() ;
00455     w_tmp.exponential_filter_r(lzmin, lzmax, p, alpha) ;
00456     Scalar x_tmp = xxx() ;
00457     x_tmp.exponential_filter_r(lzmin, lzmax, p, alpha) ;
00458     Scalar t_tmp = ttt() ;
00459     t_tmp.exponential_filter_r(lzmin, lzmax, p, alpha) ;
00460     set_auxiliary(srr_tmp, eta_tmp, mu_tmp, w_tmp, x_tmp, t_tmp) ;
00461     }
00462 }
00463 
00464 void Sym_tensor::exponential_filter_ylm(int lzmin, int lzmax, int p, 
00465               double alpha) {
00466     if( triad->identify() == (mp->get_bvect_cart()).identify() ) 
00467     for (int i=0; i<n_comp; i++)
00468         cmp[i]->exponential_filter_ylm(lzmin, lzmax, p, alpha) ;
00469     else {
00470     assert( triad->identify() == (mp->get_bvect_spher()).identify()) ;
00471     Scalar srr_tmp = operator()(1,1) ; 
00472     srr_tmp.exponential_filter_ylm(lzmin, lzmax, p, alpha) ;
00473     Scalar eta_tmp = eta() ;
00474     eta_tmp.div_r() ; //## to change one day...
00475     eta_tmp.exponential_filter_ylm(lzmin, lzmax, p, alpha) ;
00476     Scalar mu_tmp = mu() ;
00477     mu_tmp.div_r() ; //## to change one day...
00478     mu_tmp.exponential_filter_ylm(lzmin, lzmax, p, alpha) ;
00479     Scalar w_tmp = www() ;
00480     w_tmp.exponential_filter_ylm(lzmin, lzmax, p, alpha) ;
00481     Scalar x_tmp = xxx() ;
00482     x_tmp.exponential_filter_ylm(lzmin, lzmax, p, alpha) ;
00483     Scalar t_tmp = ttt() ;
00484     t_tmp.exponential_filter_ylm(lzmin, lzmax, p, alpha) ;
00485     set_auxiliary(srr_tmp, eta_tmp, mu_tmp, w_tmp, x_tmp, t_tmp) ;
00486     }
00487 }

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