【发布时间】:2020-08-14 19:14:02
【问题描述】:
我有一个四字节整数,我想将其转换为无符号 32 位整数并作为原始二进制数据(小端序)写入。根据此模式https://www.paraview.org/pipermail/paraview/2007-October/006064.html,此值将用作要在 paraview 中读取的 .vtu 文件中的偏移量 我已经尝试过 ZEXT 和 IAND 函数,但我没有成功,可能是因为我对 C 语言和 c-fortran 接口的了解非常基础。 下面是我正在尝试做的草稿
use ISO_C_BINDING
...
INTEGER(kind=4), dimension(8):: offset=0
...
OPEN(newunit=vtu, action='write', access='stream', STATUS='new', form='unformatted', FILE=filename)
....
WRITE(vtu)char(95),ZEXT(offset(1),C_INT32_T),...
WRITE(vtu)ZEXT(offset(2),C_INT32_T),...
...
--编辑 (01/05/2020)
SUBROUTINE print_vtu_binary_appended
USE DECLARE
use iso_fortran_env
IMPLICIT NONE
INTEGER(kind=int32) :: i, vtu, print_number=0
INTEGER(kind=int32), dimension(6) :: offset
character (len=24) :: folder
IF (step==0) then
call new_folder(folder)
END IF
offset(1) = 0
offset(2) = offset(1) + 4 + SIZEOF(preceding_position)
offset(3) = offset(2) + 4 + SIZEOF(preceding_velocity)
offset(4) = offset(3) + 4 + SIZEOF(radius)
offset(5) = offset(4) + 4
offset(6) = offset(5) + 4
!or
!offset(1) = 0
!offset(2) = offset(1) + 4 + 8*number_of_particles*3 !(double precision*no_particles*no_components)
!offset(3) = offset(2) + 4 + 8*number_of_particles*3
!offset(4) = offset(3) + 4 + 8*number_of_particles
!offset(5) = offset(4) + 4
!offset(6) = offset(5) + 4
OPEN(newunit=vtu, action='write', access='stream', STATUS='new', form='unformatted', FILE='./'//folder//'/'//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),preceding_position
WRITE(vtu)offset(2),preceding_velocity
WRITE(vtu)offset(3),radius
WRITE(vtu)offset(4),offset(5),offset(6)
!a different way to write
!WRITE(vtu)char(95),offset(1),(preceding_position,i=1,number_of_particles)
!WRITE(vtu)offset(2),(preceding_velocity,i=1,number_of_particles)
!WRITE(vtu)offset(3),(radius,i=1,number_of_particles)
!WRITE(vtu)offset(4),offset(5),offset(6)
!another different way
!WRITE(vtu)char(95),offset(1),(preceding_position(i,1),preceding_position(i,2),preceding_position(i,3),i=1,number_of_particles)
!WRITE(vtu)offset(2),(preceding_velocity(i,1),preceding_velocity(i,2),preceding_velocity(i,3),i=1,number_of_particles)
!WRITE(vtu)offset(3),(radius,i=1,number_of_particles)
!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
感谢弗拉基米尔 F 的回答。但是,我仍然收到此错误消息:
错误:在 C:\bbd\ecd3383f\build\superbuild\paraview\src\VTK\IO\XML\vtkXMLUnstructuredDataReader.cxx 中,第 466 行 vtkXMLUnstructuredGridReader (00000244BF849310): 无法从第 0 片的点中读取点数组。元素中的数据数组可能太短。
我认为问题出在我编写偏移量的方式上(换句话说,Paraview 没有识别有符号整数)。我测试了三种编写方法和两种计算偏移量的方法(如您在代码中所见)。我不知道出了什么问题。我做了一个类似的子程序来打印一个 .vtu ASCII 文件,一个 .vtk 二进制文件,我都成功了。
【问题讨论】:
-
欢迎,不要使用javascript快照按钮来格式化你的代码,使用代码按钮。
-
Fortran 对无符号整数一无所知,即使考虑到 C 互操作性,那么您将如何将四字节整数转换为 32 位无符号整数?
-
您确实需要查看您创建的文件以明确找出其中的问题所在。这将使您处于一个更好的位置来调整程序以编写将被接受的输出。
-
我查看了该文件并将其与 paraview 从 正确 .vtu ascii 文件生成的二进制文件进行了比较。但是,我仍然无法识别错误。
-
请不要分享有关外部资源的任何重要信息。 1. 没有人知道会有什么样的病毒。 2.它不会一直呆在那里,问题将不再有意义。