Load Wavica and Rayica

In[1]:=

Needs["Wavica`Wavica`"]

+++++++++++++++++++++++++++++++++++++++

Rayica 2.0 was loaded in 19 s and needs 7123 kilobytes of memory on top of 4776 kilobytes already used

Wavica 1.0 was loaded.

Arbitrary Precision Calculations

Both Rayica and Wavica permit the use of abitrary precision calculations. This is controlled with the RayTracePrecision option:

In[2]:=

?RayTracePrecision

RayTracePrecision -> precision gives the number of decimal digits of precision used for ray-tracing.

To illustrate this, we will work with the following optical system:

In[14]:=

sys = {WedgeOfRays[20],Move[PlanoConvexLens[100,50,10,CurvatureDirection->Back],90],Move[Screen[{50,50}],150]}

Out[14]=

RowBox[{{, RowBox[{WedgeOfRays[20], ,, TagBox[StyleBox[TagBox[RowBox[{Move, [, RowBox[{PlanoCo ... 50, 50}], ,, 150.}], ]}], HoldForm], FontColor -> RGBColor[0., 0.392187, 0.]], DisplayForm]}], }}]

In[15]:=

TurboPlot[sys];

[Graphics:HTMLFiles/index_6.gif]

Arbitrary Precision Calculations in Rayica

In Rayica, both the TurboPlot and TurboTrace functions support arbitrary precision calculations. In its default mode, however, all calculations are carried out in machine precision of 16 decimal places. Here is a default calculation of the optical length of the rays traced to the final screen surface:

In[6]:=

TurboTrace[sys,OpticalLength]//InputForm

Out[6]//InputForm=

{155.2594749592117, 155.23244752966428, 155.2594749592117}

Next, we use RayTracePrecision->50 to repeat the above calculation with 50 decimal places of precision:

In[7]:=

TurboTrace[sys,OpticalLength,RayTracePrecision->50]

Out[7]=

RowBox[{{, RowBox[{155.259474947573901666175818636139183393839888979, ,, 155.23244751863872199115302388987169854791463358253, ,, 155.259474947573901666175818636139183393839888979}], }}]

We can use TurboTrace with OutputType->RayTraceFunction to extract a ray-trace function model of the system. Again, we use RayTracePrecision->50. This model is stored in a variable called res.

In[8]:=

res = RayTraceFunction/.TurboTrace[sys,OpticalLength,OutputType->RayTraceFunction,RayTracePrecision->50]

Out[8]=

RayTraceFunction[{$inputrays}, -raytrace code: 111232 Bytes- : RayTracePrecision -> 50]

This stored RayTraceFunction can now make new calculations with different light source models. Here we use a LineOfRays and WedgeOfRays in separate calculations.

In[9]:=

res[LineOfRays[20]]

Out[9]=

RowBox[{{, RowBox[{155.00000507744214362697178541607015410128185915359, ,, 155.23244751863872199115302388987169854791463358253, ,, 155.00000507744214362697178541607015410128185915359}], }}]

In[10]:=

res[WedgeOfRays[20]]

Out[10]=

RowBox[{{, RowBox[{155.259474947573901666175818636139183393839888979, ,, 155.23244751863872199115302388987169854791463358253, ,, 155.259474947573901666175818636139183393839888979}], }}]

Arbitrary Precision Calculations in Wavica

Most functions in Wavica supports arbitrary precision control. This includes: SymbolicTrace, FindInterference, GaussianPlot, GaussianTrace, FindABCDMatrix , ZernikeFit, and FindWaveFronts. For remaining discussion, we will examine the use of FindWaveFronts and GaussianPlot.

FindWaveFronts in one dimension

Here is the default behavior of FindWaveFronts. This calculation shows the one-dimensional wavefront at the final screen surface in the system.

FindWaveFronts[sys]

Surface Location :  {ComponentNumber2, SurfaceNumber1, WaveFrontID1, Source1}

[Graphics:HTMLFiles/index_12.gif]

[Graphics:HTMLFiles/index_13.gif]

[Graphics:HTMLFiles/index_14.gif]

RowBox[{{, RowBox[{{, RowBox[{ComponentNumber2, ,, RowBox[{Energy, , 100.}], , ... ble -> False]}], ,, RowBox[{WaveLength, , 0.532}], ,, WaveTiltWaveTilt}], }}], }}]

Here is the same calculation with RayTracePrecision->50.

