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
我的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
如果是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
您好,我只读一次的问题已经,解决,我换了一个判据。但是我想把数组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
如果save的数组太大,会不会出现我这个错误,像我的这个数组10001*2,这么大的
作者: wzjdse 时间: 2020-8-20 16:45
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 编辑
是否编一个小程序,只读这个txt文件
作者: 风平老涡 时间: 2020-8-21 03:45
本帖最后由 风平老涡 于 2020-8-20 16:36 编辑
这个txt文件是由abaqus产生的吧,原先的format是什么?
作者: wzjdse 时间: 2020-8-21 08:55
您好,这个txt是之前就有的(拿matlab算出的力的数据),所以我想在最初的时候读入进来
作者: wzjdse 时间: 2020-8-21 09:00
我试了一下,是不是子程序没法再调用另一个子程序? 所以我就直接在子程序里写的读txt的代码,没有单独写一个子程序去读txt
作者: wzjdse 时间: 2020-8-21 09:17
您好,下面这句代码:
[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
非常感谢您,回答很专业,第三点:
[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 |