chb_cos_legmp.C

00001 /*
00002  *   Copyright (c) 1999-2001 Eric Gourgoulhon
00003  *                 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_cos_legmp_C[] = "$Header: /cvsroot/Lorene/C++/Source/Non_class_members/Coef/chb_cos_legmp.C,v 1.2 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 cos(j*theta) 
00030  *  representant une fonction 3-D symetrique 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 cos( 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.
00054  *
00055  * Sortie:
00056  * -------
00057  *   double* cfo :  tableau des coefficients a_l du develop. en fonctions de
00058  *          Legendre associees P_n^m:
00059  *
00060  *          f(theta) = 
00061  *              som_{l=m}^{nt-1} a_l P_l^m( cos(theta) )
00062  *      
00063  *          avec m pair :  m = 0, 2, ..., np.         
00064  *
00065  *          P_n^m(x) represente la fonction de Legendre associee
00066  *             de degre n et d'ordre m normalisee de facon a ce que
00067  *
00068  *          int_0^pi [ P_n^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_l (0 <= l <= nt-1) est stoke dans le 
00074  *          tableau cfo comme suit
00075  *                a_l = cfo[ nr*nt* k + i + nr* l ]
00076  *          ou k et i sont les indices correspondant a phi et r 
00077  *          respectivement: m = 2( k/2 ).
00078  *          NB: pour l < m,  a_l = 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_cos_legmp.C,v 1.2 2009/10/23 12:54:47 j_novak Exp $
00087  * $Log: chb_cos_legmp.C,v $
00088  * Revision 1.2  2009/10/23 12:54:47  j_novak
00089  * New base T_LEG_MI
00090  *
00091  * Revision 1.1  2009/10/13 13:49:36  j_novak
00092  * New base T_LEG_MP.
00093  *
00094  *
00095  * $Header: /cvsroot/Lorene/C++/Source/Non_class_members/Coef/chb_cos_legmp.C,v 1.2 2009/10/23 12:54:47 j_novak Exp $
00096  *
00097  */
00098 
00099 
00100 // headers du C
00101 #include <assert.h>
00102 #include <stdlib.h>
00103 
00104 // Prototypage
00105 #include "headcpp.h"
00106 #include "proto.h"
00107 
00108 //******************************************************************************
00109 
00110 void chb_cos_legmp(const int* deg , const double* cfi, double* cfo) {
00111 
00112 int k2, l, jmin, j, i, m ;
00113  
00114 // Nombres de degres de liberte en phi et theta :
00115     int np = deg[0] ;
00116     int nt = deg[1] ;
00117     int nr = deg[2] ;
00118 
00119     assert(np < 4*nt) ;
00120 
00121     // Tableau de travail
00122     double* som = new double[nr] ;
00123 
00124 // Recherche de la matrice de passage  cos --> Legendre 
00125     double* aa = mat_cos_legmp(np, nt) ;
00126     
00127 // Increment en m pour la matrice aa :
00128     int maa = nt * nt  ;
00129    
00130 // Pointeurs de travail :
00131     double* resu = cfo ;
00132     const double* cc = cfi ;
00133 
00134 // Increment en phi :
00135     int ntnr = nt * nr ;
00136 
00137 // Indice courant en phi :
00138     int k = 0 ;
00139 
00140 //----------------------------------------------------------------
00141 //          Cas axisymetrique       
00142 //----------------------------------------------------------------
00143 
00144     if (np == 1) {
00145 
00146     m = 0 ; 
00147 
00148 // Boucle sur l'indice l du developpement en Legendre
00149 
00150 // ... produit matriciel (parallelise sur r)
00151         for (l=m; l<nt; l++) {
00152             for (i=0; i<nr; i++) {
00153             som[i] = 0 ; 
00154             }
00155             
00156             jmin =  l  ;    // pour m=0, aa_lj = 0 pour j<l
00157             for (j=jmin; j<nt; j++) {
00158             double amlj = aa[nt*l + j] ;
00159             for (i=0; i<nr; i++) {
00160                 som[i] += amlj * cc[nr*j + i] ;
00161             }
00162             }
00163             
00164             for (i=0; i<nr; i++) {
00165             *resu = som[i]  ;
00166             resu++ ;  
00167             }
00168             
00169         }  // fin de la boucle sur l 
00170     
00171     // Mise a zero des coefficients k=1 et k=2 :
00172     // ---------------------------------------
00173     
00174     for (i=ntnr; i<3*ntnr; i++) {
00175         cfo[i] = 0 ;         
00176     }       
00177         
00178 
00179     // on sort
00180     delete [] som ;
00181     return ; 
00182     
00183     }   // fin du cas np=1
00184 
00185 
00186 //----------------------------------------------------------------
00187 //          Cas 3-D     
00188 //----------------------------------------------------------------
00189 
00190 
00191 // Boucle sur phi  : 
00192 
00193 
00194     for (m=0; m < np + 1 ; m+=2) {      
00195         
00196     for (k2=0; k2 < 2; k2++) {  // k2=0 : cos(m phi)  ;   k2=1 : sin(m phi)
00197 
00198         if ( (k == 1) || (k == np+1) ) {    // On met les coef de sin(0 phi)
00199                         // et sin( np phi)  a zero 
00200         for (l=0; l<nt; l++) {
00201             for (i=0; i<nr; i++) {
00202             *resu = 0 ;
00203             resu++ ; 
00204             }           
00205         }
00206         }
00207         else {
00208 
00209 // Boucle sur l'indice l du developpement en Legendre
00210 
00211         int lmax = (m<nt-1 ? m : nt-1) ;
00212         for (l=0; l<lmax; l++) {
00213             for (i=0; i<nr; i++) {
00214             *resu = 0 ;
00215             resu++ ; 
00216             }
00217         }       
00218 // ... produit matriciel (parallelise sur r)
00219         for (l=m; l<nt; l++) {
00220             for (i=0; i<nr; i++) {
00221             som[i] = 0 ; 
00222             }
00223             
00224             jmin = ( m == 0 ) ? l : 0 ;  // pour m=0, aa_lj = 0 pour j<l
00225             for (j=jmin; j<nt; j++) {
00226             double amlj = aa[nt*l + j] ;
00227             for (i=0; i<nr; i++) {
00228                 som[i] += amlj * cc[nr*j + i] ;
00229             }
00230             }
00231             
00232             for (i=0; i<nr; i++) {
00233             *resu = som[i]  ;
00234             resu++ ;  
00235             }
00236             
00237         }  // fin de la boucle sur l 
00238 
00239         }   // fin du cas k != 1 et k!=np+1
00240         
00241 // On passe au phi suivant :
00242         cc = cc + ntnr  ; 
00243         k++ ;
00244                 
00245     }   // fin de la boucle sur k2 
00246     
00247 // On passe a l'harmonique en phi suivante :
00248 
00249     aa += maa ; // pointeur sur la nouvelle matrice de passage
00250         
00251     }   // fin de la boucle (m) sur phi  
00252 
00253 //## verif : 
00254     assert(resu == cfo + (np+2)*ntnr) ;
00255 
00256     // Menage
00257     delete [] som ;
00258     
00259 }

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