chb_legpi_sini.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_legpi_sini_C[] = "$Header: /cvsroot/Lorene/C++/Source/Non_class_members/Coef/chb_legpi_sini.C,v 1.4 2005/02/18 13:14:11 j_novak Exp $" ;
00024 
00025 /*
00026  *  Calcule les coefficients du developpement (suivant theta) 
00027  *  en sin((2j+1) theta) 
00028  *  a partir des coefficients du developpement en fonctions
00029  *  associees de Legendre P_l^m(cos(theta)) (l impair et m impair)
00030  *  pour une une fonction 3-D symetrique par rapport au plan equatorial
00031  *  z = 0 et antisymetrique par le retournement (x, y, z) --> (-x, -y, z). 
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 a_j du develop. en fonctions de
00042  *          Legendre associees P_n^m:
00043  *
00044  *          f(theta) = 
00045  *              som_{l=(m-1)/2}^{nt-2} a_j P_{2j+1}^m( cos(theta) )
00046  *            
00047  *      (m impair) 
00048  *
00049  *          ou P_l^m(x) represente la fonction de Legendre associee
00050  *             de degre l et d'ordre m normalisee de facon a ce que
00051  *
00052  *          int_0^pi [ P_l^m(cos(theta)) ]^2  sin(theta) dtheta = 1
00053  *
00054  *          L'espace memoire correspondant au pointeur cfi doit etre 
00055  *              nr*nt*(np+2) et doit avoir ete alloue avant 
00056  *          l'appel a la routine.    
00057  *          Le coefficient a_j (0 <= j <= nt-1) doit etre stoke dans le 
00058  *          tableau cfi comme suit
00059  *                a_j = cfi[ nr*nt* k + i + nr* j ]
00060  *          ou k et i sont les indices correspondant a phi et r 
00061  *          respectivement: m = 2 (k/2).
00062  *          NB: pour j<(m-1)/2,  a_j = 0
00063  *
00064  * Sortie:
00065  * -------
00066  *   double* cfo :  tableau des coefficients c_j du develop. en sin definis
00067  *            comme suit (a r et phi fixes) :
00068  *
00069  *          f(theta) = som_{j=0}^{nt-2} c_j sin( (2j+1) theta ) 
00070  *            
00071  *          L'espace memoire correspondant au pointeur cfo doit etre 
00072  *              nr*nt*(np+2) et doit avoir ete alloue avant 
00073  *          l'appel a la routine.    
00074  *          Le coefficient c_j (0 <= j <= nt-1) est stoke dans le 
00075  *          tableau cfo comme suit
00076  *                c_j = cfo[ nr*nt* k + i + nr* j ]
00077  *          ou k et i sont les indices correspondant a
00078  *          phi et r respectivement.
00079  *              NB:     c_{nt-1} = 0.
00080  *
00081  *
00082  * NB:
00083  * ---
00084  *  Il n'est pas possible d'avoir le pointeur cfo egal a cfi.
00085  */
00086 
00087 /*
00088  * $Id: chb_legpi_sini.C,v 1.4 2005/02/18 13:14:11 j_novak Exp $
00089  * $Log: chb_legpi_sini.C,v $
00090  * Revision 1.4  2005/02/18 13:14:11  j_novak
00091  * Changing of malloc/free to new/delete + suppression of some unused variables
00092  * (trying to avoid compilation warnings).
00093  *
00094  * Revision 1.3  2003/01/31 10:31:23  e_gourgoulhon
00095  * Suppressed the directive #include <malloc.h> for malloc is defined
00096  * in <stdlib.h>
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.1  2000/11/14  15:12:11  eric
00106  * Traitement du cas np=1
00107  *
00108  * Revision 2.0  2000/09/29  16:07:35  eric
00109  * *** empty log message ***
00110  *
00111  *
00112  * $Header: /cvsroot/Lorene/C++/Source/Non_class_members/Coef/chb_legpi_sini.C,v 1.4 2005/02/18 13:14:11 j_novak Exp $
00113  *
00114  */
00115 
00116 // headers du C
00117 #include <stdlib.h>
00118 #include <assert.h>
00119 
00120 // Headers Lorene
00121 #include "headcpp.h"
00122 #include "proto.h"
00123 
00124 //******************************************************************************
00125 
00126 void chb_legpi_sini(const int* deg , const double* cfi, double* cfo) {
00127 
00128 int k2, l, 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     assert( cfi != cfo ) ; 
00137 
00138     // Tableau de travail
00139     double* som = new double[nr] ; 
00140 
00141 // Recherche de la matrice de passage  Legendre -->  cos/sin 
00142     double* bb = mat_legpi_sini(np, nt) ;
00143     
00144 // Increment en m pour la matrice bb :
00145     int mbb = nt * nt  ;
00146    
00147 // Pointeurs de travail :
00148     double* resu = cfo ;
00149     const double* cc = cfi ;
00150 
00151 // Increment en phi :
00152     int ntnr = nt * nr ;
00153 
00154 // Indice courant en phi :
00155     int k = 0 ;
00156 
00157     // Cas k=0 (m=1 : cos(phi)) 
00158     // ------------------------
00159 
00160     // Boucle sur l'indice j du developpement en sin( (2j+1) theta) 
00161 
00162     for (j=0; j<nt-1; j++) {
00163 
00164     // ... produit matriciel (parallelise sur r)
00165     for (i=0; i<nr; i++) {
00166         som[i] = 0 ; 
00167     }
00168 
00169     for (l=0; l<nt-1; l++) {
00170         double bmjl = bb[nt*j + l] ;
00171         for (i=0; i<nr; i++) {
00172         som[i] += bmjl * cc[nr*l + i] ;
00173         }
00174     }
00175             
00176     for (i=0; i<nr; i++) {
00177         *resu = som[i]  ;
00178         resu++ ;  
00179     }
00180             
00181     }  // fin de la boucle sur j 
00182 
00183     // Dernier coef en j=nt-1 mis a zero pour le cas m impair : 
00184     for (i=0; i<nr; i++) {
00185     *resu = 0  ;
00186     resu++ ;  
00187     }
00188         
00189     // Special case np=1 (axisymmetry)
00190     // -------------------------------
00191     if (np==1) {
00192     for (i=0; i<2*ntnr; i++) {
00193         *resu = 0 ;
00194         resu++ ; 
00195     }
00196     delete []  som  ; 
00197     return ;                
00198     }
00199     
00200     // On passe au phi suivant :
00201     cc = cc + ntnr  ; 
00202     k++ ;
00203         
00204     // Cas k=1 : tout est mis a zero
00205     // -----------------------------    
00206 
00207     for (l=0; l<nt; l++) {
00208     for (i=0; i<nr; i++) {
00209         *resu = 0 ;
00210         resu++ ; 
00211     }           
00212     }
00213 
00214     // On passe au phi suivant :
00215     cc = cc + ntnr  ; 
00216     k++ ;
00217         
00218     // Cas k=2 (m=1 : sin(phi)) 
00219     // ------------------------
00220 
00221     // Boucle sur l'indice j du developpement en sin( (2j+1) theta) 
00222 
00223     for (j=0; j<nt-1; j++) {
00224 
00225     // ... produit matriciel (parallelise sur r)
00226     for (i=0; i<nr; i++) {
00227         som[i] = 0 ; 
00228     }
00229 
00230     for (l=0; l<nt-1; l++) {
00231         double bmjl = bb[nt*j + l] ;
00232         for (i=0; i<nr; i++) {
00233         som[i] += bmjl * cc[nr*l + i] ;
00234         }
00235     }
00236             
00237     for (i=0; i<nr; i++) {
00238         *resu = som[i]  ;
00239         resu++ ;  
00240     }
00241             
00242     }  // fin de la boucle sur j 
00243 
00244     // Dernier coef en j=nt-1 mis a zero pour le cas m impair : 
00245     for (i=0; i<nr; i++) {
00246     *resu = 0  ;
00247     resu++ ;  
00248     }
00249         
00250     // On passe au phi suivant :
00251     cc = cc + ntnr  ; 
00252     k++ ;
00253         
00254     // On passe au m suivant :
00255     bb += mbb ; // pointeur sur la nouvelle matrice de passage 
00256 
00257     // Cas k >= 3
00258     // ----------
00259 
00260     for (m=3; m < np ; m+=2) {      
00261         
00262     for (k2=0; k2 < 2; k2++) {  // k2=0 : cos(m phi)  ;   k2=1 : sin(m phi)
00263     
00264         // Boucle sur l'indice j du developpement en sin( (2j+1) theta) 
00265 
00266         for (j=0; j<nt-1; j++) {
00267 
00268         // ... produit matriciel (parallelise sur r)
00269         for (i=0; i<nr; i++) {
00270             som[i] = 0 ; 
00271         }
00272 
00273         for (l=(m-1)/2; l<nt-1; l++) {
00274             double bmjl = bb[nt*j + l] ;
00275             for (i=0; i<nr; i++) {
00276             som[i] += bmjl * cc[nr*l + 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 j 
00286 
00287         // Dernier coef en j=nt-1 mis a zero pour le cas m impair : 
00288         for (i=0; i<nr; i++) {
00289         *resu = 0  ;
00290         resu++ ;  
00291         }
00292         
00293         // On passe au phi suivant :
00294         cc = cc + ntnr  ; 
00295         k++ ;
00296         
00297     }  //  fin de la boucle sur k2 
00298     
00299     // On passe a l'harmonique en phi suivante :
00300     bb += mbb ; // pointeur sur la nouvelle matrice de passage 
00301     
00302     }   // fin de la boucle (m) sur phi  
00303 
00304 
00305     // Cas k=np+1 : tout est mis a zero
00306     // -------------------------------- 
00307 
00308     for (l=0; l<nt; l++) {
00309     for (i=0; i<nr; i++) {
00310         *resu = 0 ;
00311         resu++ ; 
00312     }           
00313     }
00314 
00315 
00316 //## verif : 
00317     assert(resu == cfo + (np+2)*ntnr) ;
00318 
00319     // Menage
00320     delete [] som ;
00321     
00322 }

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