End of record error in file opening

2019-06-14 04:35发布

I am currently writing a code to simulate particle collisions. I am trying to open as much files as there are particles (N) and then put the data for positions and velocities in each of these files for each step of the time integration (using Euler's method, but that is not relevant). For that, I tried using a do loop so it will open all the files I need - then I put all the data in them with a different do loop later - and then close them all.

I first tried just doing a do loop to open the files - but it gave errors of the type "file already open in another unit", so I did the following:

module parameters
implicit none
character :: posvel
integer :: i, j, N
real :: tmax
real, parameter :: tmin=0.0, pi=3.14159265, k=500.0*10E3, dt=10.0E-5, dx=10.0E-3, g=9.806, ro=1.5*10E3
real, dimension(:), allocatable :: xold, xnew, vold, vnew, m, F, r
end module parameters

PROGRAM Collision
use parameters
implicit none

write(*,*) 'Enter total number of particles (integer number):'
read(*,*) N

allocate(xold(N))
allocate(vold(N))
allocate(xnew(N))
allocate(vnew(N))
allocate(m(N))
allocate(F(N))
allocate(r(N))

xold(1) = 0.0
vold(1) = 0.0
m(1) = 6.283*10E-9
r(1) = 10E-4

xold(2) = 5.0
vold(2) = 0.0
m(2) = 6.283*10E-9
r(2) = 10E-4

write(*,*) 'Type total time elapsed for the simulation(real number):'
read(*,*) tmax

do i = 1, N
    write(posvel,"(a,i3.3,a)") "posveldata",i,".txt"
    open(unit=i,file=posvel, status="unknown")
end do

do i = 1, N
    close(unit=i)
end do

END PROGRAM Collision

The last ten lines are the ones that regard to my problem.

That worked in codeblocks - it opened just the number of files I needed, but I'm actually using gfortran and it gives me and "end of record" error in the write statement.

How can I make it to execute properly and give me the N different files that I need?

P.S.: It is not a problem of compilation, but after I execute the program.

1条回答
混吃等死
2楼-- · 2019-06-14 05:09

Your character string in the parameter module has only 1 character length, so it cannot contain the full file name. So please use a longer string, for example

character(100) :: posvel

Then you can open each file as

do i = 1, N
    write(posvel,"(a,i0,a)") "posveldata",i,".txt"
    open(unit=i,file=trim(posvel), status="unknown")
end do

Here, I have used the format i0 to automatically determine a proper width for integer, and trim() for removing unnecessary blanks in the file name (though they may not be necessary). The write statement can also be written more compactly as

write(posvel,"('posveldata',i0,'.txt')") i

by embedding character literals into the format specification.


The error message "End of record" comes from the above issue. This can be confirmed by the following code

character c

write(c,"(a)") "1"
print *, "c = ", c
write(c,"(a)") "23"   !! line 8 in test.f90
print *, "c = ", c

for which gfortran gives

c = 1
At line 8 of file test.f90
Fortran runtime error: End of record

This means that while c is used as an internal file, this "file" does not have enough space to accommodate two characters (here "23"). For comparison, ifort14 gives

c = 1
forrtl: severe (66): output statement overflows record, unit -5, file Internal Formatted Write

while Oracle Fortran12 gives

c = 1
******  FORTRAN RUN-TIME SYSTEM  ******
Error 1010:  record too long
Location:  the WRITE statement at line 8 of "test.f90"
Aborted

(It is interesting that Oracle Fortran reports the record to be "too long", which may refer to the input string.)

查看更多
登录 后发表回答