有这样一个外部力的文件,需要每个时间步调用
Fbrk.txt 文件内容如下,第一列是时间
1.07800 13.73559 -16.39831 20.38910 65.25252 -48.86218 4.65947
1.07900 13.79601 -16.47273 20.48058 65.55000 -49.07506 4.68276
1.08000 13.85654 -16.54730 20.57223 65.84805 -49.28829 4.70614
1.08100 13.91718 -16.62199 20.66405 66.14667 -49.50187 4.72960
1.08200 13.97793 -16.69683 20.75603 66.44587 -49.71579 4.75314
1.08300 14.03878 -16.77181 20.84818 66.74563 -49.93005 4.77676
1.08400 14.09974 -16.84692 20.94049 67.04597 -50.14466 4.80048
1.08500 14.16081 -16.92217 21.03297 67.34688 -50.35962 4.82427
1.08600 14.22199 -16.99756 21.12562 67.64837 -50.57492 4.84815
1.08700 14.28327 -17.07308 21.21844 67.95043 -50.79057 4.87212
1.08800 14.34466 -17.14874 21.31142 68.25306 -51.00656 4.89617
1.08900 14.40616 -17.22455 21.40457 68.55626 -51.22289 4.92030
1.09000 14.46776 -17.30048 21.49789 68.86004 -51.43957 4.94452
1.09100 14.52948 -17.37656 21.59137 69.16439 -51.65659 4.96883
1.09200 14.59130 -17.45277 21.68502 69.46932 -51.87396 4.99322
1.09300 14.65323 -17.52912 21.77884 69.77482 -52.09167 5.01770
1.09400 14.71526 -17.60561 21.87283 70.08089 -52.30972 5.04226
1.09500 14.77740 -17.68223 21.96697 70.38750 -52.52809 5.06691
想通过建立一个子程序,当时间为某一时刻,比如,t=0.011时,找到Fbrk.txt中相应的行,读出那一行的数据,加载到主程序中。
我的基本思路是,每次调用的时候都打开文本文件,然后采用动态数组读取t=0.011以前的所有数据到数组中,然后提取此刻时间步(t/0.001+1)的数据.
调试后发现,对应的时刻的数据能正确提取。
但是因为Fbrk.txt 非常大,大约250M,程序大约在50s (大约5万多步)的时候就跳出来了,program exception-breakpoint。
个人认为,数据量很大,每次都要打开文件,读取此时刻以前的所有数据到数组,随着时间推移,数组会非常大,所以会造成出错。
不知道哪位大虾能帮忙找找解决方案。
源程序如下:
--------------------------------------------------------------------------------------------------------------------------------------
SUBROUTINE ForceDLL(time,x,xdot,xdot2,amat,omega,omegadot,F,M)
!DEC$ ATTRIBUTES DLLEXPORT::ForceDLL
!DEC$ ATTRIBUTES ALIAS:'forcedll' :: ForceDLL
! input
DOUBLE PRECISION ,INTENT(IN) :: time ! time
DOUBLE PRECISION ,DIMENSION(3) ,INTENT(IN) :: x ! global position of reference node
DOUBLE PRECISION ,DIMENSION(3) ,INTENT(IN) :: xdot ! global velocity of reference node
DOUBLE PRECISION ,DIMENSION(3) ,INTENT(IN) :: xdot2 ! global acceleration of reference node !
DOUBLE PRECISION ,DIMENSION(3),INTENT(IN) :: omega ! angular velocity of reference node (global base)
DOUBLE PRECISION ,DIMENSION(3) ,INTENT(IN) :: omegadot ! angular acceleration of reference node (global base)
DOUBLE PRECISION ,DIMENSION(3,3),INTENT(IN) :: amat ! rotation matrix (body -> global)
! output
DOUBLE PRECISION ,DIMENSION(3) ,INTENT(OUT) :: F ! External force in reference node (global base)
DOUBLE PRECISION ,DIMENSION(3) ,INTENT(OUT) :: M ! External moment in reference node (global base)
!
INTEGER :: I,J,K,N, L ! generic counter for the time step
real,allocatable :: Force(:,: ) ! read data from external file
!
N=floor(time/0.001)+1
write (*,*) N
allocate(Force(7,N))
open(20, FILE="Fbrk.txt" )
!!! read the external file into an array
do I=1,N
read (20,*) Force(:,I)
end do
close (20)
K=floor(time/0.001)+1
open(300, FILE="data.txt" )
write (300,'(I3,I10/)') N
!
!
!
F(1)=Force(2,K)*1000.0
F(2)=Force(3,K)*1000.0
F(3)=Force(4,K)*1000.0
M(1)=Force(5,K)*1000.0
M(2)=Force(6,K)*1000.0
M(3)=Force(7,K)*1000.0
END SUBROUTINE ForceDLL
---------------------------------------------------------------------------
同时尝试采用直接访问文件(direct)的操作,直接读取对应的行N的数据
调试的时候发现无法正确调用其中的数值
N=floor(time/0.001)+1 !N为数据的行数
open(20, FILE="Fbrk.txt", access='direct', form='formatted', recl=142, status='old')
do while (.true.)
read (20, '(f20.5)', rec=N, IOSTAT=error) Force(:,N)
if (error/=0) exit
end do
close (20)
这里的 read (20, '(f20.5)', rec=N, IOSTAT=error) Force(:,N) 不知道是否使用正确,因为每行有7个数据,需要给Force(1,N)~Force(7,N).
请大家指导指导,非常感谢