2. HFSS脚本录制与IronPython基础

在批量仿真任务中,手工点击建模、设置边界、扫频求解的方式无法复用,也无法保证多次运行的一致性。HFSS 提供了脚本录制功能,可以把界面上的操作翻译成 IronPython 代码,再通过脚本回放或改写实现参数化、循环化和批量化。本节围绕三件事展开:脚本怎么录、录出来的 IronPython 代码怎么读和改、脚本在什么环境里运行与调试。

一、脚本录制:把界面操作变成代码

HFSS 的脚本录制入口在 Tools → Record Script。点击后选择保存路径与文件名,扩展名使用 .py,随后在 AEDT 界面中进行的建模、赋材料、加边界、设求解、加扫频等操作都会被记录为 IronPython 语句。再次点击 Tools → Stop Recording Script 结束录制。录制期间建议只做与目标相关的操作,避免误点产生冗余代码。

一个典型录制片段如下(示例参数,仅用于说明结构):

# 录制生成的建模片段(示例)
oProject = oDesktop.GetActiveProject()
oDesign = oProject.GetActiveDesign()
oEditor = oDesign.SetActiveEditor("3D Modeler")

oEditor.CreateBox(
    [
        "NAME:BoxParameters",
        "XPosition:=-15mm",
        "YPosition:=-10mm",
        "ZPosition:=-0.5mm",
        "XSize:=30mm",
        "YSize:=20mm",
        "ZSize:=1mm"
    ],
    ["NAME:Attributes", "Name:Substrate", "MaterialValue:=\"FR4_epoxy\""]
)

可以看到,录制结果并不是“点击了某个按钮”,而是对 oEditor 这类 COM 对象的调用,参数以 NAME:xxx 的键值对列表传入。理解这一点,就理解了脚本改写的抓手:把 XSize:=30mm 换成变量,就实现了参数化。

二、IronPython 语法要点

IronPython 是运行在 .NET 上的 Python 实现,语法与 Python 2.7 接近,但能直接调用 AEDT 的 COM 接口。对 HFSS 自动化而言,需要重点掌握以下几类语法。

  • 变量与数值单位:HFSS 参数以字符串形式传递,如 "30mm"、"2.4GHz"。数值计算时可用纯数字,但写回模型时必须带单位字符串,否则会按默认单位解释。
  • 列表与字典:录制代码大量使用列表 [ ] 传递参数块,用 "NAME:xxx" 作为块标识。改写时保持列表结构完整,不要漏掉 NAME: 前缀。
  • 字符串格式化:批量仿真常用 "XSize:=%s" % L 或 "XSize:={0}".format(L) 把变量拼进参数字符串,这是参数扫描的核心写法。
  • 循环与条件:for 遍历参数列表、if 判断求解是否收敛,是批量任务的基本控制结构。
  • 异常处理:用 try/except 包裹求解调用,避免单个频点失败导致整个批处理中断。

下面是一个把长度参数化的改写示例:

# 参数化改写(示例)
L_list = [20, 25, 30, 35]   # 单位 mm
for L in L_list:
    oEditor.ChangeProperty(
        [
            "NAME:AllTabs",
            [
                "NAME:Geometry3DAttributeTab",
                ["NAME:PropServers", "Substrate"],
                ["NAME:ChangedProps",
                 ["NAME:XSize", "Value:=", "%dmm" % L]]
            ]
        ]
    )
    oDesign.Analyze("Setup1")

三、脚本运行机制

HFSS 脚本有两种运行方式。第一种是在 AEDT 内部通过 Tools → Run Script 执行,脚本运行在当前已打开的工程上下文中,oDesktop、oProject、oDesign 这些全局对象由环境自动注入,无需自己创建。第二种是在外部用 RunScript 命令行或 Python 解释器调用,此时需要先通过 ScriptEnv.Initialize() 建立与 AEDT 的连接,再获取 oDesktop。

脚本执行遵循“自上而下、逐句解释”的顺序,遇到 Analyze 这类求解调用会阻塞直到求解结束。因此批量脚本的耗时主要来自求解,而不是代码本身。若脚本中途报错,已完成的建模和求解结果会保留在工程中,这也是调试时可以分段运行的原因。

① 脚本录制 Tools → Record Script 界面操作 → .py 文件 建模 / 边界 / 求解 / 扫频 产出:可回放的原始脚本 ② IronPython 改写 变量替换固定尺寸 for 循环遍历参数列表 try/except 容错 产出:参数化批处理脚本 ③ 运行与调试 内部:Run Script 外部:ScriptEnv 初始化 分段运行定位报错 产出:批量结果与日志 脚本运行机制与对象上下文 oDesktop AEDT 应用入口 oProject 当前工程 oDesign 当前设计 oEditor 建模编辑器 逐句解释执行 · Analyze 阻塞至求解结束 · 报错后已完成结果保留在工程中

四、调试环境搭建

脚本出错时,最有效的定位方式是分段运行。把脚本按“建模段—边界段—求解段—后处理段”拆开,逐段执行,观察哪一段抛出异常。AEDT 的 Message Manager 会给出错误行号和对象名,例如 NameError: name 'oEditor' is not defined 通常说明脚本在外部运行时没有正确初始化环境。

若使用外部编辑器(如 PyCharm 或 VS Code)编写脚本,需要把 AEDT 安装目录下的 Script 相关库路径加入解释器搜索路径,并安装 pywin32 以支持 COM 调用。一个可用的外部启动模板如下:

# 外部运行模板(示例)
import ScriptEnv
ScriptEnv.Initialize("Ansoft.ElectronicsDesktop")
oDesktop = ScriptEnv.GetDesktop()
oProject = oDesktop.GetActiveProject()
oDesign = oProject.GetActiveDesign()
print("已连接:", oDesign.GetName())
调试建议:先在 GUI 中录制一段最小可运行脚本,确认能跑通,再逐步加入变量和循环。每次只改一处,便于定位问题。
注意:IronPython 与 Python 3 语法存在差异,例如 print 在 IronPython 中既可用语句也可用函数形式,但 f-string 不被支持,应使用 % 或 .format()。

五、从录制到批量的关键转换

录制脚本只是起点,真正用于批量仿真需要完成三个转换:把固定尺寸换成变量、把单次求解包进循环、把结果输出到文件。下表给出常见录制语句与批量写法的对应关系(示例)。

录制语句(固定值) 批量写法(参数化) 作用
"XSize:=30mm" "XSize:=%dmm" % L 尺寸随循环变化
oDesign.Analyze("Setup1") 放入 for 循环内 每个参数各求解一次
oModule.GetSolutionData() 结果写入 .csv 批量收集数据

完成上述转换后,脚本就具备了批量仿真的基本能力。下一阶段将在此基础上引入参数扫描与结果自动提取,把“能跑”推进到“跑得准、收得全”。