在模块中使用外部功能

时间:2017-01-17 15:55:19

标签: fortran gfortran

我正在Fortran中编写一个n维数值解算器。我创建了一个从主程序调用的模块。我在为第一个订单编写ode时使用clang来调用未知函数。但是,在使用external复制多个维度的结果时,我收到以下错误

external

这意味着我的编译器无法使用数组输出处理外部函数。

我尝试使用接口块来预定义具有固定尺寸的函数参数,我最终得到了这个错误

Error: EXTERNAL attribute conflicts with DIMENSION attribute in 'f_x' 

在Fortran中是否有任何方法可以使用外部函数返回在子例程中使用虚函数初始化的数组。

这是我使用的代码。

Error: PROCEDURE attribute conflicts with INTENT attribute in 'f_x' 

我可以在模块中定义一个带有固定功能输入的标准积分器并直接按名称调用它,但由于我处理各种订单的ODE,每次我改变订单时都会很复杂,我需要更新这个模块也是如此。

2 个答案:

答案 0 :(得分:4)

这里有两个不同的问题。

首先,您对函数f_x的显式接口的规范是incorrect:函数结果f_x必须不具有intent(out)属性。这包含第二条错误消息。

第一条错误消息与稍后使用

有关
external f_x

external语句为f_x external属性提供了external。这很好,因为虚拟过程是一个外部函数。但是,您还为该过程提供了与(现已更正的)接口块的显式接口。此接口块还指出该过程具有external属性。

执行此操作后,您违反了一个实体未在一个范围块中两次显式赋予相同属性的约束。要解决此问题,您应删除其中一个规范。因为该函数返回一个数组结果,所以它的接口必须在引用它的子例程中是显式的,因此必须保留接口块。也就是说,删除real(dp) f_x(norder, nvar)语句。

为清楚起见,您还应删除已注释的delayed-web声明。这样的声明对于函数来说是错误的。

答案 1 :(得分:2)

正如francescalus已经指出的那样,函数应该是明确的INTERFACEd,或者声明为EXTERNAL - 而不是两者。使用EXTERNAL是旧式Fortran,因为在Fortran 90中引入了函数接口以取代EXTERNAL的需要,EXTERNAL是一个相当陈旧的功能,仍然可以向后兼容。

此外,函数结果不能具有INTENT属性。函数意味着通过"自己的名称"返回结果,如y=f_x(...)中所示。因此,您应该将f_x本身声明为REAL(没有任何INTENT属性),或者更好的是,在函数声明及其接口中使用RESULT属性。在递归函数中使用RESULT属性实际上是必需的,但即使函数不是递归的,这也是一个好习惯。因此,您的函数的接口应该写为

INTERFACE
    FUNCTION f_x (x_0, t_0) RESULT(res)
        INTEGER, PARAMETER :: dp=kind(0.d0)
        REAL(kind=dp), DIMENSION(2,3), INTENT(IN) :: x_0
        REAL(kind=dp), INTENT(IN) :: t_0
        REAL, DIMENSION(2,3) :: res
    END FUNCTION f_x
END INTERFACE

在实际的f_x实现中,您应该使用res(或者您想要调用RESULT的任何内容)作为保存此函数应该返回的结果的变量。

请注意,我也做了一些非必要的修改,但强烈建议:像你一样声明x_0REAL(dp), INTENT(IN) :: x_0(2, 3)也是旧式Fortran(引入了DIMENSION属性事情更清楚)。此外,一些Fortran实现,尤其是F标准,不接受REAL(dp)而需要REAL(kind=dp)