Fortran: namelist + associate不能工作



我将参数存储在派生类型中,并且希望在运行时通过名称列表从文件中加载它们。这是代码的草图:

module options_definitions
implicit none
type :: opts
integer :: option1
integer :: option2
contains
procedure :: load      => load_options
end type opts
contains
subroutine load_options(this,path_to_profiles_folder,profile_name)
class(opts),      intent(inout) :: this
character(len=*), intent(in)    :: path_to_profiles_folder
character(len=*), intent(in)    :: profile_name 
integer                         :: err, ios
logical                         :: file_exists
character(len=255)              :: err_message
character(len=255)              :: path_to_profile_folder
ASSOCIATE( option1    => this%option1, &
           option2    => this%option2)
namelist /options_nml/ option1, option2
! the following is INESSENTIAL added for completeness
!-----------------------------------------------------
path_to_profile_folder=trim(path_to_profiles_folder)//trim(profile_name)
! load options from the configuration file (namelist set above)
INQUIRE(FILE=trim(path_to_profile_folder)//'/'//trim(opt_file_name), EXIST=file_exists)   ! 'file_exists' will be TRUE if the file exists and FALSE otherwise
if (file_exists) then
   call my_open(111,trim(path_to_profile_folder)//'/'//trim(opt_file_name),&
      'Options module could not open the options configuration file')
   read(111,NML=options_nml,iostat=ios,iomsg=err_message)
   call check_read_success_and_close(111,trim(path_to_profile_folder)//'/'//trim(opt_file_name),ios,err_message,&
      'Options module could not read from the options configuration file')
else
   print*,'Warning: The required configuration file containing options &
      (options.nml) does not exist. The inbuilt options will be &
      used instead.'
endif
!---------------------------------------
end associate
end subroutine load_options

编译器报错option1, option2,…((iFort) error #6404: This name does not have a type, and must have an explicit type. [OPTION1]).

从名称列表结构(https://software.intel.com/sites/products/documentation/doclib/stdxe/2013/composerxe/compiler/fortran-mac/GUID-EAC90ABA-859A-4745-B9FC-B8D66B5B6FF0.htm)的描述中,我读到

var-list中的每个变量必须被USE或主机关联访问

我要说的是这里的情况,因为thisintent(inout)的假参数。这不是使用协会吗?

怎么了?是否有一种解决方法,使我不必在不同的地方多次申报相同的东西?

(如。将option1声明为模块私有,并在load_options例程结束时将其复制到this中,而不是使用associate结构,但我更喜欢在以后添加选项时不太容易遗漏的东西)

提前感谢您的评论。

PS:就在发帖之前,我发现了这个问题。代码看起来像它可以做我想要的,但没有看到unit类型的定义,我无法理解它的作用。

编辑1:跟进Vladimir的评论现在我明白是怎么回事了。在问题中,我链接作者使用指向this的指针,而不是指向单个字段,如果我能使其工作,这将是我的首选选项。当我尝试它时,编译器对名称列表声明很好,但拒绝从输入文件读取,说

错误#5498:可分配或指针派生类型的字段需要用户定义的I/O过程。读(111年,NML = options_nml iostat = ios, iomsg = err_message)

有什么建议这样的I/O过程看起来像什么吗?我很困惑,如果有可能在名称列表声明中添加派生类型(或指向它的指针),那么我会假设输入文件中的变量应该被称为this%option1,那就是它。我在这里发现了另一个讨论,来自英特尔的Steve Lionel支持这个观点,他说

Fortran标准只允许在名称列表对象列表中使用"variable-name"。但是,您可以将T放在名称列表中,并在名称列表输入中引用T%I(并在输出中显示)。

但是编译器甚至没有看到文件就报错了。

EDIT2:我在上面的代码中所做的更改(导致第一次编辑时编译器错误)是这样的:

class(opts), intent(inout), target :: THIS
TYPE(opts), POINTER :: THIS_NML
namelist /options_nml/ THIS_NML
THIS_NML => THIS

关联结构被删除,原始名称列表声明被删除。错误发生在if (file_exists)块的read语句中。我所做的就是在命名列表声明中使用一个指向结构体的指针。仅此而已。

实际上你可以使用我的答案链接的解决方案。unit的确切定义在这里并不重要。

select type(t => this)
  type is (opts)
    associate( option1    => t%option1, &
               option2    => t%option2)
      namelist /options_nml/ option1, option2
      read...
    end associate
end select

这是因为this在你的例子中是多态的。

我调查了一下,这种用法是否符合标准,事实并非如此。当被要求遵循标准

时,Ifort明确警告
ifort -stand f08  namelist.f90
namelist.f90(8): warning #7775: Placement of NAMELIST statement is non-standard.

还有许多其他的变通方法。你可以创建本地指针并在名字列表中读取它们,这正是你链接的答案所做的。这也将与gfortran编译。我要走这条路。

integer, pointer :: option1, option2
namelist /options_nml/ option1, option2
option1 => this%option1
option2 => this%option2
read...

或者使用普通的局部变量,将值复制到this

相关内容

  • 没有找到相关文章

最新更新