lap_cpt_mat.C

00001 /*
00002  *   Copyright (c) 2000-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 lap_cpt_mat_C[] = "$Header: /cvsroot/Lorene/C++/Source/Non_class_members/PDE/lap_cpt_mat.C,v 1.3 2007/06/21 20:06:31 k_taniguchi Exp $" ;
00024 
00025 /*
00026  * $Id: lap_cpt_mat.C,v 1.3 2007/06/21 20:06:31 k_taniguchi Exp $
00027  * $Log: lap_cpt_mat.C,v $
00028  * Revision 1.3  2007/06/21 20:06:31  k_taniguchi
00029  * nmax increased to 200
00030  *
00031  * Revision 1.2  2002/10/16 14:37:11  j_novak
00032  * Reorganization of #include instructions of standard C++, in order to
00033  * use experimental version 3 of gcc.
00034  *
00035  * Revision 1.1.1.1  2001/11/20 15:19:28  e_gourgoulhon
00036  * LORENE
00037  *
00038  * Revision 2.0  2000/03/16  16:23:08  phil
00039  * *** empty log message ***
00040  *
00041  *
00042  * $Header: /cvsroot/Lorene/C++/Source/Non_class_members/PDE/lap_cpt_mat.C,v 1.3 2007/06/21 20:06:31 k_taniguchi Exp $
00043  *
00044  */
00045 
00046 
00047 
00048 
00049 //fichiers includes
00050 #include <stdio.h>
00051 #include <stdlib.h>
00052 
00053 #include "matrice.h"
00054 #include "type_parite.h"
00055 #include "proto.h"
00056 
00057 /*
00058  * Routine renvoyant la matrice de l'operateur (1-x^2)*Laplacien f = s
00059  * Pour  l != 1 le resultat est donne en s est donne en Chebyshev et
00060  * f en Gelerkin (T_i + T_{i+1} pour l pair et (2*i+3)T_i + (2*i+1)T_{i+1} pour 
00061  * l impair.
00062  * Pour l=1 pas de probleme de singularite on reste donc en Chebyshev.
00063  */
00064   
00065 
00066         //-----------------------------------
00067         // Routine pour les cas non prevus --
00068         //-----------------------------------
00069 
00070 Matrice _lap_cpt_mat_pas_prevu(int n, int l) {
00071     cout << "laplacien * (1-r^2/R_0^2) pas prevu..." << endl ;
00072     cout << "n : " << n << endl ;
00073     cout << "l : " << l << endl ;
00074     abort() ;
00075     exit(-1) ;
00076     Matrice res(1, 1) ; // On ne passe jamais ici de toute facon !
00077     return res;
00078 }
00079 
00080 
00081            //-------------------------
00082            //--   CAS R_CHEBP    -----
00083            //--------------------------
00084             
00085 
00086 Matrice _lap_cpt_mat_r_chebp (int n, int l) {
00087  
00088    const int nmax = 200 ;// Nombre de Matrices stockees
00089    static Matrice* tab[nmax] ;  // les matrices calculees
00090    static int nb_dejafait = 0 ; // nbre de matrices calculees
00091    static int l_dejafait[nmax] ;
00092    static int nr_dejafait[nmax] ;
00093     
00094    int indice = -1 ;
00095    
00096    // On determine si la matrice a deja ete calculee :
00097    for (int conte=0 ; conte<nb_dejafait ; conte ++)
00098     if ((l_dejafait[conte] == l) && (nr_dejafait[conte] == n))
00099     indice = conte ;
00100     
00101    // Calcul a faire : 
00102    if (indice  == -1) {
00103        if (nb_dejafait >= nmax) {
00104        cout << "_laplacien_nul_mat_r_chebp : trop de matrices" << endl ;
00105        abort() ;
00106        exit (-1) ;
00107        }
00108        
00109 
00110     l_dejafait[nb_dejafait] = l ;
00111     nr_dejafait[nb_dejafait] = n ;
00112     
00113     Matrice res(n-1, n-1) ;
00114     res.set_etat_qcq() ;
00115     
00116     
00117     double* xdsdx = new double[n] ;
00118     double* x2d2sdx2 = new double[n] ;
00119     double* d2sdx2 = new double[n] ;
00120     double* sxdsdx = new double[n] ;
00121     double* sx2 = new double [n] ;
00122     
00123     for (int i=0 ; i< n-1 ; i++) {
00124     for (int j=0 ; j<n ; j++)
00125         xdsdx[j] = 0 ;
00126     xdsdx[i] = 1 ;
00127     xdsdx[i+1] = 1 ;
00128     xdsdx_1d (n, &xdsdx, R_CHEBP) ;
00129     
00130     
00131     for (int j=0 ; j<n ; j++)
00132     x2d2sdx2[j] = 0 ;
00133     x2d2sdx2[i] = 1 ;
00134     x2d2sdx2[i+1] = 1 ;
00135     
00136     d2sdx2_1d(n, &x2d2sdx2, R_CHEBP) ;
00137     for (int j=0 ; j<n ; j++)
00138     d2sdx2[j] = x2d2sdx2[j] ;
00139     multx2_1d(n, &x2d2sdx2, R_CHEBP) ;
00140     
00141 
00142     for (int j=0 ; j<n ; j++)
00143     sxdsdx[j] = 0 ;
00144     sxdsdx[i] = 1 ;
00145     sxdsdx[i+1] = 1 ;
00146     sxdsdx_1d(n, &sxdsdx, R_CHEBP) ;
00147     
00148     
00149     for (int j=0 ; j<n ; j++)
00150     sx2[j] = 0 ;
00151     sx2[i] = 1 ;
00152     sx2[i+1] = 1 ;
00153     sx2_1d(n, &sx2, R_CHEBP) ;
00154     
00155     for (int j=0 ; j<n-1 ; j++)
00156     res.set(j, i) = (d2sdx2[j] + 2*sxdsdx[j] - l*(l+1)*sx2[j])
00157               - (x2d2sdx2[j]+2*xdsdx[j]) ;
00158     res.set(i, i) += l*(l+1) ;
00159     if (i < n-2)
00160     res.set(i+1, i) += l*(l+1) ;
00161     }
00162     delete [] d2sdx2 ;
00163     delete [] x2d2sdx2 ;
00164     delete [] sxdsdx ;
00165     delete [] xdsdx ;
00166     delete [] sx2 ;
00167     
00168     tab[nb_dejafait] = new Matrice(res) ;
00169     nb_dejafait ++ ;
00170     return res ;
00171     }
00172     else
00173     return *tab[indice] ;
00174 }
00175 
00176 
00177 
00178            //------------------------
00179            //--   CAS R_CHEBI    ----
00180            //------------------------
00181             
00182 
00183 Matrice _lap_cpt_mat_r_chebi (int n, int l) {
00184   
00185    const int nmax = 200 ;// Nombre de Matrices stockees
00186    static Matrice* tab[nmax] ;  // les matrices calculees
00187    static int nb_dejafait = 0 ; // nbre de matrices calculees
00188    static int l_dejafait[nmax] ;
00189    static int nr_dejafait[nmax] ;
00190     
00191    int indice = -1 ;
00192    
00193    // On determine si la matrice a deja ete calculee :
00194    for (int conte=0 ; conte<nb_dejafait ; conte ++)
00195     if ((l_dejafait[conte] == l) && (nr_dejafait[conte] == n))
00196     indice = conte ;
00197     
00198    // Calcul a faire : 
00199    if (indice  == -1) {
00200        if (nb_dejafait >= nmax) {
00201        cout << "_laplacien_nul_mat_r_chebp : trop de matrices" << endl ;
00202        abort() ;
00203        exit (-1) ;
00204        }
00205        
00206 
00207     l_dejafait[nb_dejafait] = l ;
00208     nr_dejafait[nb_dejafait] = n ;
00209     
00210     // Non degenere si l = 1
00211     int taille = (l == 1) ? n : n-1 ;
00212     Matrice res(taille, taille) ;
00213     res.set_etat_qcq() ;
00214     
00215     
00216     double* xdsdx = new double[n] ;
00217     double* x2d2sdx2 = new double[n] ;
00218     double* d2sdx2 = new double[n] ;
00219     double* sxdsdx = new double[n] ;
00220     double* sx2 = new double [n] ;
00221     
00222     int f_un, f_deux ;
00223     
00224     for (int i=0 ; i<taille ; i++) {
00225     
00226     // Gelerkin ou Chebyshev ????
00227     if (taille == n) {
00228     f_un = 1 ;
00229     f_deux = 0 ;
00230     }
00231     else {
00232     f_un = 2*i+3 ;
00233     f_deux = 2*i+1 ;
00234     }
00235     
00236     for (int j=0 ; j<n ; j++)
00237         xdsdx[j] = 0 ;
00238     xdsdx[i] = f_un ;
00239     if (i+1 < n)
00240     xdsdx[i+1] = f_deux ;
00241     xdsdx_1d (n, &xdsdx, R_CHEBI) ;
00242     
00243     
00244     for (int j=0 ; j<n ; j++)
00245     x2d2sdx2[j] = 0 ;
00246     x2d2sdx2[i] = f_un ;
00247     if (i+1 < n)
00248     x2d2sdx2[i+1] = f_deux ;
00249     
00250     d2sdx2_1d(n, &x2d2sdx2, R_CHEBI) ;
00251     for (int j=0 ; j<n ; j++)
00252     d2sdx2[j] = x2d2sdx2[j] ;
00253     multx2_1d(n, &x2d2sdx2, R_CHEBI) ;
00254     
00255 
00256     for (int j=0 ; j<n ; j++)
00257     sxdsdx[j] = 0 ;
00258     sxdsdx[i] = f_un ;
00259     if (i+1 < n)
00260     sxdsdx[i+1] = f_deux ;
00261     sxdsdx_1d(n, &sxdsdx, R_CHEBI) ;
00262     
00263     
00264     for (int j=0 ; j<n ; j++)
00265     sx2[j] = 0 ;
00266     sx2[i] = f_un ;
00267     if (i+1 < n)
00268     sx2[i+1] = f_deux ;
00269     sx2_1d(n, &sx2, R_CHEBI) ;
00270     
00271     for (int j=0 ; j<taille ; j++)
00272     res.set(j, i) = (d2sdx2[j] + 2*sxdsdx[j] - l*(l+1)*sx2[j])
00273               - (x2d2sdx2[j]+2*xdsdx[j]) ;
00274     res.set(i, i) += l*(l+1)*f_un ;
00275     if (i < taille-1)
00276     res.set(i+1, i) += l*(l+1)*f_deux ;
00277     }
00278     delete [] d2sdx2 ;
00279     delete [] x2d2sdx2 ;
00280     delete [] sxdsdx ;
00281     delete [] xdsdx ;
00282     delete [] sx2 ;
00283     
00284     tab[nb_dejafait] = new Matrice(res) ;
00285     nb_dejafait ++ ;
00286     return res ;
00287     }
00288     else
00289     return *tab[indice] ;
00290  
00291 }
00292  
00293          //--------------------------
00294         //- La routine a appeler  ---
00295            //----------------------------
00296 Matrice lap_cpt_mat(int n, int l, int base_r)
00297 {
00298 
00299         // Routines de derivation
00300     static Matrice (*lap_cpt_mat[MAX_BASE])(int, int) ;
00301     static int nap = 0 ;
00302 
00303         // Premier appel
00304     if (nap==0) {
00305     nap = 1 ;
00306     for (int i=0 ; i<MAX_BASE ; i++) {
00307         lap_cpt_mat[i] = _lap_cpt_mat_pas_prevu ;
00308     }
00309         // Les routines existantes
00310     lap_cpt_mat[R_CHEBP >> TRA_R] = _lap_cpt_mat_r_chebp ;
00311     lap_cpt_mat[R_CHEBI >> TRA_R] = _lap_cpt_mat_r_chebi ;
00312     }
00313     
00314     Matrice res(lap_cpt_mat[base_r](n, l)) ;
00315     return res ;
00316 }
00317 

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