2016-07-12 4 views
0

У меня есть файл netCDF 4.4, который имеет четыре измерения - время, широта, долгота, уровень. Я хочу иметь возможность считывать значения широты и долготы из этого файла и хранить их в одномерном массиве. Однако я не знаю размер массива широты или долготы, и поэтому я не могу выделить размер во время объявления двух массивов lat и lon. Каждый файл netCDF, который будет обработан, будет иметь собственный размер lat и lon, и поэтому невозможно объявить это во время компиляции. Поэтому я объявлял это, используя выделение Fortran, но это не делает то, что я хочу. Он печатает 0 как значения lats и lons. Где я иду не так?Как выделить размер массива fortan Netcdf во время выполнения?

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 

ответ

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 
+0

Спасибо за ваш ответ. Предполагая, что я вызываю эту функцию, мне все еще нужно выделять массивы, используя размер выделения (:)? – gansub

+0

Да. Этот вызов дает вам длину измерения. Затем вы знаете, как большой массив вам нужно выделить. – chw21

+0

Просто, чтобы сообщить вам, я добавил два примера: один для F77 и один для F90 + – chw21

Смежные вопросы