首页 > 解决方案 > Fortran:将类型绑定过程与单独文件中的类型定义分开

问题描述

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

主程序如下,

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 支持这个功能。但是,我不明白为什么会引发上述错误。

我检查了这个类似的帖子。但是,我认为该帖子没有给我答案。


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

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

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

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

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

它在目录time_info_t中的一个低级time_base模块中定义base。但初始化过程需要重启解决方案的信息,该信息Init在目录中的上层模块中声明。这可能会导致交叉依赖问题。time_info_trst_inforestartspace

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

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

标签: oopfortran

解决方案


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

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

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


推荐阅读