This article introduces a simple optical optimization workflow leveraging PyAnsys capabilities. We will optimize the data contained inside an optical property to achieve a global reflectivity target. The workflow is based on PySpeos, which is responsible of updating the optical property in the simulation, in conjunction with PyOptiSLang, which orchestrates the optimization process.
Overview
Understand the simulation workflow and key results
PyAnsys is a powerful toolkit of Python-based modules designed to interface seamlessly with Ansys software. It empowers users to automate complex simulation tasks and streamline engineering workflows through code, enhancing both performance and precision. By embedding Ansys capabilities into larger computational ecosystems, PyAnsys helps accelerate development cycles while reducing operational costs.
In this example, we perform a very simple material optimization. The objective is to tune the refractive index of a volume material property to achieve a given reflectivity of 70%, measured in intensity.
The design update for the optimization will be handled by PySpeos, while the optimization process will be setup using PyOptiSLang.
The sample project (.speos + .scdocx files) and the python scripts can be found inside the example folder provided in this article.
Prerequisites
- Python 3.10 or higher: Make sure you have Python installed on your system.
- PyOptiSLang: Install latest release from PyPi to your python environment with the following command:
pip install ansys-optislang-core
- PySpeos: Install latest release from PyPi to your python environment with the following command:
pip install ansys-speos-core
- Ansys Speos 2025 R1 or higher
- Ansys optiSLang 2025 R1 or higher
Note: Ansys Speos installation is required because there is no Speos result lab service available in the 2025 R1 PySpeos release. A local Ansys Speos installation is needed to use the Speos Virtual Photometric Lab application in this workflow.
Step 1: Design iteration using PySpeos
In a dedicated script, we developed a series of functions that perform a specific workflow. We first apply numerical offsets to the real and imaginary parts of the nominal refractive index of the metallic sample. Once the numerical offset is applied, we write the material file and replace it in the simulation. Finally the Speos simulation is executed and we extract the total reflectivity out of the intensity result.
Step 2: Setup the optimization using PyOptiSLang
In the main script, we setup a One-Click Optimization (OCO) workflow with PyOptiSLang, from the creation of the nodes (OCO node, MOP node, etC..) and the setup of the variation analysis (parameters and responses registration, ranges, criteria, etc..) to the execution of the optimization and results analysis. The core update of the design is done by calling the dedicated script from previous step.
Run and results
Instructions for running the model and discussion of key results
Step 1: Design iteration using PySpeos
- Open the script speos_solve.py in your Python environment.
The script’s purpose is to update the sample project based on external parameters.
In this project, a flat sample is illuminated by a perfect 1W Lambertian source with a flat spectrum.
The sample has a nominal metallic material (complex refractive index). The refractive index data is based on the data contained in Base_silver_design.csv (obtained from ReflectiveIndex.INFO).
We measure the sample reflectivity using an intensity sensor on top of the sample. The principle of this optimization will be to offset independently both the real and imaginary parts of the refractive index of the sample to adjust the total reflectivity and achieve a target of 70% reflection.
The script follows the following steps:
-
Connection to PySpeos server: Inside the calculate() function, a Speos client is created via connecting to a PySpeos server. In this example, a local host with port number 50098 is used, users should modify this part with their own server information, as explained in this link . Each design parameter is then passed to the created Speos client to be processed and simulated.
- Design update: Inside the speos_simulation() function, the exported Speos file is loaded in the PySpeos client. We developed an additional function, write_material_file() , to update the refractive index values in the new_mirror.material file by applying independent numerical offsets to the real and the imaginary parts.
Next, the simulation with the new material is computed in CPU. Users can choose to run the simulation in GPU instead, by changing the line 153 from compute_CPU() to compute_GPU() .
-
Result evaluation: Speos result extraction is executed by calling the open_result() function. Speos Virtual Photometric Lab is used to open the generated Speos result and extract the measurement results.
Step 2: Setup the optimization using PyOptiSLang
- Open the main_optimization_study.py file in your Python environment.
The script performs a One-Click Optimization (OCO) through the following steps:
-
Definition of the variation analysis boundaries: Within the get_variation_analysis_boundaries() function, the user can tune the following items.
-
- parameters and distributions : in this example, we have a continuous numerical offset for the real part of the refractive index between 0 and 6 and another one for the imaginary part between -1.5 and 3.5.
- responses : in this example, the output parameter is the total flux reflected by the sample on the intensity sensor.
- constraints and objectives : our criterion measures the numerical distance between the output flux and the target of 70% reflection. We want to minimize this value as an objective.
- the number of designs to be calculated for the OCO (100 designs in this example).
-
-
optiSLang project creation and workflow setup : we create a new optiSLang instance and setup the workflow within the create_workflow() function. This includes:
-
- creation of the OCO system with a proxy solver node
- creation of the MOP node to identify important parameters (this node can be reviewed using optiSLang postprocessing)
- registration of the parameters and definition of the parameter settings (e.g., distribution function, mean value, …)
-
Within criteria_definition() we set the constraints in optiSLang. Optionally, we can save the optiSLang project to keep the results and the databases. You can find additional examples on how to create an optiSLang workflow as well as the API documentation on the official website ( API reference — PyOptiSLang )
-
optiSLang project execution and result outputs: In this step we start the optiSLang project execution in batch mode. As the project runs, optiSLang samples all designs and send them to the proxy node. From there we receive all design information (e.g., design ID, parameter values), call a Speos instance and pass the design information to the second script, speos_solve.py , to calculate the optical performance for each design within speos_simulation() . After each design, we collect the output value and print it in a summary. At the end of the optimization, the best design is printed out for the user.
- Make sure the provided Python scripts and the Direct.1.speos folder are in the same directory. If not, you will need to modify the path to the Direct.1.speos file in speos_solve.py .
- Choose the correct port number for Speos_RPC server.
- Launch ‘main_optimization_study.py' in your Python environment and run the script. The terminal will display the progress of the optimization (calculated design) along with the results. The analysis ends after the defined number of designs were completed (per default 100 designs).
- After the defined number of designs were completed, a summary will be prompted illustrating the best design after the OCO.
In this example, we get very close to the target (70,09% reflectivity) with the best design.
Important model settings
Description of important objects and settings used in this model
Design update in PySpeos: The PySpeos script can be easily changed to match your own goals. The main objective of this script is to change the content of the Speos simulation based on the pre-defined input parameters. The functions written in this script are only here to support this goal and have smaller sub-objectives (writing the material file, executing the simulation, reading the results). You can use this thought process as a template to update your own Speos simulation with any desired input parameter using PySpeos.
Optimization with PyOptiSLang: This script defines a simple One-Click-Optimization workflow. Broader and more advanced workflows including robustness, sensitivity analysis, can also be setup in a similar way.
You may also simply tune the OCO definition by changing the number of designs to run, adding more inputs or outputs parameters, etc.
Taking the model further
Information and tips for users that want to further customize the model
This example is on purpose very simple to explain the core concepts of performing a headless optimization using PySpeos and PyOptiSLang. The modification of the refractive index of a material is a pure theoretical approach to reaching a specific reflection target but it not matching actual existing materials.
A more concrete approach to this example could be to iterate on a list of existing materials, each material associated with a “cost” parameter. The optimization would then do a trade-off between multiple objectives: reaching the best performances on the reflectivity and lowering the cost price of the system as much as possible.
Additional resources
Additional documentation, examples and training material
Starting from Ansys 2025 R1 release, PySpeos and PyOptiSLang are available. You can find detailed installation instructions and user guides at the following links: