!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE check_files_dimensions ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE check_files_dimensions(MAXWRFFIL,grid_id,io_form,jointime, & 1,1
nprocs,nproc_x,nproc_y,abstimes,abstimei,abstimee, &
dir_extd,extdname,nextdfil, &
ids,ide,idss,idse,jds,jde,jdss,jdse,istatus)
!
!-----------------------------------------------------------------------
!
! PURPOSE: Check the existence of WRF files to be read and return the
! valid file number, file names and the domain grid indices.
!
!-----------------------------------------------------------------------
!
! AUTHOR:
! Yunheng Wang (04/26/2007)
!
! MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
IMPLICIT NONE
INTEGER, INTENT(IN) :: MAXWRFFIL
INTEGER, INTENT(IN) :: grid_id
INTEGER, INTENT(IN) :: io_form
LOGICAL, INTENT(IN) :: jointime
INTEGER, INTENT(IN) :: abstimes, abstimei, abstimee
INTEGER, INTENT(IN) :: nproc_x,nproc_y
INTEGER, INTENT(IN) :: nprocs(nproc_x*nproc_y)
CHARACTER(LEN=256), INTENT(IN) :: dir_extd
CHARACTER(LEN=256), INTENT(OUT) :: extdname(MAXWRFFIL)
INTEGER, INTENT(OUT) :: nextdfil
INTEGER, INTENT(OUT) :: ids, ide, jds, jde
INTEGER, INTENT(OUT) :: idss,idse,jdss,jdse
INTEGER, INTENT(OUT) :: istatus
!-----------------------------------------------------------------------
!
! Misc. local variables
!
!-----------------------------------------------------------------------
INTEGER :: year, month, day, hour, minute, second
INTEGER :: ifile, npx, npy, n
INTEGER :: ips, ipe, jps, jpe, ipss, ipse, jpss, jpse
INTEGER :: ipssv, ipesv, jpssv, jpesv
INTEGER :: nx
CHARACTER(LEN=256) :: tmpstr
LOGICAL :: fexist
LOGICAL :: dset = .FALSE., in_a_row = .FALSE.
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Begining of executable code ....
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
ids = 99999999
ide = 0
idss = 99999999
idse = 0
jds = 99999999
jde = 0
jdss = 99999999
jdse = 0
nextdfil = 0
extdname(:) = ' '
istatus = 0
WRITE(6,'(1x,a,/,1x,a,/)') &
'============================','WRF files to be read are:'
ifile = abstimes
DO WHILE (ifile <= abstimee)
CALL abss2ctim
(ifile,year,month,day,hour,minute,second)
nextdfil = nextdfil + 1
WRITE(extdname(nextdfil),'(a,a,I2.2,a,I4.4,5(a,I2.2))') &
TRIM(dir_extd),'wrfout_d',grid_id,'_', &
year,'-',month,'-',day,'_',hour,':',minute,':',second
ipssv = 0
ipesv = 0
jpssv = 0
jpesv = 0
n = 0
DO npy = 1,nproc_y
in_a_row = .FALSE.
DO npx = 1,nproc_x
IF (npx > 1) in_a_row = .TRUE.
n = n+1
IF (jointime .AND. nproc_x*nproc_y == 1) THEN
WRITE(tmpstr,'(a)') TRIM(extdname(nextdfil))
ELSE
WRITE(tmpstr,'(a,a,I4.4)') TRIM(extdname(nextdfil)),'_',nprocs(n)
END IF
INQUIRE(FILE=TRIM(tmpstr), EXIST = fexist )
IF(.NOT. fexist) THEN
WRITE(6,'(1x,a)') 'ERROR: The WRF file ', &
TRIM(tmpstr),' does not exist.'
STOP
ELSE
CALL get_wrf_patch_indices(TRIM(tmpstr),io_form, &
ips,ipe,ipss,ipse,jps,jpe,jpss,jpse,nx,istatus)
IF (istatus /= 0) EXIT
IF (.NOT. dset) THEN
IF (npx == 1) THEN
ids = ips
idss = ipss
END IF
IF (npx == nproc_x) THEN
ide = ipe
idse = ipse
END IF
IF (npy == 1) THEN
jds = jps
jdss = jpss
END IF
IF (npy == nproc_y) THEN
jde = jpe
jdse = jpse
END IF
END IF
IF ( n > 1) THEN
IF (in_a_row) THEN
IF (jps /= jpssv .OR. jpe /= jpesv .OR. ips /= ipesv+1) THEN
WRITE(6,'(/,1x,a,I4,2a,/,8x,2(a,I2),a,/,8x,a,/,8x,a,/)') &
'ERROR: Patch ',n,' for file ',TRIM(tmpstr), &
'at relative patch (',npx,',',npy, &
') is not aligned in a row with its former patch.', &
'Please check parameter nproc_xin. Either it was specified with a wrong number', &
'or the program has made a bad guess about it.'
STOP
END IF
ELSE
IF (jps /= jpesv+1) THEN
WRITE(6,'(/,1x,a,I4,2a,/,8x,2(a,I2),a,/,8x,a,/,8x,a,/)') &
'ERROR: Patch ',n,' for file ',TRIM(tmpstr), &
'at relative patch (',npx,',',npy, &
') is not aligned in column with its former patch.', &
'Please check parameter nproc_xin. Either it was specified with a wrong number', &
'or the program has made a bad guess about it.'
STOP
END IF
END IF
END IF
ipssv = ips
ipesv = ipe
jpssv = jps
jpesv = jpe
WRITE(6,'(3x,a,I2.2,a,I4,a,/,5x,a)') &
'WRF file ',nextdfil,': patch - ',n,' =', TRIM(tmpstr)
END IF
END DO
END DO
ifile = ifile + abstimei
dset = .TRUE.
END DO
!-----------------------------------------------------------------------
!
! Validate nextdfil before return
!
!-----------------------------------------------------------------------
IF(nextdfil < 1) THEN
WRITE(6,'(a)') 'No input WRF file was valid. Please check the input file.'
istatus = -3
RETURN
END IF
IF (ide < ids .OR. jde < jds) THEN
WRITE(6,'(1x,2(a,I4),/36x,2(a,I4),a)') &
'ERROR: Domain indices are invalid: ids = ',ids,', ide = ',ide, &
'; jds = ',jds,', jde = ',jde,'.'
istatus = -3
RETURN
END IF
RETURN
END SUBROUTINE check_files_dimensions
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE get_wrf_patch_indices ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE get_wrf_patch_indices(filename,io_form,ips,ipe,ipss,ipse, &,60
jps,jpe,jpss,jpse,nx,istatus)
!-----------------------------------------------------------------------
!
! PURPOSE:
! Get the size of data patch stored in the WRF data file
!
!-----------------------------------------------------------------------
!
! AUTHOR:
! Yunheng Wang (04/26/2007)
!
! MODIFICATION HISTORY:
!
!-----------------------------------------------------------------------
IMPLICIT NONE
CHARACTER(LEN=*), INTENT(IN) :: filename
INTEGER, INTENT(IN) :: io_form
INTEGER, INTENT(OUT) :: ips, ipe, jps, jpe
INTEGER, INTENT(OUT) :: ipss,ipse,jpss,jpse
INTEGER, INTENT(OUT) :: nx
INTEGER, INTENT(OUT) :: istatus
INCLUDE 'netcdf.inc'
!------------------------------------------------------------------
!
! Misc. local variables
!
!------------------------------------------------------------------
INTEGER :: ncid
CHARACTER(LEN=80) :: errmsg
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code...
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
istatus = 0
IF (io_form == 7) THEN
istatus = NF_OPEN(TRIM(filename),NF_NOWRITE,ncid)
IF(istatus /= NF_NOERR) GO TO 999
istatus = NF_GET_ATT_INT(ncid,NF_GLOBAL,'WEST-EAST_PATCH_START_STAG',ips)
IF(istatus /= NF_NOERR) GO TO 999
istatus = NF_GET_ATT_INT(ncid,NF_GLOBAL,'WEST-EAST_PATCH_END_STAG',ipe)
IF(istatus /= NF_NOERR) GO TO 999
istatus = NF_GET_ATT_INT(ncid,NF_GLOBAL,'WEST-EAST_PATCH_START_UNSTAG',ipss)
IF(istatus /= NF_NOERR) GO TO 999
istatus = NF_GET_ATT_INT(ncid,NF_GLOBAL,'WEST-EAST_PATCH_END_UNSTAG',ipse)
IF(istatus /= NF_NOERR) GO TO 999
istatus = NF_GET_ATT_INT(ncid,NF_GLOBAL,'SOUTH-NORTH_PATCH_START_STAG',jps)
IF(istatus /= NF_NOERR) GO TO 999
istatus = NF_GET_ATT_INT(ncid,NF_GLOBAL,'SOUTH-NORTH_PATCH_END_STAG',jpe)
IF(istatus /= NF_NOERR) GO TO 999
istatus = NF_GET_ATT_INT(ncid,NF_GLOBAL,'SOUTH-NORTH_PATCH_START_UNSTAG',jpss)
IF(istatus /= NF_NOERR) GO TO 999
istatus = NF_GET_ATT_INT(ncid,NF_GLOBAL,'SOUTH-NORTH_PATCH_END_UNSTAG',jpse)
IF(istatus /= NF_NOERR) GO TO 999
istatus = NF_GET_ATT_INT(ncid,NF_GLOBAL,'WEST-EAST_GRID_DIMENSION',nx)
IF(istatus /= NF_NOERR) GO TO 999
istatus = NF_CLOSE(ncid)
IF(istatus /= NF_NOERR) GO TO 999
ELSE
istatus = -1
ips = 0
ipe = 0
ipse= 0
jps = 0
jpe = 0
jpse= 0
WRITE(6,'(1x,a,/)') &
'WARNING: Only support netCDF file at present for patch indices.'
END IF
RETURN
999 CONTINUE
errmsg = NF_STRERROR(istatus)
WRITE(6,'(1x,2a)') 'NetCDF error: ',errmsg
STOP
RETURN
END SUBROUTINE get_wrf_patch_indices
!
!##################################################################
!##################################################################
!###### ######
!###### SUBROUTINE joinwrfncdf ######
!###### ######
!###### Developed by ######
!###### Center for Analysis and Prediction of Storms ######
!###### University of Oklahoma ######
!###### ######
!##################################################################
!##################################################################
!
SUBROUTINE joinwrfncdf(filenames,nfile,attadj,jointime,procs,npatch, & 1
ids,ide,idss,idse,jds,jde,jdss,jdse, &
outdirname,filetail,nvarout,varlists,debug,istatus)
!
!-----------------------------------------------------------------------
!
! PURPOSE:
!
! Join WRF files in netCDF patches into one large piece.
!
!-----------------------------------------------------------------------
!
! Author: Yunheng Wang (04/27/2007)
!
! MODIFICATIONS:
!
!-----------------------------------------------------------------------
!
IMPLICIT NONE
INTEGER, INTENT(IN) :: nfile
LOGICAL, INTENT(IN) :: attadj
LOGICAL, INTENT(IN) :: jointime
INTEGER, INTENT(IN) :: npatch
INTEGER, INTENT(IN) :: procs(npatch)
INTEGER, INTENT(IN) :: ids,ide,idss,idse,jds,jde,jdss,jdse
INTEGER, INTENT(INOUT) :: nvarout
INTEGER, INTENT(IN) :: debug
INTEGER, INTENT(OUT) :: istatus
CHARACTER(LEN=*), INTENT(IN) :: filenames(nfile)
CHARACTER(LEN=*), INTENT(IN) :: outdirname
CHARACTER(LEN=5), INTENT(IN) :: filetail
CHARACTER(LEN=20), INTENT(IN) :: varlists(nvarout)
!
!-----------------------------------------------------------------------
!
! Including files
!
!-----------------------------------------------------------------------
INCLUDE 'netcdf.inc'
!-----------------------------------------------------------------------
!
! Misc. local variables
!
!-----------------------------------------------------------------------
INTEGER :: nf, nvar, n
INTEGER :: strlen
LOGICAL :: ispatch(NF_MAX_VARS)
CHARACTER(LEN=256) :: infilename, outfilename
INTEGER :: finid, foutid
INTEGER :: idsout, ideout, jdsout, jdeout
INTEGER :: idssout, idseout, jdssout, jdseout
!
! Dimension variables
!
CHARACTER(LEN=32), PARAMETER :: xdimname = 'west_east_stag'
CHARACTER(LEN=32), PARAMETER :: ydimname = 'south_north_stag'
CHARACTER(LEN=32), PARAMETER :: xsdimname = 'west_east'
CHARACTER(LEN=32), PARAMETER :: ysdimname = 'south_north'
CHARACTER(LEN=32) :: diminnames(NF_MAX_DIMS)
CHARACTER(LEN=32) :: dimname
INTEGER :: nxid, nyid, nxlg, nylg, nxsid, nysid, nxslg, nyslg
INTEGER :: narrsize, narrisizemax, narrasizemax
INTEGER :: unlimdimid, unlimdimlen, unlimodimlen, odimid
INTEGER :: ndims, dimid, dimlen
INTEGER :: dimina(NF_MAX_DIMS) ! Dimension size in original file
! INTEGER :: dimouta(NF_MAX_DIMS) ! Dimension size in joined files
!
! Attribute variables
!
CHARACTER(LEN=32), PARAMETER :: attnm_ips = 'WEST-EAST_PATCH_START_STAG'
CHARACTER(LEN=32), PARAMETER :: attnm_ipe = 'WEST-EAST_PATCH_END_STAG'
CHARACTER(LEN=32), PARAMETER :: attnm_ipss = 'WEST-EAST_PATCH_START_UNSTAG'
CHARACTER(LEN=32), PARAMETER :: attnm_ipse = 'WEST-EAST_PATCH_END_UNSTAG'
CHARACTER(LEN=32), PARAMETER :: attnm_jps = 'SOUTH-NORTH_PATCH_START_STAG'
CHARACTER(LEN=32), PARAMETER :: attnm_jpe = 'SOUTH-NORTH_PATCH_END_STAG'
CHARACTER(LEN=32), PARAMETER :: attnm_jpss = 'SOUTH-NORTH_PATCH_START_UNSTAG'
CHARACTER(LEN=32), PARAMETER :: attnm_jpse = 'SOUTH-NORTH_PATCH_END_UNSTAG'
CHARACTER(LEN=32) :: attname
INTEGER :: ipsid, ipeid, jpsid, jpeid
INTEGER :: ipssid, ipseid, jpssid, jpseid
INTEGER :: ips, ipe, ipss, ipse
INTEGER :: jps, jpe, jpss, jpse
INTEGER :: attnum, ngatts
CHARACTER(LEN=32), PARAMETER :: attnm_ndx = 'WEST-EAST_GRID_DIMENSION'
CHARACTER(LEN=32), PARAMETER :: attnm_ndy = 'SOUTH-NORTH_GRID_DIMENSION'
INTEGER :: ndxid, ndyid
!
! Dataset varaibles
!
INTEGER, PARAMETER :: MAX_RANK = 4 ! Assume the max rank is 5
CHARACTER(LEN=32) :: varname
INTEGER :: varid, nvars, ovarid
INTEGER :: vartype, varndims, varnatts
INTEGER :: vardimids(MAX_RANK),startidx(MAX_RANK), countidx(MAX_RANK)
INTEGER :: outstart(MAX_RANK)
INTEGER :: vardim, vdimid
INTEGER :: varidlists(NF_MAX_VARS), varoutidlists(NF_MAX_VARS)
INTEGER, ALLOCATABLE :: varari(:)
REAL, ALLOCATABLE :: vararr(:)
CHARACTER(LEN=256) :: tmpstr
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
!
! Beginning of executable code below
!
!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
varidlists(:) = 0
nxlg = ide-ids+1
nylg = jde-jds+1
nxslg = idse-idss+1
nyslg = jdse-jdss+1
startidx(:) = 1
narrisizemax = 0
narrasizemax = 0
unlimdimlen = 1
istatus = 0
DO nf = 1,nfile
IF (.NOT. jointime .OR. nf == 1) THEN
strlen = LEN_TRIM(filenames(nf))
n = INDEX(filenames(nf),'/',.TRUE.)
WRITE(outfilename,'(3a)') TRIM(outdirname), &
filenames(nf)(n+1:strlen),filetail
IF (jointime .AND. npatch == 1) THEN
WRITE(infilename, '(a)') TRIM(filenames(nf))
ELSE
WRITE(infilename, '(2a,I4.4)') TRIM(filenames(nf)),'_',procs(1)
END IF
IF (debug > 0) WRITE(6,'(1x,2a)') 'Opening file - ',TRIM(infilename)
istatus = nf_open(infilename,NF_NOWRITE,finid) ! Open file
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
IF (debug > 0) WRITE(6,'(1x,2a)') 'Creating file - ',TRIM(outfilename)
! istatus = nf_create(TRIM(outfilename),NF_CLOBBER,foutid) ! CDF 1
istatus = NF_CREATE(TRIM(outfilename),IOR(NF_CLOBBER,NF_64BIT_OFFSET),foutid) ! CDF 2
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
!
! Set dimensions
!
istatus = nf_inq_dimid(finid,xdimname,nxid)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
istatus = nf_inq_dimid(finid,ydimname,nyid)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
istatus = nf_inq_dimid(finid,xsdimname,nxsid)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
istatus = nf_inq_dimid(finid,ysdimname,nysid)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
istatus = nf_inq_unlimdim(finid,unlimdimid)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
istatus = nf_inq_ndims(finid,ndims)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
IF (debug > 0) WRITE(6,'(5x,a,I2)') 'Copying dimensions - ',ndims
DO dimid = 1,ndims
istatus = nf_inq_dim(finid,dimid,dimname,dimlen)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
diminnames(dimid) = dimname
dimina(dimid) = dimlen ! Save dimension id and len
! dimouta(dimid) = dimlen ! Output dimension id and len
IF (dimid == nxid) THEN
dimlen = nxlg
! dimouta(dimid) = dimlen
ELSE IF (dimid == nxsid) THEN
dimlen = nxslg
! dimouta(dimid) = dimlen
ELSE IF (dimid == nyid) THEN
dimlen = nylg
! dimouta(dimid) = dimlen
ELSE IF (dimid == nysid) THEN
dimlen = nyslg
! dimouta(dimid) = dimlen
ELSE IF (dimid == unlimdimid) THEN
dimlen = NF_UNLIMITED
END IF
IF (debug > 0) WRITE(6,'(9x,2a)') 'Dimension name - ',TRIM(dimname)
istatus = nf_def_dim(foutid,dimname,dimlen,odimid)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
END DO
!
! Set Global attributes
!
istatus = nf_inq_attid(finid,NF_GLOBAL,TRIM(attnm_ips),ipsid)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
istatus = nf_inq_attid(finid,NF_GLOBAL,TRIM(attnm_ipe),ipeid)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
istatus = nf_inq_attid(finid,NF_GLOBAL,TRIM(attnm_ipss),ipssid)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
istatus = nf_inq_attid(finid,NF_GLOBAL,TRIM(attnm_ipse),ipseid)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
istatus = nf_inq_attid(finid,NF_GLOBAL,TRIM(attnm_jps),jpsid)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
istatus = nf_inq_attid(finid,NF_GLOBAL,TRIM(attnm_jpe),jpeid)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
istatus = nf_inq_attid(finid,NF_GLOBAL,TRIM(attnm_jpss),jpssid)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
istatus = nf_inq_attid(finid,NF_GLOBAL,TRIM(attnm_jpse),jpseid)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
istatus = nf_inq_attid(finid,NF_GLOBAL,TRIM(attnm_ndx),ndxid)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
istatus = nf_inq_attid(finid,NF_GLOBAL,TRIM(attnm_ndy),ndyid)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
istatus = nf_inq_natts(finid,ngatts)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
IF (debug > 0) WRITE(6,'(5x,a,I2)') 'Copying global attributes - ',ngatts
IF (attadj) THEN
idsout = 1
ideout = ide - ids + 1
idssout = 1
idseout = idse - idss + 1
jdsout = 1
jdeout = jde - jds + 1
jdssout = 1
jdseout = jdse - jdss + 1
ELSE
idsout = ids
ideout = ide
idssout = idss
idseout = idse
jdsout = jds
jdeout = jde
jdssout = jdss
jdseout = jdse
END IF
DO attnum = 1,ngatts
istatus = nf_inq_attname(finid,NF_GLOBAL,attnum,attname)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
IF (debug > 0) WRITE(6,'(9x,2a)') 'Attribute name - ',TRIM(attname)
IF (attadj) THEN
IF (attnum == ndxid) THEN
istatus = NF_PUT_ATT_INT(foutid,NF_GLOBAL,TRIM(attnm_ndx),NF_INT,1,nxlg)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
CYCLE
ELSE IF (attnum == ndyid) THEN
istatus = NF_PUT_ATT_INT(foutid,NF_GLOBAL,TRIM(attnm_ndy),NF_INT,1,nylg)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
CYCLE
END IF
END IF
IF (attnum == ipsid) THEN
istatus = NF_PUT_ATT_INT(foutid,NF_GLOBAL,TRIM(attnm_ips),NF_INT,1,idsout)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
ELSE IF (attnum == ipeid) THEN
istatus = NF_PUT_ATT_INT(foutid,NF_GLOBAL,TRIM(attnm_ipe),NF_INT,1,ideout)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
ELSE IF (attnum == jpsid) THEN
istatus = NF_PUT_ATT_INT(foutid,NF_GLOBAL,TRIM(attnm_jps),NF_INT,1,jdsout)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
ELSE IF (attnum == jpeid) THEN
istatus = NF_PUT_ATT_INT(foutid,NF_GLOBAL,TRIM(attnm_jpe),NF_INT,1,jdeout)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
ELSE IF (attnum == ipssid) THEN
istatus = NF_PUT_ATT_INT(foutid,NF_GLOBAL,TRIM(attnm_ipss),NF_INT,1,idssout)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
ELSE IF (attnum == ipseid) THEN
istatus = NF_PUT_ATT_INT(foutid,NF_GLOBAL,TRIM(attnm_ipse),NF_INT,1,idseout)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
ELSE IF (attnum == jpssid) THEN
istatus = NF_PUT_ATT_INT(foutid,NF_GLOBAL,TRIM(attnm_jpss),NF_INT,1,jdssout)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
ELSE IF (attnum == jpseid) THEN
istatus = NF_PUT_ATT_INT(foutid,NF_GLOBAL,TRIM(attnm_jpse),NF_INT,1,jdseout)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
ELSE
istatus = nf_copy_att(finid,NF_GLOBAL,attname,foutid,NF_GLOBAL)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
END IF
END DO
!
! Define variables
!
istatus = nf_inq_nvars(finid,nvars)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
IF (nvarout >= nvars) THEN
nvarout = nvars
DO n = 1,nvars
varidlists(n) = n
END DO
ELSE
nvar = nvarout ! suppost to process this number
nvarout = 0 ! actually got
DO n = 1,nvar
istatus = nf_inq_varid(finid,TRIM(varlists(n)),ovarid)
IF (istatus /= NF_NOERR) THEN
WRITE(6,'(1x,3a)') 'WARNING: Variable ',TRIM(varlists(n)),' not found. Skipped.'
CYCLE
END IF
nvarout = nvarout + 1
varidlists(nvarout) = ovarid
END DO
END IF
IF (debug > 0) WRITE(6,'(5x,a,I4)') 'Defining variables - ',nvarout
DO n = 1,nvarout
varid = varidlists(n)
istatus = nf_inq_var(finid,varid,varname,vartype,varndims,vardimids,varnatts)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
IF (debug > 0) WRITE(6,'(9x,2a)') 'Variables - ',TRIM(varname)
! Dimensions should be in the same order
istatus = nf_def_var(foutid,varname,vartype,varndims,vardimids,ovarid)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
varoutidlists(n) = ovarid
DO attnum = 1,varnatts ! Copy variable attributes
istatus = nf_inq_attname(finid,varid,attnum,attname)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
istatus = nf_copy_att(finid,varid,attname,foutid,ovarid)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
END DO
END DO
istatus = nf_enddef(foutid)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
IF(debug > 0) WRITE(6,'(1x,a)') 'Merged file have been defined.'
istatus = nf_close(finid) ! Close file
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
END IF ! File created.
IF (.NOT. jointime) unlimdimlen = 1
unlimodimlen = 0
!
! Write each patch to the merged file
!
ispatch(:) = .FALSE.
DO n = 1,npatch
IF (jointime .AND. npatch == 1) THEN
WRITE(infilename, '(a)') TRIM(filenames(nf))
ELSE
WRITE(infilename, '(2a,I4.4)') TRIM(filenames(nf)),'_',procs(n)
END IF
IF (debug > 0) WRITE(6,'(1x,2a)') 'Opening file - ',TRIM(infilename)
istatus = nf_open(TRIM(infilename),NF_NOWRITE,finid) ! Open file
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
!
! Get patch indice
!
istatus = nf_get_att_int(finid,NF_GLOBAL,TRIM(attnm_ips),ips)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
istatus = nf_get_att_int(finid,NF_GLOBAL,TRIM(attnm_ipe),ipe)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
istatus = nf_get_att_int(finid,NF_GLOBAL,TRIM(attnm_ipss),ipss)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
istatus = nf_get_att_int(finid,NF_GLOBAL,TRIM(attnm_ipse),ipse)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
istatus = nf_get_att_int(finid,NF_GLOBAL,TRIM(attnm_jps),jps)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
istatus = nf_get_att_int(finid,NF_GLOBAL,TRIM(attnm_jpe),jpe)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
istatus = nf_get_att_int(finid,NF_GLOBAL,TRIM(attnm_jpss),jpss)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
istatus = nf_get_att_int(finid,NF_GLOBAL,TRIM(attnm_jpse),jpse)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
!
! Get and save dimension size for this patch
!
istatus = nf_inq_ndims(finid,ndims)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
dimina(:) = 0
DO dimid = 1,ndims
istatus = nf_inq_dim(finid,dimid,dimname,dimlen)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
diminnames(dimid) = dimname
dimina(dimid) = dimlen ! Save dimension id and len
END DO
!
! loop over each variable
!
DO nvar = 1,nvarout
varid = varidlists(nvar)
vardimids(:) = 0
istatus = nf_inq_var(finid,varid,varname,vartype,varndims,vardimids,varnatts)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
countidx(:) = 1
outstart(:) = 1
narrsize = 1
DO vardim = 1, varndims
vdimid = vardimids(vardim)
countidx(vardim) = dimina (vdimid)
IF ( vdimid == nxid) THEN
outstart(vardim) = ips - ids + 1 ! start relative in subdomain
ispatch(nvar) = .TRUE.
ELSE IF ( vdimid == nyid) THEN
outstart(vardim) = jps - jds + 1
ispatch(nvar) = .TRUE.
ELSE IF ( vdimid == nxsid) THEN
outstart(vardim) = ipss - idss + 1
ispatch(nvar) = .TRUE.
ELSE IF ( vdimid == nysid) THEN
outstart(vardim) = jpss - jdss + 1
ispatch(nvar) = .TRUE.
ELSE IF (vdimid == unlimdimid) THEN
outstart(vardim) = unlimdimlen
IF (unlimodimlen <= 0) THEN
unlimodimlen = countidx(vardim)
ELSE
IF ( unlimodimlen /= countidx(vardim)) THEN
WRITE(6,'(1x,a,/)') 'ERROR: Inconsisten size for UNLIMITED dimension.'
STOP
END IF
END IF
ELSE
outstart(vardim) = 1
END IF
narrsize = countidx(vardim)*narrsize
END DO
IF ( n > 1 .AND. (.NOT. ispatch(nvar)) ) THEN
IF (debug > 2) WRITE(6,'(9x,3a)') 'Variable ',TRIM(varname),' skipped.'
CYCLE
ELSE
IF (debug > 2) THEN
WRITE(6,'(9x,3a,I2)') &
'Processing variables - ',TRIM(varname),' with rank = ',varndims
DO vardim = 1,varndims
vdimid = vardimids(vardim)
WRITE(6,'(12x,a,2(a,I4))') diminnames(vdimid), &
', startidx = ',outstart(vardim),', size = ', countidx(vardim)
END DO
END IF
END IF
! do not have to merge, use values from the first file
! IF (.NOT. ispatch(nvar)) THEN
!
! IF (debug > 0) WRITE(6,'(9x,2a)') 'Copying variables - ',TRIM(varname)
!
!write(0,*) finid,varid,foutid
! istatus = NF_COPY_VAR(finid,varid,foutid)
! IF (istatus /= NF_NOERR) CALL handle_err(istatus)
!
! ELSE
ovarid = varoutidlists(nvar)
! IF (debug > 0) WRITE(6,'(9x,2a)') 'Writing patch of variables - ',TRIM(varname)
SELECT CASE (vartype)
CASE (NF_INT)
IF (narrsize > narrisizemax) THEN ! Allocate input array only when necessary
IF (ALLOCATED(varari)) DEALLOCATE(varari, STAT = istatus)
ALLOCATE(varari(narrsize), STAT = istatus)
narrisizemax = narrsize
END IF
istatus = NF_GET_VARA_INT(finid,varid,startidx,countidx,varari)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
istatus = nf_put_vara_INT(foutid,ovarid,outstart,countidx,varari)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
CASE (NF_FLOAT)
IF (narrsize > narrasizemax) THEN ! Allocate input array only when necessary
IF (ALLOCATED(vararr)) DEALLOCATE(vararr, STAT = istatus)
ALLOCATE(vararr(narrsize), STAT = istatus)
narrasizemax = narrsize
END IF
istatus = NF_GET_VARA_REAL(finid,varid,startidx,countidx,vararr)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
istatus = nf_put_vara_REAL(foutid,ovarid,outstart,countidx,vararr)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
CASE (NF_CHAR)
istatus = NF_GET_VARA_TEXT(finid,varid,startidx,countidx,tmpstr)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
istatus = nf_put_vara_TEXT(foutid,ovarid,outstart,countidx,TRIM(tmpstr))
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
CASE DEFAULT
WRITE(6,'(1x,a,I2)') 'ERROR: unsupported variable type = ',vartype
istatus = -4
RETURN
END SELECT
! END IF ! ispatch(nvar)
END DO
istatus = nf_close(finid) ! Close file
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
END DO
unlimdimlen = unlimdimlen + unlimodimlen ! Add # of time levels
! in output file
IF (.NOT. jointime .OR. nf == nfile) THEN
istatus = nf_close(foutid)
IF (istatus /= NF_NOERR) CALL handle_err
(istatus)
END IF
END DO
RETURN
END SUBROUTINE joinwrfncdf
!
SUBROUTINE handle_err(istat) 151
IMPLICIT NONE
INTEGER, INTENT(IN) :: istat
INCLUDE 'netcdf.inc'
IF (istat /= NF_NOERR) THEN
PRINT *, TRIM(nf_strerror(istat))
STOP 'NetCDF error!'
END IF
RETURN
END SUBROUTINE handle_err