首页/文章/ 详情

pyANSYS|包含GUI的示例

1年前浏览3020

pyansys的目标是让用户可以使用python操控ANSYS的各种产品。除了使用代码进行计算流程控制外,工程中常希望能够搞个GUI界面,这样用起来更方便。既然pyansys使用的是python语言,那么界面开发自然首选PyQt。

下面是一个简单的例子,开发一个计算矩形板的热传导的程序,其中需要输入板的长宽高、温度载荷数据,输出板上的温度分布。

1 界面

利用Qt Designer可以快速地构建界面。

界面没什么好讲的,主要是一些参数输入。这里添加了一个QtIteractor用于在软件中显示vtk。但效果并不好,之前想着是可以将pyMAPDL中的几何、网格及结果显示嵌入到QtInteractor中,但折腾了半天也没搞定,后来采用迂回策略,利用pyMAPDL将几何、网格及结果保存为vtk文件,然后读入vtk文件到QtInteractor中,虽然目标是实现了,但总觉得这种方式不优雅。

2 程序代码

程序代码很简单,将pyMAPDL代码稍微改造一下就行了。主程序文件launch.py如下:

import sys

from testvistaUI import Ui_Form
from PyQt5.Qt import *
import pyvista as pv
from ansys.mapdl.core import launch_mapdl
import os


class Mywidget(QWidget, Ui_Form):
   def __init__(self):
       super().__init__()
       self.setupUi(self)
       self.length = 1.8
       self.width = 0.6
       self.height = 0.02
       self.meshSize = 5
       self.hotTemp = 50
       self.coldTemp = 10

       self.pushButton_calc.clicked.connect(self.calc)
       self.pushButton_geom.clicked.connect(self.geom)
       self.pushButton_mesh.clicked.connect(self.mesh)
       self.pushButton_Temperature.clicked.connect(self.post)
       self.horizontalSlider.valueChanged.connect(self.valueChange)
       self.mapdl = launch_mapdl()

   def calc(self):
       # 读取数据
       self.length = float(self.lineEdit_length.text().strip())
       self.width = float(self.lineEdit_width.text().strip())
       self.height = float(self.lineEdit_height.text().strip())
       self.meshSize = self.horizontalSlider.value()
       self.hotTemp = float(self.lineEdit_hotTemperature.text())
       self.coldTemp = float(self.lineEdit_coldTemperature.text())

       # 几何建模与网格
       self.mapdl.prep7()
       self.mapdl.mp('kxx', 1, 45)
       self.mapdl.et(1, 90)
       self.mapdl.block(0, self.width, 0, self.length, 0, self.height)
       self.mapdl.smrtsize(sizlvl=str(self.horizontalSlider.value()))
       self.mapdl.vsweep(1)
       self.mapdl.mesh.save('mesh.vtk')
       if os.path.isfile('mesh.vtk'):
           mesh = pv.get_reader('mesh.vtk')
           self.widget_vista.add_mesh(mesh.read(), color='white')

       # 施加载荷
       self.mapdl.asel("S", vmin=3)
       self.mapdl.nsla()
       self.mapdl.d("all", "temp", self.coldTemp)
       self.mapdl.asel("S", vmin=4)
       self.mapdl.nsla()
       self.mapdl.d("all", "temp", self.hotTemp)
       self.mapdl.allsel()

       #     求解计算
       self.mapdl.run("/SOLU")
       print(self.mapdl.solve())
       out = self.mapdl.finish()
       self.textEdit_result.append(out)

   def geom(self):
       self.mapdl.vplot(title='geometry')

   def mesh(self):
       self.mapdl.eplot(title='element',window_size=[640, 320])

   def post(self):
       self.mapdl.post1()
       self.mapdl.set(1, 1)
       self.mapdl.post_processing.plot_nodal_temperature()

   def closeEvent(self, event):
       self.mapdl.exit()

   def valueChange(self):
       self.label_meshlevel.setText(str(self.horizontalSlider.value()))
       self.label_meshlevel.setFont(QFont('Arial', 12))


if __name__ == '__main__':
   app = QApplication(sys.argv)
   app.setFont(QFont('微软雅黑', 9))
   win = Mywidget()
   win.show()
   sys.exit(app.exec())

