Simulate 2D diffraction grating using customized diffractive DLL

  • 11 June 2020
  • 9 replies
  • 1896 views

Userlevel 6
Badge +2

In OpticStudio, currently we only support one dimensional grating. However, it's not difficult to simulate 2D grating. Here we will show an example using diffractive DLL.

You may compile it with the instructions or use the DLL file attached to this article. 

Before we start, here are some articles for required background knowledge that we will not repeat in this forum post.

  1. How diffractive surfaces are modeled in OpticStudio (KBA)

  2. How diffraction ray-tracing is calculated | Zemax Community(forum post)

  3. Custom DLLs in OpticStudio: An overview of user-defined surfaces, objects, and other DLL types (KBA)

  4. How to compile a User-Defined DLL (KBA)

Let's simply open the attached cpp file and observe how it works in non-sequential mode.

This example is mainly modified from the built-in sample \Documents\Zemax\DLL\Diffractive\diff_samp_1.c 

To compile the program as C++ code. We package the functions with extern 'C'.

 

200611-121820-image.png

 

In this example, we only want to return diffraction ray direction and its relative intensity. So setting data[31] = 1 is enough. If we also know the polarization state or the full eletric field value, we can use data[31] = 2.

 

200611-121919-image.png

 

Here assumes we want to simulate 5 orders in x and y direction, so there should be totally 25 orders from (-5,-5) to (5,5). Because currently OpticStudio only considers the diffractive DLL simulates 1D grating, we need to represent the 2D orders in 1D. Here we will only consider orders from 0 to 24, which represents (-2,-2) to (2,2). If OpticStudio requests orders other than this range, we return -1, which will result in an geometric error in OpticStudio. For this reason, when using this DLL, the Start Order should be 0 and Stop Order should be 24 in OpticStudio.

 

200611-122135-image.png

 

200611-122849-image.png

 

Then, we can decompose the 1D order into corresponding 2D orders.

 

200611-132541-image.png

 

When data[31] = 1, we need to return the value for phase derivative and phase accumulation.  

 

200611-141248-image.png

200611-132810-image.png

 

Note the phase derivative is same as what we described in page 3 in this forum post: How diffraction ray-tracing is calculated | Zemax Community

The phase (variable 'P') is simply accumulation of the phase assuming the phase at surfase vertex is zero.

 

200611-140955-image.png

 

In UserParamNames(), we define the efficiency for each diffraction order.

 

200611-141411-2020-06-11_14-13-23.jpg

 

Then simply read it to data[30], which is the relative intensity reported to OpticStudio!

 

200611-141623-image.png


9 replies

Userlevel 6
Badge +2

Attached is a example for user defined surface used in sequential mode. This is modified from the built-in us_grate.c. The concept is same as above, but with one main difference: there need to be two parameters Order X and Order Y to let users explicitly specify what order to trace. This is because in sequential mode, only one path can be traced at once.


Only two parts are changed.


1. Add two parameters for x directional periodicity.



2. Code added to consider for another periodicity in x direction.

T,M becomes Tx,Ty,Mx,My.

Adding code for dpdx. Just mimics dpdy and that's it!


Userlevel 7
Badge +3

Gotta say Michael, you are doing some seriously good work here. Well done!

Userlevel 6
Badge +2

Hey Mark, that's great to see your reply and I'm glad you like it!

In OpticStudio, currently we only support one dimensional grating. However, it's not difficult to simulate 2D grating. Here we will show an example using diffractive DLL.

You may compile it with the instructions or use the DLL file attached to this article. 

Before we start, here are some articles for required background knowledge that we will not repeat in this forum post.

  1. How diffractive surfaces are modeled in OpticStudio (KBA)

  2. How diffraction ray-tracing is calculated (forum post)

  3. Custom DLLs in OpticStudio: An overview of user-defined surfaces, objects, and other DLL types (KBA)

  4. How to compile a User-Defined DLL (KBA)

Let's simply open the attached cpp file and observe how it works.

This example is mainly modified from the built-in sample \Documents\Zemax\DLL\Diffractive\diff_samp_1.c 

To compile the program as C++ code. We package the functions with extern 'C'.

 

200611-121820-image.png

 

In this example, we only want to return diffraction ray direction and its relative intensity. So setting data[31] = 1 is enough. If we also know the polarization state or the full eletric field value, we can use data[31] = 2.

 

200611-121919-image.png

 

Here assumes we want to simulate 5 orders in x and y direction, so there should be totally 25 orders from (-5,-5) to (5,5). Because currently OpticStudio only considers the diffractive DLL simulates 1D grating, we need to represent the 2D orders in 1D. Here we will only consider orders from 0 to 24, which represents (-5,-5) to (5,5). If OpticStudio requests orders other than this range, we return -1, which will result in an geometric error in OpticStudio. For this reason, when using this DLL, the Start Order should be 0 and Stop Order should be 24 in OpticStudio.

 

200611-122135-image.png

 

200611-122849-image.png

 

Then, we can decompose the 1D order into corresponding 2D orders.

 

200611-132541-image.png

 

When data[31] = 1, we need to return the value for phase derivative and phase accumulation.  

 

200611-141248-image.png

200611-132810-image.png

 

Note the phase derivative is same as what we described in page 3 in this forum post: How diffraction ray-tracing is calculated.

The phase (variable 'P') is simply accumulation of the phase assuming the phase at surfase vertex is zero.

 

200611-140955-image.png

 

