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

How to allocate size of Netcdf fortran array at run time?

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

  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

我通常使用 Fortran 90 NetCDF Module. But the 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