本模块提供Python与Workbench联合仿真的支持:可通过Python启动Workbench,并向WB实时发送脚本代码执行,同时支持查询代码执行结果和脚本变量值。
说明:本模块只提供Python与Workbench中的ScriptEngine的双向数据接口,WB中仿真功能实现还需要通过其Python脚本开发实现,可以参考以下文章:
- 《基于Python的Workbench开发指南+案例解析》
- 《Workbench开发指南:仿真流程集成》
- 《Workbench开发指南:仿真模板开发》
- 《SCDM二次开发快速入门|应用+技巧》
- 《轻松上手Mechanical脚本自动化》
- 《Fluent脚本自动化快速入门》
- 视频教程:《Python语言在ANSYS的应用52讲-掌握SCDM脚本建模及ANSYS二次开发能力》
预编译的二进制库目前只支持Windows x64平台的Python3.7、3.8、3.9版本,安装方法如下:
pip install PyWbUnit-0.3.0-cp37-none-win_amd64.whl
pip install PyWbUnit-0.3.0-cp38-none-win_amd64.whl
pip install PyWbUnit-0.3.0-cp39-none-win_amd64.whl
Help on class CoWbUnitProcess in module PyWbUnit._CoWbUnit:
class CoWbUnitProcess(builtins.object)
|
| CoWbUnitProcess(workDir=None, version=201, interactive=True)
|
| Unit class for co-simulation with Workbench using Python.
|
| >>> coWbUnit = CoWbUnitProcess()
| >>> coWbUnit.initialize()
| >>> command = 'GetTemplate(TemplateName="Static Structural", Solver="ANSYS").CreateSystem()'
| >>> coWbUnit.execWbCommand(command)
| >>> coWbUnit.execWbCommand('systems=GetAllSystems()')
| >>> print(coWbUnit.queryWbVariable('systems'))
| >>> coWbUnit.saveProject(r'D:/example.wbpj')
| >>> coWbUnit.finalize()
|
| Methods defined here:
|
| __init__(self, workDir=None, version=201, interactive=True)
| Constructor of CoWbUnitProcess.
| :param workDir: str, the directory where the Workbench starts.
| :param version: int, workbench version: 2019R1-190/2020R1-201/2021R1-211.
| :param interactive: bool, whether to display the Workbench interface
|
| execWbCommand(self, command: 'str') -> 'str'
| Send python script command to the Workbench for execution
| :param command: str, python script command
| :return: str, execution result
|
| exitWb(self) -> 'str'
| `Exit` the current Workbench client process and close the Workbench server
| :return: str
|
| finalize(self)
| Exit the current workbench and close the TCP Server connection
| :return: None
|
| initialize(self) -> None
| Called before `execWbCommand`: Start the Workbench in the server
| mode and open the TCP server port to create a socket connection
| :return: None
|
| queryWbVariable(self, variable: 'str')
| Query the value of `variable` in the workbench script environment
| :param variable: str, script variable name
| :return: str
|
| saveProject(self, filePath=None, overWrite=True)
| Save the current workbench project file to `filePath`
| If the Project has not been saved, using method: `saveProject()`
| will raise `CommandFailedException`
| :param filePath: Optional[str, None], if
| :param overWrite: bool, Whether to overwrite the original project
| :return: str, execution result
|
| terminate(self)
| Terminates the current Workbench client process
| :return: bool
|
| ----------------------------------------------------------------------
Help on class WbServerClient in module PyWbUnit._CoWbUnit:
class WbServerClient(builtins.object)
|
| WbServerClient(aasKey: 'str')
|
| Client Class for the Workbench server connection
| >>> aas_key = 'localhost:9000'
| >>> wbClient = WbServerClient(aas_key)
| >>> wbClient.execWbCommand('<wb_python_command>')
| >>> print(wbClient.queryWbVariable('<wb_python_var>'))
|
| Methods defined here:
|
| __init__(self, aasKey: 'str')
|
| execWbCommand(self, command: 'str') -> 'str'
|
| queryWbVariable(self, variable) -> 'str'
|
| ----------------------------------------------------------------------
# -*- coding: utf-8 -*-
from socket import *
class WbServerClient:
_suffix = '<EOF>'
_coding = 'US-ASCII'
_buffer = 1024
def __init__(self, aasKey: str):
aasList = aasKey.split(':')
self._address = (aasList[0], int(aasList[1]))
def execWbCommand(self, command: str) -> str:
sockCommand = command + self._suffix
with socket(AF_INET, SOCK_STREAM) as sock:
sock.connect(self._address)
sock.sendall(sockCommand.encode(self._coding))
data = sock.recv(self._buffer).decode()
return data
def queryWbVariable(self, variable) -> str:
self.execWbCommand("__variable__=" + variable + ".__repr__()")
retValue = self.execWbCommand("Query,__variable__")
return retValue[13:]
首先从PyWbUnit模块中导入CoWbUnitProcess类,详细文档说明可以通过help(CoWbUnitProcess)查看,以公众号文章:《ANSYS中使用Python实现高效结构仿真》为例,演示如何使用PyWbUnit调用Workbench完成联合仿真的过程:
# -*- coding: utf-8 -*-
from PyWbUnit import CoWbUnitProcess
# 创建wb单元实例,指定ansys wb版本,如2020R1对应201
coWbUnit = CoWbUnitProcess(workDir=r'E:/Workdata', version=201, interactive=True)
coWbUnit.initialize()
command = 'mechSys = GetTemplate(TemplateName="Static Structural", Solver="ANSYS").CreateSystem()'
coWbUnit.execWbCommand(command)
coWbUnit.execWbCommand('systems=GetAllSystems()')
print(coWbUnit.queryWbVariable('systems'))
materialScript = r'''# 创建静结构分析流程
# 获得Engineering Data数据容器
engData = mechSys.GetContainer(ComponentName="Engineering Data")
# 封装创建材料的方法
def CreateMaterial(name, density, *elastic):
mat = engData.CreateMaterial(Name=name)
mat.CreateProperty(Name="Density").SetData(Variables=["Density"],
Values=[["%s [kg m^-3]" % density]])
elasticProp = mat.CreateProperty(Name="Elasticity", Behavior="Isotropic")
elasticProp.SetData(Variables=["Young's Modulus"], Values=[["%s [MPa]" % elastic[0]]])
elasticProp.SetData(Variables=["Poisson's Ratio"], Values=[["%s" % elastic[1]]])
# 创建材料Steel,密度:7850kg/m3,杨氏模量:208e3MPa,泊松比:0.3
CreateMaterial("Steel", 7850, 209.e3, 0.3)'''
coWbUnit.execWbCommand(materialScript)
coWbUnit.execWbCommand('geo=mechSys.GetContainer("Geometry")')
coWbUnit.execWbCommand('geo.Edit(IsSpaceClaimGeometry=True)')
geoScript = r'''# Python Script, API Version = V18
# 创建悬臂梁实体区域
BlockBody.Create(Point.Origin, Point.Create(MM(200), MM(25), MM(20)))
GetRootPart().SetName("Beam")
# 选择beam实体,用于后续材料赋予
Selection.Create(GetRootPart().Bodies).CreateAGroup("ns_beamBody")
# 通过坐标点选择面对象
def GetFaceObjByPt(pt):
for face in GetRootPart().GetDescendants[IDesignFace]():
if face.Shape.ContainsPoint(pt): return face
# 选择固定约束加载面
fixSupFace = GetFaceObjByPt(Point.Create(0, MM(12.5), MM(10)))
Selection.Create(fixSupFace).CreateAGroup("ns_fixSup")
# 选择压力载荷加载面
pressFace = GetFaceObjByPt(Point.Create(MM(50), MM(12.5), MM(20)))
Selection.Create(pressFace).CreateAGroup("ns_press")
'''
coWbUnit.execWbCommand(f'geo.SendCommand(Language="Python", Command={geoScript!r})')
coWbUnit.execWbCommand(f'geo.Exit()')
launchScript = r'''# 刷新Model Component数据
modelComp = mechSys.GetComponent(Name="Model")
modelComp.Refresh()
# 获得Mechanical中Model的数据容器
model = mechSys.GetContainer(ComponentName="Model")
model.Edit()'''
coWbUnit.execWbCommand(launchScript)
mechScript = r"""# encoding: utf-8
# 给定Named Selection名称获取子对象实例
def GetLocByName(ns_name):
for ns in Model.NamedSelections.Children:
if ns.Name == ns_name: return ns
# 指定材料
matAss = Model.Materials.AddMaterialAssignment()
matAss.Material = "Steel"
matAss.Location = GetLocByName("ns_beamBody")
# 划分网格
mesh = Model.Mesh
mesh.ElementSize = Quantity("10 [mm]")
mesh.GenerateMesh()
# 获得Analyses对象
analysis = Model.Analyses[0]
# 添加固定约束
fixSup = analysis.AddFixedSupport()
fixSup.Location= GetLocByName("ns_fixSup")
# 加载压力载荷
pressLoad = analysis.AddPressure()
pressLoad.Location = GetLocByName("ns_press")
pressLoad.Magnitude.Output.DiscreteValues = [Quantity("0.5 [MPa]")]
Model.Solve()
# 后处理操作
solution = analysis.Solution
misesResult = solution.AddEquivalentStress()
misesResult.EvaluateAllResults()
# 设置视角
camera = ExtAPI.Graphics.Camera
camera.UpVector = Vector3D(0,0,1)
camera.SceneWidth = Quantity("150 [mm]")
camera.SceneHeight = Quantity("120 [mm]")
camera.FocalPoint = Point((0.08,0.0125,0), 'm')
# 输出后处理云图
misesResult.Activate()
ExtAPI.Graphics.ExportImage("d:/mises.png")"""
coWbUnit.execWbCommand(f'model.SendCommand(Language="Python", Command={mechScript!r})')
coWbUnit.execWbCommand('model.Exit()')
coWbUnit.saveProject(r"E:/Workdata/beam.wbpj")
# 关闭wb单元实例
coWbUnit.finalize()
关注微信公众号:“ANSYS仿真与开发”,后台留言;或者邮件至:tguangs@163.com