chb_sin_legmi.C

00001 /*
00002  *   Copyright (c) 1999-2001 Eric Gourgoulhon
00003  *   Copyright (c) 2009 Jerome Novak
00004  *
00005  *   This file is part of LORENE.
00006  *
00007  *   LORENE is free software; you can redistribute it and/or modify
00008  *   it under the terms of the GNU General Public License as published by
00009  *   the Free Software Foundation; either version 2 of the License, or
00010  *   (at your option) any later version.
00011  *
00012  *   LORENE is distributed in the hope that it will be useful,
00013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *   GNU General Public License for more details.
00016  *
00017  *   You should have received a copy of the GNU General Public License
00018  *   along with LORENE; if not, write to the Free Software
00019  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  *
00021  */
00022 
00023 
00024 char chb_sin_legmi_C[] = "$Header: /cvsroot/Lorene/C++/Source/Non_class_members/Coef/chb_sin_legmi.C,v 1.1 2009/10/23 12:54:47 j_novak Exp $" ;
00025 
00026 /*
00027  *  Calcule les coefficients du developpement (suivant theta) en fonctions
00028  *  associees de Legendre P_l^m(cos(theta)) a partir des coefficients du 
00029  *  developpement en sin(j*theta) 
00030  *  representant une fonction 3-D antisymetrique par le retournement 
00031  *  (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 c_j du develop. en cos defini
00042  *            comme suit (a r et phi fixes)
00043  *
00044  *          f(theta) = som_{j=0}^{nt-1} 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-2) 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. 
00054  *
00055  * Sortie:
00056  * -------
00057  *   double* cfo :  tableau des coefficients a_j du develop. en fonctions de
00058  *          Legendre associees P_l^m (m impair)
00059  *
00060  *          f(theta) = 
00061  *              som_{l=m}^{nt-1} a_j P_j^m( cos(theta) )
00062  *
00063  *          avec m impair.        
00064  *
00065  *          P_l^m(x) represente la fonction de Legendre associee
00066  *             de degre l et d'ordre m normalisee de facon a ce que
00067  *
00068  *          int_0^pi [ P_l^m(cos(theta)) ]^2  sin(theta) dtheta = 1
00069  *
00070  *          L'espace memoire correspondant au pointeur cfo doit etre 
00071  *              nr*nt*(np+2) et doit avoir ete alloue avant 
00072  *          l'appel a la routine.    
00073  *          Le coefficient a_j (0 <= j <= nt-1) est stoke dans le 
00074  *          tableau cfo comme suit
00075  *                a_j = cfo[ nr*nt* k + i + nr* j ]
00076  *          ou k et i sont les indices correspondant a phi et r 
00077  *          respectivement: m = 2( k/2 ).
00078  *          NB: pour j< m,  a_j = 0
00079  *
00080  * NB:
00081  * ---
00082  *  Il n'est pas possible d'avoir le pointeur cfo egal a cfi.
00083  */
00084 
00085 /*
00086  * $Id: chb_sin_legmi.C,v 1.1 2009/10/23 12:54:47 j_novak Exp $
00087  * $Log: chb_sin_legmi.C,v $
00088  * Revision 1.1  2009/10/23 12:54:47  j_novak
00089  * New base T_LEG_MI
00090  *
00091  *
00092  *
00093  * $Header: /cvsroot/Lorene/C++/Source/Non_class_members/Coef/chb_sin_legmi.C,v 1.1 2009/10/23 12:54:47 j_novak Exp $
00094  *
00095  */
00096 
00097 // headers du C
00098 #include <assert.h>
00099 #include <stdlib.h>
00100 
00101 // Prototypage
00102 #include "headcpp.h"
00103 #include "proto.h"
00104 
00105 //******************************************************************************
00106 
00107 void chb_sin_legmi(const int* deg , const double* cfi, double* cfo) {
00108 
00109 int k2, l, jmin, j, i, m ;
00110  
00111     // Nombres de degres de liberte en phi et theta :
00112     int np = deg[0] ;
00113     int nt = deg[1] ;
00114     int nr = deg[2] ;
00115 
00116     assert(np < 4*nt) ;
00117     assert( cfi != cfo ) ; 
00118 
00119     // Tableau de travail
00120     double* som = new double[nr] ; 
00121 
00122     // Recherche de la matrice de passage  sin --> Legendre 
00123     double* aa = mat_sin_legmi(np, nt) ;
00124     
00125     // Increment en m pour la matrice aa :
00126     int maa = nt * nt  ;
00127    
00128     // Pointeurs de travail :
00129     double* resu = cfo ;
00130     const double* cc = cfi ;
00131 
00132     // Increment en phi :
00133     int ntnr = nt * nr ;
00134 
00135     // Indice courant en phi :
00136     int k = 0 ;
00137 
00138     // Cas k=0 (m=1 : cos(phi)) 
00139     // ------------------------
00140 
00141     // Cas l=0 : a_l = 0
00142     for (i=0; i<nr; i++) {
00143       *resu = 0. ;
00144       resu++ ; 
00145     }
00146 
00147     // ... produit matriciel
00148     for (l=1; l<nt-1; l++) {
00149     for (i=0; i<nr; i++) {
00150         som[i] = 0 ; 
00151     }
00152            
00153     jmin =  l  ;  // pour m=1, aa_lj = 0 pour j<l
00154 
00155     for (j=jmin; j<nt-1; j++) {
00156         double amlj = aa[nt*l + j] ;
00157         for (i=0; i<nr; i++) {
00158         som[i] += amlj * cc[nr*j + i] ;
00159         }
00160     }
00161             
00162     for (i=0; i<nr; i++) {
00163         *resu = som[i]  ;
00164         resu++ ;   
00165     }
00166             
00167     }  // fin de la boucle sur l 
00168 
00169     // Dernier coef en l=nt-1 mis a zero pour le cas m impair : 
00170     for (i=0; i<nr; i++) {
00171     *resu = 0  ;
00172     resu++ ;
00173     }
00174 
00175     // Special case np=1 (axisymmetry)
00176     // -------------------------------
00177     if (np==1) {
00178     for (i=0; i<2*ntnr; i++) {
00179         *resu = 0 ;
00180         resu++ ; 
00181     }
00182     delete []  som  ; 
00183     return ;                
00184     }
00185     
00186     
00187     // On passe au phi suivant :
00188     cc = cc + ntnr  ; 
00189     k++ ;
00190         
00191     // Cas k=1 : tout est mis a zero
00192     // -----------------------------    
00193 
00194     for (l=0; l<nt; l++) {
00195     for (i=0; i<nr; i++) {
00196         *resu = 0 ;
00197         resu++ ;  
00198     }           
00199     }
00200 
00201     // On passe au phi suivant :
00202     cc = cc + ntnr  ; 
00203     k++ ;
00204         
00205     // Cas k=2 (m=1 : sin(phi)) 
00206     // ------------------------
00207 
00208     // Cas l=0 : a_l = 0
00209     for (i=0; i<nr; i++) {
00210       *resu = 0. ;
00211       resu++ ; 
00212     }
00213 
00214     // ... produit matriciel
00215     for (l=1; l<nt-1; l++) {
00216     for (i=0; i<nr; i++) {
00217         som[i] = 0 ; 
00218     }
00219            
00220     jmin =  l  ;  // pour m=1, aa_lj = 0 pour j<l
00221 
00222     for (j=jmin; j<nt-1; j++) {
00223         double amlj = aa[nt*l + j] ;
00224         for (i=0; i<nr; i++) {
00225         som[i] += amlj * cc[nr*j + i] ;
00226         }
00227     }
00228             
00229     for (i=0; i<nr; i++) {
00230         *resu = som[i]  ;
00231         resu++ ;   
00232     }
00233             
00234     }  // fin de la boucle sur l 
00235 
00236     // Dernier coef en l=nt-1 mis a zero pour le cas m impair : 
00237     for (i=0; i<nr; i++) {
00238     *resu = 0  ;
00239     resu++ ;   
00240     }
00241     
00242     // On passe au phi suivant :
00243     cc = cc + ntnr  ; 
00244     k++ ;
00245 
00246     // On passe au m suivant
00247     aa += maa ; // pointeur sur la nouvelle matrice de passage
00248 
00249     // Cas k >= 3
00250     // ----------
00251 
00252     for (m=3; m < np ; m+=2) {      
00253         
00254     for (k2=0; k2 < 2; k2++) {  // k2=0 : cos(m phi)  ;   k2=1 : sin(m phi)
00255         int lmax = (m<nt-1 ? m : nt -1) ;
00256         for (l=0; l<lmax; l++) {
00257         for (i=0; i<nr; i++) {
00258             *resu = 0 ;
00259             resu++ ;  
00260         }
00261         }
00262 
00263         // ... produit matriciel
00264         for (l=m; l<nt-1; l++) {
00265         for (i=0; i<nr; i++) {
00266             som[i] = 0 ; 
00267         }
00268            
00269         jmin =  1 ;  
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         for (i=0; i<nr; i++) {
00279             *resu = som[i]  ;
00280             resu++ ;   
00281         }
00282             
00283         }  // fin de la boucle sur l 
00284 
00285         // Dernier coef en l=nt-1 mis a zero pour le cas m impair : 
00286         for (i=0; i<nr; i++) {
00287         *resu = 0  ;
00288         resu++ ;   
00289         }
00290         
00291         // On passe au phi suivant :
00292         cc = cc + ntnr  ; 
00293         k++ ;
00294                         
00295     }   // fin de la boucle sur k2 
00296     
00297     // On passe a l'harmonique en phi suivante :
00298 
00299     aa += maa ; // pointeur sur la nouvelle matrice de passage
00300         
00301     }   // fin de la boucle (m) sur phi  
00302 
00303     // Cas k=np+1 : tout est mis a zero
00304     // -------------------------------- 
00305 
00306     for (l=0; l<nt; l++) {
00307     for (i=0; i<nr; i++) {
00308         *resu = 0 ;
00309         resu++ ;  
00310     }           
00311     }
00312 
00313 
00314 //## verif : 
00315     assert(resu == cfo + (np+2)*ntnr) ;
00316 
00317     // Menage
00318     delete [] som ;
00319     
00320 }

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