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

news/2024/11/17 4:25:00/

一、f2py调用fortran

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

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

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

"""======================1.fortran程序========================="""
function foo(a) result(b)!kind说明精度implicit nonereal(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 nonereal(c_double), intent(in)  :: areal(c_double)              :: bb = a + 2.d0
end function sum2! 多维数组函数
subroutine double_array(x,N) bind(C, name="double_array")use iso_c_bindingimplicit noneinteger(c_int), intent(in), value   :: Nreal(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,3print *, '半径=', r(i), '圆周长=', C(r(i))
end do
end
!次程序
function c(radius)pi=acos(-1.0)c=2*pi*radiusreturn
end

3.1 os.system命令

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

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

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


http://www.ppmy.cn/news/598616.html

相关文章

关于gfortran和ifort

最近用fortran写了个程序,分别用gfortran和ifort进行了编译,却发现同样的代码,gfortran可以编译通过,而ifort出错。下面以样例程序加以说明,看看这两个编译器有什么小区别。 代码包括三个源文件:一个主程序…

macOS使用CodeRunner快速配置fortran环境

个人网站:xzajyjs.cn 由于一些项目的缘故,需要有fortran的需求,但由于是M1 mac的缘故,不能像windows那样直接使用vsivf这种经典配置。搜了一下网上主流的跨平台方案,主要是gfortran,最近用Coderunner(主要…

python调用fortran学习笔记

起因:不想把fortran结果手动搬到excel里画图表 先在window系统试, 使用f2py方法的时候总是报错has fortran sources but no fortran compiler found,或者not supported between instances of nonetype and str。 使用dllctypes库的时候&am…

在Linux环境下,使用ifortran编译 带有结构的和.inc头文件 的fortran项目生成.so文件

在Linux环境下,使用ifortran编译 带有结构的和.inc头文件 的fortran项目生成.so文件 1 致谢2 参考文章和手册3 需求描述3.1 文件结构3.2 文件调用关系 4 主程序改造为函数5 项目编译方法5.1 方案一 直接对所有.f90源文件进行编译5.1.1 具体实现5.1.2 注意事项 5.2 方…

Fortran入门——菜鸟级基础语法

前言: 最近需要自学Fortran,本人菜鸟,零基础,这篇文章也是帮助我自己更好的记住一些基础语法。所以,有Fortran基础的,可以跳过本篇啦~ 本文的环境是mingw vscode 哈 1.后缀 Fortran文件的后缀是 .f90(还…

Fortran编译初步

写在前面 注意:本文是关于 gfortran 的文章。如果你不清楚 gfortran,g77,g95 等等的概念的话,不妨看看GCC 的 Fortran 语言编译器介绍;如果你要用 g77 的话,这是一篇g77入门。 [编辑]Fortran 编程中相关文…

idea中有个目录不显示,磁盘中是有的

java项目src下有个目录data不显示 通过打开D盘看目录是有的,运行项目的时候报错,找不到目录下的文件。 解决方案: idea -> file -> seetings -> EDitor -> file types 打开页面后右侧显示有ignore files and folders 查看这里面有…

linux f95编译器,gfortran如何告诉我是否正在编译f90或f95代码?

gfortran可以从文件扩展名中猜出某些东西;如果文件的扩展名为.f,.f90,f95,.f03或.f08,则它将采用具有适当标准的固定(.f)或自由格式。但你可以强制它使用选项-std f2003编译(比方说)fortran2003代码。例如,来自docume…