来自 Fortran 代码的 RECTILINEAR_GRID 的二进制 VTK

Binary VTK for RECTILINEAR_GRID from fortran code

我有一个 Fortran 代码可以生成二进制 VTK 格式的网格。此代码生成一个二进制 VTK 文件,如下所示:

# vtk DataFile Version 3.0
vtk output
BINARY
DATASET RECTILINEAR_GRID
DIMENSIONS        2       2       1
X_COORDINATES        2  float
^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
Y_COORDINATES        2  float
^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
Z_COORDINATES        1  float
^@^@^@^@^@^@^@^@

当我尝试使用 ParaView 打开它时,它崩溃并显示以下错误消息:

ERROR: In /home/user/OpenFOAM/ThirdParty-2.3.0/ParaView-4.1.0/VTK/IO/Legacy/vtkRectilinearGridReader.cxx, line 311 vtkRectilinearGridReader (0x379f4b0): Unrecognized keyword: ...

如果我改为用 ASCII 编写上述文件,那么它会在 ParaView 中正确打开,这就是打开的 ASCII 类似文件:

# vtk DataFile Version 3.0
vtk output
ASCII
DATASET RECTILINEAR_GRID
DIMENSIONS 2 2 1
X_COORDINATES 2 float
0 1
Y_COORDINATES 2 float
0 1
Z_COORDINATES 1 float
0

我正在使用以下代码生成二进制 VTK 格式的网格(我给出的是最低工作代码):

program VTKBinary

implicit none

real*8    :: x(2) = (0., 1.)
real*8    :: y(2) = (0., 1.)
real*8    :: z(1) = (0.)

character :: buffer*80, lf*1, str1*8, str2*8, str3*8
integer   :: ivtk = 9, int

lf = char(10) ! line feed character

open(unit=ivtk,file='test_bin.vtk',form='binary',convert='BIG_ENDIAN')

buffer = '# vtk DataFile Version 3.0'//lf  ; write(ivtk) trim(buffer)
buffer = 'vtk output'//lf                  ; write(ivtk) trim(buffer)
buffer = 'BINARY'//lf                      ; write(ivtk) trim(buffer)
buffer = 'DATASET RECTILINEAR_GRID'//lf    ; write(ivtk) trim(buffer)

! WRITE GRID
write(str1(1:8),'(i8)') size(x)
write(str2(1:8),'(i8)') size(y)
write(str3(1:8),'(i8)') size(z)
buffer = 'DIMENSIONS '//str1//str2//str3//lf  ; write(ivtk) trim(buffer)
buffer = 'X_COORDINATES '//str1//'  float'//lf ; write(ivtk) trim(buffer)
write(ivtk) x
buffer = lf//'Y_COORDINATES '//str2//'  float'//lf  ; write(ivtk) trim(buffer)
write(ivtk) y
buffer = lf//'Z_COORDINATES '//str3//'  float'//lf  ; write(ivtk) trim(buffer)
write(ivtk) z

close(ivtk)

end program VTKBinary

二进制 VTK 文件有什么问题?为什么它退出?

一个问题是,数组被指定为 [0., 1.],而不是 (0., 1.),那将是一个等于一个虚数单位的复数 i .同样的方式 [0.] 而不是 (0.)。感谢 中的 Alexander Voigt 指出问题。

你说你使用 FLOAT,但你在那里存储 real*8。它们不兼容。将 real*4 (或更现代的 real(real32) )存储在那里,或者将文本 DOUBLE 而不是 FLOAT 放在文件中。

请注意,符合 access=stream 的支架比非标准 form=binary 好得多。此外,convert=BIG_ENDIAN 是非标准的,不适用于许多编译器(例如,gfortran,如果我没记错的话)。 char(10) 最好是 achar(10) 但这是一个小问题。

顺便说一句,

buffer = 'DIMENSIONS '//str1//str2//str3//lf  ; write(ivtk) trim(buffer)

可以

write(ivtk) 'DIMENSIONS '//str1//str2//str3//lf