0,0 → 1,1368 |
real function int2d(ar,n1,n2,rid,rjd) |
c----------------------------------------------------------------------- |
c Purpose: |
c This subroutine interpolates a 2d-array to an arbitrary |
c location within the grid. |
c Arguments: |
c ar real input surface pressure, define as ar(n1,n2) |
c n1,n2 int input dimensions of ar |
c ri,rj real input grid location to be interpolated to |
c History: |
c----------------------------------------------------------------------- |
|
c argument declarations |
integer n1,n2 |
real ar(n1,n2), rid,rjd |
|
c local declarations |
integer i,j,ip1,jp1,ih,jh |
real frac0i,frac0j,frac1i,frac1j,ri,rj |
|
c do linear interpolation |
ri=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 |
* else |
i =min0(int(ri),n1-1) |
ip1=i+1 |
* endif |
|
c Check for interpolation in j |
* if (abs(float(jh)-rj).lt.1.e-3) then |
* j =jh |
* jp1=jh |
* else |
j =min0(int(rj),n2-1) |
jp1=j+1 |
* endif |
|
if ((i.eq.ip1).and.(j.eq.jp1)) then |
c no interpolation at all |
int2d=ar(i,j) |
else |
frac0i=ri-float(i) |
frac0j=rj-float(j) |
frac1i=1.-frac0i |
frac1j=1.-frac0j |
int2d = ar(i ,j ) * frac1i * frac1j |
& + ar(i ,jp1) * frac1i * frac0j |
& + ar(ip1,j ) * frac0i * frac1j |
& + ar(ip1,jp1) * frac0i * frac0j |
endif |
end |
real function int2dm(ar,n1,n2,rid,rjd,misdat) |
c----------------------------------------------------------------------- |
c Purpose: |
c This subroutine interpolates a 2d-array to an arbitrary |
c location within the grid. The interpolation includes the |
c 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 ar |
c ri,rj real input grid location to be interpolated to |
c 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 declarations |
integer n1,n2 |
real ar(n1,n2), rid,rjd, misdat |
|
c local declarations |
integer i,j,ip1,jp1,ih,jh |
real frac0i,frac0j,frac1i,frac1j,ri,rj,int2d |
|
c check if routine without missing data checking can be called instead |
if (misdat.eq.0.) then |
int2dm=int2d(ar,n1,n2,rid,rjd) |
return |
endif |
|
c do linear interpolation |
ri=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 |
* else |
i =min0(int(ri),n1-1) |
ip1=i+1 |
* endif |
|
c Check for interpolation in j |
* if (abs(float(jh)-rj).lt.1.e-3) then |
* j =jh |
* jp1=jh |
* else |
j =min0(int(rj),n2-1) |
jp1=j+1 |
* endif |
|
if ((i.eq.ip1).and.(j.eq.jp1)) then |
c no interpolation at all |
int2dm=ar(i,j) |
else |
if ((misdat.eq.ar(i ,j )).or. |
& (misdat.eq.ar(i ,jp1)).or. |
& (misdat.eq.ar(ip1,j )).or. |
& (misdat.eq.ar(ip1,jp1))) then |
int2dm=misdat |
else |
frac0i=ri-float(i) |
frac0j=rj-float(j) |
frac1i=1.-frac0i |
frac1j=1.-frac0j |
int2dm = ar(i ,j ) * frac1i * frac1j |
& + ar(i ,jp1) * frac1i * frac0j |
& + ar(ip1,j ) * frac0i * frac1j |
& + ar(ip1,jp1) * frac0i * frac0j |
endif |
endif |
end |
real function int2dp(ar,n1,n2,rid,rjd) |
c----------------------------------------------------------------------- |
c Purpose: |
c This subroutine interpolates a 2d-array to an arbitrary |
c location within the grid. The 2d-array is periodic in the |
c i-direction: ar(0,.)=ar(n1,.) and ar(1,.)=ar(n1+1,.). |
c Therefore rid can take values in the range 0,...,n1+1 |
c Arguments: |
c ar real input surface pressure, define as ar(n1,n2) |
c n1,n2 int input dimensions of ar |
c ri,rj real input grid location to be interpolated to |
c History: |
c----------------------------------------------------------------------- |
|
c argument declarations |
integer n1,n2 |
real ar(0:n1+1,n2), rid,rjd |
|
c local declarations |
integer i,j,ip1,jp1,ih,jh |
real frac0i,frac0j,frac1i,frac1j,ri,rj |
|
c do linear interpolation |
ri=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 |
* else |
i =min0(int(ri),n1-1) |
ip1=i+1 |
* endif |
|
c Check for interpolation in j |
* if (abs(float(jh)-rj).lt.1.e-5) then |
* j =jh |
* jp1=jh |
* else |
j =min0(int(rj),n2-1) |
jp1=j+1 |
* endif |
|
if ((i.eq.ip1).and.(j.eq.jp1)) then |
c no interpolation at all |
int2dp=ar(i,j) |
else |
frac0i=ri-float(i) |
frac0j=rj-float(j) |
frac1i=1.-frac0i |
frac1j=1.-frac0j |
int2dp = ar(i ,j ) * frac1i * frac1j |
& + ar(i ,jp1) * frac1i * frac0j |
& + ar(ip1,j ) * frac0i * frac1j |
& + ar(ip1,jp1) * frac0i * frac0j |
endif |
end |
real function cint2d(ar,n1,n2,n3,rid,rjd,ikd) |
c----------------------------------------------------------------------- |
c Purpose: |
c This subroutine interpolates a 3d-array to an arbitrary |
c location in the horizontal. ikd specifies the level (must |
c be an integer). A bicubic method is applied (following |
c the Numerical Recipes). |
c Arguments: |
c ar real input field, define as ar(n1,n2,n3) |
c n1,n2 int input dimensions of ar |
c rid,rjd real input grid location to be interpolated to |
c ikd int input level for interpolation |
c History: |
c----------------------------------------------------------------------- |
|
c argument declarations |
integer n1,n2,n3,ikd |
real ar(n1,n2,n3), rid,rjd |
|
c local declarations |
integer i,j,k |
real y(4),y1(4),y2(4),y12(4) |
|
c indices of lower left corner of interpolation grid |
|
i=int(rid) |
j=int(rjd) |
k=ikd |
|
c do not interpolate if i or j are at the boundaries |
|
if ((i.eq.1).or.(j.eq.1).or.(i.eq.n1).or.(j.eq.n2)) then |
cint2d=ar(i,j,k) |
return |
endif |
|
c define the arrays y,y1,y2,y12 necessary for the bicubic |
c 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) |
return |
end |
real function int3d(ar,n1,n2,n3,rid,rjd,rkd) |
c----------------------------------------------------------------------- |
c Purpose: |
c This subroutine interpolates a 3d-array to an arbitrary |
c 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 ar |
c ri,rj,rk real input grid location to be interpolated to |
c History: |
c----------------------------------------------------------------------- |
|
c argument declarations |
integer n1,n2,n3 |
real ar(n1,n2,n3), rid,rjd,rkd |
|
c local declarations |
integer i,j,k,ip1,jp1,kp1,ih,jh,kh |
real frac0i,frac0j,frac0k,frac1i,frac1j,frac1k,ri,rj,rk |
|
c do linear interpolation |
ri=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 |
* else |
i =min0(int(ri),n1-1) |
ip1=i+1 |
* endif |
|
c Check for interpolation in j |
if (abs(float(jh)-rj).lt.1.e-3) then |
j =jh |
jp1=jh |
else |
j =min0(int(rj),n2-1) |
jp1=j+1 |
endif |
|
c Check for interpolation in k |
* if (abs(float(kh)-rk).lt.1.e-3) then |
* k =kh |
* kp1=kh |
* else |
k =min0(int(rk),n3-1) |
kp1=k+1 |
* endif |
|
if (k.eq.kp1) then |
c no interpolation in k |
if ((i.eq.ip1).and.(j.eq.jp1)) then |
c no interpolation at all |
int3d=ar(i,j,k) |
c print *,'int3d 00: ',rid,rjd,rkd,int3d |
else |
c horizontal interpolation only |
frac0i=ri-float(i) |
frac0j=rj-float(j) |
frac1i=1.-frac0i |
frac1j=1.-frac0j |
int3d = ar(i ,j ,k ) * frac1i * frac1j |
& + ar(i ,jp1,k ) * frac1i * frac0j |
& + ar(ip1,j ,k ) * frac0i * frac1j |
& + ar(ip1,jp1,k ) * frac0i * frac0j |
c print *,'int3d 10: ',rid,rjd,rkd,int3d |
endif |
else |
frac0k=rk-float(k) |
frac1k=1.-frac0k |
if ((i.eq.ip1).and.(j.eq.jp1)) then |
c vertical interpolation only |
int3d = ar(i ,j ,k ) * frac1k |
& + ar(i ,j ,kp1) * frac0k |
c print *,'int3d 01: ',rid,rjd,rkd,int3d |
else |
c full 3d interpolation |
frac0i=ri-float(i) |
frac0j=rj-float(j) |
frac1i=1.-frac0i |
frac1j=1.-frac0j |
int3d = 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 * frac0k |
c print *,'int3d 11: ',rid,rjd,rkd,int3d |
endif |
endif |
end |
real function int3dm(ar,n1,n2,n3,rid,rjd,rkd,misdat) |
c----------------------------------------------------------------------- |
c Purpose: |
c This subroutine interpolates a 3d-array to an arbitrary |
c location within the grid. The interpolation includes the |
c 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 ar |
c ri,rj,rk real input grid location to be interpolated to |
c 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 declarations |
integer n1,n2,n3 |
real ar(n1,n2,n3), rid,rjd,rkd, misdat |
|
c local declarations |
integer i,j,k,ip1,jp1,kp1,ih,jh,kh |
real frac0i,frac0j,frac0k,frac1i,frac1j,frac1k,ri,rj,rk,int3d |
|
c check if routine without missing data checking can be called instead |
if (misdat.eq.0.) then |
int3dm=int3d(ar,n1,n2,n3,rid,rjd,rkd) |
return |
endif |
|
c do linear interpolation |
ri=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 |
* else |
i =min0(int(ri),n1-1) |
ip1=i+1 |
* endif |
|
c Check for interpolation in j |
* if (abs(float(jh)-rj).lt.1.e-3) then |
* j =jh |
* jp1=jh |
* else |
j =min0(int(rj),n2-1) |
jp1=j+1 |
* endif |
|
c Check for interpolation in k |
* if (abs(float(kh)-rk).lt.1.e-3) then |
* k =kh |
* kp1=kh |
* else |
k =min0(int(rk),n3-1) |
kp1=k+1 |
* endif |
|
if (k.eq.kp1) then |
c no interpolation in k |
if ((i.eq.ip1).and.(j.eq.jp1)) then |
c no interpolation at all |
if (misdat.eq.ar(i,j,k)) then |
int3dm=misdat |
else |
int3dm=ar(i,j,k) |
endif |
c print *,'int3dm 00: ',rid,rjd,rkd,int3dm |
else |
c horizontal interpolation only |
if ((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 ))) then |
int3dm=misdat |
else |
frac0i=ri-float(i) |
frac0j=rj-float(j) |
frac1i=1.-frac0i |
frac1j=1.-frac0j |
int3dm = ar(i ,j ,k ) * frac1i * frac1j |
& + ar(i ,jp1,k ) * frac1i * frac0j |
& + ar(ip1,j ,k ) * frac0i * frac1j |
& + ar(ip1,jp1,k ) * frac0i * frac0j |
c print *,'int3dm 10: ',rid,rjd,rkd,int3dm |
endif |
endif |
else |
frac0k=rk-float(k) |
frac1k=1.-frac0k |
if ((i.eq.ip1).and.(j.eq.jp1)) then |
c vertical interpolation only |
if ((misdat.eq.ar(i ,j ,k )).or. |
& (misdat.eq.ar(i ,j ,kp1))) then |
int3dm=misdat |
else |
int3dm = ar(i ,j ,k ) * frac1k |
& + ar(i ,j ,kp1) * frac0k |
c print *,'int3dm 01: ',rid,rjd,rkd,int3dm |
endif |
else |
c full 3d interpolation |
if ((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))) then |
int3dm=misdat |
else |
frac0i=ri-float(i) |
frac0j=rj-float(j) |
frac1i=1.-frac0i |
frac1j=1.-frac0j |
int3dm = 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 * frac0k |
c print *,'int3dm 11: ',rid,rjd,rkd,int3dm |
endif |
endif |
endif |
end |
real function int3dmlog(ar,n1,n2,n3,rid,rjd,rkd,misdat) |
c----------------------------------------------------------------------- |
c Purpose: |
c This subroutine interpolates a 3d-array to an arbitrary |
c location within the grid. The interpolation includes the |
c 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 ar |
c ri,rj,rk real input grid location to be interpolated to |
c 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 declarations |
integer n1,n2,n3 |
real ar(n1,n2,n3), rid,rjd,rkd, misdat |
|
c local declarations |
integer i,j,k,ip1,jp1,kp1,ih,jh,kh |
real frac0i,frac0j,frac0k,frac1i,frac1j,frac1k,ri,rj,rk,int3d |
|
c print*,'hallo in SR int3dmlog' |
c check if routine without missing data checking can be called instead |
if (misdat.eq.0.) then |
int3dmlog=int3d(ar,n1,n2,n3,rid,rjd,rkd) |
return |
endif |
|
c do linear interpolation |
ri=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 |
* else |
i =min0(int(ri),n1-1) |
ip1=i+1 |
* endif |
|
c Check for interpolation in j |
* if (abs(float(jh)-rj).lt.1.e-3) then |
* j =jh |
* jp1=jh |
* else |
j =min0(int(rj),n2-1) |
jp1=j+1 |
* endif |
|
c Check for interpolation in k |
* if (abs(float(kh)-rk).lt.1.e-3) then |
* k =kh |
* kp1=kh |
* else |
k =min0(int(rk),n3-1) |
kp1=k+1 |
* endif |
|
if (k.eq.kp1) then |
c no interpolation in k |
if ((i.eq.ip1).and.(j.eq.jp1)) then |
c no interpolation at all |
if (misdat.eq.ar(i,j,k)) then |
int3dmlog=misdat |
else |
int3dmlog=ar(i,j,k) |
endif |
c print *,'int3dmlog 00: ',rid,rjd,rkd,int3dmlog |
else |
c horizontal interpolation only |
if ((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 ))) then |
int3dmlog=misdat |
else |
frac0i=ri-float(i) |
frac0j=rj-float(j) |
frac1i=1.-frac0i |
frac1j=1.-frac0j |
int3dmlog = ar(i ,j ,k ) * frac1i * frac1j |
& + ar(i ,jp1,k ) * frac1i * frac0j |
& + ar(ip1,j ,k ) * frac0i * frac1j |
& + ar(ip1,jp1,k ) * frac0i * frac0j |
c print *,'int3dmlog 10: ',rid,rjd,rkd,int3dmlog |
endif |
endif |
else |
frac0k=rk-float(k) |
frac1k=1.-frac0k |
if ((i.eq.ip1).and.(j.eq.jp1)) then |
c vertical interpolation only |
if ((misdat.eq.ar(i ,j ,k )).or. |
& (misdat.eq.ar(i ,j ,kp1))) then |
int3dmlog=misdat |
else |
int3dmlog = log(ar(i ,j ,k )) * frac1k |
& + log(ar(i ,j ,kp1)) * frac0k |
int3dmlog = exp(int3dmlog) |
c print *,'int3dmlog 01: ',rid,rjd,rkd,int3dmlog |
endif |
else |
c full 3d interpolation |
if ((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))) then |
int3dmlog=misdat |
else |
frac0i=ri-float(i) |
frac0j=rj-float(j) |
frac1i=1.-frac0i |
frac1j=1.-frac0j |
int3dmlog = 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 * frac0k |
int3dmlog = exp(int3dmlog) |
c print *,'int3dmlog 11: ',rid,rjd,rkd,int3dmlog |
endif |
endif |
endif |
end |
|
real function int3dmvc(ar,n1,n2,n3,rid,rjd,rkd,misdat) |
c----------------------------------------------------------------------- |
c Purpose: |
c This subroutine interpolates a 3d-array to an arbitrary |
c location within the grid. The interpolation includes the |
c testing of the missing data flag 'misdat'. |
c In the vertical a Lagrangian cubic interpolation is |
c performed. |
c Arguments: |
c ar real input surface pressure, define as ar(n1,n2,n3) |
c n1,n2,n3 int input dimensions of ar |
c ri,rj,rk real input grid location to be interpolated to |
c 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 declarations |
integer n1,n2,n3 |
real ar(n1,n2,n3), rid,rjd,rkd, misdat |
|
c local declarations |
integer i,j,k,ip1,jp1,kp1,ih,jh,kh,klow,n |
real frac0i,frac0j,frac1i,frac1j,ri,rj,rk |
real int2d(4) |
|
real int3dm |
|
c if n3 < 4 then do call linear interpolation in the vertical |
if (n3.lt.4) then |
int3dmvc=int3dm(ar,n1,n2,n3,rid,rjd,rkd,misdat) |
return |
endif |
|
c do linear interpolation in the horizontal |
ri=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 |
* else |
i =min0(int(ri),n1-1) |
ip1=i+1 |
* endif |
|
c Check for interpolation in j |
* if (abs(float(jh)-rj).lt.1.e-3) then |
* j =jh |
* jp1=jh |
* else |
j =min0(int(rj),n2-1) |
jp1=j+1 |
* endif |
|
c Check for interpolation in k |
* if (abs(float(kh)-rk).lt.1.e-3) then |
* k =kh |
* kp1=kh |
* else |
k =min0(int(rk),n3-1) |
kp1=k+1 |
* endif |
|
if (k.eq.kp1) then |
c no interpolation in k |
if ((i.eq.ip1).and.(j.eq.jp1)) then |
c no interpolation at all |
int3dmvc=ar(i,j,k) |
c print *,'int3dmvc 00: ',rid,rjd,rkd,int3dmvc |
else |
c horizontal interpolation only |
if ((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 ))) then |
int3dmvc=misdat |
else |
frac0i=ri-float(i) |
frac0j=rj-float(j) |
frac1i=1.-frac0i |
frac1j=1.-frac0j |
int3dmvc = ar(i ,j ,k ) * frac1i * frac1j |
& + ar(i ,jp1,k ) * frac1i * frac0j |
& + ar(ip1,j ,k ) * frac0i * frac1j |
& + ar(ip1,jp1,k ) * frac0i * frac0j |
c print *,'int3dmvc 10: ',rid,rjd,rkd,int3dmvc |
endif |
endif |
else |
if ((i.eq.ip1).and.(j.eq.jp1)) then |
c vertical interpolation only |
if ((misdat.eq.ar(i ,j ,k )).or. |
& (misdat.eq.ar(i ,j ,kp1))) then |
int3dmvc=misdat |
else |
if (k-1.lt.1) then |
klow=1 |
else if (k+2.gt.n3) then |
klow=n3-3 |
else |
klow=k-1 |
endif |
call cubint(ar(i,j,klow),ar(i,j,klow+1),ar(i,j,klow+2), |
& ar(i,j,klow+3),klow,rk,int3dmvc) |
endif |
else |
c full 3d interpolation |
if ((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))) then |
int3dmvc=misdat |
else |
frac0i=ri-float(i) |
frac0j=rj-float(j) |
frac1i=1.-frac0i |
frac1j=1.-frac0j |
if (k-1.lt.1) then |
klow=1 |
else if (k+2.gt.n3) then |
klow=n3-3 |
else |
klow=k-1 |
endif |
do n=1,4 |
int2d(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 * frac0j |
enddo |
call cubint(int2d(1),int2d(2),int2d(3),int2d(4), |
& klow,rk,int3dmvc) |
endif |
endif |
endif |
end |
real function int4d(ar,n1,n2,n3,n4,rid,rjd,rkd,rld) |
c----------------------------------------------------------------------- |
c Purpose: |
c This subroutine interpolates a 4d-array to an arbitrary |
c 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 ar |
c ri,..,rl real input grid location to be interpolated to |
c History: |
c----------------------------------------------------------------------- |
|
c argument declarations |
integer n1,n2,n3,n4 |
real ar(n1,n2,n3,n4), rid,rjd,rkd,rld |
|
c local declarations |
integer l,lp1,lh |
real frac0l,frac1l,rl,int3d |
|
c do linear interpolation in l-direction |
rl=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 |
* else |
l =min0(int(rl),n4-1) |
lp1=l+1 |
* endif |
|
if (l.eq.lp1) then |
c no interpolation in l |
int4d=int3d(ar(1,1,1,l),n1,n2,n3,rid,rjd,rkd) |
else |
c interpolation in l |
frac0l=rl-float(l) |
frac1l=1.-frac0l |
int4d = 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) * frac0l |
endif |
end |
real function int4dm(ar,n1,n2,n3,n4,rid,rjd,rkd,rld,misdat) |
c----------------------------------------------------------------------- |
c Purpose: |
c This subroutine interpolates a 4d-array to an arbitrary |
c location within the grid. The interpolation includes the |
c 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 ar |
c ri,..,rl real input grid location to be interpolated to |
c 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 declarations |
integer n1,n2,n3,n4 |
real ar(n1,n2,n3,n4), rid,rjd,rkd,rld, misdat |
|
c local declarations |
integer l,lp1,lh |
real frac0l,frac1l,rl,rint0,rint1,int4d,int3dm |
|
c check whether missing data checking is required |
if (misdat.eq.0.) then |
int4dm=int4d(ar,n1,n2,n3,n4,rid,rjd,rkd,rld) |
return |
endif |
|
c do linear interpolation in l-direction |
rl=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 |
* else |
l =min0(int(rl),n4-1) |
lp1=l+1 |
* endif |
|
if (l.eq.lp1) then |
c no interpolation in l |
int4dm = int3dm(ar(1,1,1,l),n1,n2,n3,rid,rjd,rkd,misdat) |
else |
c interpolation in l |
frac0l=rl-float(l) |
frac1l=1.-frac0l |
rint0 = 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)) then |
int4dm = misdat |
else |
int4dm = rint0*frac1l + rint1*frac0l |
endif |
endif |
end |
real function int3dl(ar,n1,n2,n3,levels,rid,rjd,rkd) |
c----------------------------------------------------------------------- |
c Purpose: |
c This subroutine interpolates a 3d-array to an arbitrary |
c location within the grid. The vertical interpolation is linear |
c 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 ar |
c levels real input array contains pressure levels for ar |
c ri,rj,rk real input grid location to be interpolated to |
c History: |
c Based on int3d July 93 |
c----------------------------------------------------------------------- |
|
c argument declarations |
integer n1,n2,n3 |
real ar(n1,n2,n3), rid,rjd,rkd |
real levels(n3) |
|
c local declarations |
real pval |
integer i,j,k,ip1,jp1,kp1,ih,jh,kh |
real frac0i,frac0j,frac0k,frac1i,frac1j,frac1k,ri,rj,rk |
|
c do linear interpolation |
ri=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 |
* else |
i =min0(int(ri),n1-1) |
ip1=i+1 |
* endif |
|
c Check for interpolation in j |
* if (abs(float(jh)-rj).lt.1.e-3) then |
* j =jh |
* jp1=jh |
* else |
j =min0(int(rj),n2-1) |
jp1=j+1 |
* endif |
|
c Check for interpolation in k |
* if (abs(float(kh)-rk).lt.1.e-3) then |
* k =kh |
* kp1=kh |
* else |
k =min0(int(rk),n3-1) |
kp1=k+1 |
* endif |
|
if (k.eq.kp1) then |
c no interpolation in k |
if ((i.eq.ip1).and.(j.eq.jp1)) then |
c no interpolation at all |
int3dl=ar(i,j,k) |
c print *,'int3dl 00: ',rid,rjd,rkd,int3dl |
else |
c horizontal interpolation only |
frac0i=ri-float(i) |
frac0j=rj-float(j) |
frac1i=1.-frac0i |
frac1j=1.-frac0j |
int3dl = ar(i ,j ,k ) * frac1i * frac1j |
& + ar(i ,jp1,k ) * frac1i * frac0j |
& + ar(ip1,j ,k ) * frac0i * frac1j |
& + ar(ip1,jp1,k ) * frac0i * frac0j |
c print *,'int3dl 10: ',rid,rjd,rkd,int3dl |
endif |
else |
* frac0k=rk-float(k) |
c calculate the pressure value to be interpolated to |
pval=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.-frac0k |
if ((i.eq.ip1).and.(j.eq.jp1)) then |
c vertical interpolation only |
int3dl = ar(i ,j ,k ) * frac1k |
& + ar(i ,j ,kp1) * frac0k |
c print *,'int3dl 01: ',rid,rjd,rkd,int3dl |
else |
c full 3d interpolation |
frac0i=ri-float(i) |
frac0j=rj-float(j) |
frac1i=1.-frac0i |
frac1j=1.-frac0j |
int3dl = 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 * frac0k |
c print *,'int3dl 11: ',rid,rjd,rkd,int3dl |
endif |
endif |
end |
subroutine bcucof(y,y1,y2,y12,c) |
c----------------------------------------------------------------------- |
c Given arrays y,y1,y2 and y12, each of length 4, containing the |
c function, gradients, and cross derivative at the four grid points |
c of a rectangular grid cell (numbered counterclockwise from the |
c lower left), and given d1 and d2, the length of the grid cell in |
c the 1- and 2-directions, this routine returns the table c that is |
c used by routine bcuint for biqubic interpolation. |
c Source: Numerical Recipes, Fortran Version, p.99 |
c----------------------------------------------------------------------- |
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 xx |
integer i,j,k,l |
|
do i=1,4 ! pack a temporary vector x |
x(i)=y(i) |
x(i+4)=y1(i) |
x(i+8)=y2(i) |
x(i+12)=y12(i) |
enddo |
|
do i=1,16 ! matrix multiply by the stored table |
xx=0. |
do k=1,16 |
xx=xx+wt(i,k)*x(k) |
enddo |
cl(i)=xx |
enddo |
|
l=0 |
do i=1,4 ! unpack the result into the output table |
do j=1,4 |
l=l+1 |
c(i,j)=cl(l) |
enddo |
enddo |
|
return |
end |
subroutine bcuint(y,y1,y2,y12,x1l,x2l,x1,x2,ansy) |
c----------------------------------------------------------------------- |
c Bicubic interpolation within a grid square. Input quantities are |
c y,y1,y2,y12 (as described in bcucof); x1l and x1u, the lower and |
c upper coordinates of the grid square in the 1-direction; x2l and |
c x2u likewise for the 2-direction; and x1,x2, the coordinates of |
c the desired point for the interpolation. The interplated function |
c value is returned as ansy. This routine calls bcucof. |
c Source: Numerical Recipes, Fortran Version, p.99/100 |
c !!! changed the proposed code !!! |
c----------------------------------------------------------------------- |
|
real y(4),y1(4),y2(4),y12(4),c(4,4) |
real ansy,x1,x2,t,u |
integer i,x1l,x2l |
|
call bcucof(y,y1,y2,y12,c) |
|
t=x1-real(x1l) |
u=x2-real(x2l) |
|
ansy=0. |
|
do i=4,1,-1 |
ansy=t*ansy+((c(i,4)*u+c(i,3))*u+c(i,2))*u+c(i,1) |
enddo |
|
return |
end |
subroutine cubint(ya1,ya2,ya3,ya4,k,x,y) |
c----------------------------------------------------------------------- |
c Interface routine for SR polint for special case of cubic |
c interpolation in index space, with xa=k,k+1,k+2,k+3 |
c----------------------------------------------------------------------- |
|
integer k |
real ya1,ya2,ya3,ya4,x,y |
|
integer n |
real xa(4),ya(4),dy |
|
do n=1,4 |
xa(1)=real(k) |
xa(2)=real(k+1) |
xa(3)=real(k+2) |
xa(4)=real(k+3) |
|
ya(1)=ya1 |
ya(2)=ya2 |
ya(3)=ya3 |
ya(4)=ya4 |
enddo |
|
call polint(xa,ya,4,x,y,dy) |
|
return |
end |
subroutine polint(xa,ya,n,x,y,dy) |
c----------------------------------------------------------------------- |
c Given arrays xa and ya, each of length n, and given a value x, this |
c routine returns a value y, and an error estimate dy. If P(x) is the |
c polynomial of degree n-1 such that p(xa(i))=ya(i),i=1,...,n, then |
c the returned value y=p(x) |
c Source: Numerical Recipes, Fortran Version, p.82 |
c----------------------------------------------------------------------- |
|
integer nmax,n |
parameter(nmax=10) |
real xa(n),ya(n),x,y,dy |
integer i,m,ns |
real c(nmax),d(nmax),den,dif,dift,ho,hp,w |
|
ns=1 |
dif=abs(x-xa(1)) |
|
do i=1,n |
dift=abs(x-xa(i)) |
if (dift.lt.dif) then |
ns=i |
dif=dift |
endif |
c(i)=ya(i) |
d(i)=ya(i) |
enddo |
|
y=ya(ns) |
ns=ns-1 |
do m=1,n-1 |
do i=1,n-m |
ho=xa(i)-x |
hp=xa(i+m)-x |
w=c(i+1)-d(i) |
den=ho-hp |
den=w/den |
d(i)=hp*den |
c(i)=ho*den |
enddo |
if (2*ns.lt.n-m) then |
dy=c(ns+1) |
else |
dy=d(ns) |
ns=ns-1 |
endif |
y=y+dy |
enddo |
|
return |
end |
subroutine 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. |
c |
c a real inp array to be filtered, dimensioned (nx,ny) |
c af real out filtered array, dimensioned (nx,ny), can be |
c equivalenced with array a in the calling routine |
c 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=1 |
c corresponds to one application of the linear filter. |
c misdat real inp missing-data value, a(i,j)=misdat indicates that |
c the corresponding value is not available. The |
c 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) |
c |
c Christoph Schaer, 1993 |
|
c argument declaration |
integer nx,ny |
real a(nx,ny),af(nx,ny),f1(nx+1,ny),f2(nx,ny+1),fil,misdat |
integer iperx,ipery,inpol,ispol |
|
c local variable declaration |
integer i,j,is |
real fh |
|
c compute constant fh |
fh=0.125*fil |
|
c compute fluxes in x-direction |
if (misdat.eq.0.) then |
do j=1,ny |
do i=2,nx |
f1(i,j)=a(i-1,j)-a(i,j) |
enddo |
enddo |
else |
do j=1,ny |
do i=2,nx |
if ((a(i,j).eq.misdat).or.(a(i-1,j).eq.misdat)) then |
f1(i,j)=0. |
else |
f1(i,j)=a(i-1,j)-a(i,j) |
endif |
enddo |
enddo |
endif |
if (iperx.eq.1) then |
c do periodic boundaries in the x-direction |
do j=1,ny |
f1(1,j)=f1(nx,j) |
f1(nx+1,j)=f1(2,j) |
enddo |
else |
c set boundary-fluxes to zero |
do j=1,ny |
f1(1,j)=0. |
f1(nx+1,j)=0. |
enddo |
endif |
|
c compute fluxes in y-direction |
if (misdat.eq.0.) then |
do j=2,ny |
do i=1,nx |
f2(i,j)=a(i,j-1)-a(i,j) |
enddo |
enddo |
else |
do j=2,ny |
do i=1,nx |
if ((a(i,j).eq.misdat).or.(a(i,j-1).eq.misdat)) then |
f2(i,j)=0. |
else |
f2(i,j)=a(i,j-1)-a(i,j) |
endif |
enddo |
enddo |
endif |
c set boundary-fluxes to zero |
do i=1,nx |
f2(i,1)=0. |
f2(i,ny+1)=0. |
enddo |
if (ipery.eq.1) then |
c do periodic boundaries in the x-direction |
do i=1,nx |
f2(i,1)=f2(i,ny) |
f2(i,ny+1)=f2(i,2) |
enddo |
endif |
if (iperx.eq.1) then |
if (ispol.eq.1) then |
c do south-pole |
is=(nx-1)/2 |
do i=1,nx |
f2(i,1)=-f2(mod(i-1+is,nx)+1,2) |
enddo |
endif |
if (inpol.eq.1) then |
c do north-pole |
is=(nx-1)/2 |
do i=1,nx |
f2(i,ny+1)=-f2(mod(i-1+is,nx)+1,ny) |
enddo |
endif |
endif |
|
c compute flux-convergence -> filter |
if (misdat.eq.0.) then |
do j=1,ny |
do i=1,nx |
af(i,j)=a(i,j)+fh*(f1(i,j)-f1(i+1,j)+f2(i,j)-f2(i,j+1)) |
enddo |
enddo |
else |
do j=1,ny |
do i=1,nx |
if (a(i,j).eq.misdat) then |
af(i,j)=misdat |
else |
af(i,j)=a(i,j)+fh*(f1(i,j)-f1(i+1,j)+f2(i,j)-f2(i,j+1)) |
endif |
enddo |
enddo |
endif |
end |
|
subroutine pipo(var3d,p3d,lev,var,nx,ny,nz,mdv,mode) |
C ==================================================== |
|
C Interpolates the 3d variable var3d on the pressure surface |
C 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 interpolation |
C mode=1 is for logarithmic interpolation |
|
integer nx,ny,nz,mode |
real lev,mdv |
real var3d(nx,ny,nz),p3d(nx,ny,nz),var(nx,ny) |
|
integer i,j,k |
real kind |
real int3dm |
|
do i=1,nx |
do j=1,ny |
|
kind=0. |
do k=1,nz-1 |
if ((p3d(i,j,k).ge.lev).and.(p3d(i,j,k+1).le.lev)) then |
kind=float(k)+(p3d(i,j,k)-lev)/ |
> (p3d(i,j,k)-p3d(i,j,k+1)) |
goto 100 |
endif |
enddo |
100 continue |
|
if (kind.eq.0.) then |
var(i,j)=mdv |
else |
var(i,j)=int3dm(var3d,nx,ny,nz,float(i),float(j),kind,mdv) |
endif |
|
enddo |
enddo |
|
return |
end |
|
subroutine thipo(var3d,th3d,lev,var,nx,ny,nz,mdv,mode) |
C ====================================================== |
|
C Interpolates the 3d variable var3d on the isentropic surface |
C 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 interpolation |
C mode=1 is for logarithmic interpolation |
|
integer nx,ny,nz,mode |
real lev,mdv |
real var3d(nx,ny,nz),th3d(nx,ny,nz),var(nx,ny) |
|
integer i,j,k |
real kind |
real int3dm |
|
do i=1,nx |
do j=1,ny |
|
kind=0 |
do k=1,nz-1 |
if ((th3d(i,j,k).le.lev).and.(th3d(i,j,k+1).ge.lev)) then |
kind=float(k)+(th3d(i,j,k)-lev)/ |
> (th3d(i,j,k)-th3d(i,j,k+1)) |
goto 100 |
endif |
enddo |
100 continue |
|
if (kind.eq.0) then |
var(i,j)=mdv |
else |
var(i,j)=int3dm(var3d,nx,ny,nz,float(i),float(j),kind,mdv) |
endif |
|
enddo |
enddo |
|
return |
end |