metric.C

00001 /*
00002  *  Definition of methods for the class Metric.
00003  *
00004  */
00005 
00006 /*
00007  *   Copyright (c) 2003 Eric Gourgoulhon & Jerome Novak
00008  *
00009  *   Copyright (c) 1999-2001 Philippe Grandclement (for previous class Metrique)
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 version 2
00015  *   as published by the Free Software Foundation.
00016  *
00017  *   LORENE is distributed in the hope that it will be useful,
00018  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020  *   GNU General Public License for more details.
00021  *
00022  *   You should have received a copy of the GNU General Public License
00023  *   along with LORENE; if not, write to the Free Software
00024  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025  *
00026  */
00027 
00028 char metric_C[] = "$Header: /cvsroot/Lorene/C++/Source/Metric/metric.C,v 1.11 2005/03/02 15:03:46 f_limousin Exp $" ;
00029 
00030 /*
00031  * $Id: metric.C,v 1.11 2005/03/02 15:03:46 f_limousin Exp $
00032  * $Log: metric.C,v $
00033  * Revision 1.11  2005/03/02 15:03:46  f_limousin
00034  * p_radial_vect is added in del_deriv() and set_der_0x0.
00035  *
00036  * Revision 1.10  2004/11/18 12:22:33  jl_jaramillo
00037  * Method to compute the unit radial vector field with respect
00038  * spherical surfaces
00039  *
00040  * Revision 1.9  2004/02/18 18:45:36  e_gourgoulhon
00041  * Computation of p_ricci_scal thanks to the new method
00042  * Tensor::trace(const Metric& ).
00043  *
00044  * Revision 1.8  2004/01/22 14:35:23  e_gourgoulhon
00045  * Corrected bug in operator=(const Sym_tensor& ): adresses of deleted
00046  * p_met_cov and p_met_con are now set to 0x0.
00047  *
00048  * Revision 1.7  2004/01/20 09:51:40  f_limousin
00049  * Correction in metric::determinant() : indices of tensors go now from 1 to
00050  * 3 !
00051  *
00052  * Revision 1.6  2003/12/30 23:06:30  e_gourgoulhon
00053  * Important reorganization of class Metric:
00054  *   -- suppression of virtual methods fait_* : the actual computations
00055  *      are now performed via the virtual methods con(), cov(), connect(),
00056  *      ricci(), ricci_scal(), determinant()
00057  *   -- the member p_connect is now treated as an ordinary derived data
00058  *      member
00059  *   -- the construction of the associated connection (member p_connect)
00060  *      is performed thanks to the new methods Map::flat_met_spher() and
00061  *      Map::flat_met_cart().
00062  *
00063  * Revision 1.5  2003/10/28 21:23:59  e_gourgoulhon
00064  * Method Tensor::contract(int, int) renamed Tensor::scontract(int, int).
00065  *
00066  * Revision 1.4  2003/10/06 16:17:30  j_novak
00067  * Calculation of contravariant derivative and Ricci scalar.
00068  *
00069  * Revision 1.3  2003/10/06 13:58:47  j_novak
00070  * The memory management has been improved.
00071  * Implementation of the covariant derivative with respect to the exact Tensor
00072  * type.
00073  *
00074  * Revision 1.2  2003/10/03 11:21:47  j_novak
00075  * More methods for the class Metric
00076  *
00077  * Revision 1.1  2003/10/02 15:45:50  j_novak
00078  * New class Metric
00079  *
00080  *
00081  *
00082  * $Header: /cvsroot/Lorene/C++/Source/Metric/metric.C,v 1.11 2005/03/02 15:03:46 f_limousin Exp $
00083  *
00084  */
00085 
00086 // C headers
00087 #include<stdlib.h>
00088 
00089 // Lorene headers
00090 #include "metric.h"
00091 #include "utilitaires.h"
00092 
00093                     //-----------------//
00094                     //  Constructors   //
00095                     //-----------------//
00096 
00097 Metric::Metric(const Sym_tensor& symti) : mp(&symti.get_mp()),
00098                       p_met_cov(0x0), 
00099                                           p_met_con(0x0) {
00100   
00101   int type_index = symti.get_index_type(0) ;
00102   assert (symti.get_index_type(1) == type_index) ;
00103 
00104   if (type_index == COV) {
00105     p_met_cov = new Sym_tensor(symti) ;
00106   }
00107   else {
00108     assert(type_index == CON) ;
00109     p_met_con = new Sym_tensor(symti) ;
00110   }
00111 
00112   set_der_0x0() ;
00113   set_tensor_depend_0x0() ;
00114 
00115 }
00116 
00117 
00118 Metric::Metric(const Metric& meti) : mp(meti.mp),
00119                                      p_met_cov(0x0),
00120                      p_met_con(0x0) {
00121 
00122   if (meti.p_met_cov != 0x0) p_met_cov = new Sym_tensor(*meti.p_met_cov) ;
00123 
00124   if (meti.p_met_con != 0x0) p_met_con = new Sym_tensor(*meti.p_met_con) ;
00125 
00126   set_der_0x0() ;
00127   set_tensor_depend_0x0() ;
00128 
00129 }
00130 
00131 Metric::Metric(const Map& mpi, FILE* ) : mp(&mpi), 
00132                      p_met_cov(0x0), 
00133                                          p_met_con(0x0) {
00134 
00135   cout << "Metric::Metric(FILE*) : not implemented yet!" << endl ;
00136 
00137   abort() ;
00138 }
00139 
00140 Metric::Metric(const Map& mpi) : mp(&mpi),  
00141                      p_met_cov(0x0), 
00142                                  p_met_con(0x0) {
00143   set_der_0x0() ;
00144   set_tensor_depend_0x0() ;
00145 
00146 }
00147 
00148 
00149                     //---------------//
00150                     //  Destructor   //
00151                     //---------------//
00152 
00153 Metric::~Metric() {
00154 
00155   if (p_met_cov != 0x0) delete p_met_cov ;
00156 
00157   if (p_met_con != 0x0) delete p_met_con ;
00158 
00159   del_deriv() ;
00160 
00161   del_tensor_depend() ;
00162 
00163 }
00164 
00165                 //-------------------//
00166                 // Memory management //
00167                 //-------------------//
00168                 
00169 void Metric::del_deriv() const {
00170   
00171   if (p_connect != 0x0) delete p_connect ; 
00172   if (p_ricci_scal != 0x0) delete p_ricci_scal ;
00173   if (p_determinant != 0x0) delete p_determinant ;
00174   if (p_radial_vect != 0x0) delete p_radial_vect ;
00175   
00176   set_der_0x0() ;
00177 
00178     //## call to del_tensor_depend() ?
00179 }
00180 
00181 void Metric::set_der_0x0() const {
00182 
00183   p_connect = 0x0 ; 
00184   p_ricci_scal = 0x0 ;
00185   p_determinant = 0x0 ;
00186   p_radial_vect = 0x0 ;
00187 
00188 }
00189 
00190 void Metric::del_tensor_depend() const {
00191 
00192     for (int i=0 ; i<N_TENSOR_DEPEND ; i++)
00193     if (tensor_depend[i] != 0x0) {
00194       int j = tensor_depend[i]->get_place_met(*this) ;
00195       if (j!=-1) tensor_depend[i]->del_derive_met(j) ;
00196     }
00197     set_tensor_depend_0x0() ;
00198  
00199 }
00200 
00201 void Metric::set_tensor_depend_0x0() const {
00202 
00203   for (int i=0 ; i<N_TENSOR_DEPEND ; i++) {
00204     tensor_depend[i] = 0x0 ;
00205   }
00206 }
00207 
00208   
00209                     //-----------------------//
00210                     // Mutators / assignment //
00211                     //-----------------------//
00212 
00213 void Metric::operator=(const Metric& meti) {
00214 
00215   assert( mp == meti.mp) ;
00216 
00217   if (p_met_cov != 0x0) {
00218     delete p_met_cov ;
00219     p_met_cov = 0x0 ; 
00220   }
00221   
00222   if (p_met_con != 0x0) {
00223     delete p_met_con ;
00224     p_met_con = 0x0 ; 
00225   }
00226   
00227   if (meti.p_met_cov != 0x0) {
00228     p_met_cov = new Sym_tensor(*meti.p_met_cov) ;
00229   }
00230 
00231   if (meti.p_met_con != 0x0) {
00232     p_met_con = new Sym_tensor(*meti.p_met_con) ;
00233   }
00234 
00235   del_deriv() ;
00236 
00237 }
00238 
00239 void Metric::operator=(const Sym_tensor& symti) {
00240   
00241   assert(mp == &symti.get_mp()) ;
00242 
00243   int type_index = symti.get_index_type(0) ;
00244   assert (symti.get_index_type(1) == type_index) ;
00245 
00246   if (p_met_cov != 0x0) {
00247     delete p_met_cov ;
00248     p_met_cov = 0x0 ; 
00249   }
00250   
00251   if (p_met_con != 0x0) {
00252     delete p_met_con ;
00253     p_met_con = 0x0 ; 
00254   }
00255   
00256   if (type_index == COV) {
00257     p_met_cov = new Sym_tensor(symti) ;
00258   }
00259   else {
00260     assert(type_index == CON) ;
00261     p_met_con = new Sym_tensor(symti) ;
00262   }
00263 
00264   del_deriv() ;
00265 
00266 }
00267 
00268             //----------------//
00269             //   Accessors    //
00270             //----------------//
00271 
00272 
00273 const Sym_tensor& Metric::cov() const {
00274   
00275     if (p_met_cov == 0x0) {   // a new computation is necessary
00276         assert( p_met_con != 0x0 ) ;
00277         p_met_cov = p_met_con->inverse() ;
00278     }
00279 
00280     return *p_met_cov ; 
00281 }
00282 
00283 const Sym_tensor& Metric::con() const {
00284   
00285     if (p_met_con == 0x0) {   // a new computation is necessary
00286         assert( p_met_cov != 0x0 ) ;
00287         p_met_con = p_met_cov->inverse() ;
00288     }
00289 
00290     return *p_met_con ; 
00291 }
00292 
00293 
00294 const Connection& Metric::connect() const {
00295 
00296     if (p_connect == 0x0) {   // a new computation is necessary
00297     
00298         // The triad is obtained from the covariant or contravariant representation:
00299         const Base_vect_spher* triad_s ; 
00300         const Base_vect_cart* triad_c ; 
00301         if (p_met_cov != 0x0) {
00302             triad_s = 
00303               dynamic_cast<const Base_vect_spher*>(p_met_cov->get_triad()) ; 
00304             triad_c = 
00305               dynamic_cast<const Base_vect_cart*>(p_met_cov->get_triad()) ; 
00306         }
00307         else {
00308             assert(p_met_con != 0x0) ; 
00309             triad_s = 
00310               dynamic_cast<const Base_vect_spher*>(p_met_con->get_triad()) ; 
00311             triad_c = 
00312               dynamic_cast<const Base_vect_cart*>(p_met_con->get_triad()) ; 
00313         }
00314     
00315         // Background flat metric in spherical or Cartesian components
00316         if ( triad_s != 0x0 ) {
00317             p_connect = new Connection(*this, mp->flat_met_spher()) ;
00318         }
00319         else {
00320             assert( triad_c != 0x0 ) ;
00321             p_connect = new Connection(*this, mp->flat_met_cart()) ;
00322         }
00323     
00324     }
00325 
00326     return *p_connect ; 
00327 
00328 }
00329 
00330 
00331 const Sym_tensor& Metric::ricci() const {
00332 
00333     const Tensor& ricci_connect = connect().ricci() ; 
00334     
00335     // Check: the Ricci tensor of the connection associated with 
00336     //  the metric must be symmetric:
00337     assert( typeid(ricci_connect) == typeid(const Sym_tensor&) ) ; 
00338 
00339     return dynamic_cast<const Sym_tensor&>( ricci_connect ) ; 
00340 }
00341 
00342 
00343 const Scalar& Metric::ricci_scal() const {
00344 
00345     if (p_ricci_scal == 0x0) {   // a new computation is necessary
00346 
00347         p_ricci_scal = new Scalar( ricci().trace(*this) ) ; 
00348 
00349     }
00350 
00351     return *p_ricci_scal  ; 
00352 
00353 }
00354 
00355 const Vector& Metric::radial_vect() const {
00356 
00357   if (p_radial_vect == 0x0) { // a new computation is necessary
00358 
00359 
00360     p_radial_vect = new Vector ((*this).get_mp(), CON, *((*this).con().get_triad()) ) ;
00361 
00362     Scalar prov ( sqrt((*this).con()(1,1)) ) ;
00363 
00364     prov.std_spectral_base() ;
00365 
00366        
00367     p_radial_vect->set(1) = (*this).con()(1,1)/ prov ;
00368  
00369     p_radial_vect->set(2) = (*this).con()(1,2)/ prov ;
00370 
00371     p_radial_vect->set(3) = (*this).con()(1,3)/ prov ;
00372 
00373 
00374 
00375     //    p_radial_vect.std_spectral_base() ;
00376 
00377 
00378   }
00379 
00380   return *p_radial_vect   ;
00381 
00382 }
00383 
00384 
00385 const Scalar& Metric::determinant() const {
00386 
00387     if (p_determinant == 0x0) {   // a new computation is necessary
00388 
00389         p_determinant = new Scalar(*mp) ;
00390         *p_determinant = cov()(1, 1)*cov()(2, 2)*cov()(3, 3) 
00391         + cov()(1, 2)*cov()(2, 3)*cov()(3, 1)
00392         + cov()(1, 3)*cov()(2, 1)*cov()(3, 2) 
00393         - cov()(3, 1)*cov()(2, 2)*cov()(1, 3)
00394         - cov()(3, 2)*cov()(2, 3)*cov()(1, 1) 
00395         - cov()(3, 3)*cov()(2, 1)*cov()(1, 2) ;
00396     }
00397 
00398     return *p_determinant ; 
00399 }
00400 
00401 
00402  
00403                 //---------//
00404                 // Outputs //
00405                 //---------//
00406 
00407 void Metric::sauve(FILE* fd) const {
00408 
00409   // Which representation is to be saved
00410   int indic ;
00411   if (p_met_cov != 0x0)
00412     indic = COV ;
00413   else if (p_met_con != 0x0)
00414     indic = CON ;
00415   else indic = 0 ;
00416   fwrite_be(&indic, sizeof(int), 1, fd) ;
00417   switch (indic) {
00418   case COV : {
00419     p_met_cov->sauve(fd) ;
00420     break ;
00421   }
00422   case CON : {
00423     p_met_con->sauve(fd) ;
00424     break ;
00425   }
00426   default : {
00427     break ;
00428   }
00429   } 
00430 }
00431 
00432 ostream& operator<<(ostream& ost, const Metric& meti) {
00433 
00434   meti >> ost ;
00435   return ost ;
00436 }
00437 
00438 
00439 ostream& Metric::operator>>(ostream& ost) const {
00440 
00441   ost << '\n' ;
00442 
00443   ost << "General type metric" << '\n' ;
00444   ost << "-------------------" << '\n' ;
00445   ost << '\n' ;
00446 
00447   if (p_met_cov == 0x0) {
00448     ost << "Covariant representation unknown!" << '\n' ;
00449     assert( p_met_con != 0x0) ;
00450     ost << "CONTRA-variant representation: " << '\n' ;
00451     ost << *p_met_con ;
00452   }
00453   else {
00454     ost << "Covariant representation: " << '\n' ;
00455     ost << *p_met_cov ;
00456   }
00457 
00458 
00459   if (p_connect == 0x0)
00460     ost << "Associated connection not computed yet." << '\n' ;
00461   else
00462     ost << "Associated connection computed." << '\n' ;
00463 
00464   if (p_ricci_scal == 0x0)
00465     ost << "Ricci scalar not computed yet." << '\n' ;
00466   else
00467     ost << "Ricci scalar computed." << '\n' ;
00468   
00469   if (p_determinant == 0x0)
00470     ost << "determinant not computed yet." << '\n' ;
00471   else
00472     ost << "determinant computed." << '\n' ;
00473 
00474   ost << endl ;
00475   return ost ;
00476 }
00477 

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