ZEMAX Users' Knowledge Base - http://www.zemax.com/kb
How to Write User-Defined Surfaces with Waterloo Maple
http://www.zemax.com/kb/articles/87/1/How-to-Write-User-Defined-Surfaces-with-Waterloo-Maple/Page1.html
By Mikhail Levtonov
Published on 14 March 2006
 
This article shows how to create ZEMAX user-defined surfaces using the Waterloo Maple mathematics package.

This article is also available in Japanese.

Introduction
This article is also available in Japanese.

The ability to write your own user-defined surfaces is an important feature in ZEMAX. It is described in several articles in the "Programming ZEMAX" hierarchy at http://www.zemax.com/kb/categories/Tutorials/Programming-ZEMAX/ . Specifically, http://www.zemax.com/kb/articles/58/1/How-to-Compile-a-User-Defined-Surface gives a detailed description of how to write and compile a user-defined surface.

This article describes how to use Waterloo Maple to help in the process of writing a user-defined surface. Maple is a powerful mathematics package, which can be used to produce optimized C (and other language) code from entered equations.

In this article I will describe creation of a simple surface based on the Odd Aspherical shape with additional decentered Gaussian sag. Such a surface is useful for tolerancing of certain types of optical elements, mostly for modelling of local irregularities. Maple will be used to produce the code needed to compute the surface sag and surface normal vector at any point on the surface.

Defining the Surface Sag
The first step in writing a user-defined surface is to describe the shape of the surface with an equation of the form

z = f(x, y)

In this article I will use Waterloo Maple to enter the required equations and produce the optimized C-code needed. In the following examples, red courier font represents data entered into Maple, blue font represents output from Maple, and text after the # symbol are comments.

In the following, the variable ka is the amplitude of a Gaussian function of fixed width, rr is the radial distance at which the amplitude has fallen to ka/100, and dx and dy are optional decentrations entered via the Lens Data Editor.



Maple input/output


This function is then added to the normal Odd Asphere sag as defined in the ZEMAX manual. By using Maple this can be easily done with common math functions and procedures:

The Gaussian sag added tot he Odd Asphere sag

This equation must be converted to C code to implement adequate DLL for Zemax. Maple has very convenient tool for this action namely “Codegen”.  Note, that array indexes are decreased by 1 when Maple performs C code generation – that’s why there is param[i+1] in the Maple code:

Code Generated by Maple

What's more, Maple can also optimize the C-code it produces:

OPtimized C-code produced by Maple

This can then be copy-and-pasted into Case 5 of the DLL, with just a little hand editing.


Defining the Surface Normal

Now we have the surface sag, the next step is to compute the direction cosines of the normal vector. The normal vector at a point (x0,y0) on a surface z = f(x,y) is given by

Normal vector


where fx = df/dx and fy = df/dy are partial derivatives. So, the direction cosines will be as follows:

direction cosines of the surface normals


In Maple, fx is given by:

Computation of Fx


The same actions are used to compute Fy.


Compiling the DLL

The final stage is to copy all this code into the DLL, with minor edits so that the ZEMAX parameters are mapped correctly to the Maple ones, declare all needed variables, and to build the dll. The source code for this surface, and the associated Maple file, are provided in the zip file you can download from the last page of this article.

After the build is finished (and any compile-time error messages are corrected) it is time for the debugging stage. This may be most complicated and time-demanding part. I use DebugView freeware utility from Sysinternals. To monitor any variable while running your DLL in Zemax you just needed to add 3 strings into source code:

1. Declare variable:
char DebugString[200];

2. Add command for output in desired place and with needed format, for example:
sprintf(DebugString, "z=%f t=%f sag=%f",z,t,sag); //will print variables z, t and sag with format determined by text in quotes
OutputDebugString (DebugString );

This example is included into attached DLL code (lines 34, 224 and 225).

After compiling with such commands it is time to start DebugView. For convenience it is best to set up filter, and for the supplied file DebugView mwas set to catch string consisting “z=”:

DebugView Filter

After loading the DLL into Zemax, DebugView will display information like following:

Debug data


Here the user can monitor the available variables and correct source, if needed.


Summary and References


This article has described some useful steps for compiling UDS DLLs:

  • Using mathematical editor to enter the equations for the surface sag and surface normals
  • Using Maple’s Codegen package to produce optimized C-code
  • Using DebugView for DLL debugging


References.

1. Eric W. Weisstein. "Normal Vector." From MathWorld--A Wolfram Web Resource. http://mathworld.wolfram.com/NormalVector.html
2. http://www.sysinternals.com/Utilities/DebugView.html