solh.C

00001 /*
00002  *   Copyright (c) 1999-2001 Philippe Grandclement
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 solh_C[] = "$Header: /cvsroot/Lorene/C++/Source/Non_class_members/PDE/solh.C,v 1.8 2008/02/18 13:53:43 j_novak Exp $" ;
00024 
00025 /*
00026  * $Id: solh.C,v 1.8 2008/02/18 13:53:43 j_novak Exp $
00027  * $Log: solh.C,v $
00028  * Revision 1.8  2008/02/18 13:53:43  j_novak
00029  * Removal of special indentation instructions.
00030  *
00031  * Revision 1.7  2007/12/20 09:11:09  jl_cornou
00032  * Correction of an error in op_sxpun about Jacobi(0,2) polynomials
00033  *
00034  * Revision 1.6  2007/12/13 15:48:46  jl_cornou
00035  * *** empty log message ***
00036  *
00037  * Revision 1.5  2007/12/12 12:30:49  jl_cornou
00038  * *** empty log message ***
00039  *
00040  * Revision 1.4  2004/10/05 15:44:21  j_novak
00041  * Minor speed enhancements.
00042  *
00043  * Revision 1.3  2003/01/31 08:49:58  e_gourgoulhon
00044  * Increased the number nmax of stored matrices from 100 to 200.
00045  *
00046  * Revision 1.2  2002/10/16 14:37:12  j_novak
00047  * Reorganization of #include instructions of standard C++, in order to
00048  * use experimental version 3 of gcc.
00049  *
00050  * Revision 1.1.1.1  2001/11/20 15:19:28  e_gourgoulhon
00051  * LORENE
00052  *
00053  * Revision 2.13  2000/01/18  14:15:50  phil
00054  * enleve assert sur nobre de points min en r
00055  *
00056  * Revision 2.12  2000/01/04  18:59:39  phil
00057  * Double nmax
00058  *
00059  * Revision 2.11  1999/10/11  14:29:37  phil
00060  * &-> &&
00061  *
00062  * Revision 2.10  1999/09/30  09:23:25  phil
00063  * remplacement des && en &
00064  *
00065  * Revision 2.9  1999/09/17  15:26:25  phil
00066  * correction definition de NMAX
00067  *
00068  * Revision 2.8  1999/06/23  12:35:00  phil
00069  * *** empty log message ***
00070  *
00071  * Revision 2.7  1999/04/28  10:49:19  phil
00072  * augmentation de nmax a 50
00073  *
00074  * Revision 2.6  1999/04/27  13:12:34  phil
00075  * *** empty log message ***
00076  *
00077  * Revision 2.5  1999/04/19  14:07:02  phil
00078  * *** empty log message ***
00079  *
00080  * Revision 2.4  1999/04/16  13:19:07  phil
00081  * *** empty log message ***
00082  *
00083  * Revision 2.3  1999/04/16  13:17:02  phil
00084  * *** empty log message ***
00085  *
00086  * Revision 2.2  1999/04/14  13:57:05  phil
00087  * Sauvegarde des solutions deja calculees
00088  *
00089  * Revision 2.1  1999/04/07  14:39:23  phil
00090  * esthetique
00091  *
00092  * Revision 2.0  1999/04/07  14:11:18  phil
00093  * *** empty log message ***
00094  *
00095  *
00096  * $Header: /cvsroot/Lorene/C++/Source/Non_class_members/PDE/solh.C,v 1.8 2008/02/18 13:53:43 j_novak Exp $
00097  *
00098  */
00099 
00100 //fichiers includes
00101 #include <stdio.h>
00102 #include <stdlib.h>
00103 #include <math.h>
00104 
00105 #include "proto.h"
00106 #include "matrice.h"
00107 #include "type_parite.h"
00108 
00109 
00110 /*
00111  * 
00112  * Renvoie une ou 2 solutions homogenes
00113  *  Si base_r = R_CHEB deux solutions (x+echelle)^l dans (0, *) et
00114  *              1/(x+echelle)^(l+1) dans (1, *)
00115  *  Si base_r = R_CHEBU 1 solution (x-1)^l+1 dans (*) 
00116  *  Si base_r = R_CHEBP ou R_CHEBI x^l dans (*)
00117  * 
00118  * Entree : 
00119  *  n : nbre de points en r
00120  *  l : nbre quantique associe
00121  *  echelle : cf ci-dessus, utile que dans le cas R_CHEB
00122  *  base_r : base de decomposition
00123  * 
00124  * Sortie :
00125  *  Tbl contenant les coefficient de la ou des solution homogenes
00126  * 
00127  */
00128 
00129         //------------------------------------
00130         // Routine pour les cas non prevus --
00131         //------------------------------------
00132 Tbl _solh_pas_prevu (int n, int l, double echelle) {
00133 
00134     cout << " Solution homogene pas prevue ..... : "<< endl ;
00135     cout << " N : " << n << endl ;
00136     cout << " l : " << l << endl ;
00137     cout << " echelle : " << echelle << endl ;
00138     abort() ;
00139     exit(-1) ;
00140     Tbl res(1) ;
00141     return res;
00142 }
00143     
00144     
00145         //-------------------
00146            //--  R_CHEB   ------
00147           //-------------------
00148 
00149 Tbl _solh_r_cheb (int n, int l, double echelle) {
00150                 
00151    const int nmax = 200 ; // Nombre de Tbl stockes
00152    static Tbl* tab[nmax] ;  // les Tbl calcules
00153    static int nb_dejafait = 0 ; // nbre de Tbl calcules
00154    static int l_dejafait[nmax] ;
00155    static int nr_dejafait[nmax] ;
00156    static double vieux_echelle = 0;
00157    
00158    // Si on a change l'echelle : on detruit tout :
00159    if (vieux_echelle != echelle) {
00160        for (int i=0 ; i<nb_dejafait ; i++) {
00161        l_dejafait[i] = -1 ;
00162        nr_dejafait[i] = -1 ;
00163        delete tab[i] ;
00164        }
00165     nb_dejafait = 0 ;
00166     vieux_echelle = echelle ;
00167    }
00168       
00169    int indice = -1 ;
00170    
00171    // On determine si la matrice a deja ete calculee :
00172    for (int conte=0 ; conte<nb_dejafait ; conte ++)
00173     if ((l_dejafait[conte] == l) && (nr_dejafait[conte] == n))
00174     indice = conte ;
00175     
00176    // Calcul a faire : 
00177    if (indice  == -1) {
00178        if (nb_dejafait >= nmax) {
00179        cout << "_solh_r_cheb : trop de Tbl" << endl ;
00180        abort() ;
00181        exit (-1) ;
00182        }
00183        
00184         
00185     l_dejafait[nb_dejafait] = l ;
00186     nr_dejafait[nb_dejafait] = n ;
00187         
00188   //  assert (l < n) ;
00189     
00190     tab[nb_dejafait] = new Tbl(2, n) ;
00191     Tbl* pres = tab[nb_dejafait] ;
00192     pres->set_etat_qcq() ;
00193     double* coloc = new double[n] ;
00194     
00195     int * deg = new int[3] ;
00196     deg[0] = 1 ; 
00197     deg[1] = 1 ;
00198     deg[2] = n ;
00199     
00200     //Construction de la premiere solution homogene :
00201     // cad celle polynomiale.
00202     
00203     if (l==0) {
00204     pres->set(0, 0) = 1 ;
00205     for (int i=1 ; i<n ; i++)
00206         pres->set(0, i) = 0 ;
00207         }
00208     else {
00209     for (int i=0 ; i<n ; i++)
00210         coloc[i] = pow(echelle-cos(M_PI*i/(n-1)), double(l)) ;
00211     
00212     cfrcheb(deg, deg, coloc, deg, coloc) ;
00213     for (int i=0 ; i<n ;i++)
00214         pres->set(0, i) = coloc[i] ;
00215     }
00216     
00217     
00218     // construction de la seconde solution homogene :
00219     // cad celle fractionnelle.
00220     for (int i=0 ; i<n ; i++)
00221     coloc[i] = 1/pow(echelle-cos(M_PI*i/(n-1)), double(l+1)) ;
00222     
00223     cfrcheb(deg, deg, coloc, deg, coloc) ;
00224     for (int i=0 ; i<n ;i++)
00225     pres->set(1, i) = coloc[i] ;    
00226     
00227     
00228     delete [] coloc ;
00229     delete [] deg ;
00230     indice = nb_dejafait ;
00231     nb_dejafait ++ ;
00232    }
00233    
00234    return *tab[indice] ;
00235 }   
00236     
00237 
00238         //-------------------
00239            //--  R_JACO02 ------
00240           //-------------------
00241 
00242 Tbl _solh_r_jaco02 (int n, int l, double echelle) {
00243                 
00244    const int nmax = 200 ; // Nombre de Tbl stockes
00245    static Tbl* tab[nmax] ;  // les Tbl calcules
00246    static int nb_dejafait = 0 ; // nbre de Tbl calcules
00247    static int l_dejafait[nmax] ;
00248    static int nr_dejafait[nmax] ;
00249    static double vieux_echelle = 0;
00250    
00251    // Si on a change l'echelle : on detruit tout :
00252    if (vieux_echelle != echelle) {
00253        for (int i=0 ; i<nb_dejafait ; i++) {
00254        l_dejafait[i] = -1 ;
00255        nr_dejafait[i] = -1 ;
00256        delete tab[i] ;
00257        }
00258     nb_dejafait = 0 ;
00259     vieux_echelle = echelle ;
00260    }
00261       
00262    int indice = -1 ;
00263    
00264    // On determine si la matrice a deja ete calculee :
00265    for (int conte=0 ; conte<nb_dejafait ; conte ++)
00266     if ((l_dejafait[conte] == l) && (nr_dejafait[conte] == n))
00267     indice = conte ;
00268     
00269    // Calcul a faire : 
00270    if (indice  == -1) {
00271        if (nb_dejafait >= nmax) {
00272        cout << "_solh_r_jaco02 : trop de Tbl" << endl ;
00273        abort() ;
00274        exit (-1) ;
00275        }
00276        
00277         
00278     l_dejafait[nb_dejafait] = l ;
00279     nr_dejafait[nb_dejafait] = n ;
00280         
00281   //  assert (l < n) ;
00282     
00283     tab[nb_dejafait] = new Tbl(2, n) ;
00284     Tbl* pres = tab[nb_dejafait] ;
00285     pres->set_etat_qcq() ;
00286     double* coloc = new double[n] ;
00287     
00288     int * deg = new int[3] ;
00289     deg[0] = 1 ; 
00290     deg[1] = 1 ;
00291     deg[2] = n ;
00292     
00293 
00294     double* zeta = pointsgausslobatto(n-1) ;
00295     //Construction de la premiere solution homogene :
00296     // cad celle polynomiale.
00297     
00298     if (l==0) {
00299     pres->set(0, 0) = 1 ;
00300     for (int i=1 ; i<n ; i++)
00301         pres->set(0, i) = 0 ;
00302         }
00303     else {
00304     for (int i=0 ; i<n ; i++)
00305         coloc[i] = pow((echelle + zeta[i]), double(l)) ;
00306     
00307     cfrjaco02(deg, deg, coloc, deg, coloc) ;
00308     for (int i=0 ; i<n ;i++)
00309         pres->set(0, i) = coloc[i] ;
00310     }
00311     
00312     
00313     // construction de la seconde solution homogene :
00314     // cad celle fractionnelle.
00315     for (int i=0 ; i<n ; i++)
00316     coloc[i] = 1/pow((echelle + zeta[i]), double(l+1)) ;
00317     
00318     cfrjaco02(deg, deg, coloc, deg, coloc) ;
00319     for (int i=0 ; i<n ;i++)
00320     pres->set(1, i) = coloc[i] ;    
00321     
00322     
00323     delete [] coloc ;
00324     delete [] deg ;
00325     indice = nb_dejafait ;
00326     nb_dejafait ++ ;
00327    }
00328    
00329    return *tab[indice] ;
00330 }   
00331 
00332 
00333 
00334         //-------------------
00335            //--  R_CHEBP  ------
00336           //-------------------
00337 
00338 Tbl _solh_r_chebp (int n, int l, double) {
00339    
00340    const int nmax = 200 ; // Nombre de Tbl stockes
00341    static Tbl* tab[nmax] ;  // les Tbl calcules
00342    static int nb_dejafait = 0 ; // nbre de Tbl calcules
00343    static int l_dejafait[nmax] ;
00344    static int nr_dejafait[nmax] ;
00345     
00346    int indice = -1 ;
00347    
00348    // On determine si la matrice a deja ete calculee :
00349    for (int conte=0 ; conte<nb_dejafait ; conte ++)
00350     if ((l_dejafait[conte] == l) && (nr_dejafait[conte] == n))
00351     indice = conte ;
00352     
00353    // Calcul a faire : 
00354    if (indice  == -1) {
00355        if (nb_dejafait >= nmax) {
00356        cout << "_solh_r_chebp : trop de Tbl" << endl ;
00357        abort() ;
00358        exit (-1) ;
00359        }
00360        
00361     
00362     l_dejafait[nb_dejafait] = l ;
00363     nr_dejafait[nb_dejafait] = n ;
00364     
00365     assert (div(l, 2).rem ==0) ;
00366     
00367   //  assert (l < 2*n-1) ;
00368     
00369     tab[nb_dejafait] = new Tbl(n) ;
00370     Tbl* pres = tab[nb_dejafait] ;
00371     pres->set_etat_qcq() ;
00372     double* coloc = new double[n] ;
00373     
00374     int * deg = new int[3] ;
00375     deg[0] = 1 ; 
00376     deg[1] = 1 ;
00377     deg[2] = n ;
00378     
00379     if (l==0) {
00380     pres->set(0) = 1 ;
00381     for (int i=1 ; i<n ; i++)
00382         pres->set(i) = 0 ;
00383         }
00384     else {
00385     for (int i=0 ; i<n ; i++)
00386         coloc[i] = pow(sin(M_PI*i/2/(n-1)), double(l)) ;
00387     
00388     cfrchebp(deg, deg, coloc, deg, coloc) ;
00389     for (int i=0 ; i<n ;i++)
00390         pres->set(i) = coloc[i] ;
00391     }
00392     
00393     delete [] coloc ;
00394     delete [] deg ;
00395     indice = nb_dejafait ;
00396     nb_dejafait ++ ;
00397    }
00398     
00399    return *tab[indice] ;
00400 }
00401     
00402     
00403             //-------------------
00404            //--  R_CHEBI   -----
00405           //-------------------
00406     
00407 Tbl _solh_r_chebi (int n, int l, double) {
00408        
00409    const int nmax = 200 ; // Nombre de Tbl stockes
00410    static Tbl* tab[nmax] ;  // les Tbl calcules
00411    static int nb_dejafait = 0 ; // nbre de Tbl calcules
00412    static int l_dejafait[nmax] ;
00413    static int nr_dejafait[nmax] ;
00414     
00415    int indice = -1 ;
00416    
00417    // On determine si la matrice a deja ete calculee :
00418    for (int conte=0 ; conte<nb_dejafait ; conte ++)
00419     if ((l_dejafait[conte] == l) && (nr_dejafait[conte] == n))
00420     indice = conte ;
00421     
00422    // Calcul a faire : 
00423    if (indice  == -1) {
00424        if (nb_dejafait >= nmax) {
00425        cout << "_solh_r_chebi : trop de Tbl" << endl ;
00426        abort() ;
00427        exit (-1) ;
00428        }
00429        
00430         
00431     l_dejafait[nb_dejafait] = l ;
00432     nr_dejafait[nb_dejafait] = n ;
00433     
00434     
00435     assert (div(l, 2).rem == 1)  ;
00436    // assert (l < 2*n) ;
00437     
00438     tab[nb_dejafait] = new Tbl(n) ;
00439     Tbl* pres = tab[nb_dejafait] ;
00440     pres->set_etat_qcq() ;
00441     double* coloc = new double[n] ;
00442     
00443     int * deg = new int[3] ;
00444     deg[0] = 1 ; 
00445     deg[1] = 1 ;
00446     deg[2] = n ;
00447     
00448     if (l==1) {
00449     pres->set(0) = 1 ;
00450     for (int i=1 ; i<n ; i++)
00451         pres->set(i) = 0 ;
00452         }
00453     else {
00454     for (int i=0 ; i<n ; i++)
00455         coloc[i] = pow(sin(M_PI*i/2/(n-1)), double(l)) ;
00456     
00457     cfrchebi(deg, deg, coloc, deg, coloc) ;
00458     for (int i=0 ; i<n ;i++)
00459         pres->set(i) = coloc[i] ;
00460     }
00461     
00462     delete [] coloc ;
00463     delete [] deg ;
00464     indice = nb_dejafait ;
00465     nb_dejafait ++ ;
00466    }
00467     
00468    return *tab[indice] ;
00469 }
00470     
00471     
00472     
00473             //-------------------
00474            //--  R_CHEBU   -----
00475           //-------------------
00476     
00477 Tbl _solh_r_chebu (int n, int l, double) {
00478            
00479    const int nmax = 200 ; // Nombre de Tbl stockes
00480    static Tbl* tab[nmax] ;  // les Tbl calcules
00481    static int nb_dejafait = 0 ; // nbre de Tbl calcules
00482    static int l_dejafait[nmax] ;
00483    static int nr_dejafait[nmax] ;
00484     
00485    int indice = -1 ;
00486    
00487    // On determine si la matrice a deja ete calculee :
00488    for (int conte=0 ; conte<nb_dejafait ; conte ++)
00489     if ((l_dejafait[conte] == l) && (nr_dejafait[conte] == n))
00490     indice = conte ;
00491     
00492    // Calcul a faire : 
00493    if (indice  == -1) {
00494        if (nb_dejafait >= nmax) {
00495        cout << "_solh_r_chebu : trop de Tbl" << endl ;
00496        abort() ;
00497        exit (-1) ;
00498       }
00499        
00500         
00501     l_dejafait[nb_dejafait] = l ;
00502     nr_dejafait[nb_dejafait] = n ;
00503     
00504     
00505   //  assert (l < n-1) ;
00506     tab[nb_dejafait] = new Tbl(n) ;
00507     Tbl* pres = tab[nb_dejafait] ;
00508     pres->set_etat_qcq() ;
00509     double* coloc = new double[n] ;
00510     
00511     int * deg = new int[3] ;
00512     deg[0] = 1 ; 
00513     deg[1] = 1 ;
00514     deg[2] = n ;
00515     
00516     for (int i=0 ; i<n ; i++)
00517     coloc[i] = pow(-1-cos(M_PI*i/(n-1)), double(l+1)) ;
00518     
00519     cfrcheb(deg, deg, coloc, deg, coloc) ;
00520     for (int i=0 ; i<n ;i++)
00521     pres->set(i) = coloc[i] ;
00522     
00523     delete [] coloc ;
00524     delete [] deg ;
00525     indice = nb_dejafait ;
00526     nb_dejafait ++ ;
00527    }
00528     
00529    return *tab[indice] ;
00530 }
00531     
00532     
00533     
00534     
00535             //-------------------
00536            //--  Fonction   ----
00537           //-------------------
00538           
00539           
00540 Tbl solh(int n, int l, double echelle, int base_r) {
00541 
00542         // Routines de derivation
00543     static Tbl (*solh[MAX_BASE])(int, int, double) ;
00544     static int nap = 0 ;
00545 
00546         // Premier appel
00547     if (nap==0) {
00548     nap = 1 ;
00549     for (int i=0 ; i<MAX_BASE ; i++) {
00550         solh[i] = _solh_pas_prevu ;
00551     }
00552         // Les routines existantes
00553     solh[R_CHEB >> TRA_R] = _solh_r_cheb ;
00554     solh[R_CHEBU >> TRA_R] = _solh_r_chebu ;
00555     solh[R_CHEBP >> TRA_R] = _solh_r_chebp ;
00556     solh[R_CHEBI >> TRA_R] = _solh_r_chebi ;
00557     solh[R_JACO02 >> TRA_R] = _solh_r_jaco02 ;
00558     }
00559     
00560     return solh[base_r](n, l, echelle) ;
00561 }

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