使用Julia

时间:2019-07-16 23:54:20

标签: matrix julia binaryfiles

我刚刚开始使用Julia,并且正在尝试读取未格式化的FORTRAN文件并将数据存储在以特定方式成形的数组中。我不确定如何使用Julia完成此操作。

我找到了Julia软件包FortranFiles,该软件包提供了直接使用Julia读取未格式化的FORTRAN文件的方法。我要读取的文件如下:

1 integer:
[nzones]

nzones*3 integers (brackets indicate one record):
[idim1,jdim1,kdim1,idim2,jdim2,kdim2,...,
idim_nzones,jdim_nzones,kdim_nzones]

series of nzones datasets:
[xvalues1,yvalues1,zvalues1](floating point values) for 1st zone
[xvalues1,yvalues1,zvalues1](floating point values) for 2nd zone
...,
[xvalues1,yvalues1,zvalues1](floating point values) for last zone

其中第一行表示区域数,其后的行表示每个i,j和k方向的网格尺寸。在最后一条记录(用...表示)之后是x,y和z坐标,它们是一个区域中每个i,j和k点的Float64s坐标,我想将数组定形为x(1 :im,1:jm,1:km,m),y(1:im,1:jm,1:km,m)和z(1:im,1:jm,1:km,m) ,jm和km是每个区域列出的imax,jmax和kmax范围。这是我到目前为止的内容:

using FortranFiles

fname = "my_file"
fid = FortranFile(fname)

@fread fid nblks::Int32
@fread fid ni::(Int32,nblks) nj::(Int32,nblks) nk::(Int32,nblks)

这是我要挂断电话的地方。对于每个区域,我都有x,y和z坐标数组,它们应该全部为3(或4)维数组。对于x数组,我想存储所有x坐标,其中x [1,1,1,1]指向i = 1,j = 1,k = 1,区域= 1和x处的x坐标值[end,end,end,end]是在i = 15,j = 45,k = 24和zone = 4时的x坐标值。然后,我想为y和z坐标值创建类似的数组。

类似的东西:

for m = 1:nblks
    im = ni[m]
    jm = nj[m]
    km = nk[m]

    @fread fid x::(Float64,im,jm,km,m) y::(Float64,im,jm,km,m) z::(Float64,im,jm,km,m)
end

但是,我遇到一个FortranFilesError:尝试这种方法时尝试读取超出记录末尾的地方。

1 个答案:

答案 0 :(得分:0)

看来我的问题与Julia读取未格式化二进制数据的方式有些相关,这与FORTRAN读取相同数据的方式不同。

在FORTRAN中,我可以做类似的事情:

integer, dimension (:), allocatable :: idim, jdim, kdim
integer :: nblks, fid, ios

fid = 10
open(unit=fid,form='unformatted', file='my_file',status='old',iostat=ios)

if( ios /= 0 ) then
    write(*,*) '*** Error reading file ***'
    stop
end if

read(fid) nblks

allocate( idim(nblks), jdim(nblks), kdim(nblks) )

read(fid) ( idim(m), jdim(m), kdim(m), m = 1, nblks )

close(fid)
...

但是,在Julia中,我需要跟踪文件指针的位置,并意识到每条记录的前面和后面都是4字节整数。我还没有找到一种将每个区域的i,j和k范围直接读入三个单独的数组的方法,就像可以在FORTRAN中完成一样(因为记录可能是逐行解析的),但是Julia中的另一种方法是只需将整个记录读取到单个nblk * 3元素向量中,然后再对向量进行整形:

fid = open("my_file")

skip(fid,4)

nblks = read(fid,Int32)

skip(fid,8)

dims = Array{Int32}(undef,3*nblks)

read!(fid,dims)

ni, nj, nk = [Array{Int32}(undef,nblks) for i in 1:3]

for m in 1:nblks
    ni[m] = dims[3*m-2]
    nj[m] = dims[3*m-1]
    nk[m] = dims[3*m]
end