!
SUBROUTINE splithdf(filenames,nfile,dimnamein, xdimname, ydimname, & 1,5
varidx_dim, nxidx, nyidx, nproc_x,nproc_y, &
outdirname, debug,istatus)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Split files in HDF4 format into patches. The patched files will
! contain the same data as original file but in evenly divided
! subdomain specified by the user.
!
!-----------------------------------------------------------------------
!
! Author: Yunheng Wang (11/07/2006)
!
! MODIFICATIONS:
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
!-----------------------------------------------------------------------
!
! Variable declaration
!
!-----------------------------------------------------------------------
INTEGER, INTENT(IN) :: nfile
CHARACTER(LEN=*), INTENT(IN) :: filenames(nfile)
CHARACTER(LEN=*), INTENT(IN) :: outdirname
CHARACTER(LEN=*), INTENT(IN) :: xdimname, ydimname
LOGICAL, INTENT(IN) :: dimnamein
! .TRUE. get attributes xdimname/ydimname for global x size and y size
! .FALSE. get x/y size by reading varidx with dimensions nxidx, nyidx
INTEGER, INTENT(IN) :: varidx_dim, nxidx, nyidx
INTEGER, INTENT(IN) :: nproc_x, nproc_y
INTEGER, INTENT(IN) :: debug
INTEGER, INTENT(OUT) :: istatus
!-----------------------------------------------------------------------
!
! Dimensions and work arrays
!
!-----------------------------------------------------------------------
INTEGER :: nxlg, nylg
INTEGER :: nx, ny
CHARACTER(LEN=1), ALLOCATABLE :: attvalstr(:)
INTEGER, ALLOCATABLE :: attvali(:)
REAL, ALLOCATABLE :: attvalr(:)
INTEGER, ALLOCATABLE :: variin(:), variout(:)
INTEGER, ALLOCATABLE :: varain(:), varaout(:)
INTEGER(KIND=SELECTED_INT_KIND(4)), ALLOCATABLE :: vari16in(:), vari16out(:)
INTEGER :: finid
CHARACTER(LEN=256), ALLOCATABLE :: outfilenames(:,:)
INTEGER, ALLOCATABLE :: foutids(:,:)
INTEGER, ALLOCATABLE :: varido (:,:)
INTEGER, ALLOCATABLE :: dimouts0(:,:,:)
!
!-----------------------------------------------------------------------
!
! Misc. local variables
!
!-----------------------------------------------------------------------
INTEGER, PARAMETER :: MAX_RANK = 5
INTEGER :: nf, dindx
INTEGER :: iout, iin
INTEGER :: nxid, nyid
INTEGER :: iloc, jloc
INTEGER :: comp_code, comp_prm(1)
INTEGER :: ngatts, nvars ! file info
CHARACTER(LEN=256) :: dimname, attname, varname
INTEGER :: attnum, atttype, attnval ! attribute info
INTEGER :: varid, varidx ! variable info
INTEGER :: vartype, varndims, varnatts
INTEGER :: vardim, varinsize, varoutsize
INTEGER :: variallsize, varaallsize, vari16allsize
INTEGER :: varibllsize, varabllsize, vari16bllsize
INTEGER :: vardimsize(MAX_RANK), vardimoutsize(MAX_RANK)
INTEGER :: startidx(MAX_RANK), stride(MAX_RANK)
INTEGER :: dimid ! dimension info
INTEGER :: sin1d, sin2d, sin3d, sin4d
INTEGER :: sout1d, sout2d, sout3d, sout4d
INTEGER :: nd1, nd2, nd3, nd4, nd5 ! Assume the max rank is 5
INTEGER :: allocstrlen, allocrlen, allocilen
INTEGER :: resetx, resety
!
!-----------------------------------------------------------------------
!
! Including files
!
!-----------------------------------------------------------------------
INCLUDE 'hdf.f90'
!-----------------------------------------------------------------------
!
! HDF Functions
!
!-----------------------------------------------------------------------
INTEGER :: sfstart, sfend, sffinfo, sfginfo, sfgainfo, sfgcompress ! file and quiry
INTEGER :: sffattr, sfrnatt, sfsnatt, sfrcatt, sfscatt ! attribute
INTEGER :: sfdimid, sfsdmname ! Dimension
INTEGER :: sfselect, sfendacc, sfcreate, sfrdata, sfwdata ! Variable
INTEGER :: sfscompress
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Begin of executable code below
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!-----------------------------------------------------------------------
!
! Check dimensions first
!
!-----------------------------------------------------------------------
finid = sfstart(filenames(1),DFACC_READ)
IF (finid <= 0) CALL print_err
(finid,'Cannot open data set.')
IF (dimnamein) THEN ! Read global attributes for dimension size
nxid = sffattr(finid, xdimname)
istatus = sfrnatt(finid, nxid, nxlg)
nyid = sffattr(finid, ydimname)
istatus = sfrnatt(finid, nyid, nylg)
ELSE ! Read variable dimensions
varid = sfselect(finid,varidx_dim)
istatus = sfginfo (varid,varname,varndims,vardimsize,vartype,varnatts)
nxlg = vardimsize(nxidx)
nylg = vardimsize(nyidx)
END IF
WRITE(6,'(1x,2(a,I5))') 'Dimensions in file to be split are: nx = ',nxlg,', ny = ',nylg
IF (MOD((nxlg-3),nproc_x) /= 0 ) THEN
WRITE(6,'(1x,a)') 'ERROR: Wrong dimension size'
WRITE(6,'(1x,2(a,I5),a)') ' Dimension size in X direction (',nxlg,&
') is not divisible by nproc_x (',nproc_x,').'
istatus = -1
RETURN
END IF
IF (MOD((nylg-3),nproc_y) /= 0 ) THEN
WRITE(6,'(1x,a)') 'ERROR: Wrong dimension size'
WRITE(6,'(1x,2(a,I5),a)') ' Dimension size in Y direction (',nylg,&
') is not divisible by nproc_y (',nproc_y,').'
istatus = -2
RETURN
END IF
istatus = sfend(finid)
!-----------------------------------------------------------------------
!
! Loop over filenames
!
!-----------------------------------------------------------------------
ALLOCATE(outfilenames(nproc_x,nproc_y), STAT = istatus)
ALLOCATE(foutids(nproc_x,nproc_y), STAT = istatus)
ALLOCATE(varido (nproc_x,nproc_y), STAT = istatus)
ALLOCATE(dimouts0(MAX_RANK,nproc_x,nproc_y), STAT = istatus)
ALLOCATE(attvalr(1), STAT = istatus)
ALLOCATE(attvali(1), STAT = istatus)
ALLOCATE(attvalstr(1024), STAT = istatus)
allocrlen = 1
allocilen = 1
allocstrlen = 1024
startidx(:) = 0
stride(:) = 1
variallsize = 0
vari16allsize = 0
varaallsize = 0
varibllsize = 0
vari16bllsize = 0
varabllsize = 0
DO nf = 1,nfile
WRITE(6,'(/,1x,a,I6)') '== Processing file No. ',nf
IF (debug > 0) WRITE(6,'(/,1x,2a)') 'Opening file - ',TRIM(filenames(nf))
finid = sfstart(filenames(nf),DFACC_READ)
IF (finid <= 0) CALL print_err
(finid,'Cannot open data set.')
dindx = INDEX(filenames(nf),'/',.TRUE.) + 1
DO jloc = 1,nproc_y ! Create patches
DO iloc = 1,nproc_x
WRITE(outfilenames(iloc,jloc),'(3a,2I2.2)') &
TRIM(outdirname),TRIM(filenames(nf)(dindx:)),'_',iloc,jloc
IF (debug > 0) WRITE(6,'(1x,2a)') 'Creating file - ',TRIM(outfilenames(iloc,jloc))
foutids(iloc,jloc) = sfstart(outfilenames(iloc,jloc),DFACC_CREATE)
IF (foutids(iloc,jloc) <= 0) CALL print_err
(finid,'Cannot open data set.')
END DO
END DO
!
! Set dimensions
!
nx = (nxlg-3)/nproc_x + 3
ny = (nylg-3)/nproc_y + 3
istatus = sffinfo(finid,nvars,ngatts)
!-----------------------------------------------------------------------
!
! Read/write Global attributes
!
!-----------------------------------------------------------------------
IF (debug > 1) WRITE(6,'(5x,a,I2)') 'Total global attributs - ',ngatts
DO attnum = 0,ngatts-1
istatus = sfgainfo(finid,attnum,attname,atttype,attnval)
IF (attnval /= 1 .AND. atttype /= DFNT_CHAR8) THEN
WRITE(6,'(1x,a,/)') 'ERROR: No support for attribute arrays still.'
istatus = -3
RETURN
ELSE
IF (debug > 2) WRITE(6,'(9x,2a)') 'Attribute name - ',TRIM(attname)
END IF
SELECT CASE (atttype)
CASE (DFNT_CHAR8) ! Character string
IF (attnval > allocstrlen) THEN
DEALLOCATE(attvalstr, STAT = istatus)
ALLOCATE (attvalstr(attnval), STAT = istatus)
allocstrlen = attnval
attvalstr = ' '
END IF
istatus = sfrcatt(finid, attnum, attvalstr)
DO jloc = 1,nproc_y ! Write CHARACTER global attributes
DO iloc = 1,nproc_x
istatus = sfscatt(foutids(iloc,jloc), TRIM(attname), atttype, attnval, attvalstr)
END DO
END DO
CASE (DFNT_FLOAT32) ! REAL number
IF (attnval > allocrlen) THEN
DEALLOCATE(attvalr, STAT = istatus)
ALLOCATE (attvalr(attnval), STAT = istatus)
allocrlen = attnval
attvalr = 0.0
END IF
istatus = sfrnatt(finid, attnum, attvalr)
DO jloc = 1,nproc_y ! Write REAL global attributes
DO iloc = 1,nproc_x
istatus = sfsnatt(foutids(iloc,jloc), TRIM(attname), atttype, attnval, attvalr)
END DO
END DO
CASE (DFNT_INT32) ! INTEGER number
IF (attnval > allocilen) THEN
DEALLOCATE(attvali, STAT = istatus)
ALLOCATE (attvali(attnval), STAT = istatus)
allocilen = attnval
attvali = 0
END IF
IF ( TRIM(attname) == TRIM(xdimname) ) THEN
attvali(1) = nx
ELSE IF ( TRIM(attname) == TRIM(ydimname) ) THEN
attvali(1) = ny
ELSE
istatus = sfrnatt(finid, attnum, attvali)
END IF
DO jloc = 1,nproc_y ! Write integer global attributes
DO iloc = 1,nproc_x
istatus = sfsnatt(foutids(iloc,jloc), TRIM(attname), atttype, attnval, attvali)
END DO
END DO
CASE DEFAULT
WRITE (6,'(/,1x,a,I2,3a,/)') 'ERROR: unsupported attribute type (', &
atttype,') for attribute ', TRIM(attname),'.'
istatus = -4
RETURN
END SELECT
END DO
!-----------------------------------------------------------------------
!
! Read/write each variable
!
!-----------------------------------------------------------------------
IF (debug > 1) WRITE(6,'(5x,a,I2)') 'Total variables - ',nvars
DO varidx = 0,nvars-1
vardimsize(:) = 1
varid = sfselect(finid,varidx)
istatus = sfginfo (varid,varname,varndims,vardimsize,vartype,varnatts)
IF (debug >2) WRITE(6,'(9x,2a)') 'Processing variables - ',TRIM(varname)
istatus = sfgcompress(varid,comp_code,comp_prm)
IF (istatus /= SUCCEED) THEN
! WRITE(6,'(1x,3a)') 'ERROR: HDF error from sfgcompress with variable ',TRIM(varname),'.'
! RETURN
comp_code = 0
comp_prm(1) = 0
END IF
IF (debug >3) WRITE(6,'(13x,2(a,I2))') 'comp_code = ',comp_code,', comp_prm = ',comp_prm(1)
! attnum = sffattr(varid, 'hdf_comp_prm') ! Whether the data set is compressed?
! IF (attnum == FAIL) THEN
! comp_prm(1) = 0
! ELSE
! istatus = sfrnatt(varid, attnum, comp_prm)
! END IF
! comp_code = 0
! IF (comp_prm(1) /= 0) THEN
! attnum = sffattr(varid, 'hdf_comp_code')
! istatus = sfrnatt(varid, attnum, comp_code)
! END IF
vardimoutsize(:) = vardimsize(:)
resetx = 0 ! Assume we only split the first two dimensions
resety = 0
IF (vardimsize(1) == nxlg) THEN ! Check the first dimension of nx/ny
vardimoutsize(1) = nx
resetx = 1
ELSE IF (vardimsize(1) == nylg) THEN
vardimoutsize(1) = ny
resety = 1
END IF
! Check the second dimension as necessary
IF (varndims > 1 .AND. vardimsize(2) == nylg) THEN
vardimoutsize(2) = ny
resety = 2
END IF
varinsize = 1
varoutsize = 1
DO vardim = 1, varndims
varinsize = vardimsize(vardim)*varinsize
varoutsize = vardimoutsize(vardim)*varoutsize
IF (debug > 4) WRITE(6,'(13x,2(I4,a))') &
vardimsize(vardim),'(in) - ', vardimoutsize(vardim), '(out).'
END DO
sin1d = vardimsize(1) ! size of one column, INPUT
sin2d = sin1d*vardimsize(2) ! size of one slice (xy)
sin3d = sin2d*vardimsize(3) ! size of one cell (xyz)
sin4d = sin3d*vardimsize(4)
sout1d = vardimoutsize(1) ! size of one column, OUTPUT
sout2d = sout1d*vardimoutsize(2)
sout3d = sout2d*vardimoutsize(3)
sout4d = sout3d*vardimoutsize(4)
dimouts0(:,:,:) = 0 ! The starting index of each dimensions for each subdomain
DO jloc = 1,nproc_y ! Create data set
DO iloc = 1,nproc_x
varido(iloc,jloc) = sfcreate(foutids(iloc,jloc), varname, &
vartype, varndims, vardimoutsize)
IF (resetx > 0) THEN
dimid = sfdimid(varido(iloc,jloc),resetx-1)
istatus = sfsdmname(dimid,xdimname)
dimouts0(resetx,iloc,jloc) = (iloc-1)*(nx-3)
END IF
IF (resety > 0) THEN
dimid = sfdimid(varido(iloc,jloc),resety-1)
istatus = sfsdmname(dimid,ydimname)
dimouts0(resety,iloc,jloc) = (jloc-1)*(ny-3)
END IF
istatus = sfscompress(varido(iloc,jloc), comp_code, comp_prm)
END DO
END DO
SELECT CASE (vartype)
CASE (dfnt_float32)
IF (varinsize > varaallsize) THEN ! Allocate input array only when necessary
IF (ALLOCATED(varain)) DEALLOCATE(varain, STAT = istatus)
ALLOCATE(varain(varinsize), STAT = istatus)
varaallsize = varinsize
END IF
IF (varoutsize > varabllsize) THEN ! Allocate output array only when necessary
IF (ALLOCATED(varaout)) DEALLOCATE(varaout, STAT = istatus)
ALLOCATE(varaout(varoutsize), STAT = istatus)
varabllsize = varoutsize
END IF
istatus = sfrdata(varid, startidx, stride, vardimsize, varain)
DO jloc = 1,nproc_y ! Write patches variables
DO iloc = 1,nproc_x
IF (debug > 3) THEN
WRITE(6,FMT='(13x,a,2(I4,a))',ADVANCE='NO') &
'Writing to processor - (',iloc,',',jloc,') with: '
DO vardim = 1,varndims
WRITE(6,FMT='(I4,a)',ADVANCE='NO') dimouts0(vardim,iloc,jloc),' '
END DO
WRITE(6,*)
END IF
DO nd5 = 1, vardimoutsize(5) ! Assume max rank is 5, IMPORTANT
DO nd4 = 1, vardimoutsize(4)
DO nd3 = 1, vardimoutsize(3)
DO nd2 = 1, vardimoutsize(2)
DO nd1 = 1, vardimoutsize(1)
iin = nd1+dimouts0(1,iloc,jloc) &
+ (nd2+dimouts0(2,iloc,jloc)-1)*sin1d &
+ (nd3+dimouts0(3,iloc,jloc)-1)*sin2d &
+ (nd4+dimouts0(4,iloc,jloc)-1)*sin3d &
+ (nd5+dimouts0(5,iloc,jloc)-1)*sin4d
iout = nd1 + (nd2-1)*sout1d + (nd3-1)*sout2d &
+ (nd4-1)*sout3d + (nd5-1)*sout4d
IF (debug > 3) WRITE(6,'(13x,a,2I2,3(a,I4),4I4)') &
'Processor - ',iloc,jloc,': Extracting from ',iin, &
' to ',iout,' at ',nd1,nd2,nd3,nd4,nd5
varaout(iout) = varain(iin)
END DO
END DO
END DO
END DO
END DO
istatus = sfwdata(varido(iloc,jloc), startidx, stride, vardimoutsize, varaout)
IF (istatus /= SUCCEED) CALL print_err
(istatus,'ERROR: sfwdata')
END DO
END DO
CASE (dfnt_int32)
IF (varinsize > variallsize) THEN ! Allocate input array only when necessary
IF (ALLOCATED(variin)) DEALLOCATE(variin, STAT = istatus)
ALLOCATE(variin(varinsize), STAT = istatus)
variallsize = varinsize
END IF
IF (varoutsize > varibllsize) THEN ! Allocate output array only when necessary
IF (ALLOCATED(variout)) DEALLOCATE(variout, STAT = istatus)
ALLOCATE(variout(varoutsize), STAT = istatus)
varibllsize = varoutsize
END IF
istatus = sfrdata(varid, startidx, stride, vardimsize, variin)
DO jloc = 1,nproc_y ! Write patches variables
DO iloc = 1,nproc_x
IF (debug > 3) THEN
WRITE(6,FMT='(13x,a,2(I4,a))',ADVANCE='NO') &
'Writing to processor - (',iloc,',',jloc,') with: '
DO vardim = 1,varndims
WRITE(6,FMT='(I4,a)',ADVANCE='NO') dimouts0(vardim,iloc,jloc),' '
END DO
WRITE(6,*)
END IF
DO nd5 = 1, vardimoutsize(5) ! Assume max rank is 5, IMPORTANT
DO nd4 = 1, vardimoutsize(4)
DO nd3 = 1, vardimoutsize(3)
DO nd2 = 1, vardimoutsize(2)
DO nd1 = 1, vardimoutsize(1)
iin = nd1+dimouts0(1,iloc,jloc) &
+ (nd2+dimouts0(2,iloc,jloc)-1)*sin1d &
+ (nd3+dimouts0(3,iloc,jloc)-1)*sin2d &
+ (nd4+dimouts0(4,iloc,jloc)-1)*sin3d &
+ (nd5+dimouts0(5,iloc,jloc)-1)*sin4d
iout = nd1 + (nd2-1)*sout1d + (nd3-1)*sout2d &
+ (nd4-1)*sout3d + (nd5-1)*sout4d
IF (debug > 3) WRITE(6,'(13x,a,2I2,3(a,I4),4I4)') &
'Processor - ',iloc,jloc,': Extracting from ',iin, &
' to ',iout,' at ',nd1,nd2,nd3,nd4,nd5
variout(iout) = variin(iin)
END DO
END DO
END DO
END DO
END DO
istatus = sfwdata(varido(iloc,jloc), startidx, stride, vardimoutsize, variout)
IF (istatus /= SUCCEED) CALL print_err
(istatus,'ERROR: sfwdata')
END DO
END DO
CASE (dfnt_int16)
IF (varinsize > vari16allsize) THEN ! Allocate input array only when necessary
IF (ALLOCATED(vari16in)) DEALLOCATE(vari16in, STAT = istatus)
ALLOCATE(vari16in(varinsize), STAT = istatus)
vari16allsize = varinsize
END IF
IF (varoutsize > vari16bllsize) THEN ! Allocate output array only when necessary
IF (ALLOCATED(vari16out)) DEALLOCATE(vari16out, STAT = istatus)
ALLOCATE(vari16out(varoutsize), STAT = istatus)
vari16bllsize = varoutsize
END IF
istatus = sfrdata(varid, startidx, stride, vardimsize, vari16in)
DO jloc = 1,nproc_y ! Write patches variables
DO iloc = 1,nproc_x
IF (debug > 3) THEN
WRITE(6,FMT='(13x,a,2(I4,a))',ADVANCE='NO') &
'Writing to processor - (',iloc,',',jloc,') with: '
DO vardim = 1,varndims
WRITE(6,FMT='(I4,a)',ADVANCE='NO') dimouts0(vardim,iloc,jloc),' '
END DO
WRITE(6,*)
END IF
DO nd5 = 1, vardimoutsize(5) ! Assume max rank is 5, IMPORTANT
DO nd4 = 1, vardimoutsize(4)
DO nd3 = 1, vardimoutsize(3)
DO nd2 = 1, vardimoutsize(2)
DO nd1 = 1, vardimoutsize(1)
iin = nd1+dimouts0(1,iloc,jloc) &
+ (nd2+dimouts0(2,iloc,jloc)-1)*sin1d &
+ (nd3+dimouts0(3,iloc,jloc)-1)*sin2d &
+ (nd4+dimouts0(4,iloc,jloc)-1)*sin3d &
+ (nd5+dimouts0(5,iloc,jloc)-1)*sin4d
iout = nd1 + (nd2-1)*sout1d + (nd3-1)*sout2d &
+ (nd4-1)*sout3d + (nd5-1)*sout4d
IF (debug > 3) WRITE(6,'(13x,a,2I2,3(a,I4),4I4)') &
'Processor - ',iloc,jloc,': Extracting from ',iin, &
' to ',iout,' at ',nd1,nd2,nd3,nd4,nd5
vari16out(iout) = vari16in(iin)
END DO
END DO
END DO
END DO
END DO
istatus = sfwdata(varido(iloc,jloc), startidx, stride, vardimoutsize, vari16out)
IF (istatus /= SUCCEED) CALL print_err
(istatus,'ERROR: sfwdata')
END DO
END DO
CASE DEFAULT
WRITE(6,'(1x,a,I2,3a,/)') 'ERROR: Unsupported variable type (', &
vartype,') for variable ',TRIM(varname),'.'
istatus = -5
RETURN
END SELECT
!
! Data set attributes
!
DO attnum = 0,varnatts-1
istatus = sfgainfo(varid,attnum,attname,atttype,attnval)
IF (debug > 2) WRITE(6,'(13x,2a)') 'Attribute name - ',TRIM(attname)
SELECT CASE (atttype)
CASE (DFNT_CHAR8) ! Character string
IF (attnval > allocstrlen) THEN
DEALLOCATE(attvalstr, STAT = istatus)
ALLOCATE (attvalstr(attnval), STAT = istatus)
allocstrlen = attnval
attvalstr = ' '
END IF
istatus = sfrcatt(varid, attnum, attvalstr)
DO jloc = 1,nproc_y ! Write CHARACTER var attributes
DO iloc = 1,nproc_x
istatus = sfscatt(varido(iloc,jloc), TRIM(attname), atttype, attnval, attvalstr)
END DO
END DO
CASE (DFNT_FLOAT32) ! REAL number
IF (attnval > allocrlen) THEN
DEALLOCATE(attvalr, STAT = istatus)
ALLOCATE (attvalr(attnval), STAT = istatus)
allocrlen = attnval
attvalr = 0.0
END IF
istatus = sfrnatt(varid, attnum, attvalr)
DO jloc = 1,nproc_y ! Write REAL global attributes
DO iloc = 1,nproc_x
istatus = sfsnatt(varido(iloc,jloc), TRIM(attname), atttype, attnval, attvalr)
END DO
END DO
CASE (DFNT_INT32) ! INTEGER number
IF (attnval > allocilen) THEN
DEALLOCATE(attvali, STAT = istatus)
ALLOCATE (attvali(attnval), STAT = istatus)
allocilen = attnval
attvali = 0
END IF
istatus = sfrnatt(varid, attnum, attvali)
DO jloc = 1,nproc_y ! Write integer global attributes
DO iloc = 1,nproc_x
istatus = sfsnatt(varido(iloc,jloc), TRIM(attname), atttype, attnval, attvali)
END DO
END DO
CASE DEFAULT
WRITE (6,'(/,1x,a,I2,5a,/)') 'ERROR: unsupported attribute type (', &
atttype,') for attribute ', TRIM(attname), &
' of variable ',TRIM(varname),'.'
istatus = -4
RETURN
END SELECT
END DO
!
! Close data sets
!
istatus = sfendacc(varid)
DO jloc = 1,nproc_y
DO iloc = 1,nproc_x
istatus = sfendacc(varido(iloc,jloc))
END DO
END DO
END DO
!
! Close files
!
IF (debug > 0) WRITE(6,'(1x,a)') 'Closing all files ...'
DO jloc = 1,nproc_y ! Close patches
DO iloc = 1,nproc_x
istatus = sfend(foutids(iloc,jloc))
END DO
END DO
istatus = sfend(finid) ! Close file
END DO
DEALLOCATE(outfilenames, foutids, varido, STAT = istatus)
DEALLOCATE(attvalstr, attvali, attvalr, STAT = istatus)
DEALLOCATE(dimouts0, STAT = istatus)
IF (ALLOCATED(varain)) DEALLOCATE(varain, varaout, STAT = istatus)
IF (ALLOCATED(variin)) DEALLOCATE(variin, variout, STAT = istatus)
IF (ALLOCATED(vari16in)) DEALLOCATE(vari16in, vari16out, STAT = istatus)
RETURN
END SUBROUTINE splithdf
SUBROUTINE print_err(istat,message) 6
IMPLICIT NONE
INTEGER, INTENT(IN) :: istat
CHARACTER(*), INTENT(IN) :: message
PRINT *, TRIM(message)
STOP 'HDF error!'
RETURN
END SUBROUTINE print_err