用Fortran写一个带有原始二进制数据的.vtu文件(paraview)。

问题描述 投票:0回答:1

我想写一个Fortran子程序,输出一个.vtu的原始二进制数据文件。我成功地写了一个.vtk二进制文件和.vtu ascii文件,但在这种文件中,我不知道问题出在哪里。我的子程序,生成的.vtu文件和paraview的错误信息如下。

MODULE OUTPUT
IMPLICIT NONE
CONTAINS
function itoa(i) result(res)
  character(:),ALLOCATABLE :: res
  INTEGER,intent(in) :: i
  character(range(i)+2) :: tmp
  write(tmp,'(i0)') i
  res = trim(tmp)
end function
SUBROUTINE print_vtu_binary_appended(step,number_of_particles,system_name,position,velocity,radius)
use iso_fortran_env
implicit none
real(kind=real64), intent(in), dimension(number_of_particles,3) :: position, velocity
real(kind=real64), intent(in), dimension(number_of_particles) :: radius
integer(kind=int32), intent(in) :: step, number_of_particles
integer(kind=int32), dimension(6) :: offset
integer(kind=int32) :: vtu, print_number=0
character(len=*), intent(in) :: system_name

offset(1) = 0
offset(2) = offset(1) + 4 + SIZEOF(position)
offset(3) = offset(2) + 4 + SIZEOF(velocity)
offset(4) = offset(3) + 4 + SIZEOF(radius)
offset(5) = offset(4) + 4
offset(6) = offset(5) + 4
OPEN(newunit=vtu, action='write', access='stream', STATUS='new', form='unformatted', FILE='./'//TRIM(system_name)//itoa(print_number)//'.vtu')
WRITE(vtu)'<?xml version="1.0"?>'//NEW_LINE('A')
WRITE(vtu)'<VTKFile type="UnstructuredGrid" version="0.1" byte_order="LittleEndian">'//NEW_LINE('A')
WRITE(vtu)'<UnstructuredGrid>'//NEW_LINE('A')
WRITE(vtu)'<Piece NumberOfPoints="'//itoa(number_of_particles)//'" NumberOfCells="0">'//NEW_LINE('A')
WRITE(vtu)'<Points>'//NEW_LINE('A')
WRITE(vtu)'<DataArray name="Position" type="Float64" NumberOfComponents="3" format="appended" offset="'//itoa(offset(1))//'">'//NEW_LINE('A')
WRITE(vtu)'</DataArray>'//NEW_LINE('A')
WRITE(vtu)'</Points>'//NEW_LINE('A')
WRITE(vtu)'<PointData>'//NEW_LINE('A')
WRITE(vtu)'<DataArray type="Float64" Name="Velocity" NumberOfComponents="3" format="appended" offset="'//itoa(offset(2))//'">'//NEW_LINE('A')
WRITE(vtu)'</DataArray>'//NEW_LINE('A')
WRITE(vtu)'<DataArray type="Float64" Name="Radius" format="appended" offset="'//itoa(offset(3))//'" >'//NEW_LINE('A')
WRITE(vtu)'</DataArray>'//NEW_LINE('A')
WRITE(vtu)'</PointData>'//NEW_LINE('A')
WRITE(vtu)'<Cells>'//NEW_LINE('A')
WRITE(vtu)'<DataArray type="Int32" Name="connectivity" format="appended" offset="'//itoa(offset(4))//'">'//NEW_LINE('A')
WRITE(vtu)'</DataArray>'//NEW_LINE('A')
WRITE(vtu)'<DataArray type="Int32" Name="offsets" format="appended" offset="'//itoa(offset(5))//'">'//NEW_LINE('A')
WRITE(vtu)'</DataArray>'//NEW_LINE('A')
WRITE(vtu)'<DataArray type="UInt8" Name="types" format="appended" offset="'//itoa(offset(6))//'">'//NEW_LINE('A')
WRITE(vtu)'</DataArray>'//NEW_LINE('A')
WRITE(vtu)'</Cells>'//NEW_LINE('A')
WRITE(vtu)'</Piece>'//NEW_LINE('A')
WRITE(vtu)'</UnstructuredGrid>'//NEW_LINE('A')
WRITE(vtu)'<AppendedData encoding="raw">'//NEW_LINE('A')
WRITE(vtu)char(95),offset(1),position
WRITE(vtu)offset(2),velocity
WRITE(vtu)offset(3),radius
WRITE(vtu)offset(4),offset(5),offset(6)
WRITE(vtu)NEW_LINE('A')//'</AppendedData>'//NEW_LINE('A')
WRITE(vtu)'</VTKFile>'
CLOSE(unit=vtu)
print_number = print_number + 1
END SUBROUTINE print_vtu_binary_appended
END MODULE OUTPUT
program test
use iso_fortran_env
use output
implicit none
integer(kind=int32) :: step=1, number_of_particles=2
real(kind=real64), dimension(2,3) :: position, velocity
real(kind=real64), dimension(2) :: radius
character(len=14) :: system_name='random_numbers'
position = reshape((/ 1.0754_real64, 2.0683_real64, 3.2479_real64, 4.08642_real64, 5.46906_real64, 6.36974_real64 /), shape(position))
velocity = reshape((/ 3.0754_real64, 7.0683_real64, 10.2479_real64, 72.08642_real64, 83.46906_real64, 22.36974_real64 /), shape(velocity))
radius = reshape((/ 0.0000754_real64, 0.00083_real64 /), shape(radius))
CALL print_vtu_binary_appended(step,number_of_particles,system_name,position,velocity,radius)
end program test

生成的xml文件的例子。

<?xml version="1.0"?>
<VTKFile type="UnstructuredGrid" version="0.1" byte_order="LittleEndian">
<UnstructuredGrid>
<Piece NumberOfPoints="8" NumberOfCells="0">
<Points>
<DataArray name="Position" type="Float64" NumberOfComponents="3" format="appended" offset="0">
</DataArray>
</Points>
<PointData>
<DataArray type="Float64" Name="Velocity" NumberOfComponents="3" format="appended" offset="196">
</DataArray>
<DataArray type="Float64" Name="Radius" format="appended" offset="392" >
</DataArray>
</PointData>
<Cells>
<DataArray type="Int32" Name="connectivity" format="appended" offset="460">
</DataArray>
<DataArray type="Int32" Name="offsets" format="appended" offset="464">
</DataArray>
<DataArray type="UInt8" Name="types" format="appended" offset="468">
</DataArray>
</Cells>
</Piece>
</UnstructuredGrid>
<AppendedData encoding="raw">
...
</AppendedData>
</VTKFile>

Paraview中的错误:

ERROR: 在C:\bbd\ecd3383f\build/superbuild/paraview/src/VTK/\IOXML/vtkXMLUnstructuredDataReader.cxx,第466行vtkXMLUnstructuredGridReader(000001DDC1DD5090)。Cannot read points array from Points in piece 0. The data array in the element may be too short.

binary fortran vtk paraview
1个回答
0
投票

我想问题可能是由末端记录引起的,我建议使用 "char(10) "代替固有的 "new_line"。

在我的库中(https:/github.comszaghiVTKFortran。)我用的是

character(1), parameter :: end_rec = char(10) !< End-character for binary-record finalize.

编辑

对不起,我猜错了,我认为 "char(10) "更安全,因为用 "new_line "可以选择种类,所以我认为终止的字节数不同,我的错。

在阅读你的代码时,你使用 "offset "来跟踪附加数据的偏移量和附加部分中每个数据数组的字节数。我认为这是不安全的:如果你把你的偏移量定义从int64改成int32,你的测试在我目前的架构中就可以工作(GNU Fortran 9.3.0, Linux 4.19.0-6-amd64, paraview 5.8.0)。

还请注意,你的itao函数没有为传递的参数 "i "定义种类,但你同时传递了int64和int32。

我建议把偏移量和字节数的定义分开,但是对于小文件来说,把偏移量定义为int32对我来说是可行的。

© www.soinside.com 2019 - 2024. All rights reserved.