1

How do I write out data from an unformatted file in the terminal, in Fortran? Is it possible to do something similar to:

write(*,*) file_with_data

The reason is that I'm using a program where I try to run this code in a do loop:

read(lun) Vl0

But I get an error message in the first iteration. The error message is
"forrtl: severe (67): input statement requires too much data, unit 99" (lun=99)

So I'm trying to understand why there is a mismatch between the amount of data in the lun-file and the allocated array Vlm. Because I don't really understand why there is a mismatch. I thought it would be a good idea to print the data from the lun file and the pre-allocated array for Vlm to see if they match in size.

For further details of the code see below:


The error message appears when the program uses a specific subroutine. Here is a part of the subroutine. I have only selected the lines that I find relevant (The entire subroutine is much longer).

double complex,   allocatable   :: Vlm(:)

allocate (Vlm((grid%Lmax+1)**2))

open(lun, file=vgrdfile,iostat=ios,form='unformatted')
read(lun) ! Skip the header

do i = 1, grid%nrp
 read(lun) Vlm     !Error appears here
end

When I run the program that uses this subroutine I get an error message "forrtl: severe (67): input statement requires too much data, unit 99" (lun=99). In the test I'm running, grid%Lmax=1. So Vlm is really allocated as allocate (Vlm(4)). So for every iteration it should read a line in lun and store that to Vlm. So in the end Vlm should be a double complex array with 4 columns and grid%nrp rows.

The vgrdfile is named chiral-RNN1000-Vlm-L01-R0400-NR00004 and is generated by the following fortran code called potV_chiral.f95 :

program h_pot
integer(kind=4) :: lmax, nr, lmax_pot
real(kind=8) :: rmax
integer(kind=1) :: spherical, linear, even
integer :: i
real(kind=8) :: pi, r
double complex, allocatable :: Vc(:)
real, allocatable :: Vr(:)
real, allocatable :: Vi(:)
nr = 4
lmax = 1
lmax_pot = 1
rmax = 400d0
spherical = 0
linear = 0
even = 0
pi = acos(-1d0)
allocate (Vc( (lmax+1)**2 ))
allocate (Vr( (lmax+1)**2 ))
allocate (Vi( (lmax+1)**2 ))
open(1,file="chiral-RNN1000-Vlm-L01-R0400-NR00004",form="unformatted")
open(2,file="test.txt",form="formatted")
write(1) lmax,nr,rmax,spherical,linear,even !Creating header
do i = 1, nr
    do l=1, (lmax_pot+1)**2
         read(*,*) Vr(l), Vi(l)
         Vc(l)=dcmplx(Vr(l),Vi(l))
    end do
    write(1) Vc
    write(2,*) Vc
end do
close(1)
end program h_pot

The unformatted vgrdfile is created writing "f95 potV_chiral.f95" and "./a.out <complex_sample " Where the complex_sample file consists of two columns:

1.0 1.0
1.0 2.0
1.0 1.0
1.0 0.0
1.0 2.0
1.0 1.0
2.0 0.0
2.0 1.0
0.0 1.0
1.0 1.0
3.0 1.0
2.0 1.0
2.0 1.0
5.0 1.0
5.0 1.0
-1.0 1.0

The test.txt file looks like this:

(  1.00000000    ,  1.00000000    ) (  1.00000000    ,  2.00000000    ) (  1.00000000    ,  1.00000000    ) (  1.00000000    ,  0.00000000    )
(  1.00000000    ,  2.00000000    ) (  1.00000000    ,  1.00000000    ) (  2.00000000    ,  0.00000000    ) (  2.00000000    ,  1.00000000    )
(  0.00000000    ,  1.00000000    ) (  1.00000000    ,  1.00000000    ) (  3.00000000    ,  1.00000000    ) (  2.00000000    ,  1.00000000    )
(  2.00000000    ,  1.00000000    ) (  5.00000000    ,  1.00000000    ) (  5.00000000    ,  1.00000000    ) ( -1.00000000    ,  1.00000000    )

Note that I have very little experience with Fortran and working with binary files.


Edit: As @IanBush suggested. It might be because there is insufficient data. But personally I suspect that the reason is that I store the data in the unformatted file wrong, and not so much because of too little or too much data.
The reason for this is that In the code I can run a similar case, where I instead make a double-precision array (with a different dimension) and create the unformatted file by reading a single data column. This case works perfectly.

double precision, allocatable   :: Vl0(:)

! File header
integer(kind=1) :: head_sym(3)
integer(kind=4) :: head_lmax, head_nr
real(kind=8)    :: head_rmax

lun = 99
open(lun, file=vgrdfile,iostat=ios,form='unformatted')
read(lun) head_lmax,head_nr,head_rmax,head_sym
close(lun)

