grille_val_interp.C

00001 /*
00002  * Methods for interpolating with class Grille_val, and its derivative classes.
00003  *
00004  * See the file grille_val.h for documentation
00005  *
00006  */
00007 
00008 /*
00009  *   Copyright (c) 2001 Jerome Novak
00010  *
00011  *   This file is part of LORENE.
00012  *
00013  *   LORENE is free software; you can redistribute it and/or modify
00014  *   it under the terms of the GNU General Public License as published by
00015  *   the Free Software Foundation; either version 2 of the License, or
00016  *   (at your option) any later version.
00017  *
00018  *   LORENE is distributed in the hope that it will be useful,
00019  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021  *   GNU General Public License for more details.
00022  *
00023  *   You should have received a copy of the GNU General Public License
00024  *   along with LORENE; if not, write to the Free Software
00025  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00026  *
00027  */
00028 
00029 
00030 char grille_val_interp_C[] = "$Header: /cvsroot/Lorene/C++/Source/Valencia/grille_val_interp.C,v 1.12 2010/02/04 16:44:35 j_novak Exp $" ;
00031 
00032 /*
00033  * $Id: grille_val_interp.C,v 1.12 2010/02/04 16:44:35 j_novak Exp $
00034  * $Log: grille_val_interp.C,v $
00035  * Revision 1.12  2010/02/04 16:44:35  j_novak
00036  * Reformulation of the parabolic interpolation, to have better accuracy
00037  *
00038  * Revision 1.11  2005/06/23 13:40:08  j_novak
00039  * The tests on the number of dimensions have been changed to handle better the
00040  * axisymmetric case.
00041  *
00042  * Revision 1.10  2005/06/22 09:11:17  lm_lin
00043  *
00044  * Grid wedding: convert from the old C++ object "Cmp" to "Scalar".
00045  *
00046  * Revision 1.9  2004/05/07 12:32:13  j_novak
00047  * New summation from spectral to FD grid. Much faster!
00048  *
00049  * Revision 1.8  2004/03/25 14:52:33  j_novak
00050  * Suppressed some documentation/
00051  *
00052  * Revision 1.7  2003/12/19 15:05:14  j_novak
00053  * Trying to avoid shadowed variables
00054  *
00055  * Revision 1.6  2003/12/05 14:51:54  j_novak
00056  * problem with new SGI compiler
00057  *
00058  * Revision 1.5  2003/10/03 16:17:17  j_novak
00059  * Corrected some const qualifiers
00060  *
00061  * Revision 1.4  2002/11/13 11:22:57  j_novak
00062  * Version "provisoire" de l'interpolation (sommation depuis la grille
00063  * spectrale) aux interfaces de la grille de Valence.
00064  *
00065  * Revision 1.3  2002/09/09 13:00:40  e_gourgoulhon
00066  * Modification of declaration of Fortran 77 prototypes for
00067  * a better portability (in particular on IBM AIX systems):
00068  * All Fortran subroutine names are now written F77_* and are
00069  * defined in the new file C++/Include/proto_f77.h.
00070  *
00071  * Revision 1.2  2001/11/23 16:03:07  j_novak
00072  *
00073  *  minor modifications on the grid check.
00074  *
00075  * Revision 1.1  2001/11/22 13:41:54  j_novak
00076  * Added all source files for manipulating Valencia type objects and making
00077  * interpolations to and from Meudon grids.
00078  *
00079  *
00080  * $Header: /cvsroot/Lorene/C++/Source/Valencia/grille_val_interp.C,v 1.12 2010/02/04 16:44:35 j_novak Exp $
00081  *
00082  */
00083 
00084 // Fichier includes
00085 #include "grille_val.h"
00086 #include "proto_f77.h"
00087 
00088                         //------------------
00089                         // Compatibilite
00090                         //------------------
00091 
00092 //Compatibilite entre une grille valencienne cartesienne et une meudonaise
00093 bool Gval_cart::compatible(const Map* mp, const int lmax, const int lmin) 
00094   const {
00095 
00096   //Seulement avec des mappings du genre affine
00097   assert( dynamic_cast<const Map_af*>(mp) != 0x0) ; 
00098 
00099   const Mg3d* mgrid = mp->get_mg() ;
00100   assert(lmin >= 0 && lmax <= mgrid->get_nzone()) ;
00101   int dim_spec = 1 ;
00102   for (int i=lmin; i<lmax; i++) {
00103     if ((mgrid->get_nt(i) > 1)&&(dim_spec==1)) dim_spec = 2; 
00104     if (mgrid->get_np(i) > 1) dim_spec = 3;
00105   }
00106   if (dim_spec != dim.ndim) {
00107     cout << "Grille_val::compatibilite: the number of dimensions" << endl ;
00108     cout << "of both grids do not coincide!" << endl;
00109     abort() ;
00110   }
00111   if (type_t != mgrid->get_type_t()) {
00112     cout << "Grille_val::compatibilite: the symmetries in theta" << endl ;
00113     cout << "of both grids do not coincide!" << endl;
00114     abort() ;
00115   }
00116   if (type_p != mgrid->get_type_p()) {
00117     cout << "Grille_val::compatibilite: the symmetries in phi" << endl ;
00118     cout << "of both grids do not coincide!" << endl;
00119     abort() ;
00120   }
00121 
00122   bool dimension = true ;
00123   const Coord& rr = mp->r ;
00124 
00125   double rout = (+rr)(lmax-1, 0, 0, mgrid->get_nr(lmax-1) - 1) ;
00126 
00127   dimension &= (rout <= *zrmax) ;
00128   switch (dim_spec) {
00129   case 1:{
00130     dimension &= ((+rr)(lmin,0,0,0) >= *zrmin) ;
00131     break ;
00132   }
00133   case 2: {
00134     if (mgrid->get_type_t() == SYM) 
00135       {dimension &= (*zrmin <= 0.) ;}
00136     else {
00137       dimension &= (*zrmin <= -rout ) ;}
00138     dimension &= (*xmin <= 0.) ;
00139     dimension &= (*xmax >= rout ) ;
00140     break ;
00141   }
00142   case 3: {
00143     if (mgrid->get_type_t() == SYM) 
00144       {dimension &= (*zrmin <= 0.) ;}
00145     else {
00146       dimension &= (*zrmin <= -rout) ;}
00147     if (mgrid->get_type_p() == SYM) {
00148       dimension &= (*ymin <= 0.) ;
00149       dimension &= (*xmin <= -rout) ;
00150     }
00151     else {
00152       dimension &= (*xmin <= -rout ) ;
00153       dimension &= (*ymin <= -rout ) ;
00154     }
00155     dimension &= (*xmax >= rout) ;
00156     dimension &= (*ymax >= rout) ;
00157     break ;
00158   }
00159   }
00160   return dimension ;
00161 
00162 }
00163 //Compatibilite entre une grille valencienne spherique  et une meudonaise
00164 bool Gval_spher::compatible(const Map* mp, const int lmax, const int lmin) 
00165   const {
00166 
00167   //Seulement avec des mappings du genre affine.
00168   assert( dynamic_cast<const Map_af*>(mp) != 0x0) ;
00169  
00170   int dim_spec = 1 ;
00171 
00172   const Mg3d* mgrid = mp->get_mg() ;
00173   for (int i=lmin; i<lmax; i++) {
00174     if ((mgrid->get_nt(i) > 1)&&(dim_spec==1)) dim_spec = 2; 
00175     if (mgrid->get_np(i) > 1) dim_spec = 3;
00176   }
00177   if (dim_spec > dim.ndim) {
00178     cout << "Grille_val::compatibilite: the number of dimensions" << endl ;
00179     cout << "of both grids do not coincide!" << endl;
00180     cout << "Spectral : " << dim_spec << "D,   FD: " << dim.ndim << "D" << endl ;
00181     abort() ;
00182   }
00183   if (type_t != mgrid->get_type_t()) {
00184     cout << "Grille_val::compatibilite: the symmetries in theta" << endl ;
00185     cout << "of both grids do not coincide!" << endl;
00186     abort() ;
00187   }
00188   if (type_p != mgrid->get_type_p()) {
00189     cout << "Grille_val::compatibilite: the symmetries in phi" << endl ;
00190     cout << "of both grids do not coincide!" << endl;
00191     abort() ;
00192   }
00193 
00194   const Coord& rr = mp->r ;
00195 
00196   int i_b = mgrid->get_nr(lmax-1) - 1 ;
00197 
00198   double rmax = (+rr)(lmax-1, 0, 0, i_b) ;
00199   double rmin = (+rr)(lmin, 0, 0, 0) ;
00200   double valmax = get_zr(dim.dim[0]+nfantome - 1) ;
00201   double valmin = get_zr(-nfantome) ;
00202 
00203   bool dimension = ((rmax <= (valmax)) && (rmin>= (valmin))) ;
00204 
00205   return dimension ;
00206 }
00207 
00208 // Teste si la grille valencienne cartesienne est contenue dans le mapping
00209 // de Meudon (pour le passage Meudon->Valence )
00210 bool Gval_cart::contenue_dans(const Map& mp, const int lmax, const int lmin)
00211  const {
00212   //Seulement avec des mappings du genre affine
00213   assert( dynamic_cast<const Map_af*>(&mp) != 0x0) ; 
00214 
00215   const Mg3d* mgrid = mp.get_mg() ;
00216   assert(lmin >= 0 && lmax <= mgrid->get_nzone()) ;
00217   int dim_spec = 1 ;
00218   for (int i=lmin; i<lmax; i++) {
00219     if ((mgrid->get_nt(i) > 1)&&(dim_spec==1)) dim_spec = 2; 
00220     if (mgrid->get_np(i) > 1) dim_spec = 3;
00221   }
00222   if (dim_spec != dim.ndim) {
00223     cout << "Grille_val::contenue_dans: the number of dimensions" << endl ;
00224     cout << "of both grids do not coincide!" << endl;
00225     abort() ;
00226   }
00227   if (type_t != mgrid->get_type_t()) {
00228     cout << "Grille_val::contenue_dans: the symmetries in theta" << endl ;
00229     cout << "of both grids do not coincide!" << endl;
00230     abort() ;
00231   }
00232   if (type_p != mgrid->get_type_p()) {
00233     cout << "Grille_val::contenue_dans: the symmetries in phi" << endl ;
00234     cout << "of both grids do not coincide!" << endl;
00235     abort() ;
00236   }
00237 
00238   bool dimension = true ;
00239   const Coord& rr = mp.r ;
00240 
00241   //For an affine mapping:
00242   double radius = (+rr)(lmax-1,0,0,mgrid->get_nr(lmax-1)-1) ;
00243   double radius2 = radius*radius ;
00244 
00245   if (dim_spec ==1) {
00246     dimension &= ((+rr)(lmin,0,0,0) <= *zrmin) ;
00247     dimension &= (radius >= *zrmax) ;
00248   }
00249   if (dim_spec ==2) { //## a transformer en switch...
00250     dimension &= ((+rr)(lmin,0,0,0)/radius < 1.e-6) ;
00251     dimension &= (*xmin >= 0.) ;
00252     if (mgrid->get_type_t() == SYM) dimension &= (*zrmin >= 0.) ;
00253     double x1 = *xmax ;
00254     double z1 = (fabs(*zrmax)>fabs(*zrmin)? *zrmax : *zrmin) ;
00255     dimension &= (x1*x1+z1*z1 <= radius2) ;
00256   }
00257   if (dim_spec == 3) {
00258     if (mgrid->get_type_t() == SYM) dimension &= (*zrmin >= 0.) ;
00259     if (mgrid->get_type_p() == SYM) dimension &= (*ymin >= 0.) ;
00260     double x1 = (fabs(*xmax)>fabs(*xmin)? *xmax : *xmin) ;
00261     double y1 = (fabs(*ymax)>fabs(*ymin)? *ymax : *ymin) ;
00262     double z1 = (fabs(*zrmax)>fabs(*zrmin)? *zrmax : *zrmin) ;
00263     dimension &= (x1*x1+y1*y1+z1*z1 <= radius2) ;
00264   }
00265   return dimension ;
00266 }
00267 
00268 // Teste si la grille valencienne spherique est contenue dans le mapping
00269 // de Meudon  (pour le passage Meudon->Valence )
00270 bool Gval_spher::contenue_dans(const Map& mp, const int lmax, const int lmin)
00271   const {
00272 
00273   //Seulement avec des mappings du genre affine.
00274   assert( dynamic_cast<const Map_af*>(&mp) != 0x0) ;
00275  
00276   const Mg3d* mgrid = mp.get_mg() ;
00277   
00278   if (type_t != mgrid->get_type_t()) {
00279     cout << "Grille_val::contenue_dans: the symmetries in theta" << endl ;
00280     cout << "of both grids do not coincide!" << endl;
00281     abort() ;
00282   }
00283   if (type_p != mgrid->get_type_p()) {
00284     cout << "Grille_val::contenue_dans: the symmetries in phi" << endl ;
00285     cout << "of both grids do not coincide!" << endl;
00286     abort() ;
00287   }
00288 
00289   const Coord& rr = mp.r ;
00290 
00291   int i_b = mgrid->get_nr(lmax-1) - 1 ;
00292 
00293   double rmax = (+rr)(lmax-1, 0, 0, i_b) ;
00294   double rmin = (+rr)(lmin, 0, 0, 0) ;
00295   double valmin = get_zr(0) ;
00296   double valmax = get_zr(dim.dim[0] - 1) ;
00297 
00298   bool dimension = ((rmax >= valmax) && (rmin<= valmin)) ;
00299 
00300   return dimension ;
00301 }
00302 
00303                         //------------------
00304                         // Interpolation 1D
00305                         //------------------
00306 
00307 // Interpolation pour la classe de base
00308 Tbl Grille_val::interpol1(const Tbl& rdep, const Tbl& rarr, const Tbl& fdep, 
00309               int flag, const int type_inter) const {
00310   assert(rdep.get_ndim() == 1) ;
00311   assert(rarr.get_ndim() == 1) ;
00312   assert(rdep.dim == fdep.dim) ;
00313 
00314   Tbl farr(rarr.dim) ;
00315   farr.set_etat_qcq() ;
00316   
00317   int ndep = rdep.get_dim(0) ;
00318   int narr = rarr.get_dim(0) ;
00319 
00320   switch (type_inter) {
00321   case 0: {
00322     int ndeg[4] ;
00323     ndeg[0] = ndep ;
00324     ndeg[1] = narr ;
00325     double* err0 = new double[ndep+narr] ;
00326     double* err1 = new double[ndep+narr] ;
00327     double* den0 = new double[ndep+narr] ;
00328     double* den1 = new double[ndep+narr] ;
00329     for (int i=0; i<ndep; i++) {
00330       err0[i] = rdep(i) ;
00331       den0[i] = fdep(i) ; 
00332     }
00333     for (int i=0; i<narr; i++) err1[i] = rarr(i) ;
00334     F77_insmts(ndeg, &flag, err0, err1, den0, den1) ;
00335     for (int i=0; i<narr; i++) farr.set(i) = den1[i] ;
00336     delete[] err0 ;
00337     delete[] den0 ;
00338     delete[] err1 ;
00339     delete[] den1 ;
00340     break ;
00341   }
00342    case 1: {
00343      int ip = 0 ;
00344      int is = 1 ;
00345      assert(ndep > 1);
00346      for (int i=0; i<narr; i++) {
00347        while(rdep(is) < rarr(i)) is++ ;
00348        assert(is<ndep) ;
00349        ip = is - 1 ;
00350        farr.t[i] = (fdep(is)*(rdep(ip)-rarr(i)) + 
00351                     fdep(ip)*(rarr(i)-rdep(is))) /
00352          (rdep(ip)-rdep(is)) ;
00353      }
00354      break ;
00355    }
00356     
00357    case 2:
00358      int i1, i2, i3 ;
00359      double xr, x1, x2, x3, y1, y2, y3 ;
00360      i2 = 0 ;
00361      i3 = 1 ;
00362     assert(ndep > 2) ;
00363     for (int i=0; i<narr; i++) {
00364       xr = rarr(i) ;
00365       while(rdep.t[i3] < xr) i3++ ;
00366       assert(i3<ndep) ;
00367       if (i3 == 1) {
00368       i1 = 0 ;
00369       i2 = 1 ;
00370       i3 = 2 ;
00371       }
00372       else {
00373       i2 = i3 - 1 ;
00374       i1 = i2 - 1 ;
00375       }
00376       x1 = rdep(i1) ;
00377       x2 = rdep(i2) ;
00378       x3 = rdep(i3) ;
00379       y1 = fdep(i1) ;
00380       y2 = fdep(i2) ;
00381       y3 = fdep(i3) ;
00382       double c = y1 ;
00383       double b = (y2 - y1) / (x2 - x1) ;
00384       double a = ( (y3 - y2)/(x3 - x2) - (y2 - y1)/(x2 - x1) ) / (x3 - x1) ;
00385       farr.t[i] = c + b*(xr - x1) + a*(xr - x1)*(xr - x2) ;
00386     }
00387     break ;
00388     
00389   case 3:
00390     cout << "Spline interpolation not implemented yet!" << endl ;
00391     abort() ;
00392     break ;
00393     
00394    default:
00395      cout << "Unknown type of interpolation!" << endl ;
00396      abort() ;
00397      break ;
00398    }
00399    return farr ;
00400 }
00401   
00402                         //------------------
00403                         // Interpolation 2D
00404                         //------------------
00405 
00406 // Interpolation pour les classes derivees
00407 Tbl Gval_spher::interpol2(const Tbl& fdep, const Tbl& rarr, 
00408                const Tbl& tarr, const int type_inter) const 
00409 {
00410   assert(dim.ndim >= 2) ;
00411   assert(fdep.get_ndim() == 2) ;
00412   assert(rarr.get_ndim() == 1) ;
00413   assert(tarr.get_ndim() == 1) ;
00414 
00415   int ntv = tet->get_dim(0) ;
00416   int nrv = zr->get_dim(0) ;
00417   int ntm = tarr.get_dim(0) ;
00418   int nrm = rarr.get_dim(0) ;
00419 
00420   Tbl *fdept = new Tbl(nrv) ;
00421   fdept->set_etat_qcq() ;
00422   Tbl intermediaire(ntv, nrm) ;
00423   intermediaire.set_etat_qcq() ;
00424 
00425   Tbl farr(ntm, nrm) ;
00426   farr.set_etat_qcq() ;
00427 
00428   int job = 1 ;
00429   for (int i=0; i<ntv; i++) {
00430     for (int j=0; j<nrv; j++) fdept->t[j] = fdep.t[i*nrv+j] ;
00431     Tbl fr(interpol1(*zr, rarr, *fdept, job, type_inter)) ;
00432     job = 0 ;
00433     for (int j=0; j<nrm; j++) intermediaire.t[i*nrm+j] = fr.t[j] ;
00434   }
00435   delete fdept ;
00436 
00437   fdept = new Tbl(ntv) ;
00438   fdept->set_etat_qcq() ;
00439   job = 1 ;
00440   for (int i=0; i<nrm; i++) {
00441     for (int j=0; j<ntv; j++) fdept->t[j] = intermediaire.t[j*nrm+i] ;
00442     Tbl fr(interpol1(*tet, tarr, *fdept, job, type_inter)) ;
00443     job = 0 ;
00444     for (int j=0; j<ntm; j++) farr.set(j,i) = fr(j) ;
00445   }
00446   delete fdept ;
00447   return farr ;
00448 }
00449 
00450 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00451 
00452 struct Point {
00453   double x ;
00454   int l ;
00455   int k ;
00456 };
00457 
00458 #endif /* DOXYGEN_SHOULD_SKIP_THIS */ 
00459 
00460 int copar(const void* a, const void* b) {
00461   double x = (reinterpret_cast<const Point*>(a))->x ;
00462   double y = (reinterpret_cast<const Point*>(b))->x ;
00463   return x > y ? 1 : -1 ;
00464 } 
00465 
00466 Tbl Gval_cart::interpol2(const Tbl& fdep, const Tbl& rarr, 
00467                const Tbl& tetarr, const int type_inter) const 
00468 {
00469   return interpol2c(*zr, *x, fdep, rarr, tetarr, type_inter) ;
00470 }
00471 
00472 Tbl Gval_cart::interpol2c(const Tbl& zdep, const Tbl& xdep, const Tbl& fdep, 
00473           const Tbl& rarr, const Tbl& tarr, const int inter_type) const {
00474   
00475   assert(fdep.get_ndim() == 2) ;
00476   assert(zdep.get_ndim() == 1) ;
00477   assert(xdep.get_ndim() == 1) ;
00478   assert(rarr.get_ndim() == 1) ;
00479   assert(tarr.get_ndim() == 1) ;
00480   
00481   int nz = zdep.get_dim(0) ;
00482   int nx = xdep.get_dim(0) ;
00483   int nr = rarr.get_dim(0) ;
00484   int nt = tarr.get_dim(0) ;
00485  
00486   Tbl farr(nt, nr) ;
00487   farr.set_etat_qcq() ;
00488   
00489   int narr = nt*nr ;
00490   Point* zlk = new Point[narr] ;
00491   int inum = 0 ;
00492   int ir, it ;
00493   for (it=0; it < nt; it++) {
00494     for (ir=0; ir < nr; ir++) {
00495       zlk[inum].x = rarr(ir)*cos(tarr(it)) ; 
00496       zlk[inum].l = ir ;
00497       zlk[inum].k = it ;
00498       inum++ ;
00499     }
00500   }
00501   
00502   void* base = reinterpret_cast<void*>(zlk) ;
00503   size_t nel = size_t(narr) ;
00504   size_t width = sizeof(Point) ;
00505   qsort (base, nel, width, copar) ; 
00506   
00507   Tbl effdep(nz) ; effdep.set_etat_qcq() ;
00508  
00509   double x12 = 1e-6*(zdep(nz-1) - zdep(0)) ; 
00510   // Attention!! x12 doit etre compatible avec son equivalent dans insmts
00511   int ndistz = 0;
00512   inum = 0 ;
00513   do  {
00514     inum++ ;
00515     if (inum < narr) {
00516       if ( (zlk[inum].x - zlk[inum-1].x) > x12 ) {ndistz++ ; }
00517     }
00518   } while (inum < narr) ;
00519   ndistz++ ;
00520   Tbl errarr(ndistz) ; 
00521   errarr.set_etat_qcq() ;
00522   Tbl effarr(ndistz) ; 
00523   ndistz = 0 ;
00524   inum = 0 ;
00525   do  {
00526     errarr.set(ndistz) = zlk[inum].x ;
00527     inum ++ ;
00528     if (inum < narr) {
00529       if ( (zlk[inum].x - zlk[inum-1].x) > x12 ) {ndistz++ ; }
00530     }
00531   } while (inum < narr) ;
00532   ndistz++ ;
00533 
00534   int ijob = 1 ;
00535 
00536   Tbl tablo(nx, ndistz) ;
00537   tablo.set_etat_qcq() ;
00538   for (int j=0; j<nx; j++) {
00539       for (int i=0; i<nz; i++) effdep.set(i) = fdep(j,i) ;
00540       effarr = interpol1(zdep, errarr, effdep, ijob, inter_type) ;
00541       ijob = 0 ;
00542       for (int i=0; i<ndistz; i++) tablo.set(j,i) = effarr(i) ;
00543   }
00544 
00545   inum = 0 ;
00546   int indz = 0 ;
00547   Tbl effdep2(nx) ;
00548   effdep2.set_etat_qcq() ;
00549   while (inum < narr) {
00550     Point* xlk = new Point[3*nr] ;
00551     int nxline = 0 ;
00552     int inum1 ;
00553     do { 
00554       ir = zlk[inum].l ;
00555       it = zlk[inum].k ;
00556       xlk[nxline].x = rarr(ir)*sin(tarr(it)) ;
00557       xlk[nxline].l = ir ;
00558       xlk[nxline].k = it ;
00559       nxline ++ ; inum ++ ;
00560       inum1 = (inum < narr ? inum : 0) ;
00561     } while ( ( (zlk[inum1].x - zlk[inum-1].x) < x12 ) && (inum < narr)) ;
00562     void* bas2 = reinterpret_cast<void*>(xlk) ;
00563     size_t ne2 = size_t(nxline) ;
00564     qsort (bas2, ne2, width, copar) ;
00565     
00566     int inum2 = 0 ;
00567     int ndistx = 0 ;
00568     do  {
00569       inum2 ++ ;
00570       if (inum2 < nxline) {
00571     if ( (xlk[inum2].x - xlk[inum2-1].x) > x12 ) {ndistx++ ; }
00572       }
00573     } while (inum2 < nxline) ;
00574     ndistx++ ;
00575 
00576     Tbl errarr2(ndistx) ;
00577     errarr2.set_etat_qcq() ;
00578     Tbl effarr2(ndistx) ;
00579     inum2 = 0 ; 
00580     ndistx = 0 ;
00581     do  {
00582       errarr2.set(ndistx) = xlk[inum2].x ;
00583       inum2 ++ ;
00584       if (inum2 < nxline) {
00585     if ( (xlk[inum2].x - xlk[inum2-1].x) > x12 ) {ndistx++ ; }
00586       }
00587     } while (inum2 < nxline) ;
00588     ndistx++ ;
00589 
00590     for (int j=0; j<nx; j++) {
00591       effdep2.set(j) = tablo(j,indz) ;
00592     } 
00593     indz++ ;
00594     ijob = 1 ;
00595     effarr2 = interpol1(xdep, errarr2, effdep2, ijob, inter_type) ;
00596     int iresu = 0 ;
00597     if (ijob == -1) {
00598       for (int i=0; i<nxline; i++) {
00599     while (fabs(xlk[i].x - xdep(iresu)) > x12 ) {
00600       iresu++ ;
00601     }
00602     ir = xlk[i].l ;
00603     it = xlk[i].k ;
00604     farr.set(it,ir) = effdep2(iresu) ;
00605       }
00606     }
00607     else {
00608       double resu ;
00609       for (int i=0; i<nxline; i++) {
00610     resu = effarr2(iresu) ;
00611     if (i<nxline-1) {
00612       if ((xlk[i+1].x-xlk[i].x) > x12) {
00613         iresu++ ;
00614       }
00615     }
00616     ir = xlk[i].l ;
00617     it = xlk[i].k ;
00618     farr.set(it,ir) = resu ;
00619       }
00620     }
00621     delete [] xlk ;
00622   }
00623 
00624   delete [] zlk ;
00625   return farr ;
00626 }
00627 
00628 
00629                         //------------------
00630                         // Interpolation 3D
00631                         //------------------
00632 
00633 // Interpolation pour les classes derivees
00634 Tbl Gval_spher::interpol3(const Tbl& fdep, const Tbl& rarr, const Tbl& tarr, 
00635               const Tbl& parr, const int type_inter) const {
00636   assert(dim.ndim == 3) ;
00637   assert(fdep.get_ndim() == 3) ;
00638   assert(rarr.get_ndim() == 1) ;
00639   assert(tarr.get_ndim() == 1) ;
00640   assert(parr.get_ndim() == 1) ;
00641 
00642   int npv = phi->get_dim(0) ;
00643   int ntv = tet->get_dim(0) ;
00644   int nrv = zr->get_dim(0) ;
00645   int npm = parr.get_dim(0) ;
00646   int ntm = tarr.get_dim(0) ;
00647   int nrm = rarr.get_dim(0) ;
00648 
00649   Tbl *fdept = new Tbl(ntv, nrv) ;
00650   fdept->set_etat_qcq() ;
00651   Tbl intermediaire(npv, ntm, nrm) ;
00652   intermediaire.set_etat_qcq() ;
00653 
00654   Tbl farr(npm, ntm, nrm) ;
00655   farr.set_etat_qcq() ;
00656 
00657   for (int i=0; i<npv; i++) {
00658     for (int j=0; j<ntv; j++) 
00659       for (int k=0; k<nrv; k++) fdept->t[j*nrv+k] = fdep.t[(i*ntv+j)*nrv+k] ;
00660     Tbl fr(interpol2(*fdept, rarr, tarr, type_inter)) ;
00661     for (int j=0; j<ntm; j++)
00662       for (int k=0; k<nrm; k++) intermediaire.set(i,j,k) = fr(j,k) ;
00663   }
00664   delete fdept ;
00665 
00666   int job = 1 ;
00667   fdept = new Tbl(npv) ;
00668   fdept->set_etat_qcq() ;
00669   for (int i=0; i<ntm; i++) {
00670     for (int j=0; j<nrm; j++) {
00671       for (int k=0; k<npv; k++) fdept->set(k) = intermediaire(k,i,j) ;
00672       Tbl fr(interpol1(*phi, parr, *fdept, job, type_inter)) ;
00673       job = 0 ;
00674       for (int k=0; k<npm; k++) farr.set(k,i,j) = fr(k) ;
00675     }
00676   }
00677   delete fdept ;
00678   return farr ;
00679 }
00680 
00681 Tbl Gval_cart::interpol3(const Tbl& fdep, const Tbl& rarr, 
00682               const Tbl& tarr, const Tbl& parr, const 
00683               int inter_type) const {
00684 
00685   assert(fdep.get_ndim() == 3) ;
00686   assert(rarr.get_ndim() == 1) ;
00687   assert(tarr.get_ndim() == 1) ;
00688   assert(parr.get_ndim() == 1) ;
00689   
00690   int nz = zr->get_dim(0) ;
00691   int nx = x->get_dim(0) ;
00692   int ny = y->get_dim(0) ;
00693   int nr = rarr.get_dim(0) ;
00694   int nt = tarr.get_dim(0) ;
00695   int np = parr.get_dim(0) ;
00696   Tbl farr(np, nt, nr) ;
00697   farr.set_etat_qcq() ;
00698 
00699   bool coq = (rarr(0)/rarr(nr-1) > 1.e-6) ;
00700   Tbl* rarr2(0x0);
00701   if (coq) {     // If the spectral grid is only made of shells
00702     rarr2 = new Tbl(2*nr) ;
00703     rarr2->set_etat_qcq() ;
00704     double dr = rarr(0)/nr ;
00705     for (int i=0; i<nr; i++) rarr2->set(i) = i*dr ;
00706     for (int i=nr; i<2*nr; i++) rarr2->set(i) = rarr(i-nr) ;
00707   }
00708 
00709   int nr2 = coq ? 2*nr : nr ;
00710 
00711   Tbl cylindre(nz, np, nr2) ;
00712   cylindre.set_etat_qcq() ;
00713   for(int iz=0; iz<nz; iz++) {
00714     Tbl carre(ny,nx) ;
00715     carre.set_etat_qcq() ;
00716     Tbl cercle(np, nr2) ;
00717     for (int iy=0; iy<ny; iy++) 
00718       for (int ix=0; ix<nx; ix++) 
00719     carre.set(iy,ix) = fdep(iy,ix,iz) ; // This should be optimized...
00720     cercle = interpol2c(*x, *y, carre, coq ? *rarr2 : rarr, parr, inter_type) ;
00721       
00722     for (int ip=0; ip<np; ip++) 
00723       for (int ir=0; ir<nr2; ir++) 
00724     cylindre.set(iz,ip,ir) = cercle(ip,ir) ;
00725   }
00726 
00727  for (int ip=0; ip<np; ip++) {
00728     Tbl carre(nr2, nz) ;
00729     carre.set_etat_qcq() ;
00730     Tbl cercle(nt, nr) ;
00731     for (int ir=0; ir<nr2; ir++) 
00732       for (int iz=0; iz<nz; iz++) 
00733     carre.set(ir,iz) = cylindre(iz,ip,ir) ;
00734     cercle = interpol2c(*zr, coq ? *rarr2 : rarr , carre, rarr, tarr, 
00735             inter_type) ;
00736     for (int it=0; it<nt; it++) 
00737       for (int ir=0; ir<nr; ir++) 
00738     farr.set(ip,it,ir) = cercle(it,ir) ;
00739   }
00740 
00741  if (coq) delete rarr2 ;
00742  return farr ;
00743 
00744 }
00745 
00746 

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