Dynamic workflow between Lumerical RCWA and Zemax OpticStudio

Updated: 2023-May-5

In this article, a dynamic workflow using Zemax OpticStudio and Lumerical RCWA for accurately simulating 1D/2D gratings in a whole optical system is introduced. The methodology will be first briefly introduced. Then details about how to set up the system will be explained.

Note: This feature is only available in Ansys Zemax OpticStudio Premium/Enterprise.

Authored By Michael Cheng, Yihua Hsiao


Article Attachments

The DLL in this article receives regular updates. Read more about the latest updates here: Zemax - Lumerical RCWA dynamic linking updates & known bugs and download the latest version here: DLL: Dynamic Link RCWA


Previously, OpticStudio provided a 1D RCWA plugin for 1D grating simulation. In this article, a similar but much more powerful workflow based on a dynamic link from Zemax OpticStudio to Lumerical RCWA is introduced.
In this workflow, designers build the macroscopic optical system in Zemax OpticStudio and build the microstructure of the grating in Lumerical. The simulations in both software are seamlessly connected. During the raytracing process in Zemax OpticStudio, if a ray hits the grating, Lumerical RCWA will be automatically called for solving the field response and providing return data.
This workflow has several advantages:

  1. Complex 1D/2D gratings modeling: With a powerful geometry editor, users can easily build and simulate arbitrary 1D or 2D gratings.
  2. Fast prototyping: The parameters in Lumerical are exposed in OpticStudio. Any change made in OpticStudio can automatically trigger Lumerical to calculate updated data for new grating shapes and return the new data. There is no need to import and export the data.
  3. Optimization: Users can easily define their customized parameterized model in Lumerical and optimize the grating shape considering the whole system's performance.
  4. Import & Export grating shape: The workflow supports standard import and export grating geometry in file formats of STEP, STL, and GDS II.

System requirements

To use this dynamic workflow, both Zemax OpticStudio and Lumerical need to be installed on the same PC with Windows as the operating system.

Zemax OpticStudio edition must be Ansys Zemax OpticStudio Premium or Ansys Zemax OpticStudio Enterprise. Legacy Zemax OpticStudio is not allowed. Both Lease and Paid-Up Ansys Zemax licenses are valid to use this tool.

Lumerical must have an FDTD license, and the edition must be 2023 R1.0 or later.

Please see the section “Legacy versions of DLLs”, at the end of the article, to find more information if you have used any old version of DLL built in 2022.

Static vs. dynamic workflows

It may be worth mentioning that there are two existing workflows to exchange data between Lumerical and OpticStudio. One is the dynamic workflow that we are going to introduce in this article. Another is the static workflow which works in a different way. The two workflows have different flexibilities, and no one is superior to the other. Users should consider which one to use based on their design case.


Preparing the grating file in Lumerical

The grating geometry at each periodic box needs to be defined in a Lumerical .fsp file. In the dynamic workflow, OpticStudio would automatically call Lumerical fsp file, apply the parameters sent by OpticStudio, and then calculate the electric field response. The length of the fsp name is recommended to be less than 50.

Several .fsp files simple grating geometries are provided in the attachments of this article, as shown below.

Users can also customize their own parametric models if they follow the rules below.


A structure group called “topcell” must be defined in the .fsp file.


Structure group is a type of object groups in Lumerical. A quick explanation is that structure group can be considered as a composite object that is built by many basic structures, such like Polygon and Rectangle. When two structures overlap, the priority is determined by the mesh order or the object. More information can be found in Lumerical knowledge base.

Structure Groups - Simulation object

Understanding mesh order for overlapping objects

In structure group in Lumerical, we can define “Properties” and “Script”. The properties are like the parameters of an object. We can write the script so it will read the property values and update the basic structures in the group. The script is quite flexible where it can even add/delete structures inside. This makes the structure group itself like a new object that you set up its shape, material via the Properties.



Structures in topcell

In the topcell group, in addition to the grating structures, we must define two Rectangle objects to represent the materials at positive and negative sides. They should be centered at (x=0,y=0) and their x and y sizes should be larger than period_x and period_y. They should be at the top (+z) and bottom (-z) outside of the “simulation region” as shown in the following picture.

