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



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

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))
-----------^

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

根据API文档,要使用的函数应该是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=关键字。]

最新更新