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

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