scalar.C

00001 /*
00002  *  Methods of class Scalar
00003  *
00004  *   (see file scalar.h for documentation)
00005  *
00006  */
00007 
00008 /*
00009  *   Copyright (c) 2003-2004 Eric Gourgoulhon & Jerome Novak
00010  *
00011  *   Copyright (c) 1999-2001 Philippe Grandclement (for preceding class Cmp)
00012  *
00013  *   This file is part of LORENE.
00014  *
00015  *   LORENE is free software; you can redistribute it and/or modify
00016  *   it under the terms of the GNU General Public License as published by
00017  *   the Free Software Foundation; either version 2 of the License, or
00018  *   (at your option) any later version.
00019  *
00020  *   LORENE is distributed in the hope that it will be useful,
00021  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00022  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023  *   GNU General Public License for more details.
00024  *
00025  *   You should have received a copy of the GNU General Public License
00026  *   along with LORENE; if not, write to the Free Software
00027  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00028  *
00029  */
00030 
00031 
00032 char scalar_C[] = "$Header: /cvsroot/Lorene/C++/Source/Tensor/Scalar/scalar.C,v 1.34 2012/01/17 15:10:12 j_penner Exp $" ;
00033 
00034 
00035 /*
00036  * Revision 1.32  2011/04/08 12:55:50  e_gourgoulhon
00037  * Scalar::val_point : division by r^dzpuis to return the actual
00038  * (i.e. physical) value of the field in the external compactified
00039  * domain.
00040  *
00041  * Revision 1.31  2005/10/25 08:56:39  p_grandclement
00042  * addition of std_spectral_base in the case of odd functions near the origin
00043  *
00044  * Revision 1.30  2005/03/11 13:16:37  j_novak
00045  * Corrected an error in multipole_spectrum().
00046  *
00047  * Revision 1.29  2004/10/11 15:09:04  j_novak
00048  * The radial manipulation functions take Scalar as arguments, instead of Cmp.
00049  * Added a conversion operator from Scalar to Cmp.
00050  * The Cmp radial manipulation function make conversion to Scalar, call to the
00051  * Map_radial version with a Scalar argument and back.
00052  *
00053  * Revision 1.28  2004/08/24 09:14:51  p_grandclement
00054  * Addition of some new operators, like Poisson in 2d... It now requieres the
00055  * GSL library to work.
00056  *
00057  * Also, the way a variable change is stored by a Param_elliptic is changed and
00058  * no longer uses Change_var but rather 2 Scalars. The codes using that feature
00059  * will requiere some modification. (It should concern only the ones about monopoles)
00060  *
00061  * Revision 1.27  2004/06/22 08:50:00  p_grandclement
00062  * Addition of everything needed for using the logarithmic mapping
00063  *
00064  * Revision 1.26  2004/06/11 14:29:58  j_novak
00065  * Scalar::multipole_spectrum() is now a const method.
00066  *
00067  * Revision 1.25  2004/03/04 09:51:36  e_gourgoulhon
00068  * Method dz_nonzero() : treated the case ETATUN.
00069  *
00070  * Revision 1.24  2004/02/19 22:11:50  e_gourgoulhon
00071  * Added argument "comment" in method spectral_display.
00072  *
00073  * Revision 1.23  2004/01/12 15:32:25  j_novak
00074  * Yet another problem with ETATUN
00075  *
00076  * Revision 1.22  2003/11/05 15:31:13  e_gourgoulhon
00077  * Method set_etat_qcq(): del_t() is not invoqued for etat == ETATUN.
00078  *
00079  * Revision 1.21  2003/11/03 10:25:27  j_novak
00080  * Suppressed the call to del_deriv() in set_etat_qcq() method.
00081  *
00082  * Revision 1.20  2003/10/28 21:33:13  e_gourgoulhon
00083  * In operator=(const Scalar& ci) changed the place of va.del_t()
00084  * in order to correct an error in the case where both this and ci
00085  * are in the state ETATUN.
00086  *
00087  * Revision 1.19  2003/10/28 12:36:10  e_gourgoulhon
00088  * Corrected operator=(const Scalar& ci) for the case ETATUN: the
00089  * spectral bases are now copied.
00090  *
00091  * Revision 1.18  2003/10/27 14:51:25  e_gourgoulhon
00092  * Correction of errors in constructor from a Tensor.
00093  *
00094  * Revision 1.17  2003/10/22 08:35:30  j_novak
00095  * Error corrected
00096  *
00097  * Revision 1.16  2003/10/19 19:54:37  e_gourgoulhon
00098  * -- Modified method spectral_display: now calling Valeur::display_coef.
00099  *
00100  * Revision 1.15  2003/10/15 16:03:38  j_novak
00101  * Added the angular Laplace operator for Scalar.
00102  *
00103  * Revision 1.14  2003/10/15 10:43:06  e_gourgoulhon
00104  * Added new members p_dsdt and p_stdsdp.
00105  *
00106  * Revision 1.13  2003/10/13 13:52:40  j_novak
00107  * Better managment of derived quantities.
00108  *
00109  * Revision 1.12  2003/10/11 14:42:16  e_gourgoulhon
00110  * Suppressed unusued argument new_triad in method change_triad.
00111  *
00112  * Revision 1.11  2003/10/10 15:57:29  j_novak
00113  * Added the state one (ETATUN) to the class Scalar
00114  *
00115  * Revision 1.10  2003/10/07 08:05:03  j_novak
00116  * Added an assert for the constructor from a Tensor.
00117  *
00118  * Revision 1.9  2003/10/06 16:16:03  j_novak
00119  * New constructor from a Tensor.
00120  *
00121  * Revision 1.8  2003/10/06 13:58:48  j_novak
00122  * The memory management has been improved.
00123  * Implementation of the covariant derivative with respect to the exact Tensor
00124  * type.
00125  *
00126  * Revision 1.7  2003/10/05 21:15:42  e_gourgoulhon
00127  * - Suppressed method std_spectral_base_scal().
00128  * - Added method std_spectral_base().
00129  *
00130  * Revision 1.6  2003/10/01 13:04:44  e_gourgoulhon
00131  * The method Tensor::get_mp() returns now a reference (and not
00132  * a pointer) onto a mapping.
00133  *
00134  * Revision 1.5  2003/09/29 12:52:58  j_novak
00135  * Methods for changing the triad are implemented.
00136  *
00137  * Revision 1.4  2003/09/24 20:55:27  e_gourgoulhon
00138  * Added -- constructor by conversion of a Cmp
00139  *       -- operator=(const Cmp&)
00140  *
00141  * Revision 1.3  2003/09/24 15:10:54  j_novak
00142  * Suppression of the etat flag in class Tensor (still present in Scalar)
00143  *
00144  * Revision 1.2  2003/09/24 10:21:07  e_gourgoulhon
00145  * added more methods
00146  *
00147  * Revision 1.1  2003/09/23 08:52:17  e_gourgoulhon
00148  * new version
00149  *
00150  *
00151  * $Header: /cvsroot/Lorene/C++/Source/Tensor/Scalar/scalar.C,v 1.34 2012/01/17 15:10:12 j_penner Exp $
00152  *
00153  */
00154 
00155 // headers C
00156 #include <assert.h>
00157 #include <stdlib.h>
00158 #include <math.h>
00159 
00160 // headers Lorene
00161 #include "map.h"
00162 #include "scalar.h"
00163 #include "tensor.h"
00164 #include "type_parite.h"
00165 #include "utilitaires.h"
00166 #include "proto.h"
00167 #include "cmp.h"
00168 
00169 
00170             //---------------//
00171             // Constructors  //
00172             //---------------//
00173 
00174 
00175 Scalar::Scalar(const Map& mpi) : Tensor(mpi), etat(ETATNONDEF), dzpuis(0), 
00176                  va(mpi.get_mg()) {
00177 
00178     cmp[0] = this ; 
00179     set_der_0x0() ;
00180 
00181 }
00182 
00183 
00184 // Constructor from a Tensor
00185 // -------------------------
00186 Scalar::Scalar(const Tensor& ti) : Tensor(*(ti.mp)), etat(ti.cmp[0]->etat), 
00187                    dzpuis(ti.cmp[0]->dzpuis), va(ti.cmp[0]->va) {
00188 
00189   assert(ti.valence == 0) ;
00190 
00191   cmp[0] = this ; 
00192   set_der_0x0() ;
00193 
00194 }
00195 
00196 
00197 // Copy constructor
00198 // ----------------
00199 Scalar::Scalar(const Scalar& sci)  : Tensor(*(sci.mp)), etat(sci.etat), 
00200                      dzpuis(sci.dzpuis), va(sci.va) {
00201     
00202   cmp[0] = this ; 
00203   set_der_0x0() ;   // On ne recopie pas les derivees
00204 
00205 }
00206 
00207 // Conversion from a Cmp
00208 //----------------------
00209 Scalar::Scalar(const Cmp& ci) : Tensor(*(ci.get_mp())),
00210                                 etat(ci.get_etat()),
00211                                 dzpuis(ci.get_dzpuis()),
00212                                 va(ci.va) {
00213     cmp[0] = this ;
00214     set_der_0x0() ; 
00215 }
00216     
00217 // From file
00218 // ---------
00219 Scalar::Scalar(const Map& mpi, const Mg3d& mgi, FILE* fd) : Tensor(mpi), 
00220         va(mgi, fd) {
00221 
00222     assert( mpi.get_mg() == &mgi ) ; 
00223 
00224     fread_be(&etat, sizeof(int), 1, fd) ;           // L'etat
00225     fread_be(&dzpuis, sizeof(int), 1, fd) ;     // dzpuis
00226 
00227     cmp[0] = this ; 
00228 
00229     set_der_0x0() ; // Les derivees sont initialisees a zero
00230 
00231 }
00232 
00233             //--------------//
00234             // Destructor  //
00235             //--------------//
00236 
00237 // Destructeur
00238 Scalar::~Scalar() {
00239     del_t() ;
00240     cmp[0] = 0x0 ; //cmp[0] was set to 'this' before (now 0x0 to break a 
00241                    // in loop in ~Tensor!)
00242            
00243 }
00244 
00245             //-----------------------//
00246             // Memory management     //
00247             //-----------------------//
00248 
00249 // Destructeur logique
00250 void Scalar::del_t() {
00251 
00252     va.del_t() ;
00253     va.set_etat_nondef() ;
00254     Scalar::del_deriv() ;
00255 
00256 }
00257 
00258 void Scalar::del_deriv() const{
00259     if (p_dsdr != 0x0) delete p_dsdr ;
00260     if (p_srdsdt != 0x0) delete p_srdsdt ;
00261     if (p_srstdsdp != 0x0) delete p_srstdsdp ; 
00262     if (p_dsdt != 0x0) delete p_dsdt ;
00263     if (p_stdsdp != 0x0) delete p_stdsdp ;
00264     if (p_dsdx != 0x0) delete p_dsdx ; 
00265     if (p_dsdy != 0x0) delete p_dsdy ;
00266     if (p_dsdz != 0x0) delete p_dsdz ;
00267     if (p_lap != 0x0) delete p_lap ; 
00268     if (p_lapang != 0x0) delete p_lapang ; 
00269     if (p_integ != 0x0) delete p_integ ;
00270     if (p_dsdradial != 0x0) delete p_dsdradial ;
00271     if (p_dsdrho != 0x0) delete p_dsdrho ;
00272     set_der_0x0() ;
00273 
00274     Tensor::del_deriv() ;
00275 }
00276 
00277 void Scalar::set_der_0x0() const {
00278     p_dsdr = 0x0 ;
00279     p_srdsdt = 0x0 ;
00280     p_srstdsdp = 0x0 ;
00281     p_dsdt = 0x0 ;
00282     p_stdsdp = 0x0 ;
00283     p_dsdx = 0x0 ;
00284     p_dsdy = 0x0 ;
00285     p_dsdz = 0x0 ;
00286     p_lap = 0x0 ; 
00287     p_lapang = 0x0 ; 
00288     ind_lap = - 1 ; 
00289     p_integ = 0x0 ; 
00290     p_dsdradial = 0x0 ;
00291     p_dsdrho = 0x0 ;
00292 }
00293 
00294 // ETATZERO
00295 void Scalar::set_etat_zero() {
00296     if (etat == ETATZERO) return ;
00297     else {
00298         del_deriv() ;
00299         va.set_etat_zero() ;
00300         etat = ETATZERO ;
00301     }
00302 }
00303 
00304 // ETATUN
00305 void Scalar::set_etat_one() {
00306     if (etat == ETATUN) return ;
00307     else {
00308       del_deriv() ;
00309       va = 1 ;
00310       etat = ETATUN ;
00311     }
00312 }
00313 
00314 // ETATNONDEF
00315 void Scalar::set_etat_nondef() {
00316     if (etat == ETATNONDEF) return ;
00317     else {
00318         del_t() ;
00319         etat = ETATNONDEF ;
00320     }
00321 }
00322 
00323 // ETATQCQ
00324 void Scalar::set_etat_qcq() {
00325 
00326     if (etat == ETATQCQ) return ;
00327     else {
00328         if (etat != ETATUN) del_t() ;
00329         etat = ETATQCQ ;
00330     }
00331 }
00332 
00333 
00334 // Allocates everything
00335 // --------------------
00336 void Scalar::allocate_all() {
00337     
00338     set_etat_qcq() ; 
00339     va.set_etat_c_qcq() ;       // allocation in configuration space
00340     Mtbl* mt = va.c ; 
00341     mt->set_etat_qcq() ;
00342     for (int l=0; l<mt->get_nzone(); l++) {
00343         mt->t[l]->set_etat_qcq() ; 
00344     }
00345     
00346 } 
00347 
00348 
00349 
00350 // ZERO hard
00351 void Scalar::annule_hard() {
00352 
00353     va.annule_hard() ;
00354     del_deriv() ; 
00355     etat = ETATQCQ ;
00356 }
00357 
00358 
00359 // Sets the Scalar to zero in several domains
00360 // ---------------------------------------
00361 
00362 void Scalar::annule(int l_min, int l_max) {
00363     
00364     // Cas particulier: annulation globale : 
00365     if ( (l_min == 0) && (l_max == va.mg->get_nzone()-1) ) {
00366       set_etat_zero() ;
00367       return ; 
00368     }
00369     
00370     assert( etat != ETATNONDEF ) ; 
00371     
00372     if ( etat == ETATZERO ) {
00373         return ;        // rien n'a faire si c'est deja zero
00374     }
00375     else {
00376         assert( (etat == ETATQCQ) || (etat == ETATUN) ) ;   // sinon...
00377 
00378         etat = ETATQCQ ;
00379         va.annule(l_min, l_max) ;   // Annule la Valeur
00380     
00381         // Annulation des membres derives
00382         if (p_dsdr != 0x0) p_dsdr->annule(l_min, l_max) ;
00383         if (p_srdsdt != 0x0) p_srdsdt->annule(l_min, l_max) ;
00384         if (p_srstdsdp != 0x0) p_srstdsdp->annule(l_min, l_max) ;
00385         if (p_dsdt != 0x0) p_dsdt->annule(l_min, l_max) ;
00386         if (p_stdsdp != 0x0) p_stdsdp->annule(l_min, l_max) ;
00387         if (p_dsdx != 0x0) p_dsdx->annule(l_min, l_max) ;
00388         if (p_dsdy != 0x0) p_dsdy->annule(l_min, l_max) ;
00389         if (p_dsdz != 0x0) p_dsdz->annule(l_min, l_max) ;
00390         if (p_lap != 0x0) p_lap->annule(l_min, l_max) ;
00391         if (p_lapang != 0x0) p_lapang->annule(l_min, l_max) ;
00392         if (p_integ != 0x0) delete p_integ ;
00393         if (p_dsdradial != 0x0) p_dsdradial->annule(l_min, l_max) ;
00394     }
00395     
00396 }
00397 
00398 
00399             //------------//
00400             // Assignment //
00401             //------------//
00402 
00403 
00404 // From tensor
00405 // -----------
00406 
00407 void Scalar::operator=(const Tensor& uu) {
00408 
00409     assert(uu.valence == 0) ; 
00410     
00411     operator=(*(uu.cmp[0])) ; 
00412 
00413 }
00414 
00415 // From Scalar
00416 // ----------
00417 void Scalar::operator=(const Scalar& ci) {
00418     
00419 
00420     assert(&ci != this) ;    // pour eviter l'auto-affectation
00421     
00422     // Les elements fixes
00423     assert( mp == ci.mp ) ;
00424     
00425     dzpuis = ci.dzpuis ; 
00426     
00427     // La valeur eventuelle
00428     switch(ci.etat) {
00429     case ETATNONDEF: {
00430         set_etat_nondef() ; 
00431         break ;         // valeur par defaut
00432     }
00433     
00434     case ETATZERO: {
00435         set_etat_zero() ;
00436         break ;
00437     }
00438     
00439     case ETATUN: {
00440         set_etat_one() ;
00441         va.set_base( ci.va.get_base() )  ;   
00442         break ;
00443     }
00444     
00445     case ETATQCQ: {
00446         // Menage general de la Valeur, mais pas des quantites derivees !
00447         va.del_t() ;
00448         
00449         set_etat_qcq() ; // set_etat_qcq n'appelle pas del_deriv()
00450         va = ci.va ;
00451 
00452         // On detruit les quantites derivees (seulement lorsque tout est fini !)
00453         del_deriv() ; 
00454 
00455         break ;
00456     }
00457     
00458     default: {
00459         cout << "Unkwown state in Scalar::operator=(const Scalar&) !" 
00460          << endl ;
00461         abort() ;
00462         break ;
00463     }
00464     }
00465 
00466 }
00467     
00468 // From Cmp
00469 // --------
00470 void Scalar::operator=(const Cmp& ci) {
00471     
00472 
00473     // Menage general de la Valeur, mais pas des quantites derivees !
00474     va.del_t() ;
00475     
00476     // Les elements fixes
00477     assert( mp == ci.get_mp() ) ;
00478     
00479     dzpuis = ci.get_dzpuis() ; 
00480     
00481     // La valeur eventuelle
00482     switch(ci.get_etat()) {
00483     
00484     case ETATNONDEF: {
00485         set_etat_nondef() ; 
00486         break ;         // valeur par defaut
00487     }
00488     
00489     case ETATZERO: {
00490         set_etat_zero() ;
00491         break ;
00492     }
00493     
00494     case ETATQCQ: {
00495         set_etat_qcq() ;
00496         va = ci.va ;
00497 
00498         // On detruit les quantites derivees (seulement lorsque tout est fini !)
00499         del_deriv() ; 
00500 
00501         break ;
00502     }
00503     
00504     default: {
00505         cout << "Unkwown state in Scalar::operator=(const Cmp&) !" 
00506          << endl ;
00507         abort() ;
00508         break ;
00509     }
00510     }
00511 
00512 }
00513     
00514 
00515 
00516 
00517 
00518 // From Valeur
00519 // -----------
00520 void Scalar::operator=(const Valeur& vi) {
00521 
00522     // Traitement de l'auto-affectation :
00523     if (&vi == &va) {
00524         return ; 
00525     }
00526 
00527     // Protection
00528     assert(vi.get_etat() != ETATNONDEF) ;
00529     
00530     // Menage general de la Valeur, mais pas des quantites derivees !
00531     va.del_t() ;
00532 
00533     
00534     // La valeure eventuelle
00535     switch(vi.get_etat()) {
00536 
00537     case ETATZERO: {
00538         set_etat_zero() ;
00539         break ;
00540     }
00541 
00542     case ETATQCQ: {
00543         set_etat_qcq() ;
00544         va = vi ;
00545         
00546         // On detruit les quantites derivees (seulement lorsque tout est fini !)
00547         del_deriv() ; 
00548 
00549         break ;
00550     }
00551     
00552     default: {
00553         cout << "Unkwown state in Scalar::operator=(const Valeur&) !" << endl ;
00554         abort() ;
00555         break ;
00556     }
00557     }
00558 
00559 }
00560 
00561 // From Mtbl
00562 // ---------
00563 void Scalar::operator=(const Mtbl& mi) {
00564     
00565     // Protection
00566     assert(mi.get_etat() != ETATNONDEF) ;
00567 
00568     assert(&mi != va.c) ;  // pour eviter l'auto-affectation
00569 
00570    
00571     // Menage general de la Valeur, mais pas des quantites derivees !
00572     va.del_t() ;
00573 
00574     // La valeure eventuelle
00575     switch(mi.get_etat()) {
00576     case ETATZERO: {
00577         set_etat_zero() ;
00578         break ;
00579     }
00580     
00581     case ETATQCQ: {
00582         set_etat_qcq() ;
00583         va = mi ;
00584 
00585         // On detruit les quantites derivees (seulement lorsque tout est fini !)
00586         del_deriv() ; 
00587 
00588         break ;
00589      }
00590     
00591     default: {
00592         cout << "Unkwown state in Scalar::operator=(const Mtbl&) !" << endl ;
00593         abort() ;
00594         break ;
00595     }
00596     }
00597 
00598 
00599 }
00600 
00601 // From double
00602 // -----------
00603 void Scalar::operator=(double x) {
00604     
00605   if (x == double(0)) {
00606     set_etat_zero() ;
00607   }
00608   else {
00609     if (x == double(1)) {
00610       set_etat_one() ;
00611     }
00612     else {
00613       set_etat_qcq() ;
00614       del_deriv() ;
00615     va = x ;
00616     }
00617   }
00618   
00619   dzpuis = 0 ; 
00620 }
00621 
00622 // From int
00623 // --------
00624 void Scalar::operator=(int n) {
00625     
00626   if (n == 0) {
00627     set_etat_zero() ;
00628   }
00629   else {
00630     if (n == 1) {
00631       set_etat_one() ;
00632     }
00633     else {
00634       set_etat_qcq() ;
00635       del_deriv() ;
00636       va = n ;
00637     }
00638   } 
00639   dzpuis = 0 ; 
00640   
00641 }
00642 
00643 // Conversion to a Cmp
00644 //----------------------
00645 Scalar::operator Cmp() const {
00646 
00647   Cmp resu(mp) ;
00648   resu = va ;
00649   resu.set_dzpuis(dzpuis) ;
00650   return resu ;
00651 
00652 }
00653             //------------//
00654             // Sauvegarde //
00655             //------------//
00656 
00657 void Scalar::sauve(FILE* fd) const {
00658 
00659     va.sauve(fd) ;      // la valeur (en premier pour la construction
00660                 //   lors de la lecture du fichier)
00661 
00662     fwrite_be(&etat, sizeof(int), 1, fd) ;          // l'etat
00663     fwrite_be(&dzpuis, sizeof(int), 1, fd) ;        // dzpuis
00664 
00665 }
00666     
00667             //------------//
00668             // Impression //
00669             //------------//
00670 
00671 // Operator <<
00672 // -----------
00673 ostream& operator<<(ostream& ost, const Scalar& ci) {
00674 
00675     switch(ci.etat) {
00676     case ETATNONDEF: {
00677         ost << "*** UNDEFINED STATE *** " << endl ;
00678         break ;
00679     }
00680     
00681     case ETATZERO: {
00682         ost << "*** identically ZERO ***" << endl ; 
00683         break ; 
00684     }
00685     
00686     case ETATUN: {
00687         ost << "*** identically ONE ***" << endl ; 
00688         break ; 
00689     }
00690     
00691     case ETATQCQ: {
00692         ost << "*** dzpuis = " << ci.get_dzpuis() << endl ; 
00693         ost << ci.va << endl ; 
00694         break ;
00695     }
00696     
00697     default: {
00698         cout << "operator<<(ostream&, const Scalar&) : unknown state !" 
00699          << endl ;
00700         abort() ;
00701         break ; 
00702     }
00703     }
00704     
00705     // Termine
00706     return ost ;
00707 }
00708 
00709 // spectral_display
00710 //-----------------
00711 
00712 void Scalar::spectral_display(const char* comment, 
00713             double thres, int precis, ostream& ost) const {
00714 
00715 
00716     if (comment != 0x0) {
00717         ost << comment << " : " << endl ; 
00718     }
00719     
00720     // Cas particuliers
00721     //-----------------
00722 
00723     if (etat == ETATNONDEF) {
00724         ost << "*** UNDEFINED ***" << endl << endl ; 
00725         return ;
00726     }
00727 
00728     if (etat == ETATZERO) {
00729         ost << "*** identically ZERO ***" << endl ; 
00730         return ;
00731     }
00732 
00733     if (etat == ETATUN) {
00734         ost << "*** identically ONE ***" << endl ; 
00735         return ;
00736     }
00737 
00738     // Cas general : on affiche la Valeur
00739     //------------
00740        
00741     if (dzpuis != 0) {
00742         ost << "*** dzpuis = " << dzpuis << endl ; 
00743     }
00744     va.display_coef(thres, precis, ost) ;
00745 
00746 }
00747 
00748 
00749 
00750     
00751             //------------------------------------//
00752             //  Spectral bases of the Valeur va   //
00753             //------------------------------------//
00754             
00755 void Scalar::std_spectral_base() {
00756       
00757     va.std_base_scal() ;  
00758                    
00759 }    
00760 
00761             
00762 void Scalar::std_spectral_base_odd() {
00763       
00764     va.std_base_scal_odd() ;  
00765                    
00766 }    
00767 
00768 
00769 void Scalar::set_spectral_base(const Base_val& bi) {
00770 
00771     va.set_base(bi) ; 
00772 
00773 }    
00774 
00775 
00776             //--------------------------//
00777             //  dzpuis manipulations    //
00778             //--------------------------//
00779             
00780 void Scalar::set_dzpuis(int dzi) {
00781     
00782     dzpuis = dzi ;
00783     
00784 }
00785 
00786 bool Scalar::dz_nonzero() const {
00787     
00788     assert(etat != ETATNONDEF) ; 
00789     
00790     const Mg3d* mg = mp->get_mg() ;
00791     
00792     int nzm1 = mg->get_nzone() - 1; 
00793     if (mg->get_type_r(nzm1) != UNSURR) {
00794         return false ; 
00795     } 
00796     
00797     if (etat == ETATZERO) {
00798         return false ; 
00799     }
00800     
00801     if (etat == ETATUN) {
00802         return true ; 
00803     }
00804     
00805     assert( etat == ETATQCQ ) ;
00806     
00807     if (va.etat == ETATZERO) {
00808         return false ; 
00809     }
00810 
00811     assert(va.etat == ETATQCQ) ; 
00812     
00813     if (va.c != 0x0) {
00814     if ( (va.c)->get_etat() == ETATZERO ) {
00815         return false ; 
00816     }
00817     
00818     assert( (va.c)->get_etat() == ETATQCQ ) ; 
00819     if ( (va.c)->t[nzm1]->get_etat() == ETATZERO ) {
00820         return false ; 
00821     }
00822     else {
00823         assert( (va.c)->t[nzm1]->get_etat() == ETATQCQ ) ; 
00824         return true ; 
00825     }
00826     }
00827     else{
00828     assert(va.c_cf != 0x0) ; 
00829     if ( (va.c_cf)->get_etat() == ETATZERO ) {
00830         return false ; 
00831     }
00832     assert( (va.c_cf)->get_etat() == ETATQCQ ) ; 
00833     if ( (va.c_cf)->t[nzm1]->get_etat() == ETATZERO ) {
00834         return false ; 
00835     }
00836     else {
00837         assert( (va.c_cf)->t[nzm1]->get_etat() == ETATQCQ ) ; 
00838         return true ; 
00839     }
00840     
00841     } 
00842     
00843 }
00844 
00845 bool Scalar::check_dzpuis(int dzi) const {
00846     
00847     if (dz_nonzero()) {     // the check must be done
00848         return (dzpuis == dzi) ; 
00849     }
00850     else{
00851         return true ; 
00852     }
00853     
00854 }
00855 
00856 
00857 
00858         //---------------------------------------//
00859         //      Value at an arbitrary point      //
00860         //---------------------------------------//
00861 
00862 double Scalar::val_point(double r, double theta, double phi) const {
00863 
00864 
00865     assert(etat != ETATNONDEF) ; 
00866     
00867     if (etat == ETATZERO) {
00868         return double(0) ; 
00869     }
00870     
00871     if (etat == ETATUN) {
00872         return double(1) ; 
00873     }
00874     
00875     assert(etat == ETATQCQ) ; 
00876     
00877     // 1/ Search for the domain and the grid coordinates (xi,theta',phi')
00878     //    which corresponds to the point (r,theta,phi)
00879     
00880     int l ; 
00881     double xi ; 
00882     mp->val_lx(r, theta, phi, l,  xi) ;     // call of val_lx with default 
00883                         // accuracy parameters
00884     // 2/ Call to the Valeur version
00885     if (l == mp->get_mg()->get_nzone() - 1){  // in the last domain, one must take into account dzpuis
00886       switch (dzpuis) {
00887       case 0:
00888     {
00889       return va.val_point(l, xi, theta, phi);
00890       break;
00891     }
00892       case 1:
00893     {
00894       return va.val_point(l, xi, theta, phi)/r ; 
00895       break;
00896     }
00897       case 2:
00898     {
00899       return va.val_point(l, xi, theta, phi)/(r*r) ; 
00900       break;
00901     }
00902       case 3:
00903     {
00904       return va.val_point(l, xi, theta, phi)/(r*r*r) ; 
00905       break;
00906     }
00907       case 4:
00908     {
00909       return va.val_point(l, xi, theta, phi)/(r*r*r*r) ; 
00910       break;
00911     }
00912       default:
00913     {
00914       cout << "scalar::val_point unexpected value of dzpuis !" << endl;
00915       abort();
00916     }
00917       }
00918     }
00919     else{
00920       return va.val_point(l, xi, theta, phi);
00921     }
00922 }
00923  
00924         //---------------------------------//
00925         //      Multipolar spectrum        //
00926         //---------------------------------//
00927 
00928 Tbl Scalar::multipole_spectrum() const {
00929 
00930   assert (etat != ETATNONDEF) ;
00931 
00932   const Mg3d* mg = mp->get_mg() ;
00933   int nzone = mg->get_nzone() ;
00934   int lmax = 0 ;
00935   
00936   for (int lz=0; lz<nzone; lz++) 
00937     lmax = (lmax < 2*mg->get_nt(lz) - 1 ? 2*mg->get_nt(lz) - 1 : lmax) ;
00938 
00939   Tbl resu(nzone, lmax) ;
00940   if (etat == ETATZERO) {
00941     resu.set_etat_zero() ;
00942     return resu ;
00943   }
00944 
00945   assert((etat == ETATQCQ) || (etat == ETATUN));
00946 
00947   Valeur va_copy = va ;
00948 
00949   va_copy.coef() ;
00950   va_copy.ylm() ;
00951   resu.annule_hard() ;
00952   const Base_val& base = va_copy.c_cf->base ;
00953   int m_quant, l_quant, base_r ;
00954   for (int lz=0; lz<nzone; lz++) 
00955     for (int k=0 ; k<mg->get_np(lz) ; k++) 
00956       for (int j=0 ; j<mg->get_nt(lz) ; j++) {
00957     if (nullite_plm(j, mg->get_nt(lz), k, mg->get_np(lz), base) == 1) 
00958       {
00959         // quantic numbers and spectral bases
00960         donne_lm(nzone, lz, j, k, base, m_quant, l_quant, base_r) ;
00961         for (int i=0; i<mg->get_nr(lz); i++) resu.set(lz, l_quant) 
00962                      += fabs((*va_copy.c_cf)(lz, k, j, i)) ; 
00963       }
00964       }
00965 
00966   return resu ;
00967 }
00968 
00969 void Scalar::change_triad(const Base_vect& ) {
00970 
00971   cout << "WARNING: Scalar::change_triad : "<< endl ;
00972   cout << "This method does nothing ... " << endl ;
00973 
00974 }

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