fortran - 在模块中使用外部函数

标签 fortran gfortran

我正在用 Fortran 编写一个 n 维数值求解器。我为此创建了一个从主程序调用的模块。在编写一阶 ode 时,我使用 external 调用未知函数。但是,在使用 external 复制多维结果时,出现以下错误

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

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

我尝试使用接口(interface) block 来预定义具有固定尺寸的函数参数,但我最终遇到了这个错误

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

在 Fortran 中有什么方法可以让外部函数返回一个数组,该数组正在子例程中使用虚拟函数进行初始化。

这是我使用的代码。

module int_adaptive
implicit none
contains

subroutine RK4nd(f_x, norder, nvar, x_0, t_0, t_f, x_out, t_out)
    INTERFACE
        FUNCTION f_x (x_0, t_0)
            integer, parameter  :: dp=kind(0.d0)
            REAL(dp), INTENT(IN)    :: x_0(2, 3), t_0
            REAL, intent(out)   :: f_x(2,3)
        END FUNCTION f_x
    END INTERFACE


    integer, parameter  :: dp=kind(0.d0)
    integer             :: norder, i, nvar
    external            :: f_x
    real(dp), intent(in):: x_0(norder, nvar), t_0, t_f
    real(dp)            :: x_out(norder, nvar), t_out, k1(norder, nvar), y1(norder, nvar), y(norder, nvar)
    real(dp)            :: k2(norder, nvar), k3(norder, nvar), k4(norder, nvar),&
                           y2(norder, nvar), y3(norder, nvar), y4(norder, nvar)!, f_x(norder, nvar)
    real(dp)            :: h_min, h_0, h_max, tol, err_est, h, t

    if (h_0<h) then
        h = h_0
    end if
    if ((t_f - t_0) < 0.0) then
        h = -h
    end if
    t = t_0
    y = x_0

    do while (t .NE. t_f)
        k1 = f_x(y, t)
        y1 = y + k1*h/2.0

        k2 = f_x(y1, t+h/2.0)
        y2 = y + k2*h/2.0

        k3 = f_x(y2, t+h/2.0)
        y3 = y + k3*h

        k4 = f_x(y3, t+h)
        y4 = y + (k1+ 2*k2 + 2*k3 +k4)*h/6.0

        t = t + h
        y = y4

    end do

    x_out = y
    t_out = t

end subroutine
end module

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

最佳答案

这里有两个截然不同的问题。

首先是函数f_x 的显式接口(interface)规范是incorrect : 函数结果 f_x 不能有 intent(out) 属性。这涵盖了第二条错误消息。

第一条错误信息与后面的使用有关

external f_x

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

这样一来,您就违反了一个约束条件,即在一个范围 block 中,实体不会被显式赋予相同的属性两次。要解决此问题,您应该删除其中一个规范。因为函数返回一个数组结果,它的接口(interface)在引用它的子程序中必须是显式的,所以必须保留接口(interface) block 。也就是说,删除 external 语句。

为清楚起见,您还应该删除注释掉的 real(dp) f_x(norder, nvar) 声明。这样的声明对于函数来说是错误的。

关于fortran - 在模块中使用外部函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41701581/

相关文章:

fortran - 关闭警告 : `Non-conforming tab character` in gfortran

c - 简单数学函数的基准 : why is Fortran and Julia faster than C

fortran - 具有重载赋值的嵌套派生类型

fortran - Fortran 中 COMPILER_OPTIONS() 应该返回什么?

performance - Fortran 递归速度 : pass by reference vs. 按值传递

file-io - 英特尔 Fortran 形式的标准等效项 = 'binary'

Fortran "Error: Two main PROGRAMs at (1) and (2)"

fortran - gfortran 中的 ieee_arithmetic 内在模块

c++ - 这是确定性的步调一致吗?

fortran - 这个 1977 年之前的 Fortran 程序中的参数中的参数是什么意思?