S4 Home | Download | FAQ | Lua API | Developer information | Changelog
S4 is built as a set of extensions to the Lua scripting language. Usage of S4 involves writing a Lua script to call into various parts of S4. Here we describe all of the S4 specific functions that can be called within the Lua environment.
All top level functions of S4 are located in the S4 library.
These functions mainly return objects which can be manipulated to obtain desired results.
Returns a new blank Simulation object.
S = S4.NewSimulation()
None.
Returns a new SpectrumSampler object.
sampler = S4.NewSpectrumSampler(f_start, f_end, options)
Returns a new Interpolator object.
interpolator = S4.NewInterpolator('type', {
{x1, {y1_1, y1_2, ... }},
{x2, {y2_1, y2_2, ... }},
...
})
linearcubic hermite splineThe second argument should be a table of tables. Each subtable should have as its first element the abscissa of a data sample, and the second element should be a table of all the ordinate values. The ordinate ordering is clearly important, and only the number of ordinate values for the first abscissa value determines the assumed number of ordinate values for the remaining abscissae.
Forces the computation of a layer solution for several simulation objects in parallel. When compiled without thread support, the computations are done serially.
S4.SolveInParallel('layer', Sa, Sb, ...)
Clone method to make copies.None.
Performs unit conversions.
S4.ConvertUnits(value, from_units, to_units)
value is currently expressed, and the desired units.
Currently supported units:
Lengths: “um”, “nm”, “m”, “cm”, “mm”
Energies: “eV”, “J”
Frequencies: “THz”, “GHz”, “Hz”, “rad/s”The converted value, or nil if no conversion was possible.
Performs adaptive numerical integration in an arbitrary number of dimensions.
integral,error = S4.Integrate(func, range1, range2, ..., opts)
Returns the integrated value and an estimate of the error.
When used with the -a switch, the value of S4.arg is set to the command line switch argument.
This is a convenient way of passing command line arguments to S4 scripts, or in parallel environments for specifying machine IDs.
When no command line switch is specified, S4.arg is nil.
Multiple variables may be passed in by passing in multiple Lua statements:
./S4 -a "a=1;b=2;c=3" input.lua
Then within the script, the variables may be set with the statement
pcall(loadstring(S4.arg))
On a version of S4 with MPI support, gives the MPI machine rank (0-based index of processor node). For versions without MPI support, this is always 0.
On a version of S4 with MPI support, gives the MPI size (total number of processor nodes). For versions without MPI support, this is always 1.
The Simulation object is the primary object which computes solutions to systems.
When a new Simulation object is requested from S4.NewSimulation(), all settings are in a blank state, with no materals, layers, or excitation.
When solutions are requested, only a minimal set of internal computations are performed in order to satisfy the request.
Sets the real-space lattice.
S:SetLattice(L)
S:SetLattice({x1,y1}, {x2,y2})
This function can take a single numeric argument, which sets the period for a 1D lattice. This function can also take two table arguments, each of which must have two numeric elements. The first table specifies the x- and y-coordinates of the first lattice basis vector, while the second table specifies the second basis vector. The basis vectors should have positive orientation (the cross product of the first with the second should yield a vector with positive z-coordinate).
None
Sets the maximum number of in-plane (x and y) Fourier expansion orders to use. All fields and eigenmodes of the system use the same Fourier basis of the same dimension.
The computation time is roughly proportional to the cube of this number, and the memory usage is roughly proportional to the square.
S:SetNumG(n)
GetNumG.None
Adds a new material with a specified dielectric constant.
S:AddMaterial(name, {eps_r, eps_i})
S:AddMaterial(name, {
{xx_r, xx_i}, {xy_r, xy_i}, {xz_r, xz_i},
{yx_r, yx_i}, {yy_r, yy_i}, {yz_r, yz_i},
{zx_r, zx_i}, {zy_r, zy_i}, {zz_r, zz_i}
})
None
Updates an existing material with a new dielectric constant or adds a material if none exists.
S:SetMaterial(name, {eps_r, eps_i})
S:SetMaterial(name, {
{xx_r, xx_i}, {xy_r, xy_i}, {xz_r, xz_i},
{yx_r, yx_i}, {yy_r, yy_i}, {yz_r, yz_i},
{zx_r, zx_i}, {zy_r, zy_i}, {zz_r, zz_i}
})
None
Adds a new unpatterned layer with a specified thickness and material.
S:AddLayer(name, thickness, material)
None
Updates an existing layer with a new thickness and removes all layer patterning. If no matching layer is found, adds a new unpatterned layer with a specified thickness and material. The behavior is undefined if the new material does not match the old material during an update (currently, the new material is ignored, but this may change in the future). If only the thickness needs to be modified, use SetLayerThickness.
S:SetLayer(name, thickness, material)
None
Updates an existing layer with a new thickness. Previously cached layer eigenmodes are preserved, making this function the preferred way to update a layer’s thickness.
S:SetLayerThickness(name, thickness)
None
Adds a new layer with a specified thickness, but identical patterning as another existing layer. Note that this merely creates a reference to the copied layer; further patterning of the copied layer also affects the new layer. Additionally, a copy of a copy cannot be made.
S:AddLayerCopy(name, thickness, original_name)
None
Adds a (filled) circle of a specified material to an existing non-copy layer. The circle should not intersect any other patterning shapes, but may contain or be contained within other shapes.
S:SetLayerPatternCircle(layer, material, center, radius)
None
Adds a (filled) ellipse of a specified material to an existing non-copy layer. The ellipse should not intersect any other patterning shapes, but may contain or be contained within other shapes.
S:SetLayerPatternEllipse(layer, material, center, angle, halfwidths)
None
Adds a (filled) rectangle of a specified material to an existing non-copy layer. The rectangle should not intersect any other patterning shapes, but may contain or be contained within other shapes.
S:SetLayerPatternRectangle(layer, material, center, angle, halfwidths)
None
Adds a (filled) polygon of a specified material to an existing non-copy layer. The polygon should not self-intersect nor intersect any other patterning shapes, but may contain or be contained within other shapes. The polygon must also be specified with positive orientation (the vertices circle CCW about an interior point).
S:SetLayerPatternPolygon(layer, material, center, angle, vertices)
vertices[1] is the x-coordinate of the first vertex and vertices[2] is its y-coordinate, and vertices[3] is the x-coordinate of the second vertex, etc.None
Sets the excitation to be a planewave incident upon the front (first layer specified) of the structure. If both tilt angles are specified to be zero, then the planewave is normally incident with the electric field polarized along the x-axis for the p-polarization. The phase of each polarization is defined at the origin (z = 0).
S:SetExcitationPlanewave({phi,theta}, {s_amp, s_phase}, {p_amp, p_phase}, order)
phi and theta give the spherical coordinate angles of the planewave k-vector. For zero angles, the k-vector is assumed to be (0, 0, kz), while the electric field is assumed to be (E0, 0, 0), and the magnetic field is in (0, H0, 0). The angle phi specifies first the angle by which the E,H,k frame should be rotated (CW) about the y-axis, and the angle theta specifies next the angle by which the E,H,k frame should be rotated (CCW) about the z-axis. Note the different directions of rotations for each angle.None
Low level function to set excitations by a superposition of incident modes of the exterior layers. For unpatterned layers, the incident modes are forward propagating planewaves in the front, and backward propagating planewaves in the back.
S:SetExcitationExterior{
{ G-index, pol, { amp-re, amp-im } },
...
}
None
Sets the operating frequency of the system (and excitation).
S:SetFrequency(freqr, freqi)
None
Retrieves the reciprocal lattice basis vectors. The vectors lack the scaling by 2pi (multiply them by 2pi to obtain the true reciprocal lattice basis vectors).
Gu,Gv = S:GetReciprocalLattice()
None.
SetLattice.
Each vector is a table of length 2, holding the x- and y-coordinates of the vector.Retrieves the dielectric constant at a particular point in the system by reconstructing the Fourier series using the G-vectors of the system.
Note that this reconstruction is not representative of the actual dielectric constant profile used in simulations (such a notion is not meaningful). The reconstruction is created using the closed-form Fourier series coefficients of the specified patterning, summed over the terms comprising the G-vector list obtained from lattice truncation. This function exists to provide an intuitive sense for the spatial resolution of a particular G-vector truncation order.
eps_r, eps_i = S:GetEpsilon({x, y, z})
Outputs a list of PostScript commands to render the exact layer pattern description from the specified patterning commands. Assumes letter-sized paper.
S:OutputLayerPatternDescription(name, filename)
None.
Outputs a Gnuplot format dump of the Fourier series reconstruction of the dielectric constant in the unit cell. Note that the output will appear distorted for non-orthogonal unit cells.
Note that this reconstruction is not representative of the actual dielectric constant profile used in simulations (such a notion is not meaningful). The reconstruction is created using the closed-form Fourier series coefficients of the specified patterning, summed over the terms comprising the G-vector list obtained from lattice truncation. This function exists to provide an intuitive sense for the spatial resolution of a particular G-vector truncation order.
S:OutputLayerPatternRealization(name, Nu, Nv, filename)
Nu*Nv.None.
Outputs a POV-Ray script that will render one unit cell of the structure in 3D. Materials named air or vacuum (case insensitive) will be completely transparent.
S:OutputStructurePOVRay(filename)
None.
Returns the specified number of Fourier series orders to use (number of G-vectors), or, if a solution has been computed, the actual number of G-vectors used.
n = S:GetNumG()
None.
n is the actual number of G-vectors used.Returns a table of reciprocal lattice coordinates of the Fourier series orders used. The coordinates are in the reciprocal lattice basis, and so they are integers.
G = S:GetGList()
None.
Returns the index (1-based) of a particular diffraction order. The index can be used directly in GetPoyntingFluxByOrder to obtain the diffracted power of a particular order. The coordinate arguments are in the reciprocal lattice basis, and so they are integers. A particular diffraction order is only a meaningful concept in a uniform (unpatterned) layer, otherwise the diffraction order corresponds to an arbitrary layer eigenfunction index.
i = S:GetDiffractionOrder(m, n)
Returns the raw mode amplitudes within a particular layer. For uniform (unpatterned) layers, the modes are simply the diffracted orders, and the indexing of the returned amplitudes corresponds to the value obtained from GetDiffractedOrder. The first value is guaranteed to be the straight transmitted or specularly reflected diffraction order. For patterned layers, there is typically no meaningful information in these amplitudes.
forw,back = S:GetAmplitudes(layer, offset)
Returns the integral of the Poynting flux density over a unit cell surface normal to the z-direction. In other words, the z-component of the Poynting flux is returned.
forw_r, back_r, forw_i, back_i = S:GetPoyntingFlux(layer, offset)
Returns the integral of the Poynting flux density over a unit cell surface normal to the z-direction for each Fourier series order. In other words, the z-component of the Poynting flux for each order is returned.
P = S:GetPoyntingFluxByOrder(layer, offset)
GetPoyntingFlux.Returns the integral of the electromagnetic stress tensor over a unit cell surface normal to the z-direction.
Txr, Tyr, Tzr, Txi, Tyi, Tzi = S:GetStressTensorIntegral(layer, offset)
Returns the volume integral of the electromagnetic energy density (epsilon*|E|^2 + |H|^2) over a unit cell throughout the entire thickness of a layer.
Ur,Ui = S:GetLayerEnergyDensityIntegral(layer)
Returns the volume integral of the electric energy density (epsilon*|E|^2) over a unit cell throughout the entire thickness of a layer.
Ur,Ui = S:GetLayerElectricEnergyDensityIntegral(layer)
Returns the volume integral of the magnetic energy density (|H|^2) over a unit cell throughout the entire thickness of a layer.
Ur,Ui = S:GetLayerMagneticEnergyDensityIntegral(layer)
Returns the volume integral of the squared electric field intensity (|E|^2) over a unit cell throughout the entire thickness of a layer.
Ur,Ui = S:GetLayerElectricFieldIntensityIntegral(layer)
Returns the line integral along z (depth direction) of the squared magnitudes of electric and magnetic field components (|Ex|^2, |Ey|^2, etc.) throughout the entire thickness of a layer.
IEx, IEy, IEz, IHx, IHy, IHz = S:GetLayerZIntegral(layer, {x, y})
Returns the electric field at a particular point within the structure.
Exr, Eyr, Ezr, Exi, Eyi, Ezi = S:GetEField({x, y, z})
Returns the magnetic field at a particular point within the structure.
Hxr, Hyr, Hzr, Hxi, Hyi, Hzi = S:GetHField({x, y, z})
Returns the electric and magnetic field at a particular point within the structure. Note that it is more efficient to call this function when both fields are needed.
Exr, Eyr, Ezr, Hxr, Hyr, Hzr, Exi, Eyi, Ezi, Hxi, Hyi, Hzi = S:GetFields({x, y, z})
Returns the determinant of the S-matrix (scattering matrix) of the entire structure. The determinant is an analytic function in the complex frequency plane and has poles at the complex modal frequencies of the system.
mantr, manti, base, expo = S:GetSMatrixDeterminant()
None.
Enables or disables smoothing of the Fourier series representations of the layer dielectric constants using the Lanczos sigma factor (box filtering). This reduces the Gibbs phenomenon ringing in the real space reconstruction.
S:UseLanczosSmoothing(use)
None.
Enables or disables the use of discretization in generating the Fourier coefficients of the in-plane epsilon profiles, instead of using values from closed-form equations. When enabled, the coefficients are obtained by FFT.
See the list of formulations for details.
S:UseDiscretizedEpsilon(use)
None.
Enables or disables the use of proper in-plane Fourier factorization rules by decomposing fields into a polarization basis which conforms to the material boundaries. The polarization basis field is generated automatically by computing a quasi-harmonic vector field everywhere tangent to the layer pattern boundaries. This option is not guaranteed to work in the presence of tensor dielectric constants.
Enabling this feature typically improves convergence with respect to the number of G-vectors. See the list of formulations for details.
S:UsePolarizationDecomposition(use)
None.
Enables or disables the use of second-order accurate epsilon averaging rules within a pixel. The average epsilon within a pixel is computed using the fill factor of each material and the interface direction.
Enabling this feature may improve convergence with respect to the number of G-vectors. See the list of formulations for details.
S:UseSubpixelSmoothing(use)
None.
This option only has an effect with EnablePolarizationDecomposition.
When enabled, a Jones vector basis field is used instead of a conformal harmonic field.
Enabling this feature may improve convergence with respect to the number of G-vectors. See the list of formulations for details.
S:UseJonesVectorBasis(use)
None.
This option only has an effect with EnablePolarizationDecomposition.
When enabled, the resulting vector field is normalized. Where the vector field is zero, the unit vector in the x-direction is used.
Enabling this feature may improve convergence with respect to the number of G-vectors. See the list of formulations for details.
S:UseNormalVectorBasis(use)
None.
This option only has an effect with UseDiscretizedEpsilon or UseSubpixelSmoothing.
This function sets the resolution of the FFT grid and vector field generated by EnablePolarizationDecomposition.
The resolution is multiplied by the largest G-vector extent (integer lattice coordinate), and should be at least 2 to satisfy the Nyquist limit. It is best to use a number with small integer factors in order for the FFT to be computed efficiently. The size of each dimension of the FFT is obviously proportional to this value. The default is 8.
See the list of formulations for details.
S:SetResolution(n)
None.
Setting this option to a filename prefix causes the vector field used by the polarization decomposition to be dumped to files (one for each layer) in Gnuplot format. The files are named by concatenating the provided prefix string with each layer’s name.
S:SetBasisFieldDumpPrefix(prefix)
None.
Sets the type of lattice truncation to use when selecting G-vectors.
S:SetLatticeTruncation(trunc)
None.
Sets the type of lattice truncation to use when selecting G-vectors.
S:SetVerbosity(level)
None.
Setting this option will prevent storage of certain intermediate results. This will save approximately 30% memory for non-trivial layers. The drawback is slower computation of any output quantities that require solutions.
S:UseLessMemory(use)
None.
Duplicates an existing Simulation object, copying all materials, layers, and excitation information. No partial solution information is copied.
S2 = S:Clone()
None.
A copy of the Simulation object.
The SpectrumSampler object provides a convenient way to sample spectral information of a system. For example, it is used to resolve sharp peaks in transmission spectra. Interaction with a SpectrumSampler object is by contract; a new frequency is retrieved from it by which simulation results at that frequency are computed, and then the results are submitted.
The frequencies given out by a SpectrumSampler object aim to produce a visually pleasing plot of the resulting spectrum by limiting the maximum normalized bend angles between adjacent line segments of the plot.
A typical usage is shown below:
function f(x) -- example function
return math.sin(x)
end
sampler = S4.NewSpectrumSampler(0.1, 0.9, -- start and end frequencies
{ -- table of options
InitialNumPoints = 33,
RangeThreshold = 0.001,
MaxBend = math.cos(math.rad(10)),
MinimumSpacing = 1e-6
})
while not sampler:IsDone() do
x = sampler:GetFrequency()
y = f(x) -- compute the desired result
sampler:SubmitResult(y)
end
spectrum = sampler:GetSpectrum()
for i,xy in ipairs(spectrum) do
print(xy[1],xy[2])
end
Queries whether the SpectrumSampler has completed sampling. When sampling has been completed, no further frequencies should be requested from the SpectrumSampler object, and no further results should be submitted.
done = sampler:IsDone()
None.
A boolean value indicating whether sampling has completed.
Retrieves the next frequency at which to sample the spectrum. This function should only be used if the SpectrumSampler object was created with Parallize set to false (the default).
freq = sampler:GetFrequency()
None.
The (numeric) frequency at which the next result should be computed and submitted.
Retrieves the next set of frequencies at which to sample the spectrum. This function should only be used if the SpectrumSampler object was created with Parallize set to true.
freqlist = sampler:GetFrequency()
None.
A list of (numeric) frequencies at which the next results should be computed and submitted.
Submits a result to the SpectrumSampler object. The result is assumed to be at the frequency of the last requested frequency. This function should only be used if the SpectrumSampler object was created with Parallize set to false (the default).
done = sampler:SubmitResult(result)
A boolean value indicating whether sampling has completed.
Submits a set of results to the SpectrumSampler object. The results are assumed to be at the frequencies of the last requested frequencies. This function should only be used if the SpectrumSampler object was created with Parallize set to true.
done = sampler:SubmitResults(result_list)
GetFrequencies.A boolean value indicating whether sampling has completed.
Retrieves a list of all sampled frequencies and submitted results. This function should only be used when the SpectrumSampler object indicates that sampling is complete.
valarray = sampler:GetSpectrum()
None.
An array (with length equal to the number of samples) of pairs (arrays of length 2) containing the sampled frequency and corresponding submitted result.
The Interpolator object provides a tool to perform various types of interpolation on data. The most common use is to interpolate between experimentally determined values for dieletric constants. A typical usage is shown below.
interpolator = S4.NewInterpolator('linear', {
{3.0, {14.2, 32}}, -- x, and list of y values
{5.4, {4.6, 10}},
{5.7, {42.7, 20}},
{8.0, {35.2, 40}}
})
for x = 0, 10, 0.1 do
y1, y2 = interpolator:Get(x)
print(x, y1, y2)
end
At each x (abscissa) value, any number of y (ordinate) values can be specified for interpolation.
Retrieves the interpolated ordinates for a given abscissa value.
y1, y2, ... = interpolator:Get(x)
A list of interpolated ordinate values.