module module_TERRAIN 1
private
public :: terrain_for, nmm_terrain
type nmm_terrain
integer :: nx,ny,level,input_type,io_form
real, pointer, dimension(:,:) :: avc,lnd,lah,loh
logical :: initialized
end type nmm_terrain
logical, save :: initialized=.false.
integer, parameter :: minlevel=0,maxlevel=20
type(nmm_terrain), target, save :: terrain(minlevel:maxlevel)
contains
function terrain_for(level,input_type,io_form) result(tr),10
implicit none
type(nmm_terrain), pointer :: tr
character*256 :: message
integer, intent(in) :: level,input_type,io_form
integer i
if(level<minlevel .or. level>maxlevel) then
3304 format("INVALID NESTING LEVEL ",I0,": only ",I0," through ",I0," are allowed.")
write(message,3304) level,minlevel,maxlevel
call wrf_error_fatal
(message)
endif
if(.not. initialized) then
call wrf_debug
(3,'initialize...')
do i=minlevel,maxlevel
tr=>terrain(i)
tr%nx=0 ; tr%ny=0
tr%level=i
tr%initialized=.false.
nullify(tr%avc)
nullify(tr%lnd)
nullify(tr%lah)
nullify(tr%loh)
end do
initialized=.true.
call wrf_debug
(3,'done with init.')
endif
call wrf_debug
(3,'get terrain for this level')
tr=>terrain(level)
if(.not. tr%initialized) then
call wrf_debug
(1,'terrain_for: need to read terrain')
call read_terrain
(tr,input_type,io_form)
endif
call wrf_debug
(3,'check input type and io form')
if(input_type /= tr%input_type) then
3306 format("MISMATCH IN INPUT_TYPE AT LEVEL ",I0,": input_type=",I0," and ",I0," both requested.")
write(message,3306) level,tr%input_type,input_type
call wrf_error_fatal
(message)
endif
if(io_form /= tr%io_form) then
3309 format("MISMATCH IN IO_FORM AT LEVEL ",I0,": io_form=",I0," and ",I0," both reqested.")
write(message,3309) level,tr%io_form,io_form
call wrf_error_fatal
(message)
endif
call wrf_debug
(1,'terrain_for: returning')
end function terrain_for
subroutine read_terrain(tr,input_type,io_form) 1,36
USE module_domain
USE module_configure
USE module_timing
USE wrfsi_static
implicit none
type(nmm_terrain), pointer :: tr
integer, intent(in) :: io_form, input_type
integer, parameter :: IO_BIN=1, IO_NET=2
CHARACTER(LEN=6) :: nestpath
character(len=128) :: input_fname
integer :: comm_1,comm_2, handle,istatus
integer :: level
character (len=32) :: cname
integer :: ndim
character (len=3) :: memorder
character (len=32) :: stagger
integer, dimension(3) :: domain_start, domain_end
integer :: wrftype,n,i,j
character (len=128), dimension(3) :: dimnames
character*256 :: message
real, allocatable, dimension(:,:,:) :: real_domain
character (len=10), parameter :: name(24) = (/ "XLAT_M ", &
"XLONG_M ", &
"XLAT_V ", &
"XLONG_V ", &
"E ", &
"F ", &
"LANDMASK ", &
"LANDUSEF ", &
"LU_INDEX ", &
"HCNVX ", &
"HSTDV ", &
"HASYW ", &
"HASYS ", &
"HASYSW ", &
"HASYNW ", &
"HLENW ", &
"HLENS ", &
"HLENSW ", &
"HLENNW ", &
"HANIS ", &
"HSLOP ", &
"HANGL ", &
"HZMAX ", &
"HGT_M " /)
level=tr%level
write(nestpath,"(a4,i1,a1)") 'nest',level,'/'
input_types: if (input_type == 1) then
!
! si version of the static file
!
CALL get_wrfsi_static_dims
(nestpath,tr%nx,tr%ny)
ALLOCATE (tr%avc(tr%nx,tr%ny))
ALLOCATE (tr%lnd(tr%nx,tr%ny))
ALLOCATE (tr%lah(tr%nx,tr%ny))
ALLOCATE (tr%loh(tr%nx,tr%ny))
CALL get_wrfsi_static_2d
(nestpath, 'avc', tr%avc)
CALL get_wrfsi_static_2d
(nestpath, 'lnd', tr%lnd)
CALL get_wrfsi_static_2d
(nestpath, 'lah', tr%lah)
CALL get_wrfsi_static_2d
(nestpath, 'loh', tr%loh)
else if (input_type == 2) then
!
! WPS version of the static file
!
call wrf_debug
(3,'wps static file')
#ifdef INTIO
if (io_form == IO_BIN) write(input_fname,"(A,I2.2,A)") "geo_nmm_nest.l",level,".int"
#endif
#ifdef NETCDF
if (io_form == IO_NET) write(input_fname,"(A,I2.2,A)") "geo_nmm_nest.l",level,".nc"
#endif
comm_1 = 1
comm_2 = 1
#ifdef INTIO
if (io_form == IO_BIN) &
call ext_int_open_for_read(trim(input_fname), comm_1, comm_2, 'sysdep info', handle, istatus)
#endif
#ifdef NETCDF
if (io_form == IO_NET) &
call ext_ncd_open_for_read
(trim(input_fname), comm_1, comm_2, 'sysdep info', handle, istatus)
#endif
if (istatus /= 0) CALL wrf_error_fatal
('NEST_TERRAIN error after ext_XXX_open_for_read '//trim(input_fname))
read_loop: do n=1,24
cname = name(n)
domain_start = 1
domain_end = 1
#ifdef INTIO
if (io_form == IO_BIN) &
call ext_int_get_var_info(handle, cname, ndim, memorder, stagger, domain_start, domain_end, wrftype, istatus)
#endif
#ifdef NETCDF
if (io_form == IO_NET) &
call ext_ncd_get_var_info
(handle, cname, ndim, memorder, stagger, domain_start, domain_end, wrftype, istatus)
#endif
if (allocated(real_domain)) deallocate(real_domain)
allocate(real_domain(domain_start(1):domain_end(1), domain_start(2):domain_end(2), domain_start(3):domain_end(3)))
#ifdef INTIO
if (io_form == IO_BIN) then
call ext_int_read_field(handle, '0000-00-00_00:00:00', cname, real_domain, wrftype, &
1, 1, 0, memorder, stagger, &
dimnames, domain_start, domain_end, domain_start, domain_end, &
domain_start, domain_end, istatus)
end if
#endif
#ifdef NETCDF
if (io_form == IO_NET) then
call ext_ncd_read_field
(handle, '0000-00-00_00:00:00', cname, real_domain, wrftype, &
1, 1, 0, memorder, stagger, &
dimnames, domain_start, domain_end, domain_start, domain_end, &
domain_start, domain_end, istatus)
end if
#endif
write(message,'("domain nx=",I0," ny=",I0)') domain_end(1),domain_end(2)
tr%nx = domain_end(1)
tr%ny = domain_end(2)
write(message,'("nx=",I0," ny=",I0)') tr%nx,tr%ny
if (cname(1:10) == "XLAT_M ") then
call wrf_debug
(10,'tr%lah...')
ALLOCATE (tr%lah(tr%nx,tr%ny))
call wrf_debug
(10,'allocated...')
do j=1,tr%ny
do i=1,tr%nx
tr%lah(i,j) = real_domain(i,j,1)
end do
end do
call wrf_debug
(10,'tr%lah.')
else if (cname(1:10) == "XLONG_M ") then
call wrf_debug
(10,'tr%loh...')
ALLOCATE (tr%loh(tr%nx,tr%ny))
call wrf_debug
(10,'allocated...')
do j=1,tr%ny
do i=1,tr%nx
tr%loh(i,j) = real_domain(i,j,1)
end do
end do
call wrf_debug
(10,'tr%loh.')
else if (cname(1:10) == "LANDMASK ") then
call wrf_debug
(10,'tr%lnd...')
ALLOCATE (tr%lnd(tr%nx,tr%ny))
call wrf_debug
(10,'allocated...')
do j=1,tr%ny
do i=1,tr%nx
tr%lnd(i,j) = real_domain(i,j,1)
end do
end do
call wrf_debug
(10,'tr%lnd')
else if (cname(1:10) == "HGT_M ") then
call wrf_debug
(10,'tr%avc...')
ALLOCATE (tr%avc(tr%nx,tr%ny))
call wrf_debug
(10,'allocated...')
do j=1,tr%ny
do i=1,tr%nx
tr%avc(i,j) = real_domain(i,j,1)
end do
end do
call wrf_debug
(10,'tr%avc.')
end if
end do read_loop
call wrf_debug
(10,"past read loop")
if(allocated(real_domain)) deallocate(real_domain)
call wrf_debug
(10,'past deallocate')
#ifdef INTIO
if (io_form == IO_BIN) then
call ext_int_ioclose(handle, istatus)
end if
#endif
#ifdef NETCDF
if (io_form == IO_NET) then
call ext_ncd_ioclose
(handle, istatus)
end if
#endif
call wrf_debug
(10,"past close")
if(.not. associated(tr%lah)) call readfail
(tr,input_fname,'lah')
if(.not. associated(tr%loh)) call readfail
(tr,input_fname,'loh')
if(.not. associated(tr%lnd)) call readfail
(tr,input_fname,'lnd')
if(.not. associated(tr%avc)) call readfail
(tr,input_fname,'avc')
else
CALL wrf_error_fatal
('NEST_TERRAIN wrong input_type')
end if input_types
tr%input_type=input_type
tr%io_form=io_form
tr%initialized=.true.
call wrf_debug
(10,"done in read_terrain")
end subroutine read_terrain
subroutine readfail(tr,input_fname,what) 4,1
implicit none
type(nmm_terrain), pointer :: tr
character*256 :: message
character*3 :: what
character(len=128) :: input_fname
3123 format('Did not find "',A,'" in file "',A,'".')
write(message,3123) trim(what),trim(input_fname)
call wrf_error_fatal
(message)
end subroutine readfail
end module module_TERRAIN