In UserParamNames(), we define the efficiency for each diffraction order.

 

200611-141411-2020-06-11_14-13-23.jpg

 

Then simply read it to data[30], which is the relative intensity reported to OpticStudio!

 

200611-141623-image.png

Hi,Michael!

      I meet a problem that when setting  data[31] = 2 in the built-in sample \Documents\Zemax\DLL\Diffractive\diff_samp_1.c and output the new DLL ,  Diffraction Grating with the new DLL in which data[31] = 2 can not receive beam rays, namely the light beams can not reach the diffraction grating.

Why it become like this?

 

      Looking forward to your reply! Thank you !

 

zhouqing

 

Userlevel 6
Badge +2

Hi Zhouqing,

Thank you for reply. Setting data[31] = 2 should be not a problem. The problem probably happens at your other code. Could you send your question to support inbox so we can help to further look at your question? Thank you!

Michael

 

 

 

Hi Michael!  Thank you very much for your reply!
 
   I have send my question to the mailbox Zemax Community <community@zemax.com>. In case of encountering problems when sending the email,I also present my questions in more detail as below:
           Firstly, I just change the code data[31] = 1 to data[31] = 2  in the built-in sample \Documents\Zemax\DLL\Diffractive\diff_samp_1.c and output the new DLL.
           When I use the new DLL in Diffraction Grating in NSC mode, the light beam can not reach the grating. Maybe there are something wrong when I changed the code in the built-in sample \Documents\Zemax\DLL\Diffractive\diff_samp_1.c.
 
           Then I review the DLL in ZEMAX Knowledgebase(KBA), there are some keys as shown below:
             s?func=mbox:getMessageData&sid=g0bAX7p2j080qEP6D49TO35KFnAAqwQk&mid=AEgAlwBsJLADUX9G95avgqpG&Part=3
               s?func=mbox:getMessageData&sid=g0bAX7p2j080qEP6D49TO35KFnAAqwQk&mid=AEgAlwBsJLADUX9G95avgqpG&Part=4
           According to the above content, If I set the code data[31] = 2  , then the data[35]~[37], and data [40]~[45] should also be calculated or set. For the further code setting of  data[35]~[37] and data [40]~[45] , I still feel  a bit difficult to input the perfect new codes as I am not familiar with the C++ and ZEMAX Programming logic for Diffractive DLL.
 
            If Michael could give me some help or suggestions for the above tricky situation as I meet.
 
            Looking forward to your reply!   Thank you!
 
Zhouqing

 

Userlevel 6
Badge +2

Hi Zhouqing,

I’m sorry for confusion, but could you try to create a case via the following link.

https://support.zemax.com/hc/requests/new

Or, you can also send the question to the support box: zemax.support@ansys.com

Both method will reach to the same team. Using the link is suggested as you will be able to check the status of the tickets. Please note you will need to create a Zemax account in order to open a ticket. Please let us know if you have any issue. Thank you.

Thank you, Michael!

 

I have send my question to the support box: zemax.support@ansys.com

 

At the same time, I also present my questions again as below:

 I just change the code data[31] = 1 to data[31] = 2  in the built-in sample \Documents\Zemax\DLL\Diffractive\diff_samp_1.c and output the new DLL.When I use the new DLL in Diffraction Grating in NSC mode, the light beam can not reach the grating. Maybe there are something wrong when I changed the code in the built-in sample \Documents\Zemax\DLL\Diffractive\diff_samp_1.c. 

 

  Then I review ” Custom DLLs in OpticStudio: An overview of user-defined surfaces, objects, and other DLL types”in ZEMAX knowledgebase (KBA), there are some keys as shown below:

     “ If data[31] equals 2, it must also calculate data 35-45, the complete output ray data. The DLL should return 0 if successful, and -1 if it encountered an error. For a complete description of all the data items passed between ZOS and the Diffraction DLL, please see the example {Zemax}\DLL\Diffraction\diff_samp_1.c.

     Note when the data[31] is 2, the power of diffracted ray is mainly calculated by the returned field data in data[40-45]. However, the data[30] can still affect the ray-tracing in two ways. One is that OpticStudio will use data[30] for estimating the Lost Energy, which shows in the Ray Trace dialog, during raytracing. One is that the diffractive ray will stop tracing if the value in data[30] is smaller than Minimum Relative Ray Intensity in the System Explorer.

           According to the above content,  If I set the code data[31] = 2  , then the data[35]~[37], and data [40]~[45] in the built-in sample diff_samp_1.c should also be calculated. For the further code setting of  data[35]~[37] and data [40]~[45] , I still  feel  a bit difficult to write the perfect new codes as I am not familiar with the C++ and ZEMAX Programming logic for Diffractive DLL.

            If Michael could give me some help or suggestions for the above tricky situation as I present.

            Looking forward to your reply!   Thank you!

 

Zhouqing

Thanks for the tutorial Michael, very informative.

 

I have tried to implement a similar code that the one you provide here but to also analize the reflection modes of a simple 2D grating. In my case I restricted the Tranmission and Reflection modes to (-1,-1) → (1,1). 

 

In my case the call for input parameters looks like this:

 

 

I have tried to modify data[11] value to accomodate either tranmission and reflection modes asking which mode is being calculated as follows:

 

 

but this proven not to work. Zemax only calculated the transmissive modes and all the reflection modes are there but as simple reflection from a glass surface.

 

 

Could you please give me a hint on how to implement this properly?

 

Thank you!

Reply