valeur_ylm.C

00001 /*
00002  *   Copyright (c) 1999-2003 Eric Gourgoulhon
00003  *   Copyright (c) 1999-2001 Philippe Grandclement
00004  *
00005  *   This file is part of LORENE.
00006  *
00007  *   LORENE is free software; you can redistribute it and/or modify
00008  *   it under the terms of the GNU General Public License as published by
00009  *   the Free Software Foundation; either version 2 of the License, or
00010  *   (at your option) any later version.
00011  *
00012  *   LORENE is distributed in the hope that it will be useful,
00013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *   GNU General Public License for more details.
00016  *
00017  *   You should have received a copy of the GNU General Public License
00018  *   along with LORENE; if not, write to the Free Software
00019  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  *
00021  */
00022 
00023 
00024 char valeur_ylm_C[] = "$Header: /cvsroot/Lorene/C++/Source/Valeur/valeur_ylm.C,v 1.10 2009/10/23 12:56:29 j_novak Exp $" ;
00025 
00026 
00027 /*
00028  * Fonction membre de la classe Valeur qui calcule les coefficients
00029  * de la decomposition spectrale en harmoniques spheriques  
00030  * a partir des coefficients en cos(l*theta) / sin(l*theta) 
00031  * 
00032  */
00033 
00034 /*
00035  * $Id: valeur_ylm.C,v 1.10 2009/10/23 12:56:29 j_novak Exp $
00036  * $Log: valeur_ylm.C,v $
00037  * Revision 1.10  2009/10/23 12:56:29  j_novak
00038  * New base T_LEG_MI
00039  *
00040  * Revision 1.9  2009/10/13 13:49:58  j_novak
00041  * New base T_LEG_MP.
00042  *
00043  * Revision 1.8  2005/11/22 10:13:44  p_grandclement
00044  * Correction of the normalization in the case nt=1
00045  *
00046  * Revision 1.7  2005/02/16 15:33:38  m_forot
00047  * Correct the case T_LEG
00048  *
00049  * Revision 1.6  2004/11/23 15:17:20  m_forot
00050  * Added the bases for the cases without any equatorial symmetry
00051  *  (T_COSSIN_C, T_COSSIN_S, T_LEG, R_CHEBPI_P, R_CHEBPI_I).
00052  *
00053  * Revision 1.5  2003/10/13 20:52:58  e_gourgoulhon
00054  * Loop variables i and l have now local scope.
00055  *
00056  * Revision 1.4  2003/09/17 12:30:22  j_novak
00057  * New checks for changing to T_LEG* bases.
00058  *
00059  * Revision 1.3  2003/09/16 08:54:09  j_novak
00060  * Addition of the T_LEG_II base (odd in theta, only for odd m) and the
00061  * transformation functions to and from the T_SIN_P base.
00062  *
00063  * Revision 1.2  2002/10/16 14:37:16  j_novak
00064  * Reorganization of #include instructions of standard C++, in order to
00065  * use experimental version 3 of gcc.
00066  *
00067  * Revision 1.1.1.1  2001/11/20 15:19:27  e_gourgoulhon
00068  * LORENE
00069  *
00070  * Revision 2.12  2000/09/29  16:10:21  eric
00071  * Ajout des bases T_LEG_IP et T_LEG_PI.
00072  *
00073  * Revision 2.11  2000/03/31  15:58:40  phil
00074  * changement des bases meme si etat est zero
00075  *
00076  * Revision 2.10  1999/12/22  16:25:26  eric
00077  * Traitement du cas ETATZERO
00078  * Test sur c_cf avant d'appeler coef().
00079  *
00080  * Revision 2.9  1999/12/16  16:41:38  phil
00081  * *** empty log message ***
00082  *
00083  * Revision 2.8  1999/12/16  16:09:56  phil
00084  * correction cas nt=1
00085  *
00086  * Revision 2.7  1999/11/30  12:46:33  eric
00087  * Valeur::base est desormais du type Base_val et non plus Base_val*.
00088  *
00089  * Revision 2.6  1999/11/19  09:25:57  eric
00090  * *** empty log message ***
00091  *
00092  * Revision 2.5  1999/10/18  14:12:09  eric
00093  * Les bases sont desormais membres des Mtbl_cf.
00094  *
00095  * Revision 2.4  1999/04/14  10:19:46  phil
00096  * *** empty log message ***
00097  *
00098  * Revision 2.3  1999/04/14  09:52:28  phil
00099  * remplacement de malloc en new
00100  *
00101  * Revision 2.2  1999/04/14  09:36:03  phil
00102  * Changement liberation memoire : free -> delete
00103  *
00104  * Revision 2.1  1999/04/13  16:44:07  phil
00105  * *** empty log message ***
00106  *
00107  * Revision 2.0  1999/04/13  16:36:57  phil
00108  * *** empty log message ***
00109  *
00110  * Revision 1.1  1999/04/13  16:36:14  phil
00111  * Initial revision
00112  *
00113  *
00114  * $Header: /cvsroot/Lorene/C++/Source/Valeur/valeur_ylm.C,v 1.10 2009/10/23 12:56:29 j_novak Exp $
00115  *
00116  */
00117 
00118 // headers du C
00119 #include <assert.h>
00120 #include <stdlib.h>
00121 #include <math.h>
00122 
00123 // headers Lorene
00124 #include "type_parite.h"
00125 #include "valeur.h"
00126 #include "proto.h"
00127 
00128 void ylm_pasprevu(const int*, const double*, double*) ;
00129 
00130 //******************************************************************************
00131 void Valeur::ylm() {
00132 
00133     static void (*chbase_t[MAX_BASE])(const int*, const double*,
00134                             double*) ;
00135     static int nouv_base_t[MAX_BASE] ;   
00136     static int premier_appel = 1 ;
00137     
00138     int deg[3] ;
00139 
00140     if (premier_appel==1) {
00141     premier_appel = 0 ;
00142 
00143     for (int i=0; i<MAX_BASE; i++) {
00144         chbase_t[i] = ylm_pasprevu ;
00145         nouv_base_t[i] = NONDEF ; 
00146     }
00147         
00148     chbase_t[T_COSSIN_CP >> TRA_T] = chb_cossincp_legp ;
00149     nouv_base_t[T_COSSIN_CP >> TRA_T] = T_LEG_P ;
00150 
00151     chbase_t[T_COSSIN_CI >> TRA_T] = chb_cossinci_legi ;
00152     nouv_base_t[T_COSSIN_CI >> TRA_T] = T_LEG_I ;
00153     
00154     chbase_t[T_COSSIN_C >> TRA_T] = chb_cossinc_leg ;
00155     nouv_base_t[T_COSSIN_C >> TRA_T] = T_LEG ;
00156 
00157     chbase_t[T_COS_P >> TRA_T] = chb_cosp_legpp ;
00158     nouv_base_t[T_COS_P >> TRA_T] = T_LEG_PP ;
00159 
00160     chbase_t[T_COS_I >> TRA_T] = chb_cosi_legip ;
00161     nouv_base_t[T_COS_I >> TRA_T] = T_LEG_IP ;
00162 
00163     chbase_t[T_SIN_I >> TRA_T] = chb_sini_legpi ;
00164     nouv_base_t[T_SIN_I >> TRA_T] = T_LEG_PI ;
00165 
00166     chbase_t[T_SIN_P >> TRA_T] = chb_sinp_legii ;
00167     nouv_base_t[T_SIN_P >> TRA_T] = T_LEG_II ;
00168 
00169     chbase_t[T_COS >> TRA_T] = chb_cos_legmp ;
00170     nouv_base_t[T_COS >> TRA_T] = T_LEG_MP ;
00171 
00172     chbase_t[T_SIN >> TRA_T] = chb_sin_legmi ;
00173     nouv_base_t[T_SIN >> TRA_T] = T_LEG_MI ;
00174     }
00175 
00176 //---------------------------------------------------------------------------
00177 // fin des operation de premier appel 
00178 //---------------------------------------------------------------------------
00179 
00180     // Tout null ?
00181     int nzone = get_mg()->get_nzone() ;
00182     if (etat == ETATZERO) {
00183     for (int l=0 ; l<nzone ; l++) {
00184         int vbase_r = base.b[l] & MSQ_R  ;
00185         int vbase_t = base.b[l] & MSQ_T  ;
00186         int vbase_p = base.b[l] & MSQ_P  ;
00187         int vbase_t_tra = vbase_t >> TRA_T ;
00188         base.b[l] = ( vbase_p | nouv_base_t[vbase_t_tra] ) | vbase_r ;
00189     }
00190     return ;
00191     }
00192     
00193     // Protection
00194     assert(etat != ETATNONDEF) ;
00195         
00196     if (c_cf == 0x0) {
00197     coef() ;     // The coefficients are required
00198     }
00199 
00200 // Boucle sur les differentes zones
00201     
00202     for (int l=0; l<nzone; l++) {
00203     
00204 // On recupere les anciennes bases en r, phi et theta : 
00205         int vbase_r = base.b[l] & MSQ_R  ;
00206         int vbase_t = base.b[l] & MSQ_T  ;
00207         int vbase_p = base.b[l] & MSQ_P  ;
00208 
00209         if ((vbase_t != T_LEG_P) && (vbase_t != T_LEG_IP) &&
00210         (vbase_t != T_LEG_PP) && (vbase_t != T_LEG_I) &&
00211         (vbase_t != T_LEG_II) && (vbase_t != T_LEG_PI) && 
00212         (vbase_t != T_LEG) && (vbase_t != T_LEG_MP) &&
00213         (vbase_t != T_LEG_MI) ) 
00214         { // cas ou le calcul est necessaire
00215 
00216         int vbase_t_tra = vbase_t >> TRA_T ;
00217         assert(vbase_t_tra < MAX_BASE) ; 
00218         bool pair = ( (vbase_t == T_COS_P) || (vbase_t == T_COS_I) ||
00219                   (vbase_t == T_COS) ) ;
00220         bool impair = ( (vbase_t == T_SIN_P) || (vbase_t == T_SIN_I) ||
00221                 (vbase_t == T_SIN) ) ;
00222 
00223 // Nouvelle base : 
00224         base.b[l] = ( vbase_p | nouv_base_t[vbase_t_tra] ) | vbase_r ;
00225         if (get_mg()->get_nt(l)==1) {
00226               *c_cf->t[l] *=sqrt(2.) ;
00227               continue ;
00228               }
00229          
00230 //... tbl contenant les coefficients dans la zone l : 
00231         Tbl* cf =  c_cf->t[l]  ;
00232 
00233         if (cf->get_etat() == ETATZERO) continue ; // On ne fait rien si le tbl = 0 
00234 
00235         deg[0] = get_mg()->get_np(l) ;     // nb. de degres de liberte en phi
00236         deg[1] = get_mg()->get_nt(l)  ;    // nb. de degres de liberte en theta
00237         deg[2] = get_mg()->get_nr(l) ;     // nb. de degres de liberte en r
00238 
00239 //... resultat du calcul :
00240         double* resu = new double [cf->get_taille()] ;
00241                         
00242 // Transformation en theta:
00243 //-------------------------
00244 
00245         if ((pair && (vbase_p == P_COSSIN_I)) ||
00246             (impair && (vbase_p == P_COSSIN_P)) )
00247           ylm_pasprevu(deg, (cf->t), resu ) ;
00248         else
00249           chbase_t[vbase_t_tra](deg, (cf->t), resu ) ;
00250         
00251 // On branche le tbl contenant les coef sur resu : 
00252         delete [] cf->t ;   // les anciens coef. sont oublies
00253         cf->t = resu ;  // nouveaux coef.
00254 
00255         }   // fin du cas ou la transformation devait etre effectuee
00256         
00257     }  // fin de la boucle sur les differentes zones
00258 
00259     // On met les bonnes bases dans c_cf : 
00260     c_cf->base = base ; 
00261 
00262 }
00263 
00264 //******************************************************************************
00265 
00266 void ylm_pasprevu(const int* , const double*, double* ) {
00267 
00268     cout << 
00269      "Valeur::ylm: change of basis not implemented yet !" 
00270      << endl ;
00271     abort() ; 
00272 }
00273 

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