Fortran Coder

标题: abaqus调用fortran子程序读取txt文件报错forrtl: severe (24) [打印本页]

作者: wzjdse    时间: 2020-8-19 22:10
标题: abaqus调用fortran子程序读取txt文件报错forrtl: severe (24)
各位大佬,我想请教一下,我在用abaqus调用fortran子程序做分析,提示错误:forrtl: severe (24): end-of-file during read, unit 11, file D:\temp\xdata.txt。在网上查网友说是对同一个txt多次读取,后来我就改了一下程序,设置只读一次。如下为代码:但改完依然报同样的错误
[Fortran] 纯文本查看 复制代码
if (stepTime==0) then
         
          !读入轴承力Fx数据
          open(11,file='D:\temp\xdata.txt',status='old')
          do ix=1,10001
              read(11,*)Fxm(ix,1),Fxm(ix,2)    !循环写入
          end do
      
          !读入轴承力Fy数据
          open(11,file='D:\temp\ydata.txt',status='old')
          do iy=1,10001
              read(11,*)Fym(iy,1),Fym(iy,2)    !循环写入
          end do
         
      end if

根据本论坛的一个贴又做了如下修改:

[Fortran] 纯文本查看 复制代码
!只读入一次
      if (stepTime.eq.0) then
         
          !读入轴承力Fx数据
          do ix=1,10001
              open(11,file='D:\temp\xdata.txt',ioStat=krl,
     &        action="readwrite",status="old")
              if(krl==0) then
                  read(11,*)Fxm(ix,1),Fxm(ix,2)    !循环写入
                  close(11)
              end if
          end do
      
          !读入轴承力Fy数据
          do iy=1,10001
              open(11,file='D:\temp\ydata.txt',ioStat=krl,
     &        action="readwrite",status="old")
              if(krl==0) then
                  read(11,*)Fym(iy,1),Fym(iy,2)    !循环写入
                  close(11)
              end if
          end do
         
      end if



报错信息改变为:forrtl: severe (29): file not found, unit 11, file C:\Users\WANGZI~1\AppData\Local\Temp\WangZijia_Housing_15704\fort.11

请教各位大神,我原本以为读取txt很简单,没成想在这卡了好久了





作者: wzjdse    时间: 2020-8-19 22:12
我的思路其实很简答,仿真最开始,读入一个已经存在的txt,之后就不读了(之前方法比较笨,想着是每次abaqus调用子程序时都要读一遍这个txt,但是发现会报错forrtl: severe (24): end-of-file during read,所以正好优化一下只读一次)。
作者: 风平老涡    时间: 2020-8-20 01:39
在你原先的俩循环之间加一个close(11),
作者: 风平老涡    时间: 2020-8-20 01:44
还有就是你的txt文件是否有20002个数据。
作者: wzjdse    时间: 2020-8-20 08:42
风平老涡 发表于 2020-8-20 01:44
还有就是你的txt文件是否有20002个数据。

我的txt就是10001行,两列,如下:
0.000000        19476.300000       
0.000100        19475.066748       
0.000200        19473.864231       
0.000300        19472.702313       
0.000400        19471.590858       
0.000500        19470.539728       
0.000600        19469.558788       
0.000700        19468.657901       
0.000800        19467.846931       
0.000900        19467.135741       
0.001000        19466.534195       
0.001100        19466.049638       
0.001200        19465.659818       
0.001300        19465.343557       
0.001400        19465.083727       

我有两个txt ,分别是xdata和ydata,分别读他们两个并循环给数组赋值,我是这么个思路


作者: wzjdse    时间: 2020-8-20 08:46
风平老涡 发表于 2020-8-20 01:44
还有就是你的txt文件是否有20002个数据。

如果是10001行,2列,那确实是20002个数据
作者: chiangtp    时间: 2020-8-20 12:35
0. 程式裡 沒有其他地方 對 'D:\temp\xdata.txt'檔案 做READ動作

1. 'D:\temp\xdata.txt'檔案 确实是10001行

2. 可能有若干行 不小心的 "沒有2个数据"

