mat_legmi_sin.C

00001 /*
00002  *   Copyright (c) 2003-2009 Jerome Novak
00003  *
00004  *   This file is part of LORENE.
00005  *
00006  *   LORENE is free software; you can redistribute it and/or modify
00007  *   it under the terms of the GNU General Public License as published by
00008  *   the Free Software Foundation; either version 2 of the License, or
00009  *   (at your option) any later version.
00010  *
00011  *   LORENE is distributed in the hope that it will be useful,
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *   GNU General Public License for more details.
00015  *
00016  *   You should have received a copy of the GNU General Public License
00017  *   along with LORENE; if not, write to the Free Software
00018  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00021 
00022 
00023 char mat_legmi_sin_C[] = "$Header: /cvsroot/Lorene/C++/Source/Non_class_members/Coef/mat_legmi_sin.C,v 1.1 2009/10/23 12:54:47 j_novak Exp $" ;
00024 
00025 /*
00026  * Fournit la matrice de passage pour la transformation des coefficients du
00027  * developpement en fonctions associees de Legendre 
00028  * P_l^m(cos(theta)) avec m impair dans les coefficients du developpement 
00029  * en sin( j theta ).
00030  * 
00031  * Cette routine n'effectue le calcul de la matrice que si celui-ci n'a pas 
00032  * deja ete fait, sinon elle renvoie le pointeur sur une valeur precedemment 
00033  * calculee.
00034  * 
00035  * Entree:
00036  * -------
00037  *  int np  :   Nombre de degres de liberte en phi 
00038  *  int nt  :   Nombre de degres de liberte en theta
00039  *
00040  * Sortie (valeur de retour) :
00041  * ---------------------------
00042  *  double* mat_legmi_sin : pointeur sur le tableau contenant l'ensemble
00043  *                  (pour les np/2 valeurs de m: m=1,3,...,np-1)) des 
00044  *              matrices de passage.
00045  *              La dimension du tableau est (np/2+1)*nt^2
00046  *              Le stokage est le suivant: 
00047  *
00048  *      mat_legmi_sin[ nt*nt* m + nt*j + l] = B_{mjl} 
00049  *              
00050  *              ou B_{mjl} (m impair) est defini par
00051  *
00052  *   P_l^m( cos(theta) ) = som_{j=1}^{nt-2} B_{mjl} sin(j*theta) 
00053  *
00054  *  ou P_n^m(x) represente la fonction de Legendre associee de degre n et 
00055  *     d'ordre m normalisee de facon a ce que
00056  *
00057  *   int_0^pi [ P_n^m(cos(theta)) ]^2  sin(theta) dtheta = 1
00058  *
00059  * 
00060  */
00061 
00062 /*
00063  * $Id: mat_legmi_sin.C,v 1.1 2009/10/23 12:54:47 j_novak Exp $
00064  * $Log: mat_legmi_sin.C,v $
00065  * Revision 1.1  2009/10/23 12:54:47  j_novak
00066  * New base T_LEG_MI
00067  *
00068  *
00069  * $Header: /cvsroot/Lorene/C++/Source/Non_class_members/Coef/mat_legmi_sin.C,v 1.1 2009/10/23 12:54:47 j_novak Exp $
00070  *
00071  */
00072 
00073 // headers du C
00074 #include <stdlib.h>
00075 #include <math.h>
00076 
00077 // Headers Lorene
00078 #include "headcpp.h"
00079 #include "proto.h"
00080 
00081 //******************************************************************************
00082 
00083 double* mat_legmi_sin(int np, int nt) {
00084 
00085 #define NMAX    30      // Nombre maximun de couples(np,nt) differents 
00086     static  double* tab[NMAX] ; // Tableau des pointeurs sur les tableaux 
00087     static  int nb_dejafait = 0 ;      // Nombre de tableaux deja initialises 
00088     static  int np_dejafait[NMAX] ;    // Valeurs de np pour lesquelles le
00089                                                // calcul a deja ete fait
00090     static  int nt_dejafait[NMAX] ;    // Valeurs de np pour lesquelles le
00091                                                // calcul a deja ete fait
00092     int i, indice,  j,  j2,  m,  l ;
00093     
00094 // Les matrices B_{mjl} pour ce couple (np,nt) ont-elles deja ete calculees ? 
00095     
00096     indice = -1 ;
00097     for ( i=0 ; i < nb_dejafait ; i++ ) {
00098     if ( (np_dejafait[i] == np) && (nt_dejafait[i] == nt) ) indice = i ;
00099     }
00100 
00101 
00102 // Si le calcul n'a pas deja ete fait, il faut le faire : 
00103     if (indice == -1) {        
00104     if ( nb_dejafait >= NMAX ) {
00105         cout << "mat_legii_sinp: nb_dejafait >= NMAX : "
00106         << nb_dejafait << " <-> " << NMAX << endl ;
00107         abort () ;  
00108         exit(-1) ;
00109         }
00110     indice = nb_dejafait ; 
00111     nb_dejafait++ ; 
00112     np_dejafait[indice] = np ;
00113     nt_dejafait[indice] = nt ;
00114 
00115     tab[indice] = new double[(np/2+1)*nt*nt] ;
00116 
00117 //-----------------------
00118 // Preparation du calcul 
00119 //-----------------------
00120 
00121 // Sur-echantillonnage :
00122     int nt2 = 2*nt - 1 ; 
00123 
00124     int deg[3] ;
00125     deg[0] = 1 ;
00126     deg[1] = nt2 ;
00127     deg[2] = 1 ;
00128 
00129 // Tableaux de travail
00130     double* yy = new double[nt2] ;
00131 
00132 
00133 //-------------------
00134 // Boucle sur m
00135 //-------------------
00136 
00137     int m_max = (np == 1) ? 1 : np-1 ; 
00138     
00139     for (m=1; m <= m_max ; m+=2) {
00140         
00141         // Recherche des fonctions de Legendre associees d'ordre m :
00142         
00143         double* leg = legendre_norm(m, nt) ;    
00144         
00145         
00146         for (l=m; l<nt-1; l++) {    // boucle sur les P_l^m
00147         
00148         int parite = 1 - 2*((l-m)%2) ;  // parite du P_l^m par rapport au plan theta=pi/2    
00149         
00150         for (j2=0; j2<nt; j2++) {
00151             yy[j2] = leg[nt2* (l-m) + 2*j2] ;
00152         }
00153         
00154         for (j2=nt; j2<nt2; j2++) {
00155             yy[j2] = parite * leg[nt2* (l-m) + 2*nt2 -2 - 2*j2] ;
00156         }
00157         
00158         //....... transformation en sin(j*theta) : 
00159 
00160         cftsin(deg, deg, yy, deg, yy) ; 
00161 
00162         //....... le resultat fournit les elements de matrice : 
00163         for (j=0; j<nt-1; j++) {
00164             tab[indice][ nt*nt*((m-1)/2) + nt*j + l] = yy[j] ; 
00165         }
00166         
00167         }  // fin de la boucle sur l (indice de P_l^m)
00168         
00169         delete [] leg ;
00170             
00171     }  // fin de la boucle sur m
00172     
00173 // Liberation espace memoire
00174 // -------------------------
00175     
00176     delete [] yy ;
00177     
00178     } // fin du cas ou le calcul etait necessaire
00179     
00180     return tab[indice] ;
00181     
00182 }
00183 
00184 

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