5

我正在设计一个用于解决 PDE 系统的 Fortran 代码。

它现在的设计方式是我有一个Variable具有多个属性的类型,其中最重要的是val存储值的数组。

现在我还有一个solver类,它将对variable. 我认为将整个传递variable给求解器并在variable%val每次我想运行它时使用(在执行期间数千次)效率低下,所以我决定在solver类中定义指针字段以将求解器绑定到适当的变量。例如

program example
    use variable
    use solvers

    type(Variable) T 
    type(Solver) solver_temperature

    !Contructors
    call T%create()
    call solver_temperature%create(T)

    call solver_temperature%solve()
end program example

和求解器模块

module solvers
type Solver
    real*8, pointer :: T(:,:)

contains 
    procedure :: create
    procedure :: solve
end type

contains
    subroutine create(this,T)
        type(Solver) :: this
        type(Variable) :: T

        this%T => T%val
    end subroutine
end module

在我的程序中,我为不同的物理属性定义了不同的变量,以及与这些变量相关联的不同求解器,如上所示。

一般来说,我是 OOP 的新手,所以我的问题是这是否是一个体面的设计?尤其是从性能的角度来看。就速度而言,这与T仅创建一个数组并将其传递给子程序solve相比如何?有一些常规的方法可以做到这一点吗?

4

1 回答 1

5

我已经使用 Fortran 的 OO 功能一年左右了,这里有一些伪装成答案的扩展评论。

如果您只关心原始执行速度,那么通常(并且基于论证和我的经验而不是数据)您可能会更好地避开 OO 特性;但是在许多情况下,可以提出相同的论点,即最好避免在 FORTRAN77 之后添加到语言中的任何内容。

当基于代码设计、可理解性、可扩展性之类的问题时,支持 OO 的论点会更有说服力。如果这些对您很重要,那么您应该考虑使用 OO 功能。

正如 Vladimir 已经评论的那样,使用变量指针似乎没有多大意义。不要忘记,大多数 Fortran 实现都是通过引用进行调用,以避免复制(大量)数据的工作。

就个人而言,我不喜欢您定义类型绑定过程的方式create。我更喜欢将这种操作实现为一个函数,这样我就可以编写如下代码行:

t = solver%new()

而不是你的

call T%create()

请注意,这是我的偏好,它更多的是风格问题,而不是效率或正确性问题。我注意到您没有向子例程声明参数的意图create;也许是因为您只发布了一段代码。

因为 OO 对于 Fortran 来说相对较新(并且可以说,对于在 Fortran 广泛使用的领域工作的大多数人来说相对陌生),所以没有太多有用的材料来指导我们采用它。我会推荐Scientific Software Design。它对主题进行了不错的覆盖,并就为什么科学和工程程序员应该采用 OO 提出了争论。

于 2012-05-28T10:59:41.737 回答