fmonegaglia
fmonegaglia

Reputation: 2819

f2py subroutine calling fortran functions

Is it possible to write a Fortran f2py subroutine that calls a Fortran function which is calling another Fortran function? For Example:

subroutine hello(a)
    ...
    call  newton(b, c)
    ...
end subroutine hello

subroutine newton (d,e)
    ...
    e=q(d)
    ...
end subroutine newton

real function q(x)
    ...
    q = h(x) + h(x-1)
    ...
end function

real function h(x)
    ...
end function h

Sorry for the mess. I tried but I get errors compiling...the only sub i need to call from Python is the first sub, thanks in advance.

Upvotes: 3

Views: 1497

Answers (1)

OriolAbril
OriolAbril

Reputation: 8773

f2py allows to convert Fortran subroutines to python functions. Therefore, when it tries to convert the Fortran functions to python callable objects it raises an error and crashes. If these functions were to be called from python, they would have to be rewritten as subroutines. However, as they only have to be called from one Fortran subroutine, there is no need for that.

The solution is to include the functions inside the subroutine, using contains. Below there is a working example, using the same structure as above:

subs.f

subroutine hello(a,b)
  real(8), intent(in) :: a
  real(8), intent(out) :: b

  call  newton(a, b)

end subroutine hello

subroutine newton (d,e)
  real(8), intent(in) :: d
  real(8), intent(out) :: e

  e=q(d)

  contains
    real(8) function q(x)
    real(8) :: x

    q = h(x) + h(x-1)

    end function

    real(8) function h(x)
    real(8) :: x

    h = x*x-3*x+2

    end function h
end subroutine newton

This file can be converted to a python callable using f2py, particularly, using the "quick way" explained in the f2py docs running f2py -c subs.f -m fsubs from the command line generates a callable shared object, which can be imported with import fsubs. This module has some help:

help(fsubs)
# Output
Help on module fsubs:

NAME
    fsubs

DESCRIPTION
    This module 'fsubs' is auto-generated with f2py (version:2).
    Functions:
      b = hello(a)
      e = newton(d)
...

As it can be seen, the fsubs module contains 2 functions, hello and newton, the 2 subroutines. Now, we can call hello from python using fsubs.hello(4) which as expected, yields 8.

Upvotes: 3

Related Questions