scalar_deriv.C

00001 /*
00002  * Computations of partial derivatives d/dx, d/dy and d/dz of a Scalar.
00003  */
00004 
00005 /*
00006  *   Copyright (c) 2003-2004 Eric Gourgoulhon & Jerome Novak
00007  *
00008  *   Copyright (c) 1999-2001 Eric Gourgoulhon (for a preceding Cmp version)
00009  *   Copyright (c) 1999-2001 Philippe Grandclement (for a preceding Cmp version)
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 scalar_deriv_C[] = "$Header: /cvsroot/Lorene/C++/Source/Tensor/Scalar/scalar_deriv.C,v 1.19 2012/01/17 15:10:21 j_penner Exp $" ;
00031 
00032 
00033 
00034 /*
00035  * Revision 1.17  2005/11/24 09:25:08  j_novak
00036  * Added the Scalar version for the Laplacian
00037  *
00038  * Revision 1.16  2005/09/15 15:51:27  j_novak
00039  * The "rotation" (change of triad) methods take now Scalars as default
00040  * arguments.
00041  *
00042  * Revision 1.15  2005/05/25 16:11:05  j_novak
00043  * Better handling of the case with no compactified domain.
00044  *
00045  * Revision 1.14  2004/08/24 09:14:52  p_grandclement
00046  * Addition of some new operators, like Poisson in 2d... It now requieres the
00047  * GSL library to work.
00048  *
00049  * Also, the way a variable change is stored by a Param_elliptic is changed and
00050  * no longer uses Change_var but rather 2 Scalars. The codes using that feature
00051  * will requiere some modification. (It should concern only the ones about monopoles)
00052  *
00053  * Revision 1.13  2004/06/22 08:50:00  p_grandclement
00054  * Addition of everything needed for using the logarithmic mapping
00055  *
00056  * Revision 1.12  2004/02/26 22:51:34  e_gourgoulhon
00057  * Added methods derive_cov, derive_con and derive_lie.
00058  *
00059  * Revision 1.11  2004/01/28 14:02:06  j_novak
00060  * Suppressed base handling.
00061  *
00062  * Revision 1.10  2004/01/28 13:25:42  j_novak
00063  * The ced_mult_r arguments have been suppressed from the Scalar::*dsd* methods.
00064  * In the div/mult _r_dzpuis, there is no more default value.
00065  *
00066  * Revision 1.9  2004/01/27 15:10:02  j_novak
00067  * New methods Scalar::div_r_dzpuis(int) and Scalar_mult_r_dzpuis(int)
00068  * which replace div_r_inc*. Tried to clean the dzpuis handling.
00069  * WARNING: no testing at this point!!
00070  *
00071  * Revision 1.8  2003/11/03 13:37:59  j_novak
00072  * Still dzpuis...
00073  *
00074  * Revision 1.7  2003/10/29 13:14:03  e_gourgoulhon
00075  * Added integer argument to derivative functions dsdr, etc...
00076  * so that one can choose the dzpuis of the result (default=2).
00077  *
00078  * Revision 1.6  2003/10/17 13:46:15  j_novak
00079  * The argument is now between 1 and 3 (instead of 0->2)
00080  *
00081  * Revision 1.5  2003/10/15 16:03:38  j_novak
00082  * Added the angular Laplace operator for Scalar.
00083  *
00084  * Revision 1.4  2003/10/15 10:43:58  e_gourgoulhon
00085  * Added new methods dsdt and stdsdp.
00086  *
00087  * Revision 1.3  2003/10/11 14:43:29  e_gourgoulhon
00088  * Changed name of local Cmp "deriv" to "derivee" (in order not
00089  * to shadow the member deriv).
00090  *
00091  * Revision 1.2  2003/10/10 15:57:29  j_novak
00092  * Added the state one (ETATUN) to the class Scalar
00093  *
00094  * Revision 1.1  2003/09/25 08:13:52  j_novak
00095  * Added method for calculating derivatives
00096  *
00097  *
00098  * $Header: /cvsroot/Lorene/C++/Source/Tensor/Scalar/scalar_deriv.C,v 1.19 2012/01/17 15:10:21 j_penner Exp $
00099  *
00100  */
00101  
00102 // Headers Lorene
00103 #include "scalar.h"
00104 #include "map.h"
00105 #include "tensor.h"
00106 #include "cmp.h"
00107 
00108             //---------------------//
00109             //         d/dr        //
00110             //---------------------//
00111 
00112 const Scalar& Scalar::dsdr() const {
00113 
00114     // Protection
00115     assert(etat != ETATNONDEF) ;
00116 
00117     // If the derivative has not been previously computed, the 
00118     //  computation must be done by the appropriate routine of the mapping : 
00119 
00120     if (p_dsdr == 0x0) {
00121       p_dsdr = new Scalar(*mp) ;
00122       if (etat == ETATUN) {
00123     p_dsdr->set_etat_zero() ;
00124       }
00125       else {
00126     mp->dsdr(*this, *p_dsdr) ;
00127 
00128       }
00129     }
00130      
00131     int dzp = (dzpuis == 0) ? 2 : dzpuis+1 ;
00132     if (mp->get_mg()->get_type_r(mp->get_mg()->get_nzone() - 1) != UNSURR)
00133     dzp = 0 ;
00134     p_dsdr->set_dzpuis(dzp) ;
00135 
00136     return *p_dsdr ;
00137 
00138 }
00139 
00140             //--------------------//
00141             //    1/r d/dtheta    //
00142             //--------------------//
00143 
00144 const Scalar& Scalar::srdsdt() const {
00145 
00146     // Protection
00147     assert(etat != ETATNONDEF) ;
00148 
00149     // If the derivative has not been previously computed, the 
00150     //  computation must be done by the appropriate routine of the mapping : 
00151 
00152     if (p_srdsdt == 0x0) {
00153     p_srdsdt = new Scalar(*mp) ;
00154     if (etat == ETATUN) {
00155       p_srdsdt->set_etat_zero() ;
00156     }
00157     else {
00158       mp->srdsdt(*this, *p_srdsdt) ;
00159     }
00160     }
00161 
00162     int dzp = (dzpuis == 0) ? 2 : dzpuis+1 ;
00163     if (mp->get_mg()->get_type_r(mp->get_mg()->get_nzone() - 1) != UNSURR)
00164     dzp = 0 ;
00165     p_srdsdt->set_dzpuis(dzp) ;
00166 
00167     return *p_srdsdt ;
00168 
00169 }
00170 
00171 
00172             //------------------------------//
00173             //    1/(r sin(theta)) d/dphi    //
00174             //------------------------------//
00175 
00176 const Scalar& Scalar::srstdsdp() const {
00177 
00178     // Protection
00179     assert(etat != ETATNONDEF) ;
00180 
00181     // If the derivative has not been previously computed, the 
00182     //  computation must be done by the appropriate routine of the mapping : 
00183 
00184     if (p_srstdsdp == 0x0) {
00185       p_srstdsdp = new Scalar(*mp) ;
00186       if (etat == ETATUN) {
00187     p_srstdsdp->set_etat_zero() ;
00188       }
00189       else {
00190     mp->srstdsdp(*this, *p_srstdsdp) ;
00191       }
00192     }
00193 
00194     int dzp = (dzpuis == 0) ? 2 : dzpuis+1 ;
00195     if (mp->get_mg()->get_type_r(mp->get_mg()->get_nzone() - 1) != UNSURR)
00196     dzp = 0 ;
00197     p_srstdsdp->set_dzpuis(dzp) ;
00198 
00199     return *p_srstdsdp ;
00200 
00201 }
00202 
00203             //--------------------//
00204             //      d/dtheta      //
00205             //--------------------//
00206 
00207 const Scalar& Scalar::dsdt() const {
00208     
00209     assert(etat != ETATNONDEF) ;    // Protection
00210 
00211     // If the derivative has not been previously computed, the 
00212     //  computation must be done by the appropriate routine of the mapping : 
00213 
00214     if (p_dsdt == 0x0) {
00215     
00216         p_dsdt = new Scalar(*mp) ;
00217 
00218         if (etat == ETATUN) {
00219             p_dsdt->set_etat_zero() ;   
00220         }
00221         else {
00222             mp->dsdt(*this, *p_dsdt) ;
00223         }
00224     }
00225     
00226     
00227     p_dsdt->set_dzpuis(dzpuis) ;
00228 
00229     return *p_dsdt ;
00230 
00231 }
00232 
00233             //------------------------------//
00234             //      1/sin(theta) d/dphi     //
00235             //------------------------------//
00236 
00237 const Scalar& Scalar::stdsdp() const {
00238     
00239     assert(etat != ETATNONDEF) ;    // Protection
00240 
00241     // If the derivative has not been previously computed, the 
00242     //  computation must be done by the appropriate routine of the mapping : 
00243 
00244     if (p_stdsdp == 0x0) {
00245     
00246         p_stdsdp = new Scalar(*mp) ;
00247 
00248         if (etat == ETATUN) {
00249             p_stdsdp->set_etat_zero() ; 
00250         }
00251         else {
00252             mp->stdsdp(*this, *p_stdsdp) ;
00253         }
00254     }
00255     p_stdsdp->set_dzpuis(dzpuis) ;
00256 
00257     return *p_stdsdp ;
00258 
00259 }
00260 
00261             //-----------------//
00262             //      d/dx       //
00263             //-----------------//
00264 
00265 const Scalar& Scalar::dsdx() const {
00266 
00267     // Protection
00268     assert(etat != ETATNONDEF) ;
00269 
00270     // If the derivative has not been previously computed, the 
00271     //  computation must be done by the appropriate routine of the mapping : 
00272 
00273     if (p_dsdx == 0x0) {
00274       p_dsdx = new Scalar(*mp) ;
00275       if (etat == ETATUN) {
00276     p_dsdx->set_etat_zero() ;
00277       }
00278       else {
00279     mp->comp_x_from_spherical(dsdr(), srdsdt(), srstdsdp(), *p_dsdx) ;
00280       }
00281     }   
00282 
00283     int dzp = (dzpuis == 0) ? 2 : dzpuis+1 ;
00284     if (mp->get_mg()->get_type_r(mp->get_mg()->get_nzone() - 1) != UNSURR)
00285     dzp = 0 ;
00286     p_dsdx->set_dzpuis(dzp) ;
00287 
00288     return *p_dsdx ;
00289 
00290 }
00291 
00292             //-----------------//
00293             //      d/dy       //
00294             //-----------------//
00295 
00296 const Scalar& Scalar::dsdy() const {
00297 
00298     // Protection
00299     assert(etat != ETATNONDEF) ;
00300 
00301     // If the derivative has not been previously computed, the 
00302     //  computation must be done by the appropriate routine of the mapping : 
00303 
00304     if (p_dsdy == 0x0) {
00305       p_dsdy = new Scalar(*mp) ;
00306       if (etat == ETATUN) {
00307     p_dsdy->set_etat_zero() ;
00308       }
00309       else {
00310     mp->comp_y_from_spherical(dsdr(), srdsdt(), srstdsdp(), *p_dsdy) ;
00311       }
00312     }
00313 
00314     int dzp = (dzpuis == 0) ? 2 : dzpuis+1 ;
00315     if (mp->get_mg()->get_type_r(mp->get_mg()->get_nzone() - 1) != UNSURR)
00316     dzp = 0 ;
00317     p_dsdy->set_dzpuis(dzp) ;
00318 
00319     return *p_dsdy ;
00320 
00321 }
00322 
00323             //-----------------//
00324             //      d/dz       //
00325             //-----------------//
00326 
00327 const Scalar& Scalar::dsdz() const {
00328 
00329     // Protection
00330     assert(etat != ETATNONDEF) ;
00331 
00332     // If the derivative has not been previously computed, the 
00333     //  computation must be done by the appropriate routine of the mapping : 
00334 
00335     if (p_dsdz == 0x0) {     
00336       p_dsdz = new Scalar(*mp) ;
00337       if (etat == ETATUN) {
00338     p_dsdz->set_etat_zero() ;
00339       }
00340       else {
00341     mp->comp_z_from_spherical(dsdr(), srdsdt(), *p_dsdz) ;
00342       }
00343     }
00344 
00345     int dzp = (dzpuis == 0) ? 2 : dzpuis+1 ;
00346     if (mp->get_mg()->get_type_r(mp->get_mg()->get_nzone() - 1) != UNSURR)
00347     dzp = 0 ;
00348     p_dsdz->set_dzpuis(dzp) ;
00349 
00350     return *p_dsdz ;
00351 
00352 }
00353 
00354             //-----------------//
00355             //      d/dx^i     //
00356             //-----------------//
00357 
00358 const Scalar& Scalar::deriv(int i) const {
00359     
00360     switch (i) {
00361     
00362     case 1 : {
00363         return dsdx() ; 
00364     }
00365     
00366     case 2 : {
00367         return dsdy() ; 
00368     }
00369     
00370     case 3 : {
00371         return dsdz() ; 
00372     }
00373     
00374     default : {
00375         cout << "Scalar::deriv : index i out of range !" << endl ; 
00376         cout << "  i = " << i << endl ; 
00377         abort() ; 
00378         return dsdx() ;  // Pour satisfaire le compilateur !
00379     }
00380     
00381     }
00382     
00383 }
00384 
00385                     //--------------------------//
00386                     //  Covariant derivatives   //
00387                     //--------------------------//
00388 
00389 const Vector& Scalar::derive_cov(const Metric& gam) const {
00390   
00391     const Vector* p_resu = 
00392         dynamic_cast<const Vector*>( &(Tensor::derive_cov(gam)) ) ;
00393 
00394     assert(p_resu != 0x0) ;
00395 
00396     return *p_resu ;
00397   
00398 }
00399 
00400 
00401 const Vector& Scalar::derive_con(const Metric& gam) const {
00402   
00403     const Vector* p_resu = 
00404         dynamic_cast<const Vector*>( &(Tensor::derive_con(gam)) ) ;
00405 
00406     assert(p_resu != 0x0) ;
00407 
00408     return *p_resu ;
00409   
00410 }
00411 
00412 
00413                     //--------------------------//
00414                     //       Lie derivative     //
00415                     //--------------------------//
00416 
00417 
00418 Scalar Scalar::derive_lie(const Vector& vv) const {
00419 
00420     Scalar resu(*mp) ; 
00421     
00422     compute_derive_lie(vv, resu) ;
00423     
00424     return resu ; 
00425     
00426 }
00427 
00428 
00429 
00430 
00431             //---------------------//
00432             //     Laplacian       //
00433             //---------------------//
00434 
00435 const Scalar& Scalar::laplacian(int zec_mult_r) const {
00436 
00437     // Protection
00438     assert(etat != ETATNONDEF) ;
00439 
00440     // If the Laplacian has not been previously computed, the 
00441     //  computation must be done by the appropriate routine of the mapping : 
00442     if ( (p_lap == 0x0) || (zec_mult_r != ind_lap) ) {
00443     if (p_lap != 0x0) {
00444         delete p_lap ;  // the Laplacian had been computed but with
00445                 //  a different value of zec_mult_r
00446     }
00447     p_lap = new Scalar(*mp) ;
00448     mp->laplacien(*this, zec_mult_r, *p_lap) ;
00449     ind_lap = zec_mult_r ;
00450     }
00451     
00452     return *p_lap ;
00453     
00454 }
00455     
00456             //-----------------------------//
00457             //     Angular Laplacian       //
00458             //-----------------------------//
00459 
00460 const Scalar& Scalar::lapang() const {
00461 
00462     // Protection
00463     assert(etat != ETATNONDEF) ;
00464 
00465     // If the Laplacian has not been previously computed, the 
00466     //  computation must be done by the appropriate routine of the mapping : 
00467     if ( p_lapang == 0x0 ) {
00468       if (etat == ETATUN) {
00469     p_lapang = new Scalar(*mp) ;
00470     p_lapang->set_etat_zero() ;
00471       }
00472       else {
00473     p_lapang = new Scalar(*mp) ;
00474     mp->lapang(*this, *p_lapang) ;
00475       }
00476     }
00477 
00478     p_lapang->set_dzpuis(dzpuis) ;
00479     
00480     return *p_lapang ;
00481     
00482 }
00483    
00484     
00485     
00486             //---------------------//
00487             //         d/dradial   //
00488             //---------------------//
00489 
00490 const Scalar& Scalar::dsdradial() const {
00491 
00492     // Protection
00493     assert(etat != ETATNONDEF) ;
00494 
00495     // If the derivative has not been previously computed, the 
00496     //  computation must be done by the appropriate routine of the mapping : 
00497 
00498     if (p_dsdradial == 0x0) {
00499       p_dsdradial = new Scalar(*mp) ;
00500       if (etat == ETATUN) {
00501     p_dsdradial->set_etat_zero() ;
00502       }
00503       else {
00504     mp->dsdradial(*this, *p_dsdradial) ;
00505       }
00506     }
00507 
00508     int dzp = (dzpuis == 0) ? 2 : dzpuis+1 ;
00509     if (mp->get_mg()->get_type_r(mp->get_mg()->get_nzone() - 1) != UNSURR)
00510     dzp = 0 ;
00511     p_dsdradial->set_dzpuis(dzp) ;
00512 
00513     return *p_dsdradial ;
00514 
00515 }
00516 
00517                          //-----------------//
00518             //      d/drho   //
00519             //-----------------//
00520 
00521 const Scalar& Scalar::dsdrho() const {
00522 
00523     // Protection
00524     assert(etat != ETATNONDEF) ;
00525 
00526     // If the derivative has not been previously computed, the 
00527     //  computation must be done by the appropriate routine of the mapping : 
00528 
00529     if (p_dsdrho == 0x0) {     
00530       p_dsdrho = new Scalar(*mp) ;
00531       if (etat == ETATUN) {
00532     p_dsdrho->set_etat_zero() ;
00533       }
00534       else {
00535     Scalar der_r (dsdr()) ;
00536     Scalar der_t (srdsdt()) ;
00537     Valeur val (der_r.get_spectral_va().mult_st() + 
00538             der_t.get_spectral_va().mult_ct()) ;
00539 
00540     Scalar res (*mp) ;
00541     res = val ;
00542  
00543     *p_dsdrho = res ;   
00544       }
00545     }
00546 
00547     int dzp = (dzpuis == 0) ? 2 : dzpuis+1 ;
00548     if (mp->get_mg()->get_type_r(mp->get_mg()->get_nzone() - 1) != UNSURR)
00549     dzp = 0 ;
00550     p_dsdrho->set_dzpuis(dzp) ;
00551 
00552     return *p_dsdrho ;
00553 
00554 }

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