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

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