3. 一個小 程式驗證一下
[Fortran] 纯文本查看 复制代码
PROGRAM test                                                                    
  IMPLICIT NONE                                                                 
                                                                                
  INTEGER :: i, ier                                                            
  REAL    :: a, b                                                               
                                                                                
  !-----------------                                                            
                                                                                
  OPEN(UNIT=11, FILE='D:\temp\xdata.txt', status='old', IOSTAT=ier)            
  IF( ier /= 0 ) STOP 'Open Error'                                             
                                                                                
  OPEN(UNIT=22, FILE='check.txt')                                               
                                                                                
  !-------                                                                     
                                                                                
  DO i = 0, 10000                                                               
    READ(11, *, IOSTAT=ier) a, b                                                
                                                                                
    IF( ier /= 0 ) THEN                                                         
      WRITE(*,*) i                                                              
      STOP 'Reading Error'                                                      
    END IF                                                                     
                                                                                
   !IF( NINT(a*10000.0) /= i ) THEN                                             
   !  WRITE(*,*) i, a, b                                                        
   !  STOP 'Data Error?'                                                        
   !END IF                                                                     
                                                                                
    WRITE(22,*) i, a, b                                                         
  END DO                                                                        
                                                                                
  !-------                                                                     
                                                                                
  CLOSE(UNIT=11)                                                               
  CLOSE(UNIT=22)                                                               
                                                                                
END PROGRAM test                                                               

作者: wzjdse    时间: 2020-8-20 14:54
chiangtp 发表于 2020-8-20 12:35
0. 程式裡 沒有其他地方 對 'D:\temp\xdata.txt'檔案 做READ動作

1. 'D:\temp\xdata.txt'檔案 确实是10001 ...

您好,我只读一次的问题已经,解决,我换了一个判据。但是我想把数组Fxm和Fym只读一次就保存下来,下次ABAQUS再调用子程序的时候就能用,所以用了save。但是一加save后,又出现了上述错误:forrtl: severe (24): end-of-file during read, unit 55, file D:\temp\xdata.txt.  下面是我的代码:
[Fortran] 纯文本查看 复制代码
dimension Fxm(10001,2)
      dimension Fym(10001,2)
      double precision Fxm,Fym,Fx,Fy,F

      data iread /1/
      save iread
      save Fxm
      save Fym
      
      !只读入一次
      if (iread.eq.1) then
         
          iread=2
          !读入轴承力Fx数据
          open(55,file='D:\temp\xdata.txt',status='old')
          do ix=1,10001
              read(55,*)Fxm(ix,1),Fxm(ix,2)    !循环写入
          end do
          close(55)
      
          !读入轴承力Fy数据
          open(22,file='D:\temp\ydata.txt',status='old')
          do iy=1,10001
              read(22,*)Fym(iy,1),Fym(iy,2)    !循环写入
          end do
          close(22)
         
      end if


想请教您这是为何
作者: chiangtp    时间: 2020-8-20 15:49
1. 用abaqus调用fortran子程序,  "abaqus" 是 Fortran library?
2. 上述程序是子程序, 如果是被某一Fortran程序調用, SAVE: 應該只會讀一次, 数组Fxm和Fym會保存下来
3. 試試
[Fortran] 纯文本查看 复制代码
      if (iread.eq.1) then                                           
          open(55,file='D:\temp\xdata.txt',status='old')            
          do ix=1,10001                                             
              read(55,*) Fxm(ix,1), Fxm(ix,2)                        
              IF( NINT(Fxm(ix,1)*10000.0) /= ix ) THEN               
                WRITE(*,*) iread, ix, Fxm(ix,1), Fxm(ix,2)           
                STOP 'Data Error?'                                   
              END IF                                                
          end do                                                     
          close(55)                                                  
          iread = 2 !---> move to here                              


作者: wzjdse    时间: 2020-8-20 16:01
chiangtp 发表于 2020-8-20 15:49
1. 用abaqus调用fortran子程序,  "abaqus" 是 Fortran library?
2. 上述程序是子程序, 如果是被某一Fortran ...

如果save的数组太大,会不会出现我这个错误,像我的这个数组10001*2,这么大的
作者: wzjdse    时间: 2020-8-20 16:45
chiangtp 发表于 2020-8-20 15:49
1. 用abaqus调用fortran子程序,  "abaqus" 是 Fortran library?
2. 上述程序是子程序, 如果是被某一Fortran ...

