为点列表而不是单个点调用子程序

Call a subroutine for a list of points instead of a single point

我有一段 Fortran 代码。该代码将 'pq' 作为用户的输入,并且是一个单点。我不想这样做,而是想从文件 points.txt 和 运行 中读取一组点 'pq' 来获取这些点数,而不仅仅是一个用户输入。可能吗?代码如下:

program prop

      use module

      implicit none

      character(len=80)    :: ErrorMsg
      character(2)          :: xy
      real(8)               :: Conc(20) = 0.d0
      character(len=20)     :: fn, fl
      real(8)               :: Mmolar, Tcritical, Pcritical, Tmininimum, Tmaximum, x, y

call Init_module()

     write(*,*) 'Insert the gas name:'
     read(*,*) fn
     write(*,*) 'Insert the gas library:'
     read(*,*) fl


     write(*,*) 'Insert the copule pq:'
     read(*,*) pq
     write(*,*) 'Insert the value of ', pq(1:1)
     read(*,*) x
     write(*,*)  'Insert the value of ', pq(2:2)
     read(*,*) y

write(*,*) 'Pres      = ', Pres( pq, x, y, ErrorMsg)
     write(*,*) 'Temp   = ', Temperature( pq, x, y, ErrorMsg)

call ReleaseObjects()

end program prop

我不想在上面的代码中将 pq 作为单个点 x,y 从用户读取,而是想从 file.txt 中读取一组点,例如 50 个点,然后是 运行子程序压力和温度。 文件的每一行包含一个点 x,y 并且每行中的 x 和 y 由几个 space 字符分隔。 file.txt的前几行是:

Ts
500
0.04781564   159.81587875
0.20396084   165.46398084
0.08159885   166.81382894
0.03879184   164.17497877
0.12585959   165.37000305
0.09895530   165.95997769
0.10389518   170.74235496

必须注意的是,浮点数的长度和符号是可以变化的。 file.txt 最初是通过 python 编写的,x、y 的格式为 '%-12.8f %-12.8f\n'%。我有以下代码来尝试读取文件,但无法从第 3 行开始读取:

real, allocatable     :: x(:),y(:)
        integer :: np

        open(12,file=trim('file.txt'),status='old',    &
             access='sequential', form='formatted', action='read' )

            read(12,*)pq
            write(*,*)'pq:', pq

            read(12,*)np
            write(*,*)'number of points:',np

            allocate (x(np))
            allocate (y(np))
            do i=1,np           
            read(12,*)x(i),y(i)
            write(*,*)x(i),y(i)
            enddo

不要使用带有星号 (*) 的 READ 语句作为请求用户输入的第一个参数,而是使用文件标识符。您需要 OPEN 包含点集的文件,假设它是 ASCII :

OPEN(UNIT=10,FILE=file.txt,ACTION='read',STATUS='old')

我认为这个命令的参数非常具有解释性。 然后假设您的文件包含多行 x 和 y 值,您可以通过执行以下操作来读取文件的每一行:

READ(10,*) x,y

如果您有多个要读取的点,如果您知道要读取的点数,只需使用 DO,否则使用 DO WHILE。以 50 分为例,这样的事情应该有效:

OPEN(UNIT=10,FILE=file.txt,ACTION='read',STATUS='old') ! Open file
DO i=1,50
    READ(10,*) x,y
    write(*,*) 'Pres      = ', Pres( pq, x, y, ErrorMsg)
    write(*,*) 'Temp   = ', Temperature( pq, x, y, ErrorMsg)
END DO
CLOSE(10) ! Close file

编辑

你的建议几乎是正确的。您忘记将 pq 声明为 character(len=2)。因此,您不应该能够通过 1 号线。 正如我所说,有一个 space 分隔符自然被星号视为一种格式。无论如何,如果您想完全匹配格式,请使用您编写数据时使用的格式。阅读您的格式 Python,我假设您写了两个带有 space 分隔符的浮点数,实际上,如果您计算数字的字符数:

0.04781564   159.81587875
^^^^^^^^^^^^|^^^^^^^^^^^^
1         12|1          12
            |
          space

在 Fortran 中给出以下格式:

read(12,'(f12.8,1X,f12.8)') x(i),y(i)

X 表示 Fortran 格式的 space 分隔符。

然后你可以在屏幕上以相同的格式写入你的数据来检查:

write(*,'(f12.8,1X,f12.8)') x(i),y(i)

它给出:

pq:Ts 
number of points:         500
0.04781564 159.81587219
0.20396084 165.46397400
0.08159885 166.81382751
0.03879184 164.17497253
0.12585959 165.37001038
0.09895530 165.95997620
0.10389518 170.74235535

您可能已经注意到您在最后一位数字上丢失了精度。这是因为您声明了一个简单的实数(4 个字节)。根据您的编译器,使用 real(kind=8)real*8 将您的 real 切换为 8 个字节(请注意,这不是正确的方法,不可移植但在您的情况下足够)

处理完文件后不要忘记关闭它:

close(12)