在 Paraview 中可视化 3D numpy 向量场

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

我编写了一些代码来计算各种电荷、电流和几何配置的电场和磁场矢量场。使用 numpy savetxt 方法将输出保存为 csv 格式:

    fieldMap = np.stack((X.ravel(), Y.ravel(), Z.ravel(), Bx.ravel(), By.ravel(), Bz.ravel(), Ex.ravel(), Ey.ravel(), Ez.ravel()))   
    heading = f" x y z Bx By Bz Ex Ey Ez \n"
    np.savetxt(path , fieldMap,  header = heading , comments="" ) 

达到预期的输出

x y z Bx By Bz Ex Ey Ez 
3.840000000000000357e-02 3.840000000000000357e-02 7.439999999999999392e-02 3.731101704388582415e-04 3.731101704388588378e-04 -1.787606656866691209e-04 -0.000000000000000000e+00 -0.000000000000000000e+00 -0.000000000000000000e+00
3.840000000000000357e-02 3.840000000000000357e-02 5.924444444444443986e-02 2.135196586408618616e-04 2.135196586408621869e-04 -4.585864781494742551e-04 -0.000000000000000000e+00 -0.000000000000000000e+00 -4.034679354447678890e-01
3.840000000000000357e-02 3.840000000000000357e-02 4.408888888888888580e-02 -1.031604762420866280e-04 -1.031604762420863569e-04 -4.494106267203430705e-04 -0.000000000000000000e+00 -0.000000000000000000e+00 -1.180245238916466377e+00
3.840000000000000357e-02 3.840000000000000357e-02 2.893333333333333174e-02 -2.527944858538051917e-04 -2.527944858538058964e-04 -1.402243480967241794e-04 -0.000000000000000000e+00 -0.000000000000000000e+00 -1.861414658185234217e+00
3.840000000000000357e-02 3.840000000000000357e-02 1.377777777777777768e-02 -1.654374219591531604e-04 -1.654374219591537025e-04 1.197934198869413612e-04 -0.000000000000000000e+00 -0.000000000000000000e+00 -2.366509916060799412e+00

Geant4 粒子传输模型的输入需要此格式,并且它按预期工作。它也按照 matplotlib 中的预期进行绘制。但试图将数据导入 Paraview 以获得更好的可视化效果却非常困难。我首先尝试直接导入 csv 文件,但出现以下错误:

ERROR: In ./VTK/Common/DataModel/vtkTable.cxx, line 355
vtkTable (0x6309affe5ef0): Column "" must have 1000 rows, but has 0.

如果我继续并尝试运行过滤器,程序就会崩溃。似乎正在将一些具有零行的不可见列插入到数据中。这是 paraview 中 csv 表的屏幕截图。

失败后,我尝试使用以下方法转换为 vtk 文件格式:pyevtk、vtk.util.numpy_support 模块、转换为 vtkImagedata、numpy 点数组转换为 vtkPolydata 和 PyVista。在每种情况下,我都会在 Paraview 中收到以下导入错误。

ERROR: In ./VTK/IO/XMLParser/vtkXMLParser.cxx, line 375
vtkXMLDataParser (0x65093f5e52a0): Error parsing XML in stream at line 19, column 36, byte index 1576: not well-formed (invalid token)

ERROR: In ./VTK/IO/XML/vtkXMLReader.cxx, line 521
vtkXMLImageDataReader (0x65094191b3a0): Error parsing input file.  ReadXMLInformation aborting.

有问题的行(在本例中为 19)始终是二进制块的第二行,位于 XML 中的标记之后。我最终运行了 pyevtk 源代码清单中的示例之一,并得到了相同的错误,因此它不是特定于我的代码。

我的第一个问题,有没有比 Paraview 更不敌意的东西我可以使用?我只需要运行一些可视化。我很惊讶像查看矢量场这样基本的事情竟然如此困难。我断断续续地工作了一个多月,但现在这是完成我的项目的最后一个障碍。 1980 年,我开始在打孔卡上使用 FORTRAN 进行编码,这是我编程过程中最艰难的一站。任何帮助将不胜感激。

我已经列出了我尝试过的所有内容。至于期望,我预计在两个如此广泛使用的软件平台之间移动数据将相对简单。至于版本,我尝试过paraview 5.10.0-RC1和5.12.0,Python 3.10和3.11.4,numpy 1.21.5和1.26.4。我没有包含我尝试过的所有代码,因为结果非常一致。任何转换为 vtk 格式的尝试都会导致 xml 解析错误,并且每次我尝试过滤表数据时导入为 csv 都会导致程序崩溃。

numpy paraview
1个回答
0
投票

几天前我遇到了类似的挑战。我发现的最佳解决方案是将矢量数据保存为 tecplot 文件,并将其导入 Paraview。

这是完整的代码,包括示例中给出的数据:

original_data = '''
x y z Bx By Bz Ex Ey Ez 
3.840000000000000357e-02 3.840000000000000357e-02 7.439999999999999392e-02 3.731101704388582415e-04 3.731101704388588378e-04 -1.787606656866691209e-04 -0.000000000000000000e+00 -0.000000000000000000e+00 -0.000000000000000000e+00
3.840000000000000357e-02 3.840000000000000357e-02 5.924444444444443986e-02 2.135196586408618616e-04 2.135196586408621869e-04 -4.585864781494742551e-04 -0.000000000000000000e+00 -0.000000000000000000e+00 -4.034679354447678890e-01
3.840000000000000357e-02 3.840000000000000357e-02 4.408888888888888580e-02 -1.031604762420866280e-04 -1.031604762420863569e-04 -4.494106267203430705e-04 -0.000000000000000000e+00 -0.000000000000000000e+00 -1.180245238916466377e+00
3.840000000000000357e-02 3.840000000000000357e-02 2.893333333333333174e-02 -2.527944858538051917e-04 -2.527944858538058964e-04 -1.402243480967241794e-04 -0.000000000000000000e+00 -0.000000000000000000e+00 -1.861414658185234217e+00
3.840000000000000357e-02 3.840000000000000357e-02 1.377777777777777768e-02 -1.654374219591531604e-04 -1.654374219591537025e-04 1.197934198869413612e-04 -0.000000000000000000e+00 -0.000000000000000000e+00 -2.366509916060799412e+00
'''

original_data  =  [x for x in original_data.split('\n') if x]
header         =  [(x.upper() if x in list('xyz') else x) for x in original_data[0].split()]
header         =  original_data[0].split()
rows           =  [row.split() for row in original_data[1:]]

filename       =  'vector_field_electrical.tec'

with open(filename,'w') as f:
    f.write('VARIABLES = "' + '", "'.join(header) + '"' + '\n')
    f.write(f"ZONE I={len(rows)}, DATAPACKING=BLOCK"    + '\n')
    for j in range(len(rows[0])):
        f.write(" ".join([str(row[j]) for row in rows]) + '\n')

Paraview 立即识别 tecplot 文件,并且轻松导入数据:

enter image description here

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