User-supplied near-axis electric field.


In CPO3D there is an option for a user-supplied routine that defines near-axis electric fields. It is accessed from /databuilder/segments/advanced options (at the bottom of the screen). This option is loosely related to the option in CPO2D to improve near-axis fields.


An example of the use of the option is given in xmpl3d62.dat.


The user-supplied routine is a subroutine of user3d.cpp. The version of user3d.cpp that is supplied with the CPO programs contains an example routine.


In fact user3d.cpp could be used to define an electric field in any region, but there would rarely be any reason to do this since the main CPO3D program is so accurate.


Near-axis (that is, paraxial) fields of extreme accuracy are however required for some aberration calculations (particularly the calculation of aberrations by ray-tracing using rays that are very near to the axis).


The inaccuracy provided by CPO3D (1.E-7) would usually be small enough if the calculated fields were smooth -that is, if the inaccuracies at neighbouring points differed by much less than 1.E-7. However the method used by CPO3D to calculate a field depends in general on the distance from the axis (that is, one expression would be used for an on-axis point, expansion terms would be added for a point that is a very small distance from the axis, and a more general expression would be used for points further from the axis -all of which is done to minimise the computing time for a given inaccuracy). This causes the relative inaccuracy of neighbouring points to be of the same magnitude as the absolute inaccuracy, giving a field that is not necessarily smooth but has irregularities of the order of 1.E-7.


Further details are given in user3d.cpp and xmpl3d62.dat.


When using the option to synthesise the near-axis fields of a series of equally spaced lenses of the same geometry then a single representative lens would usually be used to generate the near-axis data, but be careful that this lens is in the correct environment (that is, that it is still surrounded by other lenses with the appropriate spacing).


It is assumed in the present version of user3d.cpp that CPO3D has been used to obtain the field as a function of the distance s from the axis, for a set of values of the distance z along the axis, where s might be x or y or the distance in the x=y direction. It is assumed also that for a quadrupole field an external program has been used to fit the field components Ex and Ey at each value of z to the expression:

 Ex(x,y,z) = A1(z)*x + A3(z)*x**3,

 Ey(x,y,z) = -A1(z)*y - A3(z)*y**3.

(A suitable program, nearaxis.f90, is added to the end of the user3d.cpp.)

For an octupole field the relevant expressions are:

 Ex(x,y,z) = B3(z)*(x**3 - 4*x*y**2),

 Ey(x,y,z) = B3(z)*(y**3 - 4*y*x**2).

For a monopole field (that is, a round lens) the relevant expressions are:

 Ex(x,y,z) = C1(z)*x + C3(z)*x*r**2,

 Ey(x,y,z) = C1(z)*y + C3(z)*y*r**2,

For a sextupole field the relevant expressions are:

 Ex(x,y,z) = D3(z)*(x**2 - y**2),

 Ey(x,y,z) = -D3(z)*x*y.


The values of the coefficients A, B and C are put in the file userfld2.dat, which is read by user3d.cpp. Control data are put in userfld1.dat.


It might sometimes be an improvement, or even a necessity, to add 5th order terms.


Formulas used by user3d.cpp for generating the z component Ez(x,y,z) are derived from div(E) = 0, which gives:

Quadrupole: Ez(x,y,z) = -3.*A3(z)*z*(x**2 - y**2) + O(r**5)

Octupole: Ez(x,y,z) = O(r**5)

Monopole: Ez(x,y,z) = Ez(0,0,z) - 2*C1(z)*z - 4*C3(z)*z*(x**2 + y**2) + O(r**5)


The external linked program user3d.cpp uses 4-point interpolation to interpolate the coefficients A, B and C, as follows.

Suppose that the current value of z is z(n) + s, where z(n) is the nearest lower grid value of z.

Then put u = s/dz, where dz is the spacing of the grid points.

The interpolation formula is then

A(z) = g(-1)*A(z(n-1)) + g(0)*A(z(n)) + g(1)*A(z(n+1)) + g(2)*A(z(n+2)),


g[-1] = (-2*u + 3*u2 - u3)/6,

g[0] = (2 - u - 2*u2 + u3)/2,

g[1] = (2*u + u2 - u3)/2,

g[2] = (-u + u3)/6

This is the formula for Langrangian interpolation for 4 points.



To summarize, the stages involved in using this option are:

(1) Use CPO3D to generate a set of near-axis fields.

(2) Use an external program to generate the relevant coefficients (an example program is given at the end of this file and at the end of xmpl3d62.dat).

(3) Put the coefficients in a file, eg userfld2.dat.

(4) Construct a file, eg userfld1.dat, that defines the parameters of the lenses of the system (that is, their polarities, positions etc).

(5) Rewrite user3d.cpp if necessary.

(6) Generate a new user3d.dll if user3d.cpp is new (and remember that user3d.dll must be in the same directory as cpo3d.exe).

(7) Switch on the option and run.


For further information see user3d.cpp and xmpl3d62.dat. These file names are entered in the databuilder, so that the user is able to use different names if required.


Another advantage of using this option is that it usually makes ray tracing faster, sometimes much faster.


For instructions on editing user3d.cpp and creating user3d.dll, see the recent instructions given for the scattering routine.