Fortran - 编译错误 - 必须具有显式类型

时间:2014-09-19 17:15:43

标签: fortran fortran90 netcdf

我遇到了以下编译错误,并且无法找到有关如何解决以下问题的任何信息:

CAM_netcdf_to_WRF_intermediate.f90(382): warning #8236: Deferred character length in a data object or component declaration is an extension of Standard F90.
  character(len=:),allocatable :: lon_netcdf_units(:),lon_netcdf_title(:) &
----------------^
CAM_netcdf_to_WRF_intermediate.f90(470): error #6404: This name does not have a type, and must have an explicit type.   [NF90_GET_ATTRIBUTE]
  STATUS = NF90_GET_ATTRIBUTE(NCID, lon_var_id, 'units', lon_netcdf_units)
-----------^

该程序编译为:

ifort -c -CB -CU -ftrapuv -par_report0 -vec_report0 -heap-arrays -O0 -stand f90 -check all -traceback -fstack-protector -assume protect_parens -implicitnone -debug -gen-interfaces -check arg_temp_created -ftrapuv -g -traceback -convert big_endian -I/opt/cray/netcdf/4.3.0/INTEL/130/include/ CAM_netcdf_to_WRF_intermediate.f90 ; ifort CAM_netcdf_to_WRF_intermediate.o -L/opt/cray/netcdf/4.3.0/INTEL/130/lib -lnetcdf -lnetcdff

该计划:

program CAM_netcdf_to_WRF_intermediate
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  use netcdf
  implicit none

  ! Declarations:
  integer, parameter :: outfile_intermediate = 10
  integer, parameter :: outfile_intermediate_SST = 11
  integer, parameter :: outfile_diagnostics = 16
  integer, parameter :: infile_CAM_files_and_dates = 15
  character(len=24) :: HDATE

  ! dimensions:
  integer, parameter :: nx_CAM=288,ny_CAM=192,nz_CAM=26 &
       ,nfields=5,nfields2d=9,nfields2d_to_read=5 &
       ,nz_soil=4,nz_CLM=1,nfields_soil=2
  integer, parameter :: nz_WRF=38
  character(len=128) :: netcdf_cam_filename,netcdf_clm_filename,netcdf_pop_filename
  character(len=128) :: netcdf_ice_filename
  integer :: iEOF
  logical :: EOF
  ! open outpuf log file:
  open(outfile_diagnostics,form='formatted',file="Output/CCSM2WRF.log")

  ! read the first date and netcdf file name from the input file:
  open(infile_CAM_files_and_dates,form='formatted',file="Input/CCSM2WRF.input")
  read(infile_CAM_files_and_dates,*,iostat=iEOF) netcdf_cam_filename,netcdf_clm_filename,&
                        netcdf_pop_filename,netcdf_ice_filename,hdate
  if (iEOF<0) then;
print *, "EOF True"
     EOF=.true.;
  else;
print *, "EOF False"
     EOF=.false.;
  end if
     call dummy_read(nz_WRF,hdate,outfile_diagnostics,outfile_intermediate &
                    ,outfile_intermediate_SST,netcdf_cam_filename &
                    ,netcdf_clm_filename,netcdf_pop_filename &
                    ,netcdf_ice_filename,nx_CAM,ny_CAM,nz_CAM,nfields,nfields2d)
  stop
end program CAM_netcdf_to_WRF_intermediate

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
SUBROUTINE HANDLE_ERR(STATUS)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  use netcdf
  implicit none
  INTEGER STATUS
!  INCLUDE '/opt/cray/netcdf/4.3.0/INTEL/130/include/netcdf.inc'
  IF (STATUS .NE. NF90_NOERR) THEN
     PRINT *, NF90_STRERROR(STATUS)
     STOP 'Stopped'
  ENDIF
END SUBROUTINE HANDLE_ERR

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Subroutine dummy_read &
     (nz_WRF,hdate,outfile_diagnostics,outfile_intermediate &
     ,outfile_intermediate_SST,netcdf_cam_filename &
     ,netcdf_clm_filename,netcdf_pop_filename &
     ,netcdf_ice_filename,nx_CAM,ny_CAM,nz_CAM,nfields,nfields2d)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!  !DEC$ ATTRIBUTES REFERENCE :: HDATE
  use netcdf
  implicit none
  integer :: nz_WRF
  integer :: nx_CAM,ny_CAM,nz_CAM,nfields,nfields2d
  character(len=128) :: filename
  character(len=24) :: HDATE
  integer :: outfile_diagnostics,outfile_intermediate,outfile_intermediate_SST
  integer :: STATUS, NCID, NCID_clm, NCID_pop, NCID_ice
  character(len=128) :: netcdf_cam_filename, netcdf_clm_filename, netcdf_pop_filename
  character(len=128) :: netcdf_ice_filename
  integer :: lat_var_id,lon_var_id,lev_var_id,time_var_id,nlon_var_id &
            ! 3d fields
            ,T_var_id,RH_var_id,U_var_id,V_var_id,GEOP_var_id &
            ! 2d fields
            ,PS_var_id,PSL_var_id,LANDFRAC_var_id,TS_var_id,SEAICE_var_id &
            ! pressure variables
            ,P0_var_id,hyam_var_id,hybm_var_id &
            ! soil variables
            ,SM_var_id,ST_var_id &
            ! surface geopotential
            ,TOPO_var_id
  integer :: field_var_id(nfields),field2d_var_id(nfields2d) &
            ,lon_lat_netcdf_units_length,lon_lat_netcdf_title_length
  character(len=:),allocatable :: lon_netcdf_units(:),lon_netcdf_title(:) &
                                 ,lat_netcdf_units(:),lat_netcdf_title(:)
