legendre_nodes.C

00001 /*
00002  * Computation of Legendre Gauss-Lobatto nodes and weights
00003  */
00004  
00005 /*
00006  *   Copyright (c) 2005 Philippe Grandclément
00007  *
00008  *   This file is part of LORENE.
00009  *
00010  *   LORENE is free software; you can redistribute it and/or modify
00011  *   it under the terms of the GNU General Public License as published by
00012  *   the Free Software Foundation; either version 2 of the License, or
00013  *   (at your option) any later version.
00014  *
00015  *   LORENE is distributed in the hope that it will be useful,
00016  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *   GNU General Public License for more details.
00019  *
00020  *   You should have received a copy of the GNU General Public License
00021  *   along with LORENE; if not, write to the Free Software
00022  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  *
00024  */
00025 
00026 /*
00027  * $Id: legendre_nodes.C,v 1.1 2005/11/14 01:56:59 e_gourgoulhon Exp $
00028  * $Log: legendre_nodes.C,v $
00029  * Revision 1.1  2005/11/14 01:56:59  e_gourgoulhon
00030  * First version
00031  *
00032  *
00033  * $Header: /cvsroot/Lorene/School05/Monday/legendre_nodes.C,v 1.1 2005/11/14 01:56:59 e_gourgoulhon Exp $
00034  *
00035  */
00036 
00037 #include <iostream>
00038 
00039 using namespace std ;
00040 
00041 #include "math.h"
00042 
00043 void legendre_poly_der(int n, double& poly, double& pder, double& polym1, 
00044         double& pderm1, double& polym2, double& pderm2, double x) {
00045         
00046     
00047     if (n==0) {
00048          poly = 1 ;
00049          pder = 0 ;
00050          }
00051     else 
00052         if (n==1) {
00053              polym1 = 1 ;
00054          pderm1 = 0 ;
00055          poly = x ;
00056          pder = 1 ;
00057          }
00058     else {
00059          polym1 = 1 ;
00060          pderm1 = 0 ;
00061          poly = x ;
00062          pder = 1 ;
00063          for (int i=1 ; i<n ; i++) {
00064              polym2 = polym1 ;
00065          pderm2 = pderm1 ;
00066          polym1 = poly ;
00067          pderm1 = pder ;
00068          poly = ((2*i+1)*x*polym1 - i*polym2)/(i+1) ;
00069          pder = ((2*i+1)*polym1+(2*i+1)*x*pderm1-i*pderm2)/(i+1) ;
00070         }
00071     }
00072 }
00073 
00074 
00075 void legendre_nodes_weight_GL(int n, double* coloc, double* weight, double prec,
00076                               int itemax) {
00077      
00078      double x_plus = 1 ;
00079      double x_moins = -1 ;
00080      double p_plus, dp_plus, p_plus_m1, dp_plus_m1, p_plus_m2, dp_plus_m2 ;
00081      double p_moins, dp_moins, p_moins_m1, dp_moins_m1, p_moins_m2, dp_moins_m2 ;
00082      double p, dp, p_m1, dp_m1, p_m2, dp_m2 ;
00083      
00084      legendre_poly_der(n, p_plus, dp_plus, p_plus_m1, dp_plus_m1, p_plus_m2, 
00085                        dp_plus_m2, x_plus) ;
00086      legendre_poly_der(n, p_moins, dp_moins, p_moins_m1, dp_moins_m1, 
00087                        p_moins_m2, dp_moins_m2, x_moins) ;
00088      
00089      double det = p_plus_m1*p_moins_m2 - p_moins_m1*p_plus_m2 ;
00090      double r_plus = -p_plus ;
00091      double r_moins = -p_moins ;
00092      double a = (r_plus*p_moins_m2 - r_moins*p_plus_m2)/det ;
00093      double b = (r_moins*p_plus_m1 - r_plus*p_moins_m1)/det ;
00094      
00095      coloc[n-1] = 1 ;
00096      double dth = M_PI/(2*n+1) ;
00097      double cd = cos (2*dth) ;
00098      double sd = sin (2*dth) ;
00099      double cs = cos(dth) ;
00100      double ss = sin(dth) ;
00101      
00102      int borne_sup = (n%2==0) ? 
00103           n/2 : (n+1)/2  ;
00104      
00105      for (int j=1 ; j<borne_sup ; j++) {
00106           double x = cs ;
00107       bool loop = true ;
00108       int ite = 0 ;
00109       while (loop) {
00110            legendre_poly_der(n, p, dp, p_m1, dp_m1, p_m2, dp_m2, x) ;
00111            double poly = p + a*p_m1 + b*p_m2 ;
00112            double pder = dp + a * dp_m1 + b*dp_m2 ;
00113            double sum = 0 ;
00114            for (int i=0 ; i<j ; i++)
00115                 sum += 1./(x-coloc[n-i-1]) ;
00116            
00117            double increm = -poly/(pder-sum*poly) ;
00118            
00119            x += increm ;
00120            ite ++ ;
00121            if ((fabs(increm) < prec) || (ite >itemax))
00122                 loop = false ;
00123     }
00124     if (ite > itemax) {
00125         cout << "legendre_poly_der: too many iterations !..." << endl ;
00126         abort() ;
00127     }
00128     coloc[n-j-1] = x ;
00129     double auxi = cs*cd-ss*sd ;
00130     ss = cs*sd+ss*cd ;
00131     cs = auxi ;
00132     }
00133     if  (n%2==1)
00134         coloc[(n-1)/2] = 0 ; 
00135     // Copy of the symetric ones :
00136     for (int i=0 ; i<borne_sup ; i++)
00137          coloc[i] = - coloc[n-i-1] ;
00138     
00139     for (int i=0 ; i<n ; i++) {
00140           legendre_poly_der(n-1, p, dp, p_m1, dp_m1, p_m2, dp_m2, coloc[i]) ;
00141       weight[i] = 2./(n-1)/n/p/p ;
00142     }
00143 }
00144     
00145 

Generated on Tue Dec 6 14:48:44 2011 for POLYNOM by  doxygen 1.4.6