PROGRAM mrgtrn,16
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Program to merge terrain files to insure continuity for
! external grids near boundaries while accepting smaller-scale
! terrain features in the interior.
!
! Steps: Read in 2 ARPS terrain files
! 1) large-scale external grid
! 2) fine-scale terrain on final grid
! Interpolate large scale terrain to fine scale grid
! Correct for any biases in the large-scale terrain
! Blend the two grids, using the large-scale data near
! the domain edge.
! Compilation/linking:
!
! f77 -o mergetrn mergetrn.o maproj3d.o \
! extlib3d.o outlib3d.o iolib3d.o ibmlib3d.o
!
! AUTHOR: Keith Brewster
! 01/03/95
!
! MODIFICATION HISTORY:
! 10/09/96 (K. Brewster)
! Corrected input of map parameters by adding routine rdtrnall.
!
! 06/10/97 (K. Brewster)
! Added option to leave a border of external terrain data before
! beginning the merging. The border is specific in the input file
! using iborder and jborder.
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
!
INCLUDE 'globcst.inc'
INCLUDE 'grid.inc'
INTEGER :: nx, ny
INTEGER :: nx_ext, ny_ext
!
REAL, allocatable :: xs(:),ys(:)
REAL, allocatable :: xgr(:,:),ygr(:,:)
REAL, allocatable :: lat(:,:),lon(:,:)
REAL, allocatable :: hterain(:,:)
REAL, allocatable :: hterain1(:,:)
REAL, allocatable :: hterain2(:,:)
REAL, allocatable :: hterout(:,:)
REAL, allocatable :: work(:,:)
INTEGER, allocatable :: iloc(:,:),jloc(:,:)
!
REAL, allocatable :: xs_ext(:),ys_ext(:)
REAL, allocatable :: terext(:,:)
REAL, allocatable :: dxfld(:)
REAL, allocatable :: dyfld(:)
REAL, allocatable :: rdxfld(:)
REAL, allocatable :: rdyfld(:)
REAL, allocatable :: slopey(:,:)
REAL, allocatable :: alphay(:,:)
REAL, allocatable :: betay(:,:)
INTEGER, allocatable :: iw(:,:)
!
!-----------------------------------------------------------------------
!
! Terrain namelist variables
!
!-----------------------------------------------------------------------
!
REAL :: dx_ext,dy_ext
CHARACTER (LEN=80) :: terndta_ext
NAMELIST /terrain/ nx,ny,dx,dy,nx_ext,ny_ext,dx_ext,dy_ext, &
terndta,terndta_ext
INTEGER :: iborder,jborder
REAL :: rlen
INTEGER :: rmvbias,nsmth
NAMELIST /ternmrg/ iborder,jborder,rlen,rmvbias,nsmth
INTEGER :: ovrmap,mapcol,mapgrid
REAL :: latgrid,longrid
CHARACTER (LEN=80) :: mapfile
NAMELIST /map_plot/ ovrmap,mapcol,mapgrid,latgrid,longrid, &
mapfile
!
!-----------------------------------------------------------------------
!
! Misc. local variables
!
!-----------------------------------------------------------------------
!
CHARACTER (LEN=80) :: ternfn
REAL :: latnot(2)
INTEGER :: i,j,lenstr,ksmth,iproj_ext,korder
INTEGER :: istart,iend,jstart,jend
REAL :: scale_ext,trulat1_ext,trulat2_ext
REAL :: trulon_ext,ctrlat_ext,ctrlon_ext
REAL :: xctr,yctr,x0_ext,y0_ext
REAL :: x0,y0,sum,sum_ext,bias,wt
REAL :: w1,w2,w3,w4,scalex,scaley
INTEGER :: nxpic,nypic
PARAMETER (nxpic=1,nypic=1)
REAL :: sm
PARAMETER (sm=0.5)
INTEGER :: iorder
PARAMETER (iorder=1)
INTEGER :: ncl
REAL :: cl(100)
INTEGER :: iplt,mode
REAL :: angl,xlimit,ylimit,xymax
INTEGER :: istatus
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
iborder=0
jborder=0
rlen=10000.
rmvbias=0
nsmth=0
ovrmap=1
mapcol=1
mapgrid=0
latgrid=10.
longrid=10.
WRITE(6,'(/a/)') &
' Please input control parameters for terrain merging.'
READ(5,terrain,END=600)
READ(5,ternmrg,END=600)
READ(5,map_plot,END=600)
allocate(xs(nx),ys(ny),stat=istatus)
allocate(xgr(nx,ny),ygr(nx,ny),stat=istatus)
allocate(lat(nx,ny),lon(nx,ny),stat=istatus)
allocate(hterain(nx,ny),stat=istatus)
allocate(hterain1(nx,ny),stat=istatus)
allocate(hterain2(nx,ny),stat=istatus)
allocate(hterout(nx,ny),stat=istatus)
allocate(work(nx,ny),stat=istatus)
allocate(iloc(nx,ny),jloc(nx,ny),stat=istatus)
!
allocate(xs_ext(nx_ext),ys_ext(ny_ext),stat=istatus)
allocate(terext(nx_ext,ny_ext),stat=istatus)
allocate(dxfld(nx_ext),stat=istatus)
allocate(dyfld(ny_ext),stat=istatus)
allocate(rdxfld(nx_ext),stat=istatus)
allocate(rdyfld(ny_ext),stat=istatus)
allocate(slopey(nx_ext,ny_ext),stat=istatus)
allocate(alphay(nx_ext,ny_ext),stat=istatus)
allocate(betay(nx_ext,ny_ext),stat=istatus)
allocate(iw(nx,ny),stat=istatus)
!
!-----------------------------------------------------------------------
!
! Read in external terrain data
!
!-----------------------------------------------------------------------
!
lenstr = LEN(terndta_ext)
CALL strlnth
( terndta_ext, lenstr)
mapproj=-1
!
CALL rdtrnall
( nx_ext,ny_ext,dx_ext,dy_ext, &
iproj_ext,trulat1_ext,trulat2_ext, &
trulon_ext,scale_ext, &
ctrlat_ext,ctrlon_ext, &
terndta_ext(1:lenstr), terext)
IF( scale_ext == 0.0 ) scale_ext = 1.0
!
IF(ctrlon_ext > 180.) ctrlon_ext=ctrlon_ext-360.
IF(trulon_ext > 180.) trulon_ext=trulon_ext-360.
!
!-----------------------------------------------------------------------
!
! Read in fine-scale terrain data
!
!-----------------------------------------------------------------------
!
lenstr = LEN(terndta)
CALL strlnth
( terndta, lenstr)
mapproj=-1
!
CALL rdtrnall
( nx,ny,dx,dy, &
mapproj,trulat1,trulat2,trulon,sclfct, &
ctrlat,ctrlon, &
terndta(1:lenstr), hterain )
IF( sclfct == 0.0 ) sclfct = 1.0
!
IF(ctrlon > 180.) ctrlon=ctrlon-360.
IF(trulon > 180.) trulon=trulon-360.
latnot(1)=trulat1
latnot(2)=trulat2
CALL setmapr
(mapproj,sclfct,latnot,trulon)
!
CALL lltoxy
(1,1,ctrlat,ctrlon,xctr,yctr)
x0=xctr - 0.5*(nx-3)*dx
y0=yctr - 0.5*(ny-3)*dy
!
DO i=1,nx
xs(i)=x0+(i-1)*dx
END DO
DO j=1,ny
ys(j)=y0+(j-1)*dy
END DO
!
CALL xytoll
(nx,ny,xs,ys,lat,lon)
!
!-----------------------------------------------------------------------
!
! Interpolate the external data to the fine-scale grid
!
!-----------------------------------------------------------------------
!
latnot(1)=trulat1_ext
latnot(2)=trulat2_ext
CALL setmapr
(iproj_ext,scale_ext,latnot,trulon_ext)
CALL lltoxy
(1,1,ctrlat_ext,ctrlon_ext,xctr,yctr)
x0_ext=xctr - 0.5*(nx_ext-3)*dx_ext
y0_ext=yctr - 0.5*(ny_ext-3)*dy_ext
!
!-----------------------------------------------------------------------
!
! Set up external grid
!
!-----------------------------------------------------------------------
!
DO i=1,nx_ext
xs_ext(i)=x0_ext+(i-1)*dx_ext
END DO
DO j=1,ny_ext
ys_ext(j)=y0_ext+(j-1)*dy_ext
END DO
!
!-----------------------------------------------------------------------
!
! Find x,y locations of ARPS scalar grid in terms of the
! external grid.
!
!-----------------------------------------------------------------------
!
CALL lltoxy
(nx,ny,lat,lon,xgr,ygr)
!
!-----------------------------------------------------------------------
!
! Find i,j indices in the external data of the fine grid points
!
!-----------------------------------------------------------------------
!
CALL setijloc
(nx,ny,nx_ext,ny_ext,xgr,ygr,xs_ext,ys_ext, &
iloc,jloc)
CALL setdxdy
(nx_ext,ny_ext, &
1,nx_ext,1,ny_ext, &
xs_ext,ys_ext,dxfld,dyfld,rdxfld,rdyfld)
korder=MIN(iorder,2)
CALL fldint2d
(nx,ny,nx_ext,ny_ext, &
1,nx,1,ny, &
1,nx_ext,1,ny_ext, &
korder,xgr,ygr,terext,xs_ext,ys_ext,iloc,jloc, &
dxfld,dyfld,rdxfld,rdyfld, &
slopey,alphay,betay, &
hterain1)
!
!-----------------------------------------------------------------------
!
! Correct for any bias in the external data
! This is to avoid artifical hills in the terrain due to
! any bias in the external data
!
!-----------------------------------------------------------------------
!
IF(rmvbias > 0) THEN
sum=0.
sum_ext=0.
DO j=1,ny-1
DO i=1,nx-1
sum=sum+hterain(i,j)
sum_ext=sum_ext+hterain1(i,j)
END DO
END DO
bias=(sum_ext-sum)/FLOAT((nx-1)*(ny-1))
WRITE(6,'(/a,f6.2,a/)') ' Removing bias of ',bias,' meters'
!
DO j=1,ny-1
DO i=1,nx-1
hterain1(i,j)=hterain1(i,j)-bias
END DO
END DO
ELSE
WRITE(6,'(/a,i4,a/)') &
' rmvbias= ',rmvbias,' --skipping bias removal.'
END IF
!
!-----------------------------------------------------------------------
!
! Blend the two terrain arrays
!
!-----------------------------------------------------------------------
!
! scalex=-dx*dx/(rlen*rlen)
! scaley=-dy*dy/(rlen*rlen)
scalex=dx/rlen
scaley=dy/rlen
WRITE(6,'(/a,f10.2)') &
' Merging terrain fields using length scale',rlen
WRITE(6,'(a,f10.2,a)') &
' Which is equal to ',(1./scalex),' grid lengths in x'
WRITE(6,'(a,f10.2,a/)') &
' and is equal to ',(1./scaley),' grid lengths in y'
istart=iborder+1
iend=(nx-1)-iborder
jstart=jborder+1
jend=(ny-1)-jborder
!
! Start with all points set to external terrain height
!
DO j=1,ny-1
DO i=1,nx-1
hterain2(i,j) = hterain1(i,j)
END DO
END DO
!
DO j=jstart,jend
DO i=istart,iend
! w1=exp((i-1)*(i-1)*scalex)
! w2=exp((nx-1-i)*(nx-1-i)*scalex)
! w3=exp((j-1)*(j-1)*scaley)
! w4=exp((ny-1-j)*(ny-1-j)*scaley)
! wt=amin1(1.0,amax1(0.0,w1,w2,w3,w4))
! hterain2(i,j) = (1.0-wt)*hterain(i,j) + wt*hterain1(i,j)
w1=(i-istart)*scalex
w2=(iend-i)*scalex
w3=(j-jstart)*scaley
w4=(jend-j)*scaley
wt=AMAX1(0.0,AMIN1(1.0,w1,w2,w3,w4))
hterain2(i,j) = wt*hterain(i,j) + (1.-wt)*hterain1(i,j)
END DO
END DO
!
!-----------------------------------------------------------------------
!
! Call edgehammer to filter noise near the edges caused
! by merging
!
!-----------------------------------------------------------------------
!
IF(nsmth > 0) THEN
ksmth=MAX((nsmth/4),4)
WRITE(6,'(/a)') ' Calling edge hammer'
WRITE(6,'(a,i4,a,i4,a//)') &
' nsmth= ',nsmth,' affecting ',ksmth,' points from boundary'
CALL edgeham
(nx,ny,hterain2,work,hterout,nsmth,sm)
ELSE
WRITE(6,'(a)') ' nsmth= ',nsmth,' --skipping edge hammer.'
DO j=1,ny-1
DO i=1,nx-1
hterout(i,j) = hterain2(i,j)
END DO
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Write the final terrain field
!
!-----------------------------------------------------------------------
!
ternfn = terndta(1:lenstr)//'.new'
lenstr = lenstr+4
terndmp = 1
CALL fnversn
(ternfn, lenstr)
CALL writtrn
(nx,ny,ternfn(1:lenstr),dx,dy, &
mapproj,trulat1,trulat2,trulon,sclfct, &
ctrlat,ctrlon,hterout)
!
!-----------------------------------------------------------------------
!
! Whip up some plots
!
!-----------------------------------------------------------------------
!
CALL xdevic
CALL xdspac(0.9)
CALL xafstyl(1)
CALL xartyp(2)
angl = 0.0
CALL xspace(nxpic, nypic, angl , xlimit,ylimit)
CALL xaxfmt( '(i10)' )
CALL xpmagn(0.10*xlimit, 0.10*ylimit)
!
!-----------------------------------------------------------------------
!
! Set map
!
!-----------------------------------------------------------------------
!
xl = (nx-3)*dx * 0.001
yl = (ny-3)*dy * 0.001
xorig = 0.0
yorig = 0.0
CALL xstpjgrd(mapproj,trulat1,trulat2,trulon, &
ctrlat,ctrlon,xl,yl,xorig,yorig)
DO j=1,ny
DO i=1,nx
xgr(i,j)=(i-1)*dx * 0.001
ygr(i,j)=(j-1)*dy * 0.001
END DO
END DO
DO iplt=1,3
CALL xnwpic
xl = (nx-3)*dx * 0.001
yl = (ny-3)*dy * 0.001
xymax=AMAX1(xl,yl)
CALL xmap(0.0,xymax, 0.0, xymax)
CALL xaxsca(0.0,xl, (dx*0.001), 0.0, yl, (dy*0.001) )
cl(1)=0.0
cl(2)=50.
CALL xnctrs(10,30)
mode=1
IF(iplt == 1) THEN
CALL xconta(hterain(2,2),xgr(2,2),ygr(2,2),iw,nx,nx-3,ny-3, &
cl, ncl,mode )
ELSE IF (iplt == 2) THEN
CALL xconta(hterain2(2,2),xgr(2,2),ygr(2,2),iw,nx,nx-3,ny-3, &
cl, ncl,mode )
ELSE IF (iplt == 3) THEN
CALL xconta(hterout(2,2),xgr(2,2),ygr(2,2),iw,nx,nx-3,ny-3, &
cl, ncl,mode )
END IF
IF(ovrmap == 1) THEN
CALL xdrawmap(10,mapfile,mapgrid,latgrid,longrid)
END IF
END DO
CALL xgrend
STOP
!
600 CONTINUE
PRINT *, ' Error reading input data, stopping'
STOP
!
END PROGRAM mrgtrn
!
SUBROUTINE edgeham(nx,ny,hterain,work,newtern,nsmth,sm) 1
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
!-----------------------------------------------------------------------
!
! AUTHOR: Keith Brewster
! 01/03/95
!
! MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
! INPUT:
!
!
!-----------------------------------------------------------------------
!
! Variable Declarations.
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
!
INTEGER :: nx,ny
REAL :: hterain(nx,ny)
REAL :: work(nx,ny)
REAL :: newtern(nx,ny)
INTEGER :: nsmth
REAL :: sm
!
!-----------------------------------------------------------------------
!
! Misc. local variables
!
!-----------------------------------------------------------------------
!
INTEGER :: i,j,ksm,kwid
REAL :: wcen,wsid
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
DO j=1,ny-1
DO i=1,nx-1
newtern(i,j)=hterain(i,j)
END DO
END DO
!
wcen=1.-sm
wsid=0.5*sm
DO ksm=nsmth,1,-1
kwid=ksm/4
kwid=MAX(kwid,4)
DO j=1,ny-1
DO i=1,nx-1
work(i,j)=newtern(i,j)
END DO
END DO
!
!-----------------------------------------------------------------------
!
! Smooth in the x direction near west boundary
!
!-----------------------------------------------------------------------
!
DO j=1,ny-1
DO i=2,kwid
work(i,j)=wsid*(newtern(i-1,j)+newtern(i+1,j)) + &
wcen* newtern(i,j)
END DO
END DO
DO j=1,ny-1
work(1,j)=wsid*(newtern(1,j)+newtern(2,j)) + &
wcen* newtern(1,j)
END DO
!
!-----------------------------------------------------------------------
!
! Smooth in the x direction near east boundary
!
!-----------------------------------------------------------------------
!
DO j=1,ny-1
DO i=(nx-kwid),nx-2
work(i,j)=wsid*(newtern(i-1,j)+newtern(i+1,j)) + &
wcen* newtern(i,j)
END DO
END DO
DO j=1,ny-1
work(nx-1,j)=wsid*(newtern(nx-1,j)+newtern(nx-2,j)) + &
wcen* newtern(nx-1,j)
END DO
!
!-----------------------------------------------------------------------
!
! Smooth in the y direction near south boundary
!
!-----------------------------------------------------------------------
!
DO j=1,ny-1
DO i=1,nx-1
newtern(i,j)=work(i,j)
END DO
END DO
DO j=2,kwid
DO i=1,nx-1
newtern(i,j)=wsid*(work(i,j-1)+work(i,j+1)) + &
wcen* work(i,j)
END DO
END DO
DO i=1,nx-1
newtern(i,1)=wsid*(work(i,1)+work(i,2)) + &
wcen* work(i,1)
END DO
!
!-----------------------------------------------------------------------
!
! Smooth in the y direction near north boundary
!
!-----------------------------------------------------------------------
!
DO j=(ny-kwid),ny-2
DO i=1,nx-1
newtern(i,j)=wsid*(work(i,j-1)+work(i,j+1)) + &
wcen* work(i,j)
END DO
END DO
DO i=1,nx-1
newtern(i,ny-1)=wsid*(work(i,ny-1)+work(i,ny-2)) + &
wcen* work(i,ny-1)
END DO
END DO
RETURN
END SUBROUTINE edgeham
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE RDTRNALL ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE rdtrnall(nx,ny, dx,dy, & 2,4
mapproj,trulat1,trulat2,trulon,sclfct, &
ctrlat,ctrlon, &
terndta, hterain )
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Read the terrain data into model array hterain from a specified
! terrain data file.
!
!-----------------------------------------------------------------------
!
! AUTHOR: Ming Xue
! 2/27/1994.
!
! 9/10/94 (Weygandt & Y. Lu)
! Cleaned up documentation.
!
!-----------------------------------------------------------------------
!
! INPUT :
!
! nx Number of grid points in the x-direction (east/west)
! ny Number of grid points in the y-direction (north/south)
!
! dx Grid interval in x-direction
! dy Grid interval in y-direction
!
! terndta Terrain data file name
!
! OUTPUT:
!
! hterain Terrain height (m)
!
!-----------------------------------------------------------------------
!
!
!-----------------------------------------------------------------------
!
! Variable Declarations.
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INTEGER :: nx ! Number of grid points in the x-direction
INTEGER :: ny ! Number of grid points in the y-direction
REAL :: dx ! Grid interval in x-direction
REAL :: dy ! Grid interval in y-direction
INTEGER :: mapproj
REAL :: trulat1
REAL :: trulat2
REAL :: trulon
REAL :: sclfct
REAL :: ctrlat
REAL :: ctrlon
CHARACTER (LEN=80) :: terndta ! Terrain data file name
REAL :: hterain(nx,ny) ! Terrain height.
!
!-----------------------------------------------------------------------
!
! Misc. local variables:
!
!-----------------------------------------------------------------------
!
INTEGER :: inunit,istat
INTEGER :: nxin,nyin,idummy,ierr
REAL :: dxin,dyin,rdummy,amin,amax
!MP insert: character*80 savename !Message passing code.
!MP insert: integer lenfl !Message passing code.
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!
!-----------------------------------------------------------------------
!
! Define a uniform model grid.
!
!-----------------------------------------------------------------------
!
!
!-----------------------------------------------------------------------
!
! Read in the terrain data.
!
!-----------------------------------------------------------------------
!
CALL getunit
( inunit )
!MP insert: lenfl = 80 !Message passing code.
!MP insert: CALL strlnth( terndta, lenfl ) !Message passing code.
!MP insert: savename(1:80) = terndta(1:80) !Message passing code.
!MP insert: write(terndta, '(a,a,2i2.2)') !Message passing code.
!MP insert: : savename(1:lenfl),'_',loc_x,loc_y
CALL asnctl
('NEWLOCAL', 1, ierr)
CALL asnfile
(terndta, '-F f77 -N ieee', ierr)
OPEN(UNIT=inunit,FILE=terndta,FORM='unformatted',STATUS='old', &
IOSTAT=istat)
!MP insert: terndta(1:80) = savename(1:80) !Message passing code.
IF( istat /= 0) THEN
WRITE(6,'(/1x,a,a,/1x,a/)') &
'Error occured when opening terrain data file ', &
terndta,' Job stopped in READTRN.'
STOP
END IF
READ(inunit,ERR=999) nxin,nyin
IF((nx /= nxin).OR.(ny /= nyin))THEN
WRITE(6,'(a,/a,i5,a,i5,/a,i5,a,i5)') &
' Array size in the terrain data does not match that of the', &
' model grid. Dimensions in the data were nx=',nxin, &
', ny=',nyin,' the model grid size were nx=',nx,' ny= ', ny
WRITE(6,'(a)') ' Job stopped in subroutine READTRN.'
STOP
END IF
READ(inunit,ERR=999) idummy,mapproj,idummy,idummy,idummy, &
idummy,idummy,idummy,idummy,idummy, &
idummy,idummy,idummy,idummy,idummy, &
idummy,idummy,idummy,idummy,idummy
READ(inunit,ERR=999) dxin ,dyin ,ctrlat,ctrlon,rdummy, &
rdummy,trulat1,trulat2,trulon,sclfct, &
rdummy,rdummy,rdummy,rdummy,rdummy, &
rdummy,rdummy,rdummy,rdummy,rdummy
IF(ABS((dx-dxin)/dx) > 0.01.OR.ABS((dy-dyin)/dy) > 0.01)THEN
WRITE(6,'(a,a,/2(a,f13.4),/2(a,f13.4))') &
'Grid intervals in the terrain data do not match those ', &
'in the model.','In the data dx=',dxin,', dy=',dyin, &
'In the model dx=',dx,' dy= ', dy
WRITE(6,'(a)') ' Job stopped in subroutine READTRN.'
STOP
END IF
READ(inunit,ERR=999) hterain
WRITE(6,'(1x,a/)') 'Minimum and maximum terrain height:'
CALL a3dmax0
(hterain,1,nx,1,nx-1, 1,ny,1,ny-1, 1,1,1,1,amax,amin)
WRITE(6,'(1x,2(a,e13.6))') 'htrnmin = ', amin,', htrnmax=',amax
RETURN
999 WRITE(6,'(1x,a)') &
'Error in reading terrain data. Job stopped in READTRN.'
STOP
END SUBROUTINE rdtrnall