在Fortran中将模块分解为多个文件

时间:2018-02-02 22:28:22

标签: class module namespaces fortran

我试图在不同的派生类型之间添加转换函数。我'米 希望它们是返回其他派生类型的第一个派生类型的函数。只要它们在同一个文件和模块中,这就没问题了。但我真的希望它们能够被分成多个文件,否则它将是一个非常大的文件。由于依赖关系以及Fortran中缺少命名空间,我无法弄清楚如何执行此操作。

有办法做到这一点吗?

以下是我希望分成两个文件(每个派生类型一个)的示例。

Module ConversionStuff
  implicit none

  type A_T
    real :: a, b, c
  contains
    procedure :: toX => a_toX
  end type A_T

  type X_T
    real :: x, y, z
  contains
    procedure :: toA => x_toA
  end type X_T

  contains

  function a_toX(this) result(x)

     class(A_T), intent(inout) :: this
     type(X_T) :: x

     x%x = this%a * 2
     x%y = this%b * 2
     x%z = this%c * 2

  end function a_toX

  function x_toA(this) result(a)

     class(X_T), intent(inout) :: this
     type(A_T) :: a

     a%a = this%x * 0.5
     a%b = this%y * 0.5
     a%c = this%z * 0.5

  end function x_toA

End Module ConversionStuff
如果有拼写错误,我会道歉。我没有简单的方法在这台计算机上编译Fortran。

2 个答案:

答案 0 :(得分:2)

在当前语言中,这很容易通过子模块处理 - 两种类型定义都与祖先模块一起进入“共享”单独模块过程的接口,然后在子模块之间拆分过程定义。

MODULE ConversionStuff
  IMPLICIT NONE
  TYPE :: A_T
    REAL :: a, b, c
  CONTAINS
    PROCEDURE :: toX => a_toX
  END TYPE A_T
  TYPE :: X_T
    REAL :: x, y, z
  CONTAINS
    PROCEDURE :: toA => x_toA
  END TYPE x, y, z
  INTERFACE
    MODULE FUNCTION a_toX(this) RESULT(x)
      IMPLICIT NONE
      CLASS(A_T), INTENT(IN) :: this
      TYPE(X_T) :: x
    END FUNCTION a_toX
    MODULE FUNCTION x_toA(this) RESULT(a)
      IMPLICIT NONE
      CLASS(X_T), INTENT(IN) :: this
      TYPE(A_T) :: a
    END FUNCTION x_toA
  END INTERFACE
END MODULE ConversionStuff

SUBMODULE (ConversionStuff) Procedures_for_X
  IMPLICIT NONE
CONTAINS
  MODULE PROCEDURE a_toX
    x%x = this%a * 2
    x%y = this%b * 2
    x%z = this%c * 2
  END PROCEDURE a_toX
END SUBMODULE Procedures_for_X
...

在Fortran 2008之前,您有时可以使用另一种模拟上述方法的方法 - 程序的实现在一组单独编译的外部过程中使用该模块。需要注意外部程序无法看到自己的界面。

MODULE ConversionStuff
  IMPLICIT NONE
  TYPE :: A_T
    REAL :: a, b, c
  CONTAINS
    PROCEDURE :: toX => a_toX
  END TYPE A_T
  TYPE :: X_T
    REAL :: x, y, z
  CONTAINS
    PROCEDURE :: toA => x_toA
  END TYPE x, y, z
  INTERFACE
    FUNCTION a_toX(this) RESULT(x)
      IMPORT :: A_T
      IMPORT :: X_T
      IMPLICIT NONE
      CLASS(A_T), INTENT(IN) :: this
      TYPE(X_T) :: x
    END FUNCTION a_toX
    FUNCTION x_toA(this) RESULT(a)
      IMPORT :: A_T
      IMPORT :: X_T
      IMPLICIT NONE
      CLASS(X_T), INTENT(IN) :: this
      TYPE(A_T) :: a
    END FUNCTION x_toA
  END INTERFACE
  PRIVATE :: a_toX
  PRIVATE :: x_toA
END MODULE ConversionStuff

FUNCTION A_toX(this) RESULT(x)
  USE ConversionStuff
  IMPLICIT NONE
  CLASS(A_T), INTENT(IN) :: this
  TYPE(X_T) :: x
  ...etc...
END FUNCTION A_toX

对于第二种方法,使用Fortran的可访问性属性(PUBLIC和PRIVATE)存在限制。

请注意,该问题与命名空间无关,因为通常会定义概念。

答案 1 :(得分:0)

在处理完其他事情后,差不多2个月后回到这里。我发现我觉得这个特定用法更加简单和优雅。我将离开之前接受的答案,因为它肯定会回答这个问题,但这是另一种方法。

它使用include关键字。直到现在我还没有理解它在编译包含文件之前没有编译包含文件。也许有些东西我不明白,但对于这种情况,我只想分成多个文件以便我的单个文件不是很大,我认为这种方法值得在我失去的东西中取舍因为它不是一个模块。如果我遗失了某些内容,请告诉我。

我的解决方案如下。

Module ConversionStuff
  implicit none

  type A_T
    real :: a, b, c
  contains
    procedure :: toX => a_toX
  end type A_T

  type X_T
    real :: x, y, z
  contains
    procedure :: toA => x_toA
  end type X_T

  contains

  include "A.f90"
  include "X.f90"

End Module ConversionStuff

A.f90

function a_toX(this) result(x)

    class(A_T), intent(inout) :: this
    type(X_T) :: x

    x%x = this%a * 2
    x%y = this%b * 2
    x%z = this%c * 2

end function a_toX

X.f90

function x_toA(this) result(a)

    class(X_T), intent(inout) :: this
    type(A_T) :: a

    a%a = this%x * 0.5
    a%b = this%y * 0.5
    a%c = this%z * 0.5

 end function x_toA
相关问题