open(lun, file=vgrdfile,iostat=ios,form='unformatted')
read(lun) ! Skip the header

allocate (Vl0(head_lmax+1))

do i = 1, grid%nrp
        read(lun) Vl0 !works
end

Where the program I use to create the vgridfile is

program pot1
integer(kind=4) :: lmax, nr
real(kind=8) :: rmax
integer(kind=1) :: spherical, linear, even
integer :: i
real(kind=8) :: pi, r
double precision,   allocatable   :: vl0(:)

pi = acos(-1d0)
lmax=2
nr=4
rmax=160
spherical=0
linear=1
even=1

open(1,file="hyd_lineven-RNN1000-Vlm-L02-R0160-NR01024",form="unformatted")
open(2,file="output_lineven",form="formatted")
write(1) lmax,nr,rmax,spherical,linear,even

! Linear and even potential saved as
! V00(r1)  V20(r1)  V40(r1)  V60(r1) ...
! V00(r2)  V20(r2)  V40(r2)  V60(r2) ...
! ...
! V00(rn)  V20(rn)  V40(rn)  V60(rn) ...
allocate ( vl0(lmax+1) )
do i=1,nr
   read(*,*) vl0
   write(*,*) vl0
   write(1) vl0
   write(2,*) vl0
end do
close(1)
end program pot1

Where the output_even.txt looks like this

       0.0000000000000000        0.0000000000000000        0.0000000000000000     
      -22.687409291590601        0.0000000000000000        0.0000000000000000     
      -11.343704645795301        0.0000000000000000        0.0000000000000000     
      -7.5624697638635299        0.0000000000000000        0.0000000000000000   
hh25
  • 161
  • 2
  • `read(lun) Vlm` reads the whole array from the file. The error message strongly suggests that there is insufficient data in the current record in the file to satisfy the request - i.e. the data in the file and the request to read it are inconsistent. – Ian Bush Dec 06 '21 at 14:10
  • Please also note `real(kind=8)` is not portable, may not work and may not do what you expect. See https://stackoverflow.com/questions/838310/fortran-90-kind-parameter – Ian Bush Dec 06 '21 at 14:11
  • OK, looking at your code it is written as `complex` but read as the non-standard `double complex`. These might not be the same. – Ian Bush Dec 06 '21 at 15:55
  • @IanBush Thank you for your reply. I tried changing Vc to be a double complex allocatable array. I also changed the cmplx command to dcmplx. But I still get the same error message. – hh25 Dec 06 '21 at 20:40
  • Well in that case it would very much help if you can show us a *complete* program that reproduces the error you are seeing - without that much will be guesswork. – Ian Bush Dec 06 '21 at 20:45
  • I know that it suggests that there are insufficient data. However, I'm not sure why. In the code, I'm also considering a similar case where the data is stored in a double-precision allocatable array. And it runs perfectly even though the code is structured in the same way. The only difference is that I'm only from a single column with the h_pot program and changed the arrays to double precision. – hh25 Dec 06 '21 at 20:45
  • @IanBush Once again, thank you for your reply. but I'm not sure if I'm entitled to share the entire code since it's used in a research group and I haven't written it. But I don't think it's necessary to see the entire code. It doesn't add any additional insight to the error in my opinion. I know that this is exactly where the error appears and I'm certain that it reads the files listed. So the only question is why the way I'm storing the data in the unformatted file is wrong and cannot be read by the Vlm array. – hh25 Dec 06 '21 at 21:05
  • 2
    You do not have to share whole your internal codebase. The point is to create a small example that shows the problem and can be tested by other people. A [mcve]. The point is in the word *reproducible* - allowing us to reproduce the problem ourselves on our computers. The shorter the better, but it must still contain the problem. – Vladimir F Героям слава Dec 06 '21 at 21:18
  • Be aware that using magic numbers like 4, 8 or 1 for `kind=` is ugly and not portable https://stackoverflow.com/questions/838310/fortran-90-kind-parameter And using small file unit numbers like 1 or 2 is risky. Small numbers are typically used for special purposes. Most often 0,5,6 but others might be used too. – Vladimir F Героям слава Dec 06 '21 at 21:21
  • Showing us code fragments that work I am afraid is not much use in working out where the problem is. Please, a [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) as both I and Vladimir have requested. It shouldn't take much work to knock together a few lines of code which read try to read the file you have created. – Ian Bush Dec 06 '21 at 21:29
  • 3
    @IanBush You were actually correct. The issue was just that I didn't use double complex in both cases. Thank you very much for your help. I wrote a small example which worked. So I couldn't reproduce the mistake. But the issue was that I needed to update an executable with the new adjustments. I will try to keep it simple and write small testable examples in the future. – hh25 Dec 07 '21 at 00:59

0 Answers0