!  INCLUDE '/opt/cray/netcdf/4.3.0/INTEL/130/include/netcdf.inc'

  ! open output files for metgrid in WRF/WPS intermediate format:
  write(filename,'("Output/FILE:",A13)') hdate(1:13)
  write(outfile_diagnostics,*) "output intermediate file filename=",filename
  open(outfile_intermediate,form='unformatted',file=filename)

  write(filename,'("Output/SST:",A13)') hdate(1:13)
  write(outfile_diagnostics,*) "output intermediate SST file filename=",filename
  open(outfile_intermediate_SST,form='unformatted',file=filename)

  ! CAM
  STATUS = NF90_OPEN(netcdf_cam_filename, 0, NCID)
  IF (STATUS .NE. NF90_NOERR) CALL HANDLE_ERR(STATUS)
  ! CLM
  STATUS = NF90_OPEN(netcdf_clm_filename, 0, NCID_clm)
  IF (STATUS .NE. NF90_NOERR) CALL HANDLE_ERR(STATUS)
  ! POP
  STATUS = NF90_OPEN(netcdf_pop_filename, 0, NCID_pop)
  IF (STATUS .NE. NF90_NOERR) CALL HANDLE_ERR(STATUS)
  ! ICE
  STATUS = NF90_OPEN(netcdf_ice_filename, 0, NCID_ice)
  IF (STATUS .NE. NF90_NOERR) CALL HANDLE_ERR(STATUS)
  write(outfile_diagnostics,*) "done nf90_open"

  ! read netcdf data for all levels:
  ! ================================

  ! get variable IDs
  ! 3d:
  STATUS = NF90_INQ_VARID(NCID, 'lat', lat_var_id)
  STATUS = NF90_INQ_VARID(NCID, 'lon', lon_var_id)
  STATUS = NF90_INQ_VARID(NCID, 'lev', lev_var_id)
  STATUS = NF90_INQ_VARID(NCID, 'time', time_var_id)
  STATUS = NF90_INQ_VARID(NCID, 'nlon', nlon_var_id)
  STATUS = NF90_INQ_VARID(NCID, 'T', T_var_id)
  STATUS = NF90_INQ_VARID(NCID, 'Q', RH_var_id)
  STATUS = NF90_INQ_VARID(NCID, 'U', U_var_id)
  STATUS = NF90_INQ_VARID(NCID, 'V', V_var_id)
  STATUS = NF90_INQ_VARID(NCID, 'Z3', GEOP_var_id)
  IF (STATUS .NE. NF90_NOERR) CALL HANDLE_ERR(STATUS)

  ! 2d:
  STATUS = NF90_INQ_VARID(NCID, 'PS', PS_var_id)
  STATUS = NF90_INQ_VARID(NCID, 'PSL', PSL_var_id)
  STATUS = NF90_INQ_VARID(NCID, 'LANDFRAC', LANDFRAC_var_id)
  STATUS = NF90_INQ_VARID(NCID, 'PHIS', TOPO_var_id)
  IF (STATUS .NE. NF90_NOERR) CALL HANDLE_ERR(STATUS)

  ! pressure variables:
  STATUS = NF90_INQ_VARID(NCID, 'P0', P0_var_id)
  STATUS = NF90_INQ_VARID(NCID, 'hyam', hyam_var_id)
  STATUS = NF90_INQ_VARID(NCID, 'hybm', hybm_var_id)
  IF (STATUS .NE. NF90_NOERR) CALL HANDLE_ERR(STATUS)

  ! soil temp and moisture:
  STATUS = NF90_INQ_VARID(NCID_clm, 'SOILWATER_10CM', SM_var_id)
  STATUS = NF90_INQ_VARID(NCID_clm, 'TSOI_10CM', ST_var_id)
  IF (STATUS .NE. NF90_NOERR) CALL HANDLE_ERR(STATUS)

  ! Ying.Liu sst:
  STATUS = NF90_INQ_VARID(NCID_pop, 'tos', TS_var_id)
  IF (STATUS .NE. NF90_NOERR) CALL HANDLE_ERR(STATUS)

  ! Ying.Liu ice:
  STATUS = NF90_INQ_VARID(NCID_ice, 'aice_d', SEAICE_var_id)
  IF (STATUS .NE. NF90_NOERR) CALL HANDLE_ERR(STATUS)

  write(outfile_diagnostics,*) "done NF90_INQ_VARID, field_var_id=",field_var_id
  write(outfile_diagnostics,*) "field2d_var_id=",field2d_var_id

  ! get attribute values: title and units
  ! =====================================
  ! get units and titles for lon:
  STATUS = NF90_INQUIRE_ATTRIBUTE(NCID, lon_var_id, 'units', lon_lat_netcdf_units_length)
  STATUS = NF90_INQUIRE_ATTRIBUTE(NCID, lon_var_id, 'long_name', lon_lat_netcdf_title_length)
  IF (STATUS .NE. NF90_NOERR) CALL HANDLE_ERR(STATUS)
  write(outfile_diagnostics,*) " lon: netcdf units length=",lon_lat_netcdf_units_length &
       ,"; netcdf title length=",lon_lat_netcdf_title_length
