gval_from_spectral.C

00001 /*
00002  *  Functions for spectral summation to a Valencia-type grid (see grille_val.h)
00003  *
00004  */
00005 
00006 /*
00007  *   Copyright (c) 2001 and 2004 Jerome Novak
00008  *
00009  *   This file is part of LORENE.
00010  *
00011  *   LORENE is free software; you can redistribute it and/or modify
00012  *   it under the terms of the GNU General Public License version 2
00013  *   as published by the Free Software Foundation.
00014  *
00015  *   LORENE is distributed in the hope that it will be useful,
00016  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *   GNU General Public License for more details.
00019  *
00020  *   You should have received a copy of the GNU General Public License
00021  *   along with LORENE; if not, write to the Free Software
00022  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  *
00024  */
00025 
00026 char gval_from_spectral_C[] = "$Header: /cvsroot/Lorene/C++/Source/Valencia/gval_from_spectral.C,v 1.12 2009/10/28 13:40:23 j_novak Exp $" ;
00027 
00028 
00029 /*
00030  * $Id: gval_from_spectral.C,v 1.12 2009/10/28 13:40:23 j_novak Exp $
00031  * $Log: gval_from_spectral.C,v $
00032  * Revision 1.12  2009/10/28 13:40:23  j_novak
00033  * General case for the theta symmetry (now should work).
00034  *
00035  * Revision 1.11  2009/10/21 13:19:04  j_novak
00036  * Going back (temporary) to previous version.
00037  *
00038  * Revision 1.9  2007/12/21 10:46:29  j_novak
00039  * In "from_spectral..." functions: better treatment of ETATZERO case.
00040  *
00041  * Revision 1.8  2007/11/02 16:49:12  j_novak
00042  * Suppression of intermediate array for spectral summation.
00043  *
00044  * Revision 1.7  2006/10/02 07:41:03  j_novak
00045  * Corrected an error in the case r=0, when exporting to a cartesian grid.
00046  *
00047  * Revision 1.6  2005/06/23 13:44:18  j_novak
00048  * Removed some old comments.
00049  *
00050  * Revision 1.5  2005/06/23 13:40:08  j_novak
00051  * The tests on the number of dimensions have been changed to handle better the
00052  * axisymmetric case.
00053  *
00054  * Revision 1.4  2005/06/22 09:11:17  lm_lin
00055  *
00056  * Grid wedding: convert from the old C++ object "Cmp" to "Scalar".
00057  *
00058  * Revision 1.3  2004/12/17 13:35:04  m_forot
00059  * Add the case T_LEG
00060  *
00061  * Revision 1.2  2004/05/07 13:19:24  j_novak
00062  * Prevention of warnings
00063  *
00064  * Revision 1.1  2004/05/07 12:32:13  j_novak
00065  * New summation from spectral to FD grid. Much faster!
00066  *
00067  *
00068  * $Header: /cvsroot/Lorene/C++/Source/Valencia/gval_from_spectral.C,v 1.12 2009/10/28 13:40:23 j_novak Exp $
00069  *
00070  */
00071 
00072 #include<math.h>
00073 
00074 // Lorene headers
00075 #include "grille_val.h"
00076 #include "proto_f77.h"
00077 
00078 
00079                  //--------------------------------------
00080                  // Sommation depuis une grille spectrale
00081                  //--------------------------------------
00082 
00083 void Grille_val::somme_spectrale1(const Scalar& meudon, double* resu, int taille_in) const {
00084 
00085   int taille = dim.dim[0]+2*nfantome ;
00086   if (taille != taille_in) {
00087       cout << "Gval_spher::somme_spectral2():\n" ;
00088       cout << "grid size incompatible with array size... exiting!" << endl ;
00089       abort() ;
00090   }
00091   int nrv = dim.dim[0]+nfantome ;
00092   const Map& mp = meudon.get_mp() ;
00093   int l ;
00094   double xi ;
00095   for (int i=0; i<nfantome; i++) resu[i] = 0 ;
00096   for (int i=nfantome; i<nrv; i++) {
00097     mp.val_lx(zr->t[i],0.,0.,l,xi) ;
00098     resu[i] = meudon.get_spectral_va().val_point_jk(l, xi, 0, 0) ;
00099   }
00100   for (int i=nrv; i<taille; i++) resu[i] = 0 ;
00101 }
00102  
00103 void Gval_cart::somme_spectrale2(const Scalar& meudon, double* resu, int taille_in) const {
00104   int nzv = dim.dim[0] + nfantome ;
00105   int nxv = dim.dim[1] + nfantome ;
00106   int nzv2 = dim.dim[0] + 2*nfantome ;
00107   int nxv2 = dim.dim[1] + 2*nfantome ;
00108   int taille = nxv2*nzv2 ;
00109   if (taille != taille_in) {
00110       cout << "Gval_spher::somme_spectral2():\n" ;
00111       cout << "grid size incompatible with array size... exiting!" << endl ;
00112       abort() ;
00113   }
00114   const Map& mp = meudon.get_mp() ;
00115   int l ;
00116   double xi0, rr, theta ;
00117   double phi = 0 ;
00118   int inum = 0 ;
00119   for (int ix=0; ix<nfantome; ix++) {
00120     for (int iz=0; iz<nzv2; iz++) {
00121       resu[inum] = 0. ;
00122       inum++ ;
00123     }
00124   }
00125   for (int ix=nfantome; ix<nxv; ix++) {
00126     for (int iz=0; iz<nfantome; iz++) {
00127       resu[inum] = 0. ;
00128       inum++ ;
00129     }
00130     double xx2 = (x->t[ix])*(x->t[ix]) ;
00131     for (int iz=nfantome; iz<nzv; iz++) {
00132       rr = sqrt((zr->t[iz])*(zr->t[iz]) + xx2) ;
00133       theta = (rr != 0. ? acos((zr->t[iz])/rr) : 0) ;
00134       mp.val_lx(rr, theta, phi, l, xi0) ;
00135       resu[inum] = meudon.get_spectral_va().val_point(l, xi0, theta, phi) ;
00136       inum++ ;
00137     }
00138     for (int iz=nzv; iz<nzv2; iz++) {
00139       resu[inum] = 0. ;
00140       inum++ ;
00141     }
00142   }
00143   for (int ix=nxv; ix<nxv2; ix++) {
00144     for (int iz=0; iz<nzv2; iz++) {
00145       resu[inum] = 0. ;
00146       inum++ ;
00147     }
00148   }  
00149 }
00150 
00151 void Gval_cart::somme_spectrale3(const Scalar& meudon, double* resu, int taille_in) const{
00152   int nzv = dim.dim[0] + nfantome ;
00153   int nxv = dim.dim[1] + nfantome ;
00154   int nyv = dim.dim[2] + nfantome ;
00155   int nzv2 = dim.dim[0] + 2*nfantome ;
00156   int nxv2 = dim.dim[1] + 2*nfantome ;
00157   int nyv2 = dim.dim[2] + 2*nfantome ;
00158   int taille = nyv2*nxv2*nzv2 ;
00159   if (taille != taille_in) {
00160       cout << "Gval_spher::somme_spectral2():\n" ;
00161       cout << "grid size incompatible with array size... exiting!" << endl ;
00162       abort() ;
00163   }
00164   const Map& mp = meudon.get_mp() ;
00165   int l ;
00166   double xi0, rr, theta, phi ;
00167   int inum = 0 ;
00168   for (int iy=0; iy<nfantome; iy++) {
00169     for (int ix=0; ix<nxv2; ix++) {
00170       for (int iz=0; iz<nzv2; iz++){
00171     resu[inum] = 0. ;
00172     inum++ ;
00173       }
00174     }
00175   }
00176   for (int iy=nfantome; iy<nyv; iy++) { 
00177     double yy = x->t[iy] ;
00178     double yy2 = yy*yy ;
00179     for (int ix=0; ix<nfantome; ix++) {
00180       for (int iz=0; iz<nzv2; iz++) {
00181     resu[inum] = 0. ;
00182     inum++ ;
00183       }
00184     }
00185     for (int ix=nfantome; ix<nxv; ix++) {
00186       for (int iz=0; iz<nfantome; iz++) {
00187     resu[inum] = 0. ;
00188     inum++ ;
00189       }
00190       double xx = x->t[ix] ;
00191       double xx2 = xx*xx ;
00192       for (int iz=nfantome; iz<nzv; iz++) {
00193     rr = sqrt((zr->t[iz])*(zr->t[iz]) + xx2 + yy2) ;
00194     theta = (rr != 0. ? acos((zr->t[iz])/rr) : 0. );
00195     phi = (rr != 0. ? atan2(yy, xx) : 0. ) ; // return value in [-M_PI,M_PI], should work
00196     mp.val_lx(rr, theta, phi, l, xi0) ;
00197     resu[inum] = meudon.get_spectral_va().val_point(l, xi0, theta, phi) ;
00198     inum++ ;
00199       }
00200       for (int iz=nzv; iz<nzv2; iz++) {
00201     resu[inum] = 0. ;
00202     inum++ ;
00203       }
00204     }
00205     for (int ix=nxv; ix<nxv2; ix++) {
00206       for (int iz=0; iz<nzv2; iz++) {
00207     resu[inum] = 0. ;
00208     inum++ ;
00209       }
00210     }  
00211   }
00212   for (int iy=nyv; iy<nyv2; iy++) {
00213     for (int ix=0; ix<nxv2; ix++) {
00214       for (int iz=0; iz<nzv2; iz++){
00215     resu[inum] = 0. ;
00216     inum++ ;
00217       }
00218     }
00219   }
00220 }
00221 
00222 void Gval_spher::somme_spectrale2(const Scalar& meudon, double* resu, int taille_in) const {
00223 
00224     assert (dim.ndim >=2) ;
00225   int nrv = dim.dim[0] + nfantome ;
00226   int ntv = dim.dim[1] + nfantome ;
00227   int nrv2 = dim.dim[0] + 2*nfantome ;
00228   int ntv2 = dim.dim[1] + 2*nfantome ;
00229   int taille = ntv2*nrv2 ;
00230   if (taille != taille_in) {
00231       cout << "Gval_spher::somme_spectral2():\n" ;
00232       cout << "grid size incompatible with array size... exiting!" << endl ;
00233       abort() ;
00234   }
00235   const Map& mp = meudon.get_mp() ;
00236   int l ;
00237   double xi, rr, theta ;
00238   double phi0 = 0 ;
00239   int inum = 0 ;
00240   for (int it=0; it<nfantome; it++) {
00241     for (int ir=0; ir<nrv2; ir++) {
00242       resu[inum] = 0. ;
00243       inum++ ;
00244     }
00245   }
00246   for (int it=nfantome; it<ntv; it++) {
00247     for (int ir=0; ir<nfantome; ir++) {
00248       resu[inum] = 0. ;
00249       inum++ ;
00250     }
00251     theta = tet->t[it] ;
00252     for (int ir=nfantome; ir<nrv; ir++) {
00253       rr = zr->t[ir] ;
00254       mp.val_lx(rr, theta, phi0, l, xi) ;
00255       resu[inum] = meudon.get_spectral_va().val_point(l, xi, theta, phi0) ;
00256       inum++ ;
00257     }
00258     for (int ir=nrv; ir<nrv2; ir++) {
00259       resu[inum] = 0. ;
00260       inum++ ;
00261     }
00262   }
00263   for (int it=ntv; it<ntv2; it++) {
00264     for (int ir=0; ir<nrv2; ir++) {
00265       resu[inum] = 0. ;
00266       inum++ ;
00267     }
00268   }  
00269 }
00270 
00271 double* Gval_spher::somme_spectrale2ri(const Scalar& meudon) const {
00272   int nrv = dim.dim[0] + 1 + nfantome ;
00273   int ntv = dim.dim[1] + nfantome ;
00274   int nrv2 = dim.dim[0] + 1 + 2*nfantome ;
00275   int ntv2 = dim.dim[1] + 2*nfantome ;
00276   int taille = ntv2*nrv2 ;
00277   const Map& mp = meudon.get_mp() ;
00278   double* resu = new double[taille] ;
00279   int l ;
00280   double xi, rr, theta ;
00281   double phi0 = 0 ;
00282   int inum = 0 ;
00283   for (int it=0; it<nfantome; it++) {
00284     for (int ir=0; ir<nrv2; ir++) {
00285       resu[inum] = 0. ;
00286       inum++ ;
00287     }
00288   }
00289   for (int it=nfantome; it<ntv; it++) {
00290     for (int ir=0; ir<nfantome; ir++) {
00291       resu[inum] = 0. ;
00292       inum++ ;
00293     }
00294     theta = tet->t[it] ;
00295     for (int ir=nfantome; ir<nrv; ir++) {
00296       rr = zri->t[ir] ;
00297       mp.val_lx(rr, theta, phi0, l, xi) ;
00298       resu[inum] = meudon.get_spectral_va().val_point(l, xi, theta, phi0) ;
00299       inum++ ;
00300     }
00301     for (int ir=nrv; ir<nrv2; ir++) {
00302       resu[inum] = 0. ;
00303       inum++ ;
00304     }
00305   }
00306   for (int it=ntv; it<ntv2; it++) {
00307     for (int ir=0; ir<nrv2; ir++) {
00308       resu[inum] = 0. ;
00309       inum++ ;
00310     }
00311   }  
00312   return resu ;
00313 }
00314 
00315 double* Gval_spher::somme_spectrale2ti(const Scalar& meudon) const {
00316   int nrv = dim.dim[0] + nfantome ;
00317   int ntv = dim.dim[1] + 1 + nfantome ;
00318   int nrv2 = dim.dim[0] + 2*nfantome ;
00319   int ntv2 = dim.dim[1] + 1 + 2*nfantome ;
00320   int taille = ntv2*nrv2 ;
00321   const Map& mp = meudon.get_mp() ;
00322   double* resu = new double[taille] ;
00323   int l ;
00324   double xi, rr, theta ;
00325   double phi0 = 0 ;
00326   int inum = 0 ;
00327   for (int it=0; it<nfantome; it++) {
00328     for (int ir=0; ir<nrv2; ir++) {
00329       resu[inum] = 0. ;
00330       inum++ ;
00331     }
00332   }
00333   for (int it=nfantome; it<ntv; it++) {
00334     for (int ir=0; ir<nfantome; ir++) {
00335       resu[inum] = 0. ;
00336       inum++ ;
00337     }
00338     theta = teti->t[it] ;
00339     for (int ir=nfantome; ir<nrv; ir++) {
00340       rr = zr->t[ir] ;
00341       mp.val_lx(rr, theta, phi0, l, xi) ;
00342       resu[inum] = meudon.get_spectral_va().val_point(l, xi, theta, phi0) ;
00343       inum++ ;
00344     }
00345     for (int ir=nrv; ir<nrv2; ir++) {
00346       resu[inum] = 0. ;
00347       inum++ ;
00348     }
00349   }
00350   for (int it=ntv; it<ntv2; it++) {
00351     for (int ir=0; ir<nrv2; ir++) {
00352       resu[inum] = 0. ;
00353       inum++ ;
00354     }
00355   }  
00356   return resu ;
00357 }
00358 
00359 void Gval_spher::somme_spectrale3(const Scalar& meudon, double* resu, int taille_in) const{
00360 
00361   assert(meudon.get_etat() == ETATQCQ) ;
00362   meudon.get_spectral_va().coef() ;
00363 
00364   //Sizes of both grids
00365   //-------------------
00366   int nrv0 = dim.dim[0] ;
00367   int ntv0 = dim.dim[1] ;
00368   int nrv = dim.dim[0] + nfantome ;
00369   int ntv = dim.dim[1] + nfantome ;
00370   int npv = dim.dim[2] + nfantome ;
00371   int nrv2 = dim.dim[0] + 2*nfantome ;
00372   int ntv2 = dim.dim[1] + 2*nfantome ;
00373   int npv2 = dim.dim[2] + 2*nfantome ;
00374   int taille = npv2*ntv2*nrv2 ;
00375   if (taille != taille_in) {
00376       cout << "Gval_spher::somme_spectral3():\n" ;
00377       cout << "grid size incompatible with array size... exiting!" << endl ;
00378       abort() ;
00379   }
00380   const Map& mp = meudon.get_mp() ;
00381 #ifndef NDEBUG
00382   const Map_af* mpaff = dynamic_cast<const Map_af*>(&mp) ;
00383   assert(mpaff != 0x0) ;
00384 #endif
00385   const Mg3d* mg = mp.get_mg() ;
00386   int ntm = mg->get_nt(0) ;
00387   int npm = mg->get_np(0) ;
00388   int nz = mg->get_nzone() ;
00389 #ifndef NDEBUG
00390   for (int lz=1; lz<nz; lz++) { 
00391     assert (ntm == mg->get_nt(lz)) ; //Same angular grids in all domains...
00392     assert (npm == mg->get_np(lz)) ;
00393   }
00394 #endif
00395 
00396   //Intermediate quantities
00397   //-----------------------
00398   double* alpha = new double[nrv0*(npm+2)*ntm] ;
00399   double* p_coef = alpha ;
00400   double* chebnri = 0x0 ; //size ~ nrv0 * (npm+2) * nr ...
00401   int* idom = 0x0 ;
00402   initialize_spectral_r(mp, meudon.get_spectral_va().get_base(), idom, chebnri) ;
00403   double* p_func = chebnri ;
00404   Mtbl_cf& mtbcf = *meudon.get_spectral_va().c_cf ;
00405   double** coefm = new double*[nz] ;
00406   for (int lz=0; lz<nz; lz++) {
00407       assert((mtbcf.t[lz])->get_etat() != ETATNONDEF) ;
00408       coefm[lz] = (mtbcf.t[lz])->t ;
00409       if (coefm[lz] == 0x0) {
00410       int sizem = mg->get_nr(lz)*ntm*(npm+2) ;
00411       coefm[lz] = new double[sizem] ;
00412       double* pcf = coefm[lz] ;
00413       for (int i=0; i<sizem; i++)
00414           pcf[i] = 0. ;
00415       }
00416   }
00417  
00418   //First partial summation
00419   //-----------------------
00420   for (int irv=0; irv<nrv0; irv++) {
00421     int lz = idom[irv] ;
00422     double* tbcf = coefm[lz] ;
00423     int nrm = mg->get_nr(lz) ;
00424     for (int mpm=0; mpm<npm+2; mpm++) {
00425       for (int ltm=0; ltm<ntm; ltm++) {
00426     *p_coef = 0 ;
00427     for (int irm=0; irm<nrm; irm++) {
00428       *p_coef += (*tbcf)*(*p_func) ;
00429       tbcf++ ;
00430       p_func++ ;
00431 //    cout << *p_func << ", " << *tbcf << ", " << *p_coef << endl ;
00432     }
00433     p_coef++ ;
00434       }
00435     }
00436   }
00437 
00438   for (int lz=0; lz<nz; lz++) {
00439       if ((mtbcf.t[lz])->t == 0x0) delete [] coefm[lz] ;
00440   }
00441   delete [] coefm ;
00442   delete [] chebnri ;
00443   delete [] idom ;
00444 
00445   double* beta = new double[ntv0*nrv0*(npm+2)] ;
00446   p_coef = beta ;
00447   double* tetlj = 0x0 ;
00448   initialize_spectral_theta(mp, meudon.get_spectral_va().get_base(), tetlj) ;
00449   p_func = tetlj ;
00450   double* p_interm = alpha ;
00451 
00452   //Second partial summation
00453   //------------------------
00454   for (int jtv=0; jtv<ntv0; jtv++) {
00455     for (int irv=0; irv<nrv0; irv++) {
00456       for (int mpm=0; mpm<npm+2; mpm++) {
00457     *p_coef = 0 ;   
00458     for (int ltm=0; ltm<ntm; ltm++) {
00459       *p_coef += (*p_interm) * (*p_func) ;
00460       p_interm++ ;
00461       p_func++ ;
00462     }
00463     p_coef++ ;
00464       } // Loop on m      
00465       p_func -= (npm+2)*ntm ;
00466     } //Loop on irv
00467     p_interm = alpha ;
00468     p_func += (npm+2)*ntm ;
00469   } //Loop on jtv
00470 
00471   delete [] alpha ;
00472   delete [] tetlj ;
00473 
00474 
00475 
00476   // Final summation
00477   //----------------
00478   p_interm = beta ;
00479   double* expmk = 0x0 ;
00480   initialize_spectral_phi(mp, meudon.get_spectral_va().get_base(), expmk) ;
00481   p_func = expmk ;
00482   p_coef = resu ;
00483   for (int ip=0; ip<nfantome; ip++) {
00484     for (int it=0; it<ntv2; it++) {
00485       for (int ir=0; ir<nrv2; ir++){
00486     *p_coef = 0. ;
00487     p_coef++ ;
00488       }
00489     }
00490   }
00491   for (int ip=nfantome; ip<npv; ip++) { 
00492     for (int it=0; it<nfantome; it++) {
00493       for (int ir=0; ir<nrv2; ir++) {
00494     *p_coef = 0. ;
00495     p_coef++ ;
00496       }
00497     }
00498     for (int it=nfantome; it<ntv; it++) {
00499       for (int ir=0; ir<nfantome; ir++) {
00500     *p_coef = 0. ;
00501     p_coef++ ;
00502       }
00503       for (int ir=nfantome; ir<nrv; ir++) {
00504     *p_coef = 0. ;
00505     for (int mpm=0; mpm<npm+2; mpm++) {
00506       *p_coef += (*p_interm) * (*p_func) ;
00507       p_interm++ ;
00508       p_func++ ;
00509     }
00510     p_coef++ ;
00511     p_func -= (npm+2) ;
00512       }
00513       for (int ir=nrv; ir<nrv2; ir++) {
00514     *p_coef = 0. ;
00515     p_coef++ ;
00516       }
00517     }
00518     for (int it=ntv; it<ntv2; it++) {
00519       for (int ir=0; ir<nrv2; ir++) {
00520     *p_coef = 0. ;
00521     p_coef++ ;
00522       }
00523     }
00524     p_func += npm+2 ; //Next point in phi
00525     p_interm = beta ;
00526   }
00527   for (int ip=npv; ip<npv2; ip++) {
00528     for (int it=0; it<ntv2; it++) {
00529       for (int ir=0; ir<nrv2; ir++){
00530     *p_coef = 0. ;
00531     p_coef++ ;
00532       }
00533     }
00534   }
00535   delete [] expmk ;
00536   delete [] beta ;
00537 }
00538 
00539 
00540 void Gval_spher::initialize_spectral_r(const Map& mp, const Base_val& base,
00541                        int*& idom, double*& chebnri) const {
00542     
00543     int nrv0 = dim.dim[0] ;
00544     const Mg3d* mg = mp.get_mg() ;
00545     int npm = mg->get_np(0) ;
00546     int ntm = mg->get_nt(0) ;
00547     
00548     assert (idom == 0x0) ;
00549     idom = new int[nrv0] ;
00550     double* xi = new double[nrv0] ;
00551     int nrmax = 0 ;
00552 
00553     for (int i=0; i<nrv0; i++) {
00554     mp.val_lx(zr->t[i+nfantome], 0., 0., idom[i], xi[i]) ;
00555     nrmax += mg->get_nr(idom[i]) ;
00556     }
00557     
00558     assert (chebnri == 0x0) ;
00559     chebnri = new double[(npm+2)*ntm*nrmax] ;
00560     double* p_out = chebnri ;
00561     for (int irv=0; irv<nrv0; irv++) {
00562     bool nucleus = (mg->get_type_r(idom[irv]) == RARE) ;
00563     int nmax = (nucleus ? 2*mg->get_nr(idom[irv]) + 1 
00564             : mg->get_nr(idom[irv])) ;
00565     double* cheb = new double[nmax] ;
00566     cheb[0] = 1. ;
00567     cheb[1] = xi[irv] ;
00568     for (int ir=2; ir<nmax; ir++) {
00569         cheb[ir] = 2*xi[irv]*cheb[ir-1] - cheb[ir-2] ;
00570     }
00571 
00572     int base_r = base.get_base_r(idom[irv]) ;
00573     
00574     for (int ip=0; ip<npm+2; ip++) {
00575         for (int it=0; it<ntm; it++) {
00576         int fact = 1 ;
00577         int par = 0 ;
00578         if (nucleus) {
00579             fact = 2 ;
00580             switch (base_r) {
00581             
00582             case R_CHEBP : {
00583                 break ;
00584             }
00585                 
00586             case R_CHEBI : {
00587                 par = 1 ;
00588                 break ;
00589             }
00590                 
00591             case R_CHEBPI_P : {
00592                 par = it % 2 ;
00593                 break ;
00594             }
00595                 
00596             case R_CHEBPI_I : {
00597                 par = 1 - (it % 2) ;
00598                 break ;
00599             }
00600             case R_CHEBPIM_P : {
00601                 par = (ip/2) % 2 ;
00602                 break ;
00603             }
00604                 
00605             case R_CHEBPIM_I : {
00606                 par = 1 - ((ip/2) % 2) ;
00607                 break ;
00608             }
00609             
00610             default : {
00611                 cout << "Gval_spher::initialize_spectral_r : " << '\n' 
00612                  << "Unexpected radial base !" << '\n' 
00613                  << "Base : " << base_r << endl ;
00614                 abort() ;
00615             break ;
00616             }
00617         }
00618         }
00619         for (int ir=0; ir<mg->get_nr(idom[irv]); ir++) {
00620             *p_out = cheb[fact*ir+par] ;
00621             p_out++ ;
00622         }
00623         
00624         } // Loop on it
00625     } // Loop on ip
00626     delete [] cheb ;
00627     
00628     }// Loop on irv
00629     
00630     delete [] xi ;
00631 
00632 }
00633 
00634 void Gval_spher::initialize_spectral_theta(const Map& mp, const Base_val& base,
00635                        double*& tetlj) const {
00636  
00637   int ntv0 = dim.dim[1] ;
00638   const Mg3d* mg = mp.get_mg() ;
00639   int npm = mg->get_np(0) ;
00640   int ntm = mg->get_nt(0) ;
00641   int base_t = base.get_base_t(0) ;
00642 
00643   assert (tetlj == 0x0) ;
00644   tetlj = new double[(npm+2)*ntv0*ntm] ;
00645   double* p_out = tetlj ;
00646 
00647   for (int jtv=0; jtv<ntv0; jtv++) {
00648     double teta = tet->t[jtv+nfantome] ;
00649     for (int mpm=0; mpm < npm+2; mpm++) {
00650       for (int ltm=0; ltm<ntm; ltm++) {
00651     switch (base_t)  { //## One should use array of functions...
00652     case T_COS : {
00653       *p_out = cos(ltm*teta) ;
00654       break ;
00655     }
00656     case T_SIN : {
00657       *p_out  = sin(ltm*teta) ;
00658       break ;
00659     }
00660     case T_COS_P : {
00661       *p_out  = cos(2*ltm*teta) ;
00662       break ;
00663     }
00664     case T_COS_I : {
00665       *p_out = cos((2*ltm+1)*teta) ;
00666       break ;
00667     }
00668     case T_SIN_P : {
00669       *p_out  = sin(2*ltm*teta) ;
00670       break ;
00671     }
00672     case T_SIN_I : {
00673       *p_out = sin((2*ltm+1)*teta) ;
00674       break ;
00675     }
00676     case T_COSSIN_CP : {
00677       *p_out = ( ((mpm/2) % 2  == 0) ? cos(2*ltm*teta) 
00678              : sin((2*ltm+1)*teta)) ;
00679       break ;
00680     }
00681     case T_COSSIN_CI : {
00682       *p_out = ( ((mpm/2) % 2  == 0) ? cos((2*ltm+1)*teta) 
00683              : sin(2*ltm*teta)) ;
00684       break ;
00685     }
00686     case T_COSSIN_SP : {
00687       *p_out = ( ((mpm/2) % 2  == 0) ? sin(2*ltm*teta) 
00688              : cos((2*ltm+1)*teta)) ;
00689       break ;
00690     }
00691     case T_COSSIN_SI : {
00692       *p_out = ( ((mpm/2) % 2  == 0) ? sin((2*ltm+1)*teta) 
00693              : cos(2*ltm*teta)) ;
00694       break ;
00695     }
00696     case T_COSSIN_C : {
00697       *p_out = ( ((mpm/2) % 2  == 0) ? cos(ltm*teta) 
00698              : sin(ltm*teta)) ;
00699       break ;
00700     }
00701     case T_COSSIN_S : {
00702       *p_out = ( ((mpm/2) % 2  == 0) ? sin(ltm*teta) 
00703              : cos(ltm*teta)) ;
00704       break ;  
00705     }
00706     default : {
00707       cout << "Gval_spher::initialize_spectral_theta : " << '\n' 
00708            << "Unexpected theta base !" << '\n' 
00709            << "Base : " << base_t << endl ;
00710       abort() ;
00711       break ;
00712     }
00713     }
00714     p_out++ ;
00715       }
00716       if ( (base_t == T_COS_I) || (base_t == T_SIN_P) || (base_t == T_SIN_I) )
00717     {
00718       p_out-- ;
00719       *p_out = 0. ;
00720       p_out++ ;
00721     }
00722     } //Loop on mpm
00723   } //Loop on jtv
00724 
00725 }
00726 
00727 
00728 void Gval_spher::initialize_spectral_phi(const Map& mp, const Base_val& base,
00729                        double*& expmk) const {
00730  
00731   int npv0 = dim.dim[2] ;
00732   const Mg3d* mg = mp.get_mg() ;
00733   int npm = mg->get_np(0) ;
00734   int base_p = base.get_base_p(0) ;
00735 
00736   assert (expmk == 0x0) ;
00737   expmk = new double[(npm+2)*npv0] ;
00738   double* p_out = expmk ;
00739 
00740   for (int kpv=0; kpv<npv0; kpv++) {
00741     double fi = phi->t[kpv+nfantome] ;
00742     for (int mpm=0; mpm < npm+2; mpm++) {
00743     switch (base_p)  { //## One should use array of functions...
00744     case P_COSSIN : {
00745       int m = mpm / 2 ;
00746       *p_out  = ( (mpm%2 == 0) ? cos(m*fi) : sin(m*fi) ) ;
00747       break ;
00748     }
00749     case P_COSSIN_P : {
00750       int m = mpm / 2 ;
00751       *p_out  = ( (mpm%2 == 0) ? cos(2*m*fi) : sin(2*m*fi) ) ;
00752       break ;
00753     }
00754     case P_COSSIN_I : {
00755       int m = mpm / 2 ;
00756       *p_out  = ( (mpm%2 == 0) ? cos((2*m+1)*fi) : sin((2*m+1)*fi) ) ;
00757       break ;
00758     }
00759     default : {
00760       cout << "Gval_spher::initialize_spectral_phi : " << '\n' 
00761            << "Unexpected phi base !" << '\n' 
00762            << "Base : " << base_p << endl ;
00763       abort() ;
00764       break ;
00765     }
00766     }
00767     p_out++ ;
00768     } //Loop on mpm
00769   } //Loop on kpv
00770 
00771 }

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