Skip to main content

Hello.



I guess my question is fairly straight forward. However, I am not very used to any optimization procedures, so any help will be appreciated.



Assuming I have a source and a detector, and some surfaces inbetween in a non-sequential setting. I need to write a merit funtion that maximizes flux on the detector - but only for rays hitting a specific surface in between source and detector. While this is easily done by filter strings in a simple detector view, I was unsure on how to implement this in the optimization. Therefore Zemax provided some help a while ago in form of this ZPLM operand



detector = PVHX()


clear = NSDD(1,0,0,0)


NSTR 1, 0, 0, 0, 0, 0, 0, 1, 'Test.ZRD', 'H4'


ZRDPLAYBACK 'Test.ZRD', 1, detector, 1


X = NSDD(1, detector, -3, 0)


OPTRETURN 0, X



So I specify my detector in H(x) and then clear all detectors, run a raytrace with the filter string applied (in this case hit surface 4) and point it back to the detector. So now this returns the rays hitting the detector under consideration of H4, correct?



However, how do I use that in the merit funtion editor now? Would someone be able to provide me with a working example of such a merit function to get this ZPLM implemented?



Best Regards



 Moritz



 



 

Hi Moritz,



For a full description of how to use a ZPLM operand, you should check out the Knowledgebase article 'Optimization using a ZPL Macro: the ZPLM operand.'



As you already have the contents of the ZPL, you can paste them into a new macro and save it with the title 'ZPL##' where '##' is the number of the operand:



 





 



Once saved, you will enter it into the Merit Function with the optimization operand ZPLM. You will be asked for the macro number, which corrsponds to the value you entered for '##'. The output of the macro will be given under the Value column in the Merit Function. In the case of this macro, the output will represent the number of hits on the detector with the filter string 'H4'. 



I am attaching an example file for you. In the example, I have set up a Merit Function with two outputs: NSDD and ZPLM. The NSDD operand at row #6 will represent the number of hits on the detector without the filter string. Then the ZPLM operand will represent the number of rays striking the detector with the filter string. You can confirm the values with the Detector Viewer windows! The macro I use for the ZPLM operand will be stored under your {Zemax}\Macros folder as 'ZPL97.ZPL' once you open this file. 



Note: I did make one update to the macro you have here. Any string values (Test.ZRD, H4) should be surrounded by quotation marks, not by apostophes. So my macro looks like this instead:



 



detector = PVHX()


clear = NSDD(1,0,0,0)


NSTR 1, 0, 0, 0, 0, 0, 0, 1, 'Test.ZRD', 'H4'


ZRDPLAYBACK 'Test.ZRD', 1, detector, 1


X = NSDD(1, detector, -3, 0)


OPTRETURN 0, X


 



Let me know if you have any other questions about this!



Best,



Allie


Dear Allie.



Thanks for your fast help on this matter. Most of it I had already in place, sorry, should have attached a file as well. I had my macro saved etc... Now my problem (and it is still not working as I think it should work) is as follows:



I adjusted your file so that there is one source and the rectangular. So if I set surface3 (the rectangular) as a variable in hight and manually displace it a bit, then it is my impression that the optimization should readjust the position set as a variable to reach the maximum flux on the detector under the boundary condition that it has to hit the surface3.



But I (still) seem not to get it to work. I am not sure where the error is in my setup or thinking? Be aware that I also 'messed around' here X = NSDD(1, detector, -1, 0) ...



If you can provide an working example to reach that goal . that would be perfect.



Best regards.



Moritz


Hi Moritz,



In testing this, it looks like the optimization is having trouble converging. I'm not sure why the ZPLM would have trouble when it is performing a similar set of steps to any one of the default Merit Functions. I am going to get in touch with our developers about this. I will let you know when I hear back! 



Best,



Allie


Hi Moritz,



After some discussion with my colleagues, I think I found that the problem is in how the NSTR keyword is defined. If the NSTR is defined without a random seed value, then every refresh of the Merit Function will call a new ray trace with a new, random set of rays. With this, the value for NSDD will fluctuate a great deal. That can cause the optimization to fail since the solution space would not be continuous. 



To get the expected output based on the file you sent, we need to update NSTR so that it has a random seed defined. That way, the same set of rays is always being traced. Here is my updated ZPLM:



 



src = 0


split = 0


polar = 0


scat = 0


errors = 1


seed = 1


savefile = 1





detector = PVHX()


clear = NSDD(1,0,0,0)


NSTR 1, src, split, scat, polar, errors, seed, savefile, 'Test_Seed.ZRD', 'H3'


ZRDPLAYBACK 'Test_Seed.ZRD', 1, detector, 1


X = NSDD(1, detector, 0, 0)


OPTRETURN 0, X


 



I tested this in the file you sent, and found that the Rectangle Object centers itself on the beam (as expected). I am sending you the post-optimized system.  



Note: I updated the NSDD to search for power so that the target could be set as '1' in the Merit Function. 



Does that work for you?



Best,



Allie


Reply