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.

1
  • 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. Commented Aug 8, 2012 at 11:02

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

I was just coming through the same conclusion! I guess I got confused between rec (which = nt) and recl (4*nVarnxny). 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
ps: I now declare val(nx,ny,nVar).
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)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.