1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236
|
subroutine levinterpol(yy,nxmax,nymax,nzmax,nx,ny,memind,
+xt,yt,level,itime1,itime2,itime,indexf,yint)
C i i i i i i i
C i i i i i i i o
*****************************************************************************
* *
* Interpolation of 3-dimensional meteorological fields. *
* In horizontal direction bicubic interpolation interpolation is used. *
* In the temporal direction linear interpolation is used. *
* These interpolation techniques have been found to be most accurate. *
* *
* The interpolation routines have been taken from: *
* Press W.H. et al. (1992): Numerical Recipes in FORTRAN. The art of *
* scientific computing. 2nd edition. Cambridge University Press. *
* *
* But they have been modified for faster performance. *
* *
* 4-3 *
* | | The points are numbered in this order. Values and gradients are *
* 1-2 stored in fields with dimension 4. *
* *
* 1 is the first time *
* 2 is the second time *
* *
* *
* Author: A. Stohl *
* *
* 30 May 1994 *
* *
*****************************************************************************
* *
* Variables: *
* *
* dt1,dt2 time differences between fields and current position *
* indexf indicates the number of the wind field to be read in *
* indexfh help variable *
* level help variable *
* itime current time *
* itime1 time of the first wind field *
* itime2 time of the second wind field *
* ix,jy x,y coordinates of lower left subgrid point *
* level level for which interpolation shall be done *
* memind(3) points to the places of the wind fields *
* nx,ny actual field dimensions in x,y and z direction *
* nxmax,nymax,nzmax maximum field dimensions in x,y and z direction *
* x1l,x2l x,y coordinates of lower left subgrid point *
* x1u,x2u x,y coordinates of upper right subgrid point *
* xt current x coordinate *
* y(4,2,1) subset of 4 points for 2 times and 1 level *
* ygx(4,2,1) x gradients at 4 points for 2 times and 1 level *
* ygy(4,2,1) y gradients at 4 points for 2 times and 1 level *
* ygxy(4,2,1) x,y gradients at 4 points for 2 times and 1 level *
* yhelp(2,1) the interpolated values for 2 times and 1 level *
* yint the final interpolated value *
* yt current y coordinate *
* yy(0:nxmax,0:nymax,nzmax,3) meteorological field used for interpolation *
* *
*****************************************************************************
implicit none
integer nx,ny,nxmax,nymax,nzmax,memind(3),i,j,l,m,n,ix,jy
integer level,itime,itime1,itime2,indexf,indexfh,im,ip,jm,jp
real yy(0:nxmax-1,0:nymax-1,nzmax,3)
real y(4,2,1),ygx(4,2,1),ygy(4,2,1),ygxy(4,2,1),yhelp(2,1)
real x1l,x1u,x2l,x2u,dt1,dt2
real xt,yt,yint
C If point at border of grid -> small displacement into grid
************************************************************
if (xt.ge.float(nx-1)) xt=float(nx-1)-0.00001
if (yt.ge.float(ny-1)) yt=float(ny-1)-0.00001
***********************************************************************
C 1.) Bicubic horizontal interpolation
C This has to be done separately for 2 fields (Temporal)
***********************************************************************
C Determine the lower left corner
*********************************
ix=int(xt)
jy=int(yt)
x1l=float(ix)
x1u=float(ix+1)
x2l=float(jy)
x2u=float(jy+1)
C Loop over the 2*2 grid points
*******************************
do 10 l=1,4
if (l.eq.1) then
i=ix
j=jy
else if (l.eq.2) then
i=ix+1
j=jy
else if (l.eq.3) then
i=ix+1
j=jy+1
else if (l.eq.4) then
i=ix
j=jy+1
endif
ip=i+1
im=i-1
jp=j+1
jm=j-1
C Loop over 2 time steps and 3 levels
*************************************
do 10 m=1,2
do 10 n=1,1 ! this loop and dimension is necessary to be in
! agreement with the full 3-d interpolation
indexfh=memind(indexf+m-1)
C Values at the 2*2 subgrid
***************************
y(l,m,n)=yy(i,j,level,indexfh)
C Calculate derivatives in x-direction on the 2*2 subgrid
*********************************************************
if (i.eq.0) then
ygx(l,m,n) = yy(ip,j ,level,indexfh)
+ - yy(i ,j ,level,indexfh)
else if (i.eq.nx-1) then
ygx(l,m,n) = yy(i ,j ,level,indexfh)
+ - yy(im,j ,level,indexfh)
else
ygx(l,m,n) =(yy(ip,j ,level,indexfh)
+ - yy(im,j ,level,indexfh))/2.
endif
C Calculate derivatives in y-direction on the 2*2 subgrid
*********************************************************
if (j.eq.0) then
ygy(l,m,n) = yy(i ,jp,level,indexfh)
+ - yy(i ,j ,level,indexfh)
else if (j.eq.ny-1) then
ygy(l,m,n) = yy(i ,j ,level,indexfh)
+ - yy(i ,jm,level,indexfh)
else
ygy(l,m,n) =(yy(i ,jp,level,indexfh)
+ - yy(i ,jm,level,indexfh))/2.
endif
C Calculate cross derivative on the 2*2 subgrid
***********************************************
if ((i.eq.0).and.(j.eq.0)) then
ygxy(l,m,n)= yy(ip,jp,level,indexfh)-
+ yy(ip,j ,level,indexfh)-
+ yy(i ,jp,level,indexfh)+
+ yy(i ,j ,level,indexfh)
else if ((i.eq.nx-1).and.(j.eq.ny-1)) then
ygxy(l,m,n)= yy(i ,j ,level,indexfh)-
+ yy(i ,jm,level,indexfh)-
+ yy(im,j ,level,indexfh)+
+ yy(im,jm,level,indexfh)
else if ((i.eq.0).and.(j.eq.ny-1)) then
ygxy(l,m,n)= yy(ip,j ,level,indexfh)-
+ yy(ip,jm,level,indexfh)-
+ yy(i ,j ,level,indexfh)+
+ yy(i ,jm,level,indexfh)
else if ((i.eq.nx-1).and.(j.eq.0)) then
ygxy(l,m,n)= yy(i ,jp,level,indexfh)-
+ yy(i ,j ,level,indexfh)-
+ yy(im,jp,level,indexfh)+
+ yy(im,j ,level,indexfh)
else if (i.eq.nx-1) then
ygxy(l,m,n)=(yy(i ,jp,level,indexfh)-
+ yy(i ,jm,level,indexfh)-
+ yy(im,jp,level,indexfh)+
+ yy(im,jm,level,indexfh))/2.
else if (i.eq.0) then
ygxy(l,m,n)=(yy(ip,jp,level,indexfh)-
+ yy(ip,jm,level,indexfh)-
+ yy(i ,jp,level,indexfh)+
+ yy(i ,jm,level,indexfh))/2.
else if (j.eq.ny-1) then
ygxy(l,m,n)=(yy(ip,j ,level,indexfh)-
+ yy(ip,jm,level,indexfh)-
+ yy(im,j ,level,indexfh)+
+ yy(im,jm,level,indexfh))/2.
else if (j.eq.0) then
ygxy(l,m,n)=(yy(ip,jp,level,indexfh)-
+ yy(ip,j ,level,indexfh)-
+ yy(im,jp,level,indexfh)+
+ yy(im,j ,level,indexfh))/2.
else
ygxy(l,m,n)=(yy(ip,jp,level,indexfh)-
+ yy(ip,jm,level,indexfh)-
+ yy(im,jp,level,indexfh)+
+ yy(im,jm,level,indexfh))/4.
endif
10 continue
C Call bicubic interpolation
****************************
call bicubic(y,ygx,ygy,ygxy,x1l,x1u,x2l,x2u,xt,yt,yhelp,2,1)
*************************************
C 2.) Temporal interpolation (linear)
*************************************
dt1=float(itime-itime1)
dt2=float(itime2-itime)
yint=(yhelp(1,1)*dt2+yhelp(2,1)*dt1)/(dt1+dt2)
return
end
|