PageRenderTime 51ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/wrfv2_fire/external/io_phdf5/wrf-phdf5.F90

http://github.com/jbeezley/wrf-fire
FORTRAN Modern | 5378 lines | 4323 code | 782 blank | 273 comment | 478 complexity | e5d9ac9f88e1018fcfbca67fdcb8f8d8 MD5 | raw file
Possible License(s): AGPL-1.0

Large files files are truncated, but you can click here to view the full file

  1. !/***************************************************************************
  2. !* The HDF5 WRF IO module was written by the the HDF Group at NCSA, the *
  3. !* National Center for Supercomputing Applications. *
  4. !* HDF Group *
  5. !* National Center for Supercomputing Applications *
  6. !* University of Illinois at Urbana-Champaign *
  7. !* 605 E. Springfield, Champaign IL 61820 *
  8. !* http://hdf.ncsa.uiuc.edu/ *
  9. !* *
  10. !* Copyright 2004 by the Board of Trustees, University of Illinois, *
  11. !* *
  12. !* Redistribution or use of this IO module, with or without modification, *
  13. !* is permitted for any purpose, including commercial purposes. *
  14. !* *
  15. !* This software is an unsupported prototype. Use at your own risk. *
  16. !* http://hdf.ncsa.uiuc.edu/apps/WRF-ROMS *
  17. !* *
  18. !* This work was funded by the MEAD expedition at the National Center *
  19. !* for Supercomputing Applications, NCSA. For more information see: *
  20. !* http://www.ncsa.uiuc.edu/expeditions/MEAD *
  21. !* *
  22. !* *
  23. !****************************************************************************/
  24. subroutine HDF5IOWRITE(DataHandle,Comm,DateStr,Length,DomainStart,DomainEnd &
  25. ,PatchStart,PatchEnd,MemoryOrder &
  26. ,WrfDType,FieldType,groupID,TimeIndex &
  27. ,DimRank ,DatasetName,XField,Status)
  28. use wrf_phdf5_data
  29. use ext_phdf5_support_routines
  30. use HDF5
  31. implicit none
  32. include 'mpif.h'
  33. include 'wrf_status_codes.h'
  34. integer ,intent(in) :: DataHandle
  35. integer ,intent(inout) :: Comm
  36. character*(*) ,intent(in) :: DateStr
  37. integer,dimension(NVarDims) ,intent(in) :: Length
  38. integer,dimension(NVarDims) ,intent(in) :: DomainStart
  39. integer,dimension(NVarDims) ,intent(in) :: DomainEnd
  40. integer,dimension(NVarDims) ,intent(in) :: PatchStart
  41. integer,dimension(NVarDims) ,intent(in) :: PatchEnd
  42. character*(*) ,intent(in) :: MemoryOrder
  43. integer ,intent(in) :: WrfDType
  44. integer(hid_t) ,intent(in) :: FieldType
  45. integer(hid_t) ,intent(in) :: groupID
  46. integer ,intent(in) :: TimeIndex
  47. integer,dimension(*) ,intent(in) :: DimRank
  48. character (*) ,intent(in) :: DatasetName
  49. integer,dimension(*) ,intent(inout) :: XField
  50. integer ,intent(out) :: Status
  51. integer(hid_t) :: dset_id
  52. integer :: NDim
  53. integer,dimension(NVarDims) :: VStart
  54. integer,dimension(NVarDims) :: VCount
  55. character (3) :: Mem0
  56. character (3) :: UCMem0
  57. type(wrf_phdf5_data_handle) ,pointer :: DH
  58. ! attribute defination
  59. integer(hid_t) :: dimaspace_id ! DimRank dataspace id
  60. integer(hid_t) :: dimattr_id ! DimRank attribute id
  61. integer(hsize_t) ,dimension(1) :: dim_space
  62. INTEGER(HID_T) :: dspace_id ! Raw Data memory Dataspace id
  63. INTEGER(HID_T) :: fspace_id ! Raw Data file Dataspace id
  64. INTEGER(HID_T) :: crp_list ! chunk identifier
  65. integer(hid_t) :: h5_atypeid ! for fieldtype,memorder attribute
  66. integer(hid_t) :: h5_aspaceid ! for fieldtype,memorder
  67. integer(hid_t) :: h5_attrid ! for fieldtype,memorder
  68. integer(hsize_t), dimension(7) :: adata_dims
  69. integer :: routine_atype
  70. integer, dimension(:),allocatable :: dimrank_data
  71. INTEGER(HSIZE_T), dimension(:),allocatable :: dims ! Dataset dimensions
  72. INTEGER(HSIZE_T), dimension(:),allocatable :: sizes ! Dataset dimensions
  73. INTEGER(HSIZE_T), dimension(:),allocatable :: chunk_dims
  74. INTEGER(HSIZE_T), dimension(:),allocatable :: hdf5_maxdims
  75. INTEGER(HSIZE_T), dimension(:),allocatable :: offset
  76. INTEGER(HSIZE_T), dimension(:),allocatable :: count
  77. INTEGER(HSIZE_T), DIMENSION(7) :: dimsfi
  78. integer :: hdf5err
  79. integer :: i,j
  80. integer(size_t) :: dsetsize
  81. ! FOR PARALLEL IO
  82. integer(hid_t) :: xfer_list
  83. logical :: no_par
  84. ! get the handle
  85. call GetDH(DataHandle,DH,Status)
  86. if(Status /= WRF_NO_ERR) then
  87. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  88. call wrf_debug ( WARN , msg)
  89. return
  90. endif
  91. ! get the rank of the dimension
  92. call GetDim(MemoryOrder,NDim,Status)
  93. if(Status /= WRF_NO_ERR) then
  94. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  95. call wrf_debug ( WARN , msg)
  96. return
  97. endif
  98. ! If patch is equal to domain, the parallel is not necessary, sequential is used.
  99. ! In this version, we haven't implemented this yet.
  100. ! We use no_par to check whether we can use compact data storage.
  101. no_par = .TRUE.
  102. do i = 1,NDim
  103. if((PatchStart(i)/=DomainStart(i)).or.(PatchEnd(i)/=DomainEnd(i))) then
  104. no_par = .FALSE.
  105. exit
  106. endif
  107. enddo
  108. ! change the different Memory Order to XYZ for patch and domain
  109. if(MemoryOrder.NE.'0') then
  110. call ExtOrder(MemoryOrder,PatchStart,Status)
  111. call ExtOrder(MemoryOrder,PatchEnd,Status)
  112. call ExtOrder(MemoryOrder,DomainStart,Status)
  113. call ExtOrder(MemoryOrder,DomainEnd,Status)
  114. endif
  115. ! allocating memory for dynamic arrays;
  116. ! since the time step is always 1, we may ignore the fourth
  117. ! dimension time; now keep it to make it consistent with sequential version
  118. allocate(dims(NDim+1))
  119. allocate(count(NDim+1))
  120. allocate(offset(NDim+1))
  121. allocate(sizes(NDim+1))
  122. ! arrange offset, count for each hyperslab
  123. dims(1:NDim) = DomainEnd(1:NDim) - DomainStart(1:NDim) + 1
  124. dims(NDim+1) = 1
  125. count(NDim+1) = 1
  126. count(1:NDim) = Length(1:NDim)
  127. offset(NDim+1) = 0
  128. offset(1:NDim) = PatchStart(1:NDim) - 1
  129. ! allocate the dataspace to write hyperslab data
  130. dimsfi = 0
  131. do i = 1, NDim + 1
  132. dimsfi(i) = count(i)
  133. enddo
  134. ! create the memory space id
  135. call h5screate_simple_f(NDim+1,count,dspace_id,hdf5err,count)
  136. if(hdf5err.lt.0) then
  137. Status = WRF_HDF5_ERR_DATASPACE
  138. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  139. call wrf_debug ( WARN , msg)
  140. deallocate(dims)
  141. deallocate(count)
  142. deallocate(offset)
  143. deallocate(sizes)
  144. return
  145. endif
  146. ! create file space
  147. call h5screate_simple_f(NDim+1,dims,fspace_id,hdf5err,dims)
  148. if(hdf5err.lt.0) then
  149. Status = WRF_HDF5_ERR_DATASPACE
  150. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  151. call wrf_debug ( WARN , msg)
  152. deallocate(dims)
  153. deallocate(count)
  154. deallocate(offset)
  155. deallocate(sizes)
  156. return
  157. endif
  158. ! compact storage when the patch is equal to the whole domain
  159. ! calculate the non-decomposed dataset size
  160. call h5tget_size_f(FieldType,dsetsize,hdf5err)
  161. if(hdf5err.lt.0) then
  162. Status = WRF_HDF5_ERR_DATATYPE
  163. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  164. call wrf_debug ( WARN , msg)
  165. deallocate(dims)
  166. deallocate(count)
  167. deallocate(offset)
  168. deallocate(sizes)
  169. return
  170. endif
  171. do i =1,NDim
  172. dsetsize = dsetsize*dims(i)
  173. enddo
  174. if(no_par.and.(dsetsize.le.CompDsetSize)) then
  175. call h5pcreate_f(H5P_DATASET_CREATE_F,crp_list,hdf5err)
  176. if(hdf5err.lt.0) then
  177. Status = WRF_HDF5_ERR_PROPERTY_LIST
  178. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  179. call wrf_debug ( WARN , msg)
  180. deallocate(dims)
  181. deallocate(count)
  182. deallocate(offset)
  183. deallocate(sizes)
  184. return
  185. endif
  186. call h5pset_layout_f(crp_list,0,hdf5err)
  187. if(hdf5err.lt.0) then
  188. Status = WRF_HDF5_ERR_PROPERTY_LIST
  189. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  190. call wrf_debug ( WARN , msg)
  191. deallocate(dims)
  192. deallocate(count)
  193. deallocate(offset)
  194. deallocate(sizes)
  195. return
  196. endif
  197. call h5dcreate_f(DH%TgroupIDs(TimeIndex),DatasetName,FieldType,fspace_id,dset_id,&
  198. hdf5err,crp_list)
  199. call h5pclose_f(crp_list,hdf5err)
  200. else
  201. call h5dcreate_f(DH%TgroupIDs(TimeIndex),DatasetName,FieldType,fspace_id,dset_id,hdf5err)
  202. endif
  203. if(hdf5err.lt.0) then
  204. Status = WRF_HDF5_ERR_DATASET_CREATE
  205. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  206. call wrf_debug ( WARN , msg)
  207. deallocate(dims)
  208. deallocate(count)
  209. deallocate(offset)
  210. deallocate(sizes)
  211. return
  212. endif
  213. ! select the correct hyperslab for file space id
  214. CALL h5sselect_hyperslab_f(fspace_id, H5S_SELECT_SET_F, offset, count &
  215. ,hdf5err)
  216. if(hdf5err.lt.0) then
  217. Status = WRF_HDF5_ERR_DATASET_GENERAL
  218. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  219. call wrf_debug ( WARN , msg)
  220. deallocate(dims)
  221. deallocate(count)
  222. deallocate(offset)
  223. deallocate(sizes)
  224. return
  225. endif
  226. ! Create property list for collective dataset write
  227. CALL h5pcreate_f(H5P_DATASET_XFER_F, xfer_list, hdf5err)
  228. if(hdf5err.lt.0) then
  229. Status = WRF_HDF5_ERR_PROPERTY_LIST
  230. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  231. call wrf_debug ( WARN , msg)
  232. deallocate(dims)
  233. deallocate(count)
  234. deallocate(offset)
  235. deallocate(sizes)
  236. return
  237. endif
  238. CALL h5pset_dxpl_mpio_f(xfer_list, H5FD_MPIO_COLLECTIVE_F&
  239. ,hdf5err)
  240. if(hdf5err.lt.0) then
  241. Status = WRF_HDF5_ERR_PROPERTY_LIST
  242. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  243. call wrf_debug ( WARN , msg)
  244. deallocate(dims)
  245. deallocate(count)
  246. deallocate(offset)
  247. deallocate(sizes)
  248. return
  249. endif
  250. ! write the data in memory space to file space
  251. CALL h5dwrite_f(dset_id,FieldType,XField,dimsfi,hdf5err,&
  252. mem_space_id =dspace_id,file_space_id =fspace_id, &
  253. xfer_prp = xfer_list)
  254. if(hdf5err.lt.0) then
  255. Status = WRF_HDF5_ERR_DATASET_WRITE
  256. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  257. call wrf_debug ( WARN , msg)
  258. deallocate(dims)
  259. deallocate(count)
  260. deallocate(offset)
  261. deallocate(sizes)
  262. return
  263. endif
  264. CALL h5pclose_f(xfer_list,hdf5err)
  265. if(hdf5err.lt.0) then
  266. Status = WRF_HDF5_ERR_PROPERTY_LIST
  267. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  268. call wrf_debug ( WARN , msg)
  269. deallocate(dims)
  270. deallocate(count)
  271. deallocate(offset)
  272. deallocate(sizes)
  273. return
  274. endif
  275. if(TimeIndex == 1) then
  276. do i =1, MaxVars
  277. if(DH%dsetids(i) == -1) then
  278. DH%dsetids(i) = dset_id
  279. DH%VarNames(i) = DataSetName
  280. exit
  281. endif
  282. enddo
  283. ! Only writing attributes when TimeIndex ==1
  284. call write_hdf5_attributes(DataHandle,MemoryOrder,WrfDType,DimRank,&
  285. NDim,dset_id,Status)
  286. endif
  287. call h5sclose_f(fspace_id,hdf5err)
  288. call h5sclose_f(dspace_id,hdf5err)
  289. if(TimeIndex /= 1) then
  290. call h5dclose_f(dset_id,hdf5err)
  291. endif
  292. if(hdf5err.lt.0) then
  293. Status = WRF_HDF5_ERR_DATASPACE
  294. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  295. call wrf_debug ( WARN , msg)
  296. deallocate(dims)
  297. deallocate(count)
  298. deallocate(offset)
  299. deallocate(sizes)
  300. return
  301. endif
  302. Status = WRF_NO_ERR
  303. return
  304. end subroutine HDF5IOWRITE
  305. subroutine ext_phdf5_ioinit(SysDepInfo, Status)
  306. use wrf_phdf5_data
  307. use HDF5
  308. implicit none
  309. include 'wrf_status_codes.h'
  310. include 'mpif.h'
  311. CHARACTER*(*), INTENT(IN) :: SysDepInfo
  312. integer, intent(out) :: status
  313. integer :: hdf5err
  314. ! set up some variables inside the derived type
  315. WrfDataHandles(1:WrfDataHandleMax)%Free = .true.
  316. ! ?
  317. WrfDataHandles(1:WrfDataHandleMax)%TimesName = 'Times'
  318. WrfDataHandles(1:WrfDataHandleMax)%DimUnlimName = 'Time'
  319. ! set up HDF5 global variables
  320. call h5open_f(hdf5err)
  321. if(hdf5err .lt.0) then
  322. Status = WRF_HDF5_ERR_CLOSE_GENERAL
  323. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  324. call wrf_debug ( WARN , msg)
  325. return
  326. endif
  327. return
  328. end subroutine ext_phdf5_ioinit
  329. subroutine ext_phdf5_ioclose( DataHandle, Status)
  330. use wrf_phdf5_data
  331. use ext_phdf5_support_routines
  332. use hdf5
  333. implicit none
  334. include 'wrf_status_codes.h'
  335. include 'mpif.h'
  336. integer ,intent(in) :: DataHandle
  337. integer ,intent(out) :: Status
  338. type(wrf_phdf5_data_handle),pointer :: DH
  339. integer :: stat
  340. integer :: NVar
  341. integer :: hdferr
  342. integer :: table_length
  343. integer :: i
  344. integer(hid_t) :: dtype_id
  345. integer :: obj_count
  346. integer(hid_t),allocatable,dimension(:) :: obj_ids
  347. character(len=100) :: buf
  348. integer(size_t) :: name_size
  349. call GetDH(DataHandle,DH,Status)
  350. if(Status /= WRF_NO_ERR) then
  351. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', 906
  352. call wrf_debug ( WARN , msg)
  353. return
  354. endif
  355. ! THE FOLLOWING section writes dimscale information to the data set,may be put into a subroutine
  356. ! check the file status, should be either open_for_read or opened_and_committed
  357. if(DH%FileStatus == WRF_FILE_NOT_OPENED) then
  358. Status = WRF_HDF5_ERR_FILE_OPEN
  359. write(msg,*) 'Warning FILE NOT OPENED in ',__FILE__,', line', __LINE__
  360. call wrf_debug ( WARN , msg)
  361. elseif(DH%FileStatus == WRF_FILE_OPENED_NOT_COMMITTED) then
  362. Status = WRF_HDF5_ERR_DRYRUN_CLOSE
  363. write(msg,*) 'Warning TRY TO CLOSE DRYRUN in ',__FILE__,', line', __LINE__
  364. call wrf_debug ( WARN , msg)
  365. elseif(DH%FileStatus == WRF_FILE_OPENED_AND_COMMITTED) then
  366. ! Handle dim. scale
  367. ! STORE "Times" as the first element of the dimensional table
  368. DH%DIMTABLE(1)%dim_name = 'Time'
  369. DH%DIMTABLE(1)%Length = DH%TimeIndex
  370. DH%DIMTABLE(1)%unlimited = 1
  371. do i =1,MaxTabDims
  372. if(DH%DIMTABLE(i)%dim_name== NO_NAME) then
  373. exit
  374. endif
  375. enddo
  376. table_length = i-1
  377. call store_table(DataHandle,table_length,Status)
  378. if(Status.ne.WRF_NO_ERR) then
  379. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  380. call wrf_debug ( WARN , msg)
  381. return
  382. endif
  383. continue
  384. elseif(DH%FileStatus == WRF_FILE_OPENED_FOR_READ) then
  385. ! call h5dclose_f(DH%TimesID,hdferr)
  386. ! if(hdferr.lt.0) then
  387. ! Status = WRF_HDF5_ERR_DATASET_CLOSE
  388. ! write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  389. ! call wrf_debug ( WARN , msg)
  390. ! return
  391. ! endif
  392. continue
  393. else
  394. Status = WRF_HDF5_ERR_BAD_FILE_STATUS
  395. write(msg,*) 'Fatal hdf5err BAD FILE STATUS in ',__FILE__,', line', __LINE__
  396. call wrf_debug ( FATAL , msg)
  397. return
  398. endif
  399. ! close HDF5 APIs
  400. do NVar = 1, MaxVars
  401. if(DH%DsetIDs(NVar) /= -1) then
  402. call h5dclose_f(DH%DsetIDs(NVar),hdferr)
  403. if(hdferr .ne. 0) then
  404. Status = WRF_HDF5_ERR_DATASET_CLOSE
  405. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  406. call wrf_debug ( WARN , msg)
  407. return
  408. endif
  409. endif
  410. enddo
  411. do i = 1, MaxTimes
  412. if(DH%TgroupIDs(i) /= -1) then
  413. call h5gclose_f(DH%TgroupIDs(i),hdferr)
  414. if(hdferr .ne. 0) then
  415. Status = WRF_HDF5_ERR_DATASET_CLOSE
  416. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  417. call wrf_debug ( WARN , msg)
  418. return
  419. endif
  420. endif
  421. enddo
  422. call h5gclose_f(DH%GroupID,hdferr)
  423. if(hdferr .ne. 0) then
  424. Status = WRF_HDF5_ERR_CLOSE_GENERAL
  425. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  426. call wrf_debug ( WARN , msg)
  427. return
  428. endif
  429. call h5gclose_f(DH%DimGroupID,hdferr)
  430. if(hdferr .ne. 0) then
  431. Status = WRF_HDF5_ERR_CLOSE_GENERAL
  432. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  433. call wrf_debug ( WARN , msg)
  434. return
  435. endif
  436. if(Status /= WRF_NO_ERR) then
  437. write(msg,*) 'HDF5 IO CLOSE error in ',__FILE__,', line', __LINE__
  438. call wrf_debug ( WARN , msg)
  439. return
  440. endif
  441. call h5fclose_f(DH%FileID,hdferr)
  442. if(hdferr .ne. 0) then
  443. Status = WRF_HDF5_ERR_CLOSE_GENERAL
  444. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  445. call wrf_debug ( WARN , msg)
  446. return
  447. endif
  448. if(Status /= WRF_NO_ERR) then
  449. write(msg,*) 'HDF5 IO CLOSE error in ',__FILE__,', line', __LINE__
  450. call wrf_debug ( WARN , msg)
  451. return
  452. endif
  453. call free_memory(DataHandle,Status)
  454. if(Status /= WRF_NO_ERR) then
  455. Status = WRF_HDF5_ERR_OTHERS
  456. write(msg,*) 'Warning Status = ',__FILE__,', line', __LINE__
  457. call wrf_debug ( WARN , msg)
  458. return
  459. endif
  460. DH%Free=.true.
  461. return
  462. end subroutine ext_phdf5_ioclose
  463. subroutine ext_phdf5_ioexit(Status)
  464. use wrf_phdf5_data
  465. use ext_phdf5_support_routines
  466. use HDF5
  467. implicit none
  468. include 'wrf_status_codes.h'
  469. include 'mpif.h'
  470. integer ,intent(out) :: Status
  471. integer :: hdf5err
  472. type(wrf_phdf5_data_handle),pointer :: DH
  473. integer :: i
  474. integer :: stat
  475. ! free memories
  476. do i=1,WrfDataHandleMax
  477. if(.not.WrfDataHandles(i)%Free) then
  478. call free_memory(i,Status)
  479. exit
  480. endif
  481. enddo
  482. if(Status /= WRF_NO_ERR) then
  483. write(msg,*) 'free resources error in ',__FILE__,', line', __LINE__
  484. call wrf_debug ( WARN , msg)
  485. return
  486. endif
  487. CALL h5close_f(hdf5err)
  488. if(hdf5err.lt.0) then
  489. Status = WRF_HDF5_ERR_CLOSE_GENERAL
  490. write(msg,*) 'Fatal DEALLOCATION ERROR in ',__FILE__,', line', __LINE__
  491. call wrf_debug ( FATAL , msg)
  492. return
  493. endif
  494. return
  495. end subroutine ext_phdf5_ioexit
  496. !! This routine will set up everything to read HDF5 files
  497. subroutine ext_phdf5_open_for_read(FileName,Comm,iocomm,SysDepInfo,DataHandle,Status)
  498. use wrf_phdf5_data
  499. use ext_phdf5_support_routines
  500. use HDF5
  501. implicit none
  502. include 'mpif.h'
  503. include 'wrf_status_codes.h'
  504. character*(*),intent(in) :: FileName
  505. integer ,intent(in) :: Comm
  506. integer ,intent(in) :: iocomm
  507. character*(*),intent(in) :: SysDepInfo
  508. integer ,intent(out) :: DataHandle
  509. type(wrf_phdf5_data_handle),pointer :: DH
  510. integer ,intent(out) :: Status
  511. integer(hid_t) :: Fileid
  512. integer(hid_t) :: tgroupid
  513. integer(hid_t) :: dsetid
  514. integer(hid_t) :: dspaceid
  515. integer(hid_t) :: dtypeid
  516. integer(hid_t) :: acc_plist
  517. integer :: nmembers
  518. integer :: submembers
  519. integer :: tmembers
  520. integer :: ObjType
  521. character(len= 256) :: ObjName
  522. character(len= 256) :: GroupName
  523. integer :: i,j
  524. integer(hsize_t), dimension(7) :: data_dims
  525. integer(hsize_t), dimension(1) :: h5dims
  526. integer(hsize_t), dimension(1) :: h5maxdims
  527. integer :: StoredDim
  528. integer :: NumVars
  529. integer :: hdf5err
  530. integer :: info,mpi_size,mpi_rank
  531. character(Len = MaxTimeSLen) :: tname
  532. character(Len = 512) :: tgroupname
  533. ! Allocating the data handle
  534. call allocHandle(DataHandle,DH,Comm,Status)
  535. if(Status /= WRF_NO_ERR) then
  536. return
  537. endif
  538. call h5pcreate_f(H5P_FILE_ACCESS_F,acc_plist,hdf5err)
  539. if(hdf5err.lt.0) then
  540. Status = WRF_HDF5_ERR_PROPERTY_LIST
  541. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  542. call wrf_debug ( WARN , msg)
  543. return
  544. endif
  545. info = MPI_INFO_NULL
  546. CALL h5pset_fapl_mpio_f(acc_plist, comm, info, hdf5err)
  547. ! call h5pset_fapl_mpiposix_f(acc_plist,comm,.false.,hdf5err)
  548. if(hdf5err .lt. 0) then
  549. Status = WRF_HDF5_ERR_PROPERTY_LIST
  550. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  551. call wrf_debug ( WARN , msg)
  552. return
  553. endif
  554. !close every objects when closing HDF5 file.
  555. call h5pset_fclose_degree_f(acc_plist,H5F_CLOSE_STRONG_F,hdf5err)
  556. if(hdf5err .lt. 0) then
  557. Status = WRF_HDF5_ERR_PROPERTY_LIST
  558. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  559. call wrf_debug ( WARN , msg)
  560. return
  561. endif
  562. ! Open the file
  563. call h5fopen_f(FileName,H5F_ACC_RDWR_F,Fileid,hdf5err &
  564. ,acc_plist)
  565. if(hdf5err.lt.0) then
  566. Status = WRF_HDF5_ERR_FILE_OPEN
  567. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  568. call wrf_debug ( WARN , msg)
  569. return
  570. endif
  571. call h5pclose_f(acc_plist,hdf5err)
  572. if(hdf5err .lt. 0) then
  573. Status = WRF_HDF5_ERR_PROPERTY_LIST
  574. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  575. call wrf_debug ( WARN , msg)
  576. return
  577. endif
  578. ! Obtain the number of group
  579. DH%FileID = Fileid
  580. call h5gn_members_f(Fileid,"/",nmembers,hdf5err)
  581. if(hdf5err.lt.0) then
  582. Status = WRF_HDF5_ERR_GROUP
  583. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  584. call wrf_debug ( WARN , msg)
  585. return
  586. endif
  587. ! Retrieve group id and dimensional group id, the index must be from 0
  588. do i = 0, nmembers - 1
  589. call h5gget_obj_info_idx_f(Fileid,"/",i,ObjName,ObjType,&
  590. hdf5err)
  591. if(hdf5err.lt.0) then
  592. Status = WRF_HDF5_ERR_GROUP
  593. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  594. call wrf_debug ( WARN , msg)
  595. return
  596. endif
  597. if(ObjName=='DIM_GROUP') then
  598. call h5gopen_f(Fileid,"/DIM_GROUP",DH%DimGroupID,hdf5err)
  599. if(hdf5err.lt.0) then
  600. Status = WRF_HDF5_ERR_GROUP
  601. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  602. call wrf_debug ( WARN , msg)
  603. return
  604. endif
  605. ! For WRF model, the first seven character must be DATASET
  606. else if(ObjName(1:7)=='DATASET')then
  607. GroupName="/"//ObjName
  608. call h5gopen_f(Fileid,GroupName,DH%GroupID,hdf5err)
  609. if(hdf5err.lt.0) then
  610. Status = WRF_HDF5_ERR_GROUP
  611. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  612. call wrf_debug ( WARN , msg)
  613. return
  614. endif
  615. call h5gn_members_f(FileID,GroupName,submembers,Status)
  616. if(hdf5err.lt.0) then
  617. Status = WRF_HDF5_ERR_GROUP
  618. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  619. call wrf_debug ( WARN , msg)
  620. return
  621. endif
  622. do j = 0, submembers -1
  623. call h5gget_obj_info_idx_f(Fileid,GroupName,j,ObjName,ObjType,hdf5err)
  624. if(hdf5err.lt.0) then
  625. Status = WRF_HDF5_ERR_GROUP
  626. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  627. call wrf_debug ( WARN , msg)
  628. return
  629. endif
  630. call numtochar(j+1,tname)
  631. tgroupname = 'TIME_STAMP_'//tname
  632. if(ObjName(1:17)==tgroupname) then
  633. call h5gopen_f(DH%GroupID,tgroupname,tgroupid,hdf5err)
  634. if(hdf5err.lt.0) then
  635. Status = WRF_HDF5_ERR_GROUP
  636. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  637. call wrf_debug ( WARN , msg)
  638. return
  639. endif
  640. call h5gn_members_f(DH%GroupID,tgroupname,tmembers,hdf5err)
  641. if(hdf5err.lt.0) then
  642. Status = WRF_HDF5_ERR_GROUP
  643. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  644. call wrf_debug ( WARN , msg)
  645. return
  646. endif
  647. call h5dopen_f(tgroupid,"Times",dsetid,hdf5err)
  648. if(hdf5err.lt.0) then
  649. Status = WRF_HDF5_ERR_DATASET_OPEN
  650. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  651. call wrf_debug ( WARN , msg)
  652. return
  653. endif
  654. call h5dget_space_f(dsetid,dspaceid,hdf5err)
  655. if(hdf5err.lt.0) then
  656. Status = WRF_HDF5_ERR_DATASPACE
  657. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  658. call wrf_debug ( WARN , msg)
  659. return
  660. endif
  661. call h5sget_simple_extent_ndims_f(dspaceid,StoredDim,hdf5err)
  662. if(hdf5err.lt.0) then
  663. Status = WRF_HDF5_ERR_DATASPACE
  664. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  665. call wrf_debug ( WARN , msg)
  666. return
  667. endif
  668. call h5sget_simple_extent_dims_f(dspaceid,h5dims,h5maxdims,hdf5err)
  669. if(hdf5err.lt.0) then
  670. Status = WRF_HDF5_ERR_DATASPACE
  671. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  672. call wrf_debug ( WARN , msg)
  673. return
  674. endif
  675. data_dims(1) = h5dims(1)
  676. call h5dget_type_f(dsetid,dtypeid,hdf5err)
  677. if(hdf5err.lt.0) then
  678. Status = WRF_HDF5_ERR_DATATYPE
  679. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  680. call wrf_debug ( WARN , msg)
  681. return
  682. endif
  683. call h5dread_f(dsetid,dtypeid,DH%Times(j+1),data_dims,hdf5err)
  684. if(hdf5err.lt.0) then
  685. Status = WRF_HDF5_ERR_DATASET_READ
  686. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  687. call wrf_debug ( WARN , msg)
  688. return
  689. endif
  690. DH%CurrentVariable = 0
  691. DH%CurrentTime = 0
  692. DH%TimeIndex = 0
  693. call h5tclose_f(dtypeid,hdf5err)
  694. call h5sclose_f(dspaceid,hdf5err)
  695. endif
  696. enddo
  697. DH%NumberTimes = submembers
  698. ! the total member of HDF5 dataset.
  699. DH%NumVars = tmembers*submembers
  700. else
  701. Status = WRF_HDF5_ERR_OTHERS
  702. endif
  703. enddo
  704. DH%FileStatus = WRF_FILE_OPENED_FOR_READ
  705. DH%FileName = FileName
  706. ! obtain dimensional scale table
  707. call retrieve_table(DataHandle,Status)
  708. if(Status /= WRF_NO_ERR) then
  709. return
  710. endif
  711. return
  712. end subroutine ext_phdf5_open_for_read
  713. subroutine ext_phdf5_inquire_opened(DataHandle,FileName,FileStatus,Status)
  714. use wrf_phdf5_data
  715. use ext_phdf5_support_routines
  716. use HDF5
  717. implicit none
  718. include 'wrf_status_codes.h'
  719. integer ,intent(in) :: DataHandle
  720. character*(*) ,intent(in) :: FileName
  721. integer ,intent(out) :: FileStatus
  722. integer ,intent(out) :: Status
  723. type(wrf_phdf5_data_handle) ,pointer :: DH
  724. call GetDH(DataHandle,DH,Status)
  725. if(Status /= WRF_NO_ERR) then
  726. FileStatus = WRF_FILE_NOT_OPENED
  727. return
  728. endif
  729. if(FileName /= DH%FileName) then
  730. FileStatus = WRF_FILE_NOT_OPENED
  731. else
  732. FileStatus = DH%FileStatus
  733. endif
  734. Status = WRF_NO_ERR
  735. return
  736. end subroutine ext_phdf5_inquire_opened
  737. subroutine ext_phdf5_inquire_filename(DataHandle,FileName,FileStatus,Status)
  738. use wrf_phdf5_data
  739. use ext_phdf5_support_routines
  740. use HDF5
  741. implicit none
  742. include 'wrf_status_codes.h'
  743. integer ,intent(in) :: DataHandle
  744. character*(*) ,intent(out) :: FileName
  745. integer ,intent(out) :: FileStatus
  746. integer ,intent(out) :: Status
  747. type(wrf_phdf5_data_handle) ,pointer :: DH
  748. ! This line is added to make sure the wrong file will not be opened
  749. FileStatus = WRF_FILE_NOT_OPENED
  750. call GetDH(DataHandle,DH,Status)
  751. if(Status /= WRF_NO_ERR) then
  752. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,',line',__LINE__
  753. call wrf_debug (WARN, msg)
  754. return
  755. endif
  756. FileName = DH%FileName
  757. FileStatus = DH%FileStatus
  758. Status = WRF_NO_ERR
  759. return
  760. end subroutine ext_phdf5_inquire_filename
  761. ! The real routine to read HDF5 files
  762. subroutine ext_phdf5_read_field(DataHandle,DateStr,Var,Field,FieldType,Comm, &
  763. IOComm, DomainDesc, MemoryOrder, Stagger, DimNames, &
  764. DomainStart,DomainEnd,MemoryStart,MemoryEnd, &
  765. PatchStart,PatchEnd,Status)
  766. use wrf_phdf5_data
  767. use ext_phdf5_support_routines
  768. use HDF5
  769. implicit none
  770. include 'wrf_status_codes.h'
  771. integer ,intent(in) :: DataHandle
  772. character*(*) ,intent(in) :: DateStr
  773. character*(*) ,intent(in) :: Var
  774. integer ,intent(out) :: Field(*)
  775. integer ,intent(in) :: FieldType
  776. integer ,intent(inout) :: Comm
  777. integer ,intent(inout) :: IOComm
  778. integer ,intent(in) :: DomainDesc
  779. character*(*) ,intent(in) :: MemoryOrder
  780. character*(*) ,intent(in) :: Stagger ! Dummy for now
  781. character*(*) , dimension (*) ,intent(in) :: DimNames
  782. integer ,dimension(*) ,intent(in) :: DomainStart, DomainEnd
  783. integer ,dimension(*) ,intent(in) :: MemoryStart, MemoryEnd
  784. integer ,dimension(*) ,intent(in) :: PatchStart, PatchEnd
  785. integer ,intent(out) :: Status
  786. type(wrf_phdf5_data_handle) ,pointer :: DH
  787. integer :: NDim
  788. integer(hid_t) :: GroupID
  789. character (VarNameLen) :: VarName
  790. integer ,dimension(NVarDims) :: Length
  791. integer ,dimension(NVarDims) :: StoredStart
  792. integer ,dimension(NVarDims) :: StoredLen
  793. integer, dimension(NVarDims) :: TemDataStart
  794. integer ,dimension(:,:,:,:) ,allocatable :: XField
  795. integer :: NVar
  796. integer :: j
  797. integer :: i1,i2,j1,j2,k1,k2
  798. integer :: x1,x2,y1,y2,z1,z2
  799. integer :: l1,l2,m1,m2,n1,n2
  800. character (VarNameLen) :: Name
  801. integer :: XType
  802. integer :: StoredDim
  803. integer :: NAtts
  804. integer :: Len
  805. integer :: stat
  806. integer :: di
  807. integer :: FType
  808. integer(hsize_t),dimension(7) :: data_dims
  809. integer(hsize_t),dimension(:) ,allocatable :: h5_dims
  810. integer(hsize_t),dimension(:) ,allocatable :: h5_maxdims
  811. integer(hsize_t),dimension(:) ,allocatable :: DataStart
  812. integer(hsize_t),dimension(:) ,allocatable :: Datacount
  813. integer(hid_t) :: tgroupid
  814. integer(hid_t) :: dsetid
  815. integer(hid_t) :: dtype_id
  816. integer(hid_t) :: dmemtype_id
  817. integer(hid_t) :: dspace_id
  818. integer(hid_t) :: memspace_id
  819. integer :: class_type
  820. integer :: TimeIndex
  821. logical :: flag
  822. integer :: hdf5err
  823. character(Len = MaxTimeSLen) :: tname
  824. character(Len = 512) :: tgroupname
  825. ! FOR PARALLEL IO
  826. integer :: mpi_rank
  827. integer(hid_t) :: xfer_list
  828. call GetDH(DataHandle,DH,Status)
  829. if(Status /= WRF_NO_ERR) then
  830. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  831. call wrf_debug ( WARN , msg)
  832. return
  833. endif
  834. if(DH%FileStatus == WRF_FILE_NOT_OPENED) then
  835. Status = WRF_HDF5_ERR_FILE_NOT_OPENED
  836. write(msg,*) 'Warning FILE NOT OPENED in ',__FILE__,', line', __LINE__
  837. call wrf_debug ( WARN , msg)
  838. elseif(DH%FileStatus == WRF_FILE_OPENED_NOT_COMMITTED) then
  839. Status = WRF_HDF5_ERR_DRYRUN_READ
  840. write(msg,*) 'Warning DRYRUN READ in ',__FILE__,', line', __LINE__
  841. call wrf_debug ( WARN , msg)
  842. elseif(DH%FileStatus == WRF_FILE_OPENED_AND_COMMITTED) then
  843. Status = WRF_HDF5_ERR_READ_WONLY_FILE
  844. write(msg,*) 'Warning READ WRITE ONLY FILE in ',__FILE__,', line', __LINE__
  845. call wrf_debug ( WARN , msg)
  846. elseif(DH%FileStatus == WRF_FILE_OPENED_FOR_READ) then
  847. ! obtain TimeIndex
  848. call GetDataTimeIndex('read',DataHandle,DateStr,TimeIndex,Status)
  849. ! obtain the absolute name of the group where the dataset is located
  850. call numtochar(TimeIndex,tname)
  851. tgroupname = 'TIME_STAMP_'//tname
  852. call h5gopen_f(DH%GroupID,tgroupname,tgroupid,hdf5err)
  853. if(hdf5err.lt.0) then
  854. Status = WRF_HDF5_ERR_GROUP
  855. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  856. call wrf_debug ( WARN , msg)
  857. return
  858. endif
  859. call h5dopen_f(tgroupid,Var,dsetid,hdf5err)
  860. if(hdf5err.lt.0) then
  861. Status = WRF_HDF5_ERR_DATASET_OPEN
  862. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  863. call wrf_debug ( WARN , msg)
  864. return
  865. endif
  866. ! Obtain the memory datatype
  867. select case(FieldType)
  868. case (WRF_REAL)
  869. dmemtype_id = H5T_NATIVE_REAL
  870. case (WRF_DOUBLE)
  871. dmemtype_id = H5T_NATIVE_DOUBLE
  872. case (WRF_INTEGER)
  873. dmemtype_id = H5T_NATIVE_INTEGER
  874. case (WRF_LOGICAL)
  875. dmemtype_id = DH%EnumID
  876. case default
  877. Status = WRF_HDF5_ERR_DATA_TYPE_NOTFOUND
  878. write(msg,*) 'Warning BAD Memory Data type in ',__FILE__,',line',__LINE__
  879. call wrf_debug(WARN,msg)
  880. return
  881. end select
  882. ! Obtain the datatype
  883. call h5dget_type_f(dsetid,dtype_id,hdf5err)
  884. if(hdf5err.lt.0) then
  885. Status = WRF_HDF5_ERR_DATATYPE
  886. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  887. call wrf_debug ( WARN , msg)
  888. return
  889. endif
  890. ! double check whether the Fieldtype is the type of the dataset
  891. ! we may do the force coercion between real and double
  892. call h5tget_class_f(dtype_id,class_type,hdf5err)
  893. if(hdf5err.lt.0) then
  894. Status = WRF_HDF5_ERR_DATATYPE
  895. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  896. call wrf_debug ( WARN , msg)
  897. return
  898. endif
  899. if( (FieldType == WRF_REAL .OR. FieldType == WRF_DOUBLE) ) then
  900. if ( class_type /= H5T_FLOAT_F) then
  901. Status = WRF_HDF5_ERR_TYPE_MISMATCH
  902. write(msg,*) 'Warning TYPE MISMATCH in ',__FILE__,', line', __LINE__
  903. call wrf_debug ( WARN , msg)
  904. return
  905. endif
  906. else if(FieldType == WRF_CHARACTER) then
  907. if(class_type /= H5T_STRING_F) then
  908. Status = WRF_HDF5_ERR_TYPE_MISMATCH
  909. write(msg,*) 'Warning TYPE MISMATCH in ',__FILE__,', line', __LINE__
  910. call wrf_debug ( WARN , msg)
  911. return
  912. endif
  913. else if(FieldType == WRF_INTEGER) then
  914. if(class_type /= H5T_INTEGER_F) then
  915. Status = WRF_HDF5_ERR_TYPE_MISMATCH
  916. write(msg,*) 'Warning TYPE MISMATCH in ',__FILE__,', line', __LINE__
  917. call wrf_debug ( WARN , msg)
  918. return
  919. endif
  920. else if(FieldType == WRF_LOGICAL) then
  921. if(class_type /= H5T_ENUM_F) then
  922. Status = WRF_HDF5_ERR_TYPE_MISMATCH
  923. write(msg,*) 'Warning TYPE MISMATCH in ',__FILE__,', line', __LINE__
  924. call wrf_debug ( WARN , msg)
  925. return
  926. endif
  927. call h5tequal_f(dtype_id,DH%EnumID,flag,hdf5err)
  928. if(hdf5err.lt.0) then
  929. Status = WRF_HDF5_ERR_DATASET_OPEN
  930. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  931. call wrf_debug ( WARN , msg)
  932. return
  933. endif
  934. if(flag .EQV. .FALSE.) then
  935. Status = WRF_HDF5_ERR_TYPE_MISMATCH
  936. write(msg,*) 'Warning TYPE MISMATCH in ',__FILE__,', line', __LINE__
  937. call wrf_debug ( WARN , msg)
  938. return
  939. endif
  940. else
  941. Status = WRF_HDF5_ERR_BAD_DATA_TYPE
  942. write(msg,*)'Fatal Non-WRF supported TYPE in ',__FILE__,', line',__LINE__
  943. call wrf_debug(FATAL, msg)
  944. return
  945. endif
  946. ! Obtain the dataspace, check whether the dataspace is within the range
  947. ! transpose the memory order to the disk order
  948. call h5dget_space_f(dsetid,dspace_id,hdf5err)
  949. if(hdf5err.lt.0) then
  950. Status = WRF_HDF5_ERR_DATASPACE
  951. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  952. call wrf_debug ( WARN , msg)
  953. return
  954. endif
  955. call GetDim(MemoryOrder,NDim,Status)
  956. Length(1:NDim) = PatchEnd(1:NDim)-PatchStart(1:NDim)+1
  957. call ExtOrder(MemoryOrder,Length,Status)
  958. ! Obtain the rank of the dimension
  959. call h5sget_simple_extent_ndims_f(dspace_id,StoredDim,hdf5err)
  960. if(hdf5err.lt.0) then
  961. Status = WRF_HDF5_ERR_DATASPACE
  962. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  963. call wrf_debug ( WARN , msg)
  964. return
  965. endif
  966. ! From NetCDF implementation, only do error handling
  967. if((NDim+1) /= StoredDim) then
  968. Status = WRF_HDF5_ERR_BAD_VARIABLE_DIM
  969. write(msg,*) 'Fatal error BAD VARIABLE DIMENSION in ',__FILE__,', line', __LINE__
  970. call wrf_debug ( FATAL , msg)
  971. return
  972. endif
  973. allocate(h5_dims(StoredDim))
  974. allocate(h5_maxdims(StoredDim))
  975. allocate(DataStart(StoredDim))
  976. allocate(DataCount(StoredDim))
  977. call h5sget_simple_extent_dims_f(dspace_id,h5_dims,h5_maxdims,hdf5err)
  978. if(hdf5err.lt.0) then
  979. Status = WRF_HDF5_ERR_DATASPACE
  980. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  981. call wrf_debug ( WARN , msg)
  982. return
  983. endif
  984. ! This part of code needs to be adjusted, currently use NetCDF convention
  985. do j = 1, NDim
  986. if(Length(j) > h5_dims(j)) then
  987. Status = WRF_HDF5_ERR_READ_PAST_EOF
  988. write(msg,*) 'Warning READ PAST EOF in ',__FILE__,', line', __LINE__
  989. call wrf_debug ( WARN , msg)
  990. return
  991. elseif(Length(j) <= 0) then
  992. Status = WRF_HDF5_ERR_ZERO_LENGTH_READ
  993. write(msg,*) 'Warning ZERO LENGTH READ in ',__FILE__,', line', __LINE__
  994. call wrf_debug ( WARN , msg)
  995. return
  996. endif
  997. enddo
  998. ! create memspace_id
  999. data_dims(1:NDim) = Length(1:NDim)
  1000. data_dims(NDim+1) = 1
  1001. call h5screate_simple_f(NDim+1,data_dims,memspace_id,hdf5err)
  1002. if(hdf5err.lt.0) then
  1003. Status = WRF_HDF5_ERR_DATASPACE
  1004. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  1005. call wrf_debug ( WARN , msg)
  1006. return
  1007. endif
  1008. ! DataStart can start from PatchStart.
  1009. TEMDataStart(1:NDim) = PatchStart(1:NDim)-1
  1010. if(MemoryOrder.NE.'0') then
  1011. call ExtOrder(MemoryOrder,TEMDataStart,Status)
  1012. endif
  1013. DataStart(1:NDim) = TEMDataStart(1:NDim)
  1014. DataStart(NDim+1) = 0
  1015. DataCount(1:NDim) = Length(1:NDim)
  1016. DataCount(NDim+1) = 1
  1017. ! transpose the data XField to Field
  1018. call GetIndices(NDim,MemoryStart,MemoryEnd,l1,l2,m1,m2,n1,n2)
  1019. StoredStart = 1
  1020. StoredLen(1:NDim) = Length(1:NDim)
  1021. ! the dimensional information inside the disk may be greater than
  1022. ! the dimension(PatchEnd-PatchStart); here we can speed up
  1023. ! the performance by using hyperslab selection
  1024. call GetIndices(NDim,StoredStart,StoredLen,x1,x2,y1,y2,z1,z2)
  1025. call GetIndices(NDim,PatchStart,PatchEnd,i1,i2,j1,j2,k1,k2)
  1026. ! di is for double type data
  1027. di = 1
  1028. if(FieldType == WRF_DOUBLE) di = 2
  1029. allocate(XField(di,x1:x2,y1:y2,z1:z2), STAT=stat)
  1030. ! use hyperslab to only read this current timestamp
  1031. call h5sselect_hyperslab_f(dspace_id,H5S_SELECT_SET_F, &
  1032. DataStart,DataCount,hdf5err)
  1033. if(hdf5err.lt.0) then
  1034. Status = WRF_HDF5_ERR_DATASET_GENERAL
  1035. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  1036. call wrf_debug ( WARN , msg)
  1037. return
  1038. endif
  1039. ! read the data in this time stamp
  1040. call h5dread_f(dsetid,dmemtype_id,XField,data_dims,hdf5err, &
  1041. memspace_id,dspace_id,H5P_DEFAULT_F)
  1042. if(hdf5err.lt.0) then
  1043. Status = WRF_HDF5_ERR_DATASET_READ
  1044. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  1045. call wrf_debug ( WARN , msg)
  1046. return
  1047. endif
  1048. call transpose_hdf5('read',MemoryOrder,di, Field,l1,l2,m1,m2,n1,n2 &
  1049. ,XField,x1,x2,y1,y2,z1,z2 &
  1050. ,i1,i2,j1,j2,k1,k2 )
  1051. deallocate(XField, STAT=stat)
  1052. if(stat/= 0) then
  1053. Status = WRF_HDF5_ERR_DEALLOCATION
  1054. write(msg,*) 'Fatal DEALLOCATION ERROR in ',__FILE__,', line', __LINE__
  1055. call wrf_debug ( FATAL , msg)
  1056. return
  1057. endif
  1058. call h5dclose_f(dsetid,hdf5err)
  1059. if(hdf5err.lt.0) then
  1060. Status = WRF_HDF5_ERR_DATASET_CLOSE
  1061. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  1062. call wrf_debug ( WARN , msg)
  1063. return
  1064. endif
  1065. deallocate(h5_dims)
  1066. deallocate(h5_maxdims)
  1067. deallocate(DataStart)
  1068. deallocate(DataCount)
  1069. else
  1070. Status = WRF_HDF5_ERR_BAD_FILE_STATUS
  1071. write(msg,*) 'Fatal error BAD FILE STATUS in ',__FILE__,', line', __LINE__
  1072. call wrf_debug ( FATAL , msg)
  1073. endif
  1074. DH%first_operation = .FALSE.
  1075. return
  1076. end subroutine ext_phdf5_read_field
  1077. !! This routine essentially sets up everything to write HDF5 files
  1078. SUBROUTINE ext_phdf5_open_for_write_begin(FileName,Comm,IOComm,SysDepInfo,DataHandle,Status)
  1079. use wrf_phdf5_data
  1080. use HDF5
  1081. use ext_phdf5_support_routines
  1082. implicit none
  1083. include 'mpif.h'
  1084. include 'wrf_status_codes.h'
  1085. character*(*) ,intent(in) :: FileName
  1086. integer ,intent(in) :: Comm
  1087. integer ,intent(in) :: IOComm
  1088. character*(*) ,intent(in) :: SysDepInfo
  1089. integer ,intent(out) :: DataHandle
  1090. integer ,intent(out) :: Status
  1091. type(wrf_phdf5_data_handle),pointer :: DH
  1092. integer(hid_t) :: file5_id
  1093. integer(hid_t) :: g_id
  1094. integer(hid_t) :: gdim_id
  1095. integer :: hdferr
  1096. integer :: i
  1097. integer :: stat
  1098. character (7) :: Buffer
  1099. integer :: VDimIDs(2)
  1100. character(Len = 512) :: groupname
  1101. ! For parallel IO
  1102. integer(hid_t) :: plist_id
  1103. integer :: hdf5_comm,info,mpi_size,mpi_rank
  1104. call allocHandle(DataHandle,DH,Comm,Status)
  1105. if(Status /= WRF_NO_ERR) then
  1106. write(msg,*) 'Fatal ALLOCATION ERROR in ',__FILE__,', line', __LINE__
  1107. call wrf_debug ( FATAL , msg)
  1108. return
  1109. endif
  1110. DH%TimeIndex = 0
  1111. DH%Times = ZeroDate
  1112. CALL h5pcreate_f(H5P_FILE_ACCESS_F, plist_id, hdferr)
  1113. if(hdferr .lt. 0) then
  1114. Status = WRF_HDF5_ERR_PROPERTY_LIST
  1115. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  1116. call wrf_debug ( WARN , msg)
  1117. return
  1118. endif
  1119. info = MPI_INFO_NULL
  1120. CALL h5pset_fapl_mpio_f(plist_id, comm, info, hdferr)
  1121. if(hdferr .lt. 0) then
  1122. Status = WRF_HDF5_ERR_PROPERTY_LIST
  1123. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  1124. call wrf_debug ( WARN , msg)
  1125. return
  1126. endif
  1127. call h5fcreate_f(FileName,H5F_ACC_TRUNC_F,file5_id,hdferr &
  1128. ,access_prp = plist_id)
  1129. if(hdferr .lt. 0) then
  1130. Status = WRF_HDF5_ERR_FILE_CREATE
  1131. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  1132. call wrf_debug ( WARN , msg)
  1133. return
  1134. endif
  1135. call h5pclose_f(plist_id,hdferr)
  1136. if(hdferr .lt. 0) then
  1137. Status = WRF_HDF5_ERR_PROPERTY_LIST
  1138. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  1139. call wrf_debug ( WARN , msg)
  1140. return
  1141. endif
  1142. DH%FileStatus = WRF_FILE_OPENED_NOT_COMMITTED
  1143. DH%FileName = FileName
  1144. ! should add a check to see whether the file opened has been used by previous handles
  1145. DH%VarNames (1:MaxVars) = NO_NAME
  1146. DH%MDVarNames(1:MaxVars) = NO_NAME
  1147. ! group name information is stored at SysDepInfo
  1148. groupname = "/"//SysDepInfo
  1149. ! write(*,*) "groupname ",groupname
  1150. call h5gcreate_f(file5_id,groupname,g_id,hdferr)
  1151. if(hdferr .lt. 0) then
  1152. Status = WRF_HDF5_ERR_GROUP
  1153. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  1154. call wrf_debug ( WARN , msg)
  1155. return
  1156. endif
  1157. ! create dimensional group id
  1158. call h5gcreate_f(file5_id,"/DIM_GROUP",gdim_id,hdferr)
  1159. if(hdferr .lt. 0) then
  1160. Status = WRF_HDF5_ERR_GROUP
  1161. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  1162. call wrf_debug ( WARN , msg)
  1163. return
  1164. endif
  1165. DH%FileID = file5_id
  1166. DH%GroupID = g_id
  1167. DH%DIMGroupID = gdim_id
  1168. return
  1169. end subroutine ext_phdf5_open_for_write_begin
  1170. ! HDF5 doesnot need this stage, basically this routine
  1171. ! just updates the File status.
  1172. SUBROUTINE ext_phdf5_open_for_write_commit(DataHandle, Status)
  1173. use wrf_phdf5_data
  1174. use ext_phdf5_support_routines
  1175. use HDF5
  1176. implicit none
  1177. include 'wrf_status_codes.h'
  1178. integer ,intent(in) :: DataHandle
  1179. integer ,intent(out) :: Status
  1180. type(wrf_phdf5_data_handle),pointer :: DH
  1181. integer(hid_t) :: enum_type
  1182. integer :: i
  1183. integer :: stat
  1184. call GetDH(DataHandle,DH,Status)
  1185. if(Status /= WRF_NO_ERR) then
  1186. write(msg,*) 'Warning Status = ',Status,' in ',__FILE__,', line', __LINE__
  1187. call wrf_debug ( WARN , msg)
  1188. return
  1189. endif
  1190. DH%FileStatus = WRF_FILE_OPENED_AND_COMMITTED
  1191. DH%first_operation = .TRUE.
  1192. return
  1193. end subroutine ext_phdf5_open_for_write_commit
  1194. ! The real routine to write HDF5 file
  1195. subroutine ext_phdf5_write_field(DataHandle,DateStr,Var,Field,FieldType,&
  1196. Comm,IOComm,DomainDesc,MemoryOrder, &
  1197. Stagger,DimNames,DomainStart,DomainEnd,&
  1198. MemoryStart,MemoryEnd,PatchStart,PatchEnd,&
  1199. Status)
  1200. use wrf_phdf5_data
  1201. use ext_phdf5_support_routines
  1202. USE HDF5 ! This module contains all necessary modules
  1203. implicit none
  1204. include 'wrf_status_codes.h'
  1205. integer ,intent(in) :: DataHandle
  1206. character*(*) ,intent(in) :: DateStr
  1207. character*(*) ,intent(in) :: Var
  1208. integer ,intent(inout) :: Field(*)
  1209. integer ,intent(in) :: FieldType
  1210. integer ,intent(inout) :: Comm
  1211. integer ,intent(inout) :: IOComm
  1212. integer ,intent(in) :: DomainDesc
  1213. character*(*) ,intent(in) :: MemoryOrder
  1214. character*(*) ,intent(in) :: Stagger ! Dummy for now
  1215. character*(*) , dimension (*) ,intent(in) :: DimNames
  1216. integer ,dimension(*) ,intent(in) :: DomainStart, DomainEnd
  1217. integer ,dimension(*) ,intent(in) :: MemoryStart, MemoryEnd
  1218. integer ,dimension(*)

Large files files are truncated, but you can click here to view the full file