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