本节是关于Python API接口相关设置和用法的介绍。
SimWorks提供了名为simworks的Python的应用程序编程接口模块(API),允许用户通过Python脚本与SimWorks仿真软件(如FDTD、FDE、FDFD)进行交互,实现:
这个Python API接口,使得数据处理、自动化执行仿真、参数优化、高性能计算等具有更高自由度,满足用户的二次开发等高级需求。
下面介绍如何配置Python环境,使其能够正确加载SimWorks仿真软件的本地 DLL 和 Python API模块。
import os, sys
os.add_dll_directory(r"C:\Program Files\SimWorks\SimWorks FD Solutions\bin")
sys.path.append(r"C:\Program Files\SimWorks\SimWorks FD Solutions\api\python")
import simworks
import numpy as np
chmod +x ./SimWorks_FD_Solutions-v****.AppImage
--appimage-extract选项解压./SimWorks_FD_Solutions-v****.AppImage --appimage-extract
import sys, os
sys.path.append("squashfs-root/api/usr/api/python/")
Contents/api/python/。Contents/api/python/。Python API 架构支持本地调用与远程调用,并具备跨操作系统运行能力。远程调用基于客户端-服务器端双端通信实现:服务器端程序常驻监听指定端口,客户端通过该端口建立 Socket 通道与服务器端通信。客户端发起调用请求后,服务器端将解析请求并在本地启动 fd_solutions 执行任务,并将结果返回客户端,从而实现跨平台的远程调用。
为实现客户端与服务端的双向通信,服务端需要启动通信端口,首次运行前,请按以下步骤操作(相关脚本文件放置在软件安装目录下的/api/interop_server/scripts/):
运行generate_certificate脚本,根据提示生成CA证书文件,保留$(hostname)_server.crt文件,后续需发送给客户端使用。
运行interop_server_start脚本,启动interop_server服务。
服务端设置完成后,客户端需要进行连接:
首次运行前,从服务端获取$(hostname)_server.crt文件,并导入到客户端。信任该CA证书,用于客户端与服务端之间建立SSL加密通道。
在Python脚本中,通过args参数传入服务端IP地址及interop_server所监听的端口。其余脚本命令正常使用即可。

使用完成后需要关闭监听服务:
运行interop_server_stop脚本,关闭interop_server服务。
加密连接配置
以上流程默认建立的SSL加密连接,用户可根据实际网络环境选择是否启用加密连接。
在Python脚本中,通过encrypted_connection参数控制是否启用SSL加密连接,通过ca_certificate指定所使用CA证书的路径。示例代码如下:
# 使用加密连接,并指定CA证书,客户端将使用系统保存的CA证书与用户指定的CA证书
args = {"hostname": "192.168.1.74", "port": 8088, "encrypted_connection": True, "ca_certificate":r"D:\windows\certs\name_server.crt"}
# 使用加密连接,但不指定证书,客户端将使用系统保存的CA证书
args = {"hostname": "192.168.1.74", "port": 8088}
# 或
args = {"hostname": "192.168.1.74", "port": 8088, "encrypted_connection": True}
#不使用加密连接
args = {"hostname": "192.168.1.74", "port": 8088, "encrypted_connection": False}
import os
import sys
os.add_dll_directory(r"C:\Program Files\SimWorks\SimWorks FD Solutions\bin")
sys.path.append(r"C:\Program Files\SimWorks\SimWorks FD Solutions\api\python")
import simworks
import numpy as np
if __name__ == "__main__":
with simworks.FD() as fd:
# Add fdtd solver
fd.addfdtd()
fd.set("x",0)
fd.set("x span", 8e-6)
fd.set("y",0)
fd.set("y span",3e-6)
fd.set("z",0)
fd.set("z span",3e-6)
fd.set("boundary conditions x max","PML")
fd.set("boundary conditions x min","PML")
fd.set("boundary conditions y max","periodic")
fd.set("boundary conditions y min","periodic")
fd.set("boundary conditions z max","PML")
fd.set("boundary conditions z min","PML")
# Add rectangle structure
fd.addrect()
fd.set("x", 0)
fd.set("x span", 0.5e-6)
fd.set("y", 1e-6)
fd.set("y span", 2e-6)
fd.set("z", 0)
fd.set("z span", 2e-6)
# Set the material of rectangle
fd.set("material", "Ag (Silver) - CRC")
# Save project
fd.saveproject('F:\\pythondebug\\runfdtd.mpps')
# Source
fd.addplane()
fd.set('direction', 'Forward')
fd.set('incident axis', 'x')
fd.set('x', -2e-6)
fd.set('y', 0)
fd.set('y span', 6e-6)
fd.set('z', 0)
fd.set('z span', 6e-6)
fd.set('central wavelength', 1550e-9)
fd.set('wavelength span', 0)
# Monitor
fd.addpowermonitor()
fd.set("name", "T")
fd.set("spatial type", "2D X normal")
fd.set("x", 2e-6)
fd.set("y", 0)
fd.set("z", 0)
fd.set("y span", 6e-6)
fd.set("z span", 6e-6)
# Run FDTD
fd.run()
# Obtain the simulation results
Ex = fd.getdata("FDTD::T", "E", "Ex")
f = fd.getdata("FDTD::T", "E", "f")
sp = fd.getdata("FDTD::Plane", "sourcepower", "sourcepower")
print("done")

