我正在用 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/