abaqus是一个仿真软件,我只需要编辑好子程序,然后他会自动调用
作者: chiangtp    时间: 2020-8-20 18:19
1. 如果save的数组太大,会不会出现我这个错误 (像我的这个数组10001*2,这么大的): 不會的

2. SAVE/只讀一次, 很好的coding (於此, 效率是感受不到的)

3. 如果 datafile: 10001 lines, two REALs per line
          do ix=1,10001
              read(55,*)Fxm(ix,1),Fxm(ix,2)
          end do

    ---> READ(55,*) (Fxm(ix,1),Fxm(ix,2), ix=1,10001) !---> only one "READ"
    就算 datafile 不小心相鄰 two lines 合併為  4 REALs per line, 也不會讀錯 (DO/END DO 就會 runtime end-of-file during read)

4. 讀一次沒錯, CLOSE後, 再次OPEN, 讀寫頭一定在初始位置, 同一個(你要自己確定)file, 讀100次也不會有錯

5. 還有一個可能: 不是 first OPEN, 也不是 COLSE後的OPEN, 而是 Re-OPEN
[Fortran] 纯文本查看 复制代码
! [file "qq"]                                                                
!                                                                           
! 1                                                                          
! 2                                                                          
! 3                                                                          
! 4                                                                          
! 5                                                                          
! 6                                                                          
! 7                                                                          
! 8                                                                          
                                                                             
PROGRAM test                                                                 
  IMPLICIT NONE                                                              
  INTEGER :: i, j                                                            
                                                                             
  OPEN(UNIT=22, FILE='qq', STATUS='old')                                    
                                                                             
  READ(22,*) i, j                                                            
  WRITE(*,*) i, j !---> 1, 2                                                
                                                                             
  call abc()                                                                 
                                                                             
CONTAINS !-----------------------                                            
                                                                             
  SUBROUTINE abc()                                                           
    IMPLICIT NONE                                                            
    INTEGER :: i, j                                                         
                                                                             
    OPEN(UNIT=22, FILE='qq', STATUS='old') !---> re-open                     
                                                                             
    READ(22,*) i, j                                                         
    WRITE(*,*) i, j !---> 3, 4 (not 1, 2)                                    
                                                                             
  END SUBROUTINE abc                                                         
                                                                             
END PROGRAM test                                                            

作者: chiangtp    时间: 2020-8-20 18:28
SUBROUTINE abc()
    OPEN(UNIT=22, FILE='qq', STATUS='old', POSITION='REWIND') !---> 強迫讀寫頭歸位

可以local的解決問題, 但是有個logical error: 為何會發生re-open?
作者: 风平老涡    时间: 2020-8-20 23:54
本帖最后由 风平老涡 于 2020-8-20 16:33 编辑
wzjdse 发表于 2020-8-19 19:42
我的txt就是10001行,两列,如下:
0.000000        19476.300000        
0.000100        19475.066748        

是否编一个小程序,只读这个txt文件


作者: 风平老涡    时间: 2020-8-21 03:45
本帖最后由 风平老涡 于 2020-8-20 16:36 编辑
wzjdse 发表于 2020-8-19 19:42
我的txt就是10001行,两列,如下:
0.000000        19476.300000        
0.000100        19475.066748        

这个txt文件是由abaqus产生的吧,原先的format是什么?
作者: wzjdse    时间: 2020-8-21 08:55
风平老涡 发表于 2020-8-21 03:45
这个txt文件是由abaqus产生的吧,原先的format是什么?

您好,这个txt是之前就有的(拿matlab算出的力的数据),所以我想在最初的时候读入进来
作者: wzjdse    时间: 2020-8-21 09:00
风平老涡 发表于 2020-8-20 23:54
是否编一个小程序,只读这个txt文件

我试了一下,是不是子程序没法再调用另一个子程序? 所以我就直接在子程序里写的读txt的代码,没有单独写一个子程序去读txt
作者: wzjdse    时间: 2020-8-21 09:17
chiangtp 发表于 2020-8-20 18:19
1. 如果save的数组太大,会不会出现我这个错误 (像我的这个数组10001*2,这么大的): 不會的

2. SAVE/只讀 ...

您好,下面这句代码:
[Fortran] 纯文本查看 复制代码
READ(55,*) (Fxm(ix,1),Fxm(ix,2), ix=1,10001)

