2017-11-02 47 views
0

4-dデータ[時間、レベル、経度、緯度]を持つNetCDFファイルを読み込むコードをFortranで作成しました。しかし、私のコードでは、私が使用している4-d NetCDFファイル上でエラーNetCDF:開始+カウントが次元境界を超えています

NetCDF: Start+count exceeds dimension bound 

が発生します。たとえば、http://people.sc.fsu.edu/~jburkardt/f_src/netcdf/pres_temp_4D.ncのファイルには、圧力と温度があります。私は下に自分のコードを貼り付けます。間違っていることをお勧めしてください。

 
PROGRAM rw_nc4d_main 

    USE rw_nc4d, ONLY: read_nc4 

    IMPLICIT NONE 

    CHARACTER(LEN=50) :: ncfn 
    CHARACTER(LEN=15) :: vname 

    ncfn = 'pres_temp_4D.nc' 
    vname = 'pressure' 

    CALL read_nc4(ncfn, vname)  

END PROGRAM rw_nc4d_main 
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
MODULE rw_nc4d 

USE netcdf 

IMPLICIT NONE 

CONTAINS 

    SUBROUTINE read_nc4(fname,vin_name) 

    IMPLICIT NONE 

    CHARACTER(LEN=*), INTENT(IN)   :: fname 
    CHARACTER(LEN=*), INTENT(IN)   :: vin_name 

    ! Local variables 
    INTEGER     :: ncid, var_id, ndim, nvar, nattr, unlim_id 
    CHARACTER(LEN=15)  :: dname 
    INTEGER     :: dlength 
    INTEGER     :: ii, status, lx, ly, lz, lt, lzp1 
    REAL      :: sf, ofs 
    REAL, DIMENSION(:,:,:,:), ALLOCATABLE :: vin 

    CALL nc_check(nf90_open(fname, nf90_nowrite, ncid)) 
    CALL nc_check(nf90_inquire(ncid,ndim,nvar)) 

    DO ii = 1, ndim 
     CALL nc_check(nf90_inquire_dimension(ncid,ii,dname,len=dlength)) 
      SELECT CASE(TRIM(dname)) 
      CASE('lon', 'LON', 'longitude') 
      lx = dlength 
      CASE('lat', 'LAT', 'latitude') 
      ly = dlength 
      CASE('lev', 'LEV', 'level' ) 
      lz = dlength 
      CASE('time', 'TIME'   ) 
      lt = dlength 
      CASE('ilev', 'ILEV') 
      lzp1 = dlength 
      CASE DEFAULT 
      WRITE(*,*)'ERROR: nc_check for dimensions!'; STOP 
     END SELECT 
    END DO 

    ALLOCATE(vin(lt,lz,ly,lx)) 

    CALL nc_check(nf90_inq_varid(ncid,TRIM(vin_name),var_id)) 
    CALL nc_check(nf90_get_var(ncid,var_id,vin,start=(/1,1,1,1/),count=(/lt,lz,ly,lx/)),fname=TRIM(fname)) 

END SUBROUTINE read_nc4 

    SUBROUTINE nc_check(status,fname) 

    INTEGER, INTENT(IN) :: status 
    CHARACTER(LEN=*), OPTIONAL :: fname 

    IF (status /= nf90_noerr) THEN 
     IF (PRESENT(fname)) THEN 
     WRITE(*,*)'FATAL ERROR in ',TRIM(fname),' ',TRIM(nf90_strerror(status)) 
     ELSE 
     WRITE(*,*)'FATAL ERROR: ',TRIM(nf90_strerror(status)) 
     END IF 
     STOP 
    END IF 

    END SUBROUTINE nc_check 

END MODULE rw_nc4d 
+0

注意を要するすべてのFortran質問にタグfortranを使用してください。バージョン固有の質問には、fortran90のようなバージョンタグを使用します(これはおそらくこのバージョンではありません)。 –

答えて

3

寸法が前後にあります。私はあなたの変数に投稿したのと逆の順番でlongitudelatitudeがあると思われます。形状が[time, level,latitude,longitude]の変数は、Fortranでvar(longitude, latitude, level, time)と宣言する必要があります。

関連する問題