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

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