开发者

Python调用Fortran的三种形式

目录
  • 1. 简介
  • 2. python调用Fortran的三种方法
    • 2.1 基于 F2PY的f2py调用Fortran
    • 2.2 使用动态链接库调用Fortran
    • 2.3 利用Python的os包调用Fortran
  • 3. 总结

    1. 简介

    在一些研究领域很多经典算法和工具都由上古语言Fortran编写,而这部分代码又没有对应的C/C++和Pphpython版本。因此,掌握Python语言调用Fortran程序这一技能,在一些研究领域有助于我们站在巨人的肩上看的更远。Python调用Fortran可以总结为如下三种:

    1)通过 F2PY:F2PY 编程客栈是 NumPy 团队开发的一个工具,可以开发者_JAVA教程把 Fortran 程序转换为 Python 模块,从而在 Python 中调用 Fortran 程序。

    2)通过 ctypes 库:ctypes 是 Python 内置的一个库,可以用来调用外部 C 动态链接库,因此也可以用于调用 Fortran 程序。通过 ctypes 可以让 Python 调用 Fortran 程序,也可以从 Fortran 中调用 Python 函数。

    3)利用Python的os包调用Fortran。

    2. Python调用Fortran的三种方法

    2.1 基于 F2PY的f2py调用Fortran

    步骤1:

    计算圆面积的Fortran函数。接下来将用下面的函数进行演示。这里的例子是返回一个参数的,返回多个参数以及修改参数的Fortran用法。

    Fortran77定义变量时候不用加::

    function area_of_circle (r)  
    ! function result     
    implicit none      
       ! dummy arguments        
       real :: area_of_circle   
       ! local variables 
       real :: r     
       real :: pi
       pi = 4 * atan (1.0)     
       area_of_circle = pi * r**2  
    end function area_of_circle
    

    function area_of_circle (r) result(a)
    implicit none
       real :: a
       real :: r
       real :: pi
       pi = 4 * atan (1.0)
       a = pi * r**2
    end
    

    subroutine area_of_circle (r,a)
    implicit none
       real, intent(out) :: a
       real, intent(in) :: r
       real :: pi
       pi = 4 * atan (1.0)
       a = pi * r**2
    end
    

    步骤2:

    新建circle.f90后,在终端中运行如下代码:

    python -m numpy.f2py -c WARCtEcirandroidcle.f90 -m circle
    

    具体步骤如下图,然后可以看到生成的circle.cpython-36m-x86_64-linux-gnu.so

    Python调用Fortran的三种形式

    步骤3:

    在Python中,可以直接import上面的函数名

    import circle
    print(circle.__doc__)
    print(circle.area_of_circle(2))
    

    Python调用Fortran的三种形式

    注意上面的__doc编程 __是f2py自动生成的,可以看到fortran模块里面包含几个函数,每个函数里面还可以再调用doc看到接口参数类型。

    2.2 使用动态链接库调用Fortran

    步骤1:

    修改上面的Fortran代码,用result返回函数结果,指定输入和返回数据类型。

    function area_of_circle(r) result(area) bind(c, name='area_of_circle')
        use iso_c_binding
        implicit none
        real(c_double) :: area
        real(c_double), intent(in) :: r
        real :: pi
        pi = 4 * atan (1.0)
        area = pi * r**2
    end function area_of_circle
    

    步骤2:

    2.1节 所示,在系统终端或者Pycharm终端中输入命令:

     gfortran -shared circle2.f90 -o circle2.so
    

    步骤3:

    编写Python调用脚本

    import ctypes as ct
    
    # import the shared library
    fortlib = ct.CDLL('./circle2.so')
    
    # Specify arguments and result types
    fortlib.area_of_circle.argtypes = [ct.POINTER(ct.c_double)]
    fortlib.area_of_circle.restype = ct.c_double
    
    # Create a double and pass it to Fotran (by reference)
    a = ct.c_double(2)
    b = fortlib.area_of_circle(ct.byref(a))
    print(b)
    

    Python调用Fortran的三种形式

    2.3 利用Python的os包调用Fortran

    步骤1:

    以2.1节中的Fortran代码为例,稍作修改,这种方式需要Fortran代码是完整的程序可编译为可执行程序。下面代码包含了主函数,即调用函数的函数主体。

    program calling_func
       real :: a
       a = area_of_circle(2.0)
       Print *, "The area of a circle with radius 2.0 is"
       Print *, a
    end program calling_func
    
    function area_of_circle(r)
    ! function result
    implicit none
       ! dummy arguments
       real :: area_of_circle
       ! local variables
       real :: r
       real :: pi
       pi = 4 * atan (1.0)
       area_of_circle = pi * r**2
    end function area_of_circle
    

    步骤2:

    编译和调用,Windows系统注意修改路径,以及可执行程序名后缀应该是exe,Linux可执行程序后缀可以是out或者没有。

    import os
    #编译
    os.system(r"gfortran  ./circle3.f90 -o circle")
    #调用编译的circle程序
    os.system('./circle')
    

    上述代码就是类似于Windows中调用cmd。

    3. 总结

    方法1:比较推荐,针对Python编程,如果返回数据类型复杂,也不是太方便;

    方法2:过于繁琐不推荐;

    方法3:是一种需要首先编译出可执行程序然后调用,交互性不方便。如果将输入输出写为固定文件,然后由Python生产输入文件,由Python读取输出文件,也是一种比较好的选择。

    到此这篇关于Python调用Fortran的三种形式的文章就介绍到这了,更多相关Python调用Fortran内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

    0

    上一篇:

    下一篇:

    精彩评论

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

    最新开发

    开发排行榜