具有现代Fortran的求解器的良好OOP设计

tia*_*iam 5 oop fortran fortran2003

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

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

现在我还有一个solver类,它将对a执行计算variable.我认为将整个传递variable给求解器并且variable%val每次我想要运行它(在exectution期间数千次)都是低效的,所以我决定在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
Run Code Online (Sandbox Code Playgroud)

和解算器模块

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
Run Code Online (Sandbox Code Playgroud)

在我的程序中,我按照上面显示的方式为不同的物理属性定义了不同的变量,并为这些变量定义了不同的求解器.

我是OOP的新手,所以我的问题是,如果这是一个体面的设计?特别是从性能的角度来看.这与T仅仅制作一个数组并将其传递给子程序solve的速度相比如何?有没有一些常规的方法来做到这一点?

Hig*_*ark 5

我一直在使用Fortran的OO功能一年左右,这里有一些扩展的评论伪装成答案.

如果您只关心原始执行速度,那么通常(基于参数和我的经验而不是数据),您可能更好地避开OO功能; 但是在很多情况下,可以提出相同的论点,即你最好避免在FORTRAN77之后添加任何语言.

在代码设计,可理解性,可扩展性等问题的基础上,支持面向对象的争论更为强烈.如果这些对您很重要,那么您应该考虑使用OO功能.

正如弗拉基米尔已经评论过的那样,使用变量指针似乎没什么意义.不要忘记大多数Fortran实现都专门用于调用引用,以避免复制(大量)数据.

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

t = solver%new()
Run Code Online (Sandbox Code Playgroud)

而不是你的

call T%create()
Run Code Online (Sandbox Code Playgroud)

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

因为OO对Fortran来说相对较新(并且可以说,对于在Fortran被广泛使用的领域工作的大多数人来说相对不熟悉),没有太多有用的材料来指导我们采用Fortran.我推荐科学软件设计.它为主题提供了良好的报道,并就科学和工程程序员应采用OO的原因提出了论点.