python-f2py:将数组预先分配为Fortran子例程的输入

这是我想在python中调用的Fortran子例程的最小片段.任务很简单.首次调用该代码时,会将值分配给数组iwk的第一项.然后再次调用该子例程,预期的行为是所分配的条目不变.

subroutine testf2py (md,iwk,ndp,nip)

  implicit none

  integer ndp
!f2py intent(in) :: ndp
  integer nip
!f2py intent(in) :: nip
  integer iwk(31*ndp + nip)
!f2py intent(in) :: iwk     
  integer md
!f2py intent(in) :: md

  if ( md == 1 ) then
    iwk(1) = ndp
  end if  

  print*, iwk(1)

end

(第一次呼叫:md = 1,随后的呼叫:md> 1). iwk数组应在python中分配,并且两次调用之间应保持数组中的值不变.在Fortran中调用此函数可以正常工作:

program main
  implicit none
  integer :: i, ndp, nip  
  integer, allocatable :: iwk(:)

  ndp = 10
  nip = 10

  allocate(iwk(31*ndp+nip))  

  call test (1, iwk, ndp, nip)
  call test (2, iwk, ndp, nip)

end program main

2个调用的输出:

10
10

在python中,用f2py编译子例程后,它不起作用. iwk中的值更改:

import testf2py
import numpy as np

ndp = 10
nip = 10

iwk = np.empty([31*ndp+nip,], dtype=int, order='F')

testf2py.test(1, iwk, ndp, nip)
testf2py.test(2, iwk, ndp, nip)

2个调用的输出:

10
1686728152   

第二个数字是随机的.

我尝试以不同的方式在python中进行分配,即np.empty_like,np.zeros.没有帮助.我认为问题在于如何分配iwk数组(因此出现问题标题),但不确定.我必须进行哪些更改才能使其正常工作?最好是,我只想更改python脚本,并保留Fortran代码不变.

解决方法:

您告诉python数组是intent(in)的:

  integer iwk(31*ndp + nip)
!f2py intent(in) :: iwk  

您无权更改,并希望更改将保留.可能您想要intent(inout).

更好的是,忘记!f2py的意图并直接使用:

  integer, intent(inout) :: iwk(31*ndp + nip)

如果尝试修改intent(in)变量,编译器会告诉您您是错误的.

注意在Python中使用正确的dtype,它必须与Fortran类型相对应.大多数情况下,Fortran整数等效于int32,但有时也可能是int64.您也可以在Fortran中对其进行控制(整数* 4,整数(int32)等).

上一篇:模糊查询(附上源码和jquery-1.12.1.js,jquery-ui.js,jquery-ui.css)


下一篇:[LOG] 「计算物理基础」课程环境搭建手册