如何在运行时分配Netcdf fortran数组的大小? [英] How to allocate size of Netcdf fortran array at run time?
问题描述
我有一个netCDF 4.4文件,它有四个维度 - 时间,纬度,经度,水平。我希望能够从这个文件中读取纬度和经度值,并将它们存储在一维数组中。但是我不知道纬度数组或经度数组的大小,所以我不能在声明两个数组lat和lon时分配大小。每个将被处理的netCDF文件将具有它自己的lat和lon大小,所以不可能在编译时声明它。所以我使用Fortran的分配声明了这一点,但这并没有达到我想要的效果。它打印0作为lats和lons的值。
输入Z文件的变量:高度等级
字符* 80 in_cfn
I have a netCDF 4.4 file which has four dimensions- time, latitude,longitude, level. I want to be able to read the latitude and longitude values from this file and store them in a single dimensional array. However I do not know the size of the latitude array or longitude array and I so cannot allocate the size at the time of the declaration of the two arrays lat and lon. Each netCDF file that will be processed will have it's own lat and lon size and so it is not possible to declare this at compile time. So I did declare this using Fortran's allocate but this does not do what I want it to do. It prints 0 as the values of lats and lons. Where am I going wrong ?
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模块。但是 Fortran 77界面 a>类似。
I'm usually using Fortran 90 NetCDF Module. But the Fortran 77 interface works similar.
您可以通过调用 NF_INQ_DIMLEN
我已经使Fortran 77兼容(希望)程序读取纬度数组并将其打印到屏幕上:
I've made a Fortran 77 compliant (hopefully) program to read in the latitude array and print it to the screen:
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 +相同的程序:
Same program as 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 fortran数组的大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!