如何在 运行 时间分配 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
我有一个 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