将Fortran子例程输出写入从Python接口运行的文件

将Fortran子例程输出写入从Python接口运行的文件,python,fortran,fortran90,f2py,Python,Fortran,Fortran90,F2py,下面是我正在运行的Fortran代码,我想将Qr值保存到一个文件中。此子例程在python中调用和执行 subroutine thrustTorque(n, Np, Tp, r, precurve, presweep, precone, & Rhub, Rtip, precurveTip, presweepTip, T, Q) implicit none integer, parameter :: dp = kind(0.d0) ! in integer, intent(in) :

下面是我正在运行的Fortran代码,我想将
Qr
值保存到一个文件中。此子例程在python中调用和执行

subroutine thrustTorque(n, Np, Tp, r, precurve, presweep, precone, &
Rhub, Rtip, precurveTip, presweepTip, T, Q)

implicit none

integer, parameter :: dp = kind(0.d0)

! in
integer, intent(in) :: n
real(dp), dimension(n), intent(in) :: Np, Tp, r, precurve, presweep
real(dp), intent(in) :: precone, Rhub, Rtip, precurveTip, presweepTip

! out
real(dp), intent(out) :: T, Q

! local
real(dp) :: ds
real(dp), dimension(n+2) :: rfull, curvefull, sweepfull, Npfull, Tpfull
real(dp), dimension(n+2) :: thrust, torque, x_az, y_az, z_az, cone, s
integer :: i
这里有一长串的变量和它们的定义,我跳过了

现在这里
Qr(i)
我想要保存在文件中的值

T = 0.0_dp
do i = 1, n+1
    ds = s(i+1) - s(i)
    T = T + 0.5_dp*(thrust(i) + thrust(i+1))*ds
    Q = Q + 0.5_dp*(torque(i) + torque(i+1))*ds
    Qr(i) = Q
end do
end subroutine thrustTorque
我试过这个:

T = 0.0_dp
open (1, file = 'data1.dat', status ='new')
do i = 1, n+1
    ds = s(i+1) - s(i)
    T = T + 0.5_dp*(thrust(i) + thrust(i+1))*ds
    Q = Q + 0.5_dp*(torque(i) + torque(i+1))*ds
    Qr(i) = Q
    write(1, *) Qr(i)
end do
close(1)
end subroutine thrustTorque
在python中使用以下方法调用此子例程:

T, Q = _oxi.thrustTorque(Np, Tp, *args)
我无法返回
Qr
的值,因为这也与代码的其他区域相关,需要进行许多更改。相反,我更喜欢在终端中打印输出或将其保存在文件中

T = 0.0_dp
do i = 1, n+1
    ds = s(i+1) - s(i)
    T = T + 0.5_dp*(thrust(i) + thrust(i+1))*ds
    Q = Q + 0.5_dp*(torque(i) + torque(i+1))*ds
    Qr(i) = Q
end do
end subroutine thrustTorque

虽然程序被执行了,但我没有看到结果被保存在文件中,甚至没有看到文件被创建

有几个问题很突出:

  • 使用文件单元1——这不是一个好主意。Fortran通常将这些低数值用于特定单位,即标准输出、错误输出、标准输入。最好使用以下语法:

    integer :: u ! unit for file i/o
    
    open(newunit=u, file='data1.dat', status='new', action='write')
    do
        ...
    end do
    
    这样,您就可以确保单元号是免费的

  • write(*,*)
    总是写入标准输出——您应该在运行时看到屏幕上显示的值。为了写入文件,您需要用文件单元替换
    write
    语句的第一个
    *

    write(u, *) Qr(i)
    

  • Oki@francescalus的评论是正确的,它仍然使用旧版本,我必须在更改后更新代码,以便接口知道已经进行了更新。使用以下命令执行此操作:
    f2py-c-m codename codename.f90


    Edit:Oki在运行了一些测试之后,我能够打印并创建一个文件,但这必须在一个单独的子例程中,我不理解这一点。看起来它与导入功能有关
    import\u code name
    import code name
    不同。如果有人能解释这一点,请让我知道。

    根据您的观点#2当使用
    write(*,*)
    时,我在终端中没有得到任何输出。在执行这些步骤之后,仍然没有创建任何文件。是否确实正在调用新修改的子例程?是可以打印从
    获得的值
    T
    Q
    ,它们是可用的@Francescalusb但是如果您修改了子例程来处理文件写入等,那么您可能仍然在使用旧版本的对象,而没有使用旧版本的对象?我在虚拟环境中工作,每次运行这些值时都应该重新计算@francescalusTroubleshooting建议:您可以在代码中的某个其他点创建并写入任何文件吗?如果失败,您能在调用Fortran子例程之前用Python创建文件,并通过子例程访问它吗?文件路径是您期望的吗?请进一步深入了解
    import\u codename
    import codename
    之间的区别。我发现它与
    f2py
    调用有关。您可以定义适当的调用,这在我看来是很困难的,也可以让python通过使用
    python setup.py install develope--user
    安装setup.py来完成。这建立在Fortran中所做更改的基础上,并允许python调用它们