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 変数のすべての x&y を 1 タイムステップでテキスト ファイルに書き込むことです。私はいくつかの方法を試しましたが、何もうまくいきませんでした。私の最新の試みはこれです:

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初期化されていると思います。私の推測が正しければ、あなたのコードは に 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が、あなたの質問から、次のようnxにループが終了した後に閉じると思います。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

ハイ パフォーマンス マークhristo-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 に答える