python调用fortran的3种形式【f2py,动态链接库,os命令】

一、f2py调用fortran

基于 F2PY,在 Python 中调用 Fortran 函数的基本流程是:

  • Fortran 代码
  • 使用f2py编译 Fortran 代码,产生动态库
  • 在 Python 中通过import引入动态库

注意: F2py 支持有限的 Fortran 子集。

"""======================1.fortran程序========================="""
function foo(a) result(b)
    !kind说明精度
    implicit none
    real(kind=8), intent(in)    :: a(:,:)
    complex(kind=8)             :: b(size(a,1),size(a,2))
    b = exp((0,1)*a)
end function foo

"""=============2.编译fortran程序,生成动态链接库==============="""
f2py -c -m myflib testfun.f90 
#myflib为包名,testfun.f90为上面fortran代码
#在cmd输入上面的命令

"""===================3.import引入动态链接库===================="""
import myflib
import numpy as np
a = np.array([[1,2,3,4], [5,6,7,8]], order='F')
print(myflib.foo(a))

在这里插入图片描述

二、使用动态链接库

Fortran 2003 标准引入了 iso_c_bindings 作为提高与 C 互操作性的一种手段。
在 Python 方面,ctypes 是 stdlib 的一部分,它实现了与外部函数的接口。
这两个工具可以结合起来创建一个支持 Fortran 和 Python 兼容性的接口。
注意:
ctypes不支持复数,可以包装依赖其他函数。
处理多维数组:c和fortran函数返回类型不能是数组。
这是Python 中使用 Fortran 的最通用方式。

2.1 fortran程序:定义了两个函数

1.sum2函数实现双精度浮点数并添加数字 2。
2.double_array函数实现多维数组运算
3.保存为ctypes_test.f90

!bind() 方法创建一个新的函数,在 bind() 被调用时,
!这个新函数的 this 被指定为 bind() 的第一个参数,
!而其余参数将作为新函数的参数,供调用时使用。
function sum2(a) result(b) bind(c, name='sum2')
    use iso_c_binding !fortran自带的
    implicit none
    real(c_double), intent(in)  :: a
    real(c_double)              :: b
    b = a + 2.d0
end function sum2

! 多维数组函数
subroutine double_array(x,N) bind(C, name="double_array")
    use iso_c_binding
    implicit none
    integer(c_int), intent(in), value   :: N
    real(c_double), intent(inout)       :: x(N,N)
    x  = exp(x)
end subroutine double_array

2.2 生成动态链接库

在cmd输入下面的命令

gfortran -shared ctypes_test.f90 -o myflib_ctype.so

2.3 python调用fortran

1.导入动态链接库
2.明确输入输出类型
3.传值调用fortran

import ctypes as ct
import numpy as np # 为处理fortran的多维数组
"=======================调用sum2()========================="
# 1.导入动态链接库,最好写绝对路径
fortlib = ct.CDLL('C:/fortranDM/myflib_ctype.so') 
# 2.导出fortran函数
f = fortlib.sum2
# 3.指定输入输出类型
# ct.POINTER 类似指针
f.argtypes = [ct.POINTER(ct.c_double)]
f.restype = ct.c_double
# 4.创建double对象并将其传递给Fotran(通过引用)
a = ct.c_double(5)
b = f(ct.byref(a))
print(str(f.__name__)+"函数输出:\n",b)

"=======================调用double_array()========================="
# 1.导出fortran函数
f = fortlib.double_array
# 2.指定输入类型
f.argtypes=[ct.POINTER(ct.c_double), ct.c_int]
# 3.创建一个double数组
x = np.ones((3,3), order="F")
x_ptr = x.ctypes.data_as(ct.POINTER(ct.c_double))
# 4.创建double对象并将其传递给Fotran(通过引用)
rint = f(x_ptr, ct.c_int(3))
print(str(f.__name__)+"函数输出:\n",x)

在这里插入图片描述
参考文献:https://www.matecdev.com/posts/fortran-in-python.html

三、利用python的os包调用fortran

下面是fortran程序,分别求半径R=1,3,12.5时的圆周长。
此源程序由二部分组成:主程序和子程序。

!主程序
real :: r(3)
data r /1, 3, 12.5/
do i=1,3
	print *, '半径=', r(i), '圆周长=', C(r(i))
end do
end
!次程序
function c(radius)
	pi=acos(-1.0)
	c=2*pi*radius
	return
end

3.1 os.system命令

os.system(“cmd”) 调用外部命令,程序只能返回命令运行返回码:0正常,1异常;但无法捕获cmd进程执行结果。

import os
os.system(r"gfortran  C:/fortranDM/test.f90")
# 只能输出0

优点:使用简单,可以执行一句话cmd行。
缺点:无法获取cmd执行结果,不能进行交互式调用,以及复杂调用操作。

  • 4
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Matlab与Fortran的混合编程动态链接库,是指在Matlab环境中调用Fortran代码,并将其编译为动态链接库(DLL)的一方式。通过这混合编程的方式,可以充分发挥Matlab和Fortran各自的优势,提高代码执行效率和灵活性。 首先,在Matlab中调用Fortran代码需要通过mex函数来实现。mex函数是Matlab提供的用于编写和编译与Matlab交互的C/C++或Fortran代码的接口函数。我们可以编写一个mex文件,将Fortran代码包装成一个C/C++接口,然后利用mex命令编译成动态链接库。 接着,我们需要将Fortran代码编译为静态库或动态链接库Fortran代码可以通过Fortran编译器进行编译,得到目标文件(.obj或.o文件)。然后,我们可以使用静态库链接器或动态链接器将目标文件与其他必要的库文件一起链接,生成动态链接库文件(.dll或.so文件)。 最后,将生成的动态链接库文件与Matlab中封装Fortran代码的C/C++接口一起编译成mex文件。在Matlab中执行mex命令,将动态链接库文件与Matlab中的接口函数进行链接,然后就可以在Matlab中直接调用Fortran代码了。通过这方式,我们可以在Matlab中使用Fortran的高性能计算能力,并且可以灵活调用Fortran中的代码。 总之,Matlab与Fortran的混合编程动态链接库是一充分利用两编程语言的优势的方式。通过将Fortran代码编译为动态链接库,并在Matlab中调用,可以实现高效的数值计算和快速原型开发。这混合编程的方法可以提高代码的执行效率和灵活性,使得编程工作更加高效和便捷。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值