Parallel processing 从多个MPI输出合成VTK文件

Parallel processing 从多个MPI输出合成VTK文件,parallel-processing,mpi,vtk,scientific-computing,paraview,Parallel Processing,Mpi,Vtk,Scientific Computing,Paraview,对于盖驱动空腔(CFD)的格子Boltzmann模拟,我将立方域分解为(也是立方的)8个子域,它们由8个秩独立计算。每个MPI列组为每个时间步生成一个VTK文件,因为我使用的是ParaView,所以我希望将整个过程可视化为一个立方体。更具体地说,我正在努力实现的目标是: 我有一个长度为8的立方体(每个方向的元素数)=>8x8x8=512个元素 每个维度分布到2个列组,即每个列组处理4x4x4=64个元素 每个列组将其结果以VTKStructuredGrid格式写入名为lbm\u out..vt

对于盖驱动空腔(CFD)的格子Boltzmann模拟,我将立方域分解为(也是立方的)8个子域,它们由8个秩独立计算。每个MPI列组为每个时间步生成一个VTK文件,因为我使用的是ParaView,所以我希望将整个过程可视化为一个立方体。更具体地说,我正在努力实现的目标是:

  • 我有一个长度为8的立方体(每个方向的元素数)=>8x8x8=512个元素
  • 每个维度分布到2个列组,即每个列组处理4x4x4=64个元素
  • 每个列组将其结果以VTK
    StructuredGrid
    格式写入名为
    lbm\u out..vts
    的文件
  • 我想生成一个
    .pvts
    文件,该文件收集
    *.vts
    文件,并将包含子域的文件合并到一个文件中,ParaView可以将其视为整个域
不幸的是,我面临着很多问题,因为我觉得ParaView和VTK的文档记录非常糟糕,来自ParaView的错误消息完全没有用处

我有以下
*.pvts
文件,其中包括一个重影层和:

<?xml version="1.0"?>
<VTKFile type="PStructuredGrid" version="0.1" byte_order="LittleEndian">
    <PStructuredGrid WholeExtent="0 7 0 7 0 7 " GhostLevel="1">
        <PPoints>
            <PDataArray NumberOfComponents="3" type="Float32" />
        </PPoints>
        <Piece Extent="0 4 0 4 0 4" Source="lbm_out_0.0.vts"/>
        <Piece Extent="3 7 0 4 0 4" Source="lbm_out_1.0.vts"/>
        <Piece Extent="0 4 3 7 0 4" Source="lbm_out_2.0.vts"/>
        <Piece Extent="3 7 3 7 0 4" Source="lbm_out_3.0.vts"/>
        <Piece Extent="0 4 0 4 3 7" Source="lbm_out_4.0.vts"/>
        <Piece Extent="3 7 0 4 3 7" Source="lbm_out_5.0.vts"/>
        <Piece Extent="0 4 3 7 3 7" Source="lbm_out_6.0.vts"/>
        <Piece Extent="3 7 3 7 3 7" Source="lbm_out_7.0.vts"/>
    </PStructuredGrid>
</VTKFile>

有了这个文件,我觉得应该可以正常工作(注意,还没有参数,只有简单的几何信息),我的域范围完全混乱了,尽管每个
*。vts
文件都可以自己正常工作。我附上了一张截图,让事情变得更清楚:


有什么问题吗?是否可以将旧版VTK文件用于此任务?我可能做错了什么吗?我真的不知道如何完成这项任务,而且我在谷歌找到的资源非常有限。谢谢。

不幸的是,类()没有示例。因此,我决定编写最简单的代码来为结构化网格生成*.vts和.pvts文件,这与您正在寻找的情况非常相似

下面的代码使用MPI和VTK编写并行结构化网格文件。在本例中,我们有两个进程创建它们自己的.vts文件,vtkXMLPStructuredGridWriter类写入.pvts文件:

//MPI库
#包括
//VTK库
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
结构参数{
vtkProgrammableFilter*pf;
int局部_范围[6];
};
//函数对点属性数据进行操作
作废执行(作废*参数){
Args*Args=重新解释铸件(arg);
自动信息=args->pf->GetOutputInformation(0);
自动输出\u tmp=args->pf->GetOutput();
自动输入\u tmp=args->pf->GetInput();
vtkStructuredGrid*输出=动态强制转换(输出tmp);
vtkStructuredGrid*输入=动态转换(输入tmp);
输出->浅拷贝(输入);
输出->设置范围(参数->本地范围);
}
int main(int argc,char*argv[]){
MPI_Init(&argc,&argv);
int-myrank;
MPI_Comm_rank(MPI_Comm_WORLD和myrank);
int lx{10},ly{10},lz{10};//进程网格的局部维数
int dims[3]={lx+1,ly+1,lz+1};
int-global_-extent[6]={0,2*lx,0,ly,0,lz};
int local_extent[6]={myrank*lx,(myrank+1)*lx,0,ly,0,lz};
//创建并初始化vtkMPIController
自动控制=vtkSmartPointer::New();
控制->初始化(&argc,&argv,1);
int nranks=contr->getNumberOfProcess();
int rank=contr->GetLocalProcessId();
//创建网格点,分配内存并插入它们
自动点=vtkSmartPointer::New();
点->分配(dims[0]*dims[1]*dims[2]);
对于(int k=0;kSetNumberOfTuples((dims[0]-1)*(dims[1]-1)*(dims[2]-1));
密度->设置名称(“密度”);
整数指数;
for(int k=0;kSetInputData(structuredGrid);
structuredGrid->设定点(点);
structuredGrid->GetCellData()->AddArray(密度);
//创建并行编写器并调用一些函数
自动并行_writer=vtkSmartPointer::New();
parallel_writer->SetInputConnection(pf->GetOutputPort());
并行写入器->设置控制器(控制);
parallel_writer->SetFileName(“test.pvts”);
并行写入器->设置条数(nranks);
并行写入器->设置开始(秩);
并行写入器->设置尾端(秩);
parallel_writer->SetDataModeToBinary();
并行写入程序->更新();
并行写入器->写入();
控制->最终确定();
//警告:似乎MPI_Finalize不是必需的,因为我们正在使用
//vtkMPIController类中的Finalize()函数
//排队看看会发生什么。
//MPI_Finalize();
返回0;
}
这段代码只将一些数据(在本例中,密度是标量)写入到文件中,而不进行渲染。要实现可视化,您需要一个类似Paraview的软件。 要运行此代码,可以使用以下CMake文件:

cmake_minimum_required(VERSION 2.8)

PROJECT(PXMLStructuredGridWriter)
add_executable(PXMLStructuredGridWriter parallel_vtk.cpp)

find_package(VTK REQUIRED)
include(${VTK_USE_FILE})
target_link_libraries(PXMLStructuredGridWriter ${VTK_LIBRARIES})

find_package(MPI REQUIRED)
include_directories(${MPI_INCLUDE_PATH})
target_link_libraries(PXMLStructuredGridWriter ${MPI_LIBRARIES})
最后,您将在可执行文件所在的同一目录中找到如下xml文件:


确保每个*.vts文件中StructuredGrid上的“WholeExtent”属性和Piece元素上的“Extent”属性与您为.pvts文件中的每个片段指定的范围相匹配。