首页 > 解决方案 > Fortran 代码仅在通过 python 运行时才会出错

问题描述

我有一个创建 .txt 文件('fortc.txt')的 python 代码(我们称之为'pycode.py')。该文件需要由通过 fortran90 代码生成的 .exe ('f90code.exe') 读取。然后,fortran 代码执行一些操作并将结果写入另一个 .txt 文件(“res_tc.txt”),该文件之前通过 pycode.py 创建,pycode.py 最终将读取和打印。这是python代码:

import csv
import sys, os
import numpy as np

with open('fortc.txt', 'w') as g:
    writer = csv.writer(g, delimiter=" ", quoting=csv.QUOTE_NONE, escapechar=' ')
    writer.writerow(['1', '2', '3', '4'])

    f = open('res_tc.txt','w+')
    os.system('./f90code.exe')
    readres = np.loadtxt('res_tc.txt')
    tc = float(readres)
    print(tc)
    f.close()

如果我手动创建文件'fortc.txt',然后只运行 f90 代码,而不通过 python,一切正常,我得到预期的结果。但是,如果我通过 python 运行所有内容,则会正确创建“fortc.txt”,但显然 fortran 无法正确读取它。事实上,“fortc.txt”中的所有内容都被读取为“0.0000000000000”,执行操作时会产生以下错误:

Note: The following floating-point exceptions are signalling: IEEE_INVALID_FLAG IEEE_DENORMAL

显然我得到了一个“NaN”。此外,看起来 fortran 没有正确运行 do 循环,因为如果我尝试在 do 循环内打印某些内容,我不会打印出任何内容。以下是读取文件的 f90 代码部分:

program tc

      real*8, allocatable:: ne(:), kt(:), abund(:), z(:)
      integer:: i, j, ndati, n
      data ab/0.,0.1,0.31623,1./

      open(96,file='fortc.txt',status='old')

      n=0
      do
        read(96,*,end=320)
        n=n+1
      end do

      320 continue
      ndat=n

      allocate(ne(ndat), kt(ndat), abund(ndat), z(ndat))

      rewind(96)

      do j=1, ndat
         read(96,*) kt(j), abund(j), ne(j), z(j)
         print*, kt(j)
      end do
end program

f90 结束时的 print 调用没有结果,只有上面显示的错误和“NaN”(源自 python 代码中的 print)。另一方面,如果将 print 语句带到 do 循环之外,我会打印一些东西('0.00000000',如上所述)。同样,这只发生在通过 python 运行编译的 fortran 代码时,而如果我只是从终端运行 .exe,它会按预期工作。

do循环的处理方式有什么问题吗?.txt 文件中的数字没有正确读取,并且没有执行打印,这表明我可能存在问题。但是,我无法修复它。

标签: pythonfortran

解决方案


当您调用 fortran 代码时,您的输入文件为空:

with open('fortc.txt', 'w') as g:

默认情况下,Python 将刷新写入此文件的数据,并在您退出with正文时将其关闭。但是您在其中包含了对 fortran 代码的调用。

如果要with用于文件操作,请以这种方式重新排列代码:

import csv
import sys, os
import numpy as np

with open('fortc.txt', 'w') as g:
    writer = csv.writer(g, delimiter=" ", quoting=csv.QUOTE_NONE, escapechar=' ')
    writer.writerow(['1', '2', '3', '4'])

f = open('res_tc.txt','w+')   # not sure why the frotran program would output to "f" just because it is open.  If it does, ok, it will wrk.
os.system('./f90code.exe')
readres = np.loadtxt('res_tc.txt')
tc = float(readres)
print(tc)
f.close()  # you can use explicit open and close calls for fortc.txt as well

推荐阅读