☰ Contents
Python API Settings
  • SimWorks Python API

Python API Settings

This section describes the settings and usage of Python API.

SimWorks provides a Python application programming interface (API) called simworks, which allows users to interact with SimWorks software (such as FDTD, FDE, and FDFD) through Python scripts to achieve the following functions.

  • Start the simulation engine
  • Build the device structures
  • Set up materials, light sources, monitors, and boundary conditions
  • Run the simulation
  • Extract simulation results
  • Automate batch simulation tasks

This Python API interface enables greater freedom in data processing, automated simulation execution, parameter optimization, high-performance computing, etc., which meets users' advanced needs such as secondary development.

Initial environment configuration of the Python API

The following describes how to configure the Python environment so that it can correctly load the native DLL and Python API library of SimWorks simulation software.

Windows

  1. To enable interaction between SimWorks software and Python programming language, the user needs to have Python installed on the local machine. Python 3.12 version and above are recommended. If you have not installed it, it is recommended that you download the Python development tool for free, for example PyCharm.

  2. The SimWorks Python API requires the numpy library, so it is recommended to install it using tools such as pip.

  3. Append the directory of simworks.py to the current directory and use the append() function to add the path with the interface module so that the import class can successfully retrieve the simworks API. Take the default software installation directory as an example for detailed explanation:

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

Linux

  1. This feature requires Python and the numpy library to be installed. If not, refer to the installation guide for your operating system to configure them.
  2. Make sure the AppImage file is executable
chmod +x ./appimage_file.AppImage
  1. Unzip using --appimage-extract option
./appimage_file.AppImage --appimage-extract
  1. Attach the directory of simworks.py to the current directory
import sys, os
sys.path.append("squashfs-root/api/usr/api/python/")

macOS

  1. This feature requires Python and the numpy library to be installed. If not, refer to the installation guide for your operating system to configure them.
  2. If it is not installed in Applications, open the SimWorks software .dmg image file, find a "mounted" virtual disk, and finally find Contents/api/python/.
  3. Installed to Applications, go to Applications and find SimWorks FD Solutions.app, then display the package contents, and eventually find Contents/api/python/.

Remote Invocation of Python API

The Python API architecture supports both local and remote invocation and is capable of operating across different operating systems. Remote invocation is implemented through client-server communication: the server program runs persistently and listens on a specified port, while the client establishes a socket channel to communicate with the server through this port. The client sends invocation requests to the server, which parses the requests, starts the fd_solutions locally to execute tasks, and returns the results to the client, enabling cross-platform remote invocation.

To establish two-way communication between the client and server, the server must first configure the communication port. Before the first run, follow these steps (the related script files are located in the /api/interop_server/scripts/ directory of the software):

  1. Run the generate_certificate script to generate a self-signed certificate. Follow the prompts to save the certificate file and retain the $(hostname)_server.crt file, which will need to be sent to the client later.

  2. Run the interop_server_start script to start the interop_server service.

Once the server setup is complete, the client needs to connect:

  1. Before the first run, obtain the $(hostname)_server.crt file from the server and import it into the client. Trust the server's self-signed certificate to establish an SSL-encrypted channel between the client and server.

  2. In the Python script, use the args parameter to pass the server's IP address and the port on which the interop_server is listening. Other script commands can be used as usual.

After usage, the server needs to be shut down:
Run the interop_server_stop script to stop the interop_server service.

Encrypted Connection Configuration

The above process establishes an SSL-encrypted connection by default. Users can choose whether to enable encryption based on their network environment:

  • In trusted local area network environments, encryption can be disabled to simplify configuration, eliminating the need to import CA certificates.
  • Both the client and server must either enable or disable encryption simultaneously; the configurations on both ends must be consistent.

In the Python script, the encrypted_connection parameter controls whether SSL encryption is enabled, and the ca_certificate parameter specifies the path to the CA certificate. Example code is as follows:

# Use encrypted connection and specify the CA certificate. The client will use both the system's CA certificates and the user-specified CA certificate.
args = {"hostname": "192.168.1.74", "port": 8088, "encrypted_connection": True, "ca_certificate": r"D:\windows\certs\name_server.crt"}

# Use encrypted connection without specifying a certificate. The client will use the system's CA certificates.
args = {"hostname": "192.168.1.74", "port": 8088}
# Or
args = {"hostname": "192.168.1.74", "port": 8088, "encrypted_connection": True}

# Do not use encrypted connection
args = {"hostname": "192.168.1.74", "port": 8088, "encrypted_connection": False}

Examples of how to use API

  1. Almost all built-in script commands ​​in SimWorks can be used as methods on your session object in Python. Methods defined in the SimWorks API have the same names as SimWorks built-in script commands and can be called directly after creating a session. See the following code for detailed implementation:
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")

Pythonapi_project.gif

  1. Data transfer between SimWorks and Python in the SimWorks interface is illustrated here. When launching the SimWorks Finite Difference Solutions using the Python API, a connection is established between the two environments. The workspaces are not shared. Instead, variables are transferred using an identical copy, with forward and backward transfers performed based on the conversion types defined in the getv() and putv() functions.

    The SimWorks API supports the following data types: Real/Complex/String/Matrix/Struct/Cell/Dataset (matrixdataset and unstructureddataset). See the following code for detailed implementation:

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")