op_dsdphi.C

00001 /*
00002  *   Copyright (c) 1999-2000 Jean-Alain Marck
00003  *   Copyright (c) 1999-2001 Eric Gourgoulhon
00004  *
00005  *   This file is part of LORENE.
00006  *
00007  *   LORENE is free software; you can redistribute it and/or modify
00008  *   it under the terms of the GNU General Public License as published by
00009  *   the Free Software Foundation; either version 2 of the License, or
00010  *   (at your option) any later version.
00011  *
00012  *   LORENE is distributed in the hope that it will be useful,
00013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *   GNU General Public License for more details.
00016  *
00017  *   You should have received a copy of the GNU General Public License
00018  *   along with LORENE; if not, write to the Free Software
00019  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  *
00021  */
00022 
00023 
00024 char op_dsdphi_C[] = "$Header: /cvsroot/Lorene/C++/Source/Non_class_members/Operators/op_dsdphi.C,v 1.4 2006/03/10 12:45:38 j_novak Exp $" ;
00025 
00026 /*
00027  * Ensemble des routines de base pour la derivation par rapport a phi
00028  * (Utilisation interne)
00029  * 
00030  *  void _dsdphi_XXXX(Tbl * t, int & b)
00031  *  t   pointeur sur le Tbl d'entree-sortie
00032  *  b   base spectrale
00033  * 
00034  */
00035 
00036 /*
00037  * $Id: op_dsdphi.C,v 1.4 2006/03/10 12:45:38 j_novak Exp $
00038  * $Log: op_dsdphi.C,v $
00039  * Revision 1.4  2006/03/10 12:45:38  j_novak
00040  * Use of C++-style cast.
00041  *
00042  * Revision 1.3  2003/12/19 16:21:48  j_novak
00043  * Shadow hunt
00044  *
00045  * Revision 1.2  2002/09/09 13:00:40  e_gourgoulhon
00046  * Modification of declaration of Fortran 77 prototypes for
00047  * a better portability (in particular on IBM AIX systems):
00048  * All Fortran subroutine names are now written F77_* and are
00049  * defined in the new file C++/Include/proto_f77.h.
00050  *
00051  * Revision 1.1.1.1  2001/11/20 15:19:29  e_gourgoulhon
00052  * LORENE
00053  *
00054  * Revision 2.8  2000/11/14  15:08:16  eric
00055  * Traitement du cas np=1 dans P_COSSIN_I.
00056  *
00057  * Revision 2.7  2000/10/04  15:54:09  eric
00058  * *** empty log message ***
00059  *
00060  * Revision 2.6  2000/10/04  12:50:38  eric
00061  * Ajout de la base P_COSSIN_I.
00062  *
00063  * Revision 2.5  2000/10/04  11:50:32  eric
00064  * Ajout d' abort() dans le cas non prevu.
00065  *
00066  * Revision 2.4  2000/08/18  13:20:01  eric
00067  * Traitement du cas np = 1.
00068  *
00069  * Revision 2.3  2000/02/24  16:41:03  eric
00070  *  Initialisation a zero du tableau xo avant le calcul.
00071  *
00072  * Revision 2.2  1999/11/15  16:38:03  eric
00073  * Tbl::dim est desormais un Dim_tbl et non plus un Dim_tbl*.
00074  *
00075  * Revision 2.1  1999/02/23  11:36:34  hyc
00076  * *** empty log message ***
00077  *
00078  * Revision 2.0  1999/02/22  17:24:59  hyc
00079  * *** empty log message ***
00080  *
00081  * $Header: /cvsroot/Lorene/C++/Source/Non_class_members/Operators/op_dsdphi.C,v 1.4 2006/03/10 12:45:38 j_novak Exp $
00082  *
00083  */
00084 
00085 // Headers Lorene
00086 #include "tbl.h"
00087 #include "proto_f77.h"
00088 
00089 
00090 // Routine pour les cas non prevus
00091 //--------------------------------
00092 void _dsdphi_pas_prevu(Tbl* , int & b) {
00093     cout << "Unknown phi basis in Mtbl_cf::dsdp() !" << endl ;
00094     cout << " basis: " << hex << b << endl ;
00095     abort() ; 
00096 }
00097 
00098                 //------------------//
00099                 //  cas P_COSSIN    //
00100                 //------------------//
00101                 
00102 void _dsdphi_p_cossin(Tbl* tb, int & )
00103 {
00104 
00105     // Peut-etre rien a faire ?
00106     if (tb->get_etat() == ETATZERO) {
00107     return ;
00108     }
00109     
00110     // Protection
00111     assert(tb->get_etat() == ETATQCQ) ;
00112     
00113     // Pour le confort
00114     int nr = (tb->dim).dim[0] ;     // Nombre
00115     int nt = (tb->dim).dim[1] ;     //   de points
00116     int np = (tb->dim).dim[2] ;     //      physiques REELS
00117     np = np - 2 ;           // Nombre de points physiques
00118     
00119     // Variables statiques
00120     static double* cx = 0 ;
00121     static int np_pre =0 ;
00122 
00123     // Test sur np pour initialisation eventuelle
00124     //#pragma critical (loch_dsdphi_p_cossin)
00125     {
00126     if (np > np_pre) {
00127     np_pre = np ;
00128     cx = reinterpret_cast<double*>(realloc(cx, (np+2) * sizeof(double))) ;
00129     for (int i=0 ; i<np+2 ; i += 2) {
00130         cx[i] = - (i/2) ;
00131         cx[i+1] = (i/2) ;
00132         }
00133     }
00134     }       // Fin de region critique
00135 
00136     // pt. sur le tableau de double resultat
00137     double* xo = new double[(tb->dim).taille] ;
00138     
00139     // Initialisation a zero :
00140     for (int i=0; i<(tb->dim).taille; i++) {
00141     xo[i] = 0 ; 
00142     }
00143     
00144     // On y va...
00145     double* xi = tb->t ;
00146     double* xci = xi ;  // Pointeurs
00147     double* xco = xo ;  //  courants
00148     int k, j ;
00149     
00150     // k = 0: inutile, deviendra k=1
00151     xci += nr*nt ;  // Positionnement
00152     xco += nr*nt ;
00153 
00154     // k = 1: 0
00155     for (j=0 ; j<nr*nt ; j++) {
00156     xco[j] = 0 ;
00157     }   // Fin de la boucle sur r * theta
00158     xci += nr*nt ;  // Positionnement
00159     xco += nr*nt ;
00160     
00161     // 2 =< k <= np-1
00162     for (k=2 ; k<np ; k++) {
00163     for (j=0 ; j<nr*nt ; j++) {
00164         xco[j] = cx[k] * xci[j] ;
00165     }   // Fin de la boucle sur r * theta
00166     xci += nr*nt ;  // Positionnement
00167     xco += nr*nt ;
00168     }   // Fin de la boucle sur phi
00169 
00170     // k = np: inutile, deviendra k=np+1
00171     xci += nr*nt ;  // Positionnement
00172     xco += nr*nt ;
00173 
00174     // k = np+1
00175     for (j=0 ; j<nr*nt ; j++) {
00176     xco[j] = 0 ;
00177     }   // Fin de la boucle sur r * theta
00178     
00179     // Inversion des sinus et cosinus (appel a dswap de BLAS)
00180     int nbr = nr*nt ;
00181     int inc = 1 ;
00182     double* p1 = xo ;
00183     double* p2 = p1 + nr*nt ;
00184     for (k=0 ; k<np+1 ; k +=2, p1 += 2*nr*nt, p2 += 2*nr*nt) {
00185     F77_dswap(&nbr, p1, &inc, p2, &inc) ;
00186     }
00187 
00188     // On remet les choses la ou il faut
00189     delete [] tb->t ;
00190     tb->t = xo ;
00191     
00192     // base de developpement
00193     // inchangee
00194 }
00195 
00196                 //------------------//
00197                 //  cas P_COSSIN_P  //
00198                 //------------------//
00199                 
00200 void _dsdphi_p_cossin_p(Tbl* tb, int & )
00201 {
00202 
00203     // Peut-etre rien a faire ?
00204     if (tb->get_etat() == ETATZERO) {
00205     return ;
00206     }
00207     
00208     // Protection
00209     assert(tb->get_etat() == ETATQCQ) ;
00210     
00211     // Pour le confort
00212     int nr = (tb->dim).dim[0] ;     // Nombre
00213     int nt = (tb->dim).dim[1] ;     //   de points
00214     int np = (tb->dim).dim[2] ;     //      physiques REELS
00215     np = np - 2 ;           // Nombre de points physiques
00216     
00217     // Cas particulier de la symetrie axiale : 
00218     if (np == 1) {
00219     tb->set_etat_zero() ; 
00220     return ; 
00221     }
00222     
00223     // Variables statiques
00224     static double* cx = 0 ;
00225     static int np_pre =0 ;
00226 
00227     // Test sur np pour initialisation eventuelle
00228     //#pragma critical (loch_dsdphi_p_cossin_p)
00229     {
00230     if (np > np_pre) {
00231     np_pre = np ;
00232     cx = reinterpret_cast<double*>(realloc(cx, (np+2) * sizeof(double))) ;
00233     int i ;
00234     for (i=0 ; i<np+2 ; i += 2) {
00235         cx[i] = - (i/2) ;
00236         cx[i+1] = (i/2) ;
00237         }
00238     for (i=0 ; i<np+2 ; i++) {
00239         cx[i] = 2 * cx[i] ;
00240         }
00241     }
00242     }       // Fin de region critique
00243 
00244     // pt. sur le tableau de double resultat
00245     double* xo = new double[(tb->dim).taille] ;
00246     
00247     // Initialisation a zero :
00248     for (int i=0; i<(tb->dim).taille; i++) {
00249     xo[i] = 0 ; 
00250     }
00251     
00252     // On y va...
00253     double* xi = tb->t ;
00254     double* xci = xi ;  // Pointeurs
00255     double* xco = xo ;  //  courants
00256     int k, j ;
00257     
00258     // k = 0: inutile, deviendra k=1
00259     xci += nr*nt ;  // Positionnement
00260     xco += nr*nt ;
00261 
00262     // k = 1: 0
00263     for (j=0 ; j<nr*nt ; j++) {
00264     xco[j] = 0 ;
00265     }   // Fin de la boucle sur r * theta
00266     xci += nr*nt ;  // Positionnement
00267     xco += nr*nt ;
00268     
00269     // 2 =< k <= np-1
00270     for (k=2 ; k<np ; k++) {
00271     for (j=0 ; j<nr*nt ; j++) {
00272         xco[j] = cx[k] * xci[j] ;
00273     }   // Fin de la boucle sur r * theta
00274     xci += nr*nt ;  // Positionnement
00275     xco += nr*nt ;
00276     }   // Fin de la boucle sur phi
00277 
00278     // k = np: inutile, deviendra k=np+1
00279     xci += nr*nt ;  // Positionnement
00280     xco += nr*nt ;
00281 
00282     // k = np+1
00283     for (j=0 ; j<nr*nt ; j++) {
00284     xco[j] = 0 ;
00285     }   // Fin de la boucle sur r * theta
00286     
00287     // Inversion des sinus et cosinus (appel a dswap de BLAS)
00288     int nbr = nr*nt ;
00289     int inc = 1 ;
00290     double* p1 = xo ;
00291     double* p2 = p1 + nr*nt ;
00292     for (k=0 ; k<np+1 ; k +=2, p1 += 2*nr*nt, p2 += 2*nr*nt) {
00293     F77_dswap(&nbr, p1, &inc, p2, &inc) ;
00294     }
00295 
00296     // On remet les choses la ou il faut
00297     delete [] tb->t ;
00298     tb->t = xo ;
00299     
00300     // base de developpement
00301     // inchangee
00302 }
00303 
00304                 //------------------//
00305                 //  cas P_COSSIN_I  //
00306                 //------------------//
00307                 
00308 void _dsdphi_p_cossin_i(Tbl* tb, int & )
00309 {
00310 
00311     // Peut-etre rien a faire ?
00312     if (tb->get_etat() == ETATZERO) {
00313     return ;
00314     }
00315     
00316     // Protection
00317     assert(tb->get_etat() == ETATQCQ) ;
00318     
00319     // Pour le confort
00320     int nr = (tb->dim).dim[0] ;     // Nombre
00321     int nt = (tb->dim).dim[1] ;     //   de points
00322     int np = (tb->dim).dim[2] ;     //      physiques REELS
00323     np = np - 2 ;           // Nombre de points physiques
00324 
00325     int ntnr = nt*nr ;          // increment en phi
00326     
00327     // Cas particulier de la symetrie axiale : 
00328     if (np == 1) {
00329     tb->set_etat_zero() ; 
00330     return ; 
00331     }
00332             
00333     // pt. sur le tableau de double resultat
00334     double* xo = new double[(tb->dim).taille] ;
00335     
00336     // pt. sur le tableau de double entree
00337     const double* xi = tb->t ;
00338     
00339     // k = 0 :  resultat sur cos(phi)
00340     // ------------------------------
00341     
00342     double* xco = xo ;              // coef de cos(phi)
00343     const double* xci = xi + 2*ntnr ;       // coef de sin(phi)
00344     for (int i=0; i<ntnr; i++) {
00345     xco[i] = xci[i] ; 
00346     }
00347 
00348     // k = 1 :  mise a zero
00349     // --------------------
00350     
00351     xco = xo + ntnr ;       
00352     for (int i=0; i<ntnr; i++) {
00353     xco[i] = 0 ; 
00354     }
00355 
00356     // k = 2 :  resultat sur sin(phi)
00357     // ------------------------------
00358     
00359     xco = xo + 2*ntnr ;         // coef de sin(phi)
00360     xci = xi ;              // coef de cos(phi)
00361     for (int i=0; i<ntnr; i++) {
00362     xco[i] = - xci[i] ; 
00363     }
00364 
00365     // k >= 3
00366     // ------
00367     
00368     for (int k=3; k<np; k+=2) {
00369 
00370     // resultat sur cos(k phi) 
00371     // -----------------------
00372     
00373     xco = xo + k*ntnr ;     // coef de cos(k phi) 
00374     xci = xi + (k+1)*ntnr ;     // coef de sin(k phi) 
00375 
00376     for (int i=0; i<ntnr; i++) {
00377         xco[i] = k * xci[i] ; 
00378     }
00379     
00380     // resultat sur sin(k phi) 
00381     // -----------------------
00382     
00383     xco = xo + (k+1)*ntnr ;     // coef de sin(k phi) 
00384     xci = xi + k*ntnr ;     // coef de cos(k phi) 
00385 
00386     for (int i=0; i<ntnr; i++) {
00387         xco[i] = - k * xci[i] ; 
00388     }
00389     
00390     }
00391 
00392     // k = np+1 :  mise a zero
00393     // -----------------------
00394     
00395     xco = xo + (np+1)*ntnr ;        
00396     for (int i=0; i<ntnr; i++) {
00397     xco[i] = 0 ; 
00398     }
00399 
00400     // On remet les choses la ou il faut
00401     // ---------------------------------
00402     delete [] tb->t ;
00403     tb->t = xo ;
00404     
00405     // base de developpement
00406     // inchangee
00407 }

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