我正在尝试使用f2py编译Fortran 90文件,以在Python模块中使用。该文件由两个子例程组成。我可以在命令窗口中使用gfortran ljlib3.f90
来编译文件,但是在尝试使用f2py编译子例程时出现错误。
我正在Win 10(Python 2.7.10)和Mingw-w64(均已正确安装)上使用Python(x,y)。这很困难,因为这是教程中的其他人的代码,在我看来,在几乎编译结束之前(与教程进行比较时),所有代码都可以正常工作。
这里是文件ljlib3.f90中的子例程:
subroutine EnergyForces(Pos, L, rc, PEnergy, Forces, Dim, NAtom)
implicit none
integer, intent(in) :: Dim, NAtom
real(8), intent(in), dimension(0:NAtom-1, 0:Dim-1) :: Pos
real(8), intent(in) :: L, rc
real(8), intent(out) :: PEnergy
real(8), intent(inout), dimension(0:NAtom-1, 0:Dim-1) :: Forces
!f2py intent(in,out) :: Forces
real(8), dimension(Dim) :: rij, Fij, Posi
real(8) :: d2, id2, id6, id12
real(8) :: rc2, Shift
integer :: i, j
PEnergy = 0.
Forces = 0.
Shift = -4. * (rc**(-12) - rc**(-6))
rc2 = rc * rc
do i = 0, NAtom - 1
!store Pos(i,:) in a temporary array for faster access in j loop
Posi = Pos(i,:)
do j = i + 1, NAtom - 1
rij = Pos(j,:) - Posi
rij = rij - L * dnint(rij / L)
!compute only the squared distance and compare to squared cut
d2 = sum(rij * rij)
if (d2 > rc2) then
cycle
end if
id2 = 1. / d2 !inverse squared distance
id6 = id2 * id2 * id2 !inverse sixth distance
id12 = id6 * id6 !inverse twelvth distance
PEnergy = PEnergy + 4. * (id12 - id6) + Shift
Fij = rij * ((-48. * id12 + 24. * id6) * id2)
Forces(i,:) = Forces(i,:) + Fij
Forces(j,:) = Forces(j,:) - Fij
enddo
enddo
end subroutine
subroutine VVIntegrate(Pos, Vel, Accel, L, CutSq, dt, KEnergy, PEnergy, Dim,
NAtom)
implicit none
integer, intent(in) :: Dim, NAtom
real(8), intent(in) :: L, CutSq, dt
real(8), intent(inout), dimension(0:NAtom-1, 0:Dim-1) :: Pos, Vel, Accel
!f2py intent(in,out) :: Pos, Vel, Accel
real(8), intent(out) :: KEnergy, PEnergy
external :: EnergyForces
Pos = Pos + dt * Vel + 0.5 * dt*dt * Accel
Vel = Vel + 0.5 * dt * Accel
call EnergyForces(Pos, L, CutSq, PEnergy, Accel, Dim, NAtom)
Vel = Vel + 0.5 * dt * Accel
KEnergy = 0.5 * sum(Vel*Vel)
end subroutine
注意,!f2py intent(in,out)...
伪指令也用于子例程中。
使用f2py命令后:
f2py -c -m ljlib ljlib3.f90 --fcompiler=gnu95 compiler=mingw32
出现以下错误:
C:\Program_Files\mingw-w64\x86_64-7.2.0-posix-sjlj-rt_v5-
rev1\mingw64\bin\gfortran.exe -Wall -g -Wall -g -shared
c:\users\pc2012\appdata\local\temp\tmp_pzjlc\Release\users
\pc2012\appdata\local\temp\tmp_pzjlc\src.win32-2.7\ljlibmodule.o
c:\users\pc2012\appdata\local\temp\tmp_pzjlc\Release\users
\pc2012\appdata\local\temp\tmp_pzjlc\src.win32-2.7\fortranobject.o
c:\users\pc2012\appdata\local\temp\tmp_pzjlc\Release\ljlib3.o -
LC:\Program_Files\mingw-w64\x86_64-7.2.0-posix-sjlj-rt_v5-
rev1\mingw64\lib\gcc\x86_64-w64-mingw32\7.2.0 -LC:\Python27\libs -
LC:\Python27\PCbuild -lpython27 -lgfortran -o .\ljlib.pyd
c:\users\pc2012\appdata\local\temp\tmp_pzjlc\Release\users
\pc2012\appdata\local\temp\tmp_pzjlc\src.win32-
2.7\ljlibmodule.o:ljlibmodule.c:(.text+0x1a): undefined reference to
`__imp_PyFloat_Type'
c:\users\pc2012\appdata\local\temp\tmp_pzjlc\Release\users
\pc2012\appdata\local\temp\tmp_pzjlc\src.win32-
2.7\ljlibmodule.o:ljlibmodule.c:(.text+0x26): undefined reference to
`__imp_PyType_IsSubtype'
c:\users\pc2012\appdata\local\temp\tmp_pzjlc\Release\users
\pc2012\appdata\local\temp\tmp_pzjlc\src.win32-
2.7\ljlibmodule.o:ljlibmodule.c:(.text+0x55): undefined reference to
`__imp_PyNumber_Float' ...
error: Command "C:\Program_Files\mingw-w64\x86_64-7.2.0-posix-sjlj-rt_v5-
rev1\mingw64\bin\gfortran.exe -Wall -g -Wall -g -shared
c:\users\pc2012\appdata\local\temp\tmp_pzjlc\Release\users
\pc2012\appdata\local\temp\tmp_pzjlc\src.win32-2.7\ljlibmodule.o
c:\users\pc2012\appdata\local\temp\tmp_pzjlc\Release\users
\pc2012\appdata\local\temp\tmp_pzjlc\src.win32-2.7\fortranobject.o
c:\users\pc2012\appdata\local\temp\tmp_pzjlc\Release\ljlib3.o -
LC:\Program_Files\mingw-w64\x86_64-7.2.0-posix-sjlj-rt_v5-
rev1\mingw64\lib\gcc\x86_64-w64-mingw32\7.2.0 -LC:\Python27\libs -
LC:\Python27\PCbuild -lpython27 -lgfortran -o .\ljlib.pyd" failed with exit
status 1
许多undefined reference to
....'`之后发生错误。我想这是一些PATH问题,但我不确定。
import numpy as np
def EnergyForces(Pos, L, rc, Natom):
PEnergy = 0.
Forces = np.zeros([Natom,3])
Posi = np.zeros([1,3])
Shift = -4.*(rc**(-12) - rc**(-6))
rc2 = rc*rc
for i in range(Natom):
Posi = Pos[i,:]
for j in range(i+1,Natom):
rij = Pos[j,:] - Posi
rij = rij - L*np.round(rij / L)
d2 = np.linalg.norm(rij)**2
if d2 > rc2:
continue
id2 = 1. / d2
id6 = id2 * id2 * id2
id12 = id6 * id6
PEnergy = PEnergy + 4. * (id12 - id6) + Shift
Fij = rij * ((-48. * id12 + 24. * id6) * id2)
Forces[i,:] = Forces[i,:] + Fij
Forces[j,:] = Forces[j,:] - Fij
return PEnergy, Forces
def VVIntegrate(Pos, Vel, Accel, L, rc, dt, Natom):
Pos = Pos + dt*Vel + 0.5*dt*dt*Accel
Vel = Vel + 0.5*dt*Accel
PEnergy, Accel = EnergyForces(Pos, L, rc, Natom) #FOR THE NEW FORCES
Vel = Vel + 0.5*dt*Accel
KEnergy = 0.5*np.linalg.norm(Vel)**2
return Pos, Vel, Accel, KEnergy, PEnergy