!*-----------------------------------------------------------------------------
!*
!* Todd Hutchinson
!* WSI
!* 400 Minuteman Road
!* Andover, MA 01810
!* thutchinson@wsi.com
!*
!* August, 2005
!*-----------------------------------------------------------------------------
!*
!* This io_grib2 API is designed to read WRF input and write WRF output data
!* in grib version 2 format.
!*
#include "wrf_projection.h"
module gr2_data_info 74,1
!*
!* This module will hold data internal to this I/O implementation.
!* The variables will be accessible by all functions (provided they have a
!* "USE gr2_data_info" line).
!*
USE grib2tbls_types
integer , parameter :: FATAL = 1
integer , parameter :: DEBUG = 100
integer , parameter :: DateStrLen = 19
integer , parameter :: maxMsgSize = 300
integer , parameter :: firstFileHandle = 8
integer , parameter :: maxFileHandles = 200
integer , parameter :: maxLevels = 1000
integer , parameter :: maxSoilLevels = 100
integer , parameter :: maxDomains = 500
character(200) :: mapfilename = 'grib2map.tbl'
integer , parameter :: JIDSSIZE = 13
integer , parameter :: JPDTSIZE = 15
integer , parameter :: JGDTSIZE = 30
logical :: grib2map_table_filled = .FALSE.
logical :: WrfIOnotInitialized = .true.
integer, dimension(maxDomains) :: domains
integer :: max_domain = 0
character*24 :: StartDate = ''
character*24 :: InputProgramName = ''
real :: timestep
integer :: full_xsize, full_ysize
REAL, dimension(maxSoilLevels) :: soil_depth, soil_thickness
REAL, dimension(maxLevels) :: half_eta, full_eta
integer :: wrf_projection
integer :: background_proc_id
integer :: forecast_proc_id
integer :: production_status
integer :: compression
real :: center_lat, center_lon
real :: dx,dy
real :: truelat1, truelat2
real :: proj_central_lon
TYPE :: HandleVar
character, dimension(:), pointer :: fileindex(:)
integer :: CurrentTime
integer :: NumberTimes
integer :: sizeAllocated = 0
logical :: write = .FALSE.
character (DateStrLen), dimension(:),allocatable :: Times(:)
logical :: committed, opened, used
character*128 :: DataFile
integer :: FileFd
integer :: FileStatus
integer :: recnum
real :: last_scalar_time_written
ENDTYPE
TYPE (HandleVar), dimension(maxFileHandles),SAVE :: fileinfo
character(len=30000), dimension(maxFileHandles) :: td_output
character(len=30000), dimension(maxFileHandles) :: ti_output
character(len=30000), dimension(maxFileHandles) :: scalar_output
character(len=30000), dimension(maxFileHandles) :: global_input = ''
character(len=30000), dimension(maxFileHandles) :: scalar_input = ''
real :: last_fcst_secs
real :: fcst_secs
logical :: half_eta_init = .FALSE.
logical :: full_eta_init = .FALSE.
logical :: soil_thickness_init = .FALSE.
logical :: soil_depth_init = .FALSE.
end module gr2_data_info
!*****************************************************************************
subroutine ext_gr2_ioinit(SysDepInfo,Status) 3,2
USE gr2_data_info
implicit none
#include "wrf_status_codes.h"
#include "wrf_io_flags.h"
CHARACTER*(*), INTENT(IN) :: SysDepInfo
integer ,intent(out) :: Status
integer :: i
CHARACTER (LEN=300) :: wrf_err_message
call wrf_debug
( DEBUG , 'Entering ext_gr2_ioinit')
do i=firstFileHandle, maxFileHandles
fileinfo(i)%used = .false.
fileinfo(i)%committed = .false.
fileinfo(i)%opened = .false.
td_output(i) = ''
ti_output(i) = ''
scalar_output(i) = ''
enddo
domains(:) = -1
last_fcst_secs = -1.0
fileinfo(1:maxFileHandles)%FileStatus = WRF_FILE_NOT_OPENED
WrfIOnotInitialized = .false.
Status = WRF_NO_ERR
return
end subroutine ext_gr2_ioinit
!*****************************************************************************
subroutine ext_gr2_ioexit(Status) 3,3
USE gr2_data_info
implicit none
#include "wrf_status_codes.h"
integer ,intent(out) :: Status
call wrf_debug
( DEBUG , 'Entering ext_gr2_ioexit')
Status = WRF_NO_ERR
if (grib2map_table_filled) then
call free_grib2map
()
grib2map_table_filled = .FALSE.
endif
return
end subroutine ext_gr2_ioexit
!*****************************************************************************
SUBROUTINE ext_gr2_open_for_read_begin ( FileName , Comm_compute, Comm_io, & 2,27
SysDepInfo, DataHandle , Status )
USE gr2_data_info
USE grib2tbls_types
USE grib_mod
IMPLICIT NONE
#include "wrf_status_codes.h"
#include "wrf_io_flags.h"
CHARACTER*(*) :: FileName
INTEGER , INTENT(IN) :: Comm_compute , Comm_io
CHARACTER*(*) :: SysDepInfo
INTEGER , INTENT(OUT) :: DataHandle
INTEGER , INTENT(OUT) :: Status
CHARACTER (LEN=maxMsgSize) :: msg
integer :: center, subcenter, MasterTblV, &
LocalTblV, Disc, Category, ParmNum, DecScl, BinScl
integer :: fields_to_skip
integer :: JIDS(JIDSSIZE), JPDTN, JPDT(JPDTSIZE), JGDTN, &
JGDT(JGDTSIZE)
logical :: UNPACK
character*(100) :: VarName
type(gribfield) :: gfld
integer :: idx
character(len=DateStrLen) :: theTime,refTime
integer :: time_range_convert(13)
integer :: fcstsecs
integer :: endchar
integer :: ierr
INTERFACE
Subroutine load_grib2map (filename, message, status)
USE grib2tbls_types
character*(*), intent(in) :: filename
character*(*), intent(inout) :: message
integer , intent(out) :: status
END subroutine load_grib2map
END INTERFACE
call wrf_debug
( DEBUG , &
'Entering ext_gr2_open_for_read_begin, opening '//trim(FileName))
CALL gr2_get_new_handle
(DataHandle)
!
! Open grib file
!
if (DataHandle .GT. 0) then
call baopenr(DataHandle,trim(FileName),status)
if (status .ne. 0) then
Status = WRF_ERR_FATAL_BAD_FILE_STATUS
else
fileinfo(DataHandle)%opened = .true.
fileinfo(DataHandle)%DataFile = TRIM(FileName)
fileinfo(DataHandle)%FileStatus = WRF_FILE_OPENED_NOT_COMMITTED
! fileinfo(DataHandle)%CurrentTime = 1
endif
else
Status = WRF_WARN_TOO_MANY_FILES
return
endif
fileinfo(DataHandle)%recnum = -1
!
! Fill up the grib2tbls structure from data in the grib2map file.
!
if (.NOT. grib2map_table_filled) then
grib2map_table_filled = .TRUE.
CALL load_grib2map
(mapfilename, msg, status)
if (status .ne. 0) then
call wrf_message
(trim(msg))
Status = WRF_ERR_FATAL_BAD_FILE_STATUS
return
endif
endif
!
! Get the parameter info for metadata
!
VarName = "WRF_GLOBAL"
CALL get_parminfo
(VarName, center, subcenter, MasterTblV, &
LocalTblV, Disc, Category, ParmNum, DecScl, BinScl, status)
if (status .ne. 0) then
write(msg,*) 'Could not find parameter for '// &
trim(VarName)//' Skipping output of '//trim(VarName)
call wrf_message
(trim(msg))
Status = WRF_GRIB2_ERR_GRIB2MAP
return
endif
!
! Read the metadata
!
fields_to_skip = 0
!
! First, set all values to the wildcard, then reset values that we wish
! to specify.
!
call gr2_g2lib_wildcard
(JIDS, JPDT, JGDT)
JIDS(1) = center
JIDS(2) = subcenter
JIDS(3) = MasterTblV
JIDS(4) = LocalTblV
JIDS(5) = 1 ! Indicates that time is "Start of Forecast"
JIDS(13) = 1 ! Type of processed data (1 for forecast products)
JPDTN = 0 ! Product definition template number
JPDT(1) = Category
JPDT(2) = ParmNum
JPDT(3) = 2 ! Generating process id
JPDT(9) = 0 ! Forecast time
JGDTN = -1 ! Indicates that any Grid Display Template is a match
UNPACK = .FALSE. ! Dont unpack bitmap and data values
CALL GETGB2(DataHandle, DataHandle, fields_to_skip, -1, Disc, JIDS, JPDTN, &
JPDT, JGDTN, JGDT, UNPACK, fileinfo(DataHandle)%recnum, gfld, status)
if (status .ne. 0) then
if (status .eq. 99) then
write(msg,*)'Could not find metadata field named '//trim(VarName)
else
write(msg,*)'Retrieving grib field '//trim(VarName)//' failed, ',status
endif
call wrf_message
(trim(msg))
status = WRF_GRIB2_ERR_GETGB2
return
endif
global_input(DataHandle) = transfer(gfld%local,global_input(DataHandle))
global_input(DataHandle)(gfld%locallen+1:30000) = ' '
call gf_free(gfld)
!
! Read and index all scalar data
!
VarName = "WRF_SCALAR"
CALL get_parminfo
(VarName, center, subcenter, MasterTblV, &
LocalTblV, Disc, Category, ParmNum, DecScl, BinScl, status)
if (status .ne. 0) then
write(msg,*) 'Could not find parameter for '// &
trim(VarName)//' Skipping reading of '//trim(VarName)
call wrf_message
(trim(msg))
Status = WRF_GRIB2_ERR_GRIB2MAP
return
endif
!
! Read the metadata
!
! First, set all values to wild, then specify necessary values
!
call gr2_g2lib_wildcard
(JIDS, JPDT, JGDT)
JIDS(1) = center
JIDS(2) = subcenter
JIDS(3) = MasterTblV
JIDS(4) = LocalTblV
JIDS(5) = 1 ! Indicates that time is "Start of Forecast"
JIDS(13) = 1 ! Type of processed data (1 for forecast products)
JPDTN = 0 ! Product definition template number
JPDT(1) = Category
JPDT(2) = ParmNum
JPDT(3) = 2 ! Generating process id
JGDTN = -1 ! Indicates that any Grid Display Template is a match
UNPACK = .FALSE. ! Dont unpack bitmap and data values
fields_to_skip = 0
do while (status .eq. 0)
CALL GETGB2(DataHandle, 0, fields_to_skip, -1, -1, JIDS, JPDTN, &
JPDT, JGDTN, JGDT, UNPACK, fileinfo(DataHandle)%recnum, &
gfld, status)
if (status .eq. 99) then
exit
else if (status .ne. 0) then
write(msg,*)'Finding data field '//trim(VarName)//' failed 1.'
call wrf_message
(trim(msg))
Status = WRF_GRIB2_ERR_READ
return
endif
! Build times list here
write(refTime,'(I4,A,I2.2,A,I2.2,A,I2.2,A,I2.2,A,I2.2)') &
gfld%idsect(6),'-',gfld%idsect(7),'-',gfld%idsect(8),'_',&
gfld%idsect(9),':',gfld%idsect(10),':',gfld%idsect(11)
time_range_convert(:) = -1
time_range_convert(1) = 60
time_range_convert(2) = 60*60
time_range_convert(3) = 24*60*60
time_range_convert(10) = 3*60*60
time_range_convert(11) = 6*60*60
time_range_convert(12) = 12*60*60
time_range_convert(13) = 1
if (time_range_convert(gfld%ipdtmpl(8)) .gt. 0) then
fcstsecs = gfld%ipdtmpl(9)*time_range_convert(gfld%ipdtmpl(8))
else
write(msg,*)'Invalid time range in input data: ',gfld%ipdtmpl(8),&
' Skipping'
call wrf_message
(trim(msg))
call gf_free(gfld)
cycle
endif
call advance_wrf_time
(refTime,fcstsecs,theTime)
call gr2_add_time
(DataHandle,theTime)
fields_to_skip = fields_to_skip + fileinfo(DataHandle)%recnum
scalar_input(DataHandle) = transfer(gfld%local,scalar_input(DataHandle))
scalar_input(DataHandle)(gfld%locallen+1:30000) = ' '
call gf_free(gfld)
enddo
!
! Fill up the eta levels variables
!
if (.not. full_eta_init) then
CALL gr2_fill_levels
(DataHandle, "ZNW", full_eta, ierr)
if (ierr .eq. 0) then
full_eta_init = .TRUE.
endif
endif
if (.not. half_eta_init) then
CALL gr2_fill_levels
(DataHandle, "ZNU", half_eta, ierr)
if (ierr .eq. 0) then
half_eta_init = .TRUE.
endif
endif
!
! Fill up the soil levels
!
if (.not. soil_depth_init) then
call gr2_fill_levels
(DataHandle,"ZS",soil_depth, ierr)
if (ierr .eq. 0) then
soil_depth_init = .TRUE.
endif
endif
if (.not. soil_thickness_init) then
call gr2_fill_levels
(DataHandle,"DZS",soil_thickness, ierr)
if (ierr .eq. 0) then
soil_thickness_init = .TRUE.
endif
endif
!
! Fill up any variables from the global metadata
!
CALL gr2_get_metadata_value
(global_input(DataHandle), &
'START_DATE', StartDate, status)
if (status .ne. 0) then
write(msg,*)'Could not find metadata value for START_DATE, continuing'
call wrf_message
(trim(msg))
endif
CALL gr2_get_metadata_value
(global_input(DataHandle), &
'PROGRAM_NAME', InputProgramName, status)
if (status .ne. 0) then
write(msg,*)'Could not find metadata value for PROGRAM_NAME, continuing'
call wrf_message
(trim(msg))
else
endchar = SCAN(InputProgramName," ")
InputProgramName = InputProgramName(1:endchar)
endif
Status = WRF_NO_ERR
call wrf_debug
( DEBUG , 'Exiting ext_gr2_open_for_read_begin')
RETURN
END SUBROUTINE ext_gr2_open_for_read_begin
!*****************************************************************************
SUBROUTINE ext_gr2_open_for_read_commit( DataHandle , Status ) 2,3
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
#include "wrf_io_flags.h"
character(len=maxMsgSize) :: msg
INTEGER , INTENT(IN ) :: DataHandle
INTEGER , INTENT(OUT) :: Status
call wrf_debug
( DEBUG , 'Entering ext_gr2_open_for_read_commit')
Status = WRF_NO_ERR
if(WrfIOnotInitialized) then
Status = WRF_IO_NOT_INITIALIZED
write(msg,*) 'ext_gr2_ioinit was not called ',__FILE__,', line', __LINE__
call wrf_debug
( FATAL , msg)
return
endif
fileinfo(DataHandle)%committed = .true.
fileinfo(DataHandle)%FileStatus = WRF_FILE_OPENED_FOR_READ
Status = WRF_NO_ERR
RETURN
END SUBROUTINE ext_gr2_open_for_read_commit
!*****************************************************************************
SUBROUTINE ext_gr2_open_for_read ( FileName , Comm_compute, Comm_io, & 1,4
SysDepInfo, DataHandle , Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
CHARACTER*(*) :: FileName
INTEGER , INTENT(IN) :: Comm_compute , Comm_io
CHARACTER*(*) :: SysDepInfo
INTEGER , INTENT(OUT) :: DataHandle
INTEGER , INTENT(OUT) :: Status
call wrf_debug
( DEBUG , 'Entering ext_gr2_open_for_read')
DataHandle = 0 ! dummy setting to quiet warning message
CALL ext_gr2_open_for_read_begin
( FileName, Comm_compute, Comm_io, &
SysDepInfo, DataHandle, Status )
IF ( Status .EQ. WRF_NO_ERR ) THEN
CALL ext_gr2_open_for_read_commit
( DataHandle, Status )
ENDIF
return
RETURN
END SUBROUTINE ext_gr2_open_for_read
!*****************************************************************************
SUBROUTINE ext_gr2_open_for_write_begin(FileName, Comm, IOComm, SysDepInfo, & 3,6
DataHandle, Status)
USE gr2_data_info
implicit none
#include "wrf_status_codes.h"
#include "wrf_io_flags.h"
character*(*) ,intent(in) :: FileName
integer ,intent(in) :: Comm
integer ,intent(in) :: IOComm
character*(*) ,intent(in) :: SysDepInfo
integer ,intent(out) :: DataHandle
integer ,intent(out) :: Status
integer :: ierr
CHARACTER (LEN=maxMsgSize) :: msg
INTERFACE
Subroutine load_grib2map (filename, message, status)
USE grib2tbls_types
character*(*), intent(in) :: filename
character*(*), intent(inout) :: message
integer , intent(out) :: status
END subroutine load_grib2map
END INTERFACE
call wrf_debug
( DEBUG , 'Entering ext_gr2_open_for_write_begin')
Status = WRF_NO_ERR
if (.NOT. grib2map_table_filled) then
grib2map_table_filled = .TRUE.
CALL load_grib2map
(mapfilename, msg, status)
if (status .ne. 0) then
call wrf_message
(trim(msg))
Status = WRF_ERR_FATAL_BAD_FILE_STATUS
return
endif
endif
CALL gr2_get_new_handle
(DataHandle)
if (DataHandle .GT. 0) then
call baopenw(DataHandle,trim(FileName),ierr)
if (ierr .ne. 0) then
Status = WRF_ERR_FATAL_BAD_FILE_STATUS
else
fileinfo(DataHandle)%opened = .true.
fileinfo(DataHandle)%DataFile = TRIM(FileName)
fileinfo(DataHandle)%FileStatus = WRF_FILE_OPENED_NOT_COMMITTED
endif
fileinfo(DataHandle)%last_scalar_time_written = -1
fileinfo(DataHandle)%committed = .false.
td_output(DataHandle) = ''
ti_output(DataHandle) = ''
scalar_output(DataHandle) = ''
fileinfo(DataHandle)%write = .true.
else
Status = WRF_WARN_TOO_MANY_FILES
endif
RETURN
END SUBROUTINE ext_gr2_open_for_write_begin
!*****************************************************************************
SUBROUTINE ext_gr2_open_for_write_commit( DataHandle , Status ) 3,2
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
#include "wrf_io_flags.h"
INTEGER , INTENT(IN ) :: DataHandle
INTEGER , INTENT(OUT) :: Status
call wrf_debug
( DEBUG , 'Entering ext_gr2_open_for_write_commit')
IF ( fileinfo(DataHandle)%opened ) THEN
IF ( fileinfo(DataHandle)%used ) THEN
fileinfo(DataHandle)%committed = .true.
fileinfo(DataHandle)%FileStatus = WRF_FILE_OPENED_FOR_WRITE
ENDIF
ENDIF
Status = WRF_NO_ERR
RETURN
END SUBROUTINE ext_gr2_open_for_write_commit
!*****************************************************************************
subroutine ext_gr2_inquiry (Inquiry, Result, Status),1
use gr2_data_info
implicit none
#include "wrf_status_codes.h"
character *(*), INTENT(IN) :: Inquiry
character *(*), INTENT(OUT) :: Result
integer ,INTENT(INOUT) :: Status
SELECT CASE (Inquiry)
CASE ("RANDOM_WRITE","RANDOM_READ")
Result='ALLOW'
CASE ("SEQUENTIAL_WRITE","SEQUENTIAL_READ")
Result='NO'
CASE ("OPEN_READ", "OPEN_WRITE", "OPEN_COMMIT_WRITE")
Result='REQUIRE'
CASE ("OPEN_COMMIT_READ","PARALLEL_IO")
Result='NO'
CASE ("SELF_DESCRIBING","SUPPORT_METADATA","SUPPORT_3D_FIELDS")
Result='YES'
CASE ("MEDIUM")
Result ='FILE'
CASE DEFAULT
Result = 'No Result for that inquiry!'
END SELECT
Status=WRF_NO_ERR
return
end subroutine ext_gr2_inquiry
!*****************************************************************************
SUBROUTINE ext_gr2_inquire_opened ( DataHandle, FileName , FileStat, Status ) 1,2
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
#include "wrf_io_flags.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: FileName
INTEGER , INTENT(OUT) :: FileStat
INTEGER , INTENT(OUT) :: Status
call wrf_debug
( DEBUG , 'Entering ext_gr2_inquire_opened')
FileStat = WRF_NO_ERR
if ((DataHandle .ge. firstFileHandle) .and. &
(DataHandle .le. maxFileHandles)) then
FileStat = fileinfo(DataHandle)%FileStatus
else
FileStat = WRF_FILE_NOT_OPENED
endif
Status = FileStat
RETURN
END SUBROUTINE ext_gr2_inquire_opened
!*****************************************************************************
SUBROUTINE ext_gr2_ioclose ( DataHandle, Status ) 3,7
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
#include "wrf_io_flags.h"
INTEGER DataHandle, Status
INTEGER istat
character(len=1000) :: outstring
character :: lf
character*(maxMsgSize) :: msg
integer :: idx
lf=char(10)
call wrf_debug
( DEBUG , 'Entering ext_gr2_ioclose')
Status = WRF_NO_ERR
if (fileinfo(DataHandle)%write .eqv. .TRUE.) then
call gr2_fill_local_use
(DataHandle,scalar_output(DataHandle),&
"WRF_SCALAR",fcst_secs,msg,status)
if (status .ne. 0) then
call wrf_message
(trim(msg))
return
endif
fileinfo(DataHandle)%last_scalar_time_written = fcst_secs
scalar_output(DataHandle) = ''
call gr2_fill_local_use
(DataHandle,&
trim(ti_output(DataHandle))//trim(td_output(DataHandle)),&
"WRF_GLOBAL",0,msg,status)
if (status .ne. 0) then
call wrf_message
(trim(msg))
return
endif
ti_output(DataHandle) = ''
td_output(DataHandle) = ''
endif
do idx = 1,fileinfo(DataHandle)%NumberTimes
if (allocated(fileinfo(DataHandle)%Times)) then
deallocate(fileinfo(DataHandle)%Times)
endif
enddo
fileinfo(DataHandle)%NumberTimes = 0
fileinfo(DataHandle)%sizeAllocated = 0
fileinfo(DataHandle)%CurrentTime = 0
fileinfo(DataHandle)%write = .FALSE.
call baclose(DataHandle,status)
if (status .ne. 0) then
call wrf_message
("Closing file failed, continuing")
else
fileinfo(DataHandle)%opened = .true.
fileinfo(DataHandle)%DataFile = ''
fileinfo(DataHandle)%FileStatus = WRF_FILE_NOT_OPENED
endif
fileinfo(DataHandle)%used = .false.
RETURN
END SUBROUTINE ext_gr2_ioclose
!*****************************************************************************
SUBROUTINE ext_gr2_write_field( DataHandle , DateStrIn , VarName , & 2,26
Field , FieldType , Comm , IOComm, &
DomainDesc , MemoryOrder , Stagger , &
DimNames , &
DomainStart , DomainEnd , &
MemoryStart , MemoryEnd , &
PatchStart , PatchEnd , &
Status )
USE gr2_data_info
USE grib2tbls_types
IMPLICIT NONE
#include "wrf_status_codes.h"
#include "wrf_io_flags.h"
integer ,intent(in) :: DataHandle
character*(*) ,intent(in) :: DateStrIn
character*(*) ,intent(in) :: VarName
integer ,intent(in) :: FieldType
integer ,intent(inout) :: Comm
integer ,intent(inout) :: IOComm
integer ,intent(in) :: DomainDesc
character*(*) ,intent(in) :: MemoryOrder
character*(*) ,intent(in) :: Stagger
character*(*) , dimension (*) ,intent(in) :: DimNames
integer ,dimension(*) ,intent(in) :: DomainStart, DomainEnd
integer ,dimension(*) ,intent(in) :: MemoryStart, MemoryEnd
integer ,dimension(*) ,intent(in) :: PatchStart, PatchEnd
integer ,intent(out) :: Status
real , intent(in), &
dimension( 1:1,MemoryStart(1):MemoryEnd(1), &
MemoryStart(2):MemoryEnd(2), &
MemoryStart(3):MemoryEnd(3) ) :: Field
character (120) :: DateStr
character (maxMsgSize) :: msg
integer :: xsize, ysize, zsize
integer :: x, y, z
integer :: &
x_start,x_end,y_start,y_end,z_start,z_end
integer :: idx
integer :: proj_center_flag
logical :: vert_stag = .false.
real, dimension(:,:), pointer :: data
integer :: istat
integer :: accum_period
integer, dimension(maxLevels) :: level1, level2
integer, dimension(maxLevels) :: grib_levels
logical :: soil_layers, fraction
integer :: vert_unit1, vert_unit2
integer :: vert_sclFctr1, vert_sclFctr2
integer :: this_domain
logical :: new_domain
real :: &
region_center_lat, region_center_lon
integer :: dom_xsize, dom_ysize;
integer , parameter :: lcgrib = 2000000
character (lcgrib) :: cgrib
integer :: ierr
integer :: lengrib
integer :: center, subcenter, &
MasterTblV, LocalTblV, Disc, Category, ParmNum, DecScl, BinScl
CHARACTER(len=100) :: tmpstr
integer :: ndims
integer :: dim1size, dim2size, dim3size, dim3
integer :: numlevels
integer :: ngrdpts
integer :: bytes_written
call wrf_debug
( DEBUG , 'Entering ext_gr2_write_field for parameter '//&
VarName)
!
! If DateStr is all 0s, we reset it to StartDate. For some reason,
! in idealized simulations, StartDate is 0001-01-01_00:00:00 while
! the first DateStr is 0000-00-00_00:00:00.
!
if (DateStrIn .eq. '0000-00-00_00:00:00') then
DateStr = TRIM(StartDate)
else
DateStr = DateStrIn
endif
!
! Check if this is a domain that we haven t seen yet. If so, add it to
! the list of domains.
!
this_domain = 0
new_domain = .false.
do idx = 1, max_domain
if (DomainDesc .eq. domains(idx)) then
this_domain = idx
endif
enddo
if (this_domain .eq. 0) then
max_domain = max_domain + 1
domains(max_domain) = DomainDesc
this_domain = max_domain
new_domain = .true.
endif
zsize = 1
xsize = 1
ysize = 1
soil_layers = .false.
fraction = .false.
! First, handle then special cases for the boundary data.
CALL get_dims
(MemoryOrder, PatchStart, PatchEnd, ndims, x_start, x_end, &
y_start, y_end,z_start,z_end)
xsize = x_end - x_start + 1
ysize = y_end - y_start + 1
zsize = z_end - z_start + 1
do idx = 1, len(MemoryOrder)
if ((MemoryOrder(idx:idx) .eq. 'Z') .and. &
(DimNames(idx) .eq. 'soil_layers_stag')) then
soil_layers = .true.
else if ((VarName .eq. 'LANDUSEF') .or. (VarName .eq. 'SOILCBOT') .or. &
(VarName .eq. 'SOILCTOP')) then
fraction = .true.
endif
enddo
if (zsize .eq. 0) then
zsize = 1
endif
!
! Fill up the variables that hold the vertical coordinate data
!
if (VarName .eq. 'ZNU') then
do idx = 1, zsize
half_eta(idx) = Field(1,idx,1,1)
enddo
half_eta_init = .TRUE.
endif
if (VarName .eq. 'ZNW') then
do idx = 1, zsize
full_eta(idx) = Field(1,idx,1,1)
enddo
full_eta_init = .TRUE.
endif
if (VarName .eq. 'ZS') then
do idx = 1, zsize
soil_depth(idx) = Field(1,idx,1,1)
enddo
soil_depth_init = .TRUE.
endif
if (VarName .eq. 'DZS') then
do idx = 1, zsize
soil_thickness(idx) = Field(1,idx,1,1)
enddo
soil_thickness_init = .TRUE.
endif
!
! Check to assure that dimensions are valid
!
if ((xsize .lt. 1) .or. (ysize .lt. 1) .or. (zsize .lt. 1)) then
write(msg,*) 'Cannot output field with memory order: ', &
MemoryOrder,Varname
call wrf_message
(trim(msg))
return
endif
if (fileinfo(DataHandle)%opened .and. fileinfo(DataHandle)%committed) then
if (StartDate == '') then
StartDate = DateStr
endif
CALL geth_idts
(DateStr,StartDate,fcst_secs)
!
! If this is a new forecast time, and we have not written the
! last_fcst_secs scalar output yet, then write it here.
!
if ((abs(fcst_secs - 0.0) .gt. 0.01) .and. &
(last_fcst_secs .ge. 0) .and. &
(abs(fcst_secs - last_fcst_secs) .gt. 0.01) .and. &
(abs(last_fcst_secs - fileinfo(DataHandle)%last_scalar_time_written) .gt. 0.01) ) then
call gr2_fill_local_use
(DataHandle,scalar_output(DataHandle),&
"WRF_SCALAR",last_fcst_secs,msg,status)
if (status .ne. 0) then
call wrf_message
(trim(msg))
return
endif
fileinfo(DataHandle)%last_scalar_time_written = last_fcst_secs
scalar_output(DataHandle) = ''
endif
call get_vert_stag
(VarName,Stagger,vert_stag)
do idx = 1, zsize
call gr2_get_levels
(VarName, idx, zsize, soil_layers, vert_stag, &
fraction, vert_unit1, vert_unit2, vert_sclFctr1, &
vert_sclFctr2, level1(idx), level2(idx))
enddo
!
! Get the center lat/lon for the area being output. For some cases (such
! as for boundary areas, the center of the area is different from the
! center of the model grid.
!
if (index(Stagger,'X') .le. 0) then
dom_xsize = full_xsize - 1
else
dom_xsize = full_xsize
endif
if (index(Stagger,'Y') .le. 0) then
dom_ysize = full_ysize - 1
else
dom_ysize = full_ysize
endif
CALL get_region_center(MemoryOrder, wrf_projection, center_lat, &
center_lon, dom_xsize, dom_ysize, dx, dy, proj_central_lon, &
proj_center_flag, truelat1, truelat2, xsize, ysize, &
region_center_lat, region_center_lon)
if (ndims .eq. 0) then ! Scalar quantity
ALLOCATE(data(1:1,1:1), STAT=istat)
call gr2_retrieve_data
(MemoryOrder, MemoryStart, MemoryEnd, &
xsize, ysize, zsize, z, FieldType, Field, data)
write(tmpstr,'(G17.10)')data(1,1)
CALL gr2_build_string
(scalar_output(DataHandle), &
trim(adjustl(VarName)), tmpstr, 1, Status)
DEALLOCATE(data)
else if (ndims .ge. 1) then ! Vector (1-D) and 2/3 D quantities
if (ndims .eq. 1) then ! Handle Vector (1-D) parameters
dim1size = zsize
dim2size = 1
dim3size = 1
else ! Handle 2/3 D parameters
dim1size = xsize
dim2size = ysize
dim3size = zsize
endif
ALLOCATE(data(1:dim1size,1:dim2size), STAT=istat)
CALL get_parminfo
(VarName, center, subcenter, MasterTblV, &
LocalTblV, Disc, Category, ParmNum, DecScl, BinScl, status)
if (status .ne. 0) then
write(msg,*) 'Could not find parameter for '// &
trim(VarName)//' Skipping output of '//trim(VarName)
call wrf_message
(trim(msg))
Status = WRF_GRIB2_ERR_GRIB2MAP
return
endif
VERTDIM : do dim3 = 1, dim3size
call gr2_retrieve_data
(MemoryOrder, MemoryStart, MemoryEnd, xsize, &
ysize, zsize, dim3, FieldType, Field, data)
!
! Here, we do any necessary conversions to the data.
!
! Potential temperature is sometimes passed in as perturbation
! potential temperature (i.e., POT-300). Other times (i.e., from
! WRF SI), it is passed in as full potential temperature.
! Here, we convert to full potential temperature by adding 300
! only if POT < 200 K.
!
if (VarName == 'T') then
if ((data(1,1) < 200) .and. (data(1,1) .ne. 0)) then
data = data + 300
endif
endif
!
! For precip, we setup the accumulation period, and output a precip
! rate for time-step precip.
!
if ((VarName .eq. 'RAINCV') .or. (VarName .eq. 'RAINNCV')) then
! Convert time-step precip to precip rate.
data = data/timestep
accum_period = 0
else
accum_period = 0
endif
!
! Create indicator and identification sections (sections 0 and 1)
!
CALL gr2_create_w
(StartDate, cgrib, lcgrib, production_status, &
Disc, center, subcenter, MasterTblV, LocalTblV, ierr, msg)
if (ierr .ne. 0) then
call wrf_message
(trim(msg))
Status = WRF_GRIB2_ERR_GRIBCREATE
return
endif
!
! Add the grid definition section (section 3) using a 1x1 grid
!
call gr2_addgrid_w
(cgrib, lcgrib, center_lat, proj_central_lon, &
wrf_projection, truelat1, truelat2, xsize, ysize, dx, dy, &
region_center_lat, region_center_lon, ierr, msg)
if (ierr .ne. 0) then
call wrf_message
(trim(msg))
Status = WRF_GRIB2_ERR_ADDGRIB
return
endif
if (ndims .eq. 1) then
numlevels = zsize
grib_levels(:) = level1(:)
ngrdpts = zsize
else
numlevels = 2
grib_levels(1) = level1(dim3)
grib_levels(2) = level2(dim3)
ngrdpts = xsize*ysize
endif
!
! Add the Product Definition, Data representation, bitmap
! and data sections (sections 4-7)
!
call gr2_addfield_w
(cgrib, lcgrib, VarName, Category, ParmNum, &
DecScl, BinScl, fcst_secs, vert_unit1, vert_unit2, &
vert_sclFctr1, vert_sclFctr2, numlevels, &
grib_levels, ngrdpts, background_proc_id, forecast_proc_id, &
compression, data, ierr, msg)
if (ierr .eq. 11) then
write(msg,'(A,I7,A)') 'WARNING: decimal scale for field '//&
trim(VarName)//' at level ',grib_levels(1),&
' was reduced to fit field into 24 bits. '//&
' Some precision may be lost!'//&
' To prevent this message, reduce decimal scale '//&
'factor in '//trim(mapfilename)
call wrf_message
(trim(msg))
else if (ierr .eq. 12) then
write(msg,'(A,I7,A)') 'WARNING: binary scale for field '//&
trim(VarName)//' at level ',grib_levels(1), &
' was reduced to fit field into 24 bits. '//&
' Some precision may be lost!'//&
' To prevent this message, reduce binary scale '//&
'factor in '//trim(mapfilename)
call wrf_message
(trim(msg))
else if (ierr .ne. 0) then
call wrf_message
(trim(msg))
Status = WRF_GRIB2_ERR_ADDFIELD
return
endif
!
! Close out the message
!
call gribend(cgrib,lcgrib,lengrib,ierr)
if (ierr .ne. 0) then
write(msg,*) 'gribend failed with ierr: ',ierr
call wrf_message
(trim(msg))
Status = WRF_GRIB2_ERR_GRIBEND
return
endif
!
! Write the data to the file
!
! call write_file_n(fileinfo(DataHandle)%FileFd, cgrib, lengrib, ierr)
call bawrite(DataHandle, -1, lengrib, bytes_written, cgrib)
if (bytes_written .ne. lengrib) then
write(msg,*) '1 Error writing cgrib to file, wrote: ', &
bytes_written, ' bytes. Tried to write ', lengrib, ' bytes'
call wrf_message
(trim(msg))
Status = WRF_GRIB2_ERR_WRITE
return
endif
ENDDO VERTDIM
DEALLOCATE(data)
endif
last_fcst_secs = fcst_secs
endif
deallocate(data, STAT = istat)
Status = WRF_NO_ERR
call wrf_debug
( DEBUG , 'Leaving ext_gr2_write_field')
RETURN
END SUBROUTINE ext_gr2_write_field
!*****************************************************************************
SUBROUTINE ext_gr2_read_field ( DataHandle , DateStr , VarName , Field , &,20
FieldType , Comm , IOComm, DomainDesc , MemoryOrder , Stagger , &
DimNames , DomainStart , DomainEnd , MemoryStart , MemoryEnd , &
PatchStart , PatchEnd , Status )
USE gr2_data_info
USE grib_mod
IMPLICIT NONE
#include "wrf_status_codes.h"
#include "wrf_io_flags.h"
INTEGER ,intent(in) :: DataHandle
CHARACTER*(*) ,intent(in) :: DateStr
CHARACTER*(*) ,intent(in) :: VarName
integer ,intent(inout) :: FieldType
integer ,intent(inout) :: Comm
integer ,intent(inout) :: IOComm
integer ,intent(inout) :: DomainDesc
character*(*) ,intent(inout) :: MemoryOrder
character*(*) ,intent(inout) :: Stagger
character*(*) , dimension (*) ,intent(inout) :: DimNames
integer ,dimension(*) ,intent(inout) :: DomainStart, DomainEnd
integer ,dimension(*) ,intent(inout) :: MemoryStart, MemoryEnd
integer ,dimension(*) ,intent(inout) :: PatchStart, PatchEnd
integer ,intent(out) :: Status
INTEGER ,intent(out) :: Field(*)
integer :: xsize,ysize,zsize
integer :: x_start,x_end,y_start,y_end,z_start,z_end
integer :: ndims
character (len=1000) :: Value
character (maxMsgSize) :: msg
integer :: ierr
real :: Data
integer :: center, subcenter, MasterTblV, &
LocalTblV, Disc, Category, ParmNum, DecScl, BinScl
integer :: dim1size,dim2size,dim3size,dim3
integer :: idx
integer :: fields_to_skip
integer :: JIDS(JIDSSIZE), JPDTN, JPDT(JPDTSIZE), JGDTN, &
JGDT(JGDTSIZE)
logical :: UNPACK
type(gribfield) :: gfld
logical :: soil_layers, fraction
logical :: vert_stag = .false.
integer :: vert_unit1, vert_unit2
integer :: vert_sclFctr1, vert_sclFctr2
integer :: level1, level2
integer :: di
real :: tmpreal
call wrf_debug
( DEBUG , 'Entering ext_gr2_read_field'//fileinfo(DataHandle)%DataFile)
CALL get_dims
(MemoryOrder, PatchStart, PatchEnd, ndims, x_start, x_end, &
y_start, y_end,z_start,z_end)
xsize = x_end - x_start + 1
ysize = y_end - y_start + 1
zsize = z_end - z_start + 1
!
! Check to assure that dimensions are valid
!
if ((xsize .lt. 1) .or. (ysize .lt. 1) .or. (zsize .lt. 1)) then
write(msg,*) 'Cannot retrieve field with memory order: ', &
MemoryOrder,Varname
Status = WRF_GRIB2_ERR_READ
call wrf_message
(trim(msg))
return
endif
if (ndims .eq. 0) then ! Scalar quantity
call gr2_get_metadata_value
(scalar_input(DataHandle),trim(VarName),&
Value,ierr)
if (ierr /= 0) then
Status = WRF_GRIB2_ERR_READ
CALL wrf_message
( &
"gr2_get_metadata_value failed for Scalar variable "//&
trim(VarName))
return
endif
READ(Value,*,IOSTAT=ierr)Data
if (ierr .ne. 0) then
CALL wrf_message
("Reading data from "//trim(VarName)//" failed")
Status = WRF_GRIB2_ERR_READ
return
endif
if (FieldType .eq. WRF_INTEGER) then
Field(1:1) = data
else if ((FieldType .eq. WRF_REAL) .or. (FieldType .eq. WRF_DOUBLE)) then
Field(1:1) = TRANSFER(data,Field(1),1)
else
write (msg,*)'Reading of type ',FieldType,'from grib data not supported, not reading ',VarName
call wrf_message
(msg)
endif
else if (ndims .ge. 1) then ! Vector (1-D) and 2/3 D quantities
if (ndims .eq. 1) then ! Handle Vector (1-D) parameters
dim1size = zsize
dim2size = 1
dim3size = 1
else ! Handle 2/3 D parameters
dim1size = xsize
dim2size = ysize
dim3size = zsize
endif
CALL get_parminfo
(VarName, center, subcenter, MasterTblV, &
LocalTblV, Disc, Category, ParmNum, DecScl, BinScl, status)
if (status .ne. 0) then
write(msg,*) 'Could not find parameter for '// &
trim(VarName)//' Skipping output of '//trim(VarName)
call wrf_message
(trim(msg))
Status = WRF_GRIB2_ERR_GRIB2MAP
return
endif
CALL get_vert_stag
(VarName,Stagger,vert_stag)
CALL get_soil_layers
(VarName,soil_layers)
VERTDIM : do dim3 = 1, dim3size
fields_to_skip = 0
!
! First, set all values to wild, then specify necessary values
!
call gr2_g2lib_wildcard
(JIDS, JPDT, JGDT)
JIDS(1) = center
JIDS(2) = subcenter
JIDS(3) = MasterTblV
JIDS(4) = LocalTblV
JIDS(5) = 1 ! Indicates that time is "Start of Forecast"
READ (StartDate,'(I4.4,1X,I2.2,1X,I2.2,1X,I2.2,1X,I2.2,1X,I2.2)') &
(JIDS(idx),idx=6,11)
JIDS(13) = 1 ! Type of processed data(1 for forecast products)
JPDT(1) = Category
JPDT(2) = ParmNum
JPDT(3) = 2 ! Generating process id
CALL geth_idts
(DateStr,StartDate,tmpreal) ! Forecast time
JPDT(9) = NINT(tmpreal)
if (ndims .eq. 1) then
jpdtn = 1000 ! Product definition tmplate (1000 for cross-sxn)
else
call gr2_get_levels
(VarName, dim3, dim3size, soil_layers, &
vert_stag, .false., vert_unit1, vert_unit2, vert_sclFctr1, &
vert_sclFctr2, level1, level2)
jpdtn = 0 ! Product definition template (0 for horiz grid)
JPDT(10) = vert_unit1 ! Type of first surface
JPDT(11) = vert_sclFctr1 ! Scale factor first surface
JPDT(12) = level1 ! First surface
JPDT(13) = vert_unit2 ! Type of second surface
JPDT(14) = vert_sclFctr2 ! Scale factor second surface
JPDT(15) = level2 ! Second fixed surface
endif
JGDTN = -1 ! Indicates that any Grid Display Template is a match
UNPACK = .TRUE.! Unpack bitmap and data values
fields_to_skip = 0
CALL GETGB2(DataHandle, 0, fields_to_skip, &
fileinfo(DataHandle)%recnum+1, &
Disc, JIDS, JPDTN, JPDT, JGDTN, JGDT, UNPACK, &
fileinfo(DataHandle)%recnum, gfld, status)
if (status .eq. 99) then
write(msg,*)'Could not find data for field '//trim(VarName)//&
' in file '//trim(fileinfo(DataHandle)%DataFile)
call wrf_message
(trim(msg))
Status = WRF_GRIB2_ERR_READ
return
else if (status .ne. 0) then
write(msg,*)'Retrieving data field '//trim(VarName)//' failed 2.',status,dim3,DataHandle
call wrf_message
(trim(msg))
Status = WRF_GRIB2_ERR_READ
return
endif
if(FieldType == WRF_DOUBLE) then
di = 2
else
di = 1
endif
!
! Here, we do any necessary conversions to the data.
!
! The WRF executable (wrf.exe) expects perturbation potential
! temperature. However, real.exe expects full potential T.
! So, if the program is WRF, subtract 300 from Potential Temperature
! to get perturbation potential temperature.
!
if (VarName == 'T') then
if ( &
(InputProgramName .eq. 'REAL_EM') .or. &
(InputProgramName .eq. 'IDEAL') .or. &
(InputProgramName .eq. 'NDOWN_EM')) then
gfld%fld = gfld%fld - 300
endif
endif
if (ndims .eq. 1) then
CALL Transpose1D_grib
(MemoryOrder, di, FieldType, Field, &
MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), &
MemoryStart(3), MemoryEnd(3), &
gfld%fld, zsize)
else
CALL Transpose_grib
(MemoryOrder, di, FieldType, Field, &
MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), &
MemoryStart(3), MemoryEnd(3), &
gfld%fld, dim3, ysize,xsize)
endif
call gf_free(gfld)
enddo VERTDIM
endif
Status = WRF_NO_ERR
call wrf_debug
( DEBUG , 'Leaving ext_gr2_read_field')
RETURN
END SUBROUTINE ext_gr2_read_field
!*****************************************************************************
SUBROUTINE ext_gr2_get_next_var ( DataHandle, VarName, Status ) 1,2
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: VarName
INTEGER , INTENT(OUT) :: Status
call wrf_debug
( DEBUG , 'Entering ext_gr2_get_next_var')
Status = WRF_WARN_NOOP
RETURN
END SUBROUTINE ext_gr2_get_next_var
!*****************************************************************************
subroutine ext_gr2_end_of_frame(DataHandle, Status),2
USE gr2_data_info
implicit none
#include "wrf_status_codes.h"
integer ,intent(in) :: DataHandle
integer ,intent(out) :: Status
call wrf_debug
( DEBUG , 'Entering ext_gr2_end_of_frame')
Status = WRF_WARN_NOOP
return
end subroutine ext_gr2_end_of_frame
!*****************************************************************************
SUBROUTINE ext_gr2_iosync ( DataHandle, Status ) 2,2
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
INTEGER , INTENT(OUT) :: Status
integer :: ierror
call wrf_debug
( DEBUG , 'Entering ext_gr2_iosync')
Status = WRF_NO_ERR
if (DataHandle .GT. 0) then
CALL flush_file(fileinfo(DataHandle)%FileFd)
else
Status = WRF_WARN_TOO_MANY_FILES
endif
RETURN
END SUBROUTINE ext_gr2_iosync
!*****************************************************************************
SUBROUTINE ext_gr2_inquire_filename ( DataHandle, FileName , FileStat, & 5,2
Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
#include "wrf_io_flags.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: FileName
INTEGER , INTENT(OUT) :: FileStat
INTEGER , INTENT(OUT) :: Status
CHARACTER *80 SysDepInfo
call wrf_debug
( DEBUG , 'Entering ext_gr2_inquire_filename')
FileName = fileinfo(DataHandle)%DataFile
if ((DataHandle .ge. firstFileHandle) .and. &
(DataHandle .le. maxFileHandles)) then
FileStat = fileinfo(DataHandle)%FileStatus
else
FileStat = WRF_FILE_NOT_OPENED
endif
Status = WRF_NO_ERR
RETURN
END SUBROUTINE ext_gr2_inquire_filename
!*****************************************************************************
SUBROUTINE ext_gr2_get_var_info ( DataHandle , VarName , NDim , & 1,3
MemoryOrder , Stagger , DomainStart , DomainEnd , WrfType, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
integer ,intent(in) :: DataHandle
character*(*) ,intent(in) :: VarName
integer ,intent(out) :: NDim
character*(*) ,intent(out) :: MemoryOrder
character*(*) ,intent(out) :: Stagger
integer ,dimension(*) ,intent(out) :: DomainStart, DomainEnd
integer ,intent(out) :: WrfType
integer ,intent(out) :: Status
call wrf_debug
( DEBUG , 'Entering ext_gr2_get_var_info')
MemoryOrder = ""
Stagger = ""
DomainStart(1) = 0
DomainEnd(1) = 0
WrfType = 0
NDim = 0
CALL wrf_message
('ext_gr2_get_var_info not supported for grib version2 data')
Status = WRF_NO_ERR
RETURN
END SUBROUTINE ext_gr2_get_var_info
!*****************************************************************************
SUBROUTINE ext_gr2_set_time ( DataHandle, DateStr, Status ) 1,2
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: DateStr
INTEGER , INTENT(OUT) :: Status
integer :: found_time
integer :: idx
call wrf_debug
( DEBUG , 'Entering ext_gr2_set_time')
found_time = 0
do idx = 1,fileinfo(DataHandle)%NumberTimes
if (fileinfo(DataHandle)%Times(idx) == DateStr) then
found_time = 1
fileinfo(DataHandle)%CurrentTime = idx
endif
enddo
if (found_time == 0) then
Status = WRF_WARN_TIME_NF
else
Status = WRF_NO_ERR
endif
RETURN
END SUBROUTINE ext_gr2_set_time
!*****************************************************************************
SUBROUTINE ext_gr2_get_next_time ( DataHandle, DateStr, Status ) 1,3
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) , INTENT(OUT) :: DateStr
INTEGER , INTENT(OUT) :: Status
call wrf_debug
( DEBUG , 'Entering ext_gr2_get_next_time')
if (fileinfo(DataHandle)%CurrentTime == fileinfo(DataHandle)%NumberTimes) then
Status = WRF_WARN_TIME_EOF
else
fileinfo(DataHandle)%CurrentTime = fileinfo(DataHandle)%CurrentTime + 1
DateStr = fileinfo(DataHandle)%Times(fileinfo(DataHandle)%CurrentTime)
Status = WRF_NO_ERR
endif
call wrf_debug
( DEBUG , 'Leaving ext_gr2_get_next_time, got time '//DateStr)
RETURN
END SUBROUTINE ext_gr2_get_next_time
!*****************************************************************************
SUBROUTINE ext_gr2_get_previous_time ( DataHandle, DateStr, Status ) 1,2
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: DateStr
INTEGER , INTENT(OUT) :: Status
call wrf_debug
( DEBUG , 'Entering ext_gr2_get_previous_time')
if (fileinfo(DataHandle)%CurrentTime <= 0) then
Status = WRF_WARN_TIME_EOF
else
fileinfo(DataHandle)%CurrentTime = fileinfo(DataHandle)%CurrentTime - 1
DateStr = fileinfo(DataHandle)%Times(fileinfo(DataHandle)%CurrentTime)
Status = WRF_NO_ERR
endif
RETURN
END SUBROUTINE ext_gr2_get_previous_time
!******************************************************************************
!* Start of get_var_ti_* routines
!******************************************************************************
SUBROUTINE ext_gr2_get_var_ti_real ( DataHandle,Element, Varname, Data, &,5
Count, Outcount, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: VarName
real , INTENT(OUT) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: OutCount
INTEGER , INTENT(OUT) :: Status
INTEGER :: idx
INTEGER :: stat
CHARACTER(len=100) :: Value
call wrf_debug
( DEBUG , 'Entering ext_gr2_get_var_ti_real')
Status = WRF_NO_ERR
CALL gr2_get_metadata_value
(global_input(DataHandle), &
trim(VarName)//';'//trim(Element), Value, stat)
if (stat /= 0) then
CALL wrf_debug
( DEBUG , "gr2_get_metadata_value failed for "//trim(VarName)//';'//trim(Element))
Status = WRF_WARN_VAR_NF
RETURN
endif
READ(Value,*,IOSTAT=stat)(Data(idx),idx=1,Count)
if (stat .ne. 0) then
CALL wrf_message
("Reading data from"//Value//"failed")
Status = WRF_WARN_COUNT_TOO_LONG
RETURN
endif
Outcount = idx
RETURN
END SUBROUTINE ext_gr2_get_var_ti_real
!*****************************************************************************
SUBROUTINE ext_gr2_get_var_ti_real8 ( DataHandle,Element, Varname, Data, &,5
Count, Outcount, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: VarName
real*8 , INTENT(OUT) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: OutCount
INTEGER , INTENT(OUT) :: Status
INTEGER :: idx
INTEGER :: stat
CHARACTER*(100) :: VALUE
call wrf_debug
( DEBUG , 'Entering ext_gr2_get_var_ti_real8')
Status = WRF_NO_ERR
CALL gr2_get_metadata_value
(global_input(DataHandle), &
trim(VarName)//';'//trim(Element), Value, stat)
if (stat /= 0) then
CALL wrf_debug
( DEBUG , "gr2_get_metadata_value failed for "//trim(VarName)//';'//trim(Element))
Status = WRF_WARN_VAR_NF
RETURN
endif
READ(Value,*,IOSTAT=stat)(Data(idx),idx=1,Count)
if (stat .ne. 0) then
CALL wrf_message
("Reading data from"//Value//"failed")
Status = WRF_WARN_COUNT_TOO_LONG
RETURN
endif
Outcount = idx
RETURN
END SUBROUTINE ext_gr2_get_var_ti_real8
!*****************************************************************************
SUBROUTINE ext_gr2_get_var_ti_double ( DataHandle,Element, Varname, Data, &,5
Count, Outcount, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) , INTENT(IN) :: Element
CHARACTER*(*) , INTENT(IN) :: VarName
real*8 , INTENT(OUT) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: OutCount
INTEGER , INTENT(OUT) :: Status
INTEGER :: idx
INTEGER :: stat
CHARACTER*(100) :: VALUE
call wrf_debug
( DEBUG , 'Entering ext_gr2_get_var_ti_double')
Status = WRF_NO_ERR
CALL gr2_get_metadata_value
(global_input(DataHandle), &
trim(VarName)//';'//trim(Element), Value, stat)
if (stat /= 0) then
CALL wrf_debug
( DEBUG , "gr2_get_metadata_value failed for "//trim(VarName)//';'//trim(Element))
Status = WRF_WARN_VAR_NF
RETURN
endif
READ(Value,*,IOSTAT=stat)(Data(idx),idx=1,Count)
if (stat .ne. 0) then
CALL wrf_message
("Reading data from"//Value//"failed")
Status = WRF_WARN_COUNT_TOO_LONG
RETURN
endif
Outcount = idx
RETURN
END SUBROUTINE ext_gr2_get_var_ti_double
!*****************************************************************************
SUBROUTINE ext_gr2_get_var_ti_integer ( DataHandle,Element, Varname, Data, &,5
Count, Outcount, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: VarName
integer , INTENT(OUT) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: OutCount
INTEGER , INTENT(OUT) :: Status
INTEGER :: idx
INTEGER :: stat
CHARACTER*(1000) :: VALUE
call wrf_debug
( DEBUG , 'Entering ext_gr2_get_var_ti_integer')
Status = WRF_NO_ERR
CALL gr2_get_metadata_value
(global_input(DataHandle), &
trim(VarName)//';'//trim(Element), Value, stat)
if (stat /= 0) then
CALL wrf_debug
( DEBUG , "gr2_get_metadata_value failed for "//trim(VarName)//';'//trim(Element))
Status = WRF_WARN_VAR_NF
RETURN
endif
READ(Value,*,IOSTAT=stat)(Data(idx),idx=1,Count)
if (stat .ne. 0) then
CALL wrf_message
("Reading data from"//Value//"failed")
Status = WRF_WARN_COUNT_TOO_LONG
RETURN
endif
Outcount = idx
RETURN
END SUBROUTINE ext_gr2_get_var_ti_integer
!*****************************************************************************
SUBROUTINE ext_gr2_get_var_ti_logical ( DataHandle,Element, Varname, Data, &,5
Count, Outcount, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: VarName
logical , INTENT(OUT) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: OutCount
INTEGER , INTENT(OUT) :: Status
INTEGER :: idx
INTEGER :: stat
CHARACTER*(100) :: VALUE
call wrf_debug
( DEBUG , 'Entering ext_gr2_get_var_ti_logical')
Status = WRF_NO_ERR
CALL gr2_get_metadata_value
(global_input(DataHandle), &
trim(VarName)//';'//trim(Element), Value, stat)
if (stat /= 0) then
CALL wrf_debug
( DEBUG , "gr2_get_metadata_value failed for "//trim(VarName)//';'//trim(Element))
Status = WRF_WARN_VAR_NF
RETURN
endif
READ(Value,*,IOSTAT=stat)(Data(idx),idx=1,Count)
if (stat .ne. 0) then
CALL wrf_message
("Reading data from"//Value//"failed")
Status = WRF_WARN_COUNT_TOO_LONG
RETURN
endif
Outcount = idx
RETURN
END SUBROUTINE ext_gr2_get_var_ti_logical
!*****************************************************************************
SUBROUTINE ext_gr2_get_var_ti_char ( DataHandle,Element, Varname, Data, &,4
Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: VarName
CHARACTER*(*) :: Data
INTEGER , INTENT(OUT) :: Status
INTEGER :: stat
Status = WRF_NO_ERR
call wrf_debug
( DEBUG , 'Entering ext_gr2_get_var_ti_char')
CALL gr2_get_metadata_value
(global_input(DataHandle), &
trim(VarName)//';'//trim(Element), Data, stat)
if (stat /= 0) then
CALL wrf_debug
( DEBUG , "gr2_get_metadata_value failed for "//trim(VarName)//';'//trim(Element))
Status = WRF_WARN_VAR_NF
RETURN
endif
RETURN
END SUBROUTINE ext_gr2_get_var_ti_char
!******************************************************************************
!* End of get_var_ti_* routines
!******************************************************************************
!******************************************************************************
!* Start of put_var_ti_* routines
!******************************************************************************
SUBROUTINE ext_gr2_put_var_ti_real ( DataHandle,Element, Varname, Data, &,3
Count, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: VarName
real , INTENT(IN) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: Status
CHARACTER(len=1000) :: tmpstr(1000)
INTEGER :: idx
call wrf_debug
( DEBUG , 'Entering ext_gr2_put_var_ti_real')
if (fileinfo(DataHandle)%committed) then
do idx = 1,Count
write(tmpstr(idx),'(G17.10)')Data(idx)
enddo
CALL gr2_build_string
(ti_output(DataHandle), &
trim(VarName)//';'//trim(Element), tmpstr, Count, Status)
endif
RETURN
END SUBROUTINE ext_gr2_put_var_ti_real
!*****************************************************************************
SUBROUTINE ext_gr2_put_var_ti_double ( DataHandle,Element, Varname, Data, &,3
Count, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) , INTENT(IN) :: Element
CHARACTER*(*) , INTENT(IN) :: VarName
real*8 , INTENT(IN) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: Status
CHARACTER(len=1000) :: tmpstr(1000)
INTEGER :: idx
call wrf_debug
( DEBUG , 'Entering ext_gr2_put_var_ti_double')
if (fileinfo(DataHandle)%committed) then
do idx = 1,Count
write(tmpstr(idx),'(G17.10)')Data(idx)
enddo
CALL gr2_build_string
(ti_output(DataHandle), &
trim(VarName)//';'//trim(Element), tmpstr, Count, Status)
endif
RETURN
END SUBROUTINE ext_gr2_put_var_ti_double
!*****************************************************************************
SUBROUTINE ext_gr2_put_var_ti_real8 ( DataHandle,Element, Varname, Data, &,3
Count, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: VarName
real*8 , INTENT(IN) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: Status
CHARACTER(len=1000) :: tmpstr(1000)
INTEGER :: idx
call wrf_debug
( DEBUG , 'Entering ext_gr2_put_var_ti_real8')
if (fileinfo(DataHandle)%committed) then
do idx = 1,Count
write(tmpstr(idx),'(G17.10)')Data(idx)
enddo
CALL gr2_build_string
(ti_output(DataHandle), &
trim(VarName)//';'//trim(Element), tmpstr, Count, Status)
endif
RETURN
END SUBROUTINE ext_gr2_put_var_ti_real8
!*****************************************************************************
SUBROUTINE ext_gr2_put_var_ti_integer ( DataHandle,Element, Varname, Data, &,3
Count, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: VarName
integer , INTENT(IN) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: Status
CHARACTER(len=1000) :: tmpstr(1000)
INTEGER :: idx
call wrf_debug
( DEBUG , 'Entering ext_gr2_put_var_ti_integer')
if (fileinfo(DataHandle)%committed) then
do idx = 1,Count
write(tmpstr(idx),'(G17.10)')Data(idx)
enddo
CALL gr2_build_string
(ti_output(DataHandle), &
trim(VarName)//';'//trim(Element), tmpstr, Count, Status)
endif
RETURN
END SUBROUTINE ext_gr2_put_var_ti_integer
!*****************************************************************************
SUBROUTINE ext_gr2_put_var_ti_logical ( DataHandle,Element, Varname, Data, &,3
Count, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: VarName
logical , INTENT(IN) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: Status
CHARACTER(len=1000) :: tmpstr(1000)
INTEGER :: idx
call wrf_debug
( DEBUG , 'Entering ext_gr2_put_var_ti_logical')
if (fileinfo(DataHandle)%committed) then
do idx = 1,Count
write(tmpstr(idx),'(G17.10)')Data(idx)
enddo
CALL gr2_build_string
(ti_output(DataHandle), &
trim(Varname)//';'//trim(Element), tmpstr, Count, Status)
endif
RETURN
END SUBROUTINE ext_gr2_put_var_ti_logical
!*****************************************************************************
SUBROUTINE ext_gr2_put_var_ti_char ( DataHandle,Element, Varname, Data, & 2,3
Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER(len=*) :: Element
CHARACTER(len=*) :: VarName
CHARACTER(len=*) :: Data
INTEGER , INTENT(OUT) :: Status
REAL dummy
INTEGER :: Count
CHARACTER(len=1000) :: tmpstr(1)
INTEGER :: idx
call wrf_debug
( DEBUG , 'Entering ext_gr2_put_var_ti_char')
if (fileinfo(DataHandle)%committed) then
write(tmpstr(1),*)trim(Data)
CALL gr2_build_string
(ti_output(DataHandle), &
trim(VarName)//';'//trim(Element), tmpstr, 1, Status)
endif
RETURN
END SUBROUTINE ext_gr2_put_var_ti_char
!******************************************************************************
!* End of put_var_ti_* routines
!******************************************************************************
!******************************************************************************
!* Start of get_var_td_* routines
!******************************************************************************
SUBROUTINE ext_gr2_get_var_td_double ( DataHandle,Element, DateStr, &,5
Varname, Data, Count, Outcount, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) , INTENT(IN) :: Element
CHARACTER*(*) , INTENT(IN) :: DateStr
CHARACTER*(*) , INTENT(IN) :: VarName
real*8 , INTENT(OUT) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: OutCount
INTEGER , INTENT(OUT) :: Status
INTEGER :: idx
INTEGER :: stat
CHARACTER*(1000) :: VALUE
call wrf_debug
( DEBUG , 'Entering ext_gr2_get_var_td_double')
Status = WRF_NO_ERR
CALL gr2_get_metadata_value
(global_input(DataHandle), &
trim(VarName)//';'//trim(DateStr)//';'//trim(Element), Value, stat)
if (stat /= 0) then
CALL wrf_debug
( DEBUG , "gr2_get_metadata_value failed for "//trim(VarName)//';'//trim(DateStr)//';'//trim(Element))
Status = WRF_WARN_VAR_NF
RETURN
endif
READ(Value,*,IOSTAT=stat)(Data(idx),idx=1,Count)
if (stat .ne. 0) then
CALL wrf_message
("Reading data from"//Value//"failed")
Status = WRF_WARN_COUNT_TOO_LONG
RETURN
endif
Outcount = idx
RETURN
END SUBROUTINE ext_gr2_get_var_td_double
!*****************************************************************************
SUBROUTINE ext_gr2_get_var_td_real ( DataHandle,Element, DateStr,Varname, &,5
Data, Count, Outcount, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: DateStr
CHARACTER*(*) :: VarName
real , INTENT(OUT) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: OutCount
INTEGER , INTENT(OUT) :: Status
INTEGER :: idx
INTEGER :: stat
CHARACTER*(1000) :: VALUE
call wrf_debug
( DEBUG , 'Entering ext_gr2_get_var_td_real')
Status = WRF_NO_ERR
CALL gr2_get_metadata_value
(global_input(DataHandle), &
trim(VarName)//';'//trim(DateStr)//';'//trim(Element), Value, stat)
if (stat /= 0) then
CALL wrf_debug
( DEBUG , "gr2_get_metadata_value failed for "//trim(VarName)//';'//trim(DateStr)//';'//trim(Element))
Status = WRF_WARN_VAR_NF
RETURN
endif
READ(Value,*,IOSTAT=stat)(Data(idx),idx=1,Count)
if (stat .ne. 0) then
CALL wrf_message
("Reading data from"//Value//"failed")
Status = WRF_WARN_COUNT_TOO_LONG
RETURN
endif
Outcount = idx
RETURN
END SUBROUTINE ext_gr2_get_var_td_real
!*****************************************************************************
SUBROUTINE ext_gr2_get_var_td_real8 ( DataHandle,Element, DateStr,Varname, &,5
Data, Count, Outcount, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: DateStr
CHARACTER*(*) :: VarName
real*8 , INTENT(OUT) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: OutCount
INTEGER , INTENT(OUT) :: Status
INTEGER :: idx
INTEGER :: stat
CHARACTER*(1000) :: VALUE
call wrf_debug
( DEBUG , 'Entering ext_gr2_get_var_td_real8')
Status = WRF_NO_ERR
CALL gr2_get_metadata_value
(global_input(DataHandle), &
trim(VarName)//';'//trim(DateStr)//';'//trim(Element), Value, stat)
if (stat /= 0) then
CALL wrf_debug
( DEBUG , "gr2_get_metadata_value failed for "//trim(VarName)//';'//trim(DateStr)//';'//trim(Element))
Status = WRF_WARN_VAR_NF
RETURN
endif
READ(Value,*,IOSTAT=stat)(Data(idx),idx=1,Count)
if (stat .ne. 0) then
CALL wrf_message
("Reading data from"//Value//"failed")
Status = WRF_WARN_COUNT_TOO_LONG
RETURN
endif
Outcount = idx
RETURN
END SUBROUTINE ext_gr2_get_var_td_real8
!*****************************************************************************
SUBROUTINE ext_gr2_get_var_td_integer ( DataHandle,Element, DateStr,Varname, &,5
Data, Count, Outcount, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: DateStr
CHARACTER*(*) :: VarName
integer , INTENT(OUT) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: OutCount
INTEGER , INTENT(OUT) :: Status
INTEGER :: idx
INTEGER :: stat
CHARACTER*(1000) :: VALUE
call wrf_debug
( DEBUG , 'Entering ext_gr2_get_var_td_integer')
Status = WRF_NO_ERR
CALL gr2_get_metadata_value
(global_input(DataHandle), &
trim(VarName)//';'//trim(DateStr)//';'//trim(Element), Value, stat)
if (stat /= 0) then
CALL wrf_debug
( DEBUG , "gr2_get_metadata_value failed for "//trim(VarName)//';'//trim(DateStr)//';'//trim(Element))
Status = WRF_WARN_VAR_NF
RETURN
endif
READ(Value,*,IOSTAT=stat)(Data(idx),idx=1,Count)
if (stat .ne. 0) then
CALL wrf_message
("Reading data from"//Value//"failed")
Status = WRF_WARN_COUNT_TOO_LONG
RETURN
endif
Outcount = idx
RETURN
END SUBROUTINE ext_gr2_get_var_td_integer
!*****************************************************************************
SUBROUTINE ext_gr2_get_var_td_logical ( DataHandle,Element, DateStr,Varname, &,5
Data, Count, Outcount, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: DateStr
CHARACTER*(*) :: VarName
logical , INTENT(OUT) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: OutCount
INTEGER , INTENT(OUT) :: Status
INTEGER :: idx
INTEGER :: stat
CHARACTER*(1000) :: VALUE
call wrf_debug
( DEBUG , 'Entering ext_gr2_get_var_td_logical')
Status = WRF_NO_ERR
CALL gr2_get_metadata_value
(global_input(DataHandle), &
trim(VarName)//';'//trim(DateStr)//';'//trim(Element), Value, stat)
if (stat /= 0) then
CALL wrf_debug
( DEBUG , "gr2_get_metadata_value failed for "//trim(VarName)//';'//trim(DateStr)//';'//trim(Element))
Status = WRF_WARN_VAR_NF
RETURN
endif
READ(Value,*,IOSTAT=stat)(Data(idx),idx=1,Count)
if (stat .ne. 0) then
CALL wrf_message
("Reading data from"//Value//"failed")
Status = WRF_WARN_COUNT_TOO_LONG
RETURN
endif
Outcount = idx
RETURN
END SUBROUTINE ext_gr2_get_var_td_logical
!*****************************************************************************
SUBROUTINE ext_gr2_get_var_td_char ( DataHandle,Element, DateStr,Varname, &,4
Data, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: DateStr
CHARACTER*(*) :: VarName
CHARACTER*(*) :: Data
INTEGER , INTENT(OUT) :: Status
INTEGER :: stat
Status = WRF_NO_ERR
call wrf_debug
( DEBUG , 'Entering ext_gr2_get_var_td_char')
CALL gr2_get_metadata_value
(global_input(DataHandle), &
trim(VarName)//';'//trim(DateStr)//';'//trim(Element), Data, stat)
if (stat /= 0) then
CALL wrf_debug
( DEBUG , "gr2_get_metadata_value failed for "//trim(VarName)//';'//trim(DateStr)//';'//trim(Element))
Status = WRF_WARN_VAR_NF
RETURN
endif
RETURN
END SUBROUTINE ext_gr2_get_var_td_char
!******************************************************************************
!* End of get_var_td_* routines
!******************************************************************************
!******************************************************************************
!* Start of put_var_td_* routines
!******************************************************************************
SUBROUTINE ext_gr2_put_var_td_double ( DataHandle, Element, DateStr, Varname, &,3
Data, Count, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) , INTENT(IN) :: Element
CHARACTER*(*) , INTENT(IN) :: DateStr
CHARACTER*(*) , INTENT(IN) :: VarName
real*8 , INTENT(IN) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: Status
CHARACTER(len=1000) :: tmpstr(1000)
INTEGER :: idx
call wrf_debug
( DEBUG , 'Entering ext_gr2_put_var_td_double')
if (fileinfo(DataHandle)%committed) then
do idx = 1,Count
write(tmpstr(idx),'(G17.10)')Data(idx)
enddo
CALL gr2_build_string
(td_output(DataHandle), &
trim(Varname)//';'//trim(DateStr)//';'//trim(Element), &
tmpstr, Count, Status)
endif
RETURN
END SUBROUTINE ext_gr2_put_var_td_double
!*****************************************************************************
SUBROUTINE ext_gr2_put_var_td_integer ( DataHandle,Element, DateStr, &,3
Varname, Data, Count, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: DateStr
CHARACTER*(*) :: VarName
integer , INTENT(IN) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: Status
CHARACTER(len=1000) :: tmpstr(1000)
INTEGER :: idx
call wrf_debug
( DEBUG , 'Entering ext_gr2_put_var_td_integer')
if (fileinfo(DataHandle)%committed) then
do idx = 1,Count
write(tmpstr(idx),'(G17.10)')Data(idx)
enddo
CALL gr2_build_string
(td_output(DataHandle), &
trim(Varname)//';'//trim(DateStr)//';'//trim(Element), &
tmpstr, Count, Status)
endif
RETURN
END SUBROUTINE ext_gr2_put_var_td_integer
!*****************************************************************************
SUBROUTINE ext_gr2_put_var_td_real ( DataHandle,Element, DateStr,Varname, &,3
Data, Count, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: DateStr
CHARACTER*(*) :: VarName
real , INTENT(IN) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: Status
CHARACTER(len=1000) :: tmpstr(1000)
INTEGER :: idx
call wrf_debug
( DEBUG , 'Entering ext_gr2_put_var_td_real')
if (fileinfo(DataHandle)%committed) then
do idx = 1,Count
write(tmpstr(idx),'(G17.10)')Data(idx)
enddo
CALL gr2_build_string
(td_output(DataHandle), &
trim(Varname)//';'//trim(DateStr)//';'//trim(Element), &
tmpstr, Count, Status)
endif
RETURN
END SUBROUTINE ext_gr2_put_var_td_real
!*****************************************************************************
SUBROUTINE ext_gr2_put_var_td_real8 ( DataHandle,Element, DateStr,Varname, &,3
Data, Count, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: DateStr
CHARACTER*(*) :: VarName
real*8 , INTENT(IN) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: Status
CHARACTER(len=1000) :: tmpstr(1000)
INTEGER :: idx
call wrf_debug
( DEBUG , 'Entering ext_gr2_put_var_td_real8')
if (fileinfo(DataHandle)%committed) then
do idx = 1,Count
write(tmpstr(idx),'(G17.10)')Data(idx)
enddo
CALL gr2_build_string
(td_output(DataHandle), &
trim(Varname)//';'//trim(DateStr)//';'//trim(Element), &
tmpstr, Count, Status)
endif
RETURN
END SUBROUTINE ext_gr2_put_var_td_real8
!*****************************************************************************
SUBROUTINE ext_gr2_put_var_td_logical ( DataHandle,Element, DateStr, &,3
Varname, Data, Count, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: DateStr
CHARACTER*(*) :: VarName
logical , INTENT(IN) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: Status
CHARACTER(len=1000) :: tmpstr(1000)
INTEGER :: idx
call wrf_debug
( DEBUG , 'Entering ext_gr2_put_var_td_logical')
if (fileinfo(DataHandle)%committed) then
do idx = 1,Count
write(tmpstr(idx),'(G17.10)')Data(idx)
enddo
CALL gr2_build_string
(td_output(DataHandle), &
trim(Varname)//';'//trim(DateStr)//';'//trim(Element), &
tmpstr, Count, Status)
endif
RETURN
END SUBROUTINE ext_gr2_put_var_td_logical
!*****************************************************************************
SUBROUTINE ext_gr2_put_var_td_char ( DataHandle,Element, DateStr,Varname, &,3
Data, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: DateStr
CHARACTER*(*) :: VarName
CHARACTER*(*) :: Data
INTEGER , INTENT(OUT) :: Status
CHARACTER(len=1000) :: tmpstr(1)
INTEGER :: idx
call wrf_debug
( DEBUG , 'Entering ext_gr2_put_var_td_char')
if (fileinfo(DataHandle)%committed) then
write(tmpstr(idx),*)Data
CALL gr2_build_string
(td_output(DataHandle), &
trim(Varname)//';'//trim(DateStr)//';'//trim(Element), &
tmpstr, 1, Status)
endif
RETURN
END SUBROUTINE ext_gr2_put_var_td_char
!******************************************************************************
!* End of put_var_td_* routines
!******************************************************************************
!******************************************************************************
!* Start of get_dom_ti_* routines
!******************************************************************************
SUBROUTINE ext_gr2_get_dom_ti_real ( DataHandle,Element, Data, Count, &,5
Outcount, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
real , INTENT(OUT) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: Outcount
INTEGER , INTENT(OUT) :: Status
INTEGER :: idx
INTEGER :: stat
CHARACTER*(1000) :: VALUE
call wrf_debug
( DEBUG , 'Entering ext_gr2_get_dom_ti_real')
Status = WRF_NO_ERR
CALL gr2_get_metadata_value
(global_input(DataHandle), &
trim(Element), Value, stat)
if (stat /= 0) then
CALL wrf_debug
( DEBUG , "gr2_get_metadata_value failed for "//trim(Element))
Status = WRF_WARN_VAR_NF
RETURN
endif
READ(Value,*,IOSTAT=stat)(Data(idx),idx=1,Count)
if (stat .ne. 0) then
CALL wrf_message
("Reading data from"//Value//"failed")
Status = WRF_WARN_COUNT_TOO_LONG
RETURN
endif
Outcount = idx
RETURN
END SUBROUTINE ext_gr2_get_dom_ti_real
!*****************************************************************************
SUBROUTINE ext_gr2_get_dom_ti_real8 ( DataHandle,Element, Data, Count, &,5
Outcount, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
real*8 , INTENT(OUT) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: OutCount
INTEGER , INTENT(OUT) :: Status
INTEGER :: idx
INTEGER :: stat
CHARACTER*(1000) :: VALUE
call wrf_debug
( DEBUG , 'Entering ext_gr2_get_dom_ti_real8')
Status = WRF_NO_ERR
CALL gr2_get_metadata_value
(global_input(DataHandle), &
trim(Element), Value, stat)
if (stat /= 0) then
CALL wrf_debug
( DEBUG , "gr2_get_metadata_value failed for "//trim(Element))
Status = WRF_WARN_VAR_NF
RETURN
endif
READ(Value,*,IOSTAT=stat)(Data(idx),idx=1,Count)
if (stat .ne. 0) then
CALL wrf_message
("Reading data from"//Value//"failed")
Status = WRF_WARN_COUNT_TOO_LONG
RETURN
endif
Outcount = idx
RETURN
END SUBROUTINE ext_gr2_get_dom_ti_real8
!*****************************************************************************
SUBROUTINE ext_gr2_get_dom_ti_integer ( DataHandle,Element, Data, Count, &,5
Outcount, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
integer , INTENT(OUT) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: OutCount
INTEGER , INTENT(OUT) :: Status
INTEGER :: idx
INTEGER :: stat
CHARACTER*(1000) :: VALUE
call wrf_debug
( DEBUG , 'Entering ext_gr2_get_dom_ti_integer Element: '//Element)
CALL gr2_get_metadata_value
(global_input(DataHandle), &
trim(Element), Value, stat)
if (stat /= 0) then
CALL wrf_debug
( DEBUG , "gr2_get_metadata_value failed for "//trim(Element))
Status = WRF_WARN_VAR_NF
RETURN
endif
READ(Value,*,IOSTAT=stat)(Data(idx),idx=1,Count)
if (stat .ne. 0) then
CALL wrf_message
("Reading data from"//Value//"failed")
Status = WRF_WARN_COUNT_TOO_LONG
RETURN
endif
Outcount = Count
RETURN
END SUBROUTINE ext_gr2_get_dom_ti_integer
!*****************************************************************************
SUBROUTINE ext_gr2_get_dom_ti_logical ( DataHandle,Element, Data, Count, &,5
Outcount, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
logical , INTENT(OUT) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: OutCount
INTEGER , INTENT(OUT) :: Status
INTEGER :: idx
INTEGER :: stat
CHARACTER*(1000) :: VALUE
call wrf_debug
( DEBUG , 'Entering ext_gr2_get_dom_ti_logical')
Status = WRF_NO_ERR
CALL gr2_get_metadata_value
(global_input(DataHandle), &
trim(Element), Value, stat)
if (stat /= 0) then
CALL wrf_debug
( DEBUG , "gr2_get_metadata_value failed for "//trim(Element))
Status = WRF_WARN_VAR_NF
RETURN
endif
READ(Value,*,IOSTAT=stat)(Data(idx),idx=1,Count)
if (stat .ne. 0) then
CALL wrf_message
("Reading data from"//Value//"failed")
Status = WRF_WARN_COUNT_TOO_LONG
RETURN
endif
Outcount = idx
RETURN
END SUBROUTINE ext_gr2_get_dom_ti_logical
!*****************************************************************************
SUBROUTINE ext_gr2_get_dom_ti_char ( DataHandle,Element, Data, Status ),4
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: Data
INTEGER , INTENT(OUT) :: Status
INTEGER :: stat
INTEGER :: endchar
Status = WRF_NO_ERR
call wrf_debug
( DEBUG , 'Entering ext_gr2_get_dom_ti_char')
CALL gr2_get_metadata_value
(global_input(DataHandle), &
trim(Element), Data, stat)
if (stat /= 0) then
CALL wrf_debug
( DEBUG , "gr2_get_metadata_value failed for "//trim(Element))
Status = WRF_WARN_VAR_NF
RETURN
endif
RETURN
END SUBROUTINE ext_gr2_get_dom_ti_char
!*****************************************************************************
SUBROUTINE ext_gr2_get_dom_ti_double ( DataHandle,Element, Data, Count, &,5
Outcount, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) , INTENT(IN) :: Element
real*8 , INTENT(OUT) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: OutCount
INTEGER , INTENT(OUT) :: Status
INTEGER :: idx
INTEGER :: stat
CHARACTER*(1000) :: VALUE
call wrf_debug
( DEBUG , 'Entering ext_gr2_get_dom_ti_double')
Status = WRF_NO_ERR
CALL gr2_get_metadata_value
(global_input(DataHandle), &
trim(Element), Value, stat)
if (stat /= 0) then
CALL wrf_debug
( DEBUG , "gr2_get_metadata_value failed for "//trim(Element))
Status = WRF_WARN_VAR_NF
RETURN
endif
READ(Value,*,IOSTAT=stat)(Data(idx),idx=1,Count)
if (stat .ne. 0) then
CALL wrf_message
("Reading data from"//Value//"failed")
Status = WRF_WARN_COUNT_TOO_LONG
RETURN
endif
Outcount = idx
RETURN
END SUBROUTINE ext_gr2_get_dom_ti_double
!******************************************************************************
!* End of get_dom_ti_* routines
!******************************************************************************
!******************************************************************************
!* Start of put_dom_ti_* routines
!******************************************************************************
SUBROUTINE ext_gr2_put_dom_ti_real ( DataHandle,Element, Data, Count, & 2,3
Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
real , INTENT(IN) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: Status
REAL dummy
CHARACTER(len=1000) :: tmpstr(1000)
character(len=2) :: lf
integer :: idx
call wrf_debug
( DEBUG , 'Entering ext_gr2_put_dom_ti_real')
if (Element .eq. 'DX') then
dx = Data(1)/1000.
endif
if (Element .eq. 'DY') then
dy = Data(1)/1000.
endif
if (Element .eq. 'CEN_LAT') then
center_lat = Data(1)
endif
if (Element .eq. 'CEN_LON') then
center_lon = Data(1)
endif
if (Element .eq. 'TRUELAT1') then
truelat1 = Data(1)
endif
if (Element .eq. 'TRUELAT2') then
truelat2 = Data(1)
endif
if (Element == 'STAND_LON') then
proj_central_lon = Data(1)
endif
if (Element == 'DT') then
timestep = Data(1)
endif
if (fileinfo(DataHandle)%committed) then
do idx = 1,Count
write(tmpstr(idx),'(G17.10)')Data(idx)
enddo
CALL gr2_build_string
(ti_output(DataHandle), Element, &
tmpstr, Count, Status)
endif
RETURN
END SUBROUTINE ext_gr2_put_dom_ti_real
!*****************************************************************************
SUBROUTINE ext_gr2_put_dom_ti_real8 ( DataHandle,Element, Data, Count, &,3
Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
real*8 , INTENT(IN) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: Status
CHARACTER(len=1000) :: tmpstr(1000)
INTEGER :: idx
call wrf_debug
( DEBUG , 'Entering ext_gr2_put_dom_ti_real8')
if (fileinfo(DataHandle)%committed) then
do idx = 1,Count
write(tmpstr(idx),'(G17.10)')Data(idx)
enddo
CALL gr2_build_string
(ti_output(DataHandle), Element, &
tmpstr, Count, Status)
endif
RETURN
END SUBROUTINE ext_gr2_put_dom_ti_real8
!*****************************************************************************
SUBROUTINE ext_gr2_put_dom_ti_integer ( DataHandle,Element, Data, Count, & 2,4
Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
INTEGER , INTENT(IN) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: Status
REAL dummy
CHARACTER(len=1000) :: tmpstr(1000)
INTEGER :: idx
call wrf_debug
( DEBUG , 'Entering ext_gr2_put_dom_ti_integer')
if (Element == 'WEST-EAST_GRID_DIMENSION') then
full_xsize = Data(1)
else if (Element == 'SOUTH-NORTH_GRID_DIMENSION') then
full_ysize = Data(1)
else if (Element == 'MAP_PROJ') then
wrf_projection = Data(1)
else if (Element == 'BACKGROUND_PROC_ID') then
background_proc_id = Data(1)
else if (Element == 'FORECAST_PROC_ID') then
forecast_proc_id = Data(1)
else if (Element == 'PRODUCTION_STATUS') then
production_status = Data(1)
else if (Element == 'COMPRESSION') then
compression = Data(1)
endif
if (fileinfo(DataHandle)%committed) then
do idx = 1,Count
write(tmpstr(idx),'(G17.10)')Data(idx)
enddo
CALL gr2_build_string
(ti_output(DataHandle), Element, &
tmpstr, Count, Status)
endif
call wrf_debug
( DEBUG , 'Leaving ext_gr2_put_dom_ti_integer')
RETURN
END SUBROUTINE ext_gr2_put_dom_ti_integer
!*****************************************************************************
SUBROUTINE ext_gr2_put_dom_ti_logical ( DataHandle,Element, Data, Count, &,3
Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
logical , INTENT(IN) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: Status
CHARACTER(len=1000) :: tmpstr(1000)
INTEGER :: idx
call wrf_debug
( DEBUG , 'Entering ext_gr2_put_dom_ti_logical')
if (fileinfo(DataHandle)%committed) then
do idx = 1,Count
write(tmpstr(idx),'(G17.10)')Data(idx)
enddo
CALL gr2_build_string
(ti_output(DataHandle), Element, &
tmpstr, Count, Status)
endif
RETURN
END SUBROUTINE ext_gr2_put_dom_ti_logical
!*****************************************************************************
SUBROUTINE ext_gr2_put_dom_ti_char ( DataHandle,Element, Data, & 2,3
Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*), INTENT(IN) :: Data
INTEGER , INTENT(OUT) :: Status
REAL dummy
CHARACTER(len=1000) :: tmpstr
call wrf_debug
( DEBUG , 'Entering ext_gr2_put_dom_ti_char')
if (Element .eq. 'START_DATE') then
!
! This is just a hack to fix a problem when outputting restart. WRF
! outputs both the initialization time and the time of the restart
! as the StartDate. So, we ll just take the earliest.
!
if ((StartDate .eq. '') .or. (Data .le. StartDate)) then
StartDate = Data
endif
endif
if (fileinfo(DataHandle)%committed) then
write(tmpstr,*)trim(Data)
CALL gr2_build_string
(ti_output(DataHandle), Element, &
tmpstr, 1, Status)
endif
RETURN
END SUBROUTINE ext_gr2_put_dom_ti_char
!*****************************************************************************
SUBROUTINE ext_gr2_put_dom_ti_double ( DataHandle,Element, Data, Count, &,3
Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) , INTENT(IN) :: Element
real*8 , INTENT(IN) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: Status
CHARACTER(len=1000) :: tmpstr(1000)
INTEGER :: idx
call wrf_debug
( DEBUG , 'Entering ext_gr2_put_dom_ti_double')
if (fileinfo(DataHandle)%committed) then
do idx = 1,Count
write(tmpstr(idx),'(G17.10)')Data(idx)
enddo
CALL gr2_build_string
(ti_output(DataHandle), Element, &
tmpstr, Count, Status)
endif
RETURN
END SUBROUTINE ext_gr2_put_dom_ti_double
!******************************************************************************
!* End of put_dom_ti_* routines
!******************************************************************************
!******************************************************************************
!* Start of get_dom_td_* routines
!******************************************************************************
SUBROUTINE ext_gr2_get_dom_td_real ( DataHandle,Element, DateStr, Data, &,5
Count, Outcount, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: DateStr
real , INTENT(OUT) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: OutCount
INTEGER , INTENT(OUT) :: Status
INTEGER :: idx
INTEGER :: stat
CHARACTER*(1000) :: VALUE
call wrf_debug
( DEBUG , 'Entering ext_gr2_get_dom_td_real')
Status = WRF_NO_ERR
CALL gr2_get_metadata_value
(global_input(DataHandle), &
trim(DateStr)//';'//trim(Element), Value, stat)
if (stat /= 0) then
CALL wrf_debug
( DEBUG , "gr2_get_metadata_value failed for "//trim(DateStr)//';'//trim(Element))
Status = WRF_WARN_VAR_NF
RETURN
endif
READ(Value,*,IOSTAT=stat)(Data(idx),idx=1,Count)
if (stat .ne. 0) then
CALL wrf_message
("Reading data from"//Value//"failed")
Status = WRF_WARN_COUNT_TOO_LONG
RETURN
endif
Outcount = idx
RETURN
END SUBROUTINE ext_gr2_get_dom_td_real
!*****************************************************************************
SUBROUTINE ext_gr2_get_dom_td_real8 ( DataHandle,Element, DateStr, Data, &,5
Count, Outcount, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: DateStr
real*8 , INTENT(OUT) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: OutCount
INTEGER , INTENT(OUT) :: Status
INTEGER :: idx
INTEGER :: stat
CHARACTER*(1000) :: VALUE
call wrf_debug
( DEBUG , 'Entering ext_gr2_get_dom_td_real8')
Status = WRF_NO_ERR
CALL gr2_get_metadata_value
(global_input(DataHandle), &
trim(DateStr)//';'//trim(Element), Value, stat)
if (stat /= 0) then
CALL wrf_debug
( DEBUG , "gr2_get_metadata_value failed for "//trim(DateStr)//';'//trim(Element))
Status = WRF_WARN_VAR_NF
RETURN
endif
READ(Value,*,IOSTAT=stat)(Data(idx),idx=1,Count)
if (stat .ne. 0) then
CALL wrf_message
("Reading data from"//Value//"failed")
Status = WRF_WARN_COUNT_TOO_LONG
RETURN
endif
Outcount = idx
RETURN
END SUBROUTINE ext_gr2_get_dom_td_real8
!*****************************************************************************
SUBROUTINE ext_gr2_get_dom_td_integer ( DataHandle,Element, DateStr, Data, &,5
Count, Outcount, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: DateStr
integer , INTENT(OUT) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: OutCount
INTEGER , INTENT(OUT) :: Status
INTEGER :: idx
INTEGER :: stat
CHARACTER*(1000) :: VALUE
call wrf_debug
( DEBUG , 'Entering ext_gr2_get_dom_td_integer')
Status = WRF_NO_ERR
CALL gr2_get_metadata_value
(global_input(DataHandle), &
trim(DateStr)//';'//trim(Element), Value, stat)
if (stat /= 0) then
CALL wrf_debug
( DEBUG , "gr2_get_metadata_value failed for "//trim(DateStr)//';'//trim(Element))
Status = WRF_WARN_VAR_NF
RETURN
endif
READ(Value,*,IOSTAT=stat)(Data(idx),idx=1,Count)
if (stat .ne. 0) then
CALL wrf_message
("Reading data from"//Value//"failed")
Status = WRF_WARN_COUNT_TOO_LONG
RETURN
endif
Outcount = idx
RETURN
END SUBROUTINE ext_gr2_get_dom_td_integer
!*****************************************************************************
SUBROUTINE ext_gr2_get_dom_td_logical ( DataHandle,Element, DateStr, Data, &,5
Count, Outcount, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: DateStr
logical , INTENT(OUT) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: OutCount
INTEGER , INTENT(OUT) :: Status
INTEGER :: idx
INTEGER :: stat
CHARACTER*(1000) :: VALUE
call wrf_debug
( DEBUG , 'Entering ext_gr2_get_dom_td_logical')
Status = WRF_NO_ERR
CALL gr2_get_metadata_value
(global_input(DataHandle), &
trim(DateStr)//';'//trim(Element), Value, stat)
if (stat /= 0) then
CALL wrf_debug
( DEBUG , "gr2_get_metadata_value failed for "//trim(DateStr)//';'//trim(Element))
Status = WRF_WARN_VAR_NF
RETURN
endif
READ(Value,*,IOSTAT=stat)(Data(idx),idx=1,Count)
if (stat .ne. 0) then
CALL wrf_message
("Reading data from"//Value//"failed")
Status = WRF_WARN_COUNT_TOO_LONG
RETURN
endif
Outcount = idx
RETURN
END SUBROUTINE ext_gr2_get_dom_td_logical
!*****************************************************************************
SUBROUTINE ext_gr2_get_dom_td_char ( DataHandle,Element, DateStr, Data, &,4
Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: DateStr
CHARACTER*(*) :: Data
INTEGER , INTENT(OUT) :: Status
INTEGER :: stat
Status = WRF_NO_ERR
call wrf_debug
( DEBUG , 'Entering ext_gr2_get_dom_td_char')
CALL gr2_get_metadata_value
(global_input(DataHandle), &
trim(DateStr)//';'//trim(Element), Data, stat)
if (stat /= 0) then
CALL wrf_debug
( DEBUG , "gr2_get_metadata_value failed for "//trim(DateStr)//';'//trim(Element))
Status = WRF_WARN_VAR_NF
RETURN
endif
RETURN
END SUBROUTINE ext_gr2_get_dom_td_char
!*****************************************************************************
SUBROUTINE ext_gr2_get_dom_td_double ( DataHandle,Element, DateStr, Data, &,5
Count, Outcount, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) , INTENT(IN) :: Element
CHARACTER*(*) , INTENT(IN) :: DateStr
real*8 , INTENT(OUT) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: OutCount
INTEGER , INTENT(OUT) :: Status
INTEGER :: idx
INTEGER :: stat
CHARACTER*(1000) :: VALUE
call wrf_debug
( DEBUG , 'Entering ext_gr2_get_dom_td_double')
Status = WRF_NO_ERR
CALL gr2_get_metadata_value
(global_input(DataHandle), &
trim(DateStr)//';'//trim(Element), Value, stat)
if (stat /= 0) then
CALL wrf_debug
( DEBUG , "gr2_get_metadata_value failed for "//trim(DateStr)//';'//trim(Element))
Status = WRF_WARN_VAR_NF
RETURN
endif
READ(Value,*,IOSTAT=stat)(Data(idx),idx=1,Count)
if (stat .ne. 0) then
CALL wrf_message
("Reading data from"//Value//"failed")
Status = WRF_WARN_COUNT_TOO_LONG
RETURN
endif
Outcount = idx
RETURN
END SUBROUTINE ext_gr2_get_dom_td_double
!******************************************************************************
!* End of get_dom_td_* routines
!******************************************************************************
!******************************************************************************
!* Start of put_dom_td_* routines
!******************************************************************************
SUBROUTINE ext_gr2_put_dom_td_real8 ( DataHandle,Element, DateStr, Data, &,3
Count, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: DateStr
real*8 , INTENT(IN) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: Status
CHARACTER(len=1000) :: tmpstr(1000)
INTEGER :: idx
call wrf_debug
( DEBUG , 'Entering ext_gr2_put_dom_td_real8')
if (fileinfo(DataHandle)%committed) then
do idx = 1,Count
write(tmpstr(idx),'(G17.10)')Data(idx)
enddo
CALL gr2_build_string
(td_output(DataHandle), &
trim(DateStr)//';'//trim(Element), tmpstr, &
Count, Status)
endif
RETURN
END SUBROUTINE ext_gr2_put_dom_td_real8
!*****************************************************************************
SUBROUTINE ext_gr2_put_dom_td_integer ( DataHandle,Element, DateStr, Data, & 2,3
Count, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: DateStr
integer , INTENT(IN) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: Status
CHARACTER(len=1000) :: tmpstr(1000)
INTEGER :: idx
call wrf_debug
( DEBUG , 'Entering ext_gr2_put_dom_td_integer')
if (fileinfo(DataHandle)%committed) then
do idx = 1,Count
write(tmpstr(idx),'(G17.10)')Data(idx)
enddo
CALL gr2_build_string
(td_output(DataHandle), &
trim(DateStr)//';'//trim(Element), tmpstr, &
Count, Status)
endif
RETURN
END SUBROUTINE ext_gr2_put_dom_td_integer
!*****************************************************************************
SUBROUTINE ext_gr2_put_dom_td_logical ( DataHandle,Element, DateStr, Data, &,3
Count, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: DateStr
logical , INTENT(IN) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: Status
CHARACTER(len=1000) :: tmpstr(1000)
INTEGER :: idx
call wrf_debug
( DEBUG , 'Entering ext_gr2_put_dom_td_logical')
if (fileinfo(DataHandle)%committed) then
do idx = 1,Count
write(tmpstr(idx),'(G17.10)')Data(idx)
enddo
CALL gr2_build_string
(td_output(DataHandle), &
trim(DateStr)//';'//trim(Element), tmpstr, &
Count, Status)
endif
RETURN
END SUBROUTINE ext_gr2_put_dom_td_logical
!*****************************************************************************
SUBROUTINE ext_gr2_put_dom_td_char ( DataHandle,Element, DateStr, Data, &,3
Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: DateStr
CHARACTER(len=*), INTENT(IN) :: Data
INTEGER , INTENT(OUT) :: Status
CHARACTER(len=1000) :: tmpstr(1)
call wrf_debug
( DEBUG , 'Entering ext_gr2_put_dom_td_char')
if (fileinfo(DataHandle)%committed) then
write(tmpstr(1),*)Data
CALL gr2_build_string
(td_output(DataHandle), &
trim(DateStr)//';'//trim(Element), tmpstr, &
1, Status)
endif
RETURN
END SUBROUTINE ext_gr2_put_dom_td_char
!*****************************************************************************
SUBROUTINE ext_gr2_put_dom_td_double ( DataHandle,Element, DateStr, Data, &,3
Count, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) , INTENT(IN) :: Element
CHARACTER*(*) , INTENT(IN) :: DateStr
real*8 , INTENT(IN) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: Status
CHARACTER(len=1000) :: tmpstr(1000)
INTEGER :: idx
call wrf_debug
( DEBUG , 'Entering ext_gr2_put_dom_td_double')
if (fileinfo(DataHandle)%committed) then
do idx = 1,Count
write(tmpstr(idx),'(G17.10)')Data(idx)
enddo
CALL gr2_build_string
(td_output(DataHandle), &
trim(DateStr)//';'//trim(Element), tmpstr, &
Count, Status)
endif
RETURN
END SUBROUTINE ext_gr2_put_dom_td_double
!*****************************************************************************
SUBROUTINE ext_gr2_put_dom_td_real ( DataHandle,Element, DateStr, Data, & 2,3
Count, Status )
USE gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
INTEGER , INTENT(IN) :: DataHandle
CHARACTER*(*) :: Element
CHARACTER*(*) :: DateStr
real , INTENT(IN) :: Data(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: Status
CHARACTER(len=1000) :: tmpstr(1000)
INTEGER :: idx
call wrf_debug
( DEBUG , 'Entering ext_gr2_put_dom_td_real')
if (fileinfo(DataHandle)%committed) then
do idx = 1,Count
write(tmpstr(idx),'(G17.10)')Data(idx)
enddo
CALL gr2_build_string
(td_output(DataHandle), &
trim(DateStr)//';'//trim(Element), tmpstr, &
Count, Status)
endif
RETURN
END SUBROUTINE ext_gr2_put_dom_td_real
!******************************************************************************
!* End of put_dom_td_* routines
!******************************************************************************
SUBROUTINE gr2_get_new_handle(DataHandle) 2,1
USE gr2_data_info
IMPLICIT NONE
INTEGER , INTENT(OUT) :: DataHandle
INTEGER :: i
DataHandle = -1
do i=firstFileHandle, maxFileHandles
if (.NOT. fileinfo(i)%used) then
DataHandle = i
fileinfo(i)%used = .true.
exit
endif
enddo
RETURN
END SUBROUTINE gr2_get_new_handle
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!*****************************************************************************
SUBROUTINE gr2_retrieve_data (MemoryOrder, MemoryStart, MemoryEnd, xsize, ysize, & 2
zsize, z, FieldType, Field, data)
IMPLICIT NONE
#include "wrf_io_flags.h"
character*(*) ,intent(in) :: MemoryOrder
integer ,intent(in) :: xsize, ysize, zsize
integer ,intent(in) :: z
integer,dimension(*) ,intent(in) :: MemoryStart, MemoryEnd
integer ,intent(in) :: FieldType
real ,intent(in), &
dimension( 1:1,MemoryStart(1):MemoryEnd(1), &
MemoryStart(2):MemoryEnd(2), &
MemoryStart(3):MemoryEnd(3) ) :: Field
real ,dimension(1:xsize,1:ysize),intent(inout) :: data
integer :: x, y, idx
integer, dimension(:,:), pointer :: mold
integer :: istat
integer :: dim1
ALLOCATE(mold(1:xsize,1:ysize), STAT=istat)
if (istat .ne. 0) then
print *,'Could not allocate space for mold, returning'
return
endif
!
! Set the size of the first dimension of the data array (dim1) to xsize.
! If the MemoryOrder is Z or z, dim1 is overridden below.
!
dim1 = xsize
SELECT CASE (MemoryOrder)
CASE ('XYZ')
data = Field(1,1:xsize,1:ysize,z)
CASE ('C')
data = Field(1,1:xsize,1:ysize,z)
CASE ('XZY')
data = Field(1,1:xsize,z,1:ysize)
CASE ('YXZ')
do x = 1,xsize
do y = 1,ysize
data(x,y) = Field(1,y,x,z)
enddo
enddo
CASE ('YZX')
do x = 1,xsize
do y = 1,ysize
data(x,y) = Field(1,y,z,x)
enddo
enddo
CASE ('ZXY')
data = Field(1,z,1:xsize,1:ysize)
CASE ('ZYX')
do x = 1,xsize
do y = 1,ysize
data(x,y) = Field(1,z,y,x)
enddo
enddo
CASE ('XY')
data = Field(1,1:xsize,1:ysize,1)
CASE ('YX')
do x = 1,xsize
do y = 1,ysize
data(x,y) = Field(1,y,x,1)
enddo
enddo
CASE ('XSZ')
do x = 1,xsize
do y = 1,ysize
data(x,y) = Field(1,y,z,x)
enddo
enddo
CASE ('XEZ')
do x = 1,xsize
do y = 1,ysize
data(x,y) = Field(1,y,z,x)
enddo
enddo
CASE ('YSZ')
do x = 1,xsize
do y = 1,ysize
data(x,y) = Field(1,x,z,y)
enddo
enddo
CASE ('YEZ')
do x = 1,xsize
do y = 1,ysize
data(x,y) = Field(1,x,z,y)
enddo
enddo
CASE ('XS')
do x = 1,xsize
do y = 1,ysize
data(x,y) = Field(1,y,x,1)
enddo
enddo
CASE ('XE')
do x = 1,xsize
do y = 1,ysize
data(x,y) = Field(1,y,x,1)
enddo
enddo
CASE ('YS')
do x = 1,xsize
do y = 1,ysize
data(x,y) = Field(1,x,y,1)
enddo
enddo
CASE ('YE')
do x = 1,xsize
do y = 1,ysize
data(x,y) = Field(1,x,y,1)
enddo
enddo
CASE ('Z')
data(1:zsize,1) = Field(1,1:zsize,1,1)
dim1 = zsize
CASE ('z')
data(1:zsize,1) = Field(1,zsize:1,1,1)
dim1 = zsize
CASE ('0')
data(1,1) = Field(1,1,1,1)
END SELECT
!
! Here, we convert any integer fields to real
!
if (FieldType == WRF_INTEGER) then
mold = 0
do idx=1,dim1
!
! The parentheses around data(idx,:) are needed in order
! to fix a bug with transfer with the xlf compiler on NCARs
! IBM (bluesky).
!
data(idx,:)=transfer((data(idx,:)),mold)
enddo
endif
deallocate(mold)
return
end subroutine gr2_retrieve_data
!*****************************************************************************
SUBROUTINE gr2_get_levels(VarName, zidx, zsize, soil_layers, vert_stag, & 2,1
fraction, vert_unit1, vert_unit2, vert_sclFctr1, vert_sclFctr2, &
level1, level2)
use gr2_data_info
IMPLICIT NONE
integer :: zidx
integer :: zsize
logical :: soil_layers
logical :: vert_stag
logical :: fraction
integer :: vert_unit1, vert_unit2
integer :: vert_sclFctr1, vert_sclFctr2
integer :: level1
integer :: level2
character (LEN=*) :: VarName
! Setup vert_unit, and vertical levels in grib units
if ((VarName .eq. 'LANDUSEF') .or. (VarName .eq. 'SOILCTOP') &
.or. (VarName .eq. 'SOILCBOT')) then
vert_unit1 = 105;
vert_unit2 = 255;
vert_sclFctr1 = 0
vert_sclFctr2 = 0
level1 = zidx
level2 = 0
else if ((zsize .gt. 1) .and. (.not. soil_layers) .and. (.not. fraction)) &
then
vert_unit1 = 111;
vert_unit2 = 255;
vert_sclFctr1 = 4
vert_sclFctr2 = 4
if (vert_stag) then
level1 = (10000*full_eta(zidx)+0.5)
else
level1 = (10000*half_eta(zidx)+0.5)
endif
level2 = 0
else
! Set the vertical coordinate and level for soil and 2D fields
if (fraction) then
vert_unit1 = 105
vert_unit2 = 255
level1 = zidx
level2 = 0
vert_sclFctr1 = 0
vert_sclFctr2 = 0
else if (soil_layers) then
vert_unit1 = 106
vert_unit2 = 106
level1 = 100*(soil_depth(zidx) - 0.5*soil_thickness(zidx))+0.5
level2 = 100*(soil_depth(zidx) + 0.5*soil_thickness(zidx))+0.5
vert_sclFctr1 = 2
vert_sclFctr2 = 2
else if (VarName .eq. 'mu') then
vert_unit1 = 105
vert_unit2 = 255
level1 = 0
level2 = 0
vert_sclFctr1 = 0
vert_sclFctr2 = 0
else if ((VarName .eq. 'Q2') .or. (VarName .eq. 'TH2') .or. &
(VarName .eq. 'T2')) then
vert_unit1 = 103
vert_unit2 = 255
level1 = 2
level2 = 0
vert_sclFctr1 = 0
vert_sclFctr2 = 0
else if ((VarName .eq. 'Q10') .or. (VarName .eq. 'TH10') .or. &
(VarName .eq. 'U10') .or. (VarName .eq. 'V10')) then
vert_unit1 = 103
vert_unit2 = 255
level1 = 10
level2 = 0
vert_sclFctr1 = 0
vert_sclFctr2 = 0
else
vert_unit1 = 1
vert_unit2 = 255
level1 = 0
level2 = 0
vert_sclFctr1 = 0
vert_sclFctr2 = 0
endif
endif
end SUBROUTINE gr2_get_levels
!*****************************************************************************
subroutine gr2_create_w(StartDate, cgrib, lcgrib, production_status, Disc, & 2
center, subcenter, MasterTblV, LocalTblV, ierr, msg)
implicit none
character*24 ,intent(in) :: StartDate
character*(*),intent(inout) :: cgrib
integer ,intent(in) :: lcgrib
integer ,intent(in) :: production_status
integer ,intent(out) :: ierr
character*(*),intent(out) :: msg
integer , dimension(13) :: listsec1
integer , dimension(2) :: listsec0
integer :: slen
integer , intent(in) :: Disc, center, subcenter, MasterTblV, LocalTblV
!
! Create the grib message
!
listsec0(1) = Disc ! Discipline (Table 0.0)
listsec0(2) = 2 ! Grib edition number
listsec1(1) = center ! Id of Originating Center (255 for missing)
listsec1(2) = subcenter ! Id of originating sub-center (255 for missing)
listsec1(3) = MasterTblV ! Master Table Version #
listsec1(4) = LocalTblV ! Local table version #
listsec1(5) = 1 ! Significance of reference time, 1 indicates start of forecast
READ(StartDate(1:4), '(I4)') listsec1(6) ! Year of reference
READ(StartDate(6:7), '(I2)') listsec1(7) ! Month of reference
READ(StartDate(9:10), '(I2)') listsec1(8) ! Day of reference
slen = LEN(StartDate)
if (slen.GE.13) then
read(StartDate(12:13),'(I2)') listsec1(9)
else
listsec1(9) = 0
endif
if (slen.GE.16) then
read(StartDate(15:16),'(I2)') listsec1(10)
else
listsec1(10) = 0
endif
if (slen.GE.19) then
read(StartDate(18:19),'(I2)') listsec1(11)
else
listsec1(11) = 0
end if
listsec1(12) = production_status ! Production status of data
listsec1(13) = 1 ! Type of data (1 indicates forecast products)
call gribcreate(cgrib,lcgrib,listsec0,listsec1,ierr)
if (ierr .ne. 0) then
write(msg,*) 'gribcreate failed with ierr: ',ierr
else
msg = ''
endif
end SUBROUTINE gr2_create_w
!*****************************************************************************
subroutine gr2_addgrid_w(cgrib, lcgrib, central_lat, central_lon, wrf_projection, & 2,9
latin1, latin2, nx, ny, dx, dy, center_lat, center_lon, ierr,msg)
implicit none
character*(*) ,intent(inout) :: cgrib
integer ,intent(in) :: lcgrib
real ,intent(in) :: central_lat
real ,intent(in) :: central_lon
integer ,intent(in) :: wrf_projection
real ,intent(in) :: latin1
real ,intent(in) :: latin2
integer ,intent(in) :: nx
integer ,intent(in) :: ny
real ,intent(in) :: dx
real ,intent(in) :: dy
real ,intent(in) :: center_lat
real ,intent(in) :: center_lon
integer ,intent(out) :: ierr
character*(*) ,intent(out) :: msg
integer, dimension(5) :: igds
integer, parameter :: igdstmplen = 25
integer, dimension(igdstmplen) :: igdstmpl
integer, parameter :: idefnum = 0
integer, dimension(idefnum) :: ideflist
real :: LLLa, LLLo, URLa, URLo
real :: incrx, incry
real, parameter :: deg_to_microdeg = 1e6
real, parameter :: km_to_mm = 1e6
real, parameter :: km_to_m = 1e3
real, parameter :: DEG_TO_RAD = PI/180
real, parameter :: RAD_TO_DEG = 180/PI
real, parameter :: ERADIUS = 6370.0
igds(1) = 0 ! Source of grid definition
igds(2) = nx*ny ! Number of points in grid
igds(3) = 0 !
igds(4) = 0
! Here, setup the parameters that are common to all WRF projections
igdstmpl(1) = 1 ! Shape of earth (1 for spherical with specified radius)
igdstmpl(2) = 0 ! Scale factor for earth radius
igdstmpl(3) = ERADIUS*km_to_m ! Radius of earth
igdstmpl(4) = 0 ! Scale factor for major axis
igdstmpl(5) = 0 ! Major axis
igdstmpl(6) = 0 ! Scale factor for minor axis
igdstmpl(7) = 0 ! Minor axis
igdstmpl(8) = nx ! Number of points along x axis
igdstmpl(9) = ny ! Number of points along y axis
!
! Setup increments in "x" and "y" direction. For LATLON projection
! increments need to be in degrees. For all other projections,
! increments are in km.
!
if ((wrf_projection .eq. WRF_LATLON) &
.or. (wrf_projection .eq. WRF_CASSINI)) then
incrx = (dx/ERADIUS) * RAD_TO_DEG
incry = (dy/ERADIUS) * RAD_TO_DEG
else
incrx = dx
incry = dy
endif
! Latitude and longitude of first (i.e., lower left) grid point
call get_ll_latlon(central_lat, central_lon, wrf_projection, &
latin1, latin2, nx, ny, incrx, incry, center_lat, center_lon, &
LLLa, LLLo, URLa, URLo, ierr);
select case (wrf_projection)
case(WRF_LATLON,WRF_CASSINI)
igds(5) = 0
igdstmpl(10) = 0 ! Basic Angle of init projection (not important to us)
igdstmpl(11) = 0 ! Subdivision of basic angle
igdstmpl(12) = LLLa*deg_to_microdeg
igdstmpl(13) = LLLo*deg_to_microdeg
call gr2_convert_lon
(igdstmpl(13))
igdstmpl(14) = 128 ! Resolution and component flags
igdstmpl(15) = URLa*deg_to_microdeg
igdstmpl(16) = URLo*deg_to_microdeg
call gr2_convert_lon
(igdstmpl(16))
! Warning, the following assumes that dx and dy are valid at the equator.
! It is not clear in WRF where dx and dy are valid for latlon projections
igdstmpl(17) = incrx*deg_to_microdeg ! i-direction increment in micro degs
igdstmpl(18) = incry*deg_to_microdeg ! j-direction increment in micro degs
igdstmpl(19) = 64 ! Scanning mode
case(WRF_MERCATOR)
igds(5) = 10
igdstmpl(10) = LLLa*deg_to_microdeg
igdstmpl(11) = LLLo*deg_to_microdeg
call gr2_convert_lon
(igdstmpl(11))
igdstmpl(12) = 128 ! Resolution and component flags
igdstmpl(13) = latin1*deg_to_microdeg ! "True" latitude
igdstmpl(14) = URLa*deg_to_microdeg
igdstmpl(15) = URLo*deg_to_microdeg
call gr2_convert_lon
(igdstmpl(15))
igdstmpl(16) = 64 ! Scanning mode
igdstmpl(17) = 0 ! Orientation of grid between i-direction and equator
igdstmpl(18) = dx*km_to_mm ! i-direction increment
igdstmpl(19) = dy*km_to_mm ! j-direction increment
case(WRF_LAMBERT)
igds(5) = 30
igdstmpl(10) = LLLa*deg_to_microdeg
igdstmpl(11) = LLLo*deg_to_microdeg
call gr2_convert_lon
(igdstmpl(11))
igdstmpl(12) = 128 ! Resolution and component flag
igdstmpl(13) = latin1*deg_to_microdeg ! Latitude where Dx and Dy are specified
igdstmpl(14) = central_lon*deg_to_microdeg
call gr2_convert_lon
(igdstmpl(14))
igdstmpl(15) = dx*km_to_mm ! x-dimension grid-spacing in units of m^-3
igdstmpl(16) = dy*km_to_mm
if (center_lat .lt. 0) then
igdstmpl(17) = 1
else
igdstmpl(17) = 0
endif
igdstmpl(18) = 64 ! Scanning mode
igdstmpl(19) = latin1*deg_to_microdeg
igdstmpl(20) = latin2*deg_to_microdeg
igdstmpl(21) = -90*deg_to_microdeg
igdstmpl(22) = central_lon*deg_to_microdeg
call gr2_convert_lon
(igdstmpl(22))
case(WRF_POLAR_STEREO)
igds(5) = 20
igdstmpl(10) = LLLa*deg_to_microdeg
igdstmpl(11) = LLLo*deg_to_microdeg
call gr2_convert_lon
(igdstmpl(11))
igdstmpl(12) = 128 ! Resolution and component flag
igdstmpl(13) = latin1*deg_to_microdeg ! Latitude where Dx and Dy are specified
igdstmpl(14) = central_lon*deg_to_microdeg
call gr2_convert_lon
(igdstmpl(14))
igdstmpl(15) = dx*km_to_mm ! x-dimension grid-spacing in units of m^-3
igdstmpl(16) = dy*km_to_mm
if (center_lat .lt. 0) then
igdstmpl(17) = 1
else
igdstmpl(17) = 0
endif
igdstmpl(18) = 64 ! Scanning mode
case default
write(msg,*) 'invalid WRF projection: ',wrf_projection
ierr = -1
return
end select
call addgrid(cgrib,lcgrib,igds,igdstmpl,igdstmplen,ideflist,idefnum,ierr)
if (ierr .ne. 0) then
write(msg,*) 'addgrid failed with ierr: ',ierr
else
msg = ''
endif
end subroutine gr2_addgrid_w
!*****************************************************************************
subroutine gr2_addfield_w(cgrib, lcgrib, VarName, parmcat, parmnum, DecScl, & 2
BinScl, fcst_secs, vert_unit1, vert_unit2, vert_sclFctr1, vert_sclFctr2, &
numlevels, levels, ngrdpts, background_proc_id, forecast_proc_id, &
compression, fld, ierr, msg)
implicit none
character*(*) ,intent(inout) :: cgrib
integer ,intent(in) :: lcgrib
character (LEN=*) ,intent(in) :: VarName
integer ,intent(in) :: parmcat,parmnum,DecScl,BinScl
real ,intent(in) :: fcst_secs
integer ,intent(in) :: vert_unit1, vert_unit2
integer ,intent(in) :: vert_sclFctr1, vert_sclFctr2
integer ,intent(in) :: numlevels
integer, dimension(*) ,intent(in) :: levels
integer ,intent(in) :: ngrdpts
real ,intent(in) :: fld(ngrdpts)
integer ,intent(in) :: background_proc_id
integer ,intent(in) :: forecast_proc_id
integer ,intent(in) :: compression
integer ,intent(out) :: ierr
character*(*) ,intent(out) :: msg
integer :: ipdsnum
integer, parameter :: ipdstmplen = 15
integer, dimension(ipdstmplen) :: ipdstmpl
integer :: numcoord
integer, dimension(numlevels) :: coordlist
integer :: idrsnum
integer, parameter :: idrstmplen = 7
integer, dimension(idrstmplen) :: idrstmpl
integer :: ibmap
integer, dimension(1) :: bmap
if (numlevels .gt. 2) then
ipdsnum = 1000 ! Product definition tmplate (1000 for cross-sxn)
else
ipdsnum = 0 ! Product definition template (0 for horiz grid)
endif
ipdstmpl(1) = parmcat ! Parameter category
ipdstmpl(2) = parmnum ! Parameter number
ipdstmpl(3) = 2 ! Type of generating process (2 for forecast)
ipdstmpl(4) = background_proc_id ! Background generating process id
ipdstmpl(5) = forecast_proc_id ! Analysis or forecast generating process id
ipdstmpl(6) = 0 ! Data cutoff period (Hours)
ipdstmpl(7) = 0 ! Data cutoff period (minutes)
ipdstmpl(8) = 13 ! Time range indicator (13 for seconds)
ipdstmpl(9) = NINT(fcst_secs) ! Forecast time
if (ipdsnum .eq. 1000) then
numcoord = numlevels
coordlist = levels(1:numlevels)
!
! Set Data Representation templ (Use 0 for vertical cross sections,
! since there seems to be a bug in g2lib for JPEG2000 and PNG)
!
idrsnum = 0
else if (ipdsnum .eq. 0) then
ipdstmpl(10) = vert_unit1 ! Type of first surface (111 for Eta level)
ipdstmpl(11) = vert_sclFctr1 ! Scale factor for 1st surface
ipdstmpl(12) = levels(1) ! First fixed surface
ipdstmpl(13) = vert_unit2 ! Type of second fixed surface
ipdstmpl(14) = vert_sclFctr2 ! Scale factor for 2nd surface
if (numlevels .eq. 2) then
ipdstmpl(15) = levels(2)
else
ipdstmpl(15) = 0
endif
numcoord = 0
coordlist(1) = 0
! Set Data Representation templ (40 for JPEG2000, 41 for PNG)
idrsnum = compression
endif
if (idrsnum == 40) then ! JPEG 2000
idrstmpl(1) = 255 ! Reference value - ignored on input
idrstmpl(2) = BinScl ! Binary scale factor
idrstmpl(3) = DecScl ! Decimal scale factor
idrstmpl(4) = 0 ! number of bits for each data value - ignored on input
idrstmpl(5) = 0 ! Original field type - ignored on input
idrstmpl(6) = 0 ! 0 for lossless compression
idrstmpl(7) = 255 ! Desired compression ratio if idrstmpl(6) != 0
else if (idrsnum == 41) then ! PNG
idrstmpl(1) = 255 ! Reference value - ignored on input
idrstmpl(2) = BinScl ! Binary scale factor
idrstmpl(3) = DecScl ! Decimal scale factor
idrstmpl(4) = 0 ! number of bits for each data value - ignored on input
idrstmpl(5) = 0 ! Original field type - ignored on input
else if (idrsnum == 0) then! Simple packing
idrstmpl(1) = 255 ! Reference value - ignored on input
idrstmpl(2) = BinScl ! Binary scale factor
idrstmpl(3) = DecScl ! Decimal scale factor
idrstmpl(4) = 0 ! number of bits for each data value - ignored on input
idrstmpl(5) = 0 ! Original field type - ignored on input
else
write (msg,*) 'addfield failed because Data Representation template',&
idrsnum,' is invalid'
ierr = 1
return
endif
ibmap = 255 ! Flag for bitmap
call addfield(cgrib, lcgrib, ipdsnum, ipdstmpl, ipdstmplen, coordlist, &
numcoord, idrsnum, idrstmpl, idrstmplen, fld, ngrdpts, ibmap, &
bmap, ierr)
if (ierr .ne. 0) then
write(msg,*) 'addfield failed with ierr: ',ierr
else
msg = ''
endif
end subroutine gr2_addfield_w
!*****************************************************************************
subroutine gr2_fill_local_use(DataHandle,string,VarName,fcsts,msg,status) 3,12
use gr2_data_info
IMPLICIT NONE
#include "wrf_status_codes.h"
integer, intent(in) :: DataHandle
character*(*) ,intent(inout) :: string
character*(*) ,intent(in) :: VarName
integer :: center, subcenter, MasterTblV, LocalTblV, &
Disc, Category, ParmNum, DecScl, BinScl
integer ,intent(out) :: status
character*(*) ,intent(out) :: msg
integer , parameter :: lcgrib = 1000000
character (lcgrib) :: cgrib
real, dimension(1,1) :: data
integer :: lengrib
integer :: lcsec2
integer :: fcsts
integer :: bytes_written
!
! Set data to a default dummy value.
!
data = 1.0
!
! This statement prevents problems when calling addlocal in the grib2
! library. Basically, if addlocal is called with an empty string, it
! will be encoded correctly by the grib2 routine, but the grib2 routines
! that read the data (i.e., getgb2) will segfault. This prevents that
! segfault.
!
if (string .eq. '') string = 'none'
CALL get_parminfo
(VarName, center, subcenter, MasterTblV, &
LocalTblV, Disc, Category, ParmNum, DecScl, BinScl, status)
if (status .ne. 0) then
write(msg,*) 'Could not find parameter for '// &
trim(VarName)//' Skipping output of '//trim(VarName)
call wrf_message
(trim(msg))
Status = WRF_GRIB2_ERR_GRIB2MAP
return
endif
!
! Create the indicator and identification sections (sections 0 and 1)
!
CALL gr2_create_w
(StartDate, cgrib, lcgrib, production_status, Disc, &
center, subcenter, MasterTblV, LocalTblV, status, msg)
if (status .ne. 0) then
call wrf_message
(trim(msg))
Status = WRF_GRIB2_ERR_GRIBCREATE
return
endif
!
! Add the local use section
!
lcsec2 = len_trim(string)
call addlocal(cgrib,lcgrib,string,lcsec2,status)
if (status .ne. 0) then
call wrf_message
(trim(msg))
Status = WRF_GRIB2_ERR_ADDLOCAL
return
endif
!
! Add the grid definition section (section 3) using a 1x1 grid
!
call gr2_addgrid_w
(cgrib, lcgrib, center_lat, proj_central_lon, &
wrf_projection, truelat1, truelat2, 1, 1, dx, dy, &
center_lat, center_lon, status, msg)
if (status .ne. 0) then
call wrf_message
(trim(msg))
Status = WRF_GRIB2_ERR_ADDGRIB
return
endif
!
! Add the Product Definition, Data representation, bitmap
! and data sections (sections 4-7)
!
call gr2_addfield_w
(cgrib, lcgrib, VarName, Category, ParmNum, DecScl, &
BinScl, fcsts, 1, 255, 0, 0, 1, 0, 1, &
background_proc_id, forecast_proc_id, compression, data, status, msg)
if (status .ne. 0) then
call wrf_message
(trim(msg))
Status = WRF_GRIB2_ERR_ADDFIELD
return
endif
!
! Close out the message
!
call gribend(cgrib,lcgrib,lengrib,status)
if (status .ne. 0) then
write(msg,*) 'gribend failed with status: ',status
call wrf_message
(trim(msg))
Status = WRF_GRIB2_ERR_GRIBEND
return
endif
!
! Write the data to the file
!
call bawrite(DataHandle, -1, lengrib, bytes_written, cgrib)
!! call write_file_n(fileinfo(DataHandle)%FileFd, cgrib, lengrib, status)
if (bytes_written .ne. lengrib) then
write(msg,*) '2 Error writing cgrib to file, wrote: ', &
bytes_written, ' bytes. Tried to write ', lengrib, ' bytes'
call wrf_message
(trim(msg))
Status = WRF_GRIB2_ERR_WRITE
return
endif
! Set string back to the original blank value
if (string .eq. '') string = ''
return
end subroutine gr2_fill_local_use
!*****************************************************************************
!
! Set longitude to be in the range of 0-360 degrees.
!
!*****************************************************************************
subroutine gr2_convert_lon(value) 9
IMPLICIT NONE
integer, intent(inout) :: value
real, parameter :: deg_to_microdeg = 1e6
do while (value .lt. 0)
value = value + 360*deg_to_microdeg
enddo
do while (value .gt. 360*deg_to_microdeg)
value = value - 360*deg_to_microdeg
enddo
end subroutine gr2_convert_lon
!*****************************************************************************
!
! Add a time to the list of times
!
!*****************************************************************************
subroutine gr2_add_time(DataHandle,addTime) 1,3
USE gr2_data_info
IMPLICIT NONE
integer :: DataHandle
character (len=*) :: addTime
integer :: idx
logical :: already_have = .false.
logical :: swap
character (len=len(addTime)) :: tmp
character (DateStrLen), dimension(:),pointer :: tmpTimes(:)
integer,parameter :: allsize = 50
integer :: ierr
already_have = .false.
do idx = 1,fileinfo(DataHandle)%NumberTimes
if (addTime .eq. fileinfo(DataHandle)%Times(idx)) then
already_have = .true.
endif
enddo
if (.not. already_have) then
fileinfo(DataHandle)%NumberTimes = fileinfo(DataHandle)%NumberTimes + 1
if (fileinfo(DataHandle)%NumberTimes .gt. &
fileinfo(DataHandle)%sizeAllocated) then
if (fileinfo(DataHandle)%NumberTimes .eq. 1) then
if (allocated(fileinfo(DataHandle)%Times)) &
deallocate(fileinfo(DataHandle)%Times)
allocate(fileinfo(DataHandle)%Times(allsize), stat = ierr)
if (ierr .ne. 0) then
call wrf_message
('Could not allocate space for Times 1, exiting')
stop
endif
fileinfo(DataHandle)%sizeAllocated = allsize
else
allocate(tmpTimes(fileinfo(DataHandle)%NumberTimes), stat=ierr)
tmpTimes = &
fileinfo(DataHandle)%Times(1:fileinfo(DataHandle)%NumberTimes)
deallocate(fileinfo(DataHandle)%Times)
allocate(&
fileinfo(DataHandle)%Times(fileinfo(DataHandle)%sizeAllocated+allsize), stat=ierr)
if (ierr .ne. 0) then
call wrf_message
('Could not allocate space for Times 2, exiting')
stop
endif
fileinfo(DataHandle)%Times(1:fileinfo(DataHandle)%NumberTimes) = &
tmpTimes
deallocate(tmpTimes)
endif
endif
fileinfo(DataHandle)%Times(fileinfo(DataHandle)%NumberTimes) = addTime
! Sort the Times array
swap = .true.
do while (swap)
swap = .false.
do idx = 1,fileinfo(DataHandle)%NumberTimes - 1
if (fileinfo(DataHandle)%Times(idx) .gt. fileinfo(DataHandle)%Times(idx+1)) then
tmp = fileinfo(DataHandle)%Times(idx)
fileinfo(DataHandle)%Times(idx) = fileinfo(DataHandle)%Times(idx+1)
fileinfo(DataHandle)%Times(idx+1) = tmp
swap = .true.
endif
enddo
enddo
endif
return
end subroutine gr2_add_time
!*****************************************************************************
!
! Fill an array of levels
!
!*****************************************************************************
subroutine gr2_fill_levels(DataHandle,VarName,levels,ierr) 4,6
USE gr2_data_info
USE grib_mod
IMPLICIT NONE
#include "wrf_status_codes.h"
integer :: DataHandle
character (len=*) :: VarName
REAL,DIMENSION(*) :: levels
integer :: ierr
integer :: JIDS(JIDSSIZE), JPDTN, JPDT(JPDTSIZE), JGDTN, &
JGDT(JGDTSIZE)
type(gribfield) :: gfld
integer :: status, fields_to_skip
logical :: unpack
integer :: center, subcenter, MasterTblV, LocalTblV, &
Disc, Category, ParmNum, DecScl, BinScl
CHARACTER (LEN=maxMsgSize) :: msg
CALL get_parminfo
(VarName, center, subcenter, MasterTblV, &
LocalTblV, Disc, Category, ParmNum, DecScl, BinScl, status)
if (status .ne. 0) then
write(msg,*) 'Could not find parameter for '// &
trim(VarName)//' Skipping output of '//trim(VarName)
call wrf_message
(trim(msg))
ierr = -1
return
endif
!
! First, set all values to wild, then specify necessary values
!
call gr2_g2lib_wildcard
(JIDS, JPDT, JGDT)
JIDS(1) = center
JIDS(2) = subcenter
JIDS(3) = MasterTblV
JIDS(4) = LocalTblV
JIDS(5) = 1 ! Indicates that time is "Start of Forecast"
JIDS(13) = 1 ! Type of processed data (1 for forecast products)
JPDTN = 1000 ! Product definition template number
JPDT(1) = Category
JPDT(2) = ParmNum
JPDT(3) = 2 ! Generating process id
JGDTN = -1 ! Indicates that any Grid Display Template is a match
UNPACK = .TRUE. ! Unpack bitmap and data values
fields_to_skip = 0
CALL GETGB2(DataHandle, 0, fields_to_skip, -1, Disc, JIDS, JPDTN, &
JPDT, JGDTN, JGDT, UNPACK, fileinfo(DataHandle)%recnum, &
gfld, status)
if (status .eq. 99) then
write(msg,*)'Could not find field '//trim(VarName)//&
' continuing.'
call wrf_message
(trim(msg))
ierr = -1
return
else if (status .ne. 0) then
write(msg,*)'Retrieving scalar data field '//trim(VarName)//&
' failed, continuing.'
call wrf_message
(trim(msg))
ierr = -1
return
endif
levels(1:gfld%ndpts) = gfld%fld(1:gfld%ndpts)
ierr = 0
end subroutine gr2_fill_levels
!*****************************************************************************
!
! Set values for search array arguments for getgb2 to missing.
!
!*****************************************************************************
subroutine gr2_g2lib_wildcard(JIDS, JPDT, JGDT) 4,1
USE gr2_data_info
integer :: JIDS(*), JPDT(*), JGDT(*)
do idx = 1,JIDSSIZE
JIDS(idx) = -9999
enddo
do idx=1,JPDTSIZE
JPDT(idx) = -9999
enddo
do idx = 1,JGDTSIZE
JGDT(idx) = -9999
enddo
return
end subroutine gr2_g2lib_wildcard
!*****************************************************************************
!
! Retrieve a metadata value from the input string
!
!*****************************************************************************
subroutine gr2_get_metadata_value(instring, Key, Value, stat) 27
character(len=*),intent(in) :: instring
character(len=*),intent(in) :: Key
character(len=*),intent(out) :: Value
integer ,intent(out) :: stat
integer :: Key_pos, equals_pos, line_end
character :: lf
lf=char(10)
Value = 'abc'
!
! Find Starting position of Key
!
Key_pos = index(instring, lf//' '//Key//' =')
if (Key_pos .eq. 0) then
stat = -1
return
endif
!
! Find position of the "=" after the Key
!
equals_pos = index(instring(Key_pos:len(instring)), "=") + Key_pos
if (equals_pos .eq. Key_pos) then
stat = -1
return
endif
!
! Find end of line
!
line_end = index(instring(equals_pos:len(instring)), lf) + equals_pos
!
! Handle the case for the last line in the string
!
if (line_end .eq. equals_pos) then
line_end = len(trim(instring))
endif
!
! Set value
!
if ( (equals_pos + 1) .le. (line_end - 2) ) then
Value = trim(adjustl(instring(equals_pos+1:line_end-2)))
else
Value = ""
endif
stat = 0
end subroutine gr2_get_metadata_value
!*****************************************************************************
!
! Build onto a metadata string with the input value
!
!*****************************************************************************
SUBROUTINE gr2_build_string (string, Element, Value, Count, Status) 25
IMPLICIT NONE
#include "wrf_status_codes.h"
CHARACTER (LEN=*) , INTENT(INOUT) :: string
CHARACTER (LEN=*) , INTENT(IN) :: Element
CHARACTER (LEN=*) , INTENT(IN) :: Value(*)
INTEGER , INTENT(IN) :: Count
INTEGER , INTENT(OUT) :: Status
CHARACTER (LEN=2) :: lf
INTEGER :: IDX
lf=char(10)//' '
if (index(string,lf//Element//' =') .gt. 0) then
! We do nothing, since we dont want to add the same variable twice.
else
if (len_trim(string) == 0) then
string = lf//Element//' = '
else
string = trim(string)//lf//Element//' = '
endif
do idx = 1,Count
if (idx > 1) then
string = trim(string)//','
endif
string = trim(string)//' '//trim(adjustl(Value(idx)))
enddo
endif
Status = WRF_NO_ERR
END SUBROUTINE gr2_build_string