1

I am running a model and writing the model output to a binary file (a GrADS *gra file) such that, for example:

integer,parameter :: nvar =3 ,& !number of variables to be written to file
                     nx=10,ny=10,& !number of girdboxes in lat & long
                     nt = 5
integer :: it, & ! loop counter
           irec  ! Record number
real :: var1(nx,ny), var2(nx,ny),var3(nx,ny)

OPEN(30,file='Outfile.gra',action='write',form='unformatted',access='direct',&
    recl=4*nVar*nx*ny,status='replace')
!loop over timesteps
it  = 1, nt
    irec = irec + 1
    WRITE(1,rec=irec) Var1(:,:),Var2(:,:),Var3(:,:)
enddo

The file can be read in GrADS and the *ctl file looks like this

dset /mypath/Outfile.gra
title MyTitle
options little_endian
xdef 10 linear 1 1
ydef 10 linear 1 1
zdef 1 linear 1.0 1.0
tdef 5 linear 00:00Z01jan2012 1hr
vars 3
var1
var2
var3
endvars

What I would like to do, from a separate program, is write all the x&y of 1 variable at 1 timestep to a text file. I tried a number of ways but nothing has worked. My latest attempt is this one:

integer,parameter :: &
       t = 3,        & !Timestep I want to write to file
       field = 2,    & !Variable I want to write to file      
       nvar =3 ,     & !number of variables to be written to file
       nx=10,ny=10,  & !number of girdboxes in lat & long
       nt = 5          !number of timesteps
inteǵer :: it,ix,iy,&  ! loop counters
           irec        ! Record number
real :: val(nx,ny)     ! Data to be written to file

open(1,file='NewFile.txt',status='replace')
open(2,file='Outfile.gra',action='read',form='unformatted',access='direct',&
   recl=4*nVar*nx*ny,status='old')

irec =  0

do it = 1,nt
   irec=irec + nvar*nx*ny
   if(it == t) then
   irec = irec + (field-1)*nx*ny  
   do ix = 1,nx
     do iy = 1,ny
      irec=irec+1
    read(2,rec=irec) val(ix,iy)
 enddo
enddo
write(1,*) val(:,:)

This particular example gives me the following error

Fortran runtime error: Non-existing record number

but I tried other variations that did not give me any errors but simply didn't write what I was trying to write to file. Could somebody tell me what I am doing wrong and how to solve this? Thank you.

SnowFrog
  • 1,162
  • 4
  • 19
  • 38
  • 1
    You have specified the record length to be `4*nVar*nx*ny` in the `OPEN` statement and then you are incrementing the record number in steps of `nvar*nx*ny`. You only need to increment it with a step of `1`. – Hristo Iliev Aug 08 '12 at 11:02

2 Answers2

5

OK, let me try again. When you write outfile.gra you appear to write nt records to it in the block

!loop over timesteps
it  = 1, nt
    irec = irec + 1
    WRITE(1,rec=irec) Var1(:,:),Var2(:,:),Var3(:,:)
enddo

I guess that irec is initialised to 0 somewhere in the code. nt is set to 5 so, if my guess is correct, your code writes 5 records to outfile.gra.

Later, you read the same file in this block

irec =  0

do it = 1,nt
   irec=irec + nvar*nx*ny
   if(it == t) then
   irec = irec + (field-1)*nx*ny  
   do ix = 1,nx
     do iy = 1,ny
      irec=irec+1
    read(2,rec=irec) val(ix,iy)
 enddo
enddo

It's unclear where the if statement closes but from your question I guess that it closes after the loops over nx and ny, like this:

irec =  0

do it = 1,nt
   irec=irec + nvar*nx*ny
   if(it == t) then
     irec = irec + (field-1)*nx*ny  
     do ix = 1,nx
       do iy = 1,ny
         irec=irec+1
         read(2,rec=irec) val(ix,iy)
       enddo
     enddo
   end if

Again, if my guess is correct, then irec has the value 401 when the read statement is first executed.

It seems that you have written 5 records to outfile.gra and are trying to read the 401st record from it. It's entirely reasonable for the run-time to report that you are trying to read a record that doesn't exist.

High Performance Mark
  • 77,191
  • 7
  • 105
  • 161
  • I was just coming through the same conclusion! I guess I got confused between rec (which = nt) and recl (4*nVar*nx*ny). So now I have `do it = 1, t` `irec = irec + 1` `read(2,rec=irec) val(:,:,:)` `enddo` `write(1,*) val(:,:,field)` but it's not quite there yet, I have too many values. Will work on it and post the answer when I get it – SnowFrog Aug 08 '12 at 11:12
  • ps: I now declare `val(nx,ny,nVar)`. – SnowFrog Aug 08 '12 at 11:18
1

High Performance Mark and hristo-iliev identified the problem with the record number. In order to be able to do what I want, i.e. write a single variable at a single timestep the right code is

irec = 0
do it = 1, t
irec = irec + 1 
read(2,rec=irec) val(:,:,:) 
enddo 
write(1,*) val(:,:,field)

where val(nx,ny,nVar)

Community
  • 1
  • 1
SnowFrog
  • 1,162
  • 4
  • 19
  • 38