是否可以动态更改读取Fortran名称列表的名称?

时间:2014-07-03 04:22:20

标签: fortran

我想做点什么:

(伪代码)

For all x in my_namelist_list
  Read(unit_number,nml=x)
  ...
  some other operations
  ... 
end

名单的类型是什么?是否可以将其作为参数传递?

subroutine generic_reading_of_namelist(namelist_argument)

有人知道任何解决方法一起操作多个名单吗?

1 个答案:

答案 0 :(得分:3)

简而言之:namelist没有类型,因为它是一个语句,而不是一个变量声明。这意味着它的使用非常有限:仅作为I / O操作的nml =参数。

这也是一个非常古老的功能,如here所述,自推出以来,其功能几乎没有变化。

所以,最直接的取决于你想要做什么。例如,您可以尝试将一个名称列表用于多个目的,或者设计您自己的输入文件格式,并为其启用自定义读取例程。

编辑:

假设您有几个模块中的抽象类型和一些扩展:

module absTypeMod
  implicit none

  type, abstract :: absType
    integer :: i = 0
  contains
    procedure(info), pass(this), public, deferred :: info
  end type

  abstract interface
    subroutine info(this)
      import :: absType
      class(absType), intent(in) :: this
    end subroutine
  end interface
end module

module typeAMod
  use absTypeMod
  implicit none

  type, extends(absType) :: typeA
    private
    integer :: j = 1
  contains
    procedure :: info => info_A
  end type
contains
  subroutine info_A(this)
    class(typeA), intent(in) :: this
    print*, 'i:', this%i, 'j:', this%j
  end subroutine
end module

module typeBMod
  use absTypeMod
  implicit none

  type, extends(absType) :: typeB
    private
    real :: k = 2.0
  contains
    procedure :: info => info_B
  end type
contains
  subroutine info_B(this)
    class(typeB), intent(in) :: this
    print*, 'i: ', this%i, ' k: ', this%k
  end subroutine
end module

然后,您可以创建一个工厂模块,该模块提供基于某些输入实例化具体扩展的逻辑。一个例子:

module factoryMod
  use typeAMod
  use typeBMod
  private

  public :: absType, factory

contains
  subroutine factory(t, switch)
    class(absType), allocatable, intent(out) :: t
    character(*), intent(in) :: switch

    select case(switch)
      case('A')
        allocate(typeA :: t)
      case('B')
        allocate(typeB :: t)
    end select
  end subroutine
end module

并在测试程序中使用它:

program test
  use factoryMod
  implicit none

  class(absType), allocatable :: foo

  call factory(foo, 'A')
  call foo%info()          ! Output: i: 0 j: 1

  call factory(foo, 'B')
  call foo%info()          ! Output: i: 0 k: 2.000000
end program

你可以按照自己的意愿制作这个。我在这里使用一个简单的字符串来选择要在factory中分配的实际类型,但是我还使用了一个实现,我将连接的输入名称列表文件的iunit传递给工厂。在这种情况下,工厂不仅可以使用此文件来确定要创建的类型,还可以执行进一步的特定于类型的设置,无论是在工厂本身还是在某种类型绑定的初始化例程中(使用相同的输入)文件)。

另请注意,此示例工厂是子例程而不是函数,因为Fortran 2003中不允许赋值foo = factory('A') .F2008不再禁止它,但支持目前并不普遍。