为方便理解,这里将界面代码一并贴出。下面的代码是pyuic自动生成的。界面代码文件testvistaUI.py内容如下:

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_Form(object):
   def setupUi(self, Form):
       Form.setObjectName("Form")
       Form.resize(800, 518)
       Form.setMinimumSize(QtCore.QSize(800, 0))
       Form.setMaximumSize(QtCore.QSize(800, 16777215))
       self.gridLayout = QtWidgets.QGridLayout(Form)
       self.gridLayout.setObjectName("gridLayout")
       self.pushButton_geom = QtWidgets.QPushButton(Form)
       self.pushButton_geom.setObjectName("pushButton_geom")
       self.gridLayout.addWidget(self.pushButton_geom, 1, 1, 1, 1)
       self.widget_vista = QtInteractor(Form)
       self.widget_vista.setObjectName("widget_vista")
       self.gridLayout.addWidget(self.widget_vista, 0, 2, 1, 2)
       self.pushButton_Temperature = QtWidgets.QPushButton(Form)
       self.pushButton_Temperature.setObjectName("pushButton_Temperature")
       self.gridLayout.addWidget(self.pushButton_Temperature, 1, 3, 1, 1)
       self.pushButton_mesh = QtWidgets.QPushButton(Form)
       self.pushButton_mesh.setObjectName("pushButton_mesh")
       self.gridLayout.addWidget(self.pushButton_mesh, 1, 2, 1, 1)
       self.pushButton_calc = QtWidgets.QPushButton(Form)
       self.pushButton_calc.setObjectName("pushButton_calc")
       self.gridLayout.addWidget(self.pushButton_calc, 1, 0, 1, 1)
       self.groupBox_2 = QtWidgets.QGroupBox(Form)
       self.groupBox_2.setMaximumSize(QtCore.QSize(16777215, 200))
       self.groupBox_2.setObjectName("groupBox_2")
       self.gridLayout_2 = QtWidgets.QGridLayout(self.groupBox_2)
       self.gridLayout_2.setObjectName("gridLayout_2")
       self.textEdit_result = QtWidgets.QTextEdit(self.groupBox_2)
       self.textEdit_result.setMaximumSize(QtCore.QSize(16777215, 200))
       self.textEdit_result.setReadOnly(True)
       self.textEdit_result.setObjectName("textEdit_result")
       self.gridLayout_2.addWidget(self.textEdit_result, 0, 0, 1, 1)
       self.gridLayout.addWidget(self.groupBox_2, 2, 0, 1, 4)
       self.groupBox = QtWidgets.QGroupBox(Form)
       self.groupBox.setMinimumSize(QtCore.QSize(380, 0))
       self.groupBox.setMaximumSize(QtCore.QSize(380, 16777215))
       self.groupBox.setObjectName("groupBox")
       self.gridLayout_3 = QtWidgets.QGridLayout(self.groupBox)
       self.gridLayout_3.setObjectName("gridLayout_3")
       self.groupBox_3 = QtWidgets.QGroupBox(self.groupBox)
       self.groupBox_3.setMinimumSize(QtCore.QSize(0, 120))
       self.groupBox_3.setMaximumSize(QtCore.QSize(16777215, 120))
       self.groupBox_3.setObjectName("groupBox_3")
       self.gridLayout_4 = QtWidgets.QGridLayout(self.groupBox_3)
       self.gridLayout_4.setObjectName("gridLayout_4")
       self.label = QtWidgets.QLabel(self.groupBox_3)
       self.label.setObjectName("label")
       self.gridLayout_4.addWidget(self.label, 0, 0, 1, 1)
       self.lineEdit_length = QtWidgets.QLineEdit(self.groupBox_3)
       self.lineEdit_length.setObjectName("lineEdit_length")
       self.gridLayout_4.addWidget(self.lineEdit_length, 0, 1, 1, 1)
       self.label_4 = QtWidgets.QLabel(self.groupBox_3)
       self.label_4.setObjectName("label_4")
       self.gridLayout_4.addWidget(self.label_4, 0, 2, 1, 1)
       self.label_2 = QtWidgets.QLabel(self.groupBox_3)
       self.label_2.setObjectName("label_2")
       self.gridLayout_4.addWidget(self.label_2, 1, 0, 1, 1)
       self.lineEdit_width = QtWidgets.QLineEdit(self.groupBox_3)
       self.lineEdit_width.setObjectName("lineEdit_width")
       self.gridLayout_4.addWidget(self.lineEdit_width, 1, 1, 1, 1)
       self.label_5 = QtWidgets.QLabel(self.groupBox_3)
       self.label_5.setObjectName("label_5")
       self.gridLayout_4.addWidget(self.label_5, 1, 2, 1, 1)
       self.label_3 = QtWidgets.QLabel(self.groupBox_3)
       self.label_3.setObjectName("label_3")
       self.gridLayout_4.addWidget(self.label_3, 2, 0, 1, 1)
       self.lineEdit_height = QtWidgets.QLineEdit(self.groupBox_3)
       self.lineEdit_height.setObjectName("lineEdit_height")
       self.gridLayout_4.addWidget(self.lineEdit_height, 2, 1, 1, 1)
       self.label_6 = QtWidgets.QLabel(self.groupBox_3)
       self.label_6.setObjectName("label_6")
       self.gridLayout_4.addWidget(self.label_6, 2, 2, 1, 1)
       self.gridLayout_3.addWidget(self.groupBox_3, 0, 0, 1, 2)
       self.groupBox_4 = QtWidgets.QGroupBox(self.groupBox)
       self.groupBox_4.setMinimumSize(QtCore.QSize(0, 100))
       self.groupBox_4.setMaximumSize(QtCore.QSize(16777215, 100))
       self.groupBox_4.setObjectName("groupBox_4")
       self.gridLayout_6 = QtWidgets.QGridLayout(self.groupBox_4)
       self.gridLayout_6.setObjectName("gridLayout_6")
       self.label_9 = QtWidgets.QLabel(self.groupBox_4)
       self.label_9.setObjectName("label_9")
       self.gridLayout_6.addWidget(self.label_9, 0, 0, 1, 1)
       self.lineEdit_hotTemperature = QtWidgets.QLineEdit(self.groupBox_4)
       self.lineEdit_hotTemperature.setObjectName("lineEdit_hotTemperature")
       self.gridLayout_6.addWidget(self.lineEdit_hotTemperature, 0, 1, 1, 1)
       self.label_11 = QtWidgets.QLabel(self.groupBox_4)
       self.label_11.setObjectName("label_11")
       self.gridLayout_6.addWidget(self.label_11, 0, 2, 1, 1)
       self.label_10 = QtWidgets.QLabel(self.groupBox_4)
       self.label_10.setObjectName("label_10")
       self.gridLayout_6.addWidget(self.label_10, 1, 0, 1, 1)
       self.lineEdit_coldTemperature = QtWidgets.QLineEdit(self.groupBox_4)
       self.lineEdit_coldTemperature.setObjectName("lineEdit_coldTemperature")
       self.gridLayout_6.addWidget(self.lineEdit_coldTemperature, 1, 1, 1, 1)
       self.label_12 = QtWidgets.QLabel(self.groupBox_4)
       self.label_12.setObjectName("label_12")
       self.gridLayout_6.addWidget(self.label_12, 1, 2, 1, 1)
       self.gridLayout_3.addWidget(self.groupBox_4, 3, 0, 1, 2)
       self.groupBox_5 = QtWidgets.QGroupBox(self.groupBox)
       self.groupBox_5.setMinimumSize(QtCore.QSize(0, 60))
       self.groupBox_5.setMaximumSize(QtCore.QSize(16777215, 60))
       self.groupBox_5.setObjectName("groupBox_5")
       self.gridLayout_5 = QtWidgets.QGridLayout(self.groupBox_5)
       self.gridLayout_5.setObjectName("gridLayout_5")
       self.label_7 = QtWidgets.QLabel(self.groupBox_5)
       self.label_7.setObjectName("label_7")
       self.gridLayout_5.addWidget(self.label_7, 0, 0, 1, 1)
       self.horizontalSlider = QtWidgets.QSlider(self.groupBox_5)
       self.horizontalSlider.setMinimum(1)
       self.horizontalSlider.setMaximum(10)
       self.horizontalSlider.setProperty("value", 5)
       self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal)
       self.horizontalSlider.setObjectName("horizontalSlider")
       self.gridLayout_5.addWidget(self.horizontalSlider, 0, 1, 1, 1)
       self.label_meshlevel = QtWidgets.QLabel(self.groupBox_5)
       font = QtGui.QFont()
       font.setPointSize(12)
       self.label_meshlevel.setFont(font)
       self.label_meshlevel.setObjectName("label_meshlevel")
       self.gridLayout_5.addWidget(self.label_meshlevel, 0, 2, 1, 1)
       self.gridLayout_3.addWidget(self.groupBox_5, 1, 0, 1, 2)
       self.gridLayout.addWidget(self.groupBox, 0, 0, 1, 2)

       self.retranslateUi(Form)
       QtCore.QMetaObject.connectSlotsByName(Form)

   def retranslateUi(self, Form):
       _translate = QtCore.QCoreApplication.translate
       Form.setWindowTitle(_translate("Form", "pyMAPDL测试"))
       self.pushButton_geom.setText(_translate("Form", "显示几何"))
       self.pushButton_Temperature.setText(_translate("Form", "查看温度"))
       self.pushButton_mesh.setText(_translate("Form", "显示网格"))
       self.pushButton_calc.setText(_translate("Form", "开始计算"))
       self.groupBox_2.setTitle(_translate("Form", "过程输出"))
       self.groupBox.setTitle(_translate("Form", "计算参数"))
       self.groupBox_3.setTitle(_translate("Form", "几何参数"))
       self.label.setText(_translate("Form", "长度:"))
       self.lineEdit_length.setText(_translate("Form", "1.8"))
       self.label_4.setText(_translate("Form", "m"))
       self.label_2.setText(_translate("Form", "宽度:"))
       self.lineEdit_width.setText(_translate("Form", "0.6"))
       self.label_5.setText(_translate("Form", "m"))
       self.label_3.setText(_translate("Form", "高度:"))
       self.lineEdit_height.setText(_translate("Form", "0.02"))
       self.label_6.setText(_translate("Form", "m"))
       self.groupBox_4.setTitle(_translate("Form", "载荷参数"))
       self.label_9.setText(_translate("Form", "高温面温度:"))
       self.lineEdit_hotTemperature.setText(_translate("Form", "50"))
       self.label_11.setText(_translate("Form", "K"))
       self.label_10.setText(_translate("Form", "低温面温度:"))
       self.lineEdit_coldTemperature.setInputMask(_translate("Form", "100"))
       self.lineEdit_coldTemperature.setText(_translate("Form", "10"))
       self.label_12.setText(_translate("Form", "K"))
       self.groupBox_5.setTitle(_translate("Form", "网格参数"))
       self.label_7.setText(_translate("Form", "网格级别:"))
       self.label_meshlevel.setText(_translate("Form", "5"))
from pyvistaqt import QtInteractor

3 运行测试

程序启动后自动连接ANSYS APDL。

点击按钮开始计算后进行计算,图形窗口中显示几何模型。

点击显示几何按钮可以打开vtk窗口看到几何模型。

点击显示网格按钮可以查看网格。

点击查看温度按钮可以观察温度分布。

关闭软件会自动断开与ansys的连接。

4 一些问题

目前采用vtk文件进行中转,才能将计算结果显示在程序中,实现过程极不优雅,而且性能也不好。

先把功能实现了,后面慢慢再改。pyansys真心不太好玩儿~


(完毕)


来源:CFD之道
python控制ANSYS
著作权归作者所有,欢迎分享,未经许可,不得转载
首次发布时间:2023-05-18
最近编辑:1年前
CFD之道
博士 | 教师 探讨CFD职场生活,闲谈CFD里外
获赞 2559粉丝 11228文章 729课程 27
点赞
收藏
未登录
还没有评论
课程
培训
服务
行家
VIP会员 学习 福利任务 兑换礼品
下载APP
联系我们
帮助与反馈