下面介绍SimWorks和Python在simworks接口上的数据传递。用Python API启动SimWorks Finite Difference Solutions的仿真软件时,建立了两者环境之间的联系,彼此的工作空间不共享,而是在变量传递过程中创建一个相同的副本,根据getv( )和put( )函数中定义的转换类型来进行前传和后传。
SimWorks API支持的数据类型为:Real/Complex/Sring/Matrix/Struct/Cell/Dataset(matrixdataset and unstructureddataset),具体实现请见下面的代码:
import os
import sys
os.add_dll_directory(r"C:\Program Files\SimWorks\SimWorks FD Solutions\bin")
sys.path.append(r"C:\Program Files\SimWorks\SimWorks FD Solutions\api\python")
import simworks
import numpy as np
if __name__ == "__main__":
with simworks.Simworks('fd') as fd:
# Run the defined scripts in the SimWorks GUI
fd.eval("addpoly;")
# Generate various data types
fd.eval("str = 'test string content';")
fd.eval(f"mdmds = reshape({[str(i) + str(i + 1) for i in range(3*4*5)]}, [3, 4, 5]);")
fd.eval("mdc = [1+2j, 3+4j; 5+6j, 7+8j];")
fd.eval("C = {1, 2, 3; 'text', rand(5,10,2), {11; 22; 33} };")
fd.eval("E2=struct()")
fd.eval("E2.x=1;E2.y=2;E2.f=1.55e-6;E2.Ex=rand(5,5);")
# Generate the combination of allowed data types
fd.eval("{0} = struct;".format(field_result_name) +
"{0}.E = getdata('{1}','E');".format(field_result_name, monitor_name))
# Get variables from SimWorks FD Solutions
var_str = fd.getv("str")
var_mdmds = fd.getv("mdmds")
var_mdc = fd.getv("mdc")
var_cellA=fd.getv("C")
var_E=fd.getv("E2")
# Put variables from Python back to SimWorks FD Solutions
fd.putv("num", np.array([12, 13]))
fd.putv("putcomplex_np_mat", np.array([[1 + 2j, 3 + 4j], [5 + 6j, 7 + 8j]]))
fd.putv("put_mdmdr", np.arange(3 * 4 * 5).reshape([3, 4, 5]))
fd.putv("putstrmat", np.array([["123", "45678", "6789"], ['9101112', '13141516171819', '1457']], order='F'))
fd.putv("putemptystrmat", np.array([], dtype=np.str_))
fd.putv("putcell",var_cellA)
fd.putv("putstruct",var_E)
fd.savematlabmatfile('Y:\\pythondebug\\struct.mat')
print("done")