如何在运行时分配Netcdf fortran数组的大小? [英] How to allocate size of Netcdf fortran array at run time?

查看:489
本文介绍了如何在运行时分配Netcdf fortran数组的大小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