tbl_val_smooth.C

00001 /*
00002  *  Smoothes the junction with an eventual atmosphere.
00003  *
00004  */
00005 
00006 /*
00007  *   Copyright (c) 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 tbl_val_smooth_C[] = "$Header: /cvsroot/Lorene/C++/Source/Valencia/tbl_val_smooth.C,v 1.3 2004/12/30 16:14:01 j_novak Exp $" ;
00027 
00028 
00029 /*
00030  * $Id: tbl_val_smooth.C,v 1.3 2004/12/30 16:14:01 j_novak Exp $
00031  * $Log: tbl_val_smooth.C,v $
00032  * Revision 1.3  2004/12/30 16:14:01  j_novak
00033  * Changed the name of a shadowed variable.
00034  *
00035  * Revision 1.2  2004/12/03 13:24:01  j_novak
00036  * Minor modif.
00037  *
00038  * Revision 1.1  2004/11/26 17:02:19  j_novak
00039  * Added a function giving a smooth transition to the atmosphere.
00040  *
00041  *
00042  * $Header: /cvsroot/Lorene/C++/Source/Valencia/tbl_val_smooth.C,v 1.3 2004/12/30 16:14:01 j_novak Exp $
00043  *
00044  */
00045 
00046 // Lorene headers
00047 #include "tbl_val.h"
00048 
00049 //Local prototypes
00050 void radial_smoothing(double* , const double* , int , double) ;
00051 //****************************************************************************
00052 
00053 void Tbl_val::smooth_atmosphere(double atmosphere_thr) {
00054 
00055   const Gval_spher* gspher = dynamic_cast<const Gval_spher*>(gval) ;
00056   assert(gspher != 0x0) ;
00057   int ndim = gspher->get_ndim() ;
00058   int fant = gspher->get_fantome() ;
00059   int nr = get_dim(0) + 2*fant;
00060 
00061   switch (ndim) {
00062   case 1: {
00063     radial_smoothing(t, gspher->zr->t, nr, atmosphere_thr) ;
00064     break ;
00065   } 
00066   case 2: {
00067     int nt = get_dim(1)  + 2*fant ;
00068     for (int j=0; j<nt; j++) 
00069       radial_smoothing(t+j*nr, gspher->zr->t, nr, atmosphere_thr) ;
00070     break ;
00071   }
00072   case 3: {
00073     int nt = get_dim(1)  + 2*fant ;
00074     int np = get_dim(2)  + 2*fant ;
00075     for (int j=0; j<nt; j++) 
00076       for (int k=0; k<np; k++) 
00077     radial_smoothing(t+k*nt*nr+j*nr, gspher->zr->t, nr, atmosphere_thr) ;
00078     break ;
00079   }
00080     
00081   default: {
00082     cerr << "Tbl_val::smooth_atmosphere : strange number of dimensions!" 
00083      << endl ;
00084     abort() ;
00085     break ;
00086   }
00087   }
00088   return ;
00089 }
00090 
00091 void radial_smoothing(double* tab, const double* rr, int n, double rho) {
00092 
00093   assert((tab!= 0x0)&&(rr!=0x0)) ;
00094   assert (rho >= 0.) ;
00095   
00096   if (fabs(tab[n-1]) > rho) // no atmosphere here
00097     return ;
00098 
00099   double* t = tab + (n-1) ;
00100   int indice = -1 ;
00101   bool atmos = true ;
00102   bool jump = false ;
00103   for (int i=0; ((i<n)&&(atmos)); i++) {
00104     if (atmos) atmos = ( fabs(*t) < rho) ;
00105     t-- ;
00106     if (atmos) {
00107       jump = ( fabs(*t) > rho ) ;
00108       if (jump) // discontinuity found
00109     indice = n - i - 2 ;
00110     }
00111   }
00112   if (indice == -1) return ;
00113   int np = 2*(n-indice-2)/3 ;
00114   int nm = indice / 100 + 3 ;
00115   assert(n > nm+np) ;
00116   if (indice < n - np+1) { // enough points to interpolate
00117 
00118     // The inteprolation is done using a cubic polynomial
00119     //---------------------------------------------------
00120 
00121     int ileft = indice - nm + 2 ;
00122     int iright = indice + np - 1 ;
00123     double alpha = ( rr[ileft - 2] - rr[ileft - 1]) /
00124       ( rr[ileft -1] - rr[ileft]) ;
00125     double der_l = ( alpha*(alpha+2.)*tab[ileft] 
00126              - (1.+alpha)*(1.+alpha)*tab[ileft-1] 
00127              + tab[ileft-2] ) /
00128       ( (1.+alpha)*(rr[ileft - 1] - rr[ileft - 2]) ) ;
00129     double f_l = tab[ileft] ;
00130     double f_r = tab[iright] ;
00131     double tau = rr[ileft] - rr[iright] ;
00132     double alp = der_l / (tau*tau) + 2.*(f_r - f_l)/(tau*tau*tau) ;
00133     double bet = 0.5*(der_l + alp*tau*(rr[iright] - 3*rr[ileft])) / tau ;
00134     for (int i=ileft; i<iright; i++) {
00135       tab[i] = f_r + (alp*rr[i]+bet)*(rr[i] - rr[iright])*(rr[i] - rr[iright]);
00136     }
00137   }
00138   else { // too few points to interpolate -> linear extrapolation ...
00139     int ileft = indice ;
00140     double alpha = ( rr[ileft - 2] - rr[ileft - 1]) /
00141       ( rr[ileft -1] - rr[ileft]) ;
00142     double der_l = ( alpha*(alpha+2.)*tab[ileft] 
00143              - (1.+alpha)*(1.+alpha)*tab[ileft-1] 
00144              + tab[ileft-2] ) /
00145       ( (1.+alpha)*(rr[ileft - 1] - rr[ileft - 2]) ) ;
00146     for (int i=ileft; i<n; i++) {
00147       tab[i] = tab[ileft] + (rr[i] - rr[ileft])*der_l ;
00148     }    
00149   }
00150   return ;
00151 }

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