Python调用Fortran的三种形式
作者:大作家佚名 发布时间:2021-01-10 13:25:08
1. 简介
在一些研究领域很多经典算法和工具都由上古语言Fortran编写,而这部分代码又没有对应的C/C++和Python版本。因此,掌握Python语言调用Fortran程序这一技能,在一些研究领域有助于我们站在巨人的肩上看的更远。Python调用Fortran可以总结为如下三种:
1)通过 F2PY:F2PY 是 NumPy 团队开发的一个工具,可以把 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 circle.f90 -m circle
具体步骤如下图,然后可以看到生成的circle.cpython-36m-x86_64-linux-gnu.so
步骤3:
在Python中,可以直接import上面的函数名
import circle
print(circle.__doc__)
print(circle.area_of_circle(2))
注意上面的__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)
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读取输出文件,也是一种比较好的选择。
来源:https://blog.csdn.net/wokaowokaowokao12345/article/details/128918409


猜你喜欢
- 引用是指保存的值为对象的地址。在 Python 语言中,一个变量保存的值除了基本类型保存的是值外,其它都是引用,因此对于它们的使用就需要小心
- 最终效果展示实现思路在绘图区域插入一个嵌入图,嵌入图与原图的绘画保持一致,通过限制嵌入图的x轴和y轴的显示范围,达到缩放的效果,并在原图上绘
- 前言在制作论文插图时,有时要求将图片的局部放大来展示细节内容,同时将放大图拼接在原图上以方便观察对比。当然直接利用电脑自带的画图软件或者别的
- 实例如下所示:#coding=utf-8import jsonimport geventfrom django.http import Ht
- 前言Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。axios 是目前最优秀的 HTTP 请
- 最近在做压力测试嘛,需要逐步增加用户量做验证,每个用户单独创建数据库进行连接,就要不断去创建数据库,这个报错也很容易理解,mysql连接数不
- 网上学习的时候总会遇到一些好的文章,分享给大家,也谢谢作者的分享。Python 简介Python 是一个高层次的结合了解释性、编译性、互动性
- 假如您在安装SQL Server 2005时出现计数器错误,在搜索过所有的方法都不适用的情况下可以采用以下方法:将4个计数器删除:(如果没有
- MySQL注入的意图是接管网站数据库并窃取信息。常见的开源数据库,如MySQL,已经被许多网站开发人员用来储存重要信息,如密码,个人信息和管
- 先看看那种容易被注入的SQL id = 11001 sql = """
- 武器档案名称:firebug最新版本:1.7用途:前端调试器必备指数:使用难度:firebug是前端最具盛名的调试器,功能非常强悍。fire
- table单元格新增行并编辑,具体内容如下需要bootstrap.min.css —— [ Bootstrap ]jquery-1.8.2.
- 本文实例讲述了JavaScript日期工具类DateUtils定义与用法。分享给大家供大家参考,具体如下:DateUtils = { &nb
- Sqlserver 获取每组中的第一条记录在日常生活方面,我们经常需要记录一些操作,类似于日志的操作,最后的记录才是有效数据,而且可能它们属
- 引言你知道什么是依赖注入吗?依赖注入(DI)的概念虽然听起来很深奥,但是如果你用过一些新兴的php框架的话,对于DI一定不陌生,因为它们多多
- 使用bootstrap-paginator.js 分页来进行ajax 异步分页请求具体的做法如下 :首先定义一个异步提交请求的ajax 函数
- 本文实例讲述了Python查找最长不包含重复字符的子字符串算法。分享给大家供大家参考,具体如下:题目描述请从字符串中找出一个最长的不包含重复
- <HTML> <BODY> <
- blankzheng的blog:http://www.planabc.net/1、使用fieldset和legend标签在form中,我们经
- 1.循环# 1.for...in循环,依次把list或tuple中的每个元素迭代出来studentNames = ["Willar