module module_HIFREQ 2
#ifdef HWRF
! This module implements the high-frequency output requested by the
! National Hurricane Center in 2010. The hifreq_write routine will
! write a file that contains max. 10m wind, min. MSLP, their locations,
! and the nest center location once per timestep. The hifreq_read
! routine is a sample routine for reading that output. The hifreq_open
! routine is a convenience routine that can generate a nice-looking
! filename using WRF filename generation routines.
!------------------------------------------------------------------------------------------------------
private
public HIFREQ_WRITE, HIFREQ_READ, HIFREQ_OPEN
CONTAINS
!----------------------------------------------------------------------------------
! These two simple routines return an N, S, E or W for the hemisphere of
! a latitude or longitude:
character(1) function get_lat_ns(lat)
implicit none ; real lat
if(lat>=0) then
get_lat_ns='N'
else
get_lat_ns='S'
endif
end function get_lat_ns
character(1) function get_lon_ew(lon)
implicit none ; real lon
if(lon>=0) then
get_lon_ew='E'
else
get_lon_ew='W'
endif
end function get_lon_ew
!------------------------------------------------------------------------------------------------------
!
SUBROUTINE HIFREQ_READ(LUN,mingbl_mslp,maxgbl_wind,plat,plon,wlat,wlon,clat,clon,tm,ierr)
!**********************************************************************
!$$$ SUBPROGRAM DOCUMENTATION BLOCK
! . . .
! PRGRMMR: Sam Trahan
!
! ABSTRACT:
! Call this routine to write one line to read in the values
! written out by hifreq_write. Call this routine repeatedly
! to retrieve all lines.
!
! PROGRAM HISTORY LOG:
! 05-2011 : Sam Trahan
!
! ATTRIBUTES:
! LANGUAGE: FORTRAN 90
! MACHINE : IBM SP
!
! INPUT ARGUMENTS:
! LUN -- logical unit to read from
!
! OUTPUT ARGUMENTS:
! IERR -- 0 on success, 1 on error (integer)
! TM -- forecast second (real)
! MINGBL_MSLP -- min. MSLP in mbar (real)
! MAXGBL_MSLP -- max. 10m wind in knots (real)
! plat, plon -- lat & lon of MSLP minimum (degrees, real)
! wlat, wlon -- lat & lon of wind maximum (degrees, real)
! clat, clon -- lat & lon of nest center (degrees, real)
!$$$
!**********************************************************************
!
implicit none
real, intent(out) :: MINGBL_MSLP, MAXGBL_WIND
real, intent(out) :: plat, plon
real, intent(out) :: wlat, wlon
real, intent(out) :: clat, clon
real, intent(out) :: tm
integer, intent(in) :: lun
integer, intent(out) :: ierr
character*1 :: pns,pew,wns,wew,cns,cew
ierr=0
3131 format(F11.2,", ", &
F9.4,", ",F6.3,A1,", ",F7.3,A1,", ", &
F7.3,", ",F6.3,A1,", ",F7.3,A1,", ", &
F6.3,A1,", ",F7.3,A1)
read(lun,3131,err=3132) tm, &
MINGBL_MSLP,plat,pns,plon,pew, &
MAXGBL_WIND,wlat,wns,wlon,wew, &
clat,cns,clon,cew
if(pns == 'S') plat=-plat
if(pew == 'W') plon=-plon
if(wns == 'S') wlat=-wlat
if(wew == 'W') wlon=-wlon
if(cns == 'S') clat=-clat
if(cew == 'W') clon=-clon
return
3132 continue ! I/O error or end of file.
ierr=1
END SUBROUTINE HIFREQ_READ
SUBROUTINE HIFREQ_WRITE (LUN,NTSD,DT,HLAT,HLON & 1,3
,U10,V10,PINT,T,Q &
,FIS,PD,PDTOP &
,DETA1,DETA2 &
,IDS,IDE,JDS,JDE,KDS,KDE &
,IMS,IME,JMS,JME,KMS,KME &
,ITS,ITE,JTS,JTE,KTS,KTE )
!**********************************************************************
!$$$ SUBPROGRAM DOCUMENTATION BLOCK
! . . .
! PRGRMMR: Original by Young Kwon, modified by Sam Trahan
!
! ABSTRACT:
! Call this routine to write one line to the given LUN,
! containing the minimum MSLP, max 10m wind, their locations,
! and the nest center location.
! PROGRAM HISTORY LOG:
! 05-2011 : Young Kwon
! 05-2011 : Sam Trahan -- Modified for efficiency, eliminated need
! for an external parser script.
!
! ATTRIBUTES:
! LANGUAGE: FORTRAN 90
! MACHINE : IBM SP
!$$$
!**********************************************************************
!
USE MODULE_NEST_UTIL
, only : MSLP_DIAG
USE MODULE_DM
, only : wrf_dm_minloc_real, wrf_dm_maxloc_real
IMPLICIT NONE
!
LOGICAL, EXTERNAL :: wrf_dm_on_monitor
INTEGER,INTENT(IN) :: NTSD, LUN
INTEGER,INTENT(IN) :: IDS,IDE,JDS,JDE,KDS,KDE &
& ,IMS,IME,JMS,JME,KMS,KME &
& ,ITS,ITE,JTS,JTE,KTS,KTE
!
REAL, INTENT(IN) :: PDTOP, DT
REAL, DIMENSION(KMS:KME), INTENT(IN) :: DETA1,DETA2
REAL, DIMENSION(IMS:IME,JMS:JME), INTENT(IN) :: FIS,PD,HLAT,HLON
REAL, DIMENSION(IMS:IME,JMS:JME), INTENT(IN) :: U10,V10
REAL, DIMENSION(IMS:IME,JMS:JME,KMS:KME), INTENT(IN) :: PINT,T,Q
!----------------------------------------------------------------------
REAL, DIMENSION(IMS:IME,JMS:JME) :: WIND10SQ, MSLP
REAL :: MINGBL_MSLP, MAXGBL_WIND, ZDUM, PREF
REAL :: CLAT,CLON,PLAT,PLON,WLAT,WLON, WREF, HAVE_CEN
INTEGER :: IWIND,JWIND, IMSLP,JMSLP
INTEGER :: ICEN,JCEN,I,J,ITF,JTF
!----------------------------------------------------------------------
ITF=MIN(ITE,IDE-1)
JTF=MIN(JTE,JDE-1)
! Get the MSLP and the square of the 10m wind:
WIND10SQ(its:itf,jts:jtf) = U10(its:itf,jts:jtf)**2+ &
V10(its:itf,jts:jtf)**2
call MSLP_DIAG
(MSLP,PINT,T,Q &
,FIS,PD,DETA1,DETA2,PDTOP &
,IDS,IDE,JDS,JDE,KDS,KDE &
,IMS,IME,JMS,JME,KMS,KME &
,ITS,ITE,JTS,JTE,KTS,KTE )
! Find the location of the wind & pressure extrema in this tile:
imslp=its; jmslp=jts
iwind=its; jwind=jts
pref=MSLP(imslp,jmslp) ! min mslp
wref=WIND10SQ(iwind,jwind) ! max wind
do j=jts,jtf
do i=its,itf
if(MSLP(i,j) < pref) then
imslp=i ; jmslp=j
pref=MSLP(imslp,jmslp)
endif
if(WIND10SQ(i,j) > wref) then
iwind=i ; jwind=j
wref=WIND10SQ(iwind,jwind)
end if
enddo
enddo
MINGBL_MSLP=pref ; MAXGBL_WIND=sqrt(wref)/0.514444
PLAT=HLAT(imslp,jmslp) ; WLAT=HLAT(iwind,jwind)
PLON=HLON(imslp,jmslp) ; WLON=HLON(iwind,jwind)
zdum=0
! Get the center of the domain:
ICEN=(IDE-1)/2
JCEN=(JDE-1)/2
HAVE_CEN=0
if(ICEN>=its .and. ICEN<=itf .and. JCEN>=jts .and. JCEN<=jtf) then
HAVE_CEN=1
CLAT=HLAT(ICEN,JCEN)
CLON=HLON(ICEN,JCEN)
end if
! Get grid-wide extrema:
call WRF_DM_MAXLOC_REAL(have_cen,clat,clon,zdum,icen,jcen)
call WRF_DM_MINLOC_REAL(mingbl_mslp,plat,plon,zdum,imslp,jmslp)
call WRF_DM_MAXLOC_REAL(maxgbl_wind,wlat,wlon,zdum,iwind,jwind)
! Monitor process writes out values.
if(wrf_dm_on_monitor()) then
! Write out in a standard format (use hifreq_read to read it):
1313 format(F11.2,", ", &
F8.3,", ",F6.3,A1,", ",F7.3,A1,", ", &
F7.3,", ",F6.3,A1,", ",F7.3,A1,", ", &
F6.3,A1,", ",F7.3,A1)
write(LUN,1313) &
dt*ntsd, &
MINGBL_MSLP/100,abs(plat),get_lat_ns(plat),abs(plon),get_lon_ew(plon), &
MAXGBL_WIND,abs(wlat),get_lat_ns(wlat),abs(wlon),get_lon_ew(wlon), &
abs(clat),get_lat_ns(clat),abs(clon),get_lon_ew(clon)
if(mod(ntsd,126)==125) then
! bug fix for IBM: will not write unless a flush is done periodically
flush(lun)
endif
endif
RETURN
END SUBROUTINE hifreq_write
SUBROUTINE hifreq_open ( grid , config_flags ) 2,8
! Driver layer
USE module_domain
, ONLY : domain, domain_clock_get
USE module_configure
, ONLY : grid_config_rec_type
IMPLICIT NONE
LOGICAL, EXTERNAL :: wrf_dm_on_monitor
! Arguments
TYPE(domain) :: grid
TYPE (grid_config_rec_type) , INTENT(IN) :: config_flags
! Local
CHARACTER*256 :: outname
INTEGER :: fid
LOGICAL :: opened
CHARACTER*80 :: timestr
character*256 :: message
integer, parameter :: unitbase = 93, giveup=unitbase+1000
INTERFACE
SUBROUTINE construct_filename2a( result , basename , fld1 , len1 , date_char )
IMPLICIT NONE
CHARACTER*(*) :: result
CHARACTER*(*) :: basename
CHARACTER*(*) :: date_char
INTEGER , INTENT(IN) :: fld1 , len1
END SUBROUTINE construct_filename2a
END INTERFACE
CALL domain_clock_get
( grid, current_timestr=timestr )
CALL construct_filename2a
( outname ,config_flags%high_freq_outname, grid%id , 2 , timestr )
#ifdef DM_PARALLEL
if(wrf_dm_on_monitor()) then
#endif
! Find an unused unit number
fid = unitbase + grid%id
fid_loop:do while(fid <= giveup)
write(message,'("HIFREQ OPEN TRY FID = ",I0)') fid
call wrf_message
(message)
inquire(unit=fid,opened=opened)
if(.not.opened) then
write(message,'("HIFREQ OPEN UNUSED!! ",I0)') fid
call wrf_message
(message)
exit fid_loop
end if
fid=fid+1
enddo fid_loop
if(fid>giveup) then
call wrf_error_fatal
('Could not find an unused LUN in highfreq_open')
endif
write(message,'("HIFREQ APPEND ",A1,A80,A1)') '"',trim(outname),'"'
call wrf_message
(message)
open(unit=fid,file=trim(outname),position='append',form='formatted')
grid%hifreq_lun=fid
#ifdef DM_PARALLEL
else
grid%hifreq_lun=-99 ! must be non-zero but invalid
endif
#endif
END SUBROUTINE hifreq_open
! only used by HWRF...
#endif
end module module_HIFREQ