FORTRAN 中的函数参数

发布于 2024-10-07 06:02:58 字数 1578 浏览 0 评论 0原文

问题

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

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

代码

波纹管是调用该函数的程序的准系统版本其中包含实际的回调:

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

Summary

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

Problem

I am trying to have a function be the argument to another function however I keep getting the error:

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

Code

Bellow is a barebones version of the program making the call to the function and which contains the actual callback:

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

and then the module which the function taking the functional argument is:

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

Summary

So basically, testbutcher contains a function to be evaluated in a special way, so it sends it off to the module butcher (specifically the function step in butcher) to be evaluated. I can't figure out how to actually do this! If I were working in C i would simply make a pointer to polytrope and throw it to fxn.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

箜明 2024-10-14 06:02:58

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

In the function step, you define the inputs to fxn as being of INTENT(IN), but you don't declare any intent in your function polytrope. Also, the return type of fxn is not specified so it is being implicitly defined and won't be compatible with "REAL, DIMENSION(2)". I think you need a few more "IMPLICIT NONE" declarations in your code to catch this error.

何以笙箫默 2024-10-14 06:02:58

这就是我过去使用所有 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

This is what has worked for me in the past with all of MS Fortran, Digital Fortran, Intel Fortran, and gfortran:

  1. Declare the function as external to the module that uses it.
  2. Declare the function proper outside any module (it could go in its own file).

It's what I use to declare a library-invoked 'usage' subroutine in every program. It is likely that the compiler won't check that the function's signature is correct unless you also use an INTERFACE statement (which is not a bad idea).

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文