One last example of FORTRAN code callable by Zemax is the Scattering type object. These compiled DLL files go into the directory: {ZEMAXroot}\ Objects \ DLL \ SurfaceScatter.

The scattering objects allow a custom calculation for the scattering properties of a surface. Like the other examples, this also has two callable entries: UserScatterDefinition and UserParamNames. The latter, UserParamNames is identical to the call for sources, and serves only to name the user definable parameters. The entry for UserScatterDefinition is similar to the other examples. The header and comments are given below:

function UserScatterDefinition (data)
! for the call to UserScatterDefinition, the data is stored as follows:
!      data(0) = total number of values in the passed data array
!      data(1) = x position of specular ray
!      data(2) = y position of specular ray
!      data(3) = z position of specular ray
!      data(4) = l (x direction cosine of specular ray in, of scattered ray out)
!      data(5) = m (y direction cosine of specular ray in, of scattered ray out)
!      data(6) = n (z direction cosine of specular ray in, of scattered ray out)
!      data(7) = lxn (x direction cosine of normal vector to surface)
!      data(8) = myn (y direction cosine of normal vector to surface)
!      data(9) = nzn (z direction cosine of normal vector to surface)
!      data(10) = 0 initially, return 1 if DLL scatters ray,
!          2 if full polarization given
!      data(11) = mm per unit length (1.0 for mm, 25.4 for inches,
!          10.0 for cm, 1000 for m)
!      data(12) = relative energy (to be computed by dll and returned)
!      data(16) = random seed
!      data(17) = wavelength in um
!      data(20) = incident Ex real
!      data(21) = incident Ex imag
!      data(22) = incident Ey real
!      data(23) = incident Ey imag
!      data(24) = incident Ez real
!      data(25) = incident Ez imag
!      data(40) = output Ex real (to be returned if data(10) set to 2)
!      data(41) = output Ex imag (to be returned if data(10) set to 2)
!      data(42) = output Ey real (to be returned if data(10) set to 2)
!      data(43) = output Ey imag (to be returned if data(10) set to 2)
!      data(44) = output Ez real (to be returned if data(10) set to 2)
!      data(45) = output Ez imag (to be returned if data(10) set to 2)
!      data(51) = input parameter 1 from user
!      data(52) = input parameter 2 from user
!      etc... up to data(maxdata), where maxdata = int(data(0))
! This DLL will compute and return data(i) for i=4,5,6,10,12,40-45 given other data.
! Return value is normally 0 on success, -1 on failure.

implicit none
integer*4, dll_export :: UserScatterDefinition
real*8 data(0:*)

In general, the input data will far exceed the needs of the calculation – any particular scattering algorithm will likely be fairly restrictive, and hence use a small subset of this data. The case we have used is to model the grazing incidence reflection coefficients for far UV / soft X-ray optics using simple polynomial fits. In that particular case, the rest of the code consists of:

real*8 data(0:*), dot, pi, p1, p2, theta, thetamax
parameter (pi = 3.14159265358979323846)
parameter (thetamax = <constant>)
dot = data(4)*data(7) + data(5)*data(8) + data(6)*data(9)
theta = abs(asin(dot)) ! this is grazing angle
if (theta .gt. thetamax) then
data(12) = 0.0 ! cutoff
else
p1 = <polyfit numerator>
p2 = <polyfit denominator>
data(12) = p1/p2
end if
data(10) = 1.0 ! flag to show that we scattered
UserScatterDefinition = 0 ! return with null error code
return
end function


In short, we have only calculated the grazing angle (from the dot product of the specular ray and the normal ray), and then reduced the energy of the ray according to the reflection coefficient model.