/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! !! !! GNU General Public License !! !! !! !! This file is part of the Flexible Modeling System (FMS). !! !! !! !! FMS is free software; you can redistribute it and/or modify !! !! it and are expected to follow the terms of the GNU General Public !! !! License as published by the Free Software Foundation. !! !! !! !! FMS is distributed in the hope that it will be useful, !! !! but WITHOUT ANY WARRANTY; without even the implied warranty of !! !! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the !! !! GNU General Public License for more details. !! !! !! !! You should have received a copy of the GNU General Public License !! !! along with FMS; if not, write to: !! !! Free Software Foundation, Inc. !! !! 59 Temple Place, Suite 330 !! !! Boston, MA 02111-1307 USA !! !! or see: !! !! http://www.gnu.org/licenses/gpl.txt !! !! !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ #include #include #include "mosaic_util.h" #include "interp.h" #include "create_xgrid.h" /********************************************************************* void cublic_spline(size1, size2, grid1, grid2, data1, data2, yp1, ypn ) This alborithm is to get an interpolation formula that is smooth in the first derivative, and continuous in the second derivative, both within an interval and its boundaries. It will be used to interpolation data in 1-D space. INPUT Arguments: grid1: grid for input data grid. grid2: grid for output data grid. size1: size of input grid. size2: size of output grid. data1: input data associated with grid1. yp1: first derivative of starting point. Set to 0 to be "natural" (INPUT) ypn: first derivative of ending point. Set to 0 to be "natural" (INPUT) OUTPUT ARGUMENTS: data2: output data associated with grid2. (OUTPUT) *********************************************************************/ void cubic_spline(int size1, int size2, const double *grid1, const double *grid2, const double *data1, double *data2, double yp1, double ypn ) { double *y2=NULL, *u=NULL; double p, sig, qn, un, h, a, b; int i, k, n, klo, khi; for(i=1; i grid1[size1-1]) error_handler("cubic_spline: grid2 lies outside grid1"); } if(size1 < 2) error_handler("cubic_spline: the size of input grid should be at least 2"); if(size1 == 2) { /* when size1 is 2, it just reduced to a linear interpolation */ p = (data1[1]-data1[0])/(grid1[1]-grid1[0]); for(i=0; i< size2; i++) data2[i] = p*(grid2[i] - grid1[0]) + data1[0]; return; } y2 = (double *)malloc(size1*sizeof(double)); u = (double *)malloc(size1*sizeof(double)); if (yp1 >.99e30) { y2[0]=0.; u[0]=0.; } else { y2[0]=-0.5; u[0]=(3./(grid1[1]-grid1[0]))*((data1[1]-data1[0])/(grid1[1]-grid1[0])-yp1); } for(i=1; i .99e30) { qn=0.; un=0.; } else { qn=0.5; un=(3./(grid1[size1-1]-grid1[size1-2]))*(ypn-(data1[size1-1]-data1[size1-2])/(grid1[size1-1]-grid1[size1-2])); } y2[size1-1]=(un-qn*u[size1-2])/(qn*y2[size1-2]+1.); for(k=size1-2; k>=0; k--) y2[k] = y2[k]*y2[k+1]+u[k]; /* interpolate data onto grid2 */ for(k=0; k