The name of the two Rectangle objects can be arbitrary. To make is each to read and neutral, in our provided examples, we use “negative_z_material” and “positive_z_material”.


Note that, by "simulation region", we mean the region defined by uppermost and lowermost layer in the RCWA object settings. Ths is the place where we consider the structure in the RCWA calculation. It's important to know the actual RCWA object size must be slightly larger than the simulation region. In dynamic link, the RCWA object region will always to 0.1 µm larger than the simulation region. Therefore, we suggest to set the positive_z_material and negative_z_material to be 0.2 µm in their z size.


Properties of the topcell

We must define 4 user properties as below red-boxed. These user properties will be set up by the dynamic link. And in the script, we will read their values to modify the structures in the group. The 4 properties to use are as below.

* period_x, period_y: Periods in x and y directions

* n_neg, n_pos: Indexes of substrate (n_neg) and superstrate (n_pos)


There could be more properties. If we make their name with the form p#_***, note # is number and *** is any string, then these parameters will be read by the dynamic link and shown in the OpticStudio UI.


Script of the topcell

We can define scripts in the topcell as shown below.


Defining scripts is not optional, there are some required scripts we must write. We suggest users open the sample file provided by this article and use the script as a template.

Here are required scripts:

  • We must set the refractive index of the positive_z_material and negative_z_material with the variables n_pos and n_neg.
  • If the grating’s size in z direction changes, which means the simulation zone changes, we also need to modify the position of positive_z_material and negative_z_material. The thickness (size in z) of the two objects must be larger than 200 nm.
  • The script must make sure to generate the complete geometry of the grating in the range x = -period_x/2 ~ period_x/2 and y = -period_y/2 ~ period_y/2. Note this sometimes means we need to repeat the same structure twice or more times in order to have a full geometry in the periodic range.
  • Finally, optionally, users can define more user properties which is used by scripts to dynamically change the grating geometry based on the corresponding values. As shown below is an example we also provided in the attachments.
  • image9.pngimage10.png

RCWA Object

Here only the required settings in the RCWA object will be explained. More details about this solver object can be found in this article: RCWA Solver - Simulation Object – Ansys Optics

The final requirement to this fsp file is a RCWA region must be defined. This can be added by clicking “Simulation > Add RCWA”.


The only settings users must carefully check are the interfaces. This setting is related to the z-direction mesh numbers. If users don't set this value correctly, the simulation result could be inaccurate. The settings of the RCWA can be accessed by right-clicking on the object and selecting Edit object.


Before editing the interfaces, make sure you have turned on the mesh view of the simulation region.


There are two ways to set up interfaces. Users can directly define the absolute positions, but this means the highest and lowest position of the grating cannot change. The other way is to use reference positions. In this way, when you edit the parameters of the gratings from the OpticStudio UI, the interface position will automatically update when the grating shape changes.



Users can try to set the value of the interfaces, the larger interfaces value also means more mesh number.

Ignorable parameters

The following is a list of parameters that will be automatically controlled by the dynamic link and users don't need to change their value in the .fsp file.

  1.  p#_**** parameters in topcell structure.
  2.  period_x, period_y, n_neg, n_pos in topcell structure. period_x and period_y follow the settings in OpticStudio UI. n_neg and n_pos are decided by the Material settings in OpticStudio.
  3. RCWA object's x, y, z sizes. The sizes x and y follow the period_x and period_y settings in OpticStudio UI. The size z is decided by adding 0.1 µm margin to the uppermost and lowermost layer setting in RCWA object.
  4. All settings in excitation (incident ray) in RCWA object. These will be based on the incident ray's data in OpticStudio.
  5. K-space discritization settings in RCWA object. See explanation of "Max Order" below.

How to change x/y mesh 

We cannot directly edit them, and in general, it's not necessary to change the x/y direction mesh. But if users want to change the mesh size, the values are automatically determined by a number of k vector domains. If users increase the k numbers, the mesh number will also be increased. 

Set up the gratings in Zemax OpticStudio

