chb_cossinci_legi.C

00001 /*
00002  *   Copyright (c) 1999-2001 Eric Gourgoulhon
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 chb_cossinci_legi_C[] = "$Header: /cvsroot/Lorene/C++/Source/Non_class_members/Coef/chb_cossinci_legi.C,v 1.3 2005/02/18 13:14:10 j_novak Exp $" ;
00024 
00025 /*
00026  *  Calcule les coefficients du developpement (suivant theta) en fonctions
00027  *  associees de Legendre P_l^m(cos(theta)) (l-m impair) a partir des 
00028  *  coefficients du developpement en 
00029  *   cos[(2*j+1)*theta] [m pair] / sin(2*j* theta) [m impair]
00030  *  representant une fonction 3-D antisymetrique par rapport au plan equatorial
00031  *  z = 0.
00032  * 
00033  * Entree:
00034  * -------
00035  *  const int* deg : tableau du nombre effectif de degres de liberte dans chacune 
00036  *           des 3 dimensions: 
00037  *          deg[0] = np : nombre de points de collocation en phi
00038  *          deg[1] = nt : nombre de points de collocation en theta
00039  *          deg[2] = nr : nombre de points de collocation en r
00040  *
00041  *  const double* cfi :  tableau des coefficients c_j du develop. en cos/sin definis
00042  *            comme suit (a r et phi fixes)
00043  *
00044  *  pour m pair:    f(theta) = som_{j=0}^{nt-2} c_j cos( (2 j+1) theta ) 
00045  *            
00046  *  pour m impair:  f(theta) = som_{j=1}^{nt-2} c_j sin( 2j theta ) 
00047  *
00048  *          L'espace memoire correspondant au pointeur cfi doit etre 
00049  *              nr*nt*(np+2) et doit avoir ete alloue avant 
00050  *          l'appel a la routine.    
00051  *          Le coefficient c_j (0 <= j <= nt-1) doit etre stoke dans le 
00052  *          tableau cfi comme suit
00053  *                c_j = cfi[ nr*nt* k + i + nr* j ]
00054  *          ou k et i sont les indices correspondant a
00055  *          phi et r respectivement: m = k/2.
00056  *              Pour m pair, c_{nt-1} = 0.
00057  *              Pour m impair, c_0 = c_{nt-1} = 0.
00058  *
00059  * Sortie:
00060  * -------
00061  *   double* cfo :  tableau des coefficients a_l du develop. en fonctions de
00062  *          Legendre associees P_n^m impaires:
00063  *
00064  *  pour m pair:    f(theta) = 
00065  *              som_{l=m/2}^{nt-2} a_l P_{2l+1}^m( cos(theta) )
00066  *            
00067  *  pour m impair:  f(theta) = 
00068  *              som_{l=(m+1)/2}^{nt-2} a_l P_{2l}^m( cos(theta) )
00069  *
00070  *          ou P_n^m(x) represente la fonction de Legendre associee
00071  *             de degre n et d'ordre m normalisee de facon a ce que
00072  *
00073  *          int_0^pi [ P_n^m(cos(theta)) ]^2  sin(theta) dtheta = 1
00074  *
00075  *          L'espace memoire correspondant au pointeur cfo doit etre 
00076  *              nr*nt*(np+2) et doit avoir ete alloue avant 
00077  *          l'appel a la routine.    
00078  *          Le coefficient a_l (0 <= l <= nt-1) est stoke dans le 
00079  *          tableau cfo comme suit
00080  *                a_l = cfo[ nr*nt* k + i + nr* l ]
00081  *          ou k et i sont les indices correspondant a phi et r 
00082  *          respectivement: m = k/2.
00083  *          NB: pour m pair: si l < m/2 ou l = nt-1,  a_l = 0
00084  *          pour m impair: si l < (m+1)/2 ou l = nt-1,  a_l = 0
00085  *
00086  * NB:
00087  * ---
00088  *  Il n'est pas possible d'avoir le pointeur cfo egal a cfi.
00089  */
00090 
00091 /*
00092  * $Id: chb_cossinci_legi.C,v 1.3 2005/02/18 13:14:10 j_novak Exp $
00093  * $Log: chb_cossinci_legi.C,v $
00094  * Revision 1.3  2005/02/18 13:14:10  j_novak
00095  * Changing of malloc/free to new/delete + suppression of some unused variables
00096  * (trying to avoid compilation warnings).
00097  *
00098  * Revision 1.2  2002/10/16 14:36:52  j_novak
00099  * Reorganization of #include instructions of standard C++, in order to
00100  * use experimental version 3 of gcc.
00101  *
00102  * Revision 1.1.1.1  2001/11/20 15:19:29  e_gourgoulhon
00103  * LORENE
00104  *
00105  * Revision 2.0  1999/02/22  15:45:41  hyc
00106  * *** empty log message ***
00107  *
00108  *
00109  * $Header: /cvsroot/Lorene/C++/Source/Non_class_members/Coef/chb_cossinci_legi.C,v 1.3 2005/02/18 13:14:10 j_novak Exp $
00110  *
00111  */
00112 
00113 
00114 // headers du C
00115 #include <assert.h>
00116 #include <stdlib.h>
00117 
00118 // Prototypage
00119 #include "headcpp.h"
00120 #include "proto.h"
00121 
00122 //******************************************************************************
00123 
00124 void chb_cossinci_legi(const int* deg , const double* cfi, double* cfo) {
00125 
00126 // Espace de travail realloue eventuellement a chaque appel :
00127 
00128 int ip, k2, l, jmin, j, i, m ;
00129  
00130 // Nombres de degres de liberte en phi et theta :
00131     int np = deg[0] ;
00132     int nt = deg[1] ;
00133     int nr = deg[2] ;
00134 
00135     assert(np < 4*nt) ;
00136 
00137     // Tableau de travail
00138     double* som = new double[nr] ; 
00139 
00140 // Recherche de la matrice de passage  cos/sin --> Legendre 
00141     double* aa = mat_cossinci_legi(np, nt) ;
00142     
00143 // Increment en m pour la matrice aa :
00144     int maa = nt * nt  ;
00145    
00146 // Pointeurs de travail :
00147     double* resu = cfo ;
00148     const double* cc = cfi ;
00149 
00150 // Increment en phi :
00151     int ntnr = nt * nr ;
00152 
00153 // Indice courant en phi :
00154     int k = 0 ;
00155 
00156 // Ordre des harmoniques du developpement de Fourier en phi :
00157     m = 0 ;     
00158       
00159 // --------------
00160 // Boucle sur phi  : k =    4*ip    4*ip+1   4*ip+2    4*ip+3
00161 // --------------    m =    2*ip     2*ip    2*ip+1    2*ip+1
00162 //           k2 =     0       1        0     1
00163 
00164     for (ip=0; ip < np/4 + 1 ; ip++) {      
00165     
00166 //--------------------------------
00167 //  Partie  m pair
00168 //--------------------------------
00169 
00170 
00171     for (k2=0; k2 < 2; k2++) {  // k2=0 : cos(m phi)  ;   k2=1 : sin(m phi)
00172     
00173         if ( (k == 1) || (k == np+1) ) {    // On met les coef de sin(0 phi)
00174                         // et sin( np/2 phi)  a zero 
00175         for (l=0; l<nt; l++) {
00176             for (i=0; i<nr; i++) {
00177             *resu = 0 ;
00178             resu++ ; 
00179             }           
00180         }
00181         }
00182         else {
00183 
00184 // Boucle sur l'indice l du developpement en Legendre
00185 
00186      //...  0 <= l <= m/2 - 1 : a_l = 0 
00187         for (l=0; l<m/2; l++) {
00188             for (i=0; i<nr; i++) {
00189             *resu = 0 ;
00190             resu++ ; 
00191             }
00192         }       
00193 
00194      //...  m/2 <= l <= nt-2 :  produit matriciel (parallelise sur r)
00195         for (l=m/2; l<nt-1; l++) {
00196             for (i=0; i<nr; i++) {
00197             som[i] = 0 ; 
00198             }
00199             
00200             //## jmin = ( m == 0 ) ? l : 0 ;  // pour m=0, aa_lj = 0 pour j<l
00201             jmin = 0 ; 
00202             for (j=jmin; j<nt-1; j++) {
00203             double amlj = aa[nt*l + j] ;
00204             for (i=0; i<nr; i++) {
00205                 som[i] += amlj * cc[nr*j + i] ;
00206             }
00207             }
00208             
00209             for (i=0; i<nr; i++) {
00210             *resu = som[i]  ;
00211             resu++ ;  
00212             }
00213             
00214         }  // fin de la boucle sur l 
00215 
00216 
00217      //...  l = nt-1 : a_l = 0 
00218         for (i=0; i<nr; i++) {
00219             *resu = 0 ;
00220             resu++ ; 
00221         }
00222 
00223         }   // fin du cas k != 1 
00224         
00225 // On passe au phi suivant :
00226         cc = cc + ntnr  ; 
00227         k++ ;
00228                 
00229     }   // fin de la boucle sur k2 
00230     
00231 // On passe a l'harmonique en phi suivante :
00232     m++ ;
00233     aa += maa ; // pointeur sur la nouvelle matrice de passage
00234     
00235 //--------------------------------
00236 //  Partie m impair
00237 //--------------------------------
00238 
00239     for (k2=0; k2 < 2; k2++) {  // k2=0 : cos(m phi)  ;   k2=1 : sin(m phi)
00240     
00241         if ( k == np+1 ) {          // On met les coef de 
00242                         // sin( np/2 phi)  a zero 
00243         for (l=0; l<nt; l++) {
00244             for (i=0; i<nr; i++) {
00245             *resu = 0 ;
00246             resu++ ; 
00247             }           
00248         }
00249         }
00250 
00251         if (k < np+1) {  
00252 
00253 // Boucle sur l'indice l du developpement en Legendre
00254 
00255      //...  0 <= l <= (m-1)/2  : a_l = 0 
00256 
00257         for (l=0; l<(m+1)/2; l++) {
00258             for (i=0; i<nr; i++) {
00259             *resu = 0 ;
00260             resu++ ; 
00261             }
00262         }
00263 
00264      //...  (m+1)/2 <= l <= nt-2 :  produit matriciel (parallelise sur r)
00265         for (l=(m+1)/2; l<nt-1; l++) {
00266             for (i=0; i<nr; i++) {
00267             som[i] = 0 ; 
00268             }
00269            
00270             //## jmin = ( m == 1 ) ? l : 0 ;  // pour m=1, aa_lj = 0 pour j<l
00271             jmin = 1 ;  // pour j=0, sin(2*j*theta)=0  
00272 
00273             for (j=jmin; j<nt-1; j++) {
00274             double amlj = aa[nt*l + j] ;
00275             for (i=0; i<nr; i++) {
00276                 som[i] += amlj * cc[nr*j + i] ;
00277             }
00278             }
00279             
00280             for (i=0; i<nr; i++) {
00281             *resu = som[i]  ;
00282             resu++ ;  
00283             }
00284             
00285         }  // fin de la boucle sur l 
00286 
00287      //...  l = nt-1 : a_l = 0 
00288         for (i=0; i<nr; i++) {
00289             *resu = 0  ;
00290             resu++ ;  
00291         }
00292         
00293 
00294 // On passe au phi suivant :
00295         cc = cc + ntnr  ; 
00296         k++ ;
00297         
00298         }   // fin du cas k < np+1
00299         
00300     }  //  fin de la boucle sur k2 
00301     
00302 
00303 // On passe a l'harmonique en phi suivante :
00304     m++ ;
00305     aa += maa ; // pointeur sur la nouvelle matrice de passage 
00306     
00307     }   // fin de la boucle (ip) sur phi  
00308 
00309 // Mise a zero des coefficients de sin( np/2 phi ) (k=np+1)
00310 
00311 //## verif : 
00312     assert(resu == cfo + (np+2)*ntnr) ;
00313 
00314     // Menage
00315     delete [] som ;
00316     
00317 }

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