开发者

Functional Arguments in FORTRAN

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 开发者_如何学Python= (/ 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.


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.


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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