hdf5.F90       coverage:  66.67 %func     41.86 %block


     1) module HDF5_module
     2) 
     3)   use Logging_module
     4) 
     5)   use PFLOTRAN_Constants_module
     6) 
     7)   implicit none
     8) 
     9) #include "petsc/finclude/petscsys.h"
    10) 
    11)   private
    12)   
    13)   PetscErrorCode :: ierr
    14) 
    15)   PetscBool, public :: trick_hdf5 = PETSC_FALSE
    16) 
    17) #if defined(SCORPIO)
    18)   include "scorpiof.h"  
    19) #endif
    20) 
    21) #if defined(PETSC_HAVE_HDF5)
    22)   PetscMPIInt :: hdf5_err
    23)   PetscMPIInt :: io_rank
    24)       
    25) ! 64-bit stuff
    26) #ifdef PETSC_USE_64BIT_INDICES
    27) #define HDF_NATIVE_INTEGER H5T_NATIVE_INTEGER
    28) #else
    29) #define HDF_NATIVE_INTEGER H5T_NATIVE_INTEGER
    30) #endif
    31) 
    32) #endif
    33)       
    34) #if defined(PETSC_HAVE_HDF5)
    35)   public :: HDF5MapLocalToNaturalIndices, &
    36)             HDF5ReadIntegerArray, &
    37)             HDF5ReadRealArray, &
    38)             HDF5WriteStructDataSetFromVec, &
    39)             HDF5WriteDataSetFromVec, &
    40)             HDF5ReadDataSetInVec, &
    41)             HDF5WriteStructuredDataSet, &
    42)             HDF5ReadRegionFromFile, &       
    43)             HDF5ReadUnstructuredGridRegionFromFile, &
    44)             HDF5ReadCellIndexedIntegerArray, & 
    45)             HDF5ReadCellIndexedRealArray, &
    46)             HDF5QueryRegionDefinition, &
    47)             HDF5ReadRegionDefinedByVertex
    48) #else
    49)   public :: HDF5ReadRegionFromFile, &
    50)             HDF5ReadUnstructuredGridRegionFromFile, &
    51)             HDF5ReadCellIndexedIntegerArray, &
    52)             HDF5ReadCellIndexedRealArray, &
    53)             HDF5QueryRegionDefinition, &
    54)             HDF5ReadRegionDefinedByVertex
    55) #endif            
    56) 
    57) contains
    58) 
    59) #if defined(PETSC_HAVE_HDF5)
    60) 
    61) ! ************************************************************************** !
    62) 
    63) subroutine HDF5MapLocalToNaturalIndices(grid,option,file_id, &
    64)                                         dataset_name,dataset_size, &
    65)                                         indices,num_indices)
    66)   ! 
    67)   ! Set up indices array that maps local cells to
    68)   ! entries in HDF5 grid cell vectors
    69)   ! 
    70)   ! Author: Glenn Hammond
    71)   ! Date: 09/21/07
    72)   ! 
    73) 
    74)   use hdf5
    75)   
    76)   use Option_module
    77)   use Grid_module
    78)   use HDF5_Aux_module
    79)   use Utility_module, only : DeallocateArray
    80)   
    81)   implicit none
    82) 
    83) #if defined(SCORPIO)
    84) 
    85) ! Using Parallel IO library
    86)  
    87)   type(grid_type) :: grid
    88)   type(option_type) :: option
    89)   character(len=MAXWORDLENGTH) :: dataset_name
    90)   PetscInt :: dataset_size
    91)   integer :: file_id
    92)   PetscInt, pointer :: indices(:)
    93)   PetscInt :: num_indices
    94) 
    95)   integer :: file_space_id
    96)   integer :: memory_space_id
    97)   integer :: data_set_id
    98)   integer :: prop_id
    99)   integer :: dims(3)
   100)   integer :: offset(3), length(3), stride(3)
   101)   PetscMPIInt :: rank_mpi
   102)   PetscInt :: local_ghosted_id, local_id, natural_id
   103)   PetscInt :: index_count
   104)   PetscInt :: cell_count
   105)   integer :: num_cells_in_file
   106)   PetscInt :: temp_int, i
   107)   PetscMPIInt :: int_mpi
   108)   
   109)   ! Have to use 'integer' to satisfy HDF5.  PetscMPIInt works, but only if
   110)   ! it is defined as an integer
   111)   integer, allocatable :: cell_ids_i4(:)
   112)   PetscInt, allocatable :: temp(:)
   113)   
   114)   PetscInt :: read_block_size
   115)   PetscInt :: indices_array_size
   116) 
   117)   call PetscLogEventBegin(logging%event_map_indices_hdf5,ierr);CHKERRQ(ierr)
   118) 
   119)   read_block_size = HDF5_READ_BUFFER_SIZE
   120) 
   121)   call fscorpio_get_dataset_size( num_cells_in_file, file_id, dataset_name, &
   122)           option%ioread_group_id, ierr)
   123)   !>>>> get size of dataset call h5sget_simple_extent_npoints_f(file_space_id,num_cells_in_file,hdf5_err)
   124)   !if (dataset_size > 0 .and. num_cells_in_file /= dataset_size) then
   125)   !  write(option%io_buffer, &
   126)   !        '(a," data space dimension (",i9,") does not match the dimension",&
   127)   !         &" of the domain (",i9,").")') trim(dataset_name), &
   128)   !         num_cells_in_file, dataset_size
   129)   !  call printErrMsg(option)    
   130)   !endif
   131)   !
   132)   allocate(cell_ids_i4(read_block_size))
   133)   if (num_indices > 0) then
   134)     allocate(indices(num_indices))
   135)   else
   136)     indices_array_size = read_block_size
   137)     allocate(indices(indices_array_size))
   138)   endif
   139)   
   140)   rank_mpi = 1 ! This is in fact number of dimensions
   141)   offset = 0
   142)   length = 0
   143)   stride = 1
   144)   
   145)   dims = 0
   146)   cell_count = 0
   147)   index_count = 0
   148)   memory_space_id = -1
   149)   do
   150)     if (cell_count >= num_cells_in_file) exit
   151)     temp_int = num_cells_in_file-cell_count
   152)     temp_int = min(temp_int,read_block_size)
   153)     if (dims(1) /= temp_int) then
   154)       dims(1) = temp_int
   155)     endif
   156)     offset(1) = cell_count
   157)     length(1) = dims(1)
   158) 
   159)     call PetscLogEventBegin(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
   160) 
   161)     ! rank_mpi = 1 ! This is in fact number of dimensions
   162)     call fscorpio_read_same_sub_dataset(cell_ids_i4, SCORPIO_INTEGER, rank_mpi, dims, & 
   163)             offset, file_id, dataset_name, option%ioread_group_id, ierr)
   164) 
   165)     !call h5dread_f(data_set_id,HDF_NATIVE_INTEGER,cell_ids_i4,dims,hdf5_err, &
   166)                     !memory_space_id,file_space_id,prop_id)                     
   167)     call PetscLogEventEnd(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
   168)         
   169)     call PetscLogEventBegin(logging%event_hash_map,ierr);CHKERRQ(ierr)
   170) 
   171)     do i=1,dims(1)
   172)       cell_count = cell_count + 1
   173)       natural_id = cell_ids_i4(i)
   174)       local_ghosted_id = GridGetLocalGhostedIdFromHash(grid,natural_id)
   175)       if (local_ghosted_id > 0) then
   176)         local_id = grid%nG2L(local_ghosted_id)
   177)         if (local_id > 0) then
   178)           index_count = index_count + 1
   179)           if (index_count > indices_array_size .and. num_indices <= 0) then
   180)             !reallocate if array grows too large and num_indices <= 0
   181)             allocate(temp(index_count))
   182)             temp(1:index_count) = indices(1:index_count)
   183)             call DeallocateArray(indices)
   184)             indices_array_size = 2*indices_array_size
   185)             allocate(indices(indices_array_size))
   186)             indices = 0
   187)             indices(1:index_count) = temp(1:index_count)
   188)             deallocate(temp)
   189)           endif
   190)           indices(index_count) = cell_count
   191)         endif
   192)       endif
   193)     enddo
   194)   enddo
   195)   
   196)   call PetscLogEventEnd(logging%event_hash_map,ierr);CHKERRQ(ierr)
   197) 
   198)   deallocate(cell_ids_i4)
   199)   
   200)   if (num_indices > 0 .and. index_count /= num_indices) then
   201)     write(option%io_buffer, &
   202)           '("Number of indices read (",i9,") does not match the number",&
   203)            &" of indices requested (",i9,").")') &
   204)            index_count, num_indices
   205)     call printErrMsg(option)        
   206)   endif
   207)   
   208)   if (index_count > 0 .and. index_count < indices_array_size .and. &
   209)       num_indices <= 0) then
   210)     ! resize to index count
   211)     allocate(temp(index_count))
   212)     temp(1:index_count) = indices(1:index_count)
   213)     call DeallocateArray(indices)
   214)     allocate(indices(index_count))
   215)     indices(1:index_count) = temp(1:index_count)
   216)     deallocate(temp)
   217)   else
   218)     call DeallocateArray(indices)
   219)   endif
   220)   
   221)   if (num_indices <= 0) num_indices = index_count
   222) 
   223)   call PetscLogEventEnd(logging%event_map_indices_hdf5,ierr);CHKERRQ(ierr)
   224) ! End of ParallelIO library
   225) 
   226) #else 
   227) 
   228) ! Default & Glenn's HDF5 Broadcast Mechanism 
   229)  
   230)   type(grid_type) :: grid
   231)   type(option_type) :: option
   232)   character(len=MAXWORDLENGTH) :: dataset_name
   233)   character(len=MAXSTRINGLENGTH) :: string
   234)   PetscInt :: dataset_size
   235)   integer(HID_T) :: file_id
   236)   PetscInt, pointer :: indices(:)
   237)   PetscInt :: num_indices
   238) 
   239)   integer(HID_T) :: file_space_id
   240)   integer(HID_T) :: memory_space_id
   241)   integer(HID_T) :: data_set_id
   242)   integer(HID_T) :: prop_id
   243)   integer(HSIZE_T) :: dims(3)
   244)   integer(HSIZE_T) :: offset(3), length(3), stride(3)
   245)   PetscMPIInt :: rank_mpi
   246)   PetscInt :: local_ghosted_id, local_id, natural_id
   247)   PetscInt :: index_count
   248)   PetscInt :: cell_count
   249)   integer(HSIZE_T) :: num_cells_in_file
   250)   integer(SIZE_T) :: string_size
   251)   PetscInt :: temp_int, i
   252)   PetscMPIInt :: int_mpi
   253)   
   254)   ! Have to use 'integer' to satisfy HDF5.  PetscMPIInt works, but only if
   255)   ! it is defined as an integer
   256)   integer, allocatable :: cell_ids_i4(:)
   257)   PetscInt, allocatable :: temp(:)
   258)   
   259)   PetscInt :: read_block_size
   260)   PetscInt :: indices_array_size
   261) 
   262)   call PetscLogEventBegin(logging%event_map_indices_hdf5,ierr);CHKERRQ(ierr)
   263) 
   264)   read_block_size = HDF5_READ_BUFFER_SIZE
   265)   call h5dopen_f(file_id,dataset_name,data_set_id,hdf5_err)
   266)   if (hdf5_err /= 0) then
   267)     string_size = MAXSTRINGLENGTH
   268)     call h5fget_name_f(file_id,string,string_size,hdf5_err)
   269)     option%io_buffer = 'HDF5 dataset "' // trim(dataset_name) // '" not found &
   270)       &in file "' // trim(string) // '".'
   271)     call printErrMsg(option)
   272)   endif
   273)   call h5dget_space_f(data_set_id,file_space_id,hdf5_err)
   274)   ! should be a rank=1 data space
   275)   call h5sget_simple_extent_npoints_f(file_space_id,num_cells_in_file,hdf5_err)
   276)   if (dataset_size > 0 .and. num_cells_in_file /= dataset_size) then
   277)     write(option%io_buffer, &
   278)           '(a," data space dimension (",i9,") does not match the dimension",&
   279)            &" of the domain (",i9,").")') trim(dataset_name), &
   280)            num_cells_in_file, dataset_size
   281)     call printErrMsg(option)    
   282)   endif
   283)   
   284)   allocate(cell_ids_i4(read_block_size))
   285)   if (num_indices > 0) then
   286)     allocate(indices(num_indices))
   287)   else
   288)     indices_array_size = read_block_size
   289)     allocate(indices(indices_array_size))
   290)   endif
   291)   
   292)   rank_mpi = 1
   293)   offset = 0
   294)   length = 0
   295)   stride = 1
   296)   
   297)   call h5pcreate_f(H5P_DATASET_XFER_F,prop_id,hdf5_err)
   298) #ifndef SERIAL_HDF5
   299)   call h5pset_dxpl_mpio_f(prop_id,H5FD_MPIO_INDEPENDENT_F,hdf5_err)
   300) #endif
   301)   
   302)   dims = 0
   303)   cell_count = 0
   304)   index_count = 0
   305)   memory_space_id = -1
   306)   do
   307)     if (cell_count >= num_cells_in_file) exit
   308)     temp_int = int(num_cells_in_file)-cell_count
   309)     temp_int = min(temp_int,read_block_size)
   310)     if (dims(1) /= temp_int) then
   311)       if (memory_space_id > -1) call h5sclose_f(memory_space_id,hdf5_err)
   312)       dims(1) = temp_int
   313)       call h5screate_simple_f(rank_mpi,dims,memory_space_id,hdf5_err,dims)
   314)     endif
   315)     ! offset is zero-based
   316)     offset(1) = cell_count
   317)     length(1) = dims(1)
   318)     call h5sselect_hyperslab_f(file_space_id, H5S_SELECT_SET_F,offset,length, &
   319)                                hdf5_err,stride,stride) 
   320) #ifdef HDF5_BROADCAST
   321)     if (option%myrank == option%io_rank) then                           
   322) #endif
   323)       call PetscLogEventBegin(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
   324)       call h5dread_f(data_set_id,HDF_NATIVE_INTEGER,cell_ids_i4,dims,hdf5_err, &
   325)                      memory_space_id,file_space_id,prop_id)                     
   326)       call PetscLogEventEnd(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
   327) #ifdef HDF5_BROADCAST
   328)     endif
   329)     if (option%mycommsize > 1) then
   330)       int_mpi = dims(1)
   331)       call MPI_Bcast(cell_ids_i4,int_mpi,MPI_INTEGER,option%io_rank, &
   332)                      option%mycomm,ierr)
   333)     endif
   334) #endif
   335)         
   336)     call PetscLogEventBegin(logging%event_hash_map,ierr);CHKERRQ(ierr)
   337) 
   338)     do i=1,int(dims(1))
   339)       cell_count = cell_count + 1
   340)       natural_id = cell_ids_i4(i)
   341)       local_ghosted_id = GridGetLocalGhostedIdFromHash(grid,natural_id)
   342)       if (local_ghosted_id > 0) then
   343)         local_id = grid%nG2L(local_ghosted_id)
   344)         if (local_id > 0) then
   345)           index_count = index_count + 1
   346)           if (index_count > indices_array_size .and. num_indices <= 0) then
   347)             !reallocate if array grows too large and num_indices <= 0
   348)             allocate(temp(index_count))
   349)             temp(1:index_count) = indices(1:index_count)
   350)             call DeallocateArray(indices)
   351)             indices_array_size = 2*indices_array_size
   352)             allocate(indices(indices_array_size))
   353)             indices = 0
   354)             indices(1:index_count) = temp(1:index_count)
   355)             deallocate(temp)
   356)           endif
   357)           indices(index_count) = cell_count
   358)         endif
   359)       endif
   360)     enddo
   361)   enddo
   362)   
   363)   call PetscLogEventEnd(logging%event_hash_map,ierr);CHKERRQ(ierr)
   364) 
   365)   deallocate(cell_ids_i4)
   366)   
   367)   call h5pclose_f(prop_id,hdf5_err)
   368)   call h5sclose_f(memory_space_id,hdf5_err)
   369)   call h5sclose_f(file_space_id,hdf5_err)
   370)   call h5dclose_f(data_set_id,hdf5_err)
   371) 
   372)   if (num_indices > 0 .and. index_count /= num_indices) then
   373)     write(option%io_buffer, &
   374)           '("Number of indices read (",i9,") does not match the number",&
   375)            &" of indices requested (",i9,").")') &
   376)            index_count, num_indices
   377)     call printErrMsg(option)        
   378)   endif
   379)   
   380)   if (index_count > 0 .and. index_count < indices_array_size .and. &
   381)       num_indices <= 0) then
   382)     ! resize to index count
   383)     allocate(temp(index_count))
   384)     temp(1:index_count) = indices(1:index_count)
   385)     call DeallocateArray(indices)
   386)     allocate(indices(index_count))
   387)     indices(1:index_count) = temp(1:index_count)
   388)     deallocate(temp)
   389)   else
   390)     call DeallocateArray(indices)
   391)   endif
   392)   
   393)   if (num_indices <= 0) num_indices = index_count
   394) 
   395)   call PetscLogEventEnd(logging%event_map_indices_hdf5,ierr);CHKERRQ(ierr)
   396) ! End of Default & Glenn's HDF5 Broadcast Mechanism
   397) 
   398) #endif
   399) ! SCORPIO
   400) 
   401) end subroutine HDF5MapLocalToNaturalIndices
   402) 
   403) ! ************************************************************************** !
   404) 
   405) subroutine HDF5ReadRealArray(option,file_id,dataset_name,dataset_size, &
   406)                              indices,num_indices,real_array)
   407)   ! 
   408)   ! Read in local real values from hdf5 global file
   409)   ! 
   410)   ! Author: Glenn Hammond
   411)   ! Date: 09/21/07
   412)   ! 
   413) 
   414)   use hdf5
   415)   
   416)   use Option_module
   417)   use HDF5_Aux_module
   418)   use Utility_module, only : DeallocateArray
   419)   
   420)   implicit none
   421)   
   422)   type(option_type) :: option
   423)   character(len=MAXWORDLENGTH) :: dataset_name
   424)   character(len=MAXSTRINGLENGTH) :: string
   425)   PetscInt :: dataset_size
   426)   integer(HID_T) :: file_id
   427)   PetscInt :: indices(:)
   428)   PetscInt :: num_indices
   429)   PetscReal, pointer :: real_array(:)
   430)   
   431) #if defined(SCORPIO)    
   432)   integer :: file_space_id
   433)   integer :: memory_space_id
   434)   integer :: data_set_id
   435)   integer :: prop_id
   436)   integer :: dims(3)
   437)   integer :: offset(3), length(3), stride(3)
   438)   integer :: num_reals_in_file
   439) #else
   440)   integer(HID_T) :: file_space_id
   441)   integer(HID_T) :: memory_space_id
   442)   integer(HID_T) :: data_set_id
   443)   integer(HID_T) :: prop_id
   444)   integer(HSIZE_T) :: dims(3)
   445)   integer(HSIZE_T) :: offset(3), length(3), stride(3)
   446)   integer(HSIZE_T) :: num_reals_in_file
   447)   integer(SIZE_T) :: string_size
   448) #endif
   449) 
   450)   PetscMPIInt :: rank_mpi
   451)   PetscInt :: index_count
   452)   PetscInt :: real_count, prev_real_count
   453)   PetscInt :: temp_int, i, index
   454)   PetscMPIInt :: int_mpi
   455)   
   456)   PetscReal, allocatable :: real_buffer(:)
   457)   
   458)   PetscInt :: read_block_size
   459) 
   460)   call PetscLogEventBegin(logging%event_read_real_array_hdf5, &
   461)                           ierr);CHKERRQ(ierr)
   462)                           
   463) #if defined(SCORPIO)    
   464)   read_block_size = HDF5_READ_BUFFER_SIZE
   465)   ! should be a rank=1 data space (i.e., one dimensional dataset)
   466)   call fscorpio_get_dataset_size( num_reals_in_file, file_id, dataset_name, &
   467)           option%ioread_group_id, ierr)
   468) !???? get size of dataset  call h5sget_simple_extent_npoints_f(file_space_id,num_reals_in_file,hdf5_err)
   469) #if 0
   470)   if (dataset_size > 0 .and. num_reals_in_file /= dataset_size) then
   471)     write(option%io_buffer, &
   472)           '(a," data space dimension (",i9,") does not match the dimensions",&
   473)            &" of the domain (",i9,").")') trim(dataset_name), &
   474)            num_reals_in_file, grid%nmax
   475)     call printErrMsg(option)   
   476)   endif
   477) #endif
   478)   
   479)   rank_mpi = 1
   480)   offset = 0
   481)   length = 0
   482)   stride = 1
   483)   
   484)   dims = 0
   485)   real_count = 0
   486)   prev_real_count = 0
   487)   index_count = 0
   488)   memory_space_id = -1
   489)   ! if a list of indices exists, use the indexed approach
   490)   if (num_indices > 0) then
   491)     allocate(real_buffer(read_block_size))
   492)     do i=1,num_indices
   493)       index = indices(i)
   494)       if (index > real_count) then
   495)         do 
   496)           if (index <= real_count) exit
   497)           temp_int = int(num_reals_in_file-real_count)
   498)           temp_int = min(temp_int,read_block_size)
   499)           if (dims(1) /= temp_int) then
   500)             dims(1) = temp_int
   501)           endif
   502)           ! offset is zero-based
   503)           offset(1) = real_count
   504)           length(1) = dims(1)
   505) 
   506)         call PetscLogEventBegin(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
   507) 
   508)         ! rank_mpi = 1 ! This is in fact number of dimensions
   509)         call fscorpio_read_same_sub_dataset(real_buffer, SCORPIO_DOUBLE, rank_mpi, dims, & 
   510)                 offset, file_id, dataset_name, option%ioread_group_id, ierr)
   511) 
   512)         !call h5dread_f(data_set_id,H5T_NATIVE_DOUBLE,real_buffer,dims, &
   513)                        !hdf5_err,memory_space_id,file_space_id,prop_id)
   514)         call PetscLogEventEnd(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
   515)           prev_real_count = real_count
   516)           real_count = real_count + int(length(1))
   517)         enddo
   518)       endif
   519)       real_array(i) = real_buffer(index-prev_real_count)
   520)     enddo
   521) 
   522)     deallocate(real_buffer)
   523)   ! otherwise, read the entire array
   524)   else
   525)     if (.not.associated(real_array)) then
   526)       allocate(real_array(num_reals_in_file))
   527)     endif
   528)     real_array = 0.d0
   529)     dims(1) = num_reals_in_file
   530)     offset(1) = 0
   531)     length(1) = dims(1)
   532)       call PetscLogEventBegin(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
   533)       call fscorpio_read_same_sub_dataset(real_buffer, SCORPIO_DOUBLE, rank_mpi, dims, & 
   534)               offset, file_id, dataset_name, option%ioread_group_id, ierr)
   535)       call PetscLogEventEnd(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
   536)   endif
   537)   
   538) #else
   539) !SCORPIO is not defined
   540) 
   541)   read_block_size = HDF5_READ_BUFFER_SIZE
   542)   call h5dopen_f(file_id,dataset_name,data_set_id,hdf5_err)
   543)   if (hdf5_err /= 0) then
   544)     string_size = MAXSTRINGLENGTH
   545)     call h5fget_name_f(file_id,string,string_size,hdf5_err)
   546)     option%io_buffer = 'HDF5 dataset "' // trim(dataset_name) // '" not found &
   547)       &in file "' // trim(string) // '".'
   548)     call printErrMsg(option)
   549)   endif
   550)   call h5dget_space_f(data_set_id,file_space_id,hdf5_err)
   551)   ! should be a rank=1 data space
   552)   call h5sget_simple_extent_npoints_f(file_space_id,num_reals_in_file,hdf5_err)
   553) #if 0
   554)   if (dataset_size > 0 .and. num_reals_in_file /= dataset_size) then
   555)     write(option%io_buffer, &
   556)           '(a," data space dimension (",i9,") does not match the dimensions",&
   557)            &" of the domain (",i9,").")') trim(dataset_name), &
   558)            num_reals_in_file, grid%nmax
   559)     call printErrMsg(option)   
   560)   endif
   561) #endif
   562)   
   563)   rank_mpi = 1
   564)   offset = 0
   565)   length = 0
   566)   stride = 1
   567)   
   568)   call h5pcreate_f(H5P_DATASET_XFER_F,prop_id,hdf5_err)
   569) #ifndef SERIAL_HDF5
   570)   call h5pset_dxpl_mpio_f(prop_id,H5FD_MPIO_INDEPENDENT_F,hdf5_err)
   571) #endif
   572)   
   573)   dims = 0
   574)   real_count = 0
   575)   prev_real_count = 0
   576)   index_count = 0
   577)   memory_space_id = -1
   578)   ! if a list of indices exists, use the indexed approach
   579)   if (num_indices > 0) then
   580)     allocate(real_buffer(read_block_size))
   581)     do i=1,num_indices
   582)       index = indices(i)
   583)       if (index > real_count) then
   584)         do 
   585)           if (index <= real_count) exit
   586)           temp_int = int(num_reals_in_file)-real_count
   587)           temp_int = min(temp_int,read_block_size)
   588)           if (dims(1) /= temp_int) then
   589)             if (memory_space_id > -1) call h5sclose_f(memory_space_id,hdf5_err)
   590)             dims(1) = temp_int
   591)             call h5screate_simple_f(rank_mpi,dims,memory_space_id,hdf5_err,dims)
   592)           endif
   593)           ! offset is zero-based
   594)           offset(1) = real_count
   595)           length(1) = dims(1)
   596)           call h5sselect_hyperslab_f(file_space_id, H5S_SELECT_SET_F,offset, &
   597)                                      length,hdf5_err,stride,stride) 
   598) #ifdef HDF5_BROADCAST
   599)           if (option%myrank == option%io_rank) then                           
   600) #endif
   601)             call PetscLogEventBegin(logging%event_h5dread_f, &
   602)                                     ierr);CHKERRQ(ierr)
   603)             call h5dread_f(data_set_id,H5T_NATIVE_DOUBLE,real_buffer,dims, &
   604)                            hdf5_err,memory_space_id,file_space_id,prop_id)
   605)             call PetscLogEventEnd(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
   606) #ifdef HDF5_BROADCAST
   607)           endif
   608)           if (option%mycommsize > 1) then
   609)             int_mpi = dims(1)
   610)             call MPI_Bcast(real_buffer,int_mpi,MPI_DOUBLE_PRECISION, &
   611)                            option%io_rank,option%mycomm,ierr)
   612)           endif
   613) #endif
   614)           prev_real_count = real_count
   615)           real_count = real_count + int(length(1))
   616)         enddo
   617)       endif
   618)       real_array(i) = real_buffer(index-prev_real_count)
   619)     enddo
   620) 
   621) #ifdef HDF5_BROADCAST
   622)     do 
   623)       if (real_count >= num_reals_in_file) exit
   624)       temp_int = num_reals_in_file-real_count
   625)       temp_int = min(temp_int,read_block_size)
   626)       if (dims(1) /= temp_int) then
   627)         if (memory_space_id > -1) call h5sclose_f(memory_space_id,hdf5_err)
   628)         dims(1) = temp_int
   629)         call h5screate_simple_f(rank_mpi,dims,memory_space_id,hdf5_err,dims)
   630)       endif
   631)       ! offset is zero-based
   632)       offset(1) = real_count
   633)       length(1) = dims(1)
   634)       call h5sselect_hyperslab_f(file_space_id, H5S_SELECT_SET_F,offset, &
   635)                                  length,hdf5_err,stride,stride) 
   636)       if (option%myrank == io_rank) then 
   637)         call PetscLogEventBegin(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
   638)         call h5dread_f(data_set_id,H5T_NATIVE_DOUBLE,real_buffer,dims, &
   639)                        hdf5_err,memory_space_id,file_space_id,prop_id)
   640)         call PetscLogEventEnd(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
   641)       endif
   642)       if (option%mycommsize > 1) then
   643)         int_mpi = dims(1)
   644)         call MPI_Bcast(real_buffer,int_mpi,MPI_DOUBLE_PRECISION, &
   645)                        option%io_rank,option%mycomm,ierr)
   646)       endif
   647)       real_count = real_count + int(length(1))
   648)     enddo
   649) #endif
   650)     deallocate(real_buffer)
   651)   ! otherwise, read the entire array
   652)   else
   653)     if (.not.associated(real_array)) then
   654)       allocate(real_array(num_reals_in_file))
   655)     endif
   656)     real_array = 0.d0
   657)     dims(1) = num_reals_in_file
   658)     call h5screate_simple_f(rank_mpi,dims,memory_space_id,hdf5_err,dims)
   659)     offset(1) = 0
   660)     length(1) = dims(1)
   661)     call h5sselect_hyperslab_f(file_space_id, H5S_SELECT_SET_F,offset, &
   662)                                length,hdf5_err,stride,stride) 
   663) #ifdef HDF5_BROADCAST
   664)     if (option%myrank == option%io_rank) then                           
   665) #endif
   666)       call PetscLogEventBegin(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
   667)       call h5dread_f(data_set_id,H5T_NATIVE_DOUBLE,real_array,dims, &
   668)                      hdf5_err,memory_space_id,file_space_id,prop_id)
   669)       call PetscLogEventEnd(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
   670) #ifdef HDF5_BROADCAST
   671)     endif
   672)     if (option%mycommsize > 1) then
   673)       int_mpi = dims(1)
   674)       call MPI_Bcast(real_array,int_mpi,MPI_DOUBLE_PRECISION, &
   675)                      option%io_rank,option%mycomm,ierr)
   676)     endif
   677) #endif
   678)   endif
   679)   
   680)   call h5pclose_f(prop_id,hdf5_err)
   681)   if (memory_space_id > -1) call h5sclose_f(memory_space_id,hdf5_err)
   682)   call h5sclose_f(file_space_id,hdf5_err)
   683)   call h5dclose_f(data_set_id,hdf5_err)
   684) #endif
   685) !SCORPIO
   686) 
   687)   call PetscLogEventEnd(logging%event_read_real_array_hdf5,ierr);CHKERRQ(ierr)
   688)                           
   689) end subroutine HDF5ReadRealArray
   690) 
   691) ! ************************************************************************** !
   692) 
   693) subroutine HDF5ReadIntegerArray(option,file_id,dataset_name,dataset_size, &
   694)                                 indices,num_indices,integer_array)
   695)   ! 
   696)   ! Read in local integer values from hdf5 global file
   697)   ! 
   698)   ! Author: Glenn Hammond
   699)   ! Date: 09/21/07
   700)   ! 
   701) 
   702)   use hdf5
   703)   
   704)   use Grid_module
   705)   use Option_module
   706)   use HDF5_Aux_module
   707)   use Utility_module, only : DeallocateArray
   708)   
   709)   implicit none
   710) 
   711) #if defined(SCORPIO)
   712)   type(option_type) :: option
   713)   character(len=MAXWORDLENGTH) :: dataset_name
   714)   PetscInt :: dataset_size
   715)   PetscInt :: indices(:)
   716)   PetscInt :: num_indices
   717)   PetscInt :: integer_array(:)
   718)   
   719)   integer :: file_id
   720)   integer :: file_space_id
   721)   integer :: memory_space_id
   722)   integer :: data_set_id
   723)   integer :: prop_id
   724)   integer :: dims(3)
   725)   integer :: offset(3), length(3), stride(3)
   726)   integer :: num_integers
   727) 
   728) 
   729)   PetscMPIInt :: rank_mpi
   730)   PetscInt :: index_count
   731)   PetscInt :: integer_count, prev_integer_count
   732)   PetscInt :: num_integers_in_file
   733)   PetscInt :: temp_int, i, index
   734)   PetscMPIInt :: int_mpi
   735)   
   736)   integer, allocatable :: integer_buffer_i4(:)
   737)   PetscInt :: read_block_size
   738) 
   739)   call PetscLogEventBegin(logging%event_read_int_array_hdf5, &
   740)                           ierr);CHKERRQ(ierr)
   741) 
   742)   read_block_size = HDF5_READ_BUFFER_SIZE
   743)   allocate(integer_buffer_i4(read_block_size))
   744)   dims = 0
   745)   integer_count = 0
   746)   prev_integer_count = 0
   747)   index_count = 0
   748)   memory_space_id = -1
   749)   length = 0
   750)   num_integers_in_file = 0
   751) 
   752)   call fscorpio_get_dataset_size( num_integers, file_id, dataset_name, &
   753)           option%ioread_group_id, ierr)
   754)   num_integers_in_file = int(num_integers) 
   755) #if 0  
   756)      if (dataset_size > 0 .and. num_integers_in_file /= dataset_size) then
   757)          write(option%io_buffer, &
   758)               '(a," data space dimension (",i9,") does not match the dimensions",&
   759)                &" of the domain (",i9,").")') trim(dataset_name), &
   760)                num_integers_in_file,dataset_size
   761)          call printErrMsg(option)   
   762)      endif
   763) #endif
   764) 
   765)   rank_mpi = 1
   766)   offset = 0
   767)   stride = 1
   768)                   
   769)   do i=1,num_indices
   770)     index = indices(i)
   771)     if (index > integer_count) then
   772)       do
   773)         if (index <= integer_count) exit
   774)         temp_int = num_integers_in_file-integer_count
   775)         temp_int = min(temp_int,read_block_size)
   776)         if (dims(1) /= temp_int) then
   777)           dims(1) = temp_int
   778)           length(1) = dims(1)
   779)         endif
   780)         ! offset is zero-based
   781)         offset(1) = integer_count
   782)         length(1) = dims(1)
   783)         call PetscLogEventBegin(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
   784)         call fscorpio_read_same_sub_dataset(integer_buffer_i4, &
   785)                                            SCORPIO_INTEGER, rank_mpi, dims, &
   786)                                            offset, file_id, dataset_name, &
   787)                                            option%ioread_group_id, ierr)
   788)         call PetscLogEventEnd(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
   789)         prev_integer_count = integer_count
   790)         integer_count = integer_count + length(1)                  
   791)       enddo
   792)     endif
   793)     integer_array(i) = integer_buffer_i4(index-prev_integer_count)
   794)   enddo
   795) 
   796)   do
   797)     if (integer_count >= num_integers_in_file) exit
   798)     temp_int = num_integers_in_file-integer_count
   799)     temp_int = min(temp_int,read_block_size)
   800)     if (dims(1) /= temp_int) then
   801)       dims(1) = temp_int
   802)       length(1) = dims(1)
   803)     endif
   804)     ! offset is zero-based
   805)     offset(1) = integer_count
   806)     length(1) = dims(1)
   807)     call PetscLogEventBegin(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
   808)     call fscorpio_read_same_sub_dataset(integer_buffer_i4, SCORPIO_INTEGER, &
   809)                                        rank_mpi, dims, & 
   810)              offset, file_id, dataset_name, option%ioread_group_id, ierr)
   811)     !call h5dread_f(data_set_id,HDF_NATIVE_INTEGER,integer_buffer_i4,dims, &
   812)                    !hdf5_err,memory_space_id,file_space_id,prop_id)   
   813)     call PetscLogEventEnd(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
   814)     integer_count = integer_count + length(1)                  
   815)   enddo
   816)   deallocate(integer_buffer_i4)
   817) 
   818)   call PetscLogEventEnd(logging%event_read_int_array_hdf5,ierr);CHKERRQ(ierr)
   819) 
   820) #else
   821) ! SCORPIO is not defined
   822) 
   823)   type(option_type) :: option
   824)   character(len=MAXWORDLENGTH) :: dataset_name
   825)   character(len=MAXSTRINGLENGTH) :: string
   826)   PetscInt :: dataset_size
   827)   integer(HID_T) :: file_id
   828)   PetscInt :: indices(:)
   829)   PetscInt :: num_indices
   830)   PetscInt :: integer_array(:)
   831)   
   832)   integer(HID_T) :: file_space_id
   833)   integer(HID_T) :: memory_space_id
   834)   integer(HID_T) :: data_set_id
   835)   integer(HID_T) :: prop_id
   836)   integer(HSIZE_T) :: dims(3)
   837)   integer(HSIZE_T) :: offset(3), length(3), stride(3)
   838)   PetscMPIInt :: rank_mpi
   839)   PetscInt :: index_count
   840)   PetscInt :: integer_count, prev_integer_count
   841)   integer(HSIZE_T) :: num_integers_in_file
   842)   integer(SIZE_T) :: string_size
   843)   PetscInt :: temp_int, i, index
   844)   PetscMPIInt :: int_mpi
   845)   
   846)   integer, allocatable :: integer_buffer_i4(:)
   847)   
   848)   PetscInt :: read_block_size
   849) 
   850) ! Default & Glenn's HDF5 Broadcast Mechanism (uses HDF5 Independent I/O mode)
   851) 
   852)   call PetscLogEventBegin(logging%event_read_int_array_hdf5, &
   853)                           ierr);CHKERRQ(ierr)
   854) 
   855)   read_block_size = HDF5_READ_BUFFER_SIZE
   856)   call h5dopen_f(file_id,dataset_name,data_set_id,hdf5_err)
   857)   if (hdf5_err /= 0) then
   858)     string_size = MAXSTRINGLENGTH
   859)     call h5fget_name_f(file_id,string,string_size,hdf5_err)
   860)     option%io_buffer = 'HDF5 dataset "' // trim(dataset_name) // '" not found &
   861)       &in file "' // trim(string) // '".'
   862)     call printErrMsg(option)
   863)   endif
   864)   call h5dget_space_f(data_set_id,file_space_id,hdf5_err)
   865)   ! should be a rank=1 data space
   866)   call h5sget_simple_extent_npoints_f(file_space_id,num_integers_in_file, &
   867)                                       hdf5_err)
   868) #if 0
   869)   if (dataset_size > 0 .and. num_integers_in_file /= dataset_size) then
   870)     write(option%io_buffer, &
   871)           '(a," data space dimension (",i9,") does not match the dimensions",&
   872)            &" of the domain (",i9,").")') trim(dataset_name), &
   873)            num_integers_in_file,dataset_size
   874)     call printErrMsg(option)   
   875)   endif
   876) #endif
   877)   
   878)   allocate(integer_buffer_i4(read_block_size))
   879)   
   880)   rank_mpi = 1
   881)   offset = 0
   882)   length = 0
   883)   stride = 1
   884)   
   885)   call h5pcreate_f(H5P_DATASET_XFER_F,prop_id,hdf5_err)
   886) #ifndef SERIAL_HDF5
   887)   call h5pset_dxpl_mpio_f(prop_id,H5FD_MPIO_INDEPENDENT_F,hdf5_err)
   888) #endif
   889)   
   890)   dims = 0
   891)   integer_count = 0
   892)   prev_integer_count = 0
   893)   index_count = 0
   894)   memory_space_id = -1
   895) 
   896)   do i=1,num_indices
   897)     index = indices(i)
   898)     if (index > integer_count) then
   899)       do
   900)         if (index <= integer_count) exit
   901)         temp_int = int(num_integers_in_file)-integer_count
   902)         temp_int = min(temp_int,read_block_size)
   903)         if (dims(1) /= temp_int) then
   904)           if (memory_space_id > -1) call h5sclose_f(memory_space_id,hdf5_err)
   905)           dims(1) = temp_int
   906)           call h5screate_simple_f(rank_mpi,dims,memory_space_id,hdf5_err,dims)
   907)         endif
   908)         ! offset is zero-based
   909)         offset(1) = integer_count
   910)         length(1) = dims(1)
   911)         call h5sselect_hyperslab_f(file_space_id, H5S_SELECT_SET_F,offset, &
   912)                                    length,hdf5_err,stride,stride) 
   913) #ifdef HDF5_BROADCAST
   914)         if (option%myrank == option%io_rank) then                           
   915) #endif
   916)           call PetscLogEventBegin(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
   917)           call h5dread_f(data_set_id,HDF_NATIVE_INTEGER,integer_buffer_i4,dims, &
   918)                          hdf5_err,memory_space_id,file_space_id,prop_id)   
   919)           call PetscLogEventEnd(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
   920) #ifdef HDF5_BROADCAST
   921)         endif
   922)         if (option%mycommsize > 1) then
   923)           int_mpi = dims(1)
   924)           call MPI_Bcast(integer_buffer_i4,int_mpi,MPI_INTEGER,option%io_rank, &
   925)                          option%mycomm,ierr)
   926)         endif
   927) #endif
   928)         prev_integer_count = integer_count
   929)         integer_count = integer_count + int(length(1))
   930)       enddo
   931)     endif
   932)     integer_array(i) = integer_buffer_i4(index-prev_integer_count)
   933)   enddo
   934) 
   935) #ifdef HDF5_BROADCAST
   936)   do
   937)     if (integer_count >= num_integers_in_file) exit
   938)     temp_int = num_integers_in_file-integer_count
   939)     temp_int = min(temp_int,read_block_size)
   940)     if (dims(1) /= temp_int) then
   941)       if (memory_space_id > -1) call h5sclose_f(memory_space_id,hdf5_err)
   942)       dims(1) = temp_int
   943)       call h5screate_simple_f(rank_mpi,dims,memory_space_id,hdf5_err,dims)
   944)     endif
   945)     ! offset is zero-based
   946)     offset(1) = integer_count
   947)     length(1) = dims(1)
   948)     call h5sselect_hyperslab_f(file_space_id, H5S_SELECT_SET_F,offset, &
   949)                                length,hdf5_err,stride,stride) 
   950)     if (option%myrank == option%io_rank) then 
   951)       call PetscLogEventBegin(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
   952)       call h5dread_f(data_set_id,HDF_NATIVE_INTEGER,integer_buffer_i4,dims, &
   953)                      hdf5_err,memory_space_id,file_space_id,prop_id)   
   954)       call PetscLogEventEnd(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
   955)     endif
   956)     if (option%mycommsize > 1) then
   957)       int_mpi = dims(1)
   958)       call MPI_Bcast(integer_buffer_i4,int_mpi,MPI_INTEGER,option%io_rank, &
   959)                      option%mycomm,ierr)
   960)     endif
   961)     integer_count = integer_count + length(1)                  
   962)   enddo
   963) #endif
   964)   deallocate(integer_buffer_i4)
   965)   
   966)   call h5pclose_f(prop_id,hdf5_err)
   967)   if (memory_space_id > -1) call h5sclose_f(memory_space_id,hdf5_err)
   968)   call h5sclose_f(file_space_id,hdf5_err)
   969)   call h5dclose_f(data_set_id,hdf5_err)
   970) 
   971)   call PetscLogEventEnd(logging%event_read_int_array_hdf5,ierr);CHKERRQ(ierr)
   972) 
   973) ! Default & Glenn's HDF5 Broadcast Mechanism (uses HDF5 Independent I/O mode)
   974)                           
   975) #endif
   976) ! SCORPIO
   977) 
   978) end subroutine HDF5ReadIntegerArray
   979) 
   980) ! ************************************************************************** !
   981) 
   982) subroutine HDF5WriteStructuredDataSet(name,array,file_id,data_type,option, &
   983)                                       nx_global,ny_global,nz_global, &
   984)                                       nx_local,ny_local,nz_local, &
   985)                                       istart_local,jstart_local,kstart_local)
   986)   ! 
   987)   ! Writes data from an array into HDF5 file
   988)   ! 
   989)   ! Author: Glenn Hammond
   990)   ! Date: 10/25/07
   991)   ! 
   992) 
   993)   use hdf5
   994)   use Option_module
   995)   use Utility_module, only : DeallocateArray
   996)   
   997)   implicit none
   998)   
   999)   character(len=*) :: name
  1000)   PetscReal :: array(:)
  1001)   type(option_type) :: option
  1002)   PetscInt :: nx_local, ny_local, nz_local
  1003)   PetscInt :: nx_global, ny_global, nz_global
  1004)   PetscInt :: istart_local, jstart_local, kstart_local
  1005) 
  1006) #if defined(SCORPIO_WRITE)    
  1007)   integer :: file_id
  1008)   integer :: data_type
  1009)   integer :: file_space_id
  1010)   integer :: memory_space_id
  1011)   integer :: data_set_id
  1012)   integer :: prop_id
  1013)   integer :: dims(3),mem_dims(3)
  1014)   integer :: start(3), length(3), stride(3)
  1015)   integer :: nlmax ! Sarat added nlmax 
  1016)   integer :: rank_mpi,file_space_rank_mpi
  1017)   integer :: i, j, k, count, id
  1018)   integer :: ny_local_X_nz_local
  1019)   integer :: num_to_write_mpi
  1020) #else
  1021)   integer(HID_T) :: file_id
  1022)   integer(HID_T) :: data_type
  1023)   integer(HID_T) :: file_space_id
  1024)   integer(HID_T) :: memory_space_id
  1025)   integer(HID_T) :: data_set_id
  1026)   integer(HID_T) :: prop_id
  1027)   integer(HSIZE_T) :: dims(3),mem_dims(3)
  1028)   PetscMPIInt :: rank_mpi,file_space_rank_mpi  
  1029)   PetscInt :: i, j, k, count, id
  1030)   integer(HSIZE_T) :: start(3), length(3), stride(3)
  1031)   PetscInt :: ny_local_X_nz_local
  1032)   PetscMPIInt :: num_to_write_mpi
  1033) #endif
  1034)   PetscMPIInt, parameter :: ON=1, OFF=0
  1035)   PetscMPIInt :: hdf5_flag
  1036) 
  1037)   integer, pointer :: int_array_i4(:)
  1038)   PetscReal, pointer :: double_array(:)
  1039)   character(len=128) :: fscorpio_string
  1040) 
  1041)   name = trim(name) // CHAR(0)
  1042) 
  1043) #if defined(SCORPIO_WRITE)
  1044) 
  1045)   !geh: kludge to get scorpio to write name properly without garbage appended.
  1046) ! fscorpio_string(1:len_trim(name)) = name
  1047) 
  1048)   fscorpio_string = trim(name)
  1049) 
  1050)   fscorpio_string = trim(fscorpio_string) // CHAR(0)
  1051) 
  1052) !  write(option%io_buffer,'(" Writing dataset block: ", a, " type - ", i, ".")') trim(name), data_type
  1053) !  call printMsg(option)
  1054) !  write(option%io_buffer,'(" HDF_NATIVE_INTEGER is ", i, " and H5T_NATIVE_DOUBLE is ", i, " and H5T_NATIVE_INTEGER is ", i, ".")') HDF_NATIVE_INTEGER, H5T_NATIVE_DOUBLE, H5T_NATIVE_INTEGER
  1055) !  call printMsg(option)
  1056) 
  1057)   call PetscLogEventBegin(logging%event_write_struct_dataset_hdf5, &
  1058)                           ierr);CHKERRQ(ierr)
  1059)   
  1060)   ny_local_X_nz_local = ny_local*nz_local
  1061)   num_to_write_mpi = nx_local*ny_local_X_nz_local
  1062)   
  1063)   ! file space which is a 3D block
  1064)   rank_mpi = 3
  1065) 
  1066)   dims(1) = nx_global
  1067)   dims(2) = ny_global
  1068)   dims(3) = nz_global
  1069) 
  1070)   !write(option%io_buffer,'(" Writing dataset block with dimensions: ", i,i,i, ".")') dims(1), dims(2), dims(3)
  1071)   !call printMsg(option)
  1072) 
  1073)   ! create the hyperslab
  1074)   start(1) = istart_local
  1075)   start(2) = jstart_local
  1076)   start(3) = kstart_local
  1077)   length(1) =  nx_local
  1078)   length(2) =  ny_local
  1079)   length(3) =  nz_local
  1080) 
  1081)   ! Sarat added this to eliminate grid%nlmax dependency in the non-INVERT case
  1082)   ! below
  1083)   nlmax = nx_local * ny_local * nz_local
  1084) 
  1085)   if (num_to_write_mpi == 0) length(1) = 1
  1086)   stride = 1
  1087) 
  1088)     ! write the data
  1089)   if (num_to_write_mpi > 0) then
  1090)     if (data_type == H5T_NATIVE_DOUBLE) then
  1091)       allocate(double_array(nx_local*ny_local*nz_local))
  1092)       count = 0
  1093)       do k=1,nz_local
  1094)         do j=1,ny_local
  1095)           do i=1,nx_local
  1096)             id = k+(j-1)*nz_local+(i-1)*ny_local_X_nz_local
  1097)             count = count+1
  1098)             double_array(id) = array(count)
  1099)           enddo
  1100)         enddo
  1101)       enddo
  1102)       call PetscLogEventBegin(logging%event_h5dwrite_f,ierr);CHKERRQ(ierr)
  1103)        !write(option%io_buffer, &
  1104)        !   '(a," Writing double dataset1: dimensions: ",i9,i9,i9, " Data type and ndims: ",i9, i9)') & 
  1105)        !trim(name), dims(1), dims(2), dims(3), SCORPIO_DOUBLE, rank_mpi
  1106)        !call printMsg(option)   
  1107) 
  1108)        call fscorpio_write_dataset_block(double_array, SCORPIO_DOUBLE, rank_mpi, &
  1109)               dims, length, start, file_id, trim(fscorpio_string), &
  1110)               option%iowrite_group_id, ierr)
  1111)       !call h5dwrite_f(data_set_id,data_type,double_array,dims, &
  1112)                       !hdf5_err,memory_space_id,file_space_id,prop_id)  
  1113)       call PetscLogEventEnd(logging%event_h5dwrite_f,ierr);CHKERRQ(ierr)
  1114)       call DeallocateArray(double_array)
  1115)     else if (data_type == HDF_NATIVE_INTEGER) then
  1116)       allocate(int_array_i4(nx_local*ny_local*nz_local))
  1117)       count = 0
  1118)       do k=1,nz_local
  1119)         do j=1,ny_local
  1120)           do i=1,nx_local
  1121)             id = k+(j-1)*nz_local+(i-1)*ny_local_X_nz_local
  1122)             count = count+1
  1123)             int_array_i4(id) = int(array(count))
  1124)           enddo
  1125)         enddo
  1126)       enddo
  1127)       call PetscLogEventBegin(logging%event_h5dwrite_f,ierr);CHKERRQ(ierr)
  1128)        !write(option%io_buffer, &
  1129)        !   '(a," Writing integer dataset1: dimensions: ",i9,i9,i9, " Data type and ndims: ",i9, i9)') & 
  1130)        !trim(name), dims(1), dims(2), dims(3), SCORPIO_INTEGER, rank_mpi
  1131)        !call printMsg(option)   
  1132)       call fscorpio_write_dataset_block(int_array_i4, SCORPIO_INTEGER, rank_mpi, &
  1133)               dims, length, start, file_id, trim(fscorpio_string), &
  1134)               option%iowrite_group_id, ierr)
  1135)       !!call h5dwrite_f(data_set_id,data_type,int_array_i4,dims, &
  1136)       !                hdf5_err,memory_space_id,file_space_id,prop_id)
  1137)       call PetscLogEventEnd(logging%event_h5dwrite_f,ierr);CHKERRQ(ierr)
  1138)       call DeallocateArray(int_array_i4)
  1139)     endif
  1140)   endif
  1141) 
  1142)   call PetscLogEventEnd(logging%event_write_struct_dataset_hdf5, &
  1143)                         ierr);CHKERRQ(ierr)
  1144) 
  1145) #else
  1146) ! SCORPIO_WRITE is not defined  
  1147) 
  1148) ! Default HDF5 Write
  1149) 
  1150)   call PetscLogEventBegin(logging%event_write_struct_dataset_hdf5, &
  1151)                           ierr);CHKERRQ(ierr)
  1152)   
  1153)   ny_local_X_nz_local = ny_local*nz_local
  1154)   num_to_write_mpi = nx_local*ny_local_X_nz_local
  1155)   
  1156)   ! memory space which is a 1D vector  
  1157)   rank_mpi = 1
  1158)   dims = 0
  1159)   dims(1) = num_to_write_mpi
  1160)   if (num_to_write_mpi == 0) dims(1) = 1
  1161)   call h5screate_simple_f(rank_mpi,dims,memory_space_id,hdf5_err,dims)
  1162) 
  1163)   ! file space which is a 3D block
  1164)   rank_mpi = 3
  1165)   ! have to trick hdf5 for now with inverted ordering
  1166)   dims(3) = nx_global
  1167)   dims(2) = ny_global
  1168)   dims(1) = nz_global
  1169)   call h5pcreate_f(H5P_DATASET_CREATE_F,prop_id,hdf5_err)
  1170) 
  1171)   call h5eset_auto_f(OFF,hdf5_err)
  1172)   call h5dopen_f(file_id,name,data_set_id,hdf5_err)
  1173)   hdf5_flag = hdf5_err
  1174)   call h5eset_auto_f(ON,hdf5_err)
  1175)   if (hdf5_flag < 0) then 
  1176)     call h5screate_simple_f(rank_mpi,dims,file_space_id,hdf5_err,dims)
  1177)     call h5dcreate_f(file_id,name,data_type,file_space_id, &
  1178)                      data_set_id,hdf5_err,prop_id)
  1179)   else
  1180)     call h5dget_space_f(data_set_id,file_space_id,hdf5_err)
  1181)   endif
  1182) 
  1183)   call h5pclose_f(prop_id,hdf5_err)
  1184)   
  1185)   ! create the hyperslab
  1186)   start(3) = istart_local
  1187)   start(2) = jstart_local
  1188)   start(1) = kstart_local
  1189)   ! recall these are inverted
  1190)   length(3) =  nx_local
  1191)   length(2) =  ny_local
  1192)   length(1) =  nz_local
  1193)   if (num_to_write_mpi == 0) length(1) = 1
  1194)   stride = 1
  1195)   call h5sselect_hyperslab_f(file_space_id,H5S_SELECT_SET_F,start,length, &
  1196)                              hdf5_err,stride,stride)
  1197) 
  1198)     ! write the data
  1199)   call h5pcreate_f(H5P_DATASET_XFER_F,prop_id,hdf5_err)
  1200) #ifndef SERIAL_HDF5
  1201)   if (trick_hdf5) then
  1202)     call h5pset_dxpl_mpio_f(prop_id,H5FD_MPIO_INDEPENDENT_F, &
  1203)                             hdf5_err) 
  1204)   else
  1205)     call h5pset_dxpl_mpio_f(prop_id,H5FD_MPIO_COLLECTIVE_F, &
  1206)                             hdf5_err)
  1207)   endif
  1208) #endif
  1209)   if (num_to_write_mpi > 0) then
  1210)     if (data_type == HDF_NATIVE_INTEGER) then
  1211)       allocate(int_array_i4(nx_local*ny_local*nz_local))
  1212)       count = 0
  1213)       do k=1,nz_local
  1214)         do j=1,ny_local
  1215)           do i=1,nx_local
  1216)             id = k+(j-1)*nz_local+(i-1)*ny_local_X_nz_local
  1217)             count = count+1
  1218)             int_array_i4(id) = int(array(count))
  1219)           enddo
  1220)         enddo
  1221)       enddo
  1222)       call PetscLogEventBegin(logging%event_h5dwrite_f,ierr);CHKERRQ(ierr)
  1223)       call h5dwrite_f(data_set_id,data_type,int_array_i4,dims, &
  1224)                       hdf5_err,memory_space_id,file_space_id,prop_id)
  1225)       call PetscLogEventEnd(logging%event_h5dwrite_f,ierr);CHKERRQ(ierr)
  1226)       call DeallocateArray(int_array_i4)
  1227)     else
  1228)       allocate(double_array(nx_local*ny_local*nz_local))
  1229)       count = 0
  1230)       do k=1,nz_local
  1231)         do j=1,ny_local
  1232)           do i=1,nx_local
  1233)             id = k+(j-1)*nz_local+(i-1)*ny_local_X_nz_local
  1234)             count = count+1
  1235)             double_array(id) = array(count)
  1236)           enddo
  1237)         enddo
  1238)       enddo
  1239)       call PetscLogEventBegin(logging%event_h5dwrite_f,ierr);CHKERRQ(ierr)
  1240)       call h5dwrite_f(data_set_id,data_type,double_array,dims, &
  1241)                       hdf5_err,memory_space_id,file_space_id,prop_id)  
  1242)       call PetscLogEventEnd(logging%event_h5dwrite_f,ierr);CHKERRQ(ierr)
  1243)       call DeallocateArray(double_array)
  1244)     endif
  1245)     call h5pclose_f(prop_id,hdf5_err)
  1246)   endif
  1247)   call h5dclose_f(data_set_id,hdf5_err)
  1248)   call h5sclose_f(file_space_id,hdf5_err)
  1249)   call h5sclose_f(memory_space_id,hdf5_err)
  1250) 
  1251)   call PetscLogEventEnd(logging%event_write_struct_dataset_hdf5, &
  1252)                         ierr);CHKERRQ(ierr)
  1253)                           
  1254) #endif
  1255) ! SCORPIO_WRITE vs previous
  1256) 
  1257) end subroutine HDF5WriteStructuredDataSet
  1258) 
  1259) ! ************************************************************************** !
  1260) 
  1261) subroutine HDF5ReadIndices(grid,option,file_id,dataset_name,dataset_size, &
  1262)                            indices)
  1263)   ! 
  1264)   ! End of Default HDF5 Write
  1265)   ! GEH - Structured Grid Dependence - End
  1266)   ! Reads cell indices from an hdf5 dataset
  1267)   ! 
  1268)   ! Author: Glenn Hammond
  1269)   ! Date: 01/12/08
  1270)   ! 
  1271) 
  1272)   use hdf5
  1273)   
  1274)   use Option_module
  1275)   use Grid_module
  1276)   use Utility_module, only : DeallocateArray
  1277)   
  1278)   implicit none
  1279) 
  1280) #if defined(SCORPIO)
  1281) 
  1282)   type(grid_type) :: grid
  1283)   type(option_type) :: option
  1284)   character(len=MAXWORDLENGTH) :: dataset_name
  1285)   PetscInt :: dataset_size
  1286)   PetscInt, pointer :: indices(:)
  1287)   PetscInt :: num_indices
  1288)     
  1289) #if defined(SCORPIO)    
  1290)   integer :: file_id
  1291)   integer :: file_space_id
  1292)   integer :: memory_space_id
  1293)   integer :: data_set_id
  1294)   integer :: prop_id
  1295)   integer :: dims(3)
  1296)   integer :: offset(3), length(3), stride(3), globaldims(3)
  1297)   integer :: num_data_in_file
  1298) #else
  1299)   integer(HID_T) :: file_id
  1300)   integer(HID_T) :: file_space_id
  1301)   integer(HID_T) :: memory_space_id
  1302)   integer(HID_T) :: data_set_id
  1303)   integer(HID_T) :: prop_id
  1304)   integer(HSIZE_T) :: dims(3)
  1305)   integer(HSIZE_T) :: offset(3), length(3), stride(3), globaldims(3)
  1306)   integer(HSIZE_T) :: num_data_in_file
  1307) #endif
  1308)  
  1309)   PetscMPIInt :: rank_mpi
  1310)   ! seeting to MPIInt to ensure i4
  1311)   integer, allocatable :: indices_i4(:)
  1312)   
  1313)   PetscInt :: istart, iend
  1314) 
  1315)   call PetscLogEventBegin(logging%event_read_indices_hdf5,ierr);CHKERRQ(ierr)
  1316)                         
  1317)   istart = 0  ! this will be zero-based
  1318)   iend = 0
  1319)   
  1320)   ! first determine upper and lower bound on PETSc global array
  1321)   call MPI_Scan(grid%nlmax,iend,ONE_INTEGER_MPI,MPIU_INTEGER,MPI_SUM, &
  1322)                 option%mycomm,ierr)
  1323)   istart = iend - grid%nlmax
  1324)   
  1325)   ! should be a rank=1 data space
  1326)   call fscorpio_get_dataset_size( num_data_in_file, file_id, dataset_name, &
  1327)           option%ioread_group_id, ierr)
  1328)   globaldims(1) = num_data_in_file 
  1329) !???? get size of dataset  call h5sget_simple_extent_npoints_f(file_space_id,num_data_in_file,hdf5_err)
  1330)   !if (dataset_size > 0 .and. num_data_in_file /= dataset_size) then
  1331)   !  write(option%io_buffer, &
  1332)   !        '(a," data space dimension (",i9,") does not match the dimensions",&
  1333)   !         &" of the domain (",i9,").")') trim(dataset_name), &
  1334)   !         num_data_in_file,dataset_size
  1335)   !  call printErrMsg(option)   
  1336)   !else
  1337)   !  dataset_size = num_data_in_file
  1338)   !endif  
  1339)   
  1340)   dataset_size = int(num_data_in_file)
  1341) 
  1342)   if (istart < num_data_in_file) then
  1343)   
  1344)     allocate(indices_i4(-1:iend-istart))
  1345)     allocate(indices(-1:iend-istart))
  1346)     indices_i4(-1) = istart
  1347)     indices_i4(0) = iend
  1348)   
  1349)     rank_mpi = 1
  1350)     offset = 0
  1351)     length = 0
  1352)     stride = 1
  1353)   
  1354)     dims = 0
  1355)     dims(1) = iend-istart
  1356)     memory_space_id = -1
  1357) 
  1358)     ! offset is zero-based
  1359)     offset(1) = istart
  1360)     length(1) = iend-istart
  1361)     call PetscLogEventBegin(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
  1362)                                
  1363)     call fscorpio_read_dataset(indices_i4(1:iend-istart), SCORPIO_INTEGER, rank_mpi, globaldims, dims, & 
  1364)             file_id, dataset_name, option%ioread_group_id, SCORPIO_NONUNIFORM_CONTIGUOUS_READ, ierr)
  1365)     !call h5dread_f(data_set_id,HDF_NATIVE_INTEGER,indices_i4(1:iend-istart), &
  1366)                    !dims,hdf5_err,memory_space_id,file_space_id,prop_id)                     
  1367)     call PetscLogEventEnd(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
  1368)     indices(-1:iend-istart) = indices_i4(-1:iend-istart)                
  1369)     deallocate(indices_i4)
  1370)   endif
  1371)   
  1372)   call PetscLogEventEnd(logging%event_read_indices_hdf5,ierr);CHKERRQ(ierr)
  1373) 
  1374) #else
  1375) ! SCORPIO is not defined
  1376) 
  1377) ! Default HDF5 Mechanism 
  1378) 
  1379)   type(grid_type) :: grid
  1380)   type(option_type) :: option
  1381)   character(len=MAXWORDLENGTH) :: dataset_name
  1382)   character(len=MAXSTRINGLENGTH) :: string
  1383)   PetscInt :: dataset_size
  1384)   integer(HID_T) :: file_id
  1385)   PetscInt, pointer :: indices(:)
  1386)   PetscInt :: num_indices
  1387)   
  1388)   integer(HID_T) :: file_space_id
  1389)   integer(HID_T) :: memory_space_id
  1390)   integer(HID_T) :: data_set_id
  1391)   integer(HID_T) :: prop_id
  1392)   integer(HSIZE_T) :: dims(3)
  1393)   integer(HSIZE_T) :: offset(3), length(3), stride(3)
  1394)   PetscMPIInt :: ndims
  1395)   PetscMPIInt :: rank_mpi
  1396)   ! seeting to MPIInt to ensure i4
  1397)   integer, allocatable :: indices_i4(:)
  1398)   integer(HSIZE_T) :: num_data_in_file
  1399)   integer(SIZE_T) :: string_size
  1400)   
  1401)   PetscInt :: istart, iend
  1402) 
  1403)   call PetscLogEventBegin(logging%event_read_indices_hdf5,ierr);CHKERRQ(ierr)
  1404)                         
  1405)   istart = 0  ! this will be zero-based
  1406)   iend = 0
  1407)   
  1408)   ! first determine upper and lower bound on PETSc global array
  1409)   call MPI_Scan(grid%nlmax,iend,ONE_INTEGER_MPI,MPIU_INTEGER,MPI_SUM, &
  1410)                 option%mycomm,ierr)
  1411)   istart = iend - grid%nlmax
  1412)   
  1413)   call h5dopen_f(file_id,dataset_name,data_set_id,hdf5_err)
  1414)   if (hdf5_err /= 0) then
  1415)     string_size = MAXSTRINGLENGTH
  1416)     call h5fget_name_f(file_id,string,string_size,hdf5_err)
  1417)     option%io_buffer = 'HDF5 dataset "' // trim(dataset_name) // '" not found &
  1418)       &in file "' // trim(string) // '".'
  1419)     call printErrMsg(option)
  1420)   endif
  1421)   call h5dget_space_f(data_set_id,file_space_id,hdf5_err)
  1422)   ! should be a rank=1 data space
  1423)   call h5sget_simple_extent_ndims_f(file_space_id,ndims,hdf5_err)
  1424)   if (ndims /= 1) then
  1425)     write(option%io_buffer, &
  1426)           '(a," data space dimension (",i2,"D) must be 1D.")') &
  1427)           trim(dataset_name), ndims
  1428)     call printErrMsg(option)
  1429)   endif
  1430)   call h5sget_simple_extent_npoints_f(file_space_id,num_data_in_file,hdf5_err)
  1431)   if (dataset_size > 0 .and. num_data_in_file /= dataset_size) then
  1432)     write(option%io_buffer, &
  1433)           '(a," data space dimension (",i9,") does not match the dimensions",&
  1434)            &" of the domain (",i9,").")') trim(dataset_name), &
  1435)            num_data_in_file,dataset_size
  1436)     call printErrMsg(option)   
  1437)   else
  1438)     dataset_size = int(num_data_in_file)
  1439)   endif  
  1440)   
  1441)   if (istart < num_data_in_file) then
  1442)   
  1443)     allocate(indices_i4(-1:iend-istart))
  1444)     allocate(indices(-1:iend-istart))
  1445)     indices_i4(-1) = istart
  1446)     indices_i4(0) = iend
  1447)   
  1448)     rank_mpi = 1
  1449)     offset = 0
  1450)     length = 0
  1451)     stride = 1
  1452)   
  1453)     call h5pcreate_f(H5P_DATASET_XFER_F,prop_id,hdf5_err)
  1454) #ifndef SERIAL_HDF5
  1455)     call h5pset_dxpl_mpio_f(prop_id,H5FD_MPIO_INDEPENDENT_F,hdf5_err)
  1456) #endif
  1457)   
  1458)     dims = 0
  1459)     dims(1) = iend-istart
  1460)     memory_space_id = -1
  1461)     call h5screate_simple_f(rank_mpi,dims,memory_space_id,hdf5_err,dims)
  1462) 
  1463)     ! offset is zero-based
  1464)     offset(1) = istart
  1465)     length(1) = iend-istart
  1466)     call h5sselect_hyperslab_f(file_space_id,H5S_SELECT_SET_F,offset, &
  1467)                                length,hdf5_err,stride,stride) 
  1468)     call PetscLogEventBegin(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
  1469)                                
  1470)     call h5dread_f(data_set_id,HDF_NATIVE_INTEGER,indices_i4(1:iend-istart), &
  1471)                    dims,hdf5_err,memory_space_id,file_space_id,prop_id)                     
  1472)     call PetscLogEventEnd(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
  1473)     indices(-1:iend-istart) = indices_i4(-1:iend-istart)                
  1474)     deallocate(indices_i4)
  1475)   endif
  1476)   
  1477)   call h5pclose_f(prop_id,hdf5_err)
  1478)   call h5sclose_f(memory_space_id,hdf5_err)
  1479)   call h5sclose_f(file_space_id,hdf5_err)
  1480)   call h5dclose_f(data_set_id,hdf5_err)
  1481) 
  1482)   call PetscLogEventEnd(logging%event_read_indices_hdf5,ierr);CHKERRQ(ierr)
  1483) ! End of Default HDF5 Mechanism  
  1484)   
  1485) #endif
  1486) ! SCORPIO
  1487)   
  1488) end subroutine HDF5ReadIndices
  1489) 
  1490) ! ************************************************************************** !
  1491) 
  1492) subroutine HDF5ReadArray(discretization,grid,option,file_id,dataset_name, &
  1493)                          dataset_size, &
  1494)                          indices,global_vec,data_type)
  1495)   ! 
  1496)   ! Read an hdf5 array into a Petsc Vec
  1497)   ! 
  1498)   ! Author: Glenn Hammond
  1499)   ! Date: 01/12/08
  1500)   ! 
  1501)                          
  1502)   use hdf5
  1503)   
  1504)   use Option_module
  1505)   use Grid_module
  1506)   use Discretization_module
  1507)   use Utility_module, only : DeallocateArray
  1508)   
  1509)   implicit none
  1510) 
  1511) #include "petsc/finclude/petscvec.h"
  1512) #include "petsc/finclude/petscvec.h90"
  1513) 
  1514) #if defined(SCORPIO)
  1515)  
  1516)   type(discretization_type) :: discretization
  1517)   type(grid_type) :: grid
  1518)   type(option_type) :: option
  1519)   character(len=MAXWORDLENGTH) :: dataset_name
  1520)   PetscInt :: dataset_size
  1521)   integer(HID_T) :: file_id
  1522)   PetscInt, pointer :: indices(:)
  1523)   PetscInt :: num_indices
  1524)   Vec :: global_vec
  1525)   integer :: data_type 
  1526)   
  1527)   integer :: file_space_id
  1528)   integer :: memory_space_id
  1529)   integer :: data_set_id
  1530)   integer :: prop_id
  1531)   integer :: dims(3), globaldims(3)
  1532)   integer :: offset(3), length(3), stride(3)
  1533)   PetscMPIInt :: rank_mpi
  1534)   integer :: num_data_in_file
  1535)   Vec :: natural_vec
  1536)   PetscInt :: i, istart, iend
  1537)   PetscReal, allocatable :: real_buffer(:)
  1538)   integer, allocatable :: integer_buffer_i4(:)
  1539)   PetscInt, allocatable :: indices0(:)
  1540)   
  1541)   call PetscLogEventBegin(logging%event_read_array_hdf5,ierr);CHKERRQ(ierr)
  1542)                           
  1543)   istart = 0
  1544)   iend = 0
  1545)   
  1546)   ! should be a rank=1 data space
  1547) 
  1548)   call fscorpio_get_dataset_size( num_data_in_file, file_id, dataset_name, &
  1549)           option%ioread_group_id, ierr)
  1550)   globaldims(1) = num_data_in_file
  1551) !???? get size   call h5sget_simple_extent_npoints_f(file_space_id,num_data_in_file,hdf5_err)
  1552) 
  1553)   !if (dataset_size > 0 .and. num_data_in_file /= dataset_size) then
  1554)   !  write(option%io_buffer, &
  1555)   !        '(a," data space dimension (",i9,") does not match the dimensions",&
  1556)   !         &" of the domain (",i9,").")') trim(dataset_name), &
  1557)   !         num_data_in_file,grid%nmax
  1558)   !  call printErrMsg(option)   
  1559)   !endif
  1560) 
  1561)   rank_mpi = 1
  1562)   offset = 0
  1563)   length = 0
  1564)   stride = 1
  1565)   
  1566)   call DiscretizationCreateVector(discretization,ONEDOF, &
  1567)                                   natural_vec,NATURAL,option)
  1568)   call VecZeroEntries(natural_vec,ierr);CHKERRQ(ierr)
  1569) 
  1570)   ! must initialize here to avoid error below when closing memory space
  1571)   memory_space_id = -1
  1572) 
  1573)   if (associated(indices)) then
  1574) 
  1575)     istart = indices(-1)
  1576)     iend = indices(0)
  1577) 
  1578)     dims = 0
  1579)     dims(1) = iend-istart
  1580) 
  1581)     ! offset is zero-based
  1582)     offset(1) = istart
  1583)     length(1) = iend-istart
  1584)     allocate(real_buffer(iend-istart))
  1585)     if (data_type == H5T_NATIVE_DOUBLE) then
  1586)       call PetscLogEventBegin(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
  1587)     
  1588)       call fscorpio_read_dataset(real_buffer, SCORPIO_DOUBLE, rank_mpi, globaldims, dims, & 
  1589)             file_id, dataset_name, option%ioread_group_id, SCORPIO_NONUNIFORM_CONTIGUOUS_READ, ierr)
  1590)       !call h5dread_f(data_set_id,H5T_NATIVE_DOUBLE,real_buffer,dims, &
  1591)                      !hdf5_err,memory_space_id,file_space_id,prop_id)
  1592)       call PetscLogEventEnd(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
  1593)     else if (data_type == HDF_NATIVE_INTEGER) then
  1594)       allocate(integer_buffer_i4(iend-istart))
  1595)       call PetscLogEventBegin(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
  1596) 
  1597)       call fscorpio_read_dataset(integer_buffer_i4, SCORPIO_INTEGER, rank_mpi, globaldims, dims, & 
  1598)             file_id, dataset_name, option%ioread_group_id, SCORPIO_NONUNIFORM_CONTIGUOUS_READ, ierr)
  1599)       !call h5dread_f(data_set_id,HDF_NATIVE_INTEGER,integer_buffer_i4,dims, &
  1600)                      !hdf5_err,memory_space_id,file_space_id,prop_id)
  1601)       call PetscLogEventEnd(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
  1602)       do i=1,iend-istart
  1603)         real_buffer(i) = real(integer_buffer_i4(i))
  1604)       enddo
  1605)       deallocate(integer_buffer_i4)
  1606)     endif
  1607)     ! must convert indices to zero based for VecSetValues
  1608)     allocate(indices0(iend-istart))
  1609)     indices0 = indices(1:iend-istart)-1
  1610)     call VecSetValues(natural_vec,iend-istart,indices0, &
  1611)                       real_buffer,INSERT_VALUES,ierr);CHKERRQ(ierr)
  1612)     deallocate(indices0)
  1613)     deallocate(real_buffer)
  1614) 
  1615)   endif
  1616) 
  1617)   call VecAssemblyBegin(natural_vec,ierr);CHKERRQ(ierr)
  1618)   call VecAssemblyEnd(natural_vec,ierr);CHKERRQ(ierr)
  1619)   call DiscretizationNaturalToGlobal(discretization,natural_vec,global_vec, &
  1620)                                      ONEDOF)
  1621)   call VecDestroy(natural_vec,ierr);CHKERRQ(ierr)
  1622)   
  1623)   call PetscLogEventEnd(logging%event_read_array_hdf5,ierr);CHKERRQ(ierr)
  1624) 
  1625) #else
  1626) ! SCORPIO is not defined
  1627) 
  1628) ! Default HDF5 Mechanism 
  1629)  
  1630)   type(discretization_type) :: discretization
  1631)   type(grid_type) :: grid
  1632)   type(option_type) :: option
  1633)   character(len=MAXWORDLENGTH) :: dataset_name
  1634)   character(len=MAXSTRINGLENGTH) :: string
  1635)   PetscInt :: dataset_size
  1636)   integer(HID_T) :: file_id
  1637)   PetscInt, pointer :: indices(:)
  1638)   PetscInt :: num_indices
  1639)   Vec :: global_vec
  1640)   integer(HID_T) :: data_type 
  1641)   
  1642)   integer(HID_T) :: file_space_id
  1643)   integer(HID_T) :: memory_space_id
  1644)   integer(HID_T) :: data_set_id
  1645)   integer(HID_T) :: prop_id
  1646)   integer(HSIZE_T) :: dims(3)
  1647)   integer(HSIZE_T) :: offset(3), length(3), stride(3)
  1648)   PetscMPIInt :: rank_mpi
  1649)   PetscMPIInt :: ndims
  1650)   integer(HSIZE_T) :: num_data_in_file
  1651)   integer(SIZE_T) :: string_size
  1652)   Vec :: natural_vec
  1653)   PetscInt :: i, istart, iend
  1654)   PetscReal, allocatable :: real_buffer(:)
  1655)   integer, allocatable :: integer_buffer_i4(:)
  1656)   PetscInt, allocatable :: indices0(:)
  1657)   
  1658)   call PetscLogEventBegin(logging%event_read_array_hdf5,ierr);CHKERRQ(ierr)
  1659)                           
  1660)   istart = 0
  1661)   iend = 0
  1662)   
  1663)   call h5dopen_f(file_id,dataset_name,data_set_id,hdf5_err)
  1664)   if (hdf5_err /= 0) then
  1665)     string_size = MAXSTRINGLENGTH
  1666)     call h5fget_name_f(file_id,string,string_size,hdf5_err)
  1667)     option%io_buffer = 'HDF5 dataset "' // trim(dataset_name) // '" not found &
  1668)       &in file "' // trim(string) // '".'
  1669)     call printErrMsg(option)
  1670)   endif
  1671)   call h5dget_space_f(data_set_id,file_space_id,hdf5_err)
  1672)   ! should be a rank=1 data space
  1673)   call h5sget_simple_extent_ndims_f(file_space_id,ndims,hdf5_err)
  1674)   if (ndims /= 1) then
  1675)     write(option%io_buffer, &
  1676)           '(a," data space dimension (",i2,"D) must be 1D.")') &
  1677)           trim(dataset_name), ndims
  1678)     call printErrMsg(option)
  1679)   endif
  1680)   call h5sget_simple_extent_npoints_f(file_space_id,num_data_in_file,hdf5_err)
  1681) 
  1682)   if (dataset_size > 0 .and. num_data_in_file /= dataset_size) then
  1683)     write(option%io_buffer, &
  1684)           '(a," data space dimension (",i9,") does not match the dimensions",&
  1685)            &" of the domain (",i9,").")') trim(dataset_name), &
  1686)            num_data_in_file,grid%nmax
  1687)     call printErrMsg(option)   
  1688)   endif
  1689) 
  1690)   rank_mpi = 1
  1691)   offset = 0
  1692)   length = 0
  1693)   stride = 1
  1694)   
  1695)   call h5pcreate_f(H5P_DATASET_XFER_F,prop_id,hdf5_err)
  1696) #ifndef SERIAL_HDF5
  1697)   call h5pset_dxpl_mpio_f(prop_id,H5FD_MPIO_INDEPENDENT_F,hdf5_err)
  1698) #endif
  1699) 
  1700)   call DiscretizationCreateVector(discretization,ONEDOF, &
  1701)                                   natural_vec,NATURAL,option)
  1702)   call VecZeroEntries(natural_vec,ierr);CHKERRQ(ierr)
  1703) 
  1704)   ! must initialize here to avoid error below when closing memory space
  1705)   memory_space_id = -1
  1706) 
  1707)   if (associated(indices)) then
  1708) 
  1709)     istart = indices(-1)
  1710)     iend = indices(0)
  1711) 
  1712)     dims = 0
  1713)     dims(1) = iend-istart
  1714)     call h5screate_simple_f(rank_mpi,dims,memory_space_id,hdf5_err,dims)
  1715) 
  1716)     ! offset is zero-based
  1717)     offset(1) = istart
  1718)     length(1) = iend-istart
  1719)     call h5sselect_hyperslab_f(file_space_id, H5S_SELECT_SET_F,offset, &
  1720)                                length,hdf5_err,stride,stride) 
  1721)     allocate(real_buffer(iend-istart))
  1722)     if (data_type == H5T_NATIVE_DOUBLE) then
  1723)       call PetscLogEventBegin(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
  1724)       call h5dread_f(data_set_id,H5T_NATIVE_DOUBLE,real_buffer,dims, &
  1725)                      hdf5_err,memory_space_id,file_space_id,prop_id)
  1726)       call PetscLogEventEnd(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
  1727)     else if (data_type == HDF_NATIVE_INTEGER) then
  1728)       allocate(integer_buffer_i4(iend-istart))
  1729)       call PetscLogEventBegin(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
  1730)       call h5dread_f(data_set_id,HDF_NATIVE_INTEGER,integer_buffer_i4,dims, &
  1731)                      hdf5_err,memory_space_id,file_space_id,prop_id)
  1732)       call PetscLogEventEnd(logging%event_h5dread_f,ierr);CHKERRQ(ierr)
  1733)       do i=1,iend-istart
  1734)         real_buffer(i) = real(integer_buffer_i4(i))
  1735)       enddo
  1736)       deallocate(integer_buffer_i4)
  1737)     endif
  1738)     ! must convert indices to zero based for VecSetValues
  1739)     allocate(indices0(iend-istart))
  1740)     indices0 = indices(1:iend-istart)-1
  1741)     call VecSetValues(natural_vec,iend-istart,indices0, &
  1742)                       real_buffer,INSERT_VALUES,ierr);CHKERRQ(ierr)
  1743)     deallocate(indices0)
  1744)     deallocate(real_buffer)
  1745) 
  1746)   endif
  1747) 
  1748)   call h5pclose_f(prop_id,hdf5_err)
  1749)   if (memory_space_id > -1) call h5sclose_f(memory_space_id,hdf5_err)
  1750)   call h5sclose_f(file_space_id,hdf5_err)
  1751)   call h5dclose_f(data_set_id,hdf5_err)
  1752) 
  1753)   call VecAssemblyBegin(natural_vec,ierr);CHKERRQ(ierr)
  1754)   call VecAssemblyEnd(natural_vec,ierr);CHKERRQ(ierr)
  1755)   call DiscretizationNaturalToGlobal(discretization,natural_vec,global_vec, &
  1756)                                      ONEDOF)
  1757)   call VecDestroy(natural_vec,ierr);CHKERRQ(ierr)
  1758)   
  1759)   call PetscLogEventEnd(logging%event_read_array_hdf5,ierr);CHKERRQ(ierr)
  1760) ! End of Default HDF5 Mechanism
  1761) 
  1762) #endif
  1763) ! SCORPIO
  1764) 
  1765) end subroutine HDF5ReadArray
  1766) 
  1767) #endif
  1768) 
  1769) ! ************************************************************************** !
  1770) 
  1771) subroutine HDF5QueryRegionDefinition(region, filename, option, &
  1772)      cell_ids_exists, face_ids_exists, vert_ids_exists)
  1773) 
  1774)   !
  1775)   ! Queries HDF5 to determine with region definition includes which groups:
  1776)   !
  1777)   ! cell_ids_exits = true if "Regions/<Region Name>/Cell Ids" exists
  1778)   ! face_ids_exits = true if "Regions/<Region Name>/Face Ids" exists
  1779)   ! vert_ids_exits = true if "Regions/<Region Name>/Vertex Ids" exists
  1780)   !
  1781)   ! Author: Gautam Bisht, LBNL
  1782)   ! Date: 10/21/2015
  1783)   !
  1784) 
  1785) #if defined(PETSC_HAVE_HDF5)
  1786)   use hdf5
  1787) #endif
  1788) 
  1789)   use Option_module
  1790)   use Grid_module
  1791)   use Region_module
  1792)   use Patch_module
  1793)   use HDF5_Aux_module
  1794) 
  1795)   implicit none
  1796) 
  1797)   type(region_type) :: region
  1798)   character(len=MAXSTRINGLENGTH) :: filename
  1799)   PetscBool, intent (out) :: cell_ids_exists
  1800)   PetscBool, intent (out) :: face_ids_exists
  1801)   PetscBool, intent (out) :: vert_ids_exists
  1802) 
  1803)   type(option_type), pointer :: option
  1804) 
  1805)   character(len=MAXSTRINGLENGTH) :: string
  1806) 
  1807) #if defined(PETSC_HAVE_HDF5)
  1808)   integer(HID_T) :: file_id
  1809)   integer(HID_T) :: grp_id, grp_id2
  1810)   integer(HID_T) :: prop_id
  1811) #endif
  1812) 
  1813)   PetscBool :: grp_exists
  1814) 
  1815) #if !defined(PETSC_HAVE_HDF5)
  1816)   call printMsg(option,'')
  1817)   write(option%io_buffer,'("PFLOTRAN must be compiled with HDF5 to ", &
  1818)                            &"read HDF5 formatted structured grids.")')
  1819)   call printErrMsg(option)
  1820) #else
  1821) 
  1822)   ! initialize fortran hdf5 interface
  1823)   call h5open_f(hdf5_err)
  1824)   option%io_buffer = 'Opening hdf5 file: ' // trim(filename)
  1825)   call printMsg(option)
  1826)   call h5pcreate_f(H5P_FILE_ACCESS_F,prop_id,hdf5_err)
  1827) #ifndef SERIAL_HDF5
  1828)   call h5pset_fapl_mpio_f(prop_id,option%mycomm,MPI_INFO_NULL,hdf5_err)
  1829) #endif
  1830)   call HDF5OpenFileReadOnly(filename,file_id,prop_id,option)
  1831)   call h5pclose_f(prop_id,hdf5_err)
  1832) 
  1833)   ! Open the Regions group
  1834)   string = 'Regions'
  1835)   call h5gopen_f(file_id,string,grp_id,hdf5_err)
  1836) 
  1837)   ! Open the Regions group
  1838)   string = trim(region%name)
  1839)   call h5gopen_f(grp_id,string,grp_id2,hdf5_err)
  1840)   if (hdf5_err /= 0) then
  1841)     option%io_buffer = 'HDF5 group "' // trim(region%name) // '" not found.'
  1842)     call printErrMsg(option)
  1843)   endif
  1844) 
  1845)   ! Querry region definition
  1846)   string = "Cell Ids"
  1847)   call h5lexists_f(grp_id2, string, cell_ids_exists, hdf5_err)
  1848) 
  1849)   string = "Face Ids"
  1850)   call h5lexists_f(grp_id2, string, face_ids_exists, hdf5_err)
  1851) 
  1852)   string = "Vertex Ids"
  1853)   call h5lexists_f(grp_id2, string, vert_ids_exists, hdf5_err)
  1854) 
  1855)   call h5gclose_f(grp_id2,hdf5_err)
  1856)   call h5gclose_f(grp_id,hdf5_err)
  1857)   call h5fclose_f(file_id,hdf5_err)
  1858)   call h5close_f(hdf5_err)
  1859) #endif
  1860) 
  1861) end subroutine HDF5QueryRegionDefinition
  1862) 
  1863) ! ************************************************************************** !
  1864) 
  1865) subroutine HDF5ReadRegionFromFile(grid,region,filename,option)
  1866)   ! 
  1867)   ! PETSC_HAVE_HDF5
  1868)   ! Reads a region from an hdf5 file
  1869)   ! 
  1870)   ! Author: Glenn Hammond
  1871)   ! Date: 1/3/08
  1872)   ! 
  1873) 
  1874) #if defined(PETSC_HAVE_HDF5)
  1875)   use hdf5
  1876) #endif
  1877)   
  1878)   use Realization_Subsurface_class
  1879)   use Option_module
  1880)   use Grid_module
  1881)   use Region_module
  1882)   use Patch_module
  1883)   use HDF5_Aux_module
  1884)   use Utility_module, only : DeallocateArray
  1885)   
  1886)   implicit none
  1887) 
  1888) #include "petsc/finclude/petscvec.h"
  1889) #include "petsc/finclude/petscvec.h90"
  1890) 
  1891)   type(option_type), pointer :: option
  1892)   type(region_type) :: region
  1893)   character(len=MAXSTRINGLENGTH) :: filename
  1894) 
  1895)   type(grid_type), pointer :: grid
  1896)   type(patch_type), pointer :: patch  
  1897) 
  1898)   character(len=MAXSTRINGLENGTH) :: string 
  1899) 
  1900) #if defined(PETSC_HAVE_HDF5)  
  1901)   integer(HID_T) :: file_id
  1902)   integer(HID_T) :: grp_id, grp_id2
  1903)   integer(HID_T) :: prop_id
  1904) #endif
  1905) 
  1906)   PetscInt :: num_indices, i, local_id
  1907)   PetscInt, pointer :: indices(:)
  1908)   PetscInt, pointer :: integer_array(:)
  1909) 
  1910)   PetscBool :: grp_exists
  1911) 
  1912) #if !defined(PETSC_HAVE_HDF5)
  1913)   call printMsg(option,'')
  1914)   write(option%io_buffer,'("PFLOTRAN must be compiled with HDF5 to ", &
  1915)                            &"read HDF5 formatted structured grids.")')
  1916)   call printErrMsg(option)
  1917) #else
  1918) 
  1919)   call PetscLogEventBegin(logging%event_region_read_hdf5,ierr);CHKERRQ(ierr)
  1920)                           
  1921)   ! create hash table for fast lookup
  1922)   call GridCreateNaturalToGhostedHash(grid,option)
  1923) 
  1924) #if defined(SCORPIO)
  1925)   if (mod(option%myrank,option%hdf5_read_group_size) == 0) then
  1926)       option%io_buffer = 'Opening hdf5 file: ' // trim(filename)
  1927)       call printMsg(option)
  1928)   endif
  1929) 
  1930)   filename = trim(filename) // CHAR(0)
  1931)   call fscorpio_open_file(filename, option%ioread_group_id, &
  1932)                          SCORPIO_FILE_READONLY, file_id, ierr)
  1933) 
  1934)   allocate(indices(grid%nlmax))
  1935)   ! Read Cell Ids  
  1936)   string = 'Regions/' // trim(region%name) // "/Cell Ids" // CHAR(0)
  1937)   ! num_indices <= 0 indicates that the array size is uncertain and
  1938)   ! the size will be returned in num_indices
  1939)   num_indices = -1
  1940)   call HDF5MapLocalToNaturalIndices(grid,option,file_id,string,ZERO_INTEGER, &
  1941)                                     indices,num_indices)
  1942)   allocate(integer_array(num_indices))
  1943)   integer_array = 0
  1944)   string = '/Regions/' // trim(region%name) // '/Cell Ids' //CHAR(0)
  1945)   option%io_buffer = 'Reading dataset: ' // trim(string)
  1946)   call printMsg(option)   
  1947)   call HDF5ReadIntegerArray(option,file_id,string, &
  1948)                             ZERO_INTEGER,indices,num_indices, &
  1949)                             integer_array)
  1950) 
  1951)   ! convert cell ids from natural to local
  1952)   call PetscLogEventBegin(logging%event_hash_map,ierr);CHKERRQ(ierr)
  1953)   do i=1,num_indices
  1954)     integer_array(i) = &
  1955)       grid%nG2L(GridGetLocalGhostedIdFromHash(grid,integer_array(i))) 
  1956)   enddo
  1957)   call PetscLogEventEnd(logging%event_hash_map,ierr);CHKERRQ(ierr)
  1958)   region%cell_ids => integer_array
  1959)   region%def_type = DEFINED_BY_CELL_IDS
  1960)                             
  1961)   allocate(integer_array(num_indices))
  1962)   integer_array = 0
  1963)   string = '/Regions/' // trim(region%name) // '/Face Ids' //CHAR(0)
  1964)   ! Check if the region dataset has "Face Ids" group
  1965) !geh: h5lexists will not work here because the grp_id2 is not defined, and
  1966) !     even if file_id were used, it is a SCORPIO file handle, not a an HDF5 file
  1967) !     handle.  SCORPIO does provide a function 'fscorpio_group_exists', but this
  1968) !     will fail when called with reference to the DATASET 'Face Ids'; it only
  1969) !     works for groups.  Therefore, we need a function fscorpio_dataset_exists().!     Commenting out for now.
  1970) !  call h5lexists_f(grp_id2,string,grp_exists,hdf5_err)
  1971)   grp_exists = PETSC_TRUE !geh: remove when h5lexists_f is resolved.
  1972)   if (grp_exists) then
  1973)     option%io_buffer = 'Reading dataset: ' // trim(string)
  1974)     call printMsg(option)
  1975)     call HDF5ReadIntegerArray(option,file_id,string, &
  1976)                               ZERO_INTEGER,indices,num_indices, &
  1977)                               integer_array)
  1978)                             
  1979)     region%faces => integer_array
  1980)     region%def_type = DEFINED_BY_CELL_AND_FACE_IDS
  1981)   endif
  1982)   region%num_cells = num_indices
  1983)   call DeallocateArray(indices)
  1984) 
  1985)    if (mod(option%myrank,option%hdf5_read_group_size) == 0) then
  1986)        option%io_buffer = 'Closing hdf5 file: ' // trim(filename)
  1987)        call printMsg(option)   
  1988)    endif
  1989)    call fscorpio_close_file(file_id, option%ioread_group_id, ierr)
  1990) 
  1991)   call GridDestroyHashTable(grid)
  1992) 
  1993) ! SCORPIO
  1994) #else   
  1995) 
  1996)   ! initialize fortran hdf5 interface 
  1997)   call h5open_f(hdf5_err)
  1998)   option%io_buffer = 'Opening hdf5 file: ' // trim(filename)
  1999)   call printMsg(option)
  2000)   call h5pcreate_f(H5P_FILE_ACCESS_F,prop_id,hdf5_err)
  2001) #ifndef SERIAL_HDF5
  2002)   call h5pset_fapl_mpio_f(prop_id,option%mycomm,MPI_INFO_NULL,hdf5_err)
  2003) #endif
  2004)   call HDF5OpenFileReadOnly(filename,file_id,prop_id,option)
  2005)   call h5pclose_f(prop_id,hdf5_err)
  2006) 
  2007)   ! Open the Regions group
  2008)   string = 'Regions' 
  2009)   option%io_buffer = 'Opening group: ' // trim(string)
  2010)   call printMsg(option)  
  2011)   call h5gopen_f(file_id,string,grp_id,hdf5_err)
  2012) 
  2013)   ! Open the Regions group
  2014)   string = trim(region%name)
  2015)   option%io_buffer = 'Opening group: ' // trim(string)
  2016)   call printMsg(option)  
  2017)   call h5gopen_f(grp_id,string,grp_id2,hdf5_err)
  2018)   if (hdf5_err /= 0) then
  2019)     option%io_buffer = 'HDF5 group "' // trim(region%name) // '" not found.'
  2020)     call printErrMsg(option)
  2021)   endif
  2022) 
  2023)   allocate(indices(grid%nlmax))
  2024)   ! Read Cell Ids
  2025)   string = "Cell Ids"
  2026) 
  2027)   ! Check if the region dataset has "Cell Ids" group
  2028)   call h5lexists_f(grp_id2,string,grp_exists,hdf5_err)
  2029)   if (.not.grp_exists) then
  2030)     option%io_buffer = 'HDF5 group: "Regions/' // trim(region%name) // '/Cell Ids" not found.'
  2031)     call printErrMsg(option)
  2032)   endif
  2033) 
  2034)   ! num_indices <= 0 indicates that the array size is uncertain and
  2035)   ! the size will be returned in num_indices
  2036)   num_indices = -1
  2037)   call HDF5MapLocalToNaturalIndices(grid,option,grp_id2,string,ZERO_INTEGER, &
  2038)                                     indices,num_indices)
  2039)   allocate(integer_array(num_indices))
  2040)   integer_array = 0
  2041)   string = "Cell Ids"
  2042)   option%io_buffer = 'Reading dataset: ' // trim(string)
  2043)   call printMsg(option)   
  2044)   call HDF5ReadIntegerArray(option,grp_id2,string, &
  2045)                             ZERO_INTEGER,indices,num_indices, &
  2046)                             integer_array)
  2047) 
  2048)   ! convert cell ids from natural to local
  2049)   call PetscLogEventBegin(logging%event_hash_map,ierr);CHKERRQ(ierr)
  2050)   do i=1,num_indices
  2051)     integer_array(i) = grid%nG2L(GridGetLocalGhostedIdFromHash(grid,integer_array(i))) 
  2052)   enddo
  2053)   call PetscLogEventEnd(logging%event_hash_map,ierr);CHKERRQ(ierr)
  2054)   region%cell_ids => integer_array
  2055)   region%def_type = DEFINED_BY_CELL_IDS
  2056)                             
  2057)   string = "Face Ids"
  2058)   ! Check if the region dataset has "Face Ids" group
  2059)   call h5lexists_f(grp_id2,string,grp_exists,hdf5_err)
  2060)   if (grp_exists) then
  2061)     option%io_buffer = 'Reading dataset: ' // trim(string)
  2062)     call printMsg(option)
  2063)     allocate(integer_array(num_indices))
  2064)     integer_array = 0
  2065)     call HDF5ReadIntegerArray(option,grp_id2,string, &
  2066)                               ZERO_INTEGER,indices,num_indices, &
  2067)                               integer_array)
  2068)                             
  2069)     region%faces => integer_array
  2070)     region%def_type = DEFINED_BY_CELL_AND_FACE_IDS
  2071)   endif
  2072)   region%num_cells = num_indices
  2073)   call DeallocateArray(indices)
  2074) 
  2075)   option%io_buffer = 'Closing group: ' // trim(region%name)
  2076)   call printMsg(option)  
  2077)   call h5gclose_f(grp_id2,hdf5_err)
  2078)   option%io_buffer = 'Closing group: Regions'
  2079)   call printMsg(option)   
  2080)   call h5gclose_f(grp_id,hdf5_err)
  2081)   option%io_buffer = 'Closing hdf5 file: ' // trim(filename)
  2082)   call printMsg(option)   
  2083)   call h5fclose_f(file_id,hdf5_err)
  2084)   call h5close_f(hdf5_err)
  2085) 
  2086)   call GridDestroyHashTable(grid)
  2087) #endif  
  2088) ! if SCORPIO is not defined
  2089) 
  2090) #endif
  2091) !PETSC_HAVE_HDF5
  2092) 
  2093)   call PetscLogEventEnd(logging%event_region_read_hdf5,ierr);CHKERRQ(ierr)
  2094) 
  2095) end subroutine HDF5ReadRegionFromFile
  2096) 
  2097) ! ************************************************************************** !
  2098) 
  2099) subroutine HDF5ReadUnstructuredGridRegionFromFile(option,region,filename)
  2100)   ! 
  2101)   ! Reads a region from an hdf5 file
  2102)   ! for unstructured grid
  2103)   ! gb: modified the input argument, so it works for realization (subsurface)
  2104)   ! and surface_realization (surface-flow)
  2105)   ! subroutine HDF5ReadUnstructuredGridRegionFromFile(realization,region,filename)
  2106)   ! 
  2107)   ! Author: Gautam Bisht
  2108)   ! Date: 5/31/11
  2109)   ! 
  2110) 
  2111) #if defined(PETSC_HAVE_HDF5)
  2112)   use hdf5
  2113) #endif
  2114)   
  2115)   use Realization_Subsurface_class
  2116)   use Option_module
  2117)   use Grid_module
  2118)   use Region_module
  2119)   use Patch_module
  2120)   use HDF5_Aux_module
  2121)   use Grid_Unstructured_Cell_module
  2122)   use Utility_module, only : DeallocateArray
  2123)   
  2124)   implicit none
  2125) 
  2126) #include "petsc/finclude/petscvec.h"
  2127) #include "petsc/finclude/petscvec.h90"
  2128) 
  2129)   !class(realization_subsurface_type) :: realization
  2130)   type(option_type), pointer :: option
  2131)   type(region_type) :: region
  2132)   type(region_sideset_type),pointer :: sideset
  2133)   character(len=MAXSTRINGLENGTH) :: filename
  2134) 
  2135)   ! local
  2136)   !type(option_type), pointer :: option
  2137)   PetscMPIInt :: hdf5_err
  2138)   PetscMPIInt :: rank_mpi
  2139)   PetscInt :: remainder
  2140)   PetscInt :: istart, iend, ii, jj
  2141)   PetscInt, pointer :: int_buffer_1d(:)
  2142)   PetscInt, pointer :: int_buffer_2d(:,:)
  2143)   character(len=MAXSTRINGLENGTH) :: string
  2144)   character(len=MAXSTRINGLENGTH) :: string2
  2145) 
  2146) #if defined(PETSC_HAVE_HDF5)
  2147)   integer(HID_T) :: ndims
  2148)   integer(HID_T) :: file_id
  2149)   integer(HID_T) :: prop_id
  2150)   integer(HID_T) :: data_set_id
  2151)   integer(HID_T) :: data_space_id
  2152)   integer(HID_T) :: memory_space_id
  2153)   integer(HSIZE_T), allocatable :: dims_h5(:), max_dims_h5(:)
  2154)   integer(HSIZE_T) :: length(2), offset(2)
  2155)   integer(SIZE_T) :: string_size
  2156) #endif
  2157) 
  2158)   !option => realization%option
  2159) 
  2160) #if !defined(PETSC_HAVE_HDF5)
  2161)   call printMsg(option,'')
  2162)   write(option%io_buffer,'("PFLOTRAN must be compiled with HDF5 to ", &
  2163)                            &"read HDF5 formatted unstructured grids.")')
  2164)   call printErrMsg(option)
  2165) #else
  2166)   ! Initialize FORTRAN predefined datatypes
  2167)   call h5open_f(hdf5_err)
  2168) 
  2169)   ! Setup file access property with parallel I/O access
  2170)   call h5pcreate_f(H5P_FILE_ACCESS_F,prop_id,hdf5_err)
  2171) 
  2172) #ifndef SERIAL_HDF5
  2173)   call h5pset_fapl_mpio_f(prop_id,option%mycomm,MPI_INFO_NULL,hdf5_err)
  2174) #endif
  2175) 
  2176)   ! Open the file collectively
  2177)   call HDF5OpenFileReadOnly(filename,file_id,prop_id,option)
  2178)   call h5pclose_f(prop_id,hdf5_err)
  2179)   
  2180)   ! Open dataset
  2181)   string = 'Regions/'//trim(region%name)
  2182)   call h5dopen_f(file_id,string,data_set_id,hdf5_err)
  2183)   if (hdf5_err /= 0) then
  2184)     string_size = MAXSTRINGLENGTH
  2185)     call h5fget_name_f(file_id,string2,string_size,hdf5_err)
  2186)     option%io_buffer = 'HDF5 dataset "' // trim(string) // '" not found &
  2187)       &in file "' // trim(string2) // '".'
  2188)     call printErrMsg(option)
  2189)   endif
  2190) 
  2191)   ! Get dataset's dataspace
  2192)   call h5dget_space_f(data_set_id,data_space_id,hdf5_err)
  2193)   
  2194)   ! Get number of dimensions and check
  2195)   call h5sget_simple_extent_ndims_f(data_space_id,ndims,hdf5_err)
  2196)   if ((ndims > 2).or.(ndims < 1)) then
  2197)     option%io_buffer='Dimension of '//string//' dataset in ' // trim(filename) // &
  2198)      ' is > 2 or < 1.'
  2199)   call printErrMsg(option)
  2200)   endif
  2201)   
  2202)   ! Allocate memory
  2203)   allocate(dims_h5(ndims))
  2204)   allocate(max_dims_h5(ndims))
  2205)   
  2206)   ! Get dimensions of dataset
  2207)   call h5sget_simple_extent_dims_f(data_space_id,dims_h5,max_dims_h5,hdf5_err)
  2208)   
  2209)   select case(ndims)
  2210)     case(1)
  2211)     !
  2212)     !                    Read Cell IDs
  2213)     !
  2214)     region%def_type = DEFINED_BY_CELL_IDS
  2215)     region%num_cells = int(dims_h5(1)/option%mycommsize)
  2216)       remainder = int(dims_h5(1)) - region%num_cells*option%mycommsize
  2217)     if (option%myrank < remainder) region%num_cells = region%num_cells + 1
  2218)     
  2219)     ! Find istart and iend
  2220)     istart = 0
  2221)     iend   = 0
  2222)     call MPI_Exscan(region%num_cells,istart,ONE_INTEGER_MPI,MPIU_INTEGER, &
  2223)                     MPI_SUM,option%mycomm,ierr)
  2224)     call MPI_Scan(region%num_cells,iend,ONE_INTEGER_MPI,MPIU_INTEGER, &
  2225)                    MPI_SUM,option%mycomm,ierr)
  2226)   
  2227)     ! Determine the length and offset of data to be read by each processor
  2228)     length(1) = iend-istart
  2229)     offset(1) = istart
  2230) 
  2231)     !
  2232)     rank_mpi = 1
  2233)     memory_space_id = -1
  2234)   
  2235)     ! Create data space for dataset
  2236)     call h5screate_simple_f(rank_mpi, length, memory_space_id, hdf5_err)
  2237)   
  2238)     ! Select hyperslab
  2239)     call h5sselect_hyperslab_f(data_space_id,H5S_SELECT_SET_F,offset,length,hdf5_err)
  2240)   
  2241)     ! Initialize data buffer
  2242)     allocate(int_buffer_1d(length(1)))
  2243)     
  2244)     ! Create property list
  2245)     call h5pcreate_f(H5P_DATASET_XFER_F,prop_id,hdf5_err)
  2246) #ifndef SERIAL_HDF5
  2247)     call h5pset_dxpl_mpio_f(prop_id,H5FD_MPIO_COLLECTIVE_F,hdf5_err)
  2248) #endif
  2249)   
  2250)     ! Read the dataset collectively
  2251)     call h5dread_f(data_set_id,H5T_NATIVE_INTEGER,int_buffer_1d,&
  2252)                    dims_h5,hdf5_err,memory_space_id,data_space_id)
  2253) 
  2254)     ! allocate array to store vertices for each cell
  2255)     allocate(region%cell_ids(region%num_cells))
  2256)     region%cell_ids = 0
  2257) 
  2258)     ! It is assumed that cell ids in the HDF5 are 1-based. Converting them to
  2259)     ! 0-based
  2260)     do ii = 1,region%num_cells
  2261)       if (int_buffer_1d(ii) < 1 ) then
  2262)         write(option%io_buffer,'("Cell ids in the HDF5 for region less than 1")')
  2263)         call printErrMsg(option)
  2264)       endif
  2265)       region%cell_ids(ii) = int_buffer_1d(ii)
  2266)     enddo
  2267)      call DeallocateArray(int_buffer_1d)
  2268)     
  2269)   case(2)
  2270)     !
  2271)     !                  (i)  Read Vertices
  2272)     !                       OR
  2273)     !                  (ii) Cell IDs with face IDs
  2274)     !
  2275) 
  2276)     !gb: Cells IDs with face IDs - may not work now 12/22/11
  2277)     !region%num_verts = dims_h5(2)/option%mycommsize
  2278)     !  remainder = dims_h5(2) - region%num_verts*option%mycommsize
  2279)     region%sideset => RegionCreateSideset()
  2280)     sideset => region%sideset
  2281)     sideset%nfaces = int(dims_h5(2)/option%mycommsize)
  2282)     remainder = int(dims_h5(2)) - sideset%nfaces*option%mycommsize
  2283)     if (option%myrank < remainder) sideset%nfaces = sideset%nfaces + 1
  2284) 
  2285)      ! Find istart and iend
  2286)      istart = 0
  2287)      iend   = 0
  2288)      call MPI_Exscan(sideset%nfaces,istart,ONE_INTEGER_MPI,MPIU_INTEGER, &
  2289)                     MPI_SUM,option%mycomm,ierr)
  2290)      call MPI_Scan(sideset%nfaces,iend,ONE_INTEGER_MPI,MPIU_INTEGER, &
  2291)                    MPI_SUM,option%mycomm,ierr)
  2292)   
  2293)      ! Determine the length and offset of data to be read by each processor
  2294)      length(1) = dims_h5(1)
  2295)      length(2) = iend-istart
  2296)      offset(1) = 0
  2297)      offset(2) = istart
  2298)   
  2299)      !
  2300)      rank_mpi = 2
  2301)      memory_space_id = -1
  2302)   
  2303)      ! Create data space for dataset
  2304)      call h5screate_simple_f(rank_mpi, length, memory_space_id, hdf5_err)
  2305)   
  2306)      ! Select hyperslab
  2307)      call h5sselect_hyperslab_f(data_space_id,H5S_SELECT_SET_F,offset,length,hdf5_err)
  2308)   
  2309)      ! Initialize data buffer
  2310)      allocate(int_buffer_2d(length(1),length(2)))
  2311)   
  2312)      ! Create property list
  2313)      call h5pcreate_f(H5P_DATASET_XFER_F,prop_id,hdf5_err)
  2314) #ifndef SERIAL_HDF5
  2315)      call h5pset_dxpl_mpio_f(prop_id,H5FD_MPIO_COLLECTIVE_F,hdf5_err)
  2316) #endif
  2317)   
  2318)      ! Read the dataset collectively
  2319)      call h5dread_f(data_set_id,H5T_NATIVE_INTEGER,int_buffer_2d,&
  2320)           dims_h5,hdf5_err,memory_space_id,data_space_id)
  2321)      
  2322)      if (dims_h5(1) == 2) then
  2323)        !
  2324)        ! Input data is: Cell IDs + Face IDs
  2325)        !
  2326)        region%def_type = DEFINED_BY_CELL_AND_FACE_IDS
  2327)        region%num_cells = region%num_verts
  2328)        allocate(region%cell_ids(region%num_cells))
  2329)        allocate(region%faces(region%num_cells))
  2330)        region%num_verts = 0
  2331)        
  2332)        do ii = 1, region%num_cells
  2333)          region%cell_ids(ii) = int_buffer_2d(1,ii)
  2334)          region%faces(ii) = int_buffer_2d(2,ii)
  2335)        enddo
  2336)      else
  2337)        !
  2338)        ! Input data is list of Vertices
  2339)        !
  2340)        ! allocate array to store vertices for each cell
  2341)        region%def_type = DEFINED_BY_SIDESET_UGRID
  2342)        allocate(sideset%face_vertices(MAX_VERT_PER_FACE,sideset%nfaces))
  2343)        sideset%face_vertices = UNINITIALIZED_INTEGER
  2344)   
  2345)        do ii = 1,sideset%nfaces
  2346)         do jj = 2,int_buffer_2d(1,ii)+1
  2347)          sideset%face_vertices(jj-1,ii) = int_buffer_2d(jj,ii)
  2348)         enddo
  2349)        enddo
  2350)      endif
  2351)      call DeallocateArray(int_buffer_2d)
  2352)   end select
  2353)     
  2354)   deallocate(dims_h5)
  2355)   deallocate(max_dims_h5)
  2356) 
  2357)   call h5pclose_f(prop_id,hdf5_err)
  2358)   call h5sclose_f(memory_space_id,hdf5_err)
  2359)   call h5sclose_f(data_space_id,hdf5_err)
  2360)   call h5dclose_f(data_set_id,hdf5_err)
  2361)   call h5fclose_f(file_id,hdf5_err)
  2362)   call h5close_f(hdf5_err)
  2363) 
  2364) #endif
  2365) ! if defined(PETSC_HAVE_HDF5)
  2366) 
  2367) end subroutine HDF5ReadUnstructuredGridRegionFromFile
  2368) 
  2369) ! ************************************************************************** !
  2370) 
  2371) subroutine HDF5ReadRegionDefinedByVertex(option,region,filename)
  2372)   ! 
  2373)   ! Reads a region from an hdf5 file defined by Vertex Ids
  2374)   !
  2375)   ! Author: Gautam Bisht, LBNL
  2376)   ! Date: 10/21/11
  2377)   ! 
  2378) 
  2379) #if defined(PETSC_HAVE_HDF5)
  2380)   use hdf5
  2381) #endif
  2382) 
  2383)   use Realization_Subsurface_class
  2384)   use Option_module
  2385)   use Grid_module
  2386)   use Region_module
  2387)   use Patch_module
  2388)   use HDF5_Aux_module
  2389)   use Grid_Unstructured_Cell_module
  2390)   use Utility_module, only : DeallocateArray
  2391) 
  2392)   implicit none
  2393) 
  2394) #include "petsc/finclude/petscvec.h"
  2395) #include "petsc/finclude/petscvec.h90"
  2396) 
  2397)   !class(realization_subsurface_type) :: realization
  2398)   type(option_type), pointer :: option
  2399)   type(region_type) :: region
  2400)   type(region_sideset_type),pointer :: sideset
  2401)   character(len=MAXSTRINGLENGTH) :: filename
  2402) 
  2403)   ! local
  2404)   !type(option_type), pointer :: option
  2405)   PetscMPIInt :: hdf5_err
  2406)   PetscMPIInt :: rank_mpi
  2407)   PetscInt :: remainder
  2408)   PetscInt :: istart, iend, ii, jj
  2409)   PetscInt, pointer :: int_buffer_1d(:)
  2410)   PetscInt, pointer :: int_buffer_2d(:,:)
  2411)   character(len=MAXSTRINGLENGTH) :: string
  2412)   character(len=MAXSTRINGLENGTH) :: string2
  2413) 
  2414) #if defined(PETSC_HAVE_HDF5)
  2415)   integer(HID_T) :: ndims
  2416)   integer(HID_T) :: file_id
  2417)   integer(HID_T) :: prop_id
  2418)   integer(HID_T) :: data_set_id
  2419)   integer(HID_T) :: data_space_id
  2420)   integer(HID_T) :: memory_space_id
  2421)   integer(HSIZE_T), allocatable :: dims_h5(:), max_dims_h5(:)
  2422)   integer(HSIZE_T) :: length(2), offset(2)
  2423)   integer(SIZE_T) :: string_size
  2424) #endif
  2425) 
  2426) 
  2427) #if !defined(PETSC_HAVE_HDF5)
  2428)   call printMsg(option,'')
  2429)   write(option%io_buffer,'("PFLOTRAN must be compiled with HDF5 to ", &
  2430)                            &"read HDF5 formatted unstructured grids.")')
  2431)   call printErrMsg(option)
  2432) #else
  2433)   ! Initialize FORTRAN predefined datatypes
  2434)   call h5open_f(hdf5_err)
  2435) 
  2436)   ! Setup file access property with parallel I/O access
  2437)   call h5pcreate_f(H5P_FILE_ACCESS_F,prop_id,hdf5_err)
  2438) 
  2439) #ifndef SERIAL_HDF5
  2440)   call h5pset_fapl_mpio_f(prop_id,option%mycomm,MPI_INFO_NULL,hdf5_err)
  2441) #endif
  2442) 
  2443)   ! Open the file collectively
  2444)   call HDF5OpenFileReadOnly(filename,file_id,prop_id,option)
  2445)   call h5pclose_f(prop_id,hdf5_err)
  2446) 
  2447)   ! Open dataset
  2448)   string = 'Regions/' // trim(region%name) // '/Vertex Ids'
  2449)   call h5dopen_f(file_id,string,data_set_id,hdf5_err)
  2450)   if (hdf5_err /= 0) then
  2451)     string_size = MAXSTRINGLENGTH
  2452)     call h5fget_name_f(file_id,string2,string_size,hdf5_err)
  2453)     option%io_buffer = 'HDF5 dataset "' // trim(string) // '" not found &
  2454)       &in file "' // trim(string2) // '".'
  2455)     call printErrMsg(option)
  2456)   endif
  2457) 
  2458)   ! Get dataset's dataspace
  2459)   call h5dget_space_f(data_set_id,data_space_id,hdf5_err)
  2460) 
  2461)   ! Get number of dimensions and check
  2462)   call h5sget_simple_extent_ndims_f(data_space_id,ndims,hdf5_err)
  2463)   if (ndims /= 2) then
  2464)     option%io_buffer='Dimension of '//string//' dataset in ' // trim(filename) // &
  2465)      ' is /= 2.'
  2466)   call printErrMsg(option)
  2467)   endif
  2468) 
  2469)   ! Allocate memory
  2470)   allocate(dims_h5(ndims))
  2471)   allocate(max_dims_h5(ndims))
  2472) 
  2473)   ! Get dimensions of dataset
  2474)   call h5sget_simple_extent_dims_f(data_space_id,dims_h5,max_dims_h5,hdf5_err)
  2475) 
  2476)   ! Create storage for sideset
  2477)   region%sideset => RegionCreateSideset()
  2478)   sideset => region%sideset
  2479) 
  2480)   sideset%nfaces = int(dims_h5(2)/option%mycommsize)
  2481)   remainder = int(dims_h5(2)) - sideset%nfaces*option%mycommsize
  2482)   if (option%myrank < remainder) sideset%nfaces = sideset%nfaces + 1
  2483) 
  2484)   ! Find istart and iend
  2485)   istart = 0
  2486)   iend   = 0
  2487)   call MPI_Exscan(sideset%nfaces,istart,ONE_INTEGER_MPI,MPIU_INTEGER, &
  2488)                   MPI_SUM,option%mycomm,ierr)
  2489)   call MPI_Scan(sideset%nfaces,iend,ONE_INTEGER_MPI,MPIU_INTEGER, &
  2490)                 MPI_SUM,option%mycomm,ierr)
  2491) 
  2492)   ! Determine the length and offset of data to be read by each processor
  2493)   length(1) = dims_h5(1)
  2494)   length(2) = iend-istart
  2495)   offset(1) = 0
  2496)   offset(2) = istart
  2497) 
  2498)   !
  2499)   rank_mpi = 2
  2500)   memory_space_id = -1
  2501) 
  2502)   ! Create data space for dataset
  2503)   call h5screate_simple_f(rank_mpi, length, memory_space_id, hdf5_err)
  2504) 
  2505)   ! Select hyperslab
  2506)   call h5sselect_hyperslab_f(data_space_id,H5S_SELECT_SET_F,offset,length,hdf5_err)
  2507) 
  2508)   ! Initialize data buffer
  2509)   allocate(int_buffer_2d(length(1),length(2)))
  2510) 
  2511)   ! Create property list
  2512)   call h5pcreate_f(H5P_DATASET_XFER_F,prop_id,hdf5_err)
  2513) #ifndef SERIAL_HDF5
  2514)   call h5pset_dxpl_mpio_f(prop_id,H5FD_MPIO_COLLECTIVE_F,hdf5_err)
  2515) #endif
  2516) 
  2517)   ! Read the dataset collectively
  2518)   call h5dread_f(data_set_id,H5T_NATIVE_INTEGER,int_buffer_2d,&
  2519)        dims_h5,hdf5_err,memory_space_id,data_space_id)
  2520) 
  2521)   !
  2522)   ! Input data is list of Vertices
  2523)   !
  2524)   ! allocate array to store vertices for each cell
  2525)   region%def_type = DEFINED_BY_SIDESET_UGRID
  2526)   allocate(sideset%face_vertices(MAX_VERT_PER_FACE,sideset%nfaces))
  2527)   sideset%face_vertices = UNINITIALIZED_INTEGER
  2528) 
  2529)   do ii = 1,sideset%nfaces
  2530)      do jj = 1,int(dims_h5(1))
  2531)         sideset%face_vertices(jj,ii) = int_buffer_2d(jj,ii)
  2532)      enddo
  2533)   enddo
  2534)   call DeallocateArray(int_buffer_2d)
  2535) 
  2536)   deallocate(dims_h5)
  2537)   deallocate(max_dims_h5)
  2538) 
  2539)   call h5pclose_f(prop_id,hdf5_err)
  2540)   call h5sclose_f(memory_space_id,hdf5_err)
  2541)   call h5sclose_f(data_space_id,hdf5_err)
  2542)   call h5dclose_f(data_set_id,hdf5_err)
  2543)   call h5fclose_f(file_id,hdf5_err)
  2544)   call h5close_f(hdf5_err)
  2545) 
  2546) #endif
  2547) ! if defined(PETSC_HAVE_HDF5)
  2548) 
  2549) end subroutine HDF5ReadRegionDefinedByVertex
  2550) 
  2551) ! ************************************************************************** !
  2552) 
  2553) subroutine HDF5ReadCellIndexedIntegerArray(realization,global_vec,filename, &
  2554)                                            group_name, &
  2555)                                            dataset_name,append_realization_id)
  2556)   ! 
  2557)   ! Reads an array of integer values from an
  2558)   ! hdf5 file
  2559)   ! 
  2560)   ! Author: Glenn Hammond
  2561)   ! Date: 1/3/08; 02/18/09
  2562)   ! 
  2563) 
  2564) #if defined(PETSC_HAVE_HDF5)
  2565)   use hdf5
  2566) #endif
  2567)   
  2568)   use Realization_Subsurface_class
  2569)   use Discretization_module
  2570)   use Option_module
  2571)   use Grid_module
  2572)   use Field_module
  2573)   use Patch_module
  2574)   use HDF5_Aux_module
  2575)   use Utility_module, only : DeallocateArray
  2576)   
  2577)   implicit none
  2578) 
  2579) #include "petsc/finclude/petscvec.h"
  2580) #include "petsc/finclude/petscvec.h90"
  2581) 
  2582)   class(realization_subsurface_type) :: realization
  2583)   Vec :: global_vec
  2584)   character(len=MAXSTRINGLENGTH) :: filename
  2585)   character(len=MAXSTRINGLENGTH) :: group_name
  2586)   character(len=MAXSTRINGLENGTH) :: dataset_name
  2587)   PetscBool :: append_realization_id
  2588) 
  2589)   type(option_type), pointer :: option
  2590)   type(grid_type), pointer :: grid
  2591)   type(discretization_type), pointer :: discretization
  2592)   type(field_type), pointer :: field
  2593)   type(patch_type), pointer :: patch  
  2594) 
  2595)   character(len=MAXSTRINGLENGTH) :: string 
  2596) 
  2597) #if defined(PETSC_HAVE_HDF5)  
  2598)   integer(HID_T) :: file_id
  2599)   integer(HID_T) :: grp_id
  2600)   integer(HID_T) :: prop_id
  2601) #endif
  2602) 
  2603)   PetscLogDouble :: tstart, tend
  2604)   
  2605)   PetscInt, pointer :: indices(:)
  2606)   PetscInt, allocatable :: integer_array(:)
  2607)   
  2608) #if !defined(PETSC_HAVE_HDF5)
  2609)   option => realization%option
  2610)   call printMsg(option,'')
  2611)   write(option%io_buffer,'("PFLOTRAN must be compiled with HDF5 to ", &
  2612)                            &"read HDF5 formatted structured grids.")')
  2613)   call printErrMsg(option)
  2614) #else
  2615) 
  2616)   nullify(indices)
  2617) 
  2618)   option => realization%option
  2619)   discretization => realization%discretization
  2620)   patch => realization%patch
  2621)   grid => patch%grid
  2622)   field => realization%field
  2623) 
  2624)   call PetscLogEventBegin(logging%event_cell_indx_int_read_hdf5, &
  2625)                           ierr);CHKERRQ(ierr)
  2626)   
  2627) #if defined(SCORPIO)
  2628)   if (mod(option%myrank,option%hdf5_read_group_size) == 0) then  
  2629)      option%io_buffer = 'Opening hdf5 file: ' // trim(filename)
  2630)      call printMsg(option) 
  2631)   end if   
  2632)   filename = trim(filename) //CHAR(0)
  2633)   call fscorpio_open_file(filename, option%ioread_group_id, SCORPIO_FILE_READONLY, &
  2634)           file_id, ierr)
  2635) 
  2636)   ! Read Cell Ids
  2637)   call PetscTime(tstart,ierr);CHKERRQ(ierr)
  2638) 
  2639)   !if group_name exists
  2640)   if (len_trim(group_name) > 1) then
  2641)     string = trim(group_name) // "/Cell Ids" // CHAR(0)
  2642)   else
  2643)     string = "/Cell Ids" // CHAR(0)
  2644)   endif  
  2645)     
  2646)   call HDF5ReadIndices(grid,option,file_id,string,grid%nmax,indices)
  2647)   call PetscTime(tend,ierr);CHKERRQ(ierr)
  2648)   write(option%io_buffer,'(f6.2," Seconds to set up indices")') tend-tstart
  2649)   call printMsg(option)
  2650) 
  2651)   call PetscTime(tstart,ierr);CHKERRQ(ierr)
  2652)   string = ''
  2653)   if (append_realization_id) then
  2654)     write(string,'(i6)') option%id
  2655)   endif
  2656) 
  2657)   string = trim(dataset_name) // adjustl(trim(string))
  2658)   !if group_name exists
  2659)   if (len_trim(group_name) > 1) then
  2660)     string = trim(group_name) // '/' // trim(string) // CHAR(0)
  2661)   else
  2662)     string = trim(string) // CHAR(0)
  2663)   endif  
  2664) 
  2665)   option%io_buffer = 'Reading dataset: ' // trim(string)
  2666)   call printMsg(option)   
  2667) 
  2668)   call HDF5ReadArray(discretization,grid,option,file_id,string,grid%nmax, &
  2669)                      indices,global_vec,HDF_NATIVE_INTEGER)
  2670)   
  2671)   call PetscTime(tend,ierr);CHKERRQ(ierr)
  2672)   write(option%io_buffer,'(f6.2," Seconds to read integer array.")') &
  2673)     tend-tstart
  2674)   call printMsg(option)  
  2675) 
  2676)   call DeallocateArray(indices)
  2677) 
  2678)   if (mod(option%myrank,option%hdf5_read_group_size) == 0) then  
  2679)     option%io_buffer = 'Closing hdf5 file: ' // trim(filename)
  2680)     call printMsg(option)   
  2681)     call fscorpio_close_file(file_id, option%ioread_group_id, ierr)
  2682)   endif
  2683) 
  2684) #else
  2685) ! if SCORPIO is not defined
  2686) 
  2687)  ! initialize fortran hdf5 interface
  2688)   call h5open_f(hdf5_err)
  2689)   option%io_buffer = 'Opening hdf5 file: ' // trim(filename)
  2690)   call printMsg(option) 
  2691)   call h5pcreate_f(H5P_FILE_ACCESS_F,prop_id,hdf5_err)
  2692) #ifndef SERIAL_HDF5
  2693)   call h5pset_fapl_mpio_f(prop_id,option%mycomm,MPI_INFO_NULL,hdf5_err)
  2694) #endif
  2695)   call HDF5OpenFileReadOnly(filename,file_id,prop_id,option)
  2696)   call h5pclose_f(prop_id,hdf5_err)
  2697) 
  2698)   option%io_buffer = 'Setting up grid cell indices'
  2699)   call printMsg(option) 
  2700) 
  2701)   ! Open group if necessary
  2702)   if (len_trim(group_name) > 1) then
  2703)     option%io_buffer = 'Opening group: ' // trim(group_name)
  2704)     call printMsg(option)   
  2705)     call h5gopen_f(file_id,group_name,grp_id,hdf5_err)
  2706)   else
  2707)     grp_id = file_id
  2708)   endif
  2709) 
  2710)   ! Read Cell Ids
  2711)   call PetscTime(tstart,ierr);CHKERRQ(ierr)
  2712)   string = "Cell Ids"
  2713)   if (grp_id /= file_id) then
  2714)     option%io_buffer = 'Reading dataset: ' // trim(group_name) // '/' &
  2715)                        // trim(string)
  2716)   else
  2717)     option%io_buffer = 'Reading dataset: ' // trim(string)
  2718)   endif
  2719)   call printMsg(option)   
  2720)   call HDF5ReadIndices(grid,option,grp_id,string,grid%nmax,indices)
  2721)   call PetscTime(tend,ierr);CHKERRQ(ierr)
  2722)   write(option%io_buffer,'(f6.2," Seconds to set up indices")') tend-tstart
  2723)   call printMsg(option)
  2724) 
  2725) 
  2726)   call PetscTime(tstart,ierr);CHKERRQ(ierr)
  2727)   string = ''
  2728)   if (append_realization_id) then
  2729)     write(string,'(i6)') option%id
  2730)   endif
  2731)   string = trim(dataset_name) // adjustl(trim(string))
  2732)   if (grp_id /= file_id) then
  2733)     option%io_buffer = 'Reading dataset: ' // trim(group_name) // '/' &
  2734)                        // trim(string)
  2735)   else
  2736)     option%io_buffer = 'Reading dataset: ' // trim(string)
  2737)   endif
  2738)   call printMsg(option)   
  2739)   call HDF5ReadArray(discretization,grid,option,grp_id,string,grid%nmax, &
  2740)                      indices,global_vec,HDF_NATIVE_INTEGER)
  2741)   
  2742)   call PetscTime(tend,ierr);CHKERRQ(ierr)
  2743)   write(option%io_buffer,'(f6.2," Seconds to read integer array.")') &
  2744)     tend-tstart
  2745)   call printMsg(option)  
  2746) 
  2747)   call DeallocateArray(indices)
  2748) 
  2749)   if (file_id /= grp_id) then
  2750)     option%io_buffer = 'Closing group: ' // trim(group_name)
  2751)     call printMsg(option)   
  2752)     call h5gclose_f(grp_id,hdf5_err)
  2753)   endif
  2754)   option%io_buffer = 'Closing hdf5 file: ' // trim(filename)
  2755)   call printMsg(option)   
  2756)   call h5fclose_f(file_id,hdf5_err)
  2757)   call h5close_f(hdf5_err)
  2758) #endif  
  2759) ! if SCORPIO is not defined
  2760) 
  2761) #endif
  2762) ! PETSC_HAVE_HDF5
  2763) 
  2764)   call PetscLogEventEnd(logging%event_cell_indx_int_read_hdf5, &
  2765)                         ierr);CHKERRQ(ierr)
  2766)                           
  2767) end subroutine HDF5ReadCellIndexedIntegerArray
  2768) 
  2769) ! ************************************************************************** !
  2770) 
  2771) subroutine HDF5ReadCellIndexedRealArray(realization,global_vec,filename, &
  2772)                                         group_name, &
  2773)                                         dataset_name,append_realization_id)
  2774)   ! 
  2775)   ! Reads an array of real values from an hdf5 file
  2776)   ! 
  2777)   ! Author: Glenn Hammond
  2778)   ! Date: 01/16/09, 02/18/09
  2779)   ! 
  2780) 
  2781) #if defined(PETSC_HAVE_HDF5)
  2782)   use hdf5
  2783) #endif
  2784)   
  2785)   use Realization_Subsurface_class
  2786)   use Discretization_module
  2787)   use Option_module
  2788)   use Grid_module
  2789)   use Field_module
  2790)   use Patch_module
  2791)   use HDF5_Aux_module
  2792)   use Utility_module, only : DeallocateArray
  2793)   
  2794)   implicit none
  2795) 
  2796) #include "petsc/finclude/petscvec.h"
  2797) #include "petsc/finclude/petscvec.h90"
  2798) 
  2799)   class(realization_subsurface_type) :: realization
  2800)   Vec :: global_vec
  2801)   character(len=MAXSTRINGLENGTH) :: filename
  2802)   character(len=MAXSTRINGLENGTH) :: group_name
  2803)   character(len=MAXSTRINGLENGTH) :: dataset_name
  2804)   PetscBool :: append_realization_id
  2805) 
  2806)   type(option_type), pointer :: option
  2807)   type(grid_type), pointer :: grid
  2808)   type(discretization_type), pointer :: discretization
  2809)   type(field_type), pointer :: field
  2810)   type(patch_type), pointer :: patch  
  2811) 
  2812)   character(len=MAXSTRINGLENGTH) :: string 
  2813) 
  2814) #if defined(PETSC_HAVE_HDF5)  
  2815)   integer(HID_T) :: file_id
  2816)   integer(HID_T) :: grp_id
  2817)   integer(HID_T) :: prop_id
  2818) #endif
  2819) 
  2820)   PetscLogDouble :: tstart, tend
  2821)   
  2822)   PetscInt, pointer :: indices(:)
  2823)   PetscReal, allocatable :: real_array(:)
  2824)   
  2825) #if !defined(PETSC_HAVE_HDF5)
  2826)   option => realization%option
  2827)   call printMsg(option,'')
  2828)   write(option%io_buffer,'("PFLOTRAN must be compiled with HDF5 to ", &
  2829)                            &"read HDF5 formatted structured grids.")')
  2830)   call printErrMsg(option)
  2831) #else
  2832) 
  2833)   nullify(indices)
  2834) 
  2835)   option => realization%option
  2836)   discretization => realization%discretization
  2837)   patch => realization%patch
  2838)   grid => patch%grid
  2839)   field => realization%field
  2840) 
  2841)   call PetscLogEventBegin(logging%event_cell_indx_real_read_hdf5, &
  2842)                           ierr);CHKERRQ(ierr)
  2843) 
  2844) #if defined(SCORPIO)
  2845)   if (mod(option%myrank,option%hdf5_read_group_size) == 0) then  
  2846)      option%io_buffer = 'Opening hdf5 file: ' // trim(filename)
  2847)      call printMsg(option) 
  2848)   end if   
  2849)   filename = trim(filename) //CHAR(0)
  2850)   call fscorpio_open_file(filename, option%ioread_group_id, SCORPIO_FILE_READONLY, &
  2851)           file_id, ierr)
  2852) 
  2853) 
  2854) ! only new approach (old approach is removed)
  2855)   ! Read Cell Ids
  2856)   call PetscTime(tstart,ierr);CHKERRQ(ierr)
  2857) 
  2858)   !if group_name exists
  2859)   if (len_trim(group_name) > 1) then
  2860)     string = trim(group_name) // "/Cell Ids" // CHAR(0)
  2861)   else
  2862)     string = "/Cell Ids" // CHAR(0)
  2863)   endif  
  2864)     
  2865)   call HDF5ReadIndices(grid,option,file_id,string,grid%nmax,indices)
  2866)   call PetscTime(tend,ierr);CHKERRQ(ierr)
  2867)   write(option%io_buffer,'(f6.2," Seconds to set up indices")') tend-tstart
  2868)   call printMsg(option)
  2869) 
  2870)   call PetscTime(tstart,ierr);CHKERRQ(ierr)
  2871)   string = ''
  2872)   if (append_realization_id) then
  2873)     write(string,'(i6)') option%id
  2874)   endif
  2875) 
  2876)   string = trim(dataset_name) // adjustl(trim(string))
  2877)   !if group_name exists
  2878)   if (len_trim(group_name) > 1) then
  2879)     string = trim(group_name) // '/' // trim(string) // CHAR(0)
  2880)   else
  2881)     string = trim(string) // CHAR(0)
  2882)   endif  
  2883) 
  2884)   option%io_buffer = 'Reading dataset: ' // trim(string)
  2885)   call printMsg(option)   
  2886) 
  2887)   call HDF5ReadArray(discretization,grid,option,file_id,string,grid%nmax, &
  2888)                      indices,global_vec,H5T_NATIVE_DOUBLE)
  2889)   
  2890)   call PetscTime(tend,ierr);CHKERRQ(ierr)
  2891)   write(option%io_buffer,'(f6.2," Seconds to read real array.")') &
  2892)     tend-tstart
  2893)   call printMsg(option)  
  2894) 
  2895)   call DeallocateArray(indices)
  2896) 
  2897)   if (mod(option%myrank,option%hdf5_read_group_size) == 0) then  
  2898)     option%io_buffer = 'Closing hdf5 file: ' // trim(filename)
  2899)     call printMsg(option)   
  2900)     call fscorpio_close_file(file_id, option%ioread_group_id, ierr)
  2901)   endif
  2902) 
  2903) #else
  2904) ! if SCORPIO is not defined
  2905) 
  2906)   ! initialize fortran hdf5 interface
  2907)   call h5open_f(hdf5_err)
  2908)   option%io_buffer = 'Opening hdf5 file: ' // trim(filename)
  2909)   call printMsg(option) 
  2910)   call h5pcreate_f(H5P_FILE_ACCESS_F,prop_id,hdf5_err)
  2911) #ifndef SERIAL_HDF5
  2912)   call h5pset_fapl_mpio_f(prop_id,option%mycomm,MPI_INFO_NULL,hdf5_err)
  2913) #endif
  2914)   call HDF5OpenFileReadOnly(filename,file_id,prop_id,option)
  2915)   call h5pclose_f(prop_id,hdf5_err)
  2916) 
  2917)   option%io_buffer = 'Setting up grid cell indices'
  2918)   call printMsg(option) 
  2919) 
  2920)   ! Open group if necessary
  2921)   if (len_trim(group_name) > 1) then
  2922)     option%io_buffer = 'Opening group: ' // trim(group_name)
  2923)     call printMsg(option)   
  2924)     call h5gopen_f(file_id,group_name,grp_id,hdf5_err)
  2925)   else
  2926)     grp_id = file_id
  2927)   endif
  2928) 
  2929)   ! Read Cell Ids
  2930)   call PetscTime(tstart,ierr);CHKERRQ(ierr)
  2931)   string = "Cell Ids"
  2932)   if (grp_id /= file_id) then
  2933)     option%io_buffer = 'Reading dataset: ' // trim(group_name) // '/' &
  2934)                        // trim(string)
  2935)   else
  2936)     option%io_buffer = 'Reading dataset: ' // trim(string)
  2937)   endif
  2938)   call printMsg(option)   
  2939)   call HDF5ReadIndices(grid,option,grp_id,string,grid%nmax,indices)
  2940)   call PetscTime(tend,ierr);CHKERRQ(ierr)
  2941)   write(option%io_buffer,'(f6.2," Seconds to set up indices")') tend-tstart
  2942)   call printMsg(option)
  2943) 
  2944)   call PetscTime(tstart,ierr);CHKERRQ(ierr)
  2945)   string = ''
  2946)   if (append_realization_id) then
  2947)     write(string,'(i6)') option%id
  2948)   endif
  2949)   string = trim(dataset_name) // adjustl(trim(string))
  2950)   if (grp_id /= file_id) then
  2951)     option%io_buffer = 'Reading dataset: ' // trim(group_name) // '/' &
  2952)                        // trim(string)
  2953)   else
  2954)     option%io_buffer = 'Reading dataset: ' // trim(string)
  2955)   endif
  2956)   call printMsg(option)   
  2957)   call HDF5ReadArray(discretization,grid,option,file_id,string,grid%nmax, &
  2958)                      indices,global_vec,H5T_NATIVE_DOUBLE)
  2959)   call PetscTime(tend,ierr);CHKERRQ(ierr)
  2960)   write(option%io_buffer,'(f6.2," Seconds to read real array")') &
  2961)     tend-tstart
  2962)   call printMsg(option)  
  2963) 
  2964)   call DeallocateArray(indices)
  2965) 
  2966)   if (file_id /= grp_id) then
  2967)     option%io_buffer = 'Closing group: ' // trim(group_name)
  2968)     call printMsg(option)   
  2969)     call h5gclose_f(grp_id,hdf5_err)
  2970)   endif
  2971)   option%io_buffer = 'Closing hdf5 file: ' // trim(filename)
  2972)   call printMsg(option)   
  2973)   call h5fclose_f(file_id,hdf5_err)
  2974)   call h5close_f(hdf5_err)
  2975) 
  2976) #endif  
  2977) ! if SCORPIO is not defined
  2978) 
  2979) #endif
  2980) ! PETSC_HAVE_HDF5
  2981) 
  2982)   call PetscLogEventEnd(logging%event_cell_indx_real_read_hdf5, &
  2983)                         ierr);CHKERRQ(ierr)
  2984)                           
  2985) end subroutine HDF5ReadCellIndexedRealArray
  2986) 
  2987) #if defined(PETSC_HAVE_HDF5)
  2988) 
  2989) ! ************************************************************************** !
  2990) 
  2991) subroutine HDF5WriteStructDataSetFromVec(name,realization_base,vec,file_id,data_type)
  2992)   ! 
  2993)   ! Writes data from a PetscVec to HDF5 file
  2994)   ! 
  2995)   ! Author: Glenn Hammond
  2996)   ! Date: 10/25/07
  2997)   ! 
  2998) 
  2999)   use hdf5
  3000)   use Realization_Base_class, only : realization_base_type
  3001)   use Grid_module
  3002)   use Option_module
  3003)   use Patch_module
  3004)   use Utility_module, only : DeallocateArray
  3005)   
  3006)   implicit none
  3007) 
  3008) #include "petsc/finclude/petscvec.h"
  3009) #include "petsc/finclude/petscvec.h90"
  3010) 
  3011)   character(len=*) :: name
  3012)   class(realization_base_type) :: realization_base
  3013)   Vec :: vec
  3014)   integer(HID_T) :: file_id
  3015)   integer(HID_T) :: data_type
  3016)   
  3017)   type(grid_type), pointer :: grid
  3018)   type(option_type), pointer :: option
  3019)   type(patch_type), pointer :: patch  
  3020)   PetscReal, pointer :: vec_ptr(:)
  3021)   
  3022)   patch => realization_base%patch
  3023)   grid => patch%grid
  3024)   option => realization_base%option
  3025)   
  3026)   call VecGetArrayF90(vec,vec_ptr,ierr);CHKERRQ(ierr)
  3027) !GEH - Structured Grid Dependence - Begin
  3028)   call HDF5WriteStructuredDataSet(trim(name), &
  3029)                                  vec_ptr,file_id,data_type,option, &
  3030)                                   grid%structured_grid%nx, &
  3031)                                   grid%structured_grid%ny, &
  3032)                                   grid%structured_grid%nz, &
  3033)                                   grid%structured_grid%nlx, &
  3034)                                   grid%structured_grid%nly, &
  3035)                                   grid%structured_grid%nlz, &
  3036)                                   grid%structured_grid%lxs, &
  3037)                                   grid%structured_grid%lys, &
  3038)                                   grid%structured_grid%lzs)
  3039) !GEH - Structured Grid Dependence - End
  3040)   call VecRestoreArrayF90(vec,vec_ptr,ierr);CHKERRQ(ierr)
  3041)   
  3042) end subroutine HDF5WriteStructDataSetFromVec
  3043) 
  3044) ! ************************************************************************** !
  3045) 
  3046) subroutine HDF5WriteDataSetFromVec(name,option,vec,file_id,data_type)
  3047)   ! 
  3048)   ! This routine writes data from a PETSc Vec to HDF5 file for unstructured
  3049)   ! grids.
  3050)   ! subroutine HDF5WriteDataSetFromVec(name,realization,vec,file_id,data_type)
  3051)   ! 
  3052)   ! Author: Gautam Bisht, ORNL
  3053)   ! Date: 05/31/12
  3054)   ! 
  3055) 
  3056)   use hdf5
  3057)   use Realization_Subsurface_class
  3058)   use Grid_module
  3059)   use Option_module
  3060)   use Patch_module
  3061)   use Utility_module, only : DeallocateArray
  3062)   
  3063)   implicit none
  3064) 
  3065) #include "petsc/finclude/petscvec.h"
  3066) #include "petsc/finclude/petscvec.h90"
  3067) 
  3068)   character(len=32) :: name
  3069)   Vec :: vec
  3070)   integer(HID_T) :: file_id
  3071)   integer(HID_T) :: data_type
  3072)   
  3073)   type(grid_type), pointer :: grid
  3074)   type(option_type), pointer :: option
  3075)   type(patch_type), pointer :: patch
  3076)   PetscReal, pointer :: vec_ptr(:)
  3077)   
  3078)   PetscMPIInt :: rank_mpi,file_space_rank_mpi
  3079)   PetscMPIInt :: hdf5_flag
  3080)   PetscMPIInt, parameter :: ON=1, OFF=0
  3081)   integer(HID_T) :: data_set_id
  3082)   integer(HID_T) :: prop_id
  3083)   integer(HID_T) :: file_space_id
  3084)   integer(HID_T) :: memory_space_id
  3085)   integer(HSIZE_T) :: dims(3)
  3086)   integer(HSIZE_T) :: start(3), length(3), stride(3)
  3087)   PetscInt :: istart
  3088)   PetscInt :: local_size,global_size,i
  3089)   PetscInt, pointer :: int_array(:)
  3090)   PetscReal, pointer :: double_array(:)
  3091) 
  3092)   call VecGetLocalSize(vec,local_size,ierr);CHKERRQ(ierr)
  3093)   call VecGetSize(vec,global_size,ierr);CHKERRQ(ierr)
  3094)   
  3095)   ! memory space which is a 1D vector
  3096)   rank_mpi = 1
  3097)   dims = 0
  3098)   dims(1) = local_size
  3099)   call h5screate_simple_f(rank_mpi,dims,memory_space_id,hdf5_err,dims)
  3100)    
  3101)   ! file space which is a 3D block
  3102)   rank_mpi = 1
  3103)   dims = 0
  3104)   dims(1) = global_size
  3105)   call h5pcreate_f(H5P_DATASET_CREATE_F,prop_id,hdf5_err)
  3106) 
  3107)   call h5eset_auto_f(OFF,hdf5_err)
  3108)   call h5dopen_f(file_id,name,data_set_id,hdf5_err)
  3109)   hdf5_flag = hdf5_err
  3110)   call h5eset_auto_f(ON,hdf5_err)
  3111)   if (hdf5_flag < 0) then
  3112)     call h5screate_simple_f(rank_mpi,dims,file_space_id,hdf5_err,dims)
  3113)     call h5dcreate_f(file_id,name,data_type,file_space_id, &
  3114)                      data_set_id,hdf5_err,prop_id)
  3115)   else
  3116)     call h5dget_space_f(data_set_id,file_space_id,hdf5_err)
  3117)   endif
  3118) 
  3119)   call h5pclose_f(prop_id,hdf5_err)
  3120) 
  3121)   istart = 0
  3122)   call MPI_Exscan(local_size, istart, ONE_INTEGER_MPI, &
  3123)                   MPIU_INTEGER, MPI_SUM, option%mycomm, ierr)
  3124) 
  3125)   start(1) = istart
  3126)   length(1) = local_size
  3127)   stride = 1
  3128)   call h5sselect_hyperslab_f(file_space_id,H5S_SELECT_SET_F,start,length, &
  3129)                              hdf5_err,stride,stride)
  3130) 
  3131)   ! write the data
  3132)   call h5pcreate_f(H5P_DATASET_XFER_F,prop_id,hdf5_err)
  3133) #ifndef SERIAL_HDF5
  3134)   if (trick_hdf5) then
  3135)     call h5pset_dxpl_mpio_f(prop_id,H5FD_MPIO_INDEPENDENT_F, &
  3136)                             hdf5_err)
  3137)   else
  3138)     call h5pset_dxpl_mpio_f(prop_id,H5FD_MPIO_COLLECTIVE_F, &
  3139)                             hdf5_err)
  3140)   endif
  3141) #endif
  3142) 
  3143) 
  3144)   if (data_type == H5T_NATIVE_DOUBLE) then
  3145)     allocate(double_array(local_size))  
  3146)     call VecGetArrayF90(vec,vec_ptr,ierr);CHKERRQ(ierr)
  3147)     do i=1,local_size
  3148)       double_array(i) = vec_ptr(i)
  3149)     enddo
  3150)     call VecRestoreArrayF90(vec,vec_ptr,ierr);CHKERRQ(ierr)
  3151)   
  3152)     call PetscLogEventBegin(logging%event_h5dwrite_f,ierr);CHKERRQ(ierr)
  3153)     call h5dwrite_f(data_set_id,data_type,double_array,dims, &
  3154)                     hdf5_err,memory_space_id,file_space_id,prop_id)
  3155)     call PetscLogEventEnd(logging%event_h5dwrite_f,ierr);CHKERRQ(ierr)
  3156) 
  3157)     call DeallocateArray(double_array)
  3158)     call h5pclose_f(prop_id,hdf5_err)
  3159)   endif
  3160) 
  3161)   if (data_type == H5T_NATIVE_INTEGER) then
  3162)     allocate(int_array(local_size))
  3163)     call VecGetArrayF90(vec,vec_ptr,ierr);CHKERRQ(ierr)
  3164)     do i=1,local_size
  3165)       int_array(i) = int(vec_ptr(i))
  3166)     enddo
  3167)     call VecRestoreArrayF90(vec,vec_ptr,ierr);CHKERRQ(ierr)
  3168)   
  3169)     call PetscLogEventBegin(logging%event_h5dwrite_f,ierr);CHKERRQ(ierr)
  3170)     call h5dwrite_f(data_set_id,data_type,int_array,dims, &
  3171)                     hdf5_err,memory_space_id,file_space_id,prop_id)
  3172)     call PetscLogEventEnd(logging%event_h5dwrite_f,ierr);CHKERRQ(ierr)
  3173) 
  3174)     call DeallocateArray(int_array)
  3175)     call h5pclose_f(prop_id,hdf5_err)
  3176)   endif
  3177) 
  3178)   call h5dclose_f(data_set_id,hdf5_err)
  3179)   call h5sclose_f(file_space_id,hdf5_err)
  3180)   
  3181) end subroutine HDF5WriteDataSetFromVec
  3182) 
  3183) ! ************************************************************************** !
  3184) 
  3185) subroutine HDF5ReadDataSetInVec(name, option, vec, file_id, data_type)
  3186)   ! 
  3187)   ! This routine reads data from HDF5 file in a PETSc Vec
  3188)   ! 
  3189)   ! Author: Gautam Bisht, LBNL
  3190)   ! Date: 08/16/2015
  3191)   ! 
  3192) 
  3193)   use hdf5
  3194)   use Realization_Subsurface_class
  3195)   use Grid_module
  3196)   use Option_module
  3197)   use Patch_module
  3198)   use Utility_module, only : DeallocateArray
  3199) 
  3200)   implicit none
  3201) 
  3202) #include "petsc/finclude/petscvec.h"
  3203) #include "petsc/finclude/petscvec.h90"
  3204) 
  3205)   character(len=32) :: name
  3206)   Vec :: vec
  3207)   integer(HID_T) :: file_id
  3208)   integer(HID_T) :: data_type
  3209) 
  3210)   type(grid_type), pointer :: grid
  3211)   type(option_type), pointer :: option
  3212)   type(patch_type), pointer :: patch
  3213)   PetscReal, pointer :: vec_ptr(:)
  3214) 
  3215)   PetscMPIInt :: rank_mpi,file_space_rank_mpi
  3216)   PetscMPIInt :: hdf5_flag
  3217)   PetscMPIInt, parameter :: ON=1, OFF=0
  3218)   integer(HID_T) :: data_set_id
  3219)   integer(HID_T) :: prop_id
  3220)   integer(HID_T) :: file_space_id
  3221)   integer(HID_T) :: memory_space_id
  3222)   integer(HSIZE_T) :: dims(3)
  3223)   integer(HSIZE_T) :: start(3), length(3), stride(3)
  3224)   PetscInt :: istart
  3225)   PetscInt :: local_size,global_size,i
  3226)   PetscInt, pointer :: int_array(:)
  3227)   PetscReal, pointer :: double_array(:)
  3228) 
  3229)   call VecGetLocalSize(vec,local_size,ierr);CHKERRQ(ierr)
  3230)   call VecGetSize(vec,global_size,ierr);CHKERRQ(ierr)
  3231) 
  3232)   ! memory space which is a 1D vector
  3233)   rank_mpi = 1
  3234)   dims = 0
  3235)   dims(1) = local_size
  3236)   call h5screate_simple_f(rank_mpi,dims,memory_space_id,hdf5_err,dims)
  3237) 
  3238)   ! file space which is a 3D block
  3239)   rank_mpi = 1
  3240)   dims = 0
  3241)   dims(1) = global_size
  3242)   call h5pcreate_f(H5P_DATASET_CREATE_F,prop_id,hdf5_err)
  3243) 
  3244)   call h5eset_auto_f(OFF,hdf5_err)
  3245)   call h5dopen_f(file_id,name,data_set_id,hdf5_err)
  3246)   hdf5_flag = hdf5_err
  3247)   call h5eset_auto_f(ON,hdf5_err)
  3248)   if (hdf5_flag < 0) then
  3249)     call h5screate_simple_f(rank_mpi,dims,file_space_id,hdf5_err,dims)
  3250)     call h5dcreate_f(file_id,name,data_type,file_space_id, &
  3251)                      data_set_id,hdf5_err,prop_id)
  3252)   else
  3253)     call h5dget_space_f(data_set_id,file_space_id,hdf5_err)
  3254)   endif
  3255) 
  3256)   call h5pclose_f(prop_id,hdf5_err)
  3257) 
  3258)   istart = 0
  3259)   call MPI_Exscan(local_size, istart, ONE_INTEGER_MPI, &
  3260)                   MPIU_INTEGER, MPI_SUM, option%mycomm, ierr)
  3261) 
  3262)   start(1) = istart
  3263)   length(1) = local_size
  3264)   stride = 1
  3265)   call h5sselect_hyperslab_f(file_space_id,H5S_SELECT_SET_F,start,length, &
  3266)                              hdf5_err,stride,stride)
  3267) 
  3268)   ! write the data
  3269)   call h5pcreate_f(H5P_DATASET_XFER_F,prop_id,hdf5_err)
  3270) #ifndef SERIAL_HDF5
  3271)   if (trick_hdf5) then
  3272)     call h5pset_dxpl_mpio_f(prop_id,H5FD_MPIO_INDEPENDENT_F, &
  3273)                             hdf5_err)
  3274)   else
  3275)     call h5pset_dxpl_mpio_f(prop_id,H5FD_MPIO_COLLECTIVE_F, &
  3276)                             hdf5_err)
  3277)   endif
  3278) #endif
  3279) 
  3280) 
  3281)   if (data_type == H5T_NATIVE_DOUBLE) then
  3282)     allocate(double_array(local_size))
  3283) 
  3284)     call PetscLogEventBegin(logging%event_h5dwrite_f,ierr);CHKERRQ(ierr)
  3285)     call h5dread_f(data_set_id,data_type,double_array,dims, &
  3286)                     hdf5_err,memory_space_id,file_space_id,prop_id)
  3287)     call PetscLogEventEnd(logging%event_h5dwrite_f,ierr);CHKERRQ(ierr)
  3288) 
  3289)     call VecGetArrayF90(vec,vec_ptr,ierr);CHKERRQ(ierr)
  3290)     do i=1,local_size
  3291)       vec_ptr(i) = double_array(i)
  3292)     enddo
  3293)     call VecRestoreArrayF90(vec,vec_ptr,ierr);CHKERRQ(ierr)
  3294) 
  3295)     call DeallocateArray(double_array)
  3296)     call h5pclose_f(prop_id,hdf5_err)
  3297)   endif
  3298) 
  3299)   if (data_type == H5T_NATIVE_INTEGER) then
  3300)     allocate(int_array(local_size))
  3301) 
  3302)     call PetscLogEventBegin(logging%event_h5dwrite_f,ierr);CHKERRQ(ierr)
  3303)     call h5dwrite_f(data_set_id,data_type,int_array,dims, &
  3304)                     hdf5_err,memory_space_id,file_space_id,prop_id)
  3305)     call PetscLogEventEnd(logging%event_h5dwrite_f,ierr);CHKERRQ(ierr)
  3306) 
  3307)     call VecGetArrayF90(vec,vec_ptr,ierr);CHKERRQ(ierr)
  3308)     do i=1,local_size
  3309)       vec_ptr(i) = real(int_array(i))
  3310)     enddo
  3311)     call VecRestoreArrayF90(vec,vec_ptr,ierr);CHKERRQ(ierr)
  3312) 
  3313)     call DeallocateArray(int_array)
  3314)     call h5pclose_f(prop_id,hdf5_err)
  3315)   endif
  3316) 
  3317)   call h5dclose_f(data_set_id,hdf5_err)
  3318)   call h5sclose_f(file_space_id,hdf5_err)
  3319) 
  3320) end subroutine HDF5ReadDataSetInVec
  3321) 
  3322) #endif
  3323) 
  3324) end module HDF5_module
  3325) 
  3326) 
  3327) 

generated by
Intel(R) C++/Fortran Compiler code-coverage tool
Web-Page Owner: Nobody