⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 legendre.c

📁 cfd求解器使用与gmsh网格的求解
💻 C
字号:
#define RCSID "$Id: Legendre.c,v 1.15 2006/02/26 00:42:54 geuzaine Exp $"/* * Copyright (C) 1997-2006 P. Dular, C. Geuzaine * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. * * Please report all bugs and problems to <getdp@geuz.org>. * * Contributor(s): *   Ruth Sabariego */#include "GetDP.h"#include "Numeric.h"double Factorial( double n ){  /* FACTORIAL(n) is the product of all the integers from 1 to n */    double F ;  GetDP_Begin("Factorial");  if ( n < 0 ) Msg(GERROR, "Factorial(n): n must be a positive integer") ;  if ( n == 0 ) GetDP_Return(1.) ;  if ( n <= 2 ) GetDP_Return(n) ;  F = n ;  while ( n > 2 ){ n-- ; F *= n ; }    GetDP_Return(F);}double BinomialCoef( double n, double m ){  /* Binomial Coefficients: (n m)      Computes de number of ways of choosing m objects from a collection of n distinct objects */  int i ;  double B = 1. ;  GetDP_Begin("BinomialCoef") ;  if (m==0 || n==m) GetDP_Return(1.) ;  for(i = (int)n ; i > m ; i--)    B *= (double)i/(double)(i-m);  GetDP_Return(B);}double Legendre(int l, int m, double x){  /* Computes the associated Legendre polynomial P_l^m(x).     Here the degree l and the order m are the integers     satisfying -l<=m<=l, while x lies in the range -1<=x<=1 */       double fact, pll=0., pmm,  pmmp1, somx2, Cte ;  int i, ll;    GetDP_Begin("Legendre");    if ( THEABS(m) > l || fabs(x) > 1.)    Msg(GERROR, "Bad arguments for Legendre: P_l^m(x) with -l<=m<=l (int), -1<=x<=1 l = %d m = %d x = %.8g", l, m, x);   Cte = (m > 0) ? 1. : Factorial((double)(l-THEABS(m)))/Factorial((double)(l+THEABS(m))) * pow(-1.,(double)THEABS(m)) ;  m = THEABS(m) ;    pmm = 1. ;    if (m > 0) {    somx2 =  sqrt((1.-x)*(1.+x)) ;    fact = 1. ;     for (i=1;i<=m;i++){      pmm *= -fact*somx2 ;      fact += 2. ;    }  }  if (l==m){    GetDP_Return( Cte*pmm ) ;  }  else {    pmmp1 = x * (2*m+1)*pmm ;    if  (l==(m+1)){      GetDP_Return( Cte*pmmp1 ) ;    }    else {      for (ll=(m+2);ll<=l;ll++) {	pll = (x*(2*ll-1)*pmmp1-(ll+m-1)*pmm)/(ll-m) ;	pmm = pmmp1 ;	pmmp1 = pll ;      }      GetDP_Return( Cte*pll ) ;    }  }}void LegendreRecursive(int l, int m, double x, double P[]){  /* Computes recursively a (l+1)-terms sequence of the associated Legendre polynomial P_l^m(x).     l and m are the integers satisfying 0<=m<=l     x lies in the range -1<=x<=1     l = maximum order considered, m = invariable */  int il ;  double Pl_m, Plm1_m ;  GetDP_Begin("LegendreRecursive");  P[0] = Plm1_m = Legendre(0, m, x) ;  P[1] = Pl_m = Legendre(1, m, x) ;   if (l >=2)     for(il = 1 ; il < l ; il ++){          P[il+1] = (2*il+1)*x*Pl_m/(il-m+1) + (il+m)*Plm1_m/(m-il-1) ;       Plm1_m = Pl_m ;      Pl_m =  P[il+1];    }  else GetDP_End ;  GetDP_End ;}void LegendreRecursiveM(int l, double x, double P[]){  /* Computes recursively a (l+1)-terms sequence of the associated Legendre polynomial P_l^m(x).     x lies in the range -1<=x<=1, l = invariable, -l<=m<=l */  int m ;  double Pl_m, Plm1_m ;  GetDP_Begin("LegendreRecursiveM");  if (fabs(x) == 1.)    for(m = -l ; m <= l ; m ++)       P[l+m] = (m==0) ? pow(THESIGN(x),(double)l) : 0. ;      else{    if (l==0){      P[0] = Legendre(0, 0, x) ;      GetDP_End ;    }    P[0] = Plm1_m = Legendre(l, -l, x) ;    P[1] =  Pl_m =  Legendre(l, -l+1, x) ;        if (l >= 1)      for(m = -l+1 ; m < l ; m ++){     	P[l+m+1] = -2*m*x*Pl_m/sqrt(1-x*x) + (m*(m-1)-l*(l+1))*Plm1_m ; 	Plm1_m = Pl_m ;	Pl_m =  P[l+m+1];      }    else GetDP_End ;  }    GetDP_End ;}double dLegendre (int l, int m, double x){  /* Computes the derivative of the associated Legendre polynomial P_l^m(x) */  double dpl;  GetDP_Begin("dLegendre");    if ( THEABS(m) > l || fabs(x) > 1.)    Msg(GERROR,	"Bad arguments for dLegendre: -l<=m<=l (integers), -1<=x<=1. Current values: l %d m %d x %.8g", l, m, x) ;    if (fabs(x)==1.) dpl = 0.;  else        dpl = ((l+m)*(l-m+1)*sqrt(1-x*x)*((THEABS((m-1))>l) ? 0. :	  Legendre(l, m-1, x)) + m*x* Legendre (l,m,x))/(1-x*x);    GetDP_Return(dpl);}double dLegendreFinDif (int l, int m, double x){  /* Computes the derivative of the associated Legendre polynomial P_l^m(x)   using Finite Differences: f'(x) = (f(x+\delta x)-f(x-\delta x))/(2 \delta) */  double dpl, delta = 1e-6;  GetDP_Begin("dLegendreFinDif");    if ( THEABS(m) > l || fabs(x) > 1.)    Msg(GERROR, "Bad arguments for dLegendreFinDif: -l<=m<=l (integers), -1<=x<=1. Current values: l %d m %d x %.8g", l, m, x );    dpl =  (Legendre (l, m, x+delta) - Legendre (l, m, x-delta))/(2*delta);    GetDP_Return(dpl);}void PrintLegendre(int l, int m, double x, char * FileName){  double P ;  int i ;  FILE * file ;  GetDP_Begin("PrintLegendre");  Msg(INFO, "Writing Legendre: '%s' ", FileName );  file = fopen(FileName, "w");  for (i = 1 ; i <= l ; i++ ){    P = Legendre(i, m, x);    fprintf(file, "%f \n", P);       }  fclose(file);    GetDP_End;}void SphericalHarmonics(int l, int m, double Theta, double Phi, double Yl_m[]){    int am ;  double cn, Pl_m, F, cRe ;  GetDP_Begin("SphericalHarmonics");    cn = sqrt((2*l+1)*ONE_OVER_FOUR_PI) ; /* Normalization Factor */  am = THESIGN(m)*m ;   F= sqrt(Factorial((double)(l-am))/ Factorial((double)(l+am))) ;  Pl_m = Legendre(l, am, cos(Theta));  cRe = cn * F * Pl_m ;  Yl_m[0] = cRe*cos(m*Phi) ;  Yl_m[1] = cRe*sin(m*Phi) ;  GetDP_End;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -