1

问题

我试图让一个函数成为另一个函数的参数,但是我不断收到错误消息:

Error: Internal procedure 'polytrope' is not allowed as an actual argument at (1)

代码

Bellow 是调用该函数并包含实际回调的程序的准系统版本:

PROGRAM testbutcher
  USE butcher
  IMPLICIT NONE

  REAL :: t = 0, dt = 0.01
  REAL, DIMENSION(2) :: v0 = (/ 1.0, 0.0 /), fargs = (/ 1.0, 1.0 /)

  v0 = step(polytrope, v0, 2, t, dt, fargs)

  CONTAINS

  FUNCTION polytrope(v0, t, fargs) result(v1)
    REAL, DIMENSION(:) :: fargs
    REAL, DIMENSION(2) :: v0, v1
    REAL               :: t

    v1 = t * v0
    RETURN
  END FUNCTION

END PROGRAM

然后采用函数参数的函数的模块是:

MODULE butcher
  IMPLICIT NONE

  CONTAINS

  FUNCTION step(fxn, v0, n, t, dt, fargs) RESULT(v1)
    REAL, DIMENSION(n)           :: v0, v1
    REAL, DIMENSION(:)           :: fargs
    REAL, DIMENSION(tn,tm)       :: tab
    REAL                         :: t, dt
    INTEGER                      :: n, tn, tm
    INTERFACE
      FUNCTION fxn(v, t, fargs)
        REAL, DIMENSION(:), INTENT(in) :: v
        REAL, DIMENSION(:), INTENT(in) :: fargs
        REAL, INTENT(in)               :: t
      END FUNCTION
    END INTERFACE

    v1 =  fxn( v0,      &
               t + dt,  &
               fargs    &
             )

    RETURN
  END FUNCTION

END MODULE

概括

所以基本上,testbutcher 包含一个要以特殊方式评估的函数,因此它将它发送到模块 butcher(特别是 butcher 中的函数步骤)进行评估。我无法弄清楚如何实际做到这一点!如果我在 C 语言中工作,我会简单地创建一个指向 polytrope 的指针并将其扔给 fxn。

4

2 回答 2

2

在函数步骤中,您将 fxn 的输入定义为 INTENT(IN),但您没有在函数多方体中声明任何意图。此外,未指定 fxn 的返回类型,因此它是隐式定义的,并且与“REAL,DIMENSION(2)”不兼容。我认为您需要在代码中添加更多“IMPLICIT NONE”声明来捕获此错误。

于 2010-12-13T22:07:15.670 回答
0

这是过去对我有用的所有 MS Fortran、Digital Fortran、Intel Fortran 和 gfortran:

  1. 将函数声明为使用它的模块的外部函数。
  2. 在任何模块之外声明正确的函数(它可以放在自己的文件中)。

我用它来在每个程序中声明一个库调用的“使用”子例程。INTERFACE除非您还使用语句(这不是一个坏主意),否则编译器可能不会检查函数的签名是否正确。

PROGRAM testbutcher
  USE butcher
  IMPLICIT NONE
  EXTERNAL polytrope  !!!!!


  REAL :: t = 0, dt = 0.01
  REAL, DIMENSION(2) :: v0 = (/ 1.0, 0.0 /), fargs = (/ 1.0, 1.0 /)

  v0 = step(polytrope, v0, 2, t, dt, fargs)

  CONTAINS
END PROGRAM
!!!!!
FUNCTION polytrope(v0, t, fargs) result(v1)
  REAL, DIMENSION(:) :: fargs
  REAL, DIMENSION(2) :: v0, v1
  REAL               :: t

  v1 = t * v0
  RETURN
END FUNCTION
于 2010-12-30T01:17:37.130 回答