In OpticStudio, to set up a grating, it’s suggested to use one of the following 3 objects: Diffraction Grating, User Defined Object (DiffractionGrating.DLL), and User Defined Object (Polygon_grating.DLL). The Polygon_grating.DLL file is not provided in the installation folder by default, but it can be found in the article How to simulate exit pupil expander (EPE) with diffractive optics for augmented reality (AR) system in OpticStudio: part 4.

Note the grating is at Face 1 for these suggested objects.


After adding one of the above 3 objects, we then use the Object Properties…Diffraction tab to define the plugin DLL “Lumerical_RCWA_dynamic_link.dll” (or "Lumerical_sub_wavelength_dynamic_link.dll”)for the added diffraction object. This DLL creates the link to Lumerical, and you will see it includes several parameters that we are going to explain in the next section.


Parameters in Zemax OpticStudio

Shown below is a table describing all the parameters this DLL provides:

Parameter name



File Name

Shows all the files with .fsp as extension in the folder “\Zemax\DLL\Diffractive\”.


+Period/-Freq X (µm), +Period/-Freq Y (µm)

The period of the grating in x and y directions.


Max Order X

Max Order Y

The number of diffraction order (harmonics) to be considered in the RCWA solver.

A rule of thumb:


Link Lumerical

0: No connection to Lumercial, and the Lumerical window does not be opened

99: Connect to Lumercial, and the Lumerical window will be opened automatically

Any number other than 0 and 99: Connect to Lumercial, but the Lumerical window does not be opened



These are dynamically linked to the parameters defined in grating file (.fsp)


# Layer



Rotate Grating

This allows users to rotate the grating’s periodic direction.




Set it to 1

Error Log

Setting this to 1 enables the plugin to export log data.


Order Filter #

This allows users to control which order of diffraction rays will be traced.


Stochastic Mode

Setting this to 1 means rays don’t split at the grating. Instead, it diffracts a single input ray into one output order through probability.

Use it when the ray splits too many times in the system

Interp. Pre-sampling

This controls how many incident angles the plugin should request at each call.

No more than 10

Fast 2D out-coupler

This parameter is designed to speed up the calculation for 2D out-coupler used in AR waveguide.



Start Order X, Y and Stop Order X, Y

The DLL will only consider diffraction orders in the range between -Max Order ~ +Max Order. The value should be large enough to include all orders of interest. However, note it’s not meaningful to have the range of X/Y Start/Stop Order to be outside of the range defined by -Max Order X/Y ~ +Max Order X/Y. If users set it so, OpticStudio will try to ask the DLL for data with higher order than Max Order but then the DLL will simply return no power for the output rays.

File Name

This specifies which file to read for the grating geometry. Note the file must be put in the specified folder “\Zemax\DLL\Diffractive\” to be shown in the list.


+Period/-Freq X/Y (µm)

The period of the grating in x and y directions in microns. It it’s negative value then it’s interpreted by the DLL as frequency where the unit is (1/µm).

Max Order X, Y

This specifies how many harmonics (orders) are considered in the RCWA solver. When both X, Y are >= 0, Max Order Y is ignored and a circular area in harmonic space (diffraction order) is sampled, as shown below in the left-side image. When X < 0 or Y < 0, rectangular area is sampled in harmonic space. The half width in x and y directions of the rectangular area are the absolute value of Max Order X and Y, as shown below in the right-side image.


Link Lumerical

If this parameter is 0, OpticStudio will stop accessing Lumerical for ray trace data.

  • Rays will stop at the grating.
  • User defined parameter name will not show in the UI.

If this parameter is any number other than 0 and 99, OpticStudio will perform the call to Lumerical and the Lumerical window will not be opened.

If this parameter is 99, OpticStudio will perform the call to Lumerical and the Lumerical window will be opened.

This is useful when users are setting up the system, as they can temporarily stop the link to Lumerical and avoid delays in the user interface caused by the dynamic link.


p1 ~ p20

These are parameters that will map to the user properties in Lumerical .fsp file. When we change the value of these parameters, the corresponding user properties will be automatically updated in the Lumerical file.


Order Filter File#

This parameter allows users to define which order to be considered during raytracing. Physically, when a ray hits the grating, all possible diffraction rays should launch. However, sometimes we may want only some orders to be launched for efficiency.

When this parameter is set to a positive integer, it will read the predefined text file in the folder “\Zemax\DLL\Diffractive\”. For example, if it’s set to 8, then the DLL searches for filter_8.txt.

The format of the text file is as below

* First line must be an odd number n.

* The next are two n x n blocks for reflection and transmission orders.

* 1 = allowed, 0 = not allowed.

* If the file number is negative, it means always re-read the filter file. Otherwise, the filter data is read and aved in RAM for further access.


# Layer

This parameter is deprecated. The number of layers should be set up in in the RCWA object tin the .fsp file.

Rotate Grating

This is useful if users want to change the rotation of the grating but not the aperture shape of the grating.


Interpolation & Interp. Pre-sampling

For efficiency, OpticStudio caches calculated data in memory. It doesn’t call Lumerical to calculate for the same data at the same incident angles. Setting Interpolation = 1 turns this feature on.

Interp. Pre-sampling tell the dynamic link to get more calculation data from Lumerical at each of the call. There is no a standard answer to how large this should be. This is usually most useful around 5~10, but some experiment is needed to understand which value is more adequate for each of the different system.


Stochastic mode

If this is set to non-zero, rays don’t split when hitting the surface. Instead, the ray will be randomly diffracted into one order, as shown below. This is useful when one ray will hit the diffractive surface multiple times and split into too many segments.


Error Log

If this is set to 1, the DLL will export a log file in the folder “Zemax\DLL\Diffractive\” as shown below. This is useful when seeing any geometric error coming from the Lumerical Dynamic Link DLL.


Fast 2D out-coupler

When this parameter is set to non-zero, it assumes a hexagonal grating. When a ray hit the grating in an orange region in the k-space as shown below, it will try to calculate data in all related orange regions.



How dynamic link load settings from OpticStudio to Lumerical

Here is a process how the dynamic link load the settings in OpticStudio UI and write in Lumerical for user's reference.

  1. Copy "period_x", "period_y", "p#_****" from the DLL UI in OpticStudio to the properties with same name in structure "topcell" in Lumerical.
  2. Set up topcell's properties "n_neg" and "n_pos" in Lumerical based on the refractive index at the two sides of the grating face in OpticStudio.
  3. Set up the size of RCWA object. The x, y positions are always at (0,0). The x, y spans are set to the period x, y based on the OpticStudio's UI settings. The z min and max are automatically set based on the minimum and maximum interface position, extended by 100 nm outward. For example, if the smallest and largest interface position is -1.0 µm and 5.0 µm, then the z min and z max of the RCWA object is changed to -1.1 µm and 5.1 µm.
  4. The "propagation direciton" setting in the RCWA object > General is set up based on the requested ray's information in OpticStudio.
  5. Set up the RCWA object > Excitation based on the on the requested ray's information in OpticStudio. The "incident angle" is set to "table". The requested theta and phi's are set based on the interpolation method from the dynamic link DLLs. The "sample spacing" is set to "custom". The "custom frequency samples" is set to the incident ray's wavelength in OpticStudio.
  6. Set up the RCWA object > Solver. The "k vectors domain" and "max number k vectors"/"max number ku/kv" are set up based on the parameter "Max Order X/Y" in the OpticStudio UI.
  7. In RCWA object > Results, the "report field amplitudes" is set to checked.

Tips and cautions

Update: None

It’s suggested to set “Update: None” in the non-sequential editor. This can avoid crashing during parameter changes.


Lumerical FDTD window

When using this workflow, the Lumerical FDTD window is always automatically opened. Make sure you don’t accidentally close it. This will cause the program to crash.

Use same .fsp file

It is most effective to use the same .fsp file for multiple grating objects when the grating is of a similar structure. This is demonstrated in the system shown below in the upper picture. This is true even if all these grating objects have different parameters in the Object Properties…Diffraction tab. Do not duplicate the .fsp files and apply different .fsp files to different grating objects. The plugin creates a calculation cache for each of the .fsp files. If we duplicate the .fsp multiple times, then the plugin will not know they are the same source .fsp and cannot organize the data in the most efficient way.



If you optimize using OpticStudio’s optimizer, you must first run local optimization once and then use Hammer for global optimization. Also, it’s suggested to use Orthogonal Descent instead of DLS.


How the grating is located on the object

This section is supposed to help if you have questions similar to below when setting up the grating in the system.

“Where is substrate/superstrate?”

“Why are the index at two sides exchanged after tracing rays?”

To correctly set up the grating in the system, there are a few important points:

  1. The grating is located on the Face 1 of object.
  2. Both Lumerical and Zemax OpticStudio object have their own coordinates which are linked.
  3. The materials at -z and +z infinite half space are automatically determined by OpticStudio.
  4. The substrate can be at -z or +z side.

The first concept is that grating is always on the Face 1. Although, there could be exceptions, the grating is normally on the Face 1. If needed, we can check Help File to know the definition for any specific object. Note a “face” is basically a thin surface with no volume. The grating is assumed to be a surface property in our simulation.


The second concept is about coordinates in OpticStudio and Lumerical.

We can check coordinate of an object in OpticStudio by checking the “Draw Local Axis” in Object Property > Draw section, as shown below.


On the other hand, Lumerical FDTD also has a coordinate system. The coordinate system in Lumerical should exactly match to the object coordinate in Zemax OpticStudio, as shown below. The two coordinates in Lumerical and on OpticStudio object are same.


Another important thing to mention is that the refractive indexes at two sides (n_neg and n_pos) of the grating are automatically set up by the dynamic link plugin based on the object settings in the OpticStudio. As shown in the following picture, the value of n_neg and n_pos are different with different system set-up.

Note the following picture also shows how the coordinate systems between Lumerical and OpticStudio should really match. Also, although the coordinate below only shows x and z axes, this rule actually works to fully x,y,z all axes. It’s important to always check if the coordinate system in Lumerical and OpticStudio match to what the designer expected.


In the example .fsp files attached in the article, the index of n_pos will be assigned to the rectangle object “positive_z_material” in Lumerical and the index of n_neg will be assigned to “negative_z_material”, by the Lumerical script defined in the structure group “topcell”.


In above, when we say the index of grating of object or other object in OpticStudio, we mean whatever users assign in the column “Material” as shown below. If the n_neg or n_pos are from any object, then it’s from the environment default, which is 1.0.



DLL version vs. Lumerical version

The following table shows the relationship between the versions of the DLL and Lumerical. Most of them are neither forward compatibility nor backward compatibility. 

Dynamic link DLL name Lumerical ver. Note

2022 R2.3
2022 R2.4

The very first version of the dynamic link.
lumerical-sub-wavelength-dynamic-link-2023R1.dll 2023 R1

* Parameter "Link Lumerical" now support value of 99, which opens a Lumerical window as before. When it's set to 1, Lumerical window will not show.

* A new parameter "Fast 2D out-coupler" is added which makes EPE design faster.

* There are some differences when setting up a .fsp file for dynamic link:
  1. No “tag” parameter
  2. Must add “RCWA” object
  3. Designers need to carefully set up the Interfaces in RCWA object.


2023 R1.2


2023 R1.3


The version of the Lumerical can be found in the title of the software as shown below.

The version of the DLL is directly in the file name. Users can clearly know which DLL is used when looking at the UI. The version of OpticStudio itself is not critical. However, to get latest version of the DLL, users need to download and install the latest OpticStudio. For example, to get "lumerical-sub-wavelength-dynamic-link-2023R1-2.dll", users need to download and install Ansys Zemax OpticStudio 2023 R1.02 from support.ansys.com or www.zemax.com.



Here are some steps that users can check if seeing any problems.

    1. Make sure the version of the DLL and Lumerical are matched. See the section "DLL version vs. Lumerical version" above.
    2. Check the list of known and solved bugs in this community post: Zemax - Lumerical RCWA dynamic linking updates
    3. Check software edition and license type: Lumerical must has a FDTD license. OpticStudio must use Ansys license forPremium or Enterprise edition.
    4. Make sure the parameter "Link Lumerical" is set to 1, which makes DLL linking to Lumerical.
    5. If setting "Link Lumerical" to 1 doesn't work, restart OpticStudio, set the "Link Lumerical" to 99, and see if a Lumerical window is opened. This is useful to check what happen when the dynamic link editing the grating.
    6. Set the parameter “Error Log” to 1 and the DLL will export error to \Document\Zemax\DLL\Diffractive\lumerical-sub-wavelength-dynamic-link.log
    7. The filename of the .fsp file can't be logner than 56 characters.
    8. If simulation result is not accurate, check whether the mesh number in the Lumercial UI is many enough. See the above explanation about interfaces in the section "RCWA region" for the mesh in z direction, and the section "How to change x/y mesh " for the x and y directions.
    9. In order to get the converged result, the 'Max order' setting in the OpticStudio dynamic link DLL UI should be large enough. Note the higher these 2 numbers are, the accurate the result is, but the longer the simulation time will also be. See the section "Max Order X, Y" above for more details.
    10. The mesh refinement in RCWA solver settings is suggested to be “Conformal Variant 0”. If it’s metal,  “Conformal Variant 1” is suggested.
    11. If "interfaces reference position" is used and there are two interface overlap, users need to be careful about the "type", which should be either "MAX" or "MIN". Selecting the wrong reference interface may cause nothing drawn as shown in the right side of the following picture. More details about interface settings can be found in RCWA Solver - Simulation Object – Ansys Optics.

Diffractive DLL Setup Assistant

In attached download file, users can find a small tool to help users setting up DLL parameters in a more convenient way. This is mainly useful when we need to set up multiple objects and parameters. Please save the Diffractive_DLL_Setup_Assistant.exe to Documents\Zemax\ZOS-API\Extensions folder, and open this tool from the OpticStudio UI (Programming > User Extensions > Diffractive_DLL_Setup_Assistant.exe).

Here is a quick user guide about the tool.

  1. The cell "From Obj" should be a single integer for object number we want to load DLL parameter settings.
  2. The par# is a string only including integer, comma, dash, and spaces. Integers are separated by comma. Dash is used to represent a range of integers.
  3. By cliking the button Load Par#, all the parameter numbers from the object defined by "From Obj" will be written in Par# cell.
  4. Par Val is a string only including numbers, comma, and spaces. Numbers don't need to be integer and are separaterd by comma.
  5. By clicking the button Load Values, the value of parameter number defined by cell Par# in object defined by cell "From Obj" will be collected and written in cell Par Val.
  6. The To Objs is a string works similar to Par#. We can define one or multiple objects that the 3 buttons "Set MCE", "Set paraemters", and "Copy paraemters" will use for target.
  7. By clicking the button Auto Detect, the tool will automatically collect all objects that uses same DLL as the object defined by cell "From Obj" and write them in the cell To Objs.
  8. By clicking the button Set MCE, we can create a series of multi-config operands that load the diffraction DLL parameters for objects defined by "To Objs" and its parameters defined by "Par#".
  9. By clicking the button "Set paraemters", the tool will use the settings in "Par#" and the corresonding "Par Val" to set up the DLL parameters for the objects defined by "To Objs".
  10. By clicking the button "Copy parameters", the tool will copy the DLL parameter defined by "Par#" from the object "From Obj" to the objects "To Objs".
  11. By default all above operation will only consider refelct DLL parameters. When "Also Set Transmission" is checked, the transmission parameters will also be set up.
  12. There are 3 shortcuts at the right side of the step 1 block. All 3 will set Par# to 5. Link Lum On (1) will set Par Val to 1. Link Lum On (99) will set it to 99. Link Lum Off will set it to 0.


Open the attached “Demo_simple_grating_test.zar” in OpticStudio. Then, go to the object’s Diffraction property settings. Change the Link Lumerical parameter to a non-zero value and update the 3D Layout in the system.


The Lumerical FDTD window is automatically linked, and the 3D Layout will look like the below:


If we trace rays, we can see the result in the detector is as below:



From here, users can try to use other grating files and modify the user parameters to see how the geometry is automatically changed.


Was this article helpful?
2 out of 2 found this helpful



Article is closed for comments.