1

我正在运行模型并将模型输出写入二进制文件(GrADS *gra 文件),例如:

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

该文件可以在 GrADS 中读取,*ctl 文件如下所示

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

从一个单独的程序中,我想做的是在 1 个时间步将 1 个变量的所有 x&y 写入一个文本文件。我尝试了多种方法,但没有任何效果。我最近的尝试是这个:

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(:,:)

这个特定的例子给了我以下错误

Fortran 运行时错误:不存在的记录号

但我尝试了其他没有给我任何错误的变体,只是没有写出我试图写入文件的内容。有人可以告诉我我做错了什么以及如何解决这个问题吗?谢谢你。

4

2 回答 2

5

好的,让我再试一次。当您写入时,outfile.gra您似乎nt在块中写入记录

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

我猜这是在代码中的某个地方 irec初始化的。设置为so,如果我的猜测是正确的,您的代码将 5 条记录写入.0nt5outfile.gra

稍后,您在此块中读取了相同的文件

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

目前尚不清楚该if语句在哪里关闭,但从您的问题来看,我猜它在循环结束后关闭nxand ny,如下所示:

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

同样,如果我的猜测是正确的,那么在语句第一次执行时irec具有值。401read

您似乎已写入 5 条记录,outfile.gra并试图从中读取第 401 条记录。运行时报告您正在尝试读取不存在的记录是完全合理的。

于 2012-08-08T10:55:33.210 回答
1

High Performance Markhristo-iliev发现了记录号的问题。为了能够做我想做的事,即在一个时间步写一个变量,正确的代码是

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

在哪里val(nx,ny,nVar)

于 2012-08-08T11:53:01.293 回答