2017-11-02 12 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 질문에 tag fortran 태그를 사용하십시오. 버전 관련 질문에는 fortran90과 같은 버전 태그를 사용하십시오. –

답변

3

앞면 크기가 앞면입니다. 또한 변수에 longitudelatitude이 게시 된 역순으로 의심되는 것으로 나타났습니다. 모양이 [time, level,latitude,longitude] 인 변수는 Fortran에서 var(longitude, latitude, level, time)으로 선언되어야합니다.