【问题标题】:Fortran: Separate type-bound procedure from type definition in separate filesFortran:将类型绑定过程与单独文件中的类型定义分开
【发布时间】:2020-08-25 09:04:31
【问题描述】:

我尝试将类型绑定过程与单独文件中的类型定义分开。 但我失败了。这是代码。

主程序如下,

program main
  !
  use def_mod
  use funcs_mod
  !
  implicit none
  !
  type(time_info_t) :: tinfo
  !
  continue
  !
  call tinfo%InitTimeInfo()
  !
  write(*,*) tinfo%it, tinfo%time
  !
end program main

def_mod如下,

module def_mod
  !
  implicit none
  !
  public
  !
  type :: time_info_t
    !
    integer :: it
    real :: time
    !
    contains
    !
    procedure :: InitTimeInfo
    !
  end type time_info_t
  !
  type(time_info_t) :: time_info
  !
  interface
    !
    subroutine InitTimeInfo(this)
      !
      import time_info_t
      class(time_info_t) :: this
      !
    end subroutine InitTimeInfo
    !
  end interface
  !
contains
  !
  !
end module def_mod

funcs_mod如下,

module funcs_mod
  !
  implicit none
  !
  public
  !
contains
  !
  subroutine InitTimeInfo(this)
    !
    use def_mod, only: time_info_t
    !
    class(time_info_t) :: this
    !
    continue
    !
    this%it = 0
    this%time = 4.0
    !
  end subroutine InitTimeInfo
  !
end module funcs_mod

我执行以下命令来编译和链接程序。

ifort -c def.f90
ifort -c funcs.f90
ifort -o test test.f90 def.o funcs.o

它报告以下错误。

/tmp/ifortigFJkD.o: In function `MAIN__':
test.f90:(.text+0x86): undefined reference to `inittimeinfo_'
/tmp/ifortigFJkD.o:(.rodata+0x0): undefined reference to `inittimeinfo_'

我觉得 Fortran 支持这个功能。但是,我不明白为什么会引发上述错误。

我检查了this similar post。但是,我认为那篇文章没有给我答案。


更新[2020-08-25]:我认为 Fortran 的子模块功能无法实现我的目标。我的目标解释如下。

我正在开发基于有限元方法的 CFD 求解器,试图以有组织的方式组织求解器。

可以将有限元 CFD 求解器组织为包含多个模块。

  • 网格
  • 空间求解器
  • 时间求解器
  • 基础架构,包括数据类型、有限元运算符
  • 其他实用程序模块,例如,保存和写入解决方案文件以重新启动模拟

使用 CMake 编译和链接它们。而这些模块分别放在根文件夹下的不同文件夹中。

这里的一个重要问题是某些模块位于较低级别,而某些模块位于较高级别。高级模块依赖于低级模块。因此,在低级模块中定义的派生类型不能使用在高级模块中定义的派生类型。这个问题促使我将类型绑定过程与不同文件中的类型定义分开。

time_info_t 定义在位于目录base 的低级别time_base 模块中。但是time_info_t 的初始化过程Init 需要重启解决方案rst_info 的信息,该信息在位于目录space 的更高级别restart 模块中声明。这可能会导致交叉依赖问题。

time_info_t 是许多模块使用的通用数据结构。所以我想将time_info_t的定义保留在低级模块中,但将time_info_t%Init的实现移动到另一个文件中的更高级别的模块中。

所以Fortran的子模块特性无法解决这个问题。

【问题讨论】:

  • @HighPerformanceMark 嗨,我知道子模块功能。但我认为这不能解决我的问题。我添加了有关我的问题的更多信息。你能再检查一次吗?谢谢!
  • @HighPerformanceMark 很抱歉造成混乱。我觉得直接调用 Init 过程会是一个好方法。谢谢你们的cmets。

标签: oop fortran


【解决方案1】:

接口块声明了一个外部过程(一个不是内在的并且没有在模块中定义的过程)。 funcs_mod 模块中的子程序 subprogram 定义了一个模块过程。这两种程序不是一回事。

您没有向 Fortran 处理器提供外部过程的定义,因此它会报错。

要么将过程定义移出模块(使其成为子例程程序单元),要么使用单独的模块过程并在子模块中定义过程。

【讨论】:

  • 嗨,我知道子模块功能。但我认为这不能解决我的问题。我添加了有关我的问题的更多信息。你能再检查一次吗?谢谢!
  • 我回答的最后一句话(以及您在问题中链接到的问题/答案中)有两种可能的解决方案。为什么需要将 InitTimeInfo 过程放在模块中?是否会被直接调用(而不是通过绑定调用)?
  • 感谢您的回答。我觉得直接调用过程会是一个好方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-23
  • 1970-01-01
  • 1970-01-01
  • 2012-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多