FORTRAN中的功能参数

时间:2010-12-13 16:05:17

标签: fortran function-pointers fortran90 gfortran

问题

我试图让一个函数成为另一个函数的参数但是我一直得到错误:

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包含一个以特殊方式进行评估的函数,因此它将它发送给模块屠夫(特别是屠夫中的函数步骤)进行评估。我无法弄清楚如何实际做到这一点!如果我在C中工作,我只需要指向polytrope并将其抛给fxn。

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

这是我过去曾为MS Fortran,Digital Fortran,英特尔Fortran和gfortran所做的工作:

  1. 将该函数声明为使用它的模块的外部函数。
  2. 在任何模块之外声明该函数(它可以放在自己的文件中)。
  3. 这是我用来在每个程序中声明一个库调用的'usage'子程序。编译器可能不会检查函数的签名是否正确,除非您还使用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