!  allocate(lon_netcdf_units(lon_lat_netcdf_units_length))
!  allocate(lon_netcdf_title(lon_lat_netcdf_title_length))
  STATUS = NF90_GET_ATTRIBUTE(NCID, lon_var_id, 'units', lon_netcdf_units)
  STATUS = NF90_GET_ATTRIBUTE(NCID, lon_var_id, 'long_name', lon_netcdf_title)
  IF (STATUS .NE. NF90_NOERR) CALL HANDLE_ERR(STATUS)
  write(outfile_diagnostics,*) "netcdf title=",lon_netcdf_title,"; units=",lon_netcdf_units
  ! get units and titles for lat:
  STATUS = NF90_INQUIRE_ATTRIBUTE(NCID, lat_var_id, 'units', lon_lat_netcdf_units_length)
  STATUS = NF90_INQUIRE_ATTRIBUTE(NCID, lat_var_id, 'long_name', lon_lat_netcdf_title_length)
  IF (STATUS .NE. NF90_NOERR) CALL HANDLE_ERR(STATUS)
  write(outfile_diagnostics,*) " lat: netcdf units length=",lon_lat_netcdf_units_length &
       ,"; netcdf title length=",lon_lat_netcdf_title_length
!  allocate(lat_netcdf_units(lon_lat_netcdf_units_length))
!  allocate(lat_netcdf_title(lon_lat_netcdf_title_length))
  STATUS = NF90_GET_ATTRIBUTE(NCID, lat_var_id, 'units', lat_netcdf_units)
  STATUS = NF90_GET_ATTRIBUTE(NCID, lat_var_id, 'long_name', lat_netcdf_title)
  IF (STATUS .NE. NF90_NOERR) CALL HANDLE_ERR(STATUS)
  write(outfile_diagnostics,*) "netcdf title=",lat_netcdf_title,"; units=",lat_netcdf_units
!  deallocate(lon_netcdf_units,lon_netcdf_title,lat_netcdf_units,lat_netcdf_title)

  status=NF90_CLOSE(NCID)
  status=NF90_CLOSE(NCID_clm)
  status=NF90_CLOSE(NCID_pop)
  status=NF90_CLOSE(NCID_ice)

print *, "Leaving dummy, going to MAIN"
  return
end Subroutine dummy_read

一个附带问题 - 如果我取消注释在程序最底部分配lon [lat] _netcdf_units [title]的行,则会出现另一个编译器错误:

CAM_netcdf_to_WRF_intermediate.f90(467): error #8232: If any object being allocated in the ALLOCATE statement has deferred type parameter, either type specification or SOURCE= or MOLD= specifiers shall appear.   [LON_NETCDF_UNITS]
  allocate(lon_netcdf_units(lon_lat_netcdf_units_length))
-----------^

我如何分配这些字符?我应该分配它,还是不需要这样做?

1 个答案:

答案 0 :(得分:3)

根据API documentation,要使用的功能应为NF90_GET_ATT

对于正确函数的参数,属性值的变量

  

应该是字符类型的变量,并且len Fortran 90属性设置为适当的值

看起来代码正在尝试确定属性值的长度,然后为每个值分配一个延迟长度字符变量到适当的长度。一个值得称道的目标。

正如编译器警告的那样,这不是Fortran 90的功能,但这不是警告之外的问题。问题在于,值变量

的声明似乎存在一些混淆
character(len=:),allocatable :: lon_netcdf_units(:)

这是一个延迟长度字符变量,但也是一个数组。代替:

character(len=:),allocatable :: lon_netcdf_units

此(现在标量)变量长度的分配遵循表格

allocate( character(len=lon_lat_netcdf_units_length) :: lon_netcdf_units )

这是“类型规范”方法。 [或者,mold=source=选项可用,但这些不值得进入此处。]

[这是基于nf90_inquire_attribute函数返回属性的长度:我的初步检查表明调用可能不正确,并且需要len=关键字。]