op_mult_sp.C

00001 /*
00002  * Sets of routines for multiplication by sin(phi)
00003  * (internal use)
00004  *
00005  *  void _mult_sp_XXXX(Tbl * t, int & b)
00006  *  t   pointer on the Tbl containing the spectral coefficients
00007  *  b   spectral base
00008  *
00009  */
00010 
00011 /*
00012  *   Copyright (c) 2000-2001 Eric Gourgoulhon
00013  *
00014  *   This file is part of LORENE.
00015  *
00016  *   LORENE is free software; you can redistribute it and/or modify
00017  *   it under the terms of the GNU General Public License as published by
00018  *   the Free Software Foundation; either version 2 of the License, or
00019  *   (at your option) any later version.
00020  *
00021  *   LORENE is distributed in the hope that it will be useful,
00022  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00023  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00024  *   GNU General Public License for more details.
00025  *
00026  *   You should have received a copy of the GNU General Public License
00027  *   along with LORENE; if not, write to the Free Software
00028  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00029  *
00030  */
00031 
00032 
00033 char op_mult_sp_C[] = "$Header: /cvsroot/Lorene/C++/Source/Non_class_members/Operators/op_mult_sp.C,v 1.4 2007/12/14 10:19:33 jl_cornou Exp $" ;
00034 
00035 /*
00036  * $Id: op_mult_sp.C,v 1.4 2007/12/14 10:19:33 jl_cornou Exp $
00037  * $Log: op_mult_sp.C,v $
00038  * Revision 1.4  2007/12/14 10:19:33  jl_cornou
00039  * *** empty log message ***
00040  *
00041  * Revision 1.3  2007/10/05 12:37:20  j_novak
00042  * Corrected a few errors in the theta-nonsymmetric case (bases T_COSSIN_C and
00043  * T_COSSIN_S).
00044  *
00045  * Revision 1.2  2004/11/23 15:16:01  m_forot
00046  *
00047  * Added the bases for the cases without any equatorial symmetry
00048  *  (T_COSSIN_C, T_COSSIN_S, T_LEG, R_CHEBPI_P, R_CHEBPI_I).
00049  *
00050  * Revision 1.1.1.1  2001/11/20 15:19:29  e_gourgoulhon
00051  * LORENE
00052  *
00053  * Revision 2.4  2000/11/14  15:12:01  eric
00054  * Traitement du cas np=1
00055  *
00056  * Revision 2.3  2000/09/18  10:14:59  eric
00057  * Ajout des bases P_COSSIN_P et P_COSSIN_I
00058  *
00059  * Revision 2.2  2000/09/12  13:36:38  eric
00060  * Met les bonnes bases meme dans le cas ETATZERO
00061  *
00062  * Revision 2.1  2000/09/12  08:29:11  eric
00063  * Traitement des bases qui dependent de la parite de m
00064  *
00065  * Revision 2.0  2000/09/11  13:53:42  eric
00066  * *** empty log message ***
00067  *
00068  *
00069  * $Header: /cvsroot/Lorene/C++/Source/Non_class_members/Operators/op_mult_sp.C,v 1.4 2007/12/14 10:19:33 jl_cornou Exp $
00070  *
00071  */
00072 
00073 // Headers Lorene
00074 #include "tbl.h"
00075 
00076         //-----------------------------------
00077         //    Routine for unknown cases
00078         //-----------------------------------
00079 
00080 void _mult_sp_pas_prevu(Tbl* , int& base) {
00081     cout << "mult_sp() is not not implemented for the basis " << base << " !"
00082        << endl ;
00083     abort() ;
00084 }
00085 
00086             //----------------
00087             // basis P_COSSIN
00088             //----------------
00089 
00090 void _mult_sp_p_cossin(Tbl* tb, int& base) {
00091     
00092     assert(tb->get_etat() != ETATNONDEF) ;  // Protection
00093 
00094     // The spectral bases in r and theta which depend on the parity of m 
00095     // are changed
00096     // -----------------------------------------------------------------
00097     
00098     int base_r = base & MSQ_R ; 
00099     int base_t = base & MSQ_T ; 
00100     const int base_p = base & MSQ_P ; 
00101     
00102     switch (base_r) {
00103 
00104     case R_CHEBPIM_P : {
00105         base_r = R_CHEBPIM_I ; 
00106         break ; 
00107     }
00108     
00109     case R_CHEBPIM_I : {
00110         base_r = R_CHEBPIM_P ; 
00111         break ;         
00112     }
00113 
00114         case R_CHEBPI_P : {
00115         break ; 
00116     }
00117     
00118     case R_CHEBPI_I : {
00119         break ;         
00120     }  
00121       
00122     case R_CHEB : {
00123         break ; 
00124     }
00125     
00126     case R_JACO02 : {
00127         break ;
00128     }
00129     
00130     case R_CHEBU : {
00131         break ; 
00132     }
00133     
00134     default : {
00135         cout << "_mult_cp_p_cossin : unknown basis in r !" << endl ; 
00136         cout << "  base_r = " << hex << base_r << endl ; 
00137         abort() ; 
00138     }   
00139     }
00140     
00141     switch (base_t) {
00142 
00143     case T_COSSIN_CP : {
00144         base_t = T_COSSIN_SI ; 
00145         break ; 
00146     }
00147     
00148     case T_COSSIN_SI : {
00149         base_t = T_COSSIN_CP ; 
00150         break ; 
00151     }
00152     
00153     case T_COSSIN_CI : {
00154         base_t = T_COSSIN_SP ; 
00155         break ; 
00156     }
00157     
00158     case T_COSSIN_SP : {
00159         base_t = T_COSSIN_CI ; 
00160         break ; 
00161     }
00162       
00163         case T_COSSIN_S : {
00164         base_t = T_COSSIN_C ; 
00165         break ; 
00166     }
00167 
00168     case T_COSSIN_C : {
00169         base_t = T_COSSIN_S ; 
00170         break ; 
00171     }  
00172       
00173     default : {
00174         cout << "_mult_cp_p_cossin : unknown basis in theta !" << endl ; 
00175         cout << "  base_t = " << hex << base_t << endl ; 
00176         abort() ; 
00177     }   
00178     }
00179     
00180     base = base_r | base_t | base_p ; 
00181     
00182 
00183     //----------------------------------
00184     //  Start of computation 
00185     //----------------------------------
00186 
00187     // Nothing to do ? 
00188     if (tb->get_etat() == ETATZERO) {
00189     return ;
00190     }
00191     
00192     assert(tb->get_etat() == ETATQCQ) ; // Protection
00193   
00194     // Number of degrees of freedom
00195     int nr = tb->get_dim(0) ;
00196     int nt = tb->get_dim(1) ;
00197     int np = tb->get_dim(2) - 2 ;
00198     
00199 
00200     // Special case np = 1 (axisymmetry)  --> zero is returned
00201     // ---------------------------------
00202     
00203     if (np==1) {
00204     tb->set_etat_zero() ; 
00205     return ; 
00206     }
00207 
00208 
00209     assert(np >= 4) ; 
00210     
00211     int ntnr = nt*nr ;
00212     
00213     double* const cf = tb->t ;              // input coefficients
00214     double* const resu = new double[ tb->get_taille() ] ;   // final result
00215     double* co = resu ;     // initial position 
00216         
00217     // Case k=0 (m=0)
00218     // --------------
00219     
00220     int q = 3 * ntnr ; 
00221     for (int i=0; i<ntnr; i++) {
00222     co[i] = 0.5 * cf[q + i] ; 
00223     }
00224     co += ntnr ; 
00225     
00226     // Case k = 1 
00227     // ----------
00228     
00229     for (int i=0; i<ntnr; i++) {
00230     co[i] = 0 ; 
00231     }
00232     co += ntnr ; 
00233     
00234     if (np==4) {
00235 
00236     // Case k = 2  for np=4 
00237     // ----------
00238     
00239     for (int i=0; i<ntnr; i++) {
00240         co[i] = 0 ; 
00241     }
00242     co += ntnr ; 
00243     
00244     // Case k = 3  for np=4 
00245     // ----------
00246     
00247     q = 4*ntnr ; 
00248     for (int i=0; i<ntnr; i++) {
00249         co[i] = cf[i] - 0.5 * cf[q+i] ; 
00250     }
00251     co += ntnr ; 
00252         
00253     }
00254     else{
00255 
00256     // Case k = 2  for np>4 
00257     // ----------
00258     
00259     q = 5*ntnr ; 
00260     for (int i=0; i<ntnr; i++) {
00261         co[i] = 0.5 * cf[q+i] ; 
00262     }
00263     co += ntnr ; 
00264     
00265     // Case k = 3 for np>4
00266     // ----------
00267 
00268     q = 4*ntnr ; 
00269     for (int i=0; i<ntnr; i++) {
00270         co[i] = cf[i] - 0.5 * cf[q+i] ; 
00271     }
00272     co += ntnr ; 
00273     
00274     
00275     // Cases 4 <= k <= np-3
00276     // --------------------
00277     
00278     for (int k=4; k<np-2; k+=2) {
00279 
00280         int k1 = k ;    // k1 even
00281         
00282         int q1 = (k1-1)*ntnr ;
00283         int q2 = (k1+3)*ntnr ; 
00284         for (int i=0; i<ntnr; i++) {
00285         co[i] = 0.5 * ( cf[q2+i] - cf[q1+i] ) ; 
00286         }
00287         co += ntnr ; 
00288         k1++ ;      // k1 odd
00289     
00290         q1 = (k1-3)*ntnr ; 
00291         q2 = (k1+1)*ntnr ; 
00292         for (int i=0; i<ntnr; i++) {
00293         co[i] = 0.5 * ( cf[q1+i] - cf[q2+i] ) ; 
00294         }
00295         co += ntnr ; 
00296     }       
00297     
00298     // Case k = np - 2  for np>4
00299     // ---------------
00300     
00301     q = (np-3)*ntnr ; 
00302     for (int i=0; i<ntnr; i++) {
00303         co[i] = - 0.5 * cf[q + i] ; 
00304     }
00305     co += ntnr ; 
00306     
00307     // Case k = np - 1  for np>4
00308     // ---------------
00309     
00310     int q1 = (np-4)*ntnr ; 
00311     int q2 = np*ntnr ; 
00312     for (int i=0; i<ntnr; i++) {
00313         co[i] = 0.5 * ( cf[q1+i] - cf[q2+i] ) ; 
00314     }
00315     co += ntnr ; 
00316         
00317     }  // End of case np > 4
00318     
00319     
00320     // Case k = np
00321     // -----------
00322     
00323     q = (np-1)*ntnr ; 
00324     for (int i=0; i<ntnr; i++) {
00325     co[i] = - 0.5 * cf[q+i] ; 
00326     }
00327     co += ntnr ; 
00328     
00329     // Case k = np+1
00330     // -------------
00331 
00332     for (int i=0; i<ntnr; i++) {
00333     co[i] = 0 ; 
00334     }
00335     
00336     //## verif : 
00337     co += ntnr ;
00338     assert( co == resu + (np+2)*ntnr ) ; 
00339     
00340     
00341     // The result is set to tb :
00342     // ----------------------- 
00343     delete [] tb->t ;
00344     tb->t = resu ;
00345         
00346     return ; 
00347 }
00348 
00349             //------------------
00350             // basis P_COSSIN_P
00351             //------------------
00352 
00353 void _mult_sp_p_cossin_p(Tbl* tb, int& base) {
00354     
00355     assert(tb->get_etat() != ETATNONDEF) ;  // Protection
00356 
00357     // New spectral bases
00358     // ------------------        
00359     int base_r = base & MSQ_R ; 
00360     int base_t = base & MSQ_T ; 
00361     base = base_r | base_t | P_COSSIN_I ; 
00362     
00363     //----------------------------------
00364     //  Start of computation 
00365     //----------------------------------
00366 
00367     // Nothing to do ? 
00368     if (tb->get_etat() == ETATZERO) {
00369     return ;
00370     }
00371     
00372     assert(tb->get_etat() == ETATQCQ) ; // Protection
00373   
00374     // Number of degrees of freedom
00375     int nr = tb->get_dim(0) ;
00376     int nt = tb->get_dim(1) ;
00377     int np = tb->get_dim(2) - 2 ;
00378     
00379     // Special case np = 1 (axisymmetry)  --> zero is returned
00380     // ---------------------------------
00381     
00382     if (np==1) {
00383     tb->set_etat_zero() ; 
00384     return ; 
00385     }
00386 
00387     assert(np >= 4) ; 
00388     
00389     int ntnr = nt*nr ;
00390     
00391     double* const cf = tb->t ;              // input coefficients
00392     double* const resu = new double[ tb->get_taille() ] ;   // final result
00393     double* co = resu ;     // initial position 
00394         
00395     // Case k=0 
00396     // --------
00397     
00398     int q = 3 * ntnr ; 
00399     for (int i=0; i<ntnr; i++) {
00400     co[i] = 0.5 * cf[q + i] ; 
00401     }
00402     co += ntnr ; 
00403     
00404     // Case k = 1 
00405     // ----------
00406     
00407     for (int i=0; i<ntnr; i++) {
00408     co[i] = 0 ; 
00409     }
00410     co += ntnr ; 
00411     
00412     // Case k = 2 
00413     // ----------
00414     
00415     q = 2*ntnr ; 
00416     for (int i=0; i<ntnr; i++) {
00417     co[i] = cf[i] - 0.5 * cf[q+i] ; 
00418     }
00419     co += ntnr ; 
00420     
00421     // Cases 3 <= k <= np-2
00422     // --------------------
00423 
00424     for (int k=3; k<np-1; k+=2) {
00425 
00426         int k1 = k ;    // k1 odd
00427         
00428         int q1 = k1*ntnr ;
00429         int q2 = (k1+2)*ntnr ; 
00430         for (int i=0; i<ntnr; i++) {
00431         co[i] = 0.5 * ( cf[q2+i] - cf[q1+i] ) ; 
00432     }
00433     co += ntnr ; 
00434     k1++ ;      // k1 even
00435     
00436     q1 = (k1-2)*ntnr ; 
00437     q2 = k1*ntnr ; 
00438     for (int i=0; i<ntnr; i++) {
00439         co[i] = 0.5 * ( cf[q1+i] - cf[q2+i] ) ; 
00440     }
00441     co += ntnr ; 
00442     }
00443     
00444     // Case k = np - 1  
00445     // ---------------
00446         
00447     q = (np-1)*ntnr ; 
00448     for (int i=0; i<ntnr; i++) {
00449     co[i] = - 0.5 * cf[q+i] ; 
00450     }
00451     co += ntnr ; 
00452         
00453     // Case k = np
00454     // -----------
00455     
00456     int q1 = (np-2)*ntnr ; 
00457     int q2 = np*ntnr ; 
00458     for (int i=0; i<ntnr; i++) {
00459     co[i] = 0.5 * ( cf[q1+i] - cf[q2+i] ) ;
00460     }
00461     co += ntnr ; 
00462     
00463     // Case k = np+1
00464     // -------------
00465 
00466     for (int i=0; i<ntnr; i++) {
00467     co[i] = 0 ; 
00468     }
00469     
00470     //## verif : 
00471     co += ntnr ;
00472     assert( co == resu + (np+2)*ntnr ) ; 
00473     
00474     
00475     // The result is set to tb :
00476     // ----------------------- 
00477     delete [] tb->t ;
00478     tb->t = resu ;
00479         
00480     return ; 
00481 }
00482 
00483 
00484             //------------------
00485             // basis P_COSSIN_I
00486             //------------------
00487 
00488 void _mult_sp_p_cossin_i(Tbl* tb, int& base) {
00489     
00490     assert(tb->get_etat() != ETATNONDEF) ;  // Protection
00491 
00492     // New spectral bases
00493     // ------------------        
00494     int base_r = base & MSQ_R ; 
00495     int base_t = base & MSQ_T ; 
00496     base = base_r | base_t | P_COSSIN_P ; 
00497     
00498     //----------------------------------
00499     //  Start of computation 
00500     //----------------------------------
00501 
00502     // Nothing to do ? 
00503     if (tb->get_etat() == ETATZERO) {
00504     return ;
00505     }
00506     
00507     assert(tb->get_etat() == ETATQCQ) ; // Protection
00508   
00509     // Number of degrees of freedom
00510     int nr = tb->get_dim(0) ;
00511     int nt = tb->get_dim(1) ;
00512     int np = tb->get_dim(2) - 2 ;
00513     
00514     // Special case np = 1 (axisymmetry)  --> zero is returned
00515     // ---------------------------------
00516     
00517     if (np==1) {
00518     tb->set_etat_zero() ; 
00519     return ; 
00520     }
00521 
00522     assert(np >= 4) ; 
00523     
00524     int ntnr = nt*nr ;
00525     
00526     double* const cf = tb->t ;              // input coefficients
00527     double* const resu = new double[ tb->get_taille() ] ;   // final result
00528     double* co = resu ;     // initial position 
00529         
00530     // Case k=0 
00531     // --------
00532     
00533     int q = 2 * ntnr ; 
00534     for (int i=0; i<ntnr; i++) {
00535     co[i] = 0.5 * cf[q + i] ; 
00536     }
00537     co += ntnr ; 
00538     
00539     // Case k = 1 
00540     // ----------
00541     
00542     for (int i=0; i<ntnr; i++) {
00543     co[i] = 0 ; 
00544     }
00545     co += ntnr ; 
00546     
00547     // Case k = 2 
00548     // ----------
00549     
00550     int q1 = 2*ntnr ; 
00551     int q2 = 4*ntnr ; 
00552     for (int i=0; i<ntnr; i++) {
00553     co[i] = 0.5 * ( cf[q2+i] - cf[q1+i] ) ; 
00554     }
00555     co += ntnr ; 
00556     
00557     // Case k = 3 
00558     // ----------
00559     
00560     q = 3*ntnr ; 
00561     for (int i=0; i<ntnr; i++) {
00562     co[i] = 0.5 * ( cf[i] - cf[q+i] ) ; 
00563     }
00564     co += ntnr ; 
00565     
00566     // Cases 4 <= k <= np-1
00567     // --------------------
00568 
00569     for (int k=4; k<np; k+=2) {
00570 
00571         int k1 = k ;    // k1 even
00572         
00573         q1 = k1*ntnr ;
00574         q2 = (k1+2)*ntnr ; 
00575         for (int i=0; i<ntnr; i++) {
00576         co[i] = 0.5 * ( cf[q2+i] - cf[q1+i] ) ; 
00577     }
00578     co += ntnr ; 
00579     k1++ ;      // k1 odd
00580     
00581     q1 = (k1-2)*ntnr ; 
00582     q2 = k1*ntnr ; 
00583     for (int i=0; i<ntnr; i++) {
00584         co[i] = 0.5 * ( cf[q1+i] - cf[q2+i] ) ; 
00585     }
00586     co += ntnr ; 
00587     }
00588     
00589     // Case k = np
00590     // -----------
00591         
00592     q = np*ntnr ; 
00593     for (int i=0; i<ntnr; i++) {
00594     co[i] = - 0.5 * cf[q+i] ; 
00595     }
00596     co += ntnr ; 
00597             
00598     // Case k = np+1
00599     // -------------
00600 
00601     for (int i=0; i<ntnr; i++) {
00602     co[i] = 0 ; 
00603     }
00604     
00605     //## verif : 
00606     co += ntnr ;
00607     assert( co == resu + (np+2)*ntnr ) ; 
00608     
00609     
00610     // The result is set to tb :
00611     // ----------------------- 
00612     delete [] tb->t ;
00613     tb->t = resu ;
00614         
00615     return ; 
00616 }
00617 

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