op_mult_x.C

00001 /*
00002  *   Copyright (c) 1999-2001 Jerome Novak
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 op_mult_x_C[] = "$Header: /cvsroot/Lorene/C++/Source/Non_class_members/Operators/op_mult_x.C,v 1.4 2008/08/27 11:22:25 j_novak Exp $" ;
00024 
00025 /*
00026  * $Id: op_mult_x.C,v 1.4 2008/08/27 11:22:25 j_novak Exp $
00027  * $Log: op_mult_x.C,v $
00028  * Revision 1.4  2008/08/27 11:22:25  j_novak
00029  * Minor modifications
00030  *
00031  * Revision 1.3  2008/08/27 08:50:10  jl_cornou
00032  * Added Jacobi(0,2) polynomials
00033  *
00034  * Revision 1.2  2004/11/23 15:16:01  m_forot
00035  *
00036  * Added the bases for the cases without any equatorial symmetry
00037  *  (T_COSSIN_C, T_COSSIN_S, T_LEG, R_CHEBPI_P, R_CHEBPI_I).
00038  *
00039  * Revision 1.1.1.1  2001/11/20 15:19:29  e_gourgoulhon
00040  * LORENE
00041  *
00042  * Revision 1.3  2000/09/07  12:49:53  phil
00043  * *** empty log message ***
00044  *
00045  * Revision 1.2  2000/02/24  16:42:18  eric
00046  * Initialisation a zero du tableau xo avant le calcul.
00047  *
00048  * Revision 1.1  1999/11/16  13:37:41  novak
00049  * Initial revision
00050  *
00051  *
00052  * $Header: /cvsroot/Lorene/C++/Source/Non_class_members/Operators/op_mult_x.C,v 1.4 2008/08/27 11:22:25 j_novak Exp $
00053  *
00054  */
00055 
00056 /* 
00057  * Ensemble des routines de base de multiplication par x
00058  * (Utilisation interne)
00059  * 
00060  *  void _mult_x_XXXX(Tbl * t, int & b)
00061  *  t   pointeur sur le Tbl d'entree-sortie
00062  *  b   base spectrale
00063  * 
00064  */
00065  
00066  // Fichier includes
00067 #include "tbl.h"
00068 
00069 
00070         //-----------------------------------
00071         // Routine pour les cas non prevus --
00072         //-----------------------------------
00073 
00074 void _mult_x_pas_prevu(Tbl * tb, int& base) {
00075     cout << "mult_x pas prevu..." << endl ;
00076     cout << "Tbl: " << tb << " base: " << base << endl ;
00077     abort () ;
00078     exit(-1) ;
00079 }
00080 
00081             //-------------
00082             // Identite ---
00083             //-------------
00084 
00085 void _mult_x_identite(Tbl* , int& ) {
00086     return ;
00087 }
00088 
00089             //---------------
00090             // cas R_CHEBP --
00091             //--------------
00092 
00093 void _mult_x_r_chebp(Tbl* tb, int& base)
00094     {
00095     // Peut-etre rien a faire ?
00096     if (tb->get_etat() == ETATZERO) {
00097     int base_t = base & MSQ_T ;
00098     int base_p = base & MSQ_P ;
00099     base = base_p | base_t | R_CHEBI ;
00100     return ;
00101     }
00102     
00103     // Pour le confort
00104     int nr = (tb->dim).dim[0] ;     // Nombre
00105     int nt = (tb->dim).dim[1] ;     //   de points
00106     int np = (tb->dim).dim[2] ;     //      physiques REELS
00107     np = np - 2 ;           // Nombre de points physiques
00108     
00109     // pt. sur le tableau de double resultat
00110     double* xo = new double [tb->get_taille()];
00111     
00112     // Initialisation a zero :
00113     for (int i=0; i<tb->get_taille(); i++) {
00114     xo[i] = 0 ; 
00115     }
00116     
00117     // On y va...
00118     double* xi = tb->t ;
00119     double* xci = xi ;  // Pointeurs
00120     double* xco = xo ;  //  courants
00121 
00122     int borne_phi = np + 1 ; 
00123     if (np == 1) {
00124     borne_phi = 1 ; 
00125     }
00126     
00127     for (int k=0 ; k< borne_phi ; k++)
00128     if (k==1) {
00129         xci += nr*nt ;
00130         xco += nr*nt ;
00131     }
00132     else {
00133     for (int j=0 ; j<nt ; j++) {
00134 
00135         xco[0] = xci[0] + 0.5*xci[1] ;
00136         for (int i = 1 ; i < nr-1 ; i++ ) {
00137         xco[i] = 0.5*(xci[i]+xci[i+1]) ;
00138         }   // Fin de la boucle sur r
00139         xco[nr-1] = 0 ;
00140         
00141         xci += nr ;
00142         xco += nr ;
00143     }   // Fin de la boucle sur theta
00144     }   // Fin de la boucle sur phi
00145     
00146     // On remet les choses la ou il faut
00147     delete [] tb->t ;
00148     tb->t = xo ;
00149     
00150     // base de developpement
00151     // pair -> impair
00152     int base_t = base & MSQ_T ;
00153     int base_p = base & MSQ_P ;
00154     base = base_p | base_t | R_CHEBI ;
00155 
00156 }
00157 
00158             //----------------
00159             // cas R_CHEBI ---
00160             //----------------
00161 
00162 void _mult_x_r_chebi(Tbl* tb, int& base)
00163 {
00164 
00165     // Peut-etre rien a faire ?
00166     if (tb->get_etat() == ETATZERO) {
00167     int base_t = base & MSQ_T ;
00168     int base_p = base & MSQ_P ;
00169     base = base_p | base_t | R_CHEBP ;
00170     return ;
00171     }
00172     
00173     // Pour le confort
00174     int nr = (tb->dim).dim[0] ;     // Nombre
00175     int nt = (tb->dim).dim[1] ;     //   de points
00176     int np = (tb->dim).dim[2] ;     //      physiques REELS
00177     np = np - 2 ;           // Nombre de points physiques
00178     
00179     // pt. sur le tableau de double resultat
00180     double* xo = new double [tb->get_taille()];
00181     
00182     // Initialisation a zero :
00183     for (int i=0; i<tb->get_taille(); i++) {
00184     xo[i] = 0 ; 
00185     }
00186     
00187     // On y va...
00188     double* xi = tb->t ;
00189     double* xci = xi ;  // Pointeurs
00190     double* xco = xo ;  //  courants
00191     
00192     int borne_phi = np + 1 ; 
00193     if (np == 1) {
00194     borne_phi = 1 ; 
00195     }
00196     
00197     for (int k=0 ; k< borne_phi ; k++) 
00198     if (k == 1)  {
00199         xci += nr*nt ;
00200         xco += nr*nt ;
00201         }
00202     else {
00203     for (int j=0 ; j<nt ; j++) {
00204         
00205         xco[0] = 0.5*xci[0] ;
00206         for (int i = 1 ; i < nr-1 ; i++ ) {
00207         xco[i] = (xci[i]+xci[i-1])*0.5 ;
00208         }   // Fin de la premiere boucle sur r
00209         xco[nr-1] = 0.5*xci[nr-2] ;
00210         
00211         xci += nr ;
00212         xco += nr ;
00213     }   // Fin de la boucle sur theta
00214     }   // Fin de la boucle sur phi
00215     
00216     // On remet les choses la ou il faut
00217     delete [] tb->t ;
00218     tb->t = xo ;
00219     
00220     // base de developpement
00221     // impair -> pair
00222     int base_t = base & MSQ_T ;
00223     int base_p = base & MSQ_P ;    
00224     base = base_p | base_t | R_CHEBP ;
00225 }
00226 
00227             //--------------------
00228             // cas R_CHEBPIM_P --
00229             //------------------
00230 
00231 void _mult_x_r_chebpim_p(Tbl* tb, int& base)
00232 {
00233   
00234     // Peut-etre rien a faire ?
00235     if (tb->get_etat() == ETATZERO) {
00236     int base_t = base & MSQ_T ;
00237     int base_p = base & MSQ_P ;
00238     base = base_p | base_t | R_CHEBPIM_I ;
00239     return ;
00240     }
00241     
00242     // Pour le confort
00243     int nr = (tb->dim).dim[0] ;     // Nombre
00244     int nt = (tb->dim).dim[1] ;     //   de points
00245     int np = (tb->dim).dim[2] ;     //      physiques REELS
00246     np = np - 2 ;          
00247    
00248     // pt. sur le tableau de double resultat
00249     double* xo = new double [tb->get_taille()];
00250     
00251     // Initialisation a zero :
00252     for (int i=0; i<tb->get_taille(); i++) {
00253     xo[i] = 0 ; 
00254     }
00255        
00256     
00257     // On y va...
00258     double* xi = tb->t ;
00259     double* xci ;   // Pointeurs
00260     double* xco ;   //  courants
00261     
00262     
00263     // Partie paire
00264     xci = xi ;
00265     xco = xo ;
00266   
00267     int auxiliaire ;
00268     
00269     for (int k=0 ; k<np+1 ; k += 4)  {
00270     
00271     auxiliaire = (k==np) ? 1 : 2 ; // evite de prendre le dernier coef
00272     for (int kmod=0 ; kmod<auxiliaire ; kmod++) {
00273         
00274         
00275         // On evite le sin (0*phi)
00276     
00277     if ((k==0) && (kmod == 1)) { 
00278         xco += nr*nt ;
00279         xci += nr*nt ;
00280         }
00281         
00282     else 
00283         for (int j=0 ; j<nt ; j++) {
00284 
00285           xco[0] = xci[0] + 0.5*xci[1] ;
00286           for (int i = 1 ; i < nr-1 ; i++ ) {
00287             xco[i] = 0.5*(xci[i]+xci[i+1]) ;
00288           } // Fin de la boucle sur r
00289           xco[nr-1] = 0 ;
00290 
00291           xci += nr ; // au
00292           xco += nr ; //    suivant
00293         }   // Fin de la boucle sur theta
00294     }   // Fin de la boucle sur kmod
00295     xci += 2*nr*nt ;    // saute
00296     xco += 2*nr*nt ;    //  2 phis
00297     }   // Fin de la boucle sur phi
00298 
00299     // Partie impaire
00300     xci = xi + 2*nr*nt ;
00301     xco = xo + 2*nr*nt ;
00302     for (int k=2 ; k<np+1 ; k += 4) {
00303     
00304     auxiliaire = (k==np) ? 1 : 2 ; // evite de prendre le dernier coef
00305     for (int kmod=0 ; kmod<auxiliaire ; kmod++) {
00306         for (int j=0 ; j<nt ; j++) {
00307 
00308           xco[0] = 0.5*xci[0] ;
00309           for (int i = 1 ; i < nr-1 ; i++ ) {
00310         xco[i] = (xci[i]+xci[i-1])*0.5 ;
00311           } // Fin de la premiere boucle sur r
00312           xco[nr-1] = 0.5*xci[nr-2] ;
00313         
00314           xci += nr ;
00315           xco += nr ;
00316         }   // Fin de la boucle sur theta
00317     }   // Fin de la boucle sur kmod
00318     xci += 2*nr*nt ;
00319     xco += 2*nr*nt ;
00320     }   // Fin de la boucle sur phi
00321     
00322     // On remet les choses la ou il faut
00323     delete [] tb->t ;
00324     tb->t = xo ;
00325     
00326     // base de developpement
00327     // (pair,impair) -> (impair,pair)
00328     int base_t = base & MSQ_T ;
00329     int base_p = base & MSQ_P ;
00330     base = base_p | base_t | R_CHEBPIM_I ;
00331 }
00332 
00333             //-------------------
00334             // cas R_CHEBPIM_I --
00335             //-------------------
00336 
00337 void _mult_x_r_chebpim_i(Tbl* tb, int& base)
00338 {
00339 
00340    // Peut-etre rien a faire ?
00341     if (tb->get_etat() == ETATZERO) {
00342     int base_t = base & MSQ_T ;
00343     int base_p = base & MSQ_P ;
00344     base = base_p | base_t | R_CHEBPIM_P ;
00345     return ;
00346     }
00347     
00348     // Pour le confort
00349     int nr = (tb->dim).dim[0] ;     // Nombre
00350     int nt = (tb->dim).dim[1] ;     //   de points
00351     int np = (tb->dim).dim[2] ;     //      physiques REELS
00352     np = np - 2 ;          
00353    
00354     // pt. sur le tableau de double resultat
00355     double* xo = new double [tb->get_taille()];
00356     
00357     // Initialisation a zero :
00358     for (int i=0; i<tb->get_taille(); i++) {
00359     xo[i] = 0 ; 
00360     }
00361     
00362     // On y va...
00363     double* xi = tb->t ;
00364     double* xci ;   // Pointeurs
00365     double* xco ;   //  courants
00366     
00367     // Partie impaire
00368     xci = xi ;
00369     xco = xo ;
00370     
00371       
00372     int auxiliaire ;
00373     
00374     for (int k=0 ; k<np+1 ; k += 4)  {
00375     
00376     auxiliaire = (k==np) ? 1 : 2 ; // evite de prendre le dernier coef
00377     for (int kmod=0 ; kmod<auxiliaire ; kmod++) {
00378         
00379         
00380         // On evite le sin (0*phi)
00381     
00382     if ((k==0) && (kmod == 1)) { 
00383         xco += nr*nt ;
00384         xci += nr*nt ;
00385         }
00386         
00387     else 
00388       for (int j=0 ; j<nt ; j++) {
00389 
00390         xco[0] = 0.5*xci[0] ;
00391         for (int i = 1 ; i < nr-1 ; i++ ) {
00392           xco[i] = (xci[i]+xci[i-1])*0.5 ;
00393         }   // Fin de la premiere boucle sur r
00394         xco[nr-1] = 0.5*xci[nr-2] ;
00395         
00396         xci += nr ;
00397         xco += nr ;
00398       }   // Fin de la boucle sur theta
00399     }   // Fin de la boucle sur kmod
00400     xci += 2*nr*nt ;
00401     xco += 2*nr*nt ;
00402     }   // Fin de la boucle sur phi
00403 
00404     // Partie paire
00405     xci = xi + 2*nr*nt ;
00406     xco = xo + 2*nr*nt ;
00407     for (int k=2 ; k<np+1 ; k += 4) {
00408     
00409       auxiliaire = (k==np) ? 1 : 2 ; // evite de prendre le dernier coef
00410       for (int kmod=0 ; kmod<auxiliaire ; kmod++) {
00411     for (int j=0 ; j<nt ; j++) {
00412       
00413       xco[0] = xci[0] + 0.5*xci[1] ;
00414       for (int i = 1 ; i < nr-1 ; i++ ) {
00415         xco[i] = 0.5*(xci[i]+xci[i+1]) ;
00416       } // Fin de la boucle sur r
00417       xco[nr-1] = 0 ;
00418       
00419       xci += nr ;
00420       xco += nr ;
00421     }   // Fin de la boucle sur theta
00422       }   // Fin de la boucle sur kmod
00423       xci += 2*nr*nt ;
00424       xco += 2*nr*nt ;
00425     }   // Fin de la boucle sur phi
00426     
00427     // On remet les choses la ou il faut
00428     delete [] tb->t ;
00429     tb->t = xo ;
00430     
00431     // base de developpement
00432     // (impair,pair) -> (pair,impair)
00433     int base_t = base & MSQ_T ;
00434     int base_p = base & MSQ_P ;
00435     base = base_p | base_t | R_CHEBPIM_P ;
00436 }
00437 
00438             //---------------
00439             // cas R_CHEBPI_P --
00440             //--------------
00441 
00442 void _mult_x_r_chebpi_p(Tbl* tb, int& base)
00443     {
00444     // Peut-etre rien a faire ?
00445     if (tb->get_etat() == ETATZERO) {
00446     int base_t = base & MSQ_T ;
00447     int base_p = base & MSQ_P ;
00448     base = base_p | base_t | R_CHEBPI_I ;
00449     return ;
00450     }
00451     
00452     // Pour le confort
00453     int nr = (tb->dim).dim[0] ;     // Nombre
00454     int nt = (tb->dim).dim[1] ;     //   de points
00455     int np = (tb->dim).dim[2] ;     //      physiques REELS
00456     np = np - 2 ;           // Nombre de points physiques
00457     
00458     // pt. sur le tableau de double resultat
00459     double* xo = new double [tb->get_taille()];
00460     
00461     // Initialisation a zero :
00462     for (int i=0; i<tb->get_taille(); i++) {
00463     xo[i] = 0 ; 
00464     }
00465     
00466     // On y va...
00467     double* xi = tb->t ;
00468     double* xci = xi ;  // Pointeurs
00469     double* xco = xo ;  //  courants
00470 
00471     int borne_phi = np + 1 ; 
00472     if (np == 1) {
00473     borne_phi = 1 ; 
00474     }
00475     
00476     for (int k=0 ; k< borne_phi ; k++)
00477     if (k==1) {
00478         xci += nr*nt ;
00479         xco += nr*nt ;
00480     }
00481     else {
00482     for (int j=0 ; j<nt ; j++) {
00483         int  l = j%2 ;
00484         if(l==0){
00485           xco[0] = xci[0] + 0.5*xci[1] ;
00486           for (int i = 1 ; i < nr-1 ; i++ ) {
00487         xco[i] = 0.5*(xci[i]+xci[i+1]) ;
00488           } // Fin de la boucle sur r
00489           xco[nr-1] = 0 ;
00490         } else {
00491           xco[0] = 0.5*xci[0] ;
00492           for (int i = 1 ; i < nr-1 ; i++ ) {
00493         xco[i] = (xci[i]+xci[i-1])*0.5 ;
00494           } // Fin de la premiere boucle sur r
00495           xco[nr-1] = 0.5*xci[nr-2] ;
00496         }
00497         xci += nr ;
00498         xco += nr ;
00499     }   // Fin de la boucle sur theta
00500     }   // Fin de la boucle sur phi
00501     
00502     // On remet les choses la ou il faut
00503     delete [] tb->t ;
00504     tb->t = xo ;
00505     
00506     // base de developpement
00507     // pair -> impair
00508     int base_t = base & MSQ_T ;
00509     int base_p = base & MSQ_P ;
00510     base = base_p | base_t | R_CHEBPI_I ;
00511 
00512 }
00513 
00514             //----------------
00515             // cas R_CHEBPI_I ---
00516             //----------------
00517 
00518 void _mult_x_r_chebpi_i(Tbl* tb, int& base)
00519 {
00520 
00521     // Peut-etre rien a faire ?
00522     if (tb->get_etat() == ETATZERO) {
00523     int base_t = base & MSQ_T ;
00524     int base_p = base & MSQ_P ;
00525     base = base_p | base_t | R_CHEBPI_P ;
00526     return ;
00527     }
00528     
00529     // Pour le confort
00530     int nr = (tb->dim).dim[0] ;     // Nombre
00531     int nt = (tb->dim).dim[1] ;     //   de points
00532     int np = (tb->dim).dim[2] ;     //      physiques REELS
00533     np = np - 2 ;           // Nombre de points physiques
00534     
00535     // pt. sur le tableau de double resultat
00536     double* xo = new double [tb->get_taille()];
00537     
00538     // Initialisation a zero :
00539     for (int i=0; i<tb->get_taille(); i++) {
00540     xo[i] = 0 ; 
00541     }
00542     
00543     // On y va...
00544     double* xi = tb->t ;
00545     double* xci = xi ;  // Pointeurs
00546     double* xco = xo ;  //  courants
00547     
00548     int borne_phi = np + 1 ; 
00549     if (np == 1) {
00550     borne_phi = 1 ; 
00551     }
00552     
00553     for (int k=0 ; k< borne_phi ; k++) 
00554     if (k == 1)  {
00555         xci += nr*nt ;
00556         xco += nr*nt ;
00557         }
00558     else {
00559     for (int j=0 ; j<nt ; j++) {
00560         int  l = j%2 ;
00561         if(l==1){
00562           xco[0] = xci[0] + 0.5*xci[1] ;
00563           for (int i = 1 ; i < nr-1 ; i++ ) {
00564         xco[i] = 0.5*(xci[i]+xci[i+1]) ;
00565           } // Fin de la boucle sur r
00566           xco[nr-1] = 0 ;
00567         } else {
00568           xco[0] = 0.5*xci[0] ;
00569           for (int i = 1 ; i < nr-1 ; i++ ) {
00570         xco[i] = (xci[i]+xci[i-1])*0.5 ;
00571           } // Fin de la premiere boucle sur r
00572           xco[nr-1] = 0.5*xci[nr-2] ;
00573         }
00574         xci += nr ;
00575         xco += nr ;
00576     }   // Fin de la boucle sur theta
00577     }   // Fin de la boucle sur phi
00578     
00579     // On remet les choses la ou il faut
00580     delete [] tb->t ;
00581     tb->t = xo ;
00582     
00583     // base de developpement
00584     // impair -> pair
00585     int base_t = base & MSQ_T ;
00586     int base_p = base & MSQ_P ;    
00587     base = base_p | base_t | R_CHEBPI_P ;
00588 }
00589 
00590             //---------------
00591             // cas R_JACO02 -
00592             //---------------
00593 
00594 void _mult_x_r_jaco02(Tbl* tb, int&)
00595     {
00596     // Peut-etre rien a faire ?
00597     if (tb->get_etat() == ETATZERO) {
00598     return ;
00599     }
00600     
00601     // Pour le confort
00602     int nr = (tb->dim).dim[0] ;     // Nombre
00603     int nt = (tb->dim).dim[1] ;     //   de points
00604     int np = (tb->dim).dim[2] ;     //      physiques REELS
00605     np = np - 2 ;           // Nombre de points physiques
00606     
00607     // pt. sur le tableau de double resultat
00608     double* xo = new double [tb->get_taille()];
00609     
00610     // Initialisation a zero :
00611     for (int i=0; i<tb->get_taille(); i++) {
00612     xo[i] = 0 ; 
00613     }
00614     
00615     // On y va...
00616     double* xi = tb->t ;
00617     double* xci = xi ;  // Pointeurs
00618     double* xco = xo ;  //  courants
00619 
00620     int borne_phi = np + 1 ; 
00621     if (np == 1) {
00622     borne_phi = 1 ; 
00623     }
00624     
00625     for (int k=0 ; k< borne_phi ; k++)
00626     if (k==1) {
00627         xci += nr*nt ;
00628         xco += nr*nt ;
00629     }
00630     else {
00631     for (int j=0 ; j<nt ; j++) {
00632 
00633             xco[0] = 1.5*xci[0] + 0.3*xci[1] ;
00634             for (int i = 1 ; i < nr-1 ; i++) {
00635         xco[i] = i*(i+2)/double((i+1)*(2*i+1))*xci[i-1] + (i*i+3*i+3)/double((i+1)*(i+2))*xci[i] + (i+1)*(i+3)/double((i+2)*(2*i+5))*xci[i+1] ;
00636             }
00637             xco[nr-1] = (nr*nr-1)/double((nr)*(2*nr-1))*xci[nr-2] + (1+1/double((nr)*(nr+1)))*xci[nr-1] ;
00638         
00639         xci += nr ;
00640         xco += nr ;
00641     }   // Fin de la boucle sur theta
00642     }   // Fin de la boucle sur phi
00643     
00644     // On remet les choses la ou il faut
00645     delete [] tb->t ;
00646     tb->t = xo ;
00647     
00648     // base de developpement
00649     // inchangée
00650 
00651 }
00652 

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