!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE GRIBENC ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE gribenc(itype,wdlen,grbpkbit,npts,fvar,ivar, & 3,5
ipds,igds,ibdshd,pds,gds, &
nbufsz,bds,ibds,msglen,mgrib, &
tem1,item1)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Make a GRIB message for variable fvar or ivar for given PDS and
! GDS.
!
!-----------------------------------------------------------------------
!
! AUTHOR: Yuhe Liu
! 11/05/1995
!
! MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
! INPUT:
!
! itype Data type: 0 for floating array and 1 for integer array
! npts Number of grid points
! fvar Floating array to be written into GRIB file
! ivar Integer array to be written into GRIB file
! ipds Integer array of PDS
! igds Integer array of GDS
! pds PDS (GRIB Section 1).
! gds GDS (GRIB Section 3).
!
! nbusz Buffer size of a GRIB message array
!
! OUTPUT:
!
! bds BDS except the first 11 octets header
! mgrib Buffer carrying the GRIB message
! msglen Length of the GRIB message
!
!-----------------------------------------------------------------------
!
! Variable Declarations.
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INTEGER :: itype ! Data type: 0 - floating, 1 - integer
INTEGER :: wdlen ! Length of machine word in bytes
INTEGER :: grbpkbit ! Bit length in packing GRIB data
INTEGER :: npts ! Number of grid points
REAL :: fvar(npts) ! Floating array
INTEGER :: ivar(npts) ! Integer array
INTEGER :: ipds(25)
INTEGER :: igds(25)
INTEGER :: ibdshd(4)
CHARACTER (LEN=1) :: pds(28) ! PDS
CHARACTER (LEN=1) :: gds(42) ! GDS
CHARACTER (LEN=1) :: bdshd(11) ! BDS header
INTEGER :: nbufsz ! Size of GRIB message array
INTEGER :: ibds(nbufsz/4) ! Identical to BDS
CHARACTER (LEN=1) :: bds(nbufsz) ! BDS
INTEGER :: msglen ! Length of GRIB message
CHARACTER (LEN=1) :: mgrib(nbufsz) ! GRIB message array
REAL :: tem1(npts) ! working array
INTEGER :: item1(npts) ! working array
!
!-----------------------------------------------------------------------
!
! Local GRIB parameters
!
!-----------------------------------------------------------------------
!
INTEGER :: gribid(4) ! GRIB indicator 'GRIB'
DATA gribid/ 71,82,73,66/ ! ASCII code for 'G', 'R', 'I', 'B'
INTEGER :: gribend(4)
DATA gribend/ 55,55,55,55/ ! ASCII code for '7', '7', '7', '7'
INTEGER :: bdslen
INTEGER :: pdslen
INTEGER :: gdslen
!
!-----------------------------------------------------------------------
!
! Misc. local variables:
!
!-----------------------------------------------------------------------
!
INTEGER :: i
INTEGER :: npos,npts1
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!
!-----------------------------------------------------------------------
!
! Making PDS - GRIB Section 1
!
!-----------------------------------------------------------------------
!
CALL mkpds
(ipds,pds)
!
!-----------------------------------------------------------------------
!
! Making GDS - GRIB Section 2
!
!-----------------------------------------------------------------------
!
CALL mkgds
(igds,gds,npts1)
IF ( npts /= npts1 ) THEN
WRITE (6,'(a/a,i8,a,i8/a)') &
'The point number was not correct', &
'npts = ',npts1, 'while nx*ny = ',npts, &
'Model stopped in GRIBENC'
CALL arpsstop
(' ',1)
END IF
pdslen = ICHAR(pds(1))*65536 + ICHAR(pds(2))*256 + ICHAR(pds(3))
gdslen = ICHAR(gds(1))*65536 + ICHAR(gds(2))*256 + ICHAR(gds(3))
!
!-----------------------------------------------------------------------
!
! Making BDS - GRIB Section 4
!
!-----------------------------------------------------------------------
!
CALL mkbds
(itype,wdlen,grbpkbit,npts,fvar,ivar, &
pds,ibdshd,bdshd, &
nbufsz,ibds,bdslen)
msglen = 8 + pdslen + gdslen + bdslen + 11 + 4 ! no bit map section
! write (6,'(a,i3,a,i3,a,i8,a,i8)')
! : ' pdslen = ', pdslen, ' gdslen = ', gdslen,
! : ' bdslen = ', bdslen+11, ' msglen = ', msglen
!
!-----------------------------------------------------------------------
!
! Output sections to the buffer.
!
! Move SECTION 0 (8 BYTES) into mgrib
!
!-----------------------------------------------------------------------
!
npos = 0
DO i = 1,4
mgrib(i) = CHAR(gribid(i))
END DO
mgrib(5) = CHAR(MOD(msglen/65536,256)) ! Total length of
mgrib(6) = CHAR(MOD(msglen/256, 256)) ! the GRIB message
mgrib(7) = CHAR(MOD(msglen, 256)) ! in three octets
mgrib(8) = CHAR(01) ! Edition 1
npos = npos + 8
!
!-----------------------------------------------------------------------
!
! Move SECTION 1 - 'PDS' into mgrib
!
!-----------------------------------------------------------------------
!
IF ( pdslen > 0) THEN
DO i=1,pdslen
mgrib(npos+i) = pds(i)
END DO
ELSE
WRITE (6,'(a)') 'PDS length <= 0, pdslen = ', pdslen
END IF
npos = npos + pdslen
!
!-----------------------------------------------------------------------
!
! Move SECTION 2 - 'GDS' into mgrib
!
!-----------------------------------------------------------------------
!
IF ( gdslen > 0) THEN
DO i=1,gdslen
mgrib(npos+i) = gds(i)
END DO
ELSE
WRITE (6,'(a)') 'GDS length <= 0, gdslen = ', gdslen
END IF
npos = npos + gdslen
!
!-----------------------------------------------------------------------
!
! No SECTION 3 (BMS) to move
!
!-----------------------------------------------------------------------
!
! IF ( bmslen.gt.0) THEN
! DO 230 i=1,bmslen
! mgrib(npos+i) = bms(i)
!230 CONTINUE
! END IF
!
! npos = npos + bmslen
!
!-----------------------------------------------------------------------
!
! Move SECTION 4 - 'BDS' into mgrib
!
!-----------------------------------------------------------------------
!
DO i=1,11
mgrib(npos+i) = bdshd(i)
END DO
npos = npos + 11
IF ( bdslen > 0) THEN
DO i=1,bdslen
mgrib(npos+i) = bds(i)
END DO
END IF
npos = npos + bdslen
!
!-----------------------------------------------------------------------
!
! End with SECTION 5 ('7777' where '7's ASCII code is 55)
!
!-----------------------------------------------------------------------
!
DO i=1,4
mgrib(npos+i) = CHAR(gribend(i))
END DO
npos = npos + 4
IF ( npos /= msglen ) THEN
WRITE (6,'(a/a,i8,a,i8/a)') &
'The GRIB message length was incorrect.', &
'npos = ',npos, ' msglen = ',msglen, &
'Program stopped in GRIBENC'
CALL arpsstop
(' ',1)
END IF
RETURN
END SUBROUTINE gribenc
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE MKPDS ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE mkpds(ipds,pds) 1
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Make PDS from ipds
!
!-----------------------------------------------------------------------
!
! AUTHOR: Yuhe Liu
! 11/05/1995
!
! MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
! INPUT:
!
! ipds Integer array of PDS
!
! OUTPUT:
!
! pds PDS (GRIB Section 1).
!
!-----------------------------------------------------------------------
!
! Variable Declarations.
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INTEGER :: ipds(25)
CHARACTER (LEN=1) :: pds(28) ! PDS
INTEGER :: k,levflg,level,dscl
!
!-----------------------------------------------------------------------
!
! Misc. local variables:
!
!-----------------------------------------------------------------------
!
INTEGER :: i
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
pds(1) = CHAR(MOD(ipds(1)/65536,256))
pds(2) = CHAR(MOD(ipds(1)/256,256))
pds(3) = CHAR(MOD(ipds(1),256))
pds(4) = CHAR(ipds(2))
pds(5) = CHAR(ipds(3))
pds(6) = CHAR(ipds(4))
pds(7) = CHAR(ipds(5))
pds(8) = CHAR(ior(ishft(ipds(6),7),ishft(ipds(7),6)))
pds(9) = CHAR(ipds(8))
pds(10) = CHAR(ipds(9))
levflg = ipds(9)
!
!-----------------------------------------------------------------------
!
! check if level is in two octets or one
!
!-----------------------------------------------------------------------
!
IF ( (levflg >= 1.AND.levflg <= 100).OR.levflg == 102.OR. &
levflg == 103.OR.levflg == 105.OR.levflg == 107.OR. &
levflg == 109.OR.levflg == 111.OR.levflg == 113.OR. &
levflg == 115.OR.levflg == 125.OR.levflg == 160.OR. &
levflg == 200.OR.levflg == 201 ) THEN
level = ipds(11) ! one level stored in pds(11) & pds(12)
IF ( level < 0 ) THEN
level = - level ! positive integer for the abs(level)
level = ior(level,32768) ! the first bit of 16 bits for sign
END IF
pds(11) = CHAR(MOD(level/256,256))
pds(12) = CHAR(MOD(level,256))
ELSE
pds(11) = CHAR(ipds(10)) ! level 1 stored in pds(11)
pds(12) = CHAR(ipds(11)) ! level 2 stored in pds(12)
END IF
pds(13) = CHAR(ipds(12))
pds(14) = CHAR(ipds(13))
pds(15) = CHAR(ipds(14))
pds(16) = CHAR(ipds(15))
pds(17) = CHAR(ipds(16))
pds(18) = CHAR(ipds(17))
!
!-----------------------------------------------------------------------
!
! Check if time P1 is in two octets or one
!
!-----------------------------------------------------------------------
!
IF (ipds(20) == 10) THEN
pds(19) = CHAR(MOD(ipds(18)/256,256))
pds(20) = CHAR(MOD(ipds(18),256))
ELSE
pds(19) = CHAR(ipds(18))
pds(20) = CHAR(ipds(19))
END IF
pds(21) = CHAR(ipds(20))
pds(22) = CHAR(MOD(ipds(21)/256,256))
pds(23) = CHAR(MOD(ipds(21),256))
pds(24) = CHAR(ipds(22))
pds(25) = CHAR(ipds(23))
pds(26) = CHAR(ipds(24))
dscl = ipds(25)
IF (dscl < 0) THEN
dscl = -dscl ! If D-scale less than 0,
dscl = ior(dscl,32768) ! set the highest bit of two bytes to 1
END IF
pds(27) = CHAR(MOD(dscl/256,256))
pds(28) = CHAR(MOD(dscl, 256))
!
!-----------------------------------------------------------------------
!
! Set the rest bytes of PDS to zero
!
!-----------------------------------------------------------------------
!
IF (ipds(1) > 28) THEN
k = ipds(1)
DO i = 29,k
pds(i) = CHAR(0)
END DO
ELSE IF ( ipds(1) < 28 ) THEN
WRITE (6,'(a,i3/a)') &
'The PDS length must be no less than 28 octets, ipds(1) = ', &
ipds(1), 'Program stopped in MKPDS'
END IF
RETURN
END SUBROUTINE mkpds
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE MKGDS ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE mkgds(igds,gds,npts) 1,1
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Make GDS from igds
!
!-----------------------------------------------------------------------
!
! AUTHOR: Yuhe Liu
! 11/05/1995
!
! MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
! INPUT:
!
! igds Integer array of GDS
!
! OUTPUT:
!
! gds GDS (GRIB Section 2)
! npts Number of grid points
!
!-----------------------------------------------------------------------
!
! Variable Declarations.
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INTEGER :: igds(25)
CHARACTER (LEN=1) :: gds(42) ! GDS
INTEGER :: npts
!
!-----------------------------------------------------------------------
!
! Local GRIB parameters
!
!-----------------------------------------------------------------------
!
INTEGER :: gdslen
INTEGER :: lat,lon
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
!
!-----------------------------------------------------------------------
!
! ARPS only support 3 types of projection
!
!-----------------------------------------------------------------------
!
IF ( igds(3) == 5 ) THEN
gdslen = 32
ELSE IF (igds(3) == 1 .OR. igds(3) == 3 ) THEN
gdslen = 42
ELSE ! grid type not valid
WRITE (6,'(a)') &
'ARPS does not support this type of projection grid: ', &
igds(3), 'Program stopped in MKGDS'
CALL arpsstop
(' ',1)
END IF
!
!-----------------------------------------------------------------------
!
! Number of grid points
!
!-----------------------------------------------------------------------
!
npts = igds(4)*igds(5) ! npts = nx * ny
!
!-----------------------------------------------------------------------
!
! Put GDS length in bytes 1,2,3
!
!-----------------------------------------------------------------------
!
gds(1) = CHAR(MOD(gdslen/65536,256))
gds(2) = CHAR(MOD(gdslen/ 256,256))
gds(3) = CHAR(MOD(gdslen ,256))
gds(4) = CHAR(igds(1)) ! nz use one byte
gds(5) = CHAR(igds(2)) ! = 255, N/A for PV & PL
gds(6) = CHAR(igds(3)) ! data representation
gds(17) = CHAR(igds(8)) ! resolution and u&v component flag
!
!-----------------------------------------------------------------------
!
! Mercator projection
!
!-----------------------------------------------------------------------
!
IF ( igds(3) == 1 ) THEN
gds(7) = CHAR(MOD(igds(4)/256,256)) ! nx uses two bytes
gds(8) = CHAR(MOD(igds(4), 256))
gds(9) = CHAR(MOD(igds(5)/256,256)) ! ny uses two bytes
gds(10) = CHAR(MOD(igds(5), 256))
lat = igds(6) ! swlat
IF ( lat < 0 ) THEN
lat = -lat
lat = ior(lat,8388608) ! minus sign put in the highest bit
END IF
gds(11) = CHAR(MOD(lat/65536,256))
gds(12) = CHAR(MOD(lat/256, 256))
gds(13) = CHAR(MOD(lat, 256))
lon = igds(7) ! swlon
IF ( lon < 0 ) THEN
lon = -lon
lon = ior(lon,8388608) ! minus sign put in the highest bit
END IF
gds(14) = CHAR(MOD(lon/65536,256))
gds(15) = CHAR(MOD(lon/256, 256))
gds(16) = CHAR(MOD(lon, 256))
lat = igds(9) ! latitude increment
IF ( lat < 0 ) THEN
lat = -lat
lat = ior(lat,8388608) ! minus sign put in the highest bit
END IF
gds(18) = CHAR(MOD(lat/65536,256))
gds(19) = CHAR(MOD(lat/ 256,256))
gds(20) = CHAR(MOD(lat ,256))
lon = igds(10) ! longitude increment
IF ( lon < 0 ) THEN
lon = -lon
lon = ior(lon,8388608) ! minus sign put in the highest bit
END IF
gds(21) = CHAR(MOD(lon/65536,256))
gds(22) = CHAR(MOD(lon/256, 256))
gds(23) = CHAR(MOD(lon, 256))
gds(24) = CHAR(MOD(igds(13)/65536,256)) ! true latitude
gds(25) = CHAR(MOD(igds(13)/256, 256))
gds(26) = CHAR(MOD(igds(13), 256))
gds(27) = CHAR(00)
gds(28) = CHAR(igds(14))
gds(29) = CHAR(MOD(igds(12)/65536,256))
gds(30) = CHAR(MOD(igds(12)/256, 256))
gds(31) = CHAR(MOD(igds(12), 256))
gds(32) = CHAR(MOD(igds(11)/65536,256))
gds(33) = CHAR(MOD(igds(11)/256, 256))
gds(34) = CHAR(MOD(igds(11), 256))
gds(35) = CHAR(00)
gds(36) = CHAR(00)
gds(37) = CHAR(00)
gds(38) = CHAR(00)
gds(39) = CHAR(00)
gds(40) = CHAR(00)
gds(41) = CHAR(00)
gds(42) = CHAR(00)
!
!-----------------------------------------------------------------------
!
! Lambert Conformal projection
!
!-----------------------------------------------------------------------
!
ELSE IF ( igds(3) == 3 ) THEN
gds( 7) = CHAR(MOD(igds(4)/256,256)) ! nx
gds( 8) = CHAR(MOD(igds(4), 256))
gds( 9) = CHAR(MOD(igds(5)/256,256)) ! ny
gds(10) = CHAR(MOD(igds(5), 256))
lat = igds(6)
IF ( lat < 0 ) THEN
lat = -lat
lat = ior(lat,8388608)
END IF
gds(11) = CHAR(MOD(lat/65536,256))
gds(12) = CHAR(MOD(lat/256, 256))
gds(13) = CHAR(MOD(lat, 256))
lon = igds(7)
IF ( lon < 0 ) THEN
lon = -lon
lon = ior(lon,8388608)
END IF
gds(14) = CHAR(MOD(lon/65536,256))
gds(15) = CHAR(MOD(lon/256, 256))
gds(16) = CHAR(MOD(lon, 256))
lon = igds(9)
IF ( lon < 0 ) THEN
lon = -lon
lon = ior(lon,8388608)
END IF
gds(18) = CHAR(MOD(lon/65536,256))
gds(19) = CHAR(MOD(lon/256, 256))
gds(20) = CHAR(MOD(lon, 256))
gds(21) = CHAR(MOD(igds(10)/65536,256))
gds(22) = CHAR(MOD(igds(10)/ 256,256))
gds(23) = CHAR(MOD(igds(10), 256))
gds(24) = CHAR(MOD(igds(11)/65536,256))
gds(25) = CHAR(MOD(igds(11)/256, 256))
gds(26) = CHAR(MOD(igds(11), 256))
gds(27) = CHAR(igds(12))
gds(28) = CHAR(igds(13))
gds(29) = CHAR(MOD(igds(15)/65536,256))
gds(30) = CHAR(MOD(igds(15)/256, 256))
gds(31) = CHAR(MOD(igds(15), 256))
gds(32) = CHAR(MOD(igds(16)/65536,256))
gds(33) = CHAR(MOD(igds(16)/256, 256))
gds(34) = CHAR(MOD(igds(16), 256))
lat = igds(17)
IF ( lat < 0 ) THEN
lat = -lat
lat = ior(lat,8388608)
END IF
gds(35) = CHAR(MOD(lat/65536,256))
gds(36) = CHAR(MOD(lat/256, 256))
gds(37) = CHAR(MOD(lat, 256))
lon = igds(18)
IF ( lon < 0 ) THEN
lon = -lon
lon = ior(lon,8388608)
END IF
gds(38) = CHAR(MOD(lon/65536,256))
gds(39) = CHAR(MOD(lon/256, 256))
gds(40) = CHAR(MOD(lon, 256))
gds(41) = CHAR(00)
gds(42) = CHAR(00)
!
!-----------------------------------------------------------------------
!
! Polar stereographic projection
!
!-----------------------------------------------------------------------
!
ELSE IF ( igds(3) == 5 ) THEN
gds( 7) = CHAR(MOD(igds(4)/256,256))
gds( 8) = CHAR(MOD(igds(4), 256))
gds( 9) = CHAR(MOD(igds(5)/256,256))
gds(10) = CHAR(MOD(igds(5), 256))
lat = igds(6)
IF ( lat < 0 ) THEN
lat = -lat
lat = ior(lat,8388608)
END IF
gds(11) = CHAR(MOD(lat/65536,256))
gds(12) = CHAR(MOD(lat/256, 256))
gds(13) = CHAR(MOD(lat, 256))
lon = igds(7)
IF ( lon < 0 ) THEN
lon = -lon
lon = ior(lon,8388608)
END IF
gds(14) = CHAR(MOD(lon/65536,256))
gds(15) = CHAR(MOD(lon/256, 256))
gds(16) = CHAR(MOD(lon, 256))
lon = igds(9)
IF ( lon < 0 ) THEN
lon = -lon
lon = ior(lon,8388608)
END IF
gds(18) = CHAR(MOD(lon/65536,256))
gds(19) = CHAR(MOD(lon/256, 256))
gds(20) = CHAR(MOD(lon, 256))
gds(21) = CHAR(MOD(igds(10)/65536,256))
gds(22) = CHAR(MOD(igds(10)/256, 256))
gds(23) = CHAR(MOD(igds(10), 256))
gds(24) = CHAR(MOD(igds(11)/65536,256))
gds(25) = CHAR(MOD(igds(11)/256, 256))
gds(26) = CHAR(MOD(igds(11), 256))
gds(27) = CHAR(igds(12))
gds(28) = CHAR(igds(13))
gds(29) = CHAR(00)
gds(30) = CHAR(00)
gds(31) = CHAR(00)
gds(32) = CHAR(00)
END IF
RETURN
END SUBROUTINE mkgds
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE MKBDS ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE mkbds(itype,wdlen,grbpkbit,npts,fvar,ivar, & 1,3
pds,ibdshd,bdshd, &
nbufsz,ibds,bdslen)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Pack the data and make the GRIB BDS Section.
!
!-----------------------------------------------------------------------
!
! AUTHOR: Yuhe Liu
! 11/05/1995
!
! MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
! INPUT:
!
! itype Data type: 0 for floating array and 1 for integer array
! wdlen Length of a computer word in bits
! grbpkbit DATA packing length in bits
!
! npts Number of grid points
! fvar Floating array to be written into GRIB file
! ivar Integer array to be written into GRIB file
!
! ibdshd Integer array for BDS header
!
! pds PDS (GRIB Section 1).
!
! nbfusz Buffer size of a GRIB message array
!
! OUTPUT:
!
! ibds Identical to BDS
! bdshd BDS first 11 octets header
! bdslen Length of bds
!
! TEMPORARY:
!
!
!-----------------------------------------------------------------------
!
! Variable Declarations.
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INTEGER :: itype ! Data type: 0 - floating, 1 - integer
INTEGER :: grbpkbit ! DATA packing length in bits
INTEGER :: wdlen ! Length of a computer word in bits
INTEGER :: npts ! Array size
REAL :: fvar(npts) ! Floating array
INTEGER :: ivar(npts) ! Integer array
CHARACTER (LEN=1) :: pds(28) ! PDS
INTEGER :: ibdshd(4) ! Integer array for BDS header
CHARACTER (LEN=1) :: bdshd(11) ! BDS header
INTEGER :: nbufsz ! Size of GRIB message array
INTEGER :: ibds(nbufsz/wdlen) ! Identical to BDS
INTEGER :: bdslen ! Length of BDS
!
!-----------------------------------------------------------------------
!
! Local GRIB parameters
!
!-----------------------------------------------------------------------
!
INTEGER :: dscl, bscl
REAL :: scale, fmax,fmin
!
!-----------------------------------------------------------------------
!
! Misc. local variables:
!
!-----------------------------------------------------------------------
!
INTEGER :: bwidth, nbits, iskip1, iskip2
INTEGER :: i, j
REAL :: tema
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
iskip1 = 0
iskip2 = 0
ibdshd(3) = itype ! set the floating or integer data flag
!
!-----------------------------------------------------------------------
!
! Perform decimal scale to either floating or integet data array
!
!-----------------------------------------------------------------------
!
dscl = ICHAR(pds(27))*256 + ICHAR(pds(28))
IF ( IAND(dscl,32768) /= 0 ) THEN
dscl = - IAND(dscl,32761)
END IF
scale = 10.0**dscl
IF ( itype == 0 ) THEN
DO i = 1,npts
fvar(i) = fvar(i)*scale
END DO
ELSE IF ( itype == 1 ) THEN
DO i = 1,npts
fvar(i) = FLOAT(ivar(i))*scale
END DO
END IF
!
!-----------------------------------------------------------------------
!
! Find the minimum and maximum value of the array and subtract the
! minimum
!
!-----------------------------------------------------------------------
!
CALL a3dmax0
(fvar,1,npts,1,npts,1,1,1,1,1,1,1,1, fmax,fmin)
!wdt 2001/05/24 Eliminate constant field hack. RLC
!!tmp arpscntl - try having no contsant fields to fix ncl:
! IF (fmax.eq.fmin) THEN
! fmax = fmin + 1.0e-10
! fvar(1) = fmax
! ENDIF
DO i=1,npts
fvar(i) = fvar(i) - fmin
END DO
IF ( (fmax-fmin) == 0.0 ) THEN
bwidth = 0
bscl = 0
scale = 1.0
ELSE IF ( itype /= 0 ) THEN
bwidth = 8
bscl = 0
scale = 1.0
ELSE
bwidth = grbpkbit ! use the value specified by user
tema = (fmax-fmin)/(2.**(bwidth+1)-1.)
IF ( tema /= 0.0 ) THEN
tema = LOG(tema)/LOG(2.0) + 2
END IF
bscl = MIN( INT(tema), INT(tema+SIGN(1.0,tema)) )
scale = 2.0**bscl
END IF
!
!-----------------------------------------------------------------------
!
! Do binary scale to the data
!
!-----------------------------------------------------------------------
!
DO i=1,npts
ivar(i) = nint( fvar(i)/scale )
END DO
!
!-----------------------------------------------------------------------
!
! Calculate the length of BDS which must be an even number of bytes
!
!-----------------------------------------------------------------------
!
nbits = npts*bwidth + 11*8
j = MOD( nbits, 16 )
IF ( j /= 0 ) THEN
nbits = nbits + 16 -j
END IF
bdslen = nbits/8
!
!-----------------------------------------------------------------------
!
! Make the header of BDS
!
!-----------------------------------------------------------------------
!
bdshd(1) = CHAR(MOD(bdslen/65536,256))
bdshd(2) = CHAR(MOD(bdslen/256, 256))
bdshd(3) = CHAR(MOD(bdslen, 256))
bdshd(4) = CHAR( ibdshd(1)*128 + ibdshd(2)*64 &
+ ibdshd(3)*32 + ibdshd(4)*16 )
IF ( bscl < 0 ) THEN
bscl = 32768 - bscl
END IF
bdshd(5) = CHAR(MOD(bscl/256,256))
bdshd(6) = CHAR(MOD(bscl, 256))
!
!-----------------------------------------------------------------------
!
! Convert the reference floating value to IBM GRIB representation
!
!-----------------------------------------------------------------------
!
CALL flt2ibm
( fmin, bdshd(7), wdlen*8 )
! write (6,'(a,i6,a,e16.10,a,i3,a,i4,a,i8,a,i8)')
! :' E = ',bscl, ' R = ',fmin, ' L = ',bwidth,
! :' A = ',iexp, ' B = ',imant, ' M = ',nint((fmax-fmin)/scale)
bdshd(11) = CHAR(MOD(bwidth,256))
IF ( bwidth /= 0 ) THEN
CALL grbsbytes
( ibds,ivar,iskip1,bwidth,iskip2,npts )
ELSE
ibds(1) = 0
END IF
bdslen = bdslen - 11
RETURN
END SUBROUTINE mkbds
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE FLT2IBM ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE flt2ibm(rfloat,chribm,kbits) 18
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Convert floating point number from machine
! representation to GRIB representation.
!
!
!-----------------------------------------------------------------------
!
! AUTHOR: John Hennessy, ECMWF
! 06/18/1991
!
! MODIFICATIONS:
!
! 11/14/1995 (Yuhe Liu)
! Changed name, converted to ARPS standard format, and added some
! document
!
!-----------------------------------------------------------------------
!
! INPUT:
!
! rfloat Floating point number to be converted.
!
! kbits Number of bits in computer word.
!
! OUTPUT:
!
! chribm 32 bits IBM floating format in 4-byte character string
!
!-----------------------------------------------------------------------
!
! METHOD:
!
! Floating point number represented as 8 bit signed
! exponent and 24 bit mantissa in integer values.
!
! REFERENCE:
!
! WMO Manual on Codes re GRIB representation.
!
! Common block variables.
!
!-----------------------------------------------------------------------
!
! Variable Declarations.
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
REAL :: rfloat
CHARACTER (LEN=1) :: chribm(4)
INTEGER :: kbits
INTEGER :: iexp
INTEGER :: ISIGN
INTEGER :: kexp
INTEGER :: kmant
REAL :: zeps
REAL :: zref
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
IF ( kbits == 32 ) THEN
zeps = 1.0E-8
ELSE
zeps = 1.0E-12
END IF
zref = rfloat
!
!-----------------------------------------------------------------------
!
! Sign of value.
!
!-----------------------------------------------------------------------
!
ISIGN = 0
IF (zref < 0.) THEN
ISIGN = 128
zref = - zref
END IF
IF ( zref < 1.0E-20 ) zref = 0.0
!
!-----------------------------------------------------------------------
!
! Convert value of 0.0.
!
!-----------------------------------------------------------------------
!
IF (zref == 0.0) THEN
kexp = 0
kmant = 0
iexp = 0
ELSE
!
!-----------------------------------------------------------------------
!
! Convert other values.
!
! Exponent first
!
!-----------------------------------------------------------------------
!
iexp = INT(ALOG(zref)*(1.0/ALOG(16.0))+64.0+1.0+zeps)
IF ( iexp < 0 ) iexp = 0
IF ( iexp > 127 ) iexp = 127
!
!-----------------------------------------------------------------------
!
! Mantissa.
!
!-----------------------------------------------------------------------
!
kmant = nint (zref/16.0**(iexp-70))
!
!-----------------------------------------------------------------------
!
! Check that mantissa value does not exceed 24 bits.
! 16777215 = 2**24 - 1
!
!-----------------------------------------------------------------------
!
IF (kmant > 16777215) THEN
iexp = iexp + 1
kmant = nint (zref/16.0**(iexp-70))
!
!-----------------------------------------------------------------------
!
! Check for mantissa overflow. If so, set mantissa to zero
!
!-----------------------------------------------------------------------
!
IF (kmant > 16777215) THEN
WRITE (6,'(a,e20.12)') 'Bad mantissa value: overflow', &
rfloat
WRITE (6,'(a,i2,a,i10,a,i10)') &
'isign = ', ISIGN, ' iexp = ', iexp, ' kmant = ', kmant
kmant = 0
END IF
END IF
!
!-----------------------------------------------------------------------
!
! Add sign bit to exponent.
!
!-----------------------------------------------------------------------
!
END IF
kexp = iexp + ISIGN
chribm(1) = CHAR(MOD(kexp,256))
chribm(2) = CHAR(MOD(kmant/65536,256))
chribm(3) = CHAR(MOD(kmant/256, 256))
chribm(4) = CHAR(MOD(kmant, 256))
RETURN
END SUBROUTINE flt2ibm
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE WRTHISHD ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE wrthishd(nx,ny,nz,nchanl,grdbas, fmtver, x,y,z, & 1,17
wdlen,nbufsz,mgrib,nbytes)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Write the header of ARPS history dump by using GRIB representation
! to floating point numbers.
!
!
!-----------------------------------------------------------------------
!
! AUTHOR: Yuhe Liu
! 11/27/1995
!
! MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
!
! INPUT:
!
! nx Number of grid points in the x-direction (east/west)
! ny Number of grid points in the y-direction (north/south)
! nz Number of grid points in the vertical
!
! nchanl I/O unit of history dump file
!
! grdbas Flag for grid and base state dump
!
! x x coordinate of grid points in physical/comp. space (m)
! y y coordinate of grid points in physical/comp. space (m)
! z z coordinate of grid points in computational space (m)
!
! fmtver Format and version identical
!
! wdlen Length in bytes of a machine word
! nbufsz Buffer size of GRIB message
!
! OUTPUT:
!
! mgrib String containing the header of ARPS history dump
! nbytes Length in bytes of the header
!
! WORK ARRAY:
!
!-----------------------------------------------------------------------
!
! The following parameters are passed into this subroutine through
! a common block in globcst.inc, and they determine which
! variables are output.
!
! grdout =0 or 1. If grdout=0, grid variables are not dumped.
! basout =0 or 1. If basout=0, base state variables are not dumped.
! varout =0 or 1. If varout=0, model perturbation variables are not dumped.
! mstout =0 or 1. If mstout=0, water variables are not dumped.
! iceout =0 or 1. If iceout=0, qi, qs and qh are not dumped.
! rainout=0 or 1. If rainout=0, rain variables are not dumped.
! prcout =0 or 1. If prcout=0, precipitation rates are not dumped.
! tkeout =0 or 1. If tkeout=0, tke is not dumped.
! trbout =0 or 1. If trbout=0, turbulence parameter km is not dumped.
! sfcout =0 or 1. If sfcout=0, surface variables are not dumped.
! landout=0 or 1. If landout=0, surface propertty arrays are not dumped.
! radout =0 or 1. If radout=0, radiation arrays are not dumped
! flxout =0 or 1. If flxout=0, surface fluxes are not dumped.
!
! These following parameters are also passed in through common
! blocks in globcst.inc.
!
! runname,curtim,umove,vmove,xgrdorg,ygrdorg
!
!-----------------------------------------------------------------------
!
! Variable Declarations.
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INTEGER :: nx,ny,nz ! Number of grid points in 3 directions
INTEGER :: nchanl ! I/O unit
INTEGER :: grdbas ! Flag for grid and base state dump
REAL :: x (nx) ! The x-coord. of the physical and
! computational grid. Defined at u-point.
REAL :: y (ny) ! The y-coord. of the physical and
! computational grid. Defined at v-point.
REAL :: z (nz) ! The z-coord. of the computational grid.
! Defined at w-point on the staggered grid.
CHARACTER (LEN=40) :: fmtver
INTEGER :: wdlen ! Length in bytes of machine word
INTEGER :: nbufsz
INTEGER :: nbytes ! Length in bytes of the header
CHARACTER (LEN=1) :: mgrib(nbufsz) ! Header of ARPS GRIB file
!
!-----------------------------------------------------------------------
!
! Misc. local variables:
!
!-----------------------------------------------------------------------
!
INTEGER :: i,j,k
INTEGER :: idummy
INTEGER :: r0exp,r0mant
CHARACTER (LEN=1) :: chrtmp(4)
!
!-----------------------------------------------------------------------
!
! Include files:
!
!-----------------------------------------------------------------------
!
INCLUDE 'globcst.inc'
INCLUDE 'grid.inc' ! Grid & map parameters.
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
idummy = 0
r0exp = 0 ! for rdummy = 0.0
r0mant = 0 ! for rdummy = 0.0
nbytes = 3
DO i=1,40
mgrib(nbytes+i) = fmtver(i:i)
END DO
nbytes = nbytes + 40
DO i=1,80
mgrib(nbytes+i) = runname(i:i)
END DO
nbytes = nbytes + 80
mgrib(nbytes+1) = CHAR(nocmnt)
nbytes = nbytes + 1
IF( nocmnt > 0 ) THEN
DO j=1,nocmnt
DO i=1,80
mgrib(nbytes+i) = cmnt(j)(i:i)
END DO
nbytes = nbytes + 80
END DO
END IF
CALL flt2ibm
(curtim,chrtmp,wdlen*8)
mgrib(nbytes+1) = chrtmp(1)
mgrib(nbytes+2) = chrtmp(2)
mgrib(nbytes+3) = chrtmp(3)
mgrib(nbytes+4) = chrtmp(4)
nbytes = nbytes + 4
mgrib(nbytes+1) = CHAR(MOD(nx/256,256))
mgrib(nbytes+2) = CHAR(MOD(nx, 256))
nbytes = nbytes + 2
mgrib(nbytes+1) = CHAR(MOD(ny/256,256))
mgrib(nbytes+2) = CHAR(MOD(ny, 256))
nbytes = nbytes + 2
mgrib(nbytes+1) = CHAR(MOD(nz/256,256))
mgrib(nbytes+2) = CHAR(MOD(nz, 256))
nbytes = nbytes + 2
IF( grdbas == 1 ) THEN
mgrib(nbytes+1) = CHAR(1)
mgrib(nbytes+2) = CHAR(1)
mgrib(nbytes+3) = CHAR(0)
mgrib(nbytes+4) = CHAR(mstout)
mgrib(nbytes+5) = CHAR(0)
mgrib(nbytes+6) = CHAR(0)
mgrib(nbytes+7) = CHAR(0)
mgrib(nbytes+8) = CHAR(0)
mgrib(nbytes+9) = CHAR(landout)
mgrib(nbytes+10) = CHAR(totout)
mgrib(nbytes+11) = CHAR(0)
mgrib(nbytes+12) = CHAR(idummy)
mgrib(nbytes+13) = CHAR(idummy)
mgrib(nbytes+14) = CHAR(mapproj)
mgrib(nbytes+15) = CHAR(month)
mgrib(nbytes+16) = CHAR(day)
mgrib(nbytes+17) = CHAR(MOD(year/256,256))
mgrib(nbytes+18) = CHAR(MOD(year, 256))
mgrib(nbytes+19) = CHAR(hour)
mgrib(nbytes+20) = CHAR(minute)
mgrib(nbytes+21) = CHAR(second)
nbytes = nbytes + 21
ELSE
mgrib(nbytes+1) = CHAR(grdout)
mgrib(nbytes+2) = CHAR(basout)
mgrib(nbytes+3) = CHAR(varout)
mgrib(nbytes+4) = CHAR(mstout)
mgrib(nbytes+5) = CHAR(iceout)
mgrib(nbytes+6) = CHAR(trbout)
mgrib(nbytes+7) = CHAR(sfcout)
mgrib(nbytes+8) = CHAR(rainout)
mgrib(nbytes+9) = CHAR(landout)
mgrib(nbytes+10) = CHAR(totout)
mgrib(nbytes+11) = CHAR(tkeout)
mgrib(nbytes+12) = CHAR(idummy)
mgrib(nbytes+13) = CHAR(idummy)
mgrib(nbytes+14) = CHAR(mapproj)
mgrib(nbytes+15) = CHAR(month)
mgrib(nbytes+16) = CHAR(day)
mgrib(nbytes+17) = CHAR(MOD(year/256,256))
mgrib(nbytes+18) = CHAR(MOD(year, 256))
mgrib(nbytes+19) = CHAR(hour)
mgrib(nbytes+20) = CHAR(minute)
mgrib(nbytes+21) = CHAR(second)
nbytes = nbytes + 21
END IF
CALL flt2ibm
(umove,chrtmp,wdlen*8)
mgrib(nbytes+1) = chrtmp(1)
mgrib(nbytes+2) = chrtmp(2)
mgrib(nbytes+3) = chrtmp(3)
mgrib(nbytes+4) = chrtmp(4)
nbytes = nbytes + 4
CALL flt2ibm
(vmove,chrtmp,wdlen*8)
mgrib(nbytes+1) = chrtmp(1)
mgrib(nbytes+2) = chrtmp(2)
mgrib(nbytes+3) = chrtmp(3)
mgrib(nbytes+4) = chrtmp(4)
nbytes = nbytes + 4
CALL flt2ibm
(xgrdorg,chrtmp,wdlen*8)
mgrib(nbytes+1) = chrtmp(1)
mgrib(nbytes+2) = chrtmp(2)
mgrib(nbytes+3) = chrtmp(3)
mgrib(nbytes+4) = chrtmp(4)
nbytes = nbytes + 4
CALL flt2ibm
(ygrdorg,chrtmp,wdlen*8)
mgrib(nbytes+1) = chrtmp(1)
mgrib(nbytes+2) = chrtmp(2)
mgrib(nbytes+3) = chrtmp(3)
mgrib(nbytes+4) = chrtmp(4)
nbytes = nbytes + 4
CALL flt2ibm
(trulat1,chrtmp,wdlen*8)
mgrib(nbytes+1) = chrtmp(1)
mgrib(nbytes+2) = chrtmp(2)
mgrib(nbytes+3) = chrtmp(3)
mgrib(nbytes+4) = chrtmp(4)
nbytes = nbytes + 4
CALL flt2ibm
(trulat2,chrtmp,wdlen*8)
mgrib(nbytes+1) = chrtmp(1)
mgrib(nbytes+2) = chrtmp(2)
mgrib(nbytes+3) = chrtmp(3)
mgrib(nbytes+4) = chrtmp(4)
nbytes = nbytes + 4
CALL flt2ibm
(trulon,chrtmp,wdlen*8)
mgrib(nbytes+1) = chrtmp(1)
mgrib(nbytes+2) = chrtmp(2)
mgrib(nbytes+3) = chrtmp(3)
mgrib(nbytes+4) = chrtmp(4)
nbytes = nbytes + 4
CALL flt2ibm
(sclfct,chrtmp,wdlen*8)
mgrib(nbytes+1) = chrtmp(1)
mgrib(nbytes+2) = chrtmp(2)
mgrib(nbytes+3) = chrtmp(3)
mgrib(nbytes+4) = chrtmp(4)
nbytes = nbytes + 4
mgrib(nbytes+1) = CHAR(r0exp)
mgrib(nbytes+2) = CHAR(r0mant)
mgrib(nbytes+3) = CHAR(r0mant)
mgrib(nbytes+4) = CHAR(r0mant)
nbytes = nbytes + 4
mgrib(nbytes+1) = CHAR(r0exp)
mgrib(nbytes+2) = CHAR(r0mant)
mgrib(nbytes+3) = CHAR(r0mant)
mgrib(nbytes+4) = CHAR(r0mant)
nbytes = nbytes + 4
mgrib(nbytes+1) = CHAR(r0exp)
mgrib(nbytes+2) = CHAR(r0mant)
mgrib(nbytes+3) = CHAR(r0mant)
mgrib(nbytes+4) = CHAR(r0mant)
nbytes = nbytes + 4
mgrib(nbytes+1) = CHAR(r0exp)
mgrib(nbytes+2) = CHAR(r0mant)
mgrib(nbytes+3) = CHAR(r0mant)
mgrib(nbytes+4) = CHAR(r0mant)
nbytes = nbytes + 4
mgrib(nbytes+1) = CHAR(r0exp)
mgrib(nbytes+2) = CHAR(r0mant)
mgrib(nbytes+3) = CHAR(r0mant)
mgrib(nbytes+4) = CHAR(r0mant)
nbytes = nbytes + 4
mgrib(nbytes+1) = CHAR(r0exp)
mgrib(nbytes+2) = CHAR(r0mant)
mgrib(nbytes+3) = CHAR(r0mant)
mgrib(nbytes+4) = CHAR(r0mant)
nbytes = nbytes + 4
mgrib(nbytes+1) = CHAR(r0exp)
mgrib(nbytes+2) = CHAR(r0mant)
mgrib(nbytes+3) = CHAR(r0mant)
mgrib(nbytes+4) = CHAR(r0mant)
nbytes = nbytes + 4
CALL flt2ibm
(tstop,chrtmp,wdlen*8)
mgrib(nbytes+1) = chrtmp(1)
mgrib(nbytes+2) = chrtmp(2)
mgrib(nbytes+3) = chrtmp(3)
mgrib(nbytes+4) = chrtmp(4)
nbytes = nbytes + 4
CALL flt2ibm
(thisdmp,chrtmp,wdlen*8)
mgrib(nbytes+1) = chrtmp(1)
mgrib(nbytes+2) = chrtmp(2)
mgrib(nbytes+3) = chrtmp(3)
mgrib(nbytes+4) = chrtmp(4)
nbytes = nbytes + 4
CALL flt2ibm
(latitud,chrtmp,wdlen*8)
mgrib(nbytes+1) = chrtmp(1)
mgrib(nbytes+2) = chrtmp(2)
mgrib(nbytes+3) = chrtmp(3)
mgrib(nbytes+4) = chrtmp(4)
nbytes = nbytes + 4
CALL flt2ibm
(ctrlat,chrtmp,wdlen*8)
mgrib(nbytes+1) = chrtmp(1)
mgrib(nbytes+2) = chrtmp(2)
mgrib(nbytes+3) = chrtmp(3)
mgrib(nbytes+4) = chrtmp(4)
nbytes = nbytes + 4
CALL flt2ibm
(ctrlon,chrtmp,wdlen*8)
mgrib(nbytes+1) = chrtmp(1)
mgrib(nbytes+2) = chrtmp(2)
mgrib(nbytes+3) = chrtmp(3)
mgrib(nbytes+4) = chrtmp(4)
nbytes = nbytes + 4
IF ( totout /= 0 ) THEN
mgrib(nbytes+1) = CHAR(nstyp)
nbytes = nbytes + 1
!
!-----------------------------------------------------------------------
!
! Reserve 20 integers for future compatibility.
!
!-----------------------------------------------------------------------
!
mgrib(nbytes+1) = CHAR(prcout)
nbytes = nbytes + 1
mgrib(nbytes+1) = CHAR(radout)
nbytes = nbytes + 1
mgrib(nbytes+1) = CHAR(flxout)
nbytes = nbytes + 1
mgrib(nbytes+1) = CHAR(0) ! snowcvr not output anymore
nbytes = nbytes + 1
mgrib(nbytes+1) = CHAR(snowout)
nbytes = nbytes + 1
DO i=6,20
mgrib(nbytes+1) = CHAR(idummy)
nbytes = nbytes + 1
END DO
DO i=0,16,4
mgrib(nbytes+1) = CHAR(r0exp)
mgrib(nbytes+2) = CHAR(r0mant)
mgrib(nbytes+3) = CHAR(r0mant)
mgrib(nbytes+4) = CHAR(r0mant)
nbytes = nbytes + 4
END DO
END IF
!
!-----------------------------------------------------------------------
!
! If grdout=1 or grdbas=1, write out grid variables
!
!-----------------------------------------------------------------------
!
IF(grdout == 1 .OR. grdbas == 1 ) THEN
DO i=1,nx
CALL flt2ibm
( mgrib(nbytes+1) = chrtmp(1)
mgrib(nbytes+2) = chrtmp(2)
mgrib(nbytes+3) = chrtmp(3)
mgrib(nbytes+4) = chrtmp(4)
nbytes = nbytes + 4
END DO
DO j=1,ny
CALL flt2ibm
( mgrib(nbytes+1) = chrtmp(1)
mgrib(nbytes+2) = chrtmp(2)
mgrib(nbytes+3) = chrtmp(3)
mgrib(nbytes+4) = chrtmp(4)
nbytes = nbytes + 4
END DO
DO k=1,nz
CALL flt2ibm
( mgrib(nbytes+1) = chrtmp(1)
mgrib(nbytes+2) = chrtmp(2)
mgrib(nbytes+3) = chrtmp(3)
mgrib(nbytes+4) = chrtmp(4)
nbytes = nbytes + 4
END DO
END IF
mgrib(1) = CHAR(MOD(nbytes/65536,256))
mgrib(2) = CHAR(MOD(nbytes/256, 256))
mgrib(3) = CHAR(MOD(nbytes, 256))
WRITE (nchanl) (mgrib(i),i=1,nbytes)
RETURN
END SUBROUTINE wrthishd