原文首发于我的微信公众号 TaohongMaxwell:查看原文
前言
在工程设计、求解计算的过程中,往往存在大量重复性的工作,这些工作不仅耗时耗力,而且容易出错。为了提高工作效率,减少人为错误,我们希望这些重复性工作能够被计算机自动完成,从而让工程师从繁重的重复性劳动中解放出来,将更多的精力投入到创造性的工作中。
CST Studio Suite® 提供了 Python 编程接口,也提供了在 Python 环境中执行 VB 脚本的接口。并且,在 CST Studio Suite 2024 中,CST Python Libraries 的特性得到了更新。
现在,我们将使用 Jupyter Notebook 连接到 CST Studio Suite,通过一个演示案例,完成脚本控制建立模型、查看结果等工作,并在 Python 中进行更多自动化任务。
文章共分为5个部分,分别介绍以下内容:
搭建 Python 环境
控制 CST 建模
仿真并绘制结果
仿真优化
外部后处理
本期为第 2 篇文章,详细介绍如何使用 Python 控制 CST 创建仿真模型。
准备工作
在 上一篇文章 中,我们分享了如何搭建 Python 测试环境的流程。本次案例基于上一篇文章的模型操作。
如果您保留了上次搭建环境时候的 Jupyter Notebook 工程和 CST 工程,可以在关联文件后基于该模型继续操作。
如果您未保留上一次的 CST 工程,可以按照以下步骤操作:
打开测试案例并检查对应的库
在 cmd 中输入以下内容(注意全是小写)即可进入控制台。
1jupyter notebook
打开测试案例,运行有以下代码,加载必要的库。如果有报错提示缺少库,使用 pip 安装缺少的库,直到无报错出现。
1import time
2import numpy as np
3import matplotlib.pyplot as plt
4from scipy.optimize import minimize
5import tempfile
6
7tmp = tempfile.gettempdir()
8%matplotlib notebook
运行下面的代码,加载 CST Python 库。
1# cst related imports
2import cst
3import cst.interface
4import cst.results
5
6print(cst.__file__)
7# should print '<PATH_TO_CST_AMD64>\python_cst_libraries\cst\__init__.py'
如果成功执行该命令,该单元格的输出将打印库的路径。
调用 CST 并创建项目
现在,让我们调用 CST Design Environment,开始初始化连接。
1project = cst.interface.DesignEnvironment()
执行该代码,打开 CST Design Environment,会出现提示“静态/脚本模式已激活,弹出窗口已被阻止”弹窗,点击“Swich to Interactive Mode”切换到交互模式即可。
运行下面的代码,创建一个空的 CST Microwave Studio 项目。
1mws_project = project.new_mws()
运行下面的代码,激活当前项目的窗口。
1mws_project.activate()
将项目保存在当前用户的 TEMP 文件夹中,即 C:\Users<Users>\AppData\Local\Temp 路径。
1mws_project.save(tmp+ "\CST_TEST.cst" )
如果提示“文件已存在”,说明此前已经保存过该文件到该目录,没有赋予文件操作相关的命令,无法覆盖保存。
可以修改拟保存的项目名称,也可以在文件管理器中访问该路径删除原有文件。
此外,用户也可以根据自己的需求,将项目文件保存到指定的位置。
创建 offset 参数
在模型中创建一个名为 offset 的参数。
1mws_project.model3d.StoreDoubleParameter( "offset" , 3 )
请检查该参数在项目参数列表中是否可见。
建模
CST 支持 Python 与 VBA,并通过在 Python 调用封装的 VBA 命令,以获得完整的脚本功能。
在这里,我们先使用 VBA 定义模型,随后使用 Python 命令 add_to_history 将之前定义的建模命令添加到 History List 中,以完成建模操作。
模型介绍
选用一个 T 型波导进行建模演示。在 T 形波导结构中,中间的金属结构通常被称为“探针”,它的作用主要是将能量从主波导耦合到分支波导,或者从分支波导耦合到主波导。
改变探针的位置,能够改变波导内部的场分布。前面设置的 offset 参数的作用就是修改探针的位置。这个参数在建模和优化的过程中会用到。
我们尝试使用命令来进行建模操作。
使用 VBA 定义命令
在该操作的中间步骤中,并非所有的 VBA 命令都有对应的本地 Python 命令。
不过,为了保证操作的连续性,通过在 Python 中调用封装的 VBA 命令,仍然可以获得完整的脚本功能控制 CST。
接下来将通过 VBA 代码来定义一些命令。
设置求解器参数
设置仿真频率为 8-10 GHz,并设置一个 9GHz 场监视器,求解器选用 T 求解器。
1Full_History = """
2'Set Freq
3Solver.FrequencyRange 8, 10
4"""
5
6Full_History = Full_History + """
7'Define Monitor
8With Monitor
9.Reset
10.Name "e-field (f=9)"
11.Dimension "Volume"
12.Domain "Frequency"
13.FieldType "Efield"
14.Frequency 9
15.Create
16End With
17"""
18
19Full_History = Full_History + """
20'Define Solver
21ChangeSolverType "HF Time Domain"
22With Solver
23.CalculationType "TD-S"
24.StimulationPort "1"
25.StimulationMode "1"
26.MeshAdaption False
27.CalculateModesOnly False
28.SParaSymmetry False
29.StoreTDResultsInCache False
30.FullDeembedding False
31.UseDistributedComputing False
32End With
33"""
创建 T 型波导模型
1Full_History = Full_History + """
2'Define Units
3With Units
4.Geometry "mm"
5.Frequency "ghz"
6.Time "ns"
7End With
8
9' set workplane properties
10
11With WCS
12.SetWorkplaneSize "50"
13.SetWorkplaneRaster "10"
14.SetWorkplaneSnap "TRUE"
15.SetWorkplaneSnapRaster "5"
16End With
17
18' new component: component1
19Component.New "component1"
20
21' define brick: component1:solid1
22With Brick
23.Reset
24.Name "solid1"
25.Component "component1"
26.Material "Vacuum"
27.Xrange "-10", "10"
28.Yrange "0", "10"
29.Zrange "0", "40"
30.Create
31End With
32
33' pick face
34Pick.PickFaceFromId "component1:solid1", "6"
35
36' align wcs with face
37WCS.AlignWCSWithSelectedFace
38Pick.PickCenterpointFromId "component1:solid1", "6"
39WCS.AlignWCSWithSelectedPoint
40
41' define brick: component1:solid2
42With Brick
43.Reset
44.Name "solid2"
45.Component "component1"
46.Material "Vacuum"
47.Xrange "-5", "5"
48.Yrange "-10", "10"
49.Zrange "0", "20"
50.Create
51End With
52
53' pick face
54Pick.PickFaceFromId "component1:solid2", "1"
55
56' define port: 1
57With Port
58.Reset
59.PortNumber "1"
60.NumberOfModes "1"
61.AdjustPolarization False
62.PolarizationAngle "0.0"
63.ReferencePlaneDistance "0"
64.TextSize "50"
65.Coordinates "Picks"
66.Orientation "xmax"
67.PortOnBound "True"
68.ClipPickedPortToBound "False"
69.Xrange "30", "30"
70.Yrange "0", "10"
71.Zrange "10", "30"
72.Create
73End With
74
75' pick face
76Pick.PickFaceFromId "component1:solid1", "1"
77
78' define port: 2
79With Port
80.Reset
81.PortNumber "2"
82.NumberOfModes "1"
83.AdjustPolarization False
84.PolarizationAngle "0.0"
85.ReferencePlaneDistance "0"
86.TextSize "50"
87.Coordinates "Picks"
88.Orientation "zmax"
89.PortOnBound "True"
90.ClipPickedPortToBound "False"
91.Xrange "-10", "10"
92.Yrange "0", "10"
93.Zrange "40", "40"
94.Create
95End With
96
97' pick face
98Pick.PickFaceFromId "component1:solid1", "2"
99
100' define port: 3
101With Port
102.Reset
103.PortNumber "3"
104.NumberOfModes "1"
105.AdjustPolarization False
106.PolarizationAngle "0.0"
107.ReferencePlaneDistance "0"
108.TextSize "50"
109.Coordinates "Picks"
110.Orientation "zmin"
111.PortOnBound "True"
112.ClipPickedPortToBound "False"
113.Xrange "-10", "10"
114.Yrange "0", "10"
115.Zrange "0", "0"
116.Create
117End With
118
119' define boundaries
120With Boundary
121.Xmin "electric"
122.Xmax "electric"
123.Ymin "electric"
124.Ymax "electric"
125.Zmin "electric"
126.Zmax "electric"
127.Xsymmetry "none"
128.Ysymmetry "electric"
129.Zsymmetry "none"
130End With
131
132' define background
133With Background
134.ResetBackground
135.XminSpace "0.0"
136.XmaxSpace "0.0"
137.YminSpace "0.0"
138.YmaxSpace "0.0"
139.ZminSpace "0.0"
140.ZmaxSpace "0.0"
141.ApplyInAllDirections "False"
142End With
143
144With Material
145.Reset
146.FrqType "all"
147.Type "Pec"
148.MaterialUnit "Frequency", "Hz"
149.MaterialUnit "Geometry", "m"
150.MaterialUnit "Time", "s"
151.MaterialUnit "Temperature", "Kelvin"
152.Epsilon "1.0"
153.Mu "1.0"
154.ReferenceCoordSystem "Global"
155.CoordSystemType "Cartesian"
156.NLAnisotropy "False"
157.NLAStackingFactor "1"
158.NLADirectionX "1"
159.NLADirectionY "0"
160.NLADirectionZ "0"
161.Rho "0.0"
162.ThermalType "Normal"
163.ThermalConductivity "0.0"
164.SpecificHeat "0.0", "J/K/kg"
165.MetabolicRate "0"
166.BloodFlow "0"
167.VoxelConvection "0"
168.MechanicsType "Unused"
169.Colour "0.6", "0.6", "0.6"
170.Wireframe "False"
171.Reflection "False"
172.Allowoutline "True"
173.Transparentoutline "False"
174.Transparency "0"
175.ChangeBackgroundMaterial
176End With
177
178' activate global coordinates
179WCS.ActivateWCS "global"
180
181' boolean add shapes: component1:solid1, component1:solid2
182Solid.Add "component1:solid1", "component1:solid2"
183
184' pick face
185Pick.PickFaceFromId "component1:solid1", "11"
186
187' align wcs with face
188WCS.AlignWCSWithSelectedFace
189Pick.PickCenterpointFromId "component1:solid1", "11"
190WCS.AlignWCSWithSelectedPoint
191
192' store picked point: 1
193Pick.NextPickToDatabase "1"
194Pick.PickEndpointFromId "component1:solid1", "9"
195
196' define cylinder: component1:solid2
197With Cylinder
198.Reset
199.Name "solid2"
200.Component "component1"
201.Material "PEC"
202.OuterRadius "1"
203.InnerRadius "0"
204.Axis "z"
205.Zrange "zp(1)", "0"
206.Xcenter "-10+offset"
207.Ycenter "0"
208.Segments "0"
209.Create
210End With
211
212' activate global coordinates
213WCS.ActivateWCS "global"
214"""
将建模命令添加到 History List
随后,我们向 CST 发送建模命令。
注意,这次我们使用的是 Python 命令 add_to_history 。这将执行我们之前定义的命令字符串,并将这些命令添加到 History List 中。
1mws_project.model3d.add_to_history ( "My_Splitter" , Full_History)
检查几何体是否在界面中可见,并检查求解器和频率设置。
至此,已经完成建模、设置场监视器和求解器的步骤。
总结
CST 支持 Python 与 VBA,并通过在 Python 调用封装的 VBA 命令,获得完整的脚本功能。
先使用 VBA 定义模型,随后使用 Python 命令 add_to_history 将之前定义的建模等命令添加到 History List 中,以完成建模操作。