报错了,错误信息: error #8093: A do-variable within a DO body shall not appear in a variable definition context。显示do的变量不能存在于循环体中。
还是说您的意思是:
[Fortran] 纯文本查看 复制代码
open(22,file='D:\temp\ydata.txt',status='old')
read(22,*)(Fym(iy,1),Fym(iy,2),iy=1,2001)
close(22)


作者: wzjdse    时间: 2020-8-21 09:41
chiangtp 发表于 2020-8-20 18:19
1. 如果save的数组太大,会不会出现我这个错误 (像我的这个数组10001*2,这么大的): 不會的

2. SAVE/只讀 ...

非常感谢您,回答很专业,第三点:
[Fortran] 纯文本查看 复制代码
      open(22,file='D:\temp\ydata.txt',status='old')
      read(22,*)(Fym(iy,1),Fym(iy,2),iy=1,2001)
      close(22)

这样改就解决问题了。

我还想请教一下第二点:SAVE/只讀一次, 很好的coding (於此, 效率是感受不到的)。我不太理解什么意思,是说只读一次效率比较低吗
作者: 风平老涡    时间: 2020-8-21 11:01
用下面的程序读txt文件, 看看是否有错。

[Fortran] 纯文本查看 复制代码
program test
   implicit none
   integer, parameter :: rk=8
   integer :: i
   real(kind=rk) :: x(10001),y(10001)

   open(11, file="xtxt.txt")
   do i=1, 10001
       read(11,*) x(i), y(i)
       write(*,*) x(i), y(i)
   end do
end program test



作者: chiangtp    时间: 2020-8-21 12:46
[Fortran] 纯文本查看 复制代码
  ! Case [A]                                                
  READ(55,*) (Fxm(i,1), Fxm(i,2) , i=1,10001)               
                                                            
  ! Case [B]                                                
  DO i = 10001                                             
    READ(55,*) Fxm(i,1), Fxm(i,2)                           
  END DO                                                   
                                                            
  ! Case [C]                                                
  DO i = 10001                                             
    READ(55,*) tmp, Fxm(i,1), tmp, Fxm(i,2)                 
  END DO                                                   


0. Fortran Standard,  Default, 每做完一次 READ/WRITE, 就會自動 New Line, 除非是 Formatted Format 且有 ADVANCE='NO' 控制

1. Case [A]: 一次讀入 連續10001*2個 REALs (目前line到底了自動newline, READ做完後newline): 不論 (1, and/or , 2, and/or, 5, and/or, 10, ...)個REALs per line
    Case [B]: 一次讀2個 REALs (READ做完後newline), Loop 10001回: 如果不是嚴謹的2 REALs pe line, 至少有10001 lines, 就 掰掰了
    Case [C]: DataFile : >=4 REALs per line, 只想要 第2 及 第4 個REALs

2. DataFile如果是完美的 10001 lines, 2 REALs per line: Cases[A] ==Case[B], Case[B]可以的Case[A]一定可以
    Case[A]OK, Case[B] Fail,  就表示 DataFile不是完美的 10001 lines, 2 REALs per line, ---> [#7]


3. SAVE/只讀一次 很好的coding ,   or,   Case[A] only one READ, Case[B] 10001回READ,    其效率的差異是感受不到的
    (a) 資料量太少了,  0.001秒與0.01秒的感受
    (b) I/O一次 開門關門一次 是很耗時的, 當然編譯器會 很有效率地去做 白紙黑字Case[B]所要求的

4. 總結一下: 不是 Re-Open, 子程序裡SAVE有其功能, DataFile不是完美的 10001 lines, 2 REALs per line?
作者: wzjdse    时间: 2020-8-21 15:13
chiangtp 发表于 2020-8-21 12:46
[Fortran] 纯文本查看 复制代码
  ! Case [A]                                                
  READ(55,*)  ...

如果是caseA,而txt文件有5reals,但是声明的数组是2reals。读的时候按照如下代码读:
[mw_shl_code=fortran,true]READ(55,*) (Fxm(i,1), Fxm(i,2) , i=1,10001)

是不是其余3reals的数据就不会被读到,实际的读到的只有前2reals。还是说会按照,定义列数自动切换行,到时候保存的数组是2reals但是行数超过10001,这样子




欢迎光临 Fortran Coder (http://bbs.fcode.cn/) Powered by Discuz! X3.2