Blame | Last modification | View Log | Download | RSS feed
real function int2d(ar,n1,n2,rid,rjd)c-----------------------------------------------------------------------c Purpose:c This subroutine interpolates a 2d-array to an arbitraryc location within the grid.c Arguments:c ar real input surface pressure, define as ar(n1,n2)c n1,n2 int input dimensions of arc ri,rj real input grid location to be interpolated toc History:c-----------------------------------------------------------------------c argument declarationsinteger n1,n2real ar(n1,n2), rid,rjdc local declarationsinteger i,j,ip1,jp1,ih,jhreal frac0i,frac0j,frac1i,frac1j,ri,rjc do linear interpolationri=amax1(1.,amin1(float(n1),rid))rj=amax1(1.,amin1(float(n2),rjd))ih=nint(ri)jh=nint(rj)c Check for interpolation in i* if (abs(float(ih)-ri).lt.1.e-3) then* i =ih* ip1=ih* elsei =min0(int(ri),n1-1)ip1=i+1* endifc Check for interpolation in j* if (abs(float(jh)-rj).lt.1.e-3) then* j =jh* jp1=jh* elsej =min0(int(rj),n2-1)jp1=j+1* endifif ((i.eq.ip1).and.(j.eq.jp1)) thenc no interpolation at allint2d=ar(i,j)elsefrac0i=ri-float(i)frac0j=rj-float(j)frac1i=1.-frac0ifrac1j=1.-frac0jint2d = ar(i ,j ) * frac1i * frac1j& + ar(i ,jp1) * frac1i * frac0j& + ar(ip1,j ) * frac0i * frac1j& + ar(ip1,jp1) * frac0i * frac0jendifendreal function int2dm(ar,n1,n2,rid,rjd,misdat)c-----------------------------------------------------------------------c Purpose:c This subroutine interpolates a 2d-array to an arbitraryc location within the grid. The interpolation includes thec testing of the missing data flag 'misdat'.c Arguments:c ar real input surface pressure, define as ar(n1,n2)c n1,n2 int input dimensions of arc ri,rj real input grid location to be interpolated toc misdat real input missing data flag (on if misdat<>0)c Warning:c This routine has not yet been seriously testedc History:c-----------------------------------------------------------------------c argument declarationsinteger n1,n2real ar(n1,n2), rid,rjd, misdatc local declarationsinteger i,j,ip1,jp1,ih,jhreal frac0i,frac0j,frac1i,frac1j,ri,rj,int2dc check if routine without missing data checking can be called insteadif (misdat.eq.0.) thenint2dm=int2d(ar,n1,n2,rid,rjd)returnendifc do linear interpolationri=amax1(1.,amin1(float(n1),rid))rj=amax1(1.,amin1(float(n2),rjd))ih=nint(ri)jh=nint(rj)c Check for interpolation in i* if (abs(float(ih)-ri).lt.1.e-3) then* i =ih* ip1=ih* elsei =min0(int(ri),n1-1)ip1=i+1* endifc Check for interpolation in j* if (abs(float(jh)-rj).lt.1.e-3) then* j =jh* jp1=jh* elsej =min0(int(rj),n2-1)jp1=j+1* endifif ((i.eq.ip1).and.(j.eq.jp1)) thenc no interpolation at allint2dm=ar(i,j)elseif ((misdat.eq.ar(i ,j )).or.& (misdat.eq.ar(i ,jp1)).or.& (misdat.eq.ar(ip1,j )).or.& (misdat.eq.ar(ip1,jp1))) thenint2dm=misdatelsefrac0i=ri-float(i)frac0j=rj-float(j)frac1i=1.-frac0ifrac1j=1.-frac0jint2dm = ar(i ,j ) * frac1i * frac1j& + ar(i ,jp1) * frac1i * frac0j& + ar(ip1,j ) * frac0i * frac1j& + ar(ip1,jp1) * frac0i * frac0jendifendifendreal function int2dp(ar,n1,n2,rid,rjd)c-----------------------------------------------------------------------c Purpose:c This subroutine interpolates a 2d-array to an arbitraryc location within the grid. The 2d-array is periodic in thec i-direction: ar(0,.)=ar(n1,.) and ar(1,.)=ar(n1+1,.).c Therefore rid can take values in the range 0,...,n1+1c Arguments:c ar real input surface pressure, define as ar(n1,n2)c n1,n2 int input dimensions of arc ri,rj real input grid location to be interpolated toc History:c-----------------------------------------------------------------------c argument declarationsinteger n1,n2real ar(0:n1+1,n2), rid,rjdc local declarationsinteger i,j,ip1,jp1,ih,jhreal frac0i,frac0j,frac1i,frac1j,ri,rjc do linear interpolationri=amax1(0.,amin1(float(n1+1),rid))rj=amax1(1.,amin1(float(n2),rjd))ih=nint(ri)jh=nint(rj)c Check for interpolation in i* if (abs(float(ih)-ri).lt.1.e-5) then* i =ih* ip1=ih* elsei =min0(int(ri),n1-1)ip1=i+1* endifc Check for interpolation in j* if (abs(float(jh)-rj).lt.1.e-5) then* j =jh* jp1=jh* elsej =min0(int(rj),n2-1)jp1=j+1* endifif ((i.eq.ip1).and.(j.eq.jp1)) thenc no interpolation at allint2dp=ar(i,j)elsefrac0i=ri-float(i)frac0j=rj-float(j)frac1i=1.-frac0ifrac1j=1.-frac0jint2dp = ar(i ,j ) * frac1i * frac1j& + ar(i ,jp1) * frac1i * frac0j& + ar(ip1,j ) * frac0i * frac1j& + ar(ip1,jp1) * frac0i * frac0jendifendreal function cint2d(ar,n1,n2,n3,rid,rjd,ikd)c-----------------------------------------------------------------------c Purpose:c This subroutine interpolates a 3d-array to an arbitraryc location in the horizontal. ikd specifies the level (mustc be an integer). A bicubic method is applied (followingc the Numerical Recipes).c Arguments:c ar real input field, define as ar(n1,n2,n3)c n1,n2 int input dimensions of arc rid,rjd real input grid location to be interpolated toc ikd int input level for interpolationc History:c-----------------------------------------------------------------------c argument declarationsinteger n1,n2,n3,ikdreal ar(n1,n2,n3), rid,rjdc local declarationsinteger i,j,kreal y(4),y1(4),y2(4),y12(4)c indices of lower left corner of interpolation gridi=int(rid)j=int(rjd)k=ikdc do not interpolate if i or j are at the boundariesif ((i.eq.1).or.(j.eq.1).or.(i.eq.n1).or.(j.eq.n2)) thencint2d=ar(i,j,k)returnendifc define the arrays y,y1,y2,y12 necessary for the bicubicc interpolation (following the Numerical Recipes).y(1)=ar(i,j,k)y(2)=ar(i+1,j,k)y(3)=ar(i+1,j+1,k)y(4)=ar(i,j+1,k)y1(1)=-(ar(i-1,j,k)-ar(i+1,j,k))/2.y1(2)=-(ar(i,j,k)-ar(i+2,j,k))/2.y1(3)=-(ar(i,j+1,k)-ar(i+2,j+1,k))/2.y1(4)=-(ar(i-1,j+1,k)-ar(i+1,j+1,k))/2.y2(1)=-(ar(i,j-1,k)-ar(i,j+1,k))/2.y2(2)=-(ar(i+1,j-1,k)-ar(i+1,j+1,k))/2.y2(3)=-(ar(i+1,j,k)-ar(i+1,j+2,k))/2.y2(4)=-(ar(i,j,k)-ar(i,j+2,k))/2.y12(1)=(ar(i+1,j+1,k)-ar(i+1,j-1,k)-ar(i-1,j+1,k)+ar(i-1,j-1,k))/4.y12(2)=(ar(i+2,j+1,k)-ar(i+2,j-1,k)-ar(i,j+1,k)+ar(i,j-1,k))/4.y12(3)=(ar(i+2,j+2,k)-ar(i+2,j,k)-ar(i,j+2,k)+ar(i,j,k))/4.y12(4)=(ar(i+1,j+2,k)-ar(i+1,j,k)-ar(i-1,j+2,k)+ar(i-1,j,k))/4.call bcuint(y,y1,y2,y12,i,j,rid,rjd,cint2d)returnendreal function int3d(ar,n1,n2,n3,rid,rjd,rkd)c-----------------------------------------------------------------------c Purpose:c This subroutine interpolates a 3d-array to an arbitraryc location within the grid.c Arguments:c ar real input surface pressure, define as ar(n1,n2,n3)c n1,n2,n3 int input dimensions of arc ri,rj,rk real input grid location to be interpolated toc History:c-----------------------------------------------------------------------c argument declarationsinteger n1,n2,n3real ar(n1,n2,n3), rid,rjd,rkdc local declarationsinteger i,j,k,ip1,jp1,kp1,ih,jh,khreal frac0i,frac0j,frac0k,frac1i,frac1j,frac1k,ri,rj,rkc do linear interpolationri=amax1(1.,amin1(float(n1),rid))rj=amax1(1.,amin1(float(n2),rjd))rk=amax1(1.,amin1(float(n3),rkd))ih=nint(ri)jh=nint(rj)kh=nint(rk)c Check for interpolation in i* if (abs(float(ih)-ri).lt.1.e-3) then* i =ih* ip1=ih* elsei =min0(int(ri),n1-1)ip1=i+1* endifc Check for interpolation in jif (abs(float(jh)-rj).lt.1.e-3) thenj =jhjp1=jhelsej =min0(int(rj),n2-1)jp1=j+1endifc Check for interpolation in k* if (abs(float(kh)-rk).lt.1.e-3) then* k =kh* kp1=kh* elsek =min0(int(rk),n3-1)kp1=k+1* endifif (k.eq.kp1) thenc no interpolation in kif ((i.eq.ip1).and.(j.eq.jp1)) thenc no interpolation at allint3d=ar(i,j,k)c print *,'int3d 00: ',rid,rjd,rkd,int3delsec horizontal interpolation onlyfrac0i=ri-float(i)frac0j=rj-float(j)frac1i=1.-frac0ifrac1j=1.-frac0jint3d = ar(i ,j ,k ) * frac1i * frac1j& + ar(i ,jp1,k ) * frac1i * frac0j& + ar(ip1,j ,k ) * frac0i * frac1j& + ar(ip1,jp1,k ) * frac0i * frac0jc print *,'int3d 10: ',rid,rjd,rkd,int3dendifelsefrac0k=rk-float(k)frac1k=1.-frac0kif ((i.eq.ip1).and.(j.eq.jp1)) thenc vertical interpolation onlyint3d = ar(i ,j ,k ) * frac1k& + ar(i ,j ,kp1) * frac0kc print *,'int3d 01: ',rid,rjd,rkd,int3delsec full 3d interpolationfrac0i=ri-float(i)frac0j=rj-float(j)frac1i=1.-frac0ifrac1j=1.-frac0jint3d = ar(i ,j ,k ) * frac1i * frac1j * frac1k& + ar(i ,jp1,k ) * frac1i * frac0j * frac1k& + ar(ip1,j ,k ) * frac0i * frac1j * frac1k& + ar(ip1,jp1,k ) * frac0i * frac0j * frac1k& + ar(i ,j ,kp1) * frac1i * frac1j * frac0k& + ar(i ,jp1,kp1) * frac1i * frac0j * frac0k& + ar(ip1,j ,kp1) * frac0i * frac1j * frac0k& + ar(ip1,jp1,kp1) * frac0i * frac0j * frac0kc print *,'int3d 11: ',rid,rjd,rkd,int3dendifendifendreal function int3dm(ar,n1,n2,n3,rid,rjd,rkd,misdat)c-----------------------------------------------------------------------c Purpose:c This subroutine interpolates a 3d-array to an arbitraryc location within the grid. The interpolation includes thec testing of the missing data flag 'misdat'.c Arguments:c ar real input surface pressure, define as ar(n1,n2,n3)c n1,n2,n3 int input dimensions of arc ri,rj,rk real input grid location to be interpolated toc misdat real input missing data flag (on if misdat<>0)c Warning:c This routine has not yet been seriously testedc History:c-----------------------------------------------------------------------c argument declarationsinteger n1,n2,n3real ar(n1,n2,n3), rid,rjd,rkd, misdatc local declarationsinteger i,j,k,ip1,jp1,kp1,ih,jh,khreal frac0i,frac0j,frac0k,frac1i,frac1j,frac1k,ri,rj,rk,int3dc check if routine without missing data checking can be called insteadif (misdat.eq.0.) thenint3dm=int3d(ar,n1,n2,n3,rid,rjd,rkd)returnendifc do linear interpolationri=amax1(1.,amin1(float(n1),rid))rj=amax1(1.,amin1(float(n2),rjd))rk=amax1(1.,amin1(float(n3),rkd))ih=nint(ri)jh=nint(rj)kh=nint(rk)c Check for interpolation in i* if (abs(float(ih)-ri).lt.1.e-3) then* i =ih* ip1=ih* elsei =min0(int(ri),n1-1)ip1=i+1* endifc Check for interpolation in j* if (abs(float(jh)-rj).lt.1.e-3) then* j =jh* jp1=jh* elsej =min0(int(rj),n2-1)jp1=j+1* endifc Check for interpolation in k* if (abs(float(kh)-rk).lt.1.e-3) then* k =kh* kp1=kh* elsek =min0(int(rk),n3-1)kp1=k+1* endifif (k.eq.kp1) thenc no interpolation in kif ((i.eq.ip1).and.(j.eq.jp1)) thenc no interpolation at allif (misdat.eq.ar(i,j,k)) thenint3dm=misdatelseint3dm=ar(i,j,k)endifc print *,'int3dm 00: ',rid,rjd,rkd,int3dmelsec horizontal interpolation onlyif ((misdat.eq.ar(i ,j ,k )).or.& (misdat.eq.ar(i ,jp1,k )).or.& (misdat.eq.ar(ip1,j ,k )).or.& (misdat.eq.ar(ip1,jp1,k ))) thenint3dm=misdatelsefrac0i=ri-float(i)frac0j=rj-float(j)frac1i=1.-frac0ifrac1j=1.-frac0jint3dm = ar(i ,j ,k ) * frac1i * frac1j& + ar(i ,jp1,k ) * frac1i * frac0j& + ar(ip1,j ,k ) * frac0i * frac1j& + ar(ip1,jp1,k ) * frac0i * frac0jc print *,'int3dm 10: ',rid,rjd,rkd,int3dmendifendifelsefrac0k=rk-float(k)frac1k=1.-frac0kif ((i.eq.ip1).and.(j.eq.jp1)) thenc vertical interpolation onlyif ((misdat.eq.ar(i ,j ,k )).or.& (misdat.eq.ar(i ,j ,kp1))) thenint3dm=misdatelseint3dm = ar(i ,j ,k ) * frac1k& + ar(i ,j ,kp1) * frac0kc print *,'int3dm 01: ',rid,rjd,rkd,int3dmendifelsec full 3d interpolationif ((misdat.eq.ar(i ,j ,k )).or.& (misdat.eq.ar(i ,jp1,k )).or.& (misdat.eq.ar(ip1,j ,k )).or.& (misdat.eq.ar(ip1,jp1,k )).or.& (misdat.eq.ar(i ,j ,kp1)).or.& (misdat.eq.ar(i ,jp1,kp1)).or.& (misdat.eq.ar(ip1,j ,kp1)).or.& (misdat.eq.ar(ip1,jp1,kp1))) thenint3dm=misdatelsefrac0i=ri-float(i)frac0j=rj-float(j)frac1i=1.-frac0ifrac1j=1.-frac0jint3dm = ar(i ,j ,k ) * frac1i * frac1j * frac1k& + ar(i ,jp1,k ) * frac1i * frac0j * frac1k& + ar(ip1,j ,k ) * frac0i * frac1j * frac1k& + ar(ip1,jp1,k ) * frac0i * frac0j * frac1k& + ar(i ,j ,kp1) * frac1i * frac1j * frac0k& + ar(i ,jp1,kp1) * frac1i * frac0j * frac0k& + ar(ip1,j ,kp1) * frac0i * frac1j * frac0k& + ar(ip1,jp1,kp1) * frac0i * frac0j * frac0kc print *,'int3dm 11: ',rid,rjd,rkd,int3dmendifendifendifendreal function int3dmlog(ar,n1,n2,n3,rid,rjd,rkd,misdat)c-----------------------------------------------------------------------c Purpose:c This subroutine interpolates a 3d-array to an arbitraryc location within the grid. The interpolation includes thec testing of the missing data flag 'misdat'.c Prior to vertical interpolations the log is taken from the array.c Arguments:c ar real input surface pressure, define as ar(n1,n2,n3)c n1,n2,n3 int input dimensions of arc ri,rj,rk real input grid location to be interpolated toc misdat real input missing data flag (on if misdat<>0)c Warning:c This routine has not yet been seriously testedc History:c-----------------------------------------------------------------------c argument declarationsinteger n1,n2,n3real ar(n1,n2,n3), rid,rjd,rkd, misdatc local declarationsinteger i,j,k,ip1,jp1,kp1,ih,jh,khreal frac0i,frac0j,frac0k,frac1i,frac1j,frac1k,ri,rj,rk,int3dc print*,'hallo in SR int3dmlog'c check if routine without missing data checking can be called insteadif (misdat.eq.0.) thenint3dmlog=int3d(ar,n1,n2,n3,rid,rjd,rkd)returnendifc do linear interpolationri=amax1(1.,amin1(float(n1),rid))rj=amax1(1.,amin1(float(n2),rjd))rk=amax1(1.,amin1(float(n3),rkd))ih=nint(ri)jh=nint(rj)kh=nint(rk)c Check for interpolation in i* if (abs(float(ih)-ri).lt.1.e-3) then* i =ih* ip1=ih* elsei =min0(int(ri),n1-1)ip1=i+1* endifc Check for interpolation in j* if (abs(float(jh)-rj).lt.1.e-3) then* j =jh* jp1=jh* elsej =min0(int(rj),n2-1)jp1=j+1* endifc Check for interpolation in k* if (abs(float(kh)-rk).lt.1.e-3) then* k =kh* kp1=kh* elsek =min0(int(rk),n3-1)kp1=k+1* endifif (k.eq.kp1) thenc no interpolation in kif ((i.eq.ip1).and.(j.eq.jp1)) thenc no interpolation at allif (misdat.eq.ar(i,j,k)) thenint3dmlog=misdatelseint3dmlog=ar(i,j,k)endifc print *,'int3dmlog 00: ',rid,rjd,rkd,int3dmlogelsec horizontal interpolation onlyif ((misdat.eq.ar(i ,j ,k )).or.& (misdat.eq.ar(i ,jp1,k )).or.& (misdat.eq.ar(ip1,j ,k )).or.& (misdat.eq.ar(ip1,jp1,k ))) thenint3dmlog=misdatelsefrac0i=ri-float(i)frac0j=rj-float(j)frac1i=1.-frac0ifrac1j=1.-frac0jint3dmlog = ar(i ,j ,k ) * frac1i * frac1j& + ar(i ,jp1,k ) * frac1i * frac0j& + ar(ip1,j ,k ) * frac0i * frac1j& + ar(ip1,jp1,k ) * frac0i * frac0jc print *,'int3dmlog 10: ',rid,rjd,rkd,int3dmlogendifendifelsefrac0k=rk-float(k)frac1k=1.-frac0kif ((i.eq.ip1).and.(j.eq.jp1)) thenc vertical interpolation onlyif ((misdat.eq.ar(i ,j ,k )).or.& (misdat.eq.ar(i ,j ,kp1))) thenint3dmlog=misdatelseint3dmlog = log(ar(i ,j ,k )) * frac1k& + log(ar(i ,j ,kp1)) * frac0kint3dmlog = exp(int3dmlog)c print *,'int3dmlog 01: ',rid,rjd,rkd,int3dmlogendifelsec full 3d interpolationif ((misdat.eq.ar(i ,j ,k )).or.& (misdat.eq.ar(i ,jp1,k )).or.& (misdat.eq.ar(ip1,j ,k )).or.& (misdat.eq.ar(ip1,jp1,k )).or.& (misdat.eq.ar(i ,j ,kp1)).or.& (misdat.eq.ar(i ,jp1,kp1)).or.& (misdat.eq.ar(ip1,j ,kp1)).or.& (misdat.eq.ar(ip1,jp1,kp1))) thenint3dmlog=misdatelsefrac0i=ri-float(i)frac0j=rj-float(j)frac1i=1.-frac0ifrac1j=1.-frac0jint3dmlog = log(ar(i ,j ,k )) * frac1i * frac1j * frac1k& + log(ar(i ,jp1,k )) * frac1i * frac0j * frac1k& + log(ar(ip1,j ,k )) * frac0i * frac1j * frac1k& + log(ar(ip1,jp1,k )) * frac0i * frac0j * frac1k& + log(ar(i ,j ,kp1)) * frac1i * frac1j * frac0k& + log(ar(i ,jp1,kp1)) * frac1i * frac0j * frac0k& + log(ar(ip1,j ,kp1)) * frac0i * frac1j * frac0k& + log(ar(ip1,jp1,kp1)) * frac0i * frac0j * frac0kint3dmlog = exp(int3dmlog)c print *,'int3dmlog 11: ',rid,rjd,rkd,int3dmlogendifendifendifendreal function int3dmvc(ar,n1,n2,n3,rid,rjd,rkd,misdat)c-----------------------------------------------------------------------c Purpose:c This subroutine interpolates a 3d-array to an arbitraryc location within the grid. The interpolation includes thec testing of the missing data flag 'misdat'.c In the vertical a Lagrangian cubic interpolation isc performed.c Arguments:c ar real input surface pressure, define as ar(n1,n2,n3)c n1,n2,n3 int input dimensions of arc ri,rj,rk real input grid location to be interpolated toc misdat real input missing data flag (on if misdat<>0)c Warning:c This routine has not yet been seriously testedc History:c-----------------------------------------------------------------------c argument declarationsinteger n1,n2,n3real ar(n1,n2,n3), rid,rjd,rkd, misdatc local declarationsinteger i,j,k,ip1,jp1,kp1,ih,jh,kh,klow,nreal frac0i,frac0j,frac1i,frac1j,ri,rj,rkreal int2d(4)real int3dmc if n3 < 4 then do call linear interpolation in the verticalif (n3.lt.4) thenint3dmvc=int3dm(ar,n1,n2,n3,rid,rjd,rkd,misdat)returnendifc do linear interpolation in the horizontalri=amax1(1.,amin1(float(n1),rid))rj=amax1(1.,amin1(float(n2),rjd))rk=amax1(1.,amin1(float(n3),rkd))ih=nint(ri)jh=nint(rj)kh=nint(rk)c Check for interpolation in i* if (abs(float(ih)-ri).lt.1.e-3) then* i =ih* ip1=ih* elsei =min0(int(ri),n1-1)ip1=i+1* endifc Check for interpolation in j* if (abs(float(jh)-rj).lt.1.e-3) then* j =jh* jp1=jh* elsej =min0(int(rj),n2-1)jp1=j+1* endifc Check for interpolation in k* if (abs(float(kh)-rk).lt.1.e-3) then* k =kh* kp1=kh* elsek =min0(int(rk),n3-1)kp1=k+1* endifif (k.eq.kp1) thenc no interpolation in kif ((i.eq.ip1).and.(j.eq.jp1)) thenc no interpolation at allint3dmvc=ar(i,j,k)c print *,'int3dmvc 00: ',rid,rjd,rkd,int3dmvcelsec horizontal interpolation onlyif ((misdat.eq.ar(i ,j ,k )).or.& (misdat.eq.ar(i ,jp1,k )).or.& (misdat.eq.ar(ip1,j ,k )).or.& (misdat.eq.ar(ip1,jp1,k ))) thenint3dmvc=misdatelsefrac0i=ri-float(i)frac0j=rj-float(j)frac1i=1.-frac0ifrac1j=1.-frac0jint3dmvc = ar(i ,j ,k ) * frac1i * frac1j& + ar(i ,jp1,k ) * frac1i * frac0j& + ar(ip1,j ,k ) * frac0i * frac1j& + ar(ip1,jp1,k ) * frac0i * frac0jc print *,'int3dmvc 10: ',rid,rjd,rkd,int3dmvcendifendifelseif ((i.eq.ip1).and.(j.eq.jp1)) thenc vertical interpolation onlyif ((misdat.eq.ar(i ,j ,k )).or.& (misdat.eq.ar(i ,j ,kp1))) thenint3dmvc=misdatelseif (k-1.lt.1) thenklow=1else if (k+2.gt.n3) thenklow=n3-3elseklow=k-1endifcall cubint(ar(i,j,klow),ar(i,j,klow+1),ar(i,j,klow+2),& ar(i,j,klow+3),klow,rk,int3dmvc)endifelsec full 3d interpolationif ((misdat.eq.ar(i ,j ,k )).or.& (misdat.eq.ar(i ,jp1,k )).or.& (misdat.eq.ar(ip1,j ,k )).or.& (misdat.eq.ar(ip1,jp1,k )).or.& (misdat.eq.ar(i ,j ,kp1)).or.& (misdat.eq.ar(i ,jp1,kp1)).or.& (misdat.eq.ar(ip1,j ,kp1)).or.& (misdat.eq.ar(ip1,jp1,kp1))) thenint3dmvc=misdatelsefrac0i=ri-float(i)frac0j=rj-float(j)frac1i=1.-frac0ifrac1j=1.-frac0jif (k-1.lt.1) thenklow=1else if (k+2.gt.n3) thenklow=n3-3elseklow=k-1endifdo n=1,4int2d(n) = ar(i ,j ,klow-1+n ) * frac1i * frac1j& + ar(i ,jp1,klow-1+n ) * frac1i * frac0j& + ar(ip1,j ,klow-1+n ) * frac0i * frac1j& + ar(ip1,jp1,klow-1+n ) * frac0i * frac0jenddocall cubint(int2d(1),int2d(2),int2d(3),int2d(4),& klow,rk,int3dmvc)endifendifendifendreal function int4d(ar,n1,n2,n3,n4,rid,rjd,rkd,rld)c-----------------------------------------------------------------------c Purpose:c This subroutine interpolates a 4d-array to an arbitraryc location within the grid.c Arguments:c ar real input surface pressure, define as ar(n1,n2,n3)c n1,..,n4 int input dimensions of arc ri,..,rl real input grid location to be interpolated toc History:c-----------------------------------------------------------------------c argument declarationsinteger n1,n2,n3,n4real ar(n1,n2,n3,n4), rid,rjd,rkd,rldc local declarationsinteger l,lp1,lhreal frac0l,frac1l,rl,int3dc do linear interpolation in l-directionrl=amax1(1.,amin1(float(n4),rld))lh=nint(rl)c Check for interpolation in l* if (abs(float(lh)-rl).lt.1.e-3) then* l =lh* lp1=lh* elsel =min0(int(rl),n4-1)lp1=l+1* endifif (l.eq.lp1) thenc no interpolation in lint4d=int3d(ar(1,1,1,l),n1,n2,n3,rid,rjd,rkd)elsec interpolation in lfrac0l=rl-float(l)frac1l=1.-frac0lint4d = int3d(ar(1,1,1,l ),n1,n2,n3,rid,rjd,rkd) * frac1l& + int3d(ar(1,1,1,lp1),n1,n2,n3,rid,rjd,rkd) * frac0lendifendreal function int4dm(ar,n1,n2,n3,n4,rid,rjd,rkd,rld,misdat)c-----------------------------------------------------------------------c Purpose:c This subroutine interpolates a 4d-array to an arbitraryc location within the grid. The interpolation includes thec testing of the missing data flag 'misdat'.c Arguments:c ar real input surface pressure, define as ar(n1,n2,n3)c n1,..,n4 int input dimensions of arc ri,..,rl real input grid location to be interpolated toc misdat real input missing data flag (on if misdat<>0)c Warning:c This routine has not yet been seriously tested.c History:c-----------------------------------------------------------------------c argument declarationsinteger n1,n2,n3,n4real ar(n1,n2,n3,n4), rid,rjd,rkd,rld, misdatc local declarationsinteger l,lp1,lhreal frac0l,frac1l,rl,rint0,rint1,int4d,int3dmc check whether missing data checking is requiredif (misdat.eq.0.) thenint4dm=int4d(ar,n1,n2,n3,n4,rid,rjd,rkd,rld)returnendifc do linear interpolation in l-directionrl=amax1(1.,amin1(float(n4),rld))lh=nint(rl)c Check for interpolation in l* if (abs(float(lh)-rl).lt.1.e-3) then* l =lh* lp1=lh* elsel =min0(int(rl),n4-1)lp1=l+1* endifif (l.eq.lp1) thenc no interpolation in lint4dm = int3dm(ar(1,1,1,l),n1,n2,n3,rid,rjd,rkd,misdat)elsec interpolation in lfrac0l=rl-float(l)frac1l=1.-frac0lrint0 = int3dm(ar(1,1,1,l ),n1,n2,n3,rid,rjd,rkd,misdat)rint1 = int3dm(ar(1,1,1,lp1),n1,n2,n3,rid,rjd,rkd,misdat)if ((rint0.eq.misdat).or.(rint1.eq.misdat)) thenint4dm = misdatelseint4dm = rint0*frac1l + rint1*frac0lendifendifendreal function int3dl(ar,n1,n2,n3,levels,rid,rjd,rkd)c-----------------------------------------------------------------------c Purpose:c This subroutine interpolates a 3d-array to an arbitraryc location within the grid. The vertical interpolation is linearc in log(pressure).c Arguments:c ar real input surface pressure, define as ar(n1,n2,n3)c n1,n2,n3 int input dimensions of arc levels real input array contains pressure levels for arc ri,rj,rk real input grid location to be interpolated toc History:c Based on int3d July 93c-----------------------------------------------------------------------c argument declarationsinteger n1,n2,n3real ar(n1,n2,n3), rid,rjd,rkdreal levels(n3)c local declarationsreal pvalinteger i,j,k,ip1,jp1,kp1,ih,jh,khreal frac0i,frac0j,frac0k,frac1i,frac1j,frac1k,ri,rj,rkc do linear interpolationri=amax1(1.,amin1(float(n1),rid))rj=amax1(1.,amin1(float(n2),rjd))rk=amax1(1.,amin1(float(n3),rkd))ih=nint(ri)jh=nint(rj)kh=nint(rk)c Check for interpolation in i* if (abs(float(ih)-ri).lt.1.e-3) then* i =ih* ip1=ih* elsei =min0(int(ri),n1-1)ip1=i+1* endifc Check for interpolation in j* if (abs(float(jh)-rj).lt.1.e-3) then* j =jh* jp1=jh* elsej =min0(int(rj),n2-1)jp1=j+1* endifc Check for interpolation in k* if (abs(float(kh)-rk).lt.1.e-3) then* k =kh* kp1=kh* elsek =min0(int(rk),n3-1)kp1=k+1* endifif (k.eq.kp1) thenc no interpolation in kif ((i.eq.ip1).and.(j.eq.jp1)) thenc no interpolation at allint3dl=ar(i,j,k)c print *,'int3dl 00: ',rid,rjd,rkd,int3dlelsec horizontal interpolation onlyfrac0i=ri-float(i)frac0j=rj-float(j)frac1i=1.-frac0ifrac1j=1.-frac0jint3dl = ar(i ,j ,k ) * frac1i * frac1j& + ar(i ,jp1,k ) * frac1i * frac0j& + ar(ip1,j ,k ) * frac0i * frac1j& + ar(ip1,jp1,k ) * frac0i * frac0jc print *,'int3dl 10: ',rid,rjd,rkd,int3dlendifelse* frac0k=rk-float(k)c calculate the pressure value to be interpolated topval=levels(int(rk))> -(rk-aint(rk))*(levels(int(rk))-levels(int(rk)+1))frac0k=log(levels(int(rk))/pval)& /log(levels(int(rk))/levels(int(rk)+1))frac1k=1.-frac0kif ((i.eq.ip1).and.(j.eq.jp1)) thenc vertical interpolation onlyint3dl = ar(i ,j ,k ) * frac1k& + ar(i ,j ,kp1) * frac0kc print *,'int3dl 01: ',rid,rjd,rkd,int3dlelsec full 3d interpolationfrac0i=ri-float(i)frac0j=rj-float(j)frac1i=1.-frac0ifrac1j=1.-frac0jint3dl = ar(i ,j ,k ) * frac1i * frac1j * frac1k& + ar(i ,jp1,k ) * frac1i * frac0j * frac1k& + ar(ip1,j ,k ) * frac0i * frac1j * frac1k& + ar(ip1,jp1,k ) * frac0i * frac0j * frac1k& + ar(i ,j ,kp1) * frac1i * frac1j * frac0k& + ar(i ,jp1,kp1) * frac1i * frac0j * frac0k& + ar(ip1,j ,kp1) * frac0i * frac1j * frac0k& + ar(ip1,jp1,kp1) * frac0i * frac0j * frac0kc print *,'int3dl 11: ',rid,rjd,rkd,int3dlendifendifendsubroutine bcucof(y,y1,y2,y12,c)c-----------------------------------------------------------------------c Given arrays y,y1,y2 and y12, each of length 4, containing thec function, gradients, and cross derivative at the four grid pointsc of a rectangular grid cell (numbered counterclockwise from thec lower left), and given d1 and d2, the length of the grid cell inc the 1- and 2-directions, this routine returns the table c that isc used by routine bcuint for biqubic interpolation.c Source: Numerical Recipes, Fortran Version, p.99c-----------------------------------------------------------------------real c(4,4),y(4),y1(4),y2(4),y12(4),cl(16),x(16)integer wt(16,16)data wt/1,0,-3,2,4*0,-3,0,9,-6,2,0,-6,4,> 8*0,3,0,-9,6,-2,0,6,-4,> 10*0,9,-6,2*0,-6,4,2*0,3,-2,6*0,-9,6,2*0,6,-4,> 4*0,1,0,-3,2,-2,0,6,-4,1,0,-3,2,8*0,-1,0,3,-2,1,0,-3,2,> 10*0,-3,2,2*0,3,-2,6*0,3,-2,2*0,-6,4,2*0,3,-2,> 0,1,-2,1,5*0,-3,6,-3,0,2,-4,2,9*0,3,-6,3,0,-2,4,-2,> 10*0,-3,3,2*0,2,-2,2*0,-1,1,6*0,3,-3,2*0,-2,2,> 5*0,1,-2,1,0,-2,4,-2,0,1,-2,1,9*0,-1,2,-1,0,1,-2,1,> 10*0,1,-1,2*0,-1,1,6*0,-1,1,2*0,2,-2,2*0,-1,1/real xxinteger i,j,k,ldo i=1,4 ! pack a temporary vector xx(i)=y(i)x(i+4)=y1(i)x(i+8)=y2(i)x(i+12)=y12(i)enddodo i=1,16 ! matrix multiply by the stored tablexx=0.do k=1,16xx=xx+wt(i,k)*x(k)enddocl(i)=xxenddol=0do i=1,4 ! unpack the result into the output tabledo j=1,4l=l+1c(i,j)=cl(l)enddoenddoreturnendsubroutine bcuint(y,y1,y2,y12,x1l,x2l,x1,x2,ansy)c-----------------------------------------------------------------------c Bicubic interpolation within a grid square. Input quantities arec y,y1,y2,y12 (as described in bcucof); x1l and x1u, the lower andc upper coordinates of the grid square in the 1-direction; x2l andc x2u likewise for the 2-direction; and x1,x2, the coordinates ofc the desired point for the interpolation. The interplated functionc value is returned as ansy. This routine calls bcucof.c Source: Numerical Recipes, Fortran Version, p.99/100c !!! changed the proposed code !!!c-----------------------------------------------------------------------real y(4),y1(4),y2(4),y12(4),c(4,4)real ansy,x1,x2,t,uinteger i,x1l,x2lcall bcucof(y,y1,y2,y12,c)t=x1-real(x1l)u=x2-real(x2l)ansy=0.do i=4,1,-1ansy=t*ansy+((c(i,4)*u+c(i,3))*u+c(i,2))*u+c(i,1)enddoreturnendsubroutine cubint(ya1,ya2,ya3,ya4,k,x,y)c-----------------------------------------------------------------------c Interface routine for SR polint for special case of cubicc interpolation in index space, with xa=k,k+1,k+2,k+3c-----------------------------------------------------------------------integer kreal ya1,ya2,ya3,ya4,x,yinteger nreal xa(4),ya(4),dydo n=1,4xa(1)=real(k)xa(2)=real(k+1)xa(3)=real(k+2)xa(4)=real(k+3)ya(1)=ya1ya(2)=ya2ya(3)=ya3ya(4)=ya4enddocall polint(xa,ya,4,x,y,dy)returnendsubroutine polint(xa,ya,n,x,y,dy)c-----------------------------------------------------------------------c Given arrays xa and ya, each of length n, and given a value x, thisc routine returns a value y, and an error estimate dy. If P(x) is thec polynomial of degree n-1 such that p(xa(i))=ya(i),i=1,...,n, thenc the returned value y=p(x)c Source: Numerical Recipes, Fortran Version, p.82c-----------------------------------------------------------------------integer nmax,nparameter(nmax=10)real xa(n),ya(n),x,y,dyinteger i,m,nsreal c(nmax),d(nmax),den,dif,dift,ho,hp,wns=1dif=abs(x-xa(1))do i=1,ndift=abs(x-xa(i))if (dift.lt.dif) thenns=idif=diftendifc(i)=ya(i)d(i)=ya(i)enddoy=ya(ns)ns=ns-1do m=1,n-1do i=1,n-mho=xa(i)-xhp=xa(i+m)-xw=c(i+1)-d(i)den=ho-hpden=w/dend(i)=hp*denc(i)=ho*denenddoif (2*ns.lt.n-m) thendy=c(ns+1)elsedy=d(ns)ns=ns-1endify=y+dyenddoreturnendsubroutine filt2d (a,af,f1,f2,nx,ny,fil,misdat,& iperx,ipery,ispol,inpol)c =============================================================c Apply a conservative diffusion operator onto the 2d field a,c with full missing data checking.cc a real inp array to be filtered, dimensioned (nx,ny)c af real out filtered array, dimensioned (nx,ny), can bec equivalenced with array a in the calling routinec f1 real workarray, dimensioned (nx+1,ny)c f2 real workarray, dimensioned (nx,ny+1)c fil real inp filter-coeff., 0<afil<=1. Maximum filtering with afil=1c corresponds to one application of the linear filter.c misdat real inp missing-data value, a(i,j)=misdat indicates thatc the corresponding value is not available. Thec misdat-checking can be switched off with with misdat=0.c iperx int inp periodic boundaries in the x-direction (1=yes,0=no)c ipery int inp periodic boundaries in the y-direction (1=yes,0=no)c inpol int inp northpole at j=ny (1=yes,0=no)c ispol int inp southpole at j=1 (1=yes,0=no)cc Christoph Schaer, 1993c argument declarationinteger nx,nyreal a(nx,ny),af(nx,ny),f1(nx+1,ny),f2(nx,ny+1),fil,misdatinteger iperx,ipery,inpol,ispolc local variable declarationinteger i,j,isreal fhc compute constant fhfh=0.125*filc compute fluxes in x-directionif (misdat.eq.0.) thendo j=1,nydo i=2,nxf1(i,j)=a(i-1,j)-a(i,j)enddoenddoelsedo j=1,nydo i=2,nxif ((a(i,j).eq.misdat).or.(a(i-1,j).eq.misdat)) thenf1(i,j)=0.elsef1(i,j)=a(i-1,j)-a(i,j)endifenddoenddoendifif (iperx.eq.1) thenc do periodic boundaries in the x-directiondo j=1,nyf1(1,j)=f1(nx,j)f1(nx+1,j)=f1(2,j)enddoelsec set boundary-fluxes to zerodo j=1,nyf1(1,j)=0.f1(nx+1,j)=0.enddoendifc compute fluxes in y-directionif (misdat.eq.0.) thendo j=2,nydo i=1,nxf2(i,j)=a(i,j-1)-a(i,j)enddoenddoelsedo j=2,nydo i=1,nxif ((a(i,j).eq.misdat).or.(a(i,j-1).eq.misdat)) thenf2(i,j)=0.elsef2(i,j)=a(i,j-1)-a(i,j)endifenddoenddoendifc set boundary-fluxes to zerodo i=1,nxf2(i,1)=0.f2(i,ny+1)=0.enddoif (ipery.eq.1) thenc do periodic boundaries in the x-directiondo i=1,nxf2(i,1)=f2(i,ny)f2(i,ny+1)=f2(i,2)enddoendifif (iperx.eq.1) thenif (ispol.eq.1) thenc do south-poleis=(nx-1)/2do i=1,nxf2(i,1)=-f2(mod(i-1+is,nx)+1,2)enddoendifif (inpol.eq.1) thenc do north-poleis=(nx-1)/2do i=1,nxf2(i,ny+1)=-f2(mod(i-1+is,nx)+1,ny)enddoendifendifc compute flux-convergence -> filterif (misdat.eq.0.) thendo j=1,nydo i=1,nxaf(i,j)=a(i,j)+fh*(f1(i,j)-f1(i+1,j)+f2(i,j)-f2(i,j+1))enddoenddoelsedo j=1,nydo i=1,nxif (a(i,j).eq.misdat) thenaf(i,j)=misdatelseaf(i,j)=a(i,j)+fh*(f1(i,j)-f1(i+1,j)+f2(i,j)-f2(i,j+1))endifenddoenddoendifendsubroutine pipo(var3d,p3d,lev,var,nx,ny,nz,mdv,mode)C ====================================================C Interpolates the 3d variable var3d on the pressure surfaceC defined by lev. The interpolated field is returned as var.C p3d denotes the 3d pressure array.C mode determines the way of vertical interpolation:C mode=0 is for linear interpolationC mode=1 is for logarithmic interpolationinteger nx,ny,nz,modereal lev,mdvreal var3d(nx,ny,nz),p3d(nx,ny,nz),var(nx,ny)integer i,j,kreal kindreal int3dmdo i=1,nxdo j=1,nykind=0.do k=1,nz-1if ((p3d(i,j,k).ge.lev).and.(p3d(i,j,k+1).le.lev)) thenkind=float(k)+(p3d(i,j,k)-lev)/> (p3d(i,j,k)-p3d(i,j,k+1))goto 100endifenddo100 continueif (kind.eq.0.) thenvar(i,j)=mdvelsevar(i,j)=int3dm(var3d,nx,ny,nz,float(i),float(j),kind,mdv)endifenddoenddoreturnendsubroutine thipo(var3d,th3d,lev,var,nx,ny,nz,mdv,mode)C ======================================================C Interpolates the 3d variable var3d on the isentropic surfaceC defined by lev. The interpolated field is returned as var.C th3d denotes the 3d theta array.C mode determines the way of vertical interpolation:C mode=0 is for linear interpolationC mode=1 is for logarithmic interpolationinteger nx,ny,nz,modereal lev,mdvreal var3d(nx,ny,nz),th3d(nx,ny,nz),var(nx,ny)integer i,j,kreal kindreal int3dmdo i=1,nxdo j=1,nykind=0do k=1,nz-1if ((th3d(i,j,k).le.lev).and.(th3d(i,j,k+1).ge.lev)) thenkind=float(k)+(th3d(i,j,k)-lev)/> (th3d(i,j,k)-th3d(i,j,k+1))goto 100endifenddo100 continueif (kind.eq.0) thenvar(i,j)=mdvelsevar(i,j)=int3dm(var3d,nx,ny,nz,float(i),float(j),kind,mdv)endifenddoenddoreturnend