interpol_herm.C

00001 /*
00002  * Hermite interpolation of degree 3
00003  *
00004  */
00005 
00006 /*
00007  *   Copyright (c) 2000-2002 Eric Gourgoulhon
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 as published by
00013  *   the Free Software Foundation; either version 2 of the License, or
00014  *   (at your option) any later version.
00015  *
00016  *   LORENE is distributed in the hope that it will be useful,
00017  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *   GNU General Public License for more details.
00020  *
00021  *   You should have received a copy of the GNU General Public License
00022  *   along with LORENE; if not, write to the Free Software
00023  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00024  *
00025  */
00026 
00027 
00028 char interpol_herm_C[] = "$Header: /cvsroot/Lorene/C++/Source/Non_class_members/Utilities/interpol_herm.C,v 1.7 2011/10/04 16:05:19 j_novak Exp $" ;
00029 
00030 /*
00031  * $Id: interpol_herm.C,v 1.7 2011/10/04 16:05:19 j_novak Exp $
00032  * $Log: interpol_herm.C,v $
00033  * Revision 1.7  2011/10/04 16:05:19  j_novak
00034  * Update of Eos_mag class. Suppression of loge, re-definition of the derivatives
00035  * and use of interpol_herm_2d.
00036  *
00037  * Revision 1.6  2011/10/03 13:44:45  j_novak
00038  * Updated the y-derivative for the 2D version
00039  *
00040  * Revision 1.5  2011/09/27 15:38:11  j_novak
00041  * New function for 2D interpolation added. The computation of 1st derivative is
00042  * still missing.
00043  *
00044  * Revision 1.4  2003/11/21 16:14:51  m_bejger
00045  * Added the linear interpolation
00046  *
00047  * Revision 1.3  2003/05/15 09:42:12  e_gourgoulhon
00048  * Added the new function interpol_herm_der
00049  *
00050  * Revision 1.2  2002/09/09 13:00:40  e_gourgoulhon
00051  * Modification of declaration of Fortran 77 prototypes for
00052  * a better portability (in particular on IBM AIX systems):
00053  * All Fortran subroutine names are now written F77_* and are
00054  * defined in the new file C++/Include/proto_f77.h.
00055  *
00056  * Revision 1.1.1.1  2001/11/20 15:19:29  e_gourgoulhon
00057  * LORENE
00058  *
00059  * Revision 2.0  2000/11/22  19:31:42  eric
00060  * *** empty log message ***
00061  *
00062  *
00063  * $Header: /cvsroot/Lorene/C++/Source/Non_class_members/Utilities/interpol_herm.C,v 1.7 2011/10/04 16:05:19 j_novak Exp $
00064  *
00065  */
00066 
00067 // Headers Lorene
00068 #include "tbl.h"
00069 
00070 // Prototypes of F77 subroutines
00071 #include "proto_f77.h"
00072 
00073 // Linear interpolation 
00074 void interpol_linear(const Tbl& xtab, const Tbl& ytab, 
00075                      double x, int& i, double& y) {
00076 
00077     assert(ytab.dim == xtab.dim) ;
00078     //assert(dytab.dim == xtab.dim) ;   
00079     
00080     int np = xtab.get_dim(0) ;
00081     
00082     F77_huntm(xtab.t, &np, &x, &i) ;
00083     
00084     i-- ;   // Fortran --> C
00085     
00086     int i1 = i + 1 ;
00087     
00088     // double dx  = xtab(i1) - xtab(i) ;
00089         double y1  = ytab(i) ;
00090         double y2  = ytab(i1) ;
00091 
00092         double x1  = xtab(i) ;
00093         double x2  = xtab(i1) ;
00094         double x12 = x1-x2 ;
00095   
00096 
00097         double a  = (y1-y2)/x12 ;
00098         double b  = (x1*y2-y1*x2)/x12 ;
00099     
00100         y  = x*a+b ; 
00101 
00102 }
00103 
00104 // Version returning the function and its first derivative 
00105 void interpol_herm(const Tbl& xtab, const Tbl& ytab, const Tbl& dytab,
00106            double x, int& i, double& y, double& dy) {
00107 
00108     assert(ytab.dim == xtab.dim) ;
00109     assert(dytab.dim == xtab.dim) ; 
00110     
00111     int np = xtab.get_dim(0) ;
00112     
00113     F77_huntm(xtab.t, &np, &x, &i) ;
00114     
00115     i-- ;   // Fortran --> C
00116     
00117     int i1 = i + 1 ;
00118     
00119     double dx = xtab(i1) - xtab(i) ;
00120 
00121     double u = (x - xtab(i)) / dx ;
00122     double u2 = u*u ;
00123     double u3 = u2*u ;
00124     
00125     y =   ytab(i) * ( 2.*u3 - 3.*u2 + 1.)
00126         + ytab(i1) * ( 3.*u2 - 2.*u3)
00127             + dytab(i) * dx * ( u3 - 2.*u2 + u )
00128             - dytab(i1) * dx * ( u2 - u3 ) ;
00129         
00130     dy =   6. * ( ytab(i) / dx * ( u2 - u )
00131          - ytab(i1) / dx * ( u2 - u ) )
00132              + dytab(i) * ( 3.*u2 - 4.*u + 1. )
00133              + dytab(i1) * ( 3.*u2 - 2.*u ) ;
00134     
00135                 
00136 }
00137 
00138 
00139 // Version returning the second derivative 
00140 void interpol_herm_der(const Tbl& xtab, const Tbl& ytab, const Tbl& dytab,
00141            double x, int& i, double& y, double& dy, double& ddy) {
00142 
00143     assert(ytab.dim == xtab.dim) ;
00144     assert(dytab.dim == xtab.dim) ; 
00145     
00146     int np = xtab.get_dim(0) ;
00147     
00148     F77_huntm(xtab.t, &np, &x, &i) ;
00149     
00150     i-- ;   // Fortran --> C
00151     
00152     int i1 = i + 1 ;
00153     
00154     double dx = xtab(i1) - xtab(i) ;
00155 
00156     double u = (x - xtab(i)) / dx ;
00157     double u2 = u*u ;
00158     double u3 = u2*u ;
00159     
00160     y =   ytab(i) * ( 2.*u3 - 3.*u2 + 1.)
00161         + ytab(i1) * ( 3.*u2 - 2.*u3)
00162             + dytab(i) * dx * ( u3 - 2.*u2 + u )
00163             - dytab(i1) * dx * ( u2 - u3 ) ;
00164         
00165     dy =   6. * ( ytab(i) - ytab(i1) ) * ( u2 - u ) / dx 
00166              + dytab(i) * ( 3.*u2 - 4.*u + 1. )
00167              + dytab(i1) * ( 3.*u2 - 2.*u ) ;
00168          
00169     ddy = 6 * ( ( ytab(i) - ytab(i1) ) * ( 2.*u - 1. ) / dx
00170         +  dytab(i) * (6.*u - 4.)
00171         +  dytab(i1) * (6.*u - 2.) ) / dx ; 
00172                 
00173 }
00174 
00175 
00176 void interpol_herm_2d(const Tbl& xtab, const Tbl& ytab, const Tbl& ftab, 
00177               const Tbl& dfdxtab, const Tbl& dfdytab, const Tbl& d2fdxdytab,
00178               double x, double y, double& f, double& dfdy) {
00179 
00180   assert(ytab.dim == xtab.dim) ;
00181   assert(ftab.dim == xtab.dim) ;
00182   assert(dfdxtab.dim == xtab.dim) ;
00183   assert(dfdytab.dim == xtab.dim) ;
00184   assert(d2fdxdytab.dim == xtab.dim) ;
00185   
00186   int nbp1, nbp2;
00187   nbp1 = xtab.get_dim(0);
00188   nbp2 = xtab.get_dim(1);
00189   
00190   int i_near = 0 ;
00191   int j_near = 0 ;
00192 
00193   while ((xtab(i_near,0) <= x) && (nbp2 > i_near)) {
00194     i_near++; 
00195   }
00196   if (i_near != 0) {
00197     i_near-- ; 
00198   }
00199   j_near = 0;
00200   while ((ytab(i_near,j_near) < y) && (nbp1 > j_near)) {
00201     j_near++ ;
00202   }
00203   if (j_near != 0) {
00204     j_near-- ; 
00205   }
00206   
00207   int i1 = i_near+1 ; int j1 = j_near+1 ;
00208 
00209   double dx = xtab(i1, j_near) - xtab(i_near, j_near) ;
00210   double dy = ytab(i_near, j1) - ytab(i_near, j_near) ;
00211 
00212   double u = (x - xtab(i_near, j_near)) / dx ;
00213   double v = (y - ytab(i_near, j_near)) / dy ;
00214 
00215   double u2 = u*u ; double v2 = v*v ;
00216   double u3 = u2*u ; double v3 = v2*v ;
00217 
00218   double psi0_u = 2.*u3 - 3.*u2 + 1. ;
00219   double psi0_1mu = -2.*u3 + 3.*u2 ;
00220   double psi1_u = u3 - 2.*u2 + u ;
00221   double psi1_1mu = -u3 + u2 ;
00222 
00223   double psi0_v = 2.*v3 - 3.*v2 + 1. ;
00224   double psi0_1mv = -2.*v3 + 3.*v2 ;
00225   double psi1_v = v3 - 2.*v2 + v ;
00226   double psi1_1mv = -v3 + v2 ;
00227 
00228   f = ftab(i_near, j_near) * psi0_u * psi0_v
00229     + ftab(i1, j_near) * psi0_1mu * psi0_v 
00230     + ftab(i_near, j1) * psi0_u * psi0_1mv
00231     + ftab(i1, j1)  * psi0_1mu * psi0_1mv ;
00232 
00233   f += (dfdxtab(i_near, j_near) * psi1_u * psi0_v
00234     - dfdxtab(i1, j_near) * psi1_1mu * psi0_v
00235     + dfdxtab(i_near, j1) * psi1_u * psi0_1mv
00236     - dfdxtab(i1, j1) * psi1_1mu * psi0_1mv) * dx ;
00237 
00238   f += (dfdytab(i_near, j_near) * psi0_u * psi1_v
00239     + dfdytab(i1, j_near) * psi0_1mu * psi1_v
00240     - dfdytab(i_near, j1) * psi0_u * psi1_1mv
00241     - dfdytab(i1, j1) * psi0_1mu * psi1_1mv) * dy ;
00242   
00243   f += (d2fdxdytab(i_near, j_near) * psi1_u * psi1_v
00244     - d2fdxdytab(i1, j_near) * psi1_1mu * psi1_v
00245     - d2fdxdytab(i_near, j1) * psi1_u * psi1_1mv 
00246     + d2fdxdytab(i1, j1) * psi1_1mu * psi1_1mv) * dx * dy ;
00247 
00248   double dpsi0_v = 6.*(v2 - v) ;
00249   double dpsi0_1mv = 6.*(v2 - v) ;
00250   double dpsi1_v = 3.*v2 - 4.*v + 1. ;
00251   double dpsi1_1mv = 3.*v2 - 2.*v ;
00252 
00253 
00254   dfdy = (ftab(i_near, j_near) * psi0_u * dpsi0_v
00255     + ftab(i1, j_near) * psi0_1mu * dpsi0_v 
00256     - ftab(i_near, j1) * psi0_u * dpsi0_1mv
00257       - ftab(i1, j1)  * psi0_1mu * dpsi0_1mv) / dy ;
00258 
00259   dfdy += (dfdxtab(i_near, j_near) * psi1_u * dpsi0_v
00260     - dfdxtab(i1, j_near) * psi1_1mu * dpsi0_v
00261     - dfdxtab(i_near, j1) * psi1_u * dpsi0_1mv
00262     + dfdxtab(i1, j1) * psi1_1mu * dpsi0_1mv) * dx / dy ;
00263 
00264   dfdy += (dfdytab(i_near, j_near) * psi0_u * dpsi1_v
00265     + dfdytab(i1, j_near) * psi0_1mu * dpsi1_v
00266     + dfdytab(i_near, j1) * psi0_u * dpsi1_1mv
00267     + dfdytab(i1, j1) * psi0_1mu * dpsi1_1mv) ;
00268   
00269   dfdy += (d2fdxdytab(i_near, j_near) * psi1_u * dpsi1_v
00270     - d2fdxdytab(i1, j_near) * psi1_1mu * dpsi1_v
00271     + d2fdxdytab(i_near, j1) * psi1_u * dpsi1_1mv 
00272     - d2fdxdytab(i1, j1) * psi1_1mu * dpsi1_1mv) * dx ;
00273 
00274 
00275   return ;
00276 
00277 }

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