#if defined ( NO_IEEE_MODULE ) /* stub out entire module */ module module_io_int_read private contains subroutine dummy end subroutine dummy end module module_io_int_read #else ! ! Public domain. ! !> !! Module to retrieve a variable from a WRF I/O Internal format file. !! !! This module uses an index generated by module_io_int_idx. !! Note that this module contains ifdef's so if it is compiled !! with DM_PARALLEL it will use MPI IO routines. However if it !! is not, then the Fortran 2003 stream facility is used to !! read at a position in the file. !! !! Note that WRF should be compiled with file conversion for !! big endian. This is the current default. !! !! DM_PARALLEL !! ----------- !! If the MPI implementations actually supported the external32 !! view on a file we could simply call: !! !! MPI_File_set_view(..., "external32", ...) !! !! However most do not. Instead we have do a native view and then !! do a byte order rearrangement. !! !! Usage consists of: !! 1) Creating an index of records in the file !! 2) Opening the file with MPI !! 3) Retrieving the data !! 4) Closing the file with MPI !! !! Example: !! !! USE module_io_int_idx, only: io_int_index, r_info !! USE module_io_int_read, only: io_int_fetch_data !! !! type(r_info), pointer :: r(:) => NULL() ! Define the array of records !! !! call io_int_index(filename, r, ierr) ! Get an index of reocrds !! !! call mpi_file_open(mpi_comm_world, trim(filename), & !! mpi_mode_rdonly, mpi_info_null, & !! iunit, ierr) ! MPI Open the file !! !! call io_int_fetch_data(iunit, r, 'TRUELAT1', garb, ierr) !! ! Get an record (into garb) !! !! call mpi_file_close(iunit, ierr) ! Close the file !! !! SERIAL !! ------ !! !! Usage consists of: !! 1) Creating an index of records in the file !! 2) Opening the file !! 3) Retrieving the data !! 4) Closing the file !! !! Example: !! !! USE module_io_int_idx, only: io_int_index, r_info !! USE module_io_int_read, only: io_int_fetch_data !! !! type(r_info), pointer :: r(:) => NULL() ! Define the array of records !! !! call io_int_index(filename, r, ierr) ! Get an index of reocrds !! !! open(unit=iunit, file=trim(filename), & !! access='stream', status='old', & !! convert='big_endian', iostat=ierr) !! !! call io_int_fetch_data(iunit, r, 'TRUELAT1', garb, ierr) !! ! Get an record (into garb) !! !! call close(iunit, iostat=ierr) ! Close the file module module_io_int_read use module_io_int_idx, only: io_int_loc, r_info use, intrinsic :: iso_c_binding, only: c_int32_t implicit none private public :: io_int_fetch_data integer, parameter :: llong_t = selected_int_kind(16) ! int64_t character(len=128) :: message interface integer(c_int32_t) & pure function ntohl(netlong) & bind(c, name="ntohl") import :: c_int32_t integer(c_int32_t), value, intent(in) :: netlong end function end interface interface io_int_fetch_data module procedure read_i0, read_i1, read_i2, read_i3, & read_r0, read_r1, read_r2, read_r3, & read_c1 end interface io_int_fetch_data #if defined(DM_PARALLEL) && !defined(STUBMPI) include "mpif.h" contains !> !! Read a single integer ! subroutine read_i0(ifd, records, varname, dst, ierr) integer, intent(in) :: ifd type(r_info), pointer, intent(in) :: records(:) character(len=*), intent(in) :: varname integer, intent(out) :: dst integer, intent(out) :: ierr integer(kind=mpi_offset_kind) :: offset integer :: count integer :: tmp call io_int_loc(varname, records, offset, count, ierr) if (ierr .ne. 0) then return end if call mpi_file_read_at(ifd, offset, tmp, 1, & mpi_integer4, mpi_status_ignore, ierr) if (ierr .ne. 0) then write(message,*) 'MPI IO: Unable to read ', varname call wrf_error_fatal3(__FILE__, __LINE__, message) return end if dst = ntohl(tmp) ! write(message,*) 'read_i0: ', varname, ':', dst ! call wrf_debug(2, message) end subroutine read_i0 !> !! Read a 1D integer array. ! subroutine read_i1(ifd, records, varname, dst, ierr) integer, intent(in) :: ifd type(r_info), pointer, intent(in) :: records(:) character(len=*), intent(in) :: varname integer, intent(inout) :: dst(:) integer, intent(out) :: ierr integer(kind=mpi_offset_kind) :: offset integer :: count integer :: num integer :: i integer :: its, ite integer, allocatable, dimension(:) :: tmp call io_int_loc(varname, records, offset, count, ierr) if (ierr .ne. 0) then return end if its = lbound(dst,1) ite = ubound(dst,1) num = ite - its + 1 allocate(tmp(its:ite), stat=ierr) if (ierr .ne. 0) then call wrf_error_fatal3(__FILE__, __LINE__, & 'Unable to allocate a temporary array') return end if tmp = 0 if (num .ne. count) then write(message,*) 'MPI IO: Reading less data, than in file', num, & '(instead of ', count, ')' call wrf_debug(1, message) end if call mpi_file_read_at(ifd, offset, tmp, num, & mpi_integer4, mpi_status_ignore, ierr) if (ierr .ne. 0) then write(message,*) 'MPI IO: Unable to read ', varname call wrf_error_fatal3(__FILE__, __LINE__, message) return end if forall(i=its:ite) dst(i) = transfer(ntohl(tmp(i)), 1.0) end forall deallocate(tmp) ! write(message,*) 'read_i1: ', varname, ':', dst(1,1) ! call wrf_debug(2, message) end subroutine read_i1 !> !! Read a 2D integer array. ! subroutine read_i2(ifd, records, varname, dst, ierr) integer, intent(in) :: ifd type(r_info), pointer, intent(in) :: records(:) character(len=*), intent(in) :: varname integer, intent(inout) :: dst(:,:) integer, intent(out) :: ierr integer(kind=mpi_offset_kind) :: offset integer :: count integer :: num integer :: i, j integer :: its, ite, jts, jte integer, allocatable, dimension(:,:) :: tmp call io_int_loc(varname, records, offset, count, ierr) if (ierr .ne. 0) then return end if its = lbound(dst,1) ite = ubound(dst,1) jts = lbound(dst,2) jte = ubound(dst,2) num = (ite - its + 1) * (jte - jts +1) allocate(tmp(its:ite, jts:jte), stat=ierr) if (ierr .ne. 0) then call wrf_error_fatal3(__FILE__, __LINE__, & 'Unable to allocate a temporary array') return end if tmp = 0 if (num .ne. count) then write(message,*) 'MPI IO: Reading less data, than in file', num, & '(instead of ', count, ')' call wrf_debug(1, message) end if call mpi_file_read_at(ifd, offset, tmp, num, & mpi_integer4, mpi_status_ignore, ierr) if (ierr .ne. 0) then write(message,*) 'MPI IO: Unable to read ', varname call wrf_error_fatal3(__FILE__, __LINE__, message) return end if forall(i=its:ite, j=jts:jte) dst(i,j) = transfer(ntohl(tmp(i,j)), 1.0) end forall deallocate(tmp) ! write(message,*) 'read_i2: ', varname, ':', dst(1,1) ! call wrf_debug(2, message) end subroutine read_i2 !> !! Read a 3D integer array ! subroutine read_i3(ifd, records, varname, dst, ierr) integer, intent(in) :: ifd type(r_info), pointer, intent(in) :: records(:) character(len=*), intent(in) :: varname integer, intent(inout) :: dst(:,:,:) integer, intent(out) :: ierr integer(kind=mpi_offset_kind) :: offset integer :: count integer :: num integer :: i, j, k integer :: its, ite, jts, jte, kts, kte integer, allocatable, dimension(:,:,:) :: tmp call io_int_loc(varname, records, offset, count, ierr) if (ierr .ne. 0) then return end if its = lbound(dst,1) ite = ubound(dst,1) jts = lbound(dst,2) jte = ubound(dst,2) kts = lbound(dst,3) kte = ubound(dst,3) num = (ite - its + 1) * (jte - jts + 1) * (kte - kts + 1) allocate(tmp(its:ite, jts:jte, kts:kte), stat=ierr) if (ierr .ne. 0) then call wrf_error_fatal3(__FILE__, __LINE__, & 'Unable to allocate a temporary array') return end if tmp = 0 if (num .ne. count) then write(message,*) 'MPI IO: Reading less data, than in file', num, & '(instead of ', count, ')' call wrf_debug(1, message) end if call mpi_file_read_at(ifd, offset, tmp, num, & mpi_integer4, mpi_status_ignore, ierr) if (ierr .ne. 0) then write(message,*) 'MPI IO: Unable to read ', varname call wrf_error_fatal3(__FILE__, __LINE__, message) return end if forall(i=its:ite, j=jts:jte, k=kts:kte) dst(i,j,k) = transfer(ntohl(tmp(i,j,k)), 1.0) end forall deallocate(tmp) ! write(message,*) 'read_i3: ', varname, ':', dst(1,1,1) ! call wrf_debug(2, message) end subroutine read_i3 !> !! Read a single real. ! subroutine read_r0(ifd, records, varname, dst, ierr) integer, intent(in) :: ifd type(r_info), pointer, intent(in) :: records(:) character(len=*), intent(in) :: varname real, intent(out) :: dst integer, intent(out) :: ierr integer(kind=mpi_offset_kind) :: offset integer :: count integer :: tmp call io_int_loc(varname, records, offset, count, ierr) if (ierr .ne. 0) then return end if call mpi_file_read_at(ifd, offset, tmp, 1, & mpi_integer4, mpi_status_ignore, ierr) if (ierr .ne. 0) then write(message,*) 'MPI IO: Unable to read ', varname call wrf_error_fatal3(__FILE__, __LINE__, message) return end if dst = transfer(ntohl(tmp), 1.0) ! write(message,*) 'read_r0: ', varname, ':', dst ! call wrf_debug(2, message) end subroutine read_r0 !> !! Read a 1D real array. ! subroutine read_r1(ifd, records, varname, dst, ierr) integer, intent(in) :: ifd type(r_info), pointer, intent(in) :: records(:) character(len=*), intent(in) :: varname real, intent(inout) :: dst(:) integer, intent(out) :: ierr integer(kind=mpi_offset_kind) :: offset integer :: count integer :: num integer :: i integer :: its, ite integer, allocatable, dimension(:) :: tmp call io_int_loc(varname, records, offset, count, ierr) if (ierr .ne. 0) then return end if its = lbound(dst,1) ite = ubound(dst,1) num = ite - its + 1 allocate(tmp(its:ite), stat=ierr) if (ierr .ne. 0) then call wrf_error_fatal3(__FILE__, __LINE__, & 'Unable to allocate a temporary array') return end if tmp = 0 if (num .ne. count) then write(message,*) 'MPI IO: Reading less data, than in file', num, & '(instead of ', count, ')' call wrf_debug(1, message) end if call mpi_file_read_at(ifd, offset, tmp, num, & mpi_integer4, mpi_status_ignore, ierr) if (ierr .ne. 0) then write(message,*) 'MPI IO: Unable to read ', varname call wrf_error_fatal3(__FILE__, __LINE__, message) return end if forall(i=its:ite) dst(i) = transfer(ntohl(tmp(i)), 1.0) end forall deallocate(tmp) ! write(message,*) 'read_r1: ', varname, ':', dst(1,1) ! call wrf_debug(2, message) end subroutine read_r1 !> !! Read a 2D real array. ! subroutine read_r2(ifd, records, varname, dst, ierr) integer, intent(in) :: ifd type(r_info), pointer, intent(in) :: records(:) character(len=*), intent(in) :: varname real, intent(inout) :: dst(:,:) integer, intent(out) :: ierr integer(kind=mpi_offset_kind) :: offset integer :: count integer :: num integer :: i, j integer :: its, ite, jts, jte integer, allocatable, dimension(:,:) :: tmp call io_int_loc(varname, records, offset, count, ierr) if (ierr .ne. 0) then return end if its = lbound(dst,1) ite = ubound(dst,1) jts = lbound(dst,2) jte = ubound(dst,2) num = (ite - its + 1) * (jte - jts + 1) allocate(tmp(its:ite, jts:jte), stat=ierr) if (ierr .ne. 0) then call wrf_error_fatal3(__FILE__, __LINE__, & 'Unable to allocate a temporary array') return end if tmp = 0 if (num .ne. count) then write(message,*) 'MPI IO: Reading less data, than in file', num, & '(instead of ', count, ')' call wrf_debug(1, message) end if call mpi_file_read_at(ifd, offset, tmp, num, & mpi_integer4, mpi_status_ignore, ierr) if (ierr .ne. 0) then write(message,*) 'MPI IO: Unable to read ', varname call wrf_error_fatal3(__FILE__, __LINE__, message) return end if forall(i=its:ite, j=jts:jte) dst(i,j) = transfer(ntohl(tmp(i,j)), 1.0) end forall deallocate(tmp) ! write(message,*) 'read_r2: ', varname, ':', dst(1,1) ! call wrf_debug(2, message) end subroutine read_r2 !> !! Read a 3D real array ! subroutine read_r3(ifd, records, varname, dst, ierr) integer, intent(in) :: ifd type(r_info), pointer, intent(in) :: records(:) character(len=*), intent(in) :: varname real, intent(inout) :: dst(:,:,:) integer, intent(out) :: ierr integer(kind=mpi_offset_kind) :: offset integer :: count integer :: num integer :: i, j, k integer :: its, ite, jts, jte, kts, kte integer, allocatable, dimension(:,:,:) :: tmp call io_int_loc(varname, records, offset, count, ierr) if (ierr .ne. 0) then return end if its = lbound(dst,1) ite = ubound(dst,1) jts = lbound(dst,2) jte = ubound(dst,2) kts = lbound(dst,3) kte = ubound(dst,3) num = (ite - its + 1) * (jte - jts + 1) * (kte - kts + 1) allocate(tmp(its:ite, jts:jte, kts:kte), stat=ierr) if (ierr .ne. 0) then call wrf_error_fatal3(__FILE__, __LINE__, & 'Unable to allocate a temporary array') return end if tmp = 0 if (num .ne. count) then write(message,*) 'MPI IO: Reading less data, than in file', num, & '(instead of ', count, ')' call wrf_debug(1, message) end if call mpi_file_read_at(ifd, offset, tmp, num, & mpi_integer4, mpi_status_ignore, ierr) if (ierr .ne. 0) then write(message,*) 'MPI IO: Unable to read ', varname call wrf_error_fatal3(__FILE__, __LINE__, message) return end if forall(i=its:ite, j=jts:jte, k=kts:kte) dst(i,j,k) = transfer(ntohl(tmp(i,j,k)), 1.0) end forall deallocate(tmp) ! write(message,*) 'read_r3: ', varname, ':', dst(1,1,1) ! call wrf_debug(2, message) end subroutine read_r3 !> !! Read a 1D character array. ! subroutine read_c1(ifd, records, varname, dst, ierr) integer, intent(in) :: ifd type(r_info), pointer, intent(in) :: records(:) character(len=*), intent(in) :: varname character(len=*), intent(inout) :: dst integer, intent(out) :: ierr integer(kind=mpi_offset_kind) :: offset integer :: count integer :: num integer :: i integer, allocatable, dimension(:) :: tmp call io_int_loc(varname, records, offset, count, ierr) if (ierr .ne. 0) then return end if num = len(dst) allocate(tmp(num), stat=ierr) if (ierr .ne. 0) then call wrf_error_fatal3(__FILE__, __LINE__, & 'Unable to allocate a temporary array') return end if tmp = 0 call mpi_file_read_at(ifd, offset, tmp, num, & mpi_integer4, mpi_status_ignore, ierr) if (ierr .ne. 0) then write(message,*) 'MPI IO: Unable to read ', varname call wrf_error_fatal3(__FILE__, __LINE__, message) return end if ! PGI and GNU fortran compilers do not like forall loops over ! character arrays. ! PGI: TPR#19016 ! GNU: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50069 ! ! XLF does not like transfer() with the mold being an array, ! so we use achar() instead. ! ! forall(i=1:num) ! dst(i:i) = transfer(ntohl(tmp(i)), dst) ! end forall do i=1,count dst(i:i) = achar(ntohl(tmp(i))) end do deallocate(tmp) ! write(message,*) 'read_c1: ', varname, ':', dst(1,1) ! call wrf_debug(2, message) end subroutine read_c1 #else /* defined(DM_PARALLEL) && !defined(STUBMPI) */ #ifdef __PATHSCALE__ !> !! It appears Pathscale (v4) does not support Fortran 2003 stream IO. !! So we can not compile this module serially. !! Instead all these subroutine will cause FATAL error messages. contains subroutine read_i0(ifd, records, varname, dst, ierr) integer, intent(in) :: ifd type(r_info), pointer, intent(in) :: records(:) character(len=*), intent(in) :: varname integer, intent(out) :: dst integer, intent(out) :: ierr write(message,*) 'Stream IO unsupported' call wrf_error_fatal3(__FILE__, __LINE__, message) end subroutine read_i0 !> !! Read a 1D integer array. ! subroutine read_i1(ifd, records, varname, dst, ierr) integer, intent(in) :: ifd type(r_info), pointer, intent(in) :: records(:) character(len=*), intent(in) :: varname integer, intent(inout) :: dst(:) integer, intent(out) :: ierr write(message,*) 'Stream IO unsupported' call wrf_error_fatal3(__FILE__, __LINE__, message) end subroutine read_i1 !> !! Read a 2D integer array. ! subroutine read_i2(ifd, records, varname, dst, ierr) integer, intent(in) :: ifd type(r_info), pointer, intent(in) :: records(:) character(len=*), intent(in) :: varname integer, intent(inout) :: dst(:,:) integer, intent(out) :: ierr write(message,*) 'Stream IO unsupported' call wrf_error_fatal3(__FILE__, __LINE__, message) end subroutine read_i2 !> !! Read a 3D integer array ! subroutine read_i3(ifd, records, varname, dst, ierr) integer, intent(in) :: ifd type(r_info), pointer, intent(in) :: records(:) character(len=*), intent(in) :: varname integer, intent(inout) :: dst(:,:,:) integer, intent(out) :: ierr write(message,*) 'Stream IO unsupported' call wrf_error_fatal3(__FILE__, __LINE__, message) end subroutine read_i3 !> !! Read a single real. ! subroutine read_r0(ifd, records, varname, dst, ierr) integer, intent(in) :: ifd type(r_info), pointer, intent(in) :: records(:) character(len=*), intent(in) :: varname real, intent(out) :: dst integer, intent(out) :: ierr write(message,*) 'Stream IO unsupported' call wrf_error_fatal3(__FILE__, __LINE__, message) end subroutine read_r0 !> !! Read a 1D real array. ! subroutine read_r1(ifd, records, varname, dst, ierr) integer, intent(in) :: ifd type(r_info), pointer, intent(in) :: records(:) character(len=*), intent(in) :: varname real, intent(inout) :: dst(:) integer, intent(out) :: ierr write(message,*) 'Stream IO unsupported' call wrf_error_fatal3(__FILE__, __LINE__, message) end subroutine read_r1 !> !! Read a 2D real array. ! subroutine read_r2(ifd, records, varname, dst, ierr) integer, intent(in) :: ifd type(r_info), pointer, intent(in) :: records(:) character(len=*), intent(in) :: varname real, intent(inout) :: dst(:,:) integer, intent(out) :: ierr write(message,*) 'Stream IO unsupported' call wrf_error_fatal3(__FILE__, __LINE__, message) end subroutine read_r2 !> !! Read a 3D real array ! subroutine read_r3(ifd, records, varname, dst, ierr) integer, intent(in) :: ifd type(r_info), pointer, intent(in) :: records(:) character(len=*), intent(in) :: varname real, intent(inout) :: dst(:,:,:) integer, intent(out) :: ierr write(message,*) 'Stream IO unsupported' call wrf_error_fatal3(__FILE__, __LINE__, message) end subroutine read_r3 !> !! Read a 1D character array. ! subroutine read_c1(ifd, records, varname, dst, ierr) integer, intent(in) :: ifd type(r_info), pointer, intent(in) :: records(:) character(len=*), intent(in) :: varname character(len=*), intent(inout) :: dst integer, intent(out) :: ierr write(message,*) 'Stream IO unsupported' call wrf_error_fatal3(__FILE__, __LINE__, message) end subroutine read_c1 #else /* __PATHSCALE__ */ contains !> !! Read a single integer ! subroutine read_i0(ifd, records, varname, dst, ierr) integer, intent(in) :: ifd type(r_info), pointer, intent(in) :: records(:) character(len=*), intent(in) :: varname integer, intent(out) :: dst integer, intent(out) :: ierr integer(kind=llong_t) :: offset integer :: count call io_int_loc(varname, records, offset, count, ierr) if (ierr .ne. 0) then return end if offset = offset + 1 read(ifd, pos=offset, iostat=ierr) dst if (ierr .ne. 0) then write(message,*) 'Unable to read ', varname call wrf_error_fatal3(__FILE__, __LINE__, message) return end if ! write(message,*) 'read_i0: ', varname, ':', dst ! call wrf_debug(2, message) end subroutine read_i0 !> !! Read a 1D integer array. ! subroutine read_i1(ifd, records, varname, dst, ierr) integer, intent(in) :: ifd type(r_info), pointer, intent(in) :: records(:) character(len=*), intent(in) :: varname integer, intent(inout) :: dst(:) integer, intent(out) :: ierr integer(kind=llong_t) :: offset integer :: count call io_int_loc(varname, records, offset, count, ierr) if (ierr .ne. 0) then return end if offset = offset + 1 read(ifd, pos=offset, iostat=ierr) dst if (ierr .ne. 0) then write(message,*) 'Unable to read ', varname call wrf_error_fatal3(__FILE__, __LINE__, message) return end if ! write(message,*) 'read_i1: ', varname, ':', dst(1,1) ! call wrf_debug(2, message) end subroutine read_i1 !> !! Read a 2D integer array. ! subroutine read_i2(ifd, records, varname, dst, ierr) integer, intent(in) :: ifd type(r_info), pointer, intent(in) :: records(:) character(len=*), intent(in) :: varname integer, intent(inout) :: dst(:,:) integer, intent(out) :: ierr integer(kind=llong_t) :: offset integer :: count call io_int_loc(varname, records, offset, count, ierr) if (ierr .ne. 0) then return end if offset = offset + 1 read(ifd, pos=offset, iostat=ierr) dst if (ierr .ne. 0) then write(message,*) 'Unable to read ', varname call wrf_error_fatal3(__FILE__, __LINE__, message) return end if ! write(message,*) 'read_i2: ', varname, ':', dst(1,1) ! call wrf_debug(2, message) end subroutine read_i2 !> !! Read a 3D integer array ! subroutine read_i3(ifd, records, varname, dst, ierr) integer, intent(in) :: ifd type(r_info), pointer, intent(in) :: records(:) character(len=*), intent(in) :: varname integer, intent(inout) :: dst(:,:,:) integer, intent(out) :: ierr integer(kind=llong_t) :: offset integer :: count call io_int_loc(varname, records, offset, count, ierr) if (ierr .ne. 0) then return end if offset = offset + 1 read(ifd, pos=offset, iostat=ierr) dst if (ierr .ne. 0) then write(message,*) 'Unable to read ', varname call wrf_error_fatal3(__FILE__, __LINE__, message) return end if ! write(message,*) 'read_i3: ', varname, ':', dst(1,1,1) ! call wrf_debug(2, message) end subroutine read_i3 !> !! Read a single real. ! subroutine read_r0(ifd, records, varname, dst, ierr) integer, intent(in) :: ifd type(r_info), pointer, intent(in) :: records(:) character(len=*), intent(in) :: varname real, intent(out) :: dst integer, intent(out) :: ierr integer(kind=llong_t) :: offset integer :: count call io_int_loc(varname, records, offset, count, ierr) if (ierr .ne. 0) then return end if offset = offset + 1 read(ifd, pos=offset, iostat=ierr) dst if (ierr .ne. 0) then write(message,*) 'Unable to read ', varname call wrf_error_fatal3(__FILE__, __LINE__, message) return end if ! write(message,*) 'read_r0: ', varname, ':', dst ! call wrf_debug(2, message) end subroutine read_r0 !> !! Read a 1D real array. ! subroutine read_r1(ifd, records, varname, dst, ierr) integer, intent(in) :: ifd type(r_info), pointer, intent(in) :: records(:) character(len=*), intent(in) :: varname real, intent(inout) :: dst(:) integer, intent(out) :: ierr integer(kind=llong_t) :: offset integer :: count call io_int_loc(varname, records, offset, count, ierr) if (ierr .ne. 0) then return end if offset = offset + 1 read(ifd, pos=offset, iostat=ierr) dst if (ierr .ne. 0) then write(message,*) 'Unable to read ', varname call wrf_error_fatal3(__FILE__, __LINE__, message) return end if ! write(message,*) 'read_r1: ', varname, ':', dst(1,1) ! call wrf_debug(2, message) end subroutine read_r1 !> !! Read a 2D real array. ! subroutine read_r2(ifd, records, varname, dst, ierr) integer, intent(in) :: ifd type(r_info), pointer, intent(in) :: records(:) character(len=*), intent(in) :: varname real, intent(inout) :: dst(:,:) integer, intent(out) :: ierr integer(kind=llong_t) :: offset integer :: count call io_int_loc(varname, records, offset, count, ierr) if (ierr .ne. 0) then return end if offset = offset + 1 read(ifd, pos=offset, iostat=ierr) dst if (ierr .ne. 0) then write(message,*) 'Unable to read ', varname call wrf_error_fatal3(__FILE__, __LINE__, message) return end if ! write(message,*) 'read_r2: ', varname, ':', dst(1,1) ! call wrf_debug(2, message) end subroutine read_r2 !> !! Read a 3D real array ! subroutine read_r3(ifd, records, varname, dst, ierr) integer, intent(in) :: ifd type(r_info), pointer, intent(in) :: records(:) character(len=*), intent(in) :: varname real, intent(inout) :: dst(:,:,:) integer, intent(out) :: ierr integer(kind=llong_t) :: offset integer :: count call io_int_loc(varname, records, offset, count, ierr) if (ierr .ne. 0) then return end if offset = offset + 1 read(ifd, pos=offset, iostat=ierr) dst if (ierr .ne. 0) then write(message,*) 'Unable to read ', varname call wrf_error_fatal3(__FILE__, __LINE__, message) return end if ! write(message,*) 'read_r3: ', varname, ':', dst(1,1,1) ! call wrf_debug(2, message) end subroutine read_r3 !> !! Read a 1D character array. ! subroutine read_c1(ifd, records, varname, dst, ierr) integer, intent(in) :: ifd type(r_info), pointer, intent(in) :: records(:) character(len=*), intent(in) :: varname character(len=*), intent(inout) :: dst integer, intent(out) :: ierr integer(kind=llong_t) :: offset integer :: count integer :: i integer, allocatable, dimension(:) :: tmp call io_int_loc(varname, records, offset, count, ierr) if (ierr .ne. 0) then return end if allocate(tmp(count), stat=ierr) if (ierr .ne. 0) then call wrf_error_fatal3(__FILE__, __LINE__, & 'Unable to allocate a temporary array') return end if offset = offset + 1 read(ifd, pos=offset, iostat=ierr) tmp if (ierr .ne. 0) then write(message,*) 'Unable to read ', varname call wrf_error_fatal3(__FILE__, __LINE__, message) return end if ! PGI and GNU fortran compilers do not like forall loops over ! character arrays. ! PGI: TPR#19016 ! GNU: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50069 ! ! XLF does not like transfer() with the mold being an array, ! so we use achar() instead. ! ! forall(i=1:num) ! dst(i:i) = transfer(ntohl(tmp(i)), dst) ! end forall do i=1,count dst(i:i) = achar(tmp(i)) end do deallocate(tmp) ! write(message,*) 'read_c1: ', varname, ':', dst(1,1) ! call wrf_debug(2, message) end subroutine read_c1 #endif /* __PATHSCALE__ */ #endif /* defined(DM_PARALLEL) && !defined(STUBMPI) */ end module module_io_int_read #endif /* stub out entire module */