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 }
1.4.6