如何在运行时分配Netcdf fortran数组的大小?

时间:2016-07-12 09:11:15

标签: fortran netcdf

我有一个netCDF 4.4文件,它有四个维度 - 时间,纬度,经度,级别。我希望能够从该文件中读取纬度和经度值,并将它们存储在一维数组中。但是我不知道纬度数组或经度数组的大小,因此我无法在声明两个数组lat和lon时分配大小。将要处理的每个netCDF文件都有自己的lat和lon大小,因此无法在编译时声明它。所以我确实使用Fortran的分配来声明这个,但这并不是我想做的事情。它打印0作为拉特和长子的值。 我哪里错了?

  Variables for input Z file : height level
  character*80 in_cfn,varname
  integer      reason,i,in_ndim,ierr
  integer ndims_in, nvars_in, ngatts_in, unlimdimid_in
  integer lat_varid,lon_varid
  character*(*) LAT_NAME, LON_NAME
  parameter (LAT_NAME='lat', LON_NAME='lon')
  real,allocatable, dimension(:) :: lats
  real,allocatable, dimension(:) :: lons

  call system('ls hgt_*.nc > hgtFiles.txt')

  open(10,file='hgtFiles.txt',action="read")
  varname = "hgt"
  do
     read(10,*,IOSTAT=reason) in_cfn
     if (reason/=0) EXIT
     print *,in_cfn
     retval = nf_open(in_cfn,NF_NOWRITE,ncid)
     if (retval .ne. nf_noerr) call handle_err(retval)
     retval = nf_inq(ncid,ndims_in,nvars_in,ngatts_in,unlimdimid_in)
     retval = nf_inq_varid(ncid,LAT_NAME,lat_varid)
     if (retval .ne. nf_noerr) call handle_err(retval)
     retval = nf_inq_varid(ncid, LON_NAME, lon_varid)
     if (retval .ne. nf_noerr) call handle_err(retval)
     retval = nf_get_var_real(ncid, lat_varid, lats)
    if (retval .ne. nf_noerr) call handle_err(retval)
     retval = nf_get_var_real(ncid, lon_varid, lons)
     print *,size(lons)

  end do
  close(10)

  stop

  end

1 个答案:

答案 0 :(得分:2)

我通常使用Fortran 90 NetCDF Module。但Fortran 77 interface的作用相似。

您可以通过调用NF_INQ_DIMLEN

来获取维度的长度

我已经制作了一个Fortran 77兼容(希望)程序来读取纬度数组并将其打印到屏幕上:

      PROGRAM READ_LAT
        IMPLICIT NONE
        INCLUDE 'netcdf.inc'
        INTEGER NCID, LATID, LATVARID, LATLEN
        REAL LATDATA[ALLOCATABLE](:)
        CHARACTER*(*) FILENAME
        CHARACTER*(*) LATNAME
        PARAMETER (FILENAME='data.nc', LATNAME='lat')

        CALL CHECK( NF_OPEN(FILENAME, NF_NOWRITE, NCID) )
        CALL CHECK( NF_INQ_DIMID(NCID, LATNAME, LATID) )
        CALL CHECK( NF_INQ_DIMLEN(NCID, LATID, LATLEN) )

        ALLOCATE(LATDATA(LATLEN))

        CALL CHECK( NF_INQ_VARID(NCID, LATNAME, LATVARID) )
        CALL CHECK( NF_GET_VAR_REAL(NCID, LATVARID, LATDATA) )

        WRITE(*, '(F10.4)') LATDATA

        CALL CHECK( NF_CLOSE(NCID) )

      CONTAINS

        SUBROUTINE CHECK( ERRORCODE )
            IMPLICIT NONE
            INTEGER ERRORCODE
            IF (ERRORCODE .ne. NF_NOERR) THEN
                PRINT *, "Encountered Error ", ERRORCODE
                STOP
            END IF
        END SUBROUTINE
      END PROGRAM

与Fortran 90 +相同的程序:

program read_latitude
    use netcdf
    implicit none
    integer :: ncid, latid, latvarid, latlen
    real, allocatable :: latdata(:)
    character(len=*), parameter :: filename='data.nc'
    character(len=*), parameter :: latname = 'lat'

    call check( nf90_open(filename, NF90_NOWRITE, ncid) )
    call check( nf90_inq_dimid(ncid, latname, latid) )
    call check( nf90_inquire_dimension(ncid, latid, len=latlen) )

    allocate( latdata(latlen) )

    call check( nf90_inq_varid(ncid, latname, latvarid) )
    call check( nf90_get_var(ncid, latvarid, latdata) )

    write(*, '(F10.4)') latdata

    call check( nf90_close(ncid) )

    contains

        subroutine check(errorcode)
            implicit none
            integer, intent(in) :: errorcode
            if (errorcode /= NF90_NOERR) then
                write(*, '(A, I0)') "Encountered Error ", errorcode
                write(*, '(A)') nf90_strerror(errorcode)
                stop 1
            end if
        end subroutine check
end program read_latitude