gpt4 book ai didi

c++ - VTK 和 MPI : plot distributed data

转载 作者:行者123 更新时间:2023-11-28 04:51:29 24 4
gpt4 key购买 nike

经过一些研究,我无法弄清楚将 VTK 与 MPI 结合使用以可视化分布式数据的最佳方式是什么。

我要绘制的数据是立方体中的一组移动点(如果这有帮助,我们知道边界)。这组点会在每次迭代时更新,而且可能会很大。目前我们真的不知道我们的实现将如何扩展,但目标是能够处理尽可能多的点。

以下是我在研究中发现的并行绘图的 2 种方法:

  1. 使用 vtkMultiProcessController .这种方法似乎相当复杂,我找到的唯一“文档”是类文档和 an example .这可能足以使用这个类(class),但我认为这会占用我太多时间。

  2. 使用 VTK 并行格式,如 link .这个选项似乎更容易使用,并不是真正的干扰,而且可能(?)比前一个更快。

我的问题是:

  • 是否有任何其他方法可用于有效地绘制分布式点集?
  • 哪种方法最适合绘制我的数据集?
  • (附带问题)VTK(用于创建文件)和 Paraview(用于查看动画)支持绘制此类动画的最佳格式是什么?

非常感谢您的宝贵时间!

最佳答案

我认为第一种方法更可靠,因为我花了很多时间使用第二种方法,但无法从中得到正确的结果。正如您所说,VTK 类没有很好的文档,尤其是像 vtkXMLPStructuredGridWriter 这样的并行类。

对了,我建议你使用第一种方法。但是,而不是使用 vtkMultiProcessController , 使用 vtkMPIController它派生自 vtkMultiProcessController 类。最近,我为 Structured Grid 写了一个示例,通过做一些更改,您可以将它用于您自己的应用程序:

// MPI Library
#include <mpi.h>

//VTK Library
#include <vtkXMLPStructuredGridWriter.h>
#include <vtkStructuredGrid.h>
#include <vtkSmartPointer.h>
#include <vtkFloatArray.h>
#include <vtkCellData.h>
#include <vtkMPIController.h>
#include <vtkProgrammableFilter.h>
#include <vtkInformation.h>

struct Args {
vtkProgrammableFilter* pf;
int local_extent[6];
};

// function to operate on the point attribute data
void execute (void* arg) {
Args* args = reinterpret_cast<Args*>(arg);
auto info = args->pf->GetOutputInformation(0);
auto output_tmp = args->pf->GetOutput(); // this is a vtkDataObject*
auto input_tmp = args->pf->GetInput(); // this is a vtkDataObject*
vtkStructuredGrid* output = dynamic_cast<vtkStructuredGrid*>(output_tmp);
vtkStructuredGrid* input = dynamic_cast<vtkStructuredGrid*>(input_tmp);
output->ShallowCopy(input);
output->SetExtent(args->local_extent);
}

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}; //local dimensions of the process's grid
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};

// Create and Initialize vtkMPIController
auto contr = vtkSmartPointer<vtkMPIController>::New();
contr->Initialize(&argc, &argv, 1);
int nranks = contr->GetNumberOfProcesses();
int rank = contr->GetLocalProcessId();

// Create grid points, allocate memory and Insert them
auto points = vtkSmartPointer<vtkPoints>::New();
points->Allocate(dims[0]*dims[1]*dims[2]);
for (int k=0; k<dims[2]; ++k)
for (int j=0; j<dims[1]; ++j)
for (int i=0; i<dims[0]; ++i)
points->InsertPoint(i + j*dims[0] + k*dims[0]*dims[1],
i+rank*(dims[0]-1), j, k);

// Create a density field. Note that the number of cells is always less than
// number of grid points by an amount of one so we use dims[i]-1
auto density = vtkSmartPointer<vtkFloatArray>::New();
density->SetNumberOfComponents(1);
density->SetNumberOfTuples((dims[0]-1)*(dims[1]-1)*(dims[2]-1));
density->SetName ("density");
int index;
for (int k=0; k<lz; ++k)
for (int j=0; j<ly; ++j)
for (int i=0; i<lx; ++i) {
index = i + j*(dims[0]-1) + k*(dims[0]-1)*(dims[1]-1);
density->SetValue(index, i+j+k);
}

// Create a vtkProgrammableFilter
auto pf = vtkSmartPointer<vtkProgrammableFilter>::New();

// Initialize an instance of Args
Args args;
args.pf = pf;
for(int i=0; i<6; ++i) args.local_extent[i] = local_extent[i];

pf->SetExecuteMethod(execute, &args);

// Create a structured grid and assign point data and cell data to it
auto structuredGrid = vtkSmartPointer<vtkStructuredGrid>::New();
structuredGrid->SetExtent(global_extent);
pf->SetInputData(structuredGrid);
structuredGrid->SetPoints(points);
structuredGrid->GetCellData()->AddArray(density);

// Create the parallel writer and call some functions
auto parallel_writer = vtkSmartPointer<vtkXMLPStructuredGridWriter>::New();
parallel_writer->SetInputConnection(pf->GetOutputPort());
parallel_writer->SetController(contr);
parallel_writer->SetFileName("data/test.pvts");
parallel_writer->SetNumberOfPieces(nranks);
parallel_writer->SetStartPiece(rank);
parallel_writer->SetEndPiece(rank);
parallel_writer->SetDataModeToBinary();
parallel_writer->Update();
parallel_writer->Write();

contr->Finalize();

// WARNING: it seems that MPI_Finalize is not necessary since we are using
// Finalize() function from vtkMPIController class. Uncomment the following
// line and see what happens.
// MPI_Finalize ();
return 0;
}

关于你的最后一个问题,如果你使用 VTK 库,你可以选择 Ascii 和二进制格式。二进制格式通常在大小方面更小。您可以通过调用 SetDataModeToBinary() 函数轻松设置此二进制格式。我在上面的代码中使用了这个函数。

另请阅读此 question这与您正在寻找的内容相关。

关于c++ - VTK 和 MPI : plot distributed data,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48130423/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com