I have builded a program for CFD results interpolation by vtk interpolation functions.
It run successfully in jupyter, but while I write a Pyqt6 GUI and packaged by pyinstaller it show the error like below.
I don‘t now if similar problems have occurred before.
please share your data
here is my vtk interpolation class
import vtkmodules.all as vtk
import numpy as np
import pandas as pd
import csv
from pandas.core.frame import DataFrame
class sindainterp:
def init(self,sourcefilename,sindafilename):
self.sourcefie = sourcefilename[0]
self.Time = sourcefilename[1]
self.Type = sourcefilename[2]
self.sindafie = sindafilename
self.CaseNum = len(self.Time)
if (len(self.Time) == len(self.Type))and (len(self.Type) == len(self.sourcefie)):
print(‘Import Finished!’)
else:
print(‘Please Check Imported Data!’)
def read_SourceGrid(self,filename):
reader = vtk.vtkXMLMultiBlockDataReader()
reader.SetFileName(filename)
reader.Update()
# 获取第一个块(只输出单一壁面时只有一个块)
block = reader.GetOutput()
grid = block.GetBlock(0)
c2p = vtk.vtkCellDataToPointData()
c2p.SetInputData(grid)
c2p.Update()
sourcegrid = c2p.GetOutput()
return sourcegrid
def readGrid_fluent(self,fluentfile):
pointsdf = pd.read_csv(fluentfile)
points = pointsdf.iloc[:,1:4].values
temp = pointsdf.iloc[:,4].values
vtk_points = vtk.vtkPoints()
for p in points:
# print(p)
vtk_points.InsertNextPoint(p)
grid = vtk.vtkUnstructuredGrid()
grid.SetPoints(vtk_points)
scalars = vtk.vtkFloatArray()
scalars.SetName("TEMPERATURE")
for i in range(temp.shape[0]):
scalars.InsertNextValue(temp[i])
grid.GetPointData().SetScalars(scalars)
multiblock = vtk.vtkMultiBlockDataSet()
multiblock.SetBlock(0, grid)
sourcegrid = multiblock.GetBlock(0)
return sourcegrid
def read_SindaGrid(self,filename):
Points = []
Elements = []
with open(filename, 'r') as f:
reader = csv.reader(f)
for row in reader:
if row[0] == 'GRID':
Points.append(row)
elif row[0] == 'CTRIA3':
Elements.append(row)
Points = DataFrame(Points,columns=['Type','Node id','Tab', 'x', 'y', 'z']) #.iloc[:,1:].values()
Elements = DataFrame(Elements,columns=['Type','Element id','Tab', 'N1', 'N2', 'N3']) ##.iloc[:,1:].values()
Points['Node id'] = Points['Node id'].astype(int)
Points = Points.sort_values(by = ['Node id'], axis=0, ascending=True, inplace=False)
self.SindaPoints = Points.loc[:,['x','y','z']].astype(float).values
self.SindaElements = Elements.loc[:,['N1','N2','N3']].astype(int).values
vtk_points = vtk.vtkPoints()
for p in self.SindaPoints:
# print(p)
vtk_points.InsertNextPoint(np.array(p))
Sindagrid = vtk.vtkPolyData()
Sindagrid.SetPoints(vtk_points)
# print(Sindagrid)
return Sindagrid
def interpolation(self,kernel):
'''
插值核函数:vtk.vtkShepardKernel()
'''
interpolator = vtk.vtkPointInterpolator()
interpolator.SetInputData(self.sindagrid)
interpolator.SetSourceData(self.sourcegrid)
interpolator.SetKernel(kernel)
interpolator.Update()
self.sindagrid = interpolator.GetOutput()
self.sindagridpoints = self.sindagrid.GetPoints()
self.sindagridpoints_data = self.sindagrid.GetPointData()
# print(self.sindagridpoints)
def Gensindainpfile(self,outputname):
self.outputname = outputname
self.sindagrid = self.read_SindaGrid(self.sindafie)
with open(outputname, 'w', newline='') as f:
f.write('DATA: TEMPERATURE\n')
f.write('UNITS LENGTH meters\n')
f.write('UNITS TIME SECONDS\n')
f.write('UNITS TEMPERATURE K\n')
writer = csv.writer(f,delimiter='\t')
## write Nodes
for i in range(self.SindaPoints.shape[0]):
point = self.SindaPoints[i,:]
f.write('Node\t'+str(i+1)+'\t')
f.write(str(point[0]) + '\t'+str(point[1]) + '\t'+str(point[2]) + '\n')
for i in range(self.SindaElements.shape[0]):
simp = self.SindaElements[i]
simp.sort()
f.write('TRI\t'+str(i+1)+'\t')
f.write(str(simp[0]) + '\t'+str(simp[1]) + '\t'+str(simp[2]) + '\n')
for k in range(len(self.Time)):
if self.Type[k] == 'VTM':
print('case:',k,'VTM')
self.sindagrid = self.read_SindaGrid(self.sindafie)
self.sourcegrid = self.read_SourceGrid(self.sourcefie[k])
# print(self.sourcegrid)
elif self.Type[k] == 'FLUENT':
self.sindagrid = self.read_SindaGrid(self.sindafie)
self.sourcegrid = self.readGrid_fluent(self.sourcefie[k])
print('case:',k,'FLUENT')
# print(self.sourcegrid)
self.interpolation(vtk.vtkShepardKernel())
points = self.sindagridpoints
points_data = self.sindagridpoints_data
print(points_data.GetNumberOfArrays())
f.write('TIME'+' '+str(self.Time[k])+'\n')
for i in range(points.GetNumberOfPoints()):
# if self.Type[k] == 'FLUENT':
# print('i:',i)
for j in range(points_data.GetNumberOfArrays()):
# if self.Type[k] == 'FLUENT':
# print('j:',j)
array = points_data.GetArray(j)
value = array.GetComponent(i, 0) # 假设每个点数据只有一个分量
message = tuple([value]) +tuple(['! Temperature Value Node '])+ tuple([i+1])
writer.writerow(message)
print('Export file ',outputname, ' successfully')
here is the QT GUI code
from PyQt6.QtWidgets import QApplication, QMainWindow, QTableWidgetItem, QMessageBox
from sindainterpolation import Ui_MainWindow # 导入由pyuic6生成的Python文件
import VTK2SINDA
import tkinter as tk
from tkinter import filedialog
from pathlib import Path
import pandas as pd
class MainWindow(QMainWindow, Ui_MainWindow):
def init(self):
super().init()
self.setupUi(self)
self.getPathButtom.clicked.connect(self.getEngineerPath)
self.TableAdd.clicked.connect(self.TableAddRow)
self.TableDelete.clicked.connect(self.TableDelRow)
self.ImportEnvelopeButtom.clicked.connect(self.readEnvelopeTable)
self.InterpButtom.clicked.connect(self.interpolation)
self.EnvelopeTable.setSortingEnabled(True)
self.msg_box = QMessageBox()
def getEngineerPath(self): # 浏览按钮被点击
# 创建一个Tk根窗口,但不显示
root = tk.Tk()
root.withdraw()
# 打开文件选择对话框,并获取用户选择的文件路径
file_path = filedialog.askopenfilename(
title="选择网格文件",
initialdir="/", # 起始目录
filetypes=[("nastran mesh files", "*.bdf")] # 文件类型过滤
)
# 返回选择的文件路径
directory,filename = self.get_file_path_and_split(file_path)
self.MeshFileName.setText(filename)
self.DirPath.setText(directory)
def get_file_path_and_split(self,file_path):
# 创建Path对象
path = Path(file_path)
# 拆分文件名和路径
directory = path.parent # 获取目录路径
filename = path.name # 获取文件名
return str(directory), filename
def TableAddRow(self):
self.EnvelopeTable.insertRow(self.EnvelopeTable.rowCount())
def TableDelRow(self):
# 获取选中的行号
selected_index = self.EnvelopeTable.selectionModel().selectedRows()
model = self.EnvelopeTable.model()
for index in selected_index:
model.removeRow(index.row())
def readEnvelopeTable(self):
root = tk.Tk()
root.withdraw()
if self.DirPath.toPlainText() is None:
dir = '/'
else:
dir = self.DirPath.toPlainText()
# 打开文件选择对话框,并获取用户选择的文件路径
file_path = filedialog.askopenfilename(
title="选择包线csv",
initialdir= dir, # 起始目录
filetypes=[("包线配置文件", "*.csv")] # 文件类型过滤
)
if file_path == '':
self.msg_box.setWindowTitle("Message")
self.msg_box.setText("未选择合适文件")
return self.msg_box.exec()
data = pd.read_csv(file_path)
self.sourcefile = [data.iloc[:, 0].tolist(), data.iloc[:, 1].tolist(), data.iloc[:, 2].tolist()]
self.EnvelopeTable.clear()
self.EnvelopeTable.setRowCount(data.shape[0])
self.EnvelopeTable.setColumnCount(data.shape[1])
for j in range(data.shape[1]):
for i,cell in enumerate(self.sourcefile[j]):
item = QTableWidgetItem(str(cell))
self.EnvelopeTable.setItem(i, j, item)
def interpolation(self):
self.sindafile = self.DirPath.toPlainText() + '\\' + self.MeshFileName.toPlainText()
self.outputname = self.DirPath.toPlainText() + '\\' + self.OutputFileName.toPlainText()
interpolator = VTK2SINDA.sindainterp(self.sourcefile, self.sindafile)
interpolator.Gensindainpfile(self.outputname)
self.msg_box.setWindowTitle("Message")
self.msg_box.setText("导出成功")
self.msg_box.exec()
if name == “main”:
app = QApplication()
window = MainWindow()
window.show()
app.exec()