wav = FindWaveFronts[sys,RayTracePrecision->50]

Surface Location :  {ComponentNumber2, SurfaceNumber1, WaveFrontID1, Source1}

[Graphics:HTMLFiles/index_17.gif]

[Graphics:HTMLFiles/index_18.gif]

[Graphics:HTMLFiles/index_19.gif]

RowBox[{{, RowBox[{{, RowBox[{ComponentNumber2, ,, RowBox[{Energy, , 100.00000 ... ;, 0.53200000000000000000000000000000000000000000000000}], ,, WaveTiltWaveTilt}], }}], }}]

(OpticalPathDifference/.wav[[1]])[15]

47.273225331494707638360887575166965069982

FindWaveFronts in two dimensions

The previous example used a two-dimensional WedgeOfRays source. Internally, this used an InterpolatingFunction to model the wavefront behavior. When three-dimensional sources are used instead, FindWaveFronts uses a Zernike-polynomial fit of the wavefront. Here is an optical system with the three-dimensional PointOfRays.

In[16]:=

sys2D = {PointOfRays[{15,15}],Move[PlanoConvexLens[100,50,10,CurvatureDirection->Back],90],Move[Screen[{50,50}],150]}

Out[16]=

RowBox[{{, RowBox[{PointOfRays[{15, 15}], ,, TagBox[StyleBox[TagBox[RowBox[{Move, [, RowBox[{P ... 50, 50}], ,, 150.}], ]}], HoldForm], FontColor -> RGBColor[0., 0.392187, 0.]], DisplayForm]}], }}]

In[17]:=

TurboPlot[sys2D];

[Graphics:HTMLFiles/index_23.gif]

Once again, the default behavior of FindWaveFronts is to make its calculation in machine precision:

Timing[wav0 = FindWaveFronts[sys2D]]

Surface Location :  {ComponentNumber2, SurfaceNumber1, WaveFrontID1, Source1}

[Graphics:HTMLFiles/index_25.gif]

[Graphics:HTMLFiles/index_26.gif]

[Graphics:HTMLFiles/index_27.gif]

RowBox[{{, RowBox[{RowBox[{10.53,  , Second}], ,, RowBox[{{, RowBox[{{, RowBox[{ComponentNumbe ... False]}], ,, RowBox[{WaveLength, , 0.532}], ,, WaveTiltWaveTilt}], }}], }}]}], }}]

Next we use RayTracePrecision->100 with FindWaveFronts to increase the precision of the result to 100 decimal places.

Timing[wav = FindWaveFronts[sys2D,RayTracePrecision->100]]

Surface Location :  {ComponentNumber2, SurfaceNumber1, WaveFrontID1, Source1}

[Graphics:HTMLFiles/index_30.gif]

[Graphics:HTMLFiles/index_31.gif]

[Graphics:HTMLFiles/index_32.gif]

RowBox[{{, RowBox[{RowBox[{87.6,  , Second}], ,, RowBox[{{, RowBox[{{, RowBox[{ComponentNumber ... 000000000000000000000000000000000000000000000000}], ,, WaveTiltWaveTilt}], }}], }}]}], }}]

GaussianPlot

GaussianPlot is used to calculate the diffractive behavior of Gaussian beams through space. We now examine how arbitrary precision calculations are made with GaussianPlot. Here is RayTracePrecision->50.

In[12]:=

GaussianPlot[{GaussianBeam[.2,4.9], Move[Screen[200],300]},RayTracePrecision->50]

[Graphics:HTMLFiles/index_34.gif]

Out[12]=

RowBox[{{, RowBox[{BeamSpotSizeGraphics (⁃Graphics⁃), ,, RowBox[{BeamSpotS ... ], &}], )}]}], ,, RowBox[{WaveLength, , 0.532}], ,, PlotDomain {0, 300}}], }}]

When you use RayTracePrecision->Infinity, the result is calculated with fractional integers rather than floating point numbers.

In[13]:=

GaussianPlot[{GaussianBeam[.2,4.9], Move[Screen[200],300]},RayTracePrecision->Infinity]

[Graphics:HTMLFiles/index_36.gif]

Out[13]=

RowBox[{{, RowBox[{BeamSpotSizeGraphics (⁃Graphics⁃), ,, BeamSpotSizeFunct ... 931) - #1] &), ,, RowBox[{WaveLength, , 0.532}], ,, PlotDomain {0, 300}}], }}]


Created by Mathematica  (September 1, 2005)