- Description
- Install
- Lumerical script usage
- Remote-host execution
- MATLAB script usage
- MATLAB templating system for Lumerical script construction and analysis
This repository consists of a set of:
- Lumerical scripts for rapid geometry and simulation definition.
- Bash scripts for remote-host execution on a dedicated server running Linux.
- MATLAB scripts for parametrically sweeping and analyzing Lumerical structures.
These three components can be used separately or in combination, and are not interdependent for most functionality.
Note: this library is fully functional, but the documentation has not been thoroughly checked and may be missing a few options.
- Clone this repository.
- Lumerical
- Either add the
commonfolder to your Lumerical path, or prepend all files using it withaddpath('/path/to/common');. - Update the first line of all files in the
commonfolder that containaddpath('/home/nickersonm/lumerical/common');to the correct path, if different from/home/nickersonm/lumerical/commonand you have not added it to your Lumerical path. - Sample Lumerical scripts are in
common/templates/.
- Either add the
- Remote-host execution
- Copy
remote-dedicatedto the selected Linux remote host and mark as executable. - Dependencies
PuTTYis used in the provided batch files for Windows client Lumerical dispatch, but can be easily customized.xvncis required if using remote-side script execution; a common and standalone variant is TigerVNC.pueueis required if using remote-side queuing instead of local Lumerical queue management, and requirespueuegroups"cad","engine", and"fdtd-engine"with execution limits as desired.
- Verify the remote host has Lumerical installed and correctly licensed.
- Copy
- MATLAB
- Add the
MATLABfolder to your MATLAB path. - Dependencies
appendstruct,figureSize,figureTitle,smoothGrid, andtitlewrapfunctions from my MATLAB-utilities repository.- 3rd party
smoothnandsubplot_tightfunctions.
- Sample data collection routines are present in the
./routines/folder.
- Add the
The set of Lumerical scripts in common/ interacts with eachother to build epitaxy, etch geometry, and simulation entities given a brief description. With etchDef and epitaxy variables provided, lum_setup can then be called and the appropriate geometry and simulation will be created. The minimum required variables are:
etchDef: cell list of etches, each element being a structure with fields:.depthetch depth from top of epitaxy.widthwidth of the etch region, unused if .start is specified.lengthlength of the etch region, unused if .end is specified
epitaxy: cell list of epitaxial layers, top-down, each element being a structure with fields:.materialepitaxial material; currently supported: any built-in, 'AlGaAs', 'SiO2', 'SiN' , 'InGaP', 'InGaAs', 'GaAsP', 'LiNbO3_x', 'LiNbO3_z', 'AlOx', 'Au', 'Si'.thicknesslayer thickness
Details can be found below or in the script and template headers. Of special note is that the epitaxy can include quantum well or MQW definitions with thicknesses specified by .qw instead of .thickness, and the MQW gain results will be calculated and substituted into a material covering the MQW region.
Some minimal examples are:
A varFDTD simulation of a Si waveguide surrounded by SiN:
addpath('/home/nickersonm/lumerical/common'); # Replace as necessary, optionally adding multiple potential locations for different environments
# Define 220 nm SOI epitaxy
# 'guiding' hints to center simulation on that layer
epitaxy = {
{'material': 'Si', 'thickness': 0.220, 'guiding': 1},
{'material': 'SiO2', 'thickness': 2}
};
# Define waveguide with s-curve
# This is an etch definition, 'wgspace' automatically treats it as a waveguide definition and generates left and right etches
etchDef = {
{'depth': 0.5, 'wgspace': 10, 'start': [0, -2, 1], 'end': [20, 2, 1]}
};
# Background and etch material is SiO2
etchMat = 'SiO2';
# Change wavelength to 1300 nm, default 1030 nm is below Si bandgap
lambda = 1.3;
# Restrict to top instead of full epitaxy
simZ = [-1, 0.2];
# Reduce simulation Y-extent; default is full etch extents
simY = 8;
# Build simulation
lum_setup;
A MODE simulation of GaAs deep ridge waveguide:
addpath('/home/nickersonm/lumerical/common'); # Replace as necessary, optionally adding multiple potential locations for different environments
# Define basic AlGaAs/GaAs epitaxy
epitaxy = {
{'material': 'AlGaAs', 'x':0.3, 'thickness': 1},
{'material': 'GaAs', 'thickness': 1, 'guiding': 1},
{'material': 'AlGaAs', 'x': 0.2, 'thickness': 2},
{'material': 'GaAs', 'thickness': 10, 'name': 'Substrate'}
};
# Define simple ridge waveguide
# This is an etch definition, 'wgspace' automatically treats it as a waveguide definition and generates left and right etches
etchDef = {
{'depth': 3, 'wgspace': 10, 'width': 2, 'length': 10}
};
# Run as YZ MODE simulation
sim2D = 1;
# Restrict to guiding layer ±1 µm instead of full epitaxy
simZ = 1;
# Reduce simulation Y-extent; default is full etch extents
simY = 4;
# Build simulation
lum_setup;
Execute the script files in the appropriate Lumerical environment - in the case of these examples, Lumerical MODE.
After constructing the simulation and geometry, and optionally executing it, the lum_analyze script can be run to characterize a number of metrics and export the results to a MATLAB file. If the simulation does not yet have results calculated, it will be run before export. Details can be found below and in the lum_analyze script header, but a minimal nontrivial example is:
addpath('/home/nickersonm/lumerical/common'); # Replace as necessary, optionally adding multiple potential locations for different environments
# Compare MODE results to a 2 µm MFD gaussian, e.g. for coupling overlap
outField = {'pol': 0, 'mfd': 2};
# Save results to MATLAB file
matFile = 'mode_test.mat';
# Run analysis
lum_analyze;
# Look at overlap with output field, reported as [mode#, overlap, loss]
?[results.modeN, results.Pout, results.modeL];
Further examples can be found in the common/templates/ folder.
Detailed Lumerical script usage
Units: µm lengths, cm^-1 loss, 1e18 cm^-3 doping
Run lum_setup; after setting desired variables.
etchDef: cell list of etches, each element being a structure with fields:.depthetch depth from top of epitaxy.widthwidth of the etch region, unused if.startis specified.lengthlength of the etch region, unused if.endis specified- Optional etchDef fields:
.layercalculates etch depth from 'epitaxy' matrix (counting from top); overrides.depthif specified- Requires '
epitaxy' cell list of epitaxial layers
- Requires '
.wgspacegenerates appropriate etches for a waveguide with the specified.width, using this field as an exclusion zone (etch width on each side).start[x0,y0,w0]start location and width, defaultprev.endor[0,0,width].end[x1,y1,w1]end location and width, defaultstart+[length,0,0].namename for the etch object, default 'etch#'.resminimum transverse resolution for this region; will generatesimResmatrix, can be[res,yMin,yMax,xMin,xMax].cellsnumber of EME cells for this waveguide; will generatesimCellLenandsimCellNmatrix; default1.bend[EME and MODE] bend radius for this waveguide; will generatesimBend.sbend[EME only] maximum bend radius for an s-bend; will generate appropriate structure for an s-bend with .cells distinct segments.poly[[x], [y]]polygon fully defining extents of etch; overrides all other xy size specifications.thicknessspecify thickness [µm]; appends to 'epitaxy' cell list as.material='Au', .meshorder=1with given.thickness,.z,.poly.materialspecify material other than 'etch', optionally combine with '.thickness'.anglespecify etch angle; will shift top and bottom polygon points
epitaxy: cell list of epitaxial layers, top-down, each element being a structure with fields:.materialepitaxial material; currently supported: any built-in,'AlGaAs','SiO2','SiN','InGaP','InGaAs','GaAsP','LiNbO3_x','LiNbO3_z','AlOx','Au','Si'.thicknesslayer thickness- Optional epitaxy fields:
.xcomposition of first element; default 0, currently supported:'AlGaAs','InGaAs','GaAsP'.dopingdopant concentration [e18 cm^-3]; negative for n-doped, positive for p-doped.nameoverride default layer name.qwquantum well thickness, overrides 'thickness', adjacent 'qw' materials simulated and added as single material.guidinguse as assumed guiding region; default determined by lowest loss.coloroptional material color as[R, G, B, A].meshorderspecify mesh order;'etch'is 1.zspecify z-location of bottom of layer; removes cell from layer calculations, e.g. for metal pads.polyxy polygon defining layer, e.g. for metal pads; if not used with '.z', gaps will be present in epitaxy.xmaxmaximum x extent.xminminimum x extent
- CHARGE only:
contacts: cell list of electrical contacts, each element being a structure with fields:.nameexisting geometry name or new geometry (requires.dzand.polybelow).Varray of potentials to apply (optionally scalar)- Optional contacts fields:
.polyxy polygon defining new geometry.dzz-extents of new geometry.materialsupported material for new geometry; default'Au'.meshorderspecify mesh order; default1
regrowth: structure with regrowth definition with fields:.xminminimum x extent of regrowth etch, modifies 'epitaxy'.xmaxmaximum x extent of regrowth etch, modifies 'epitaxy'; ignored if xmin set.depthetch depth to remove original epitaxy to; either depth or layer required.layerauto-compute etch depth from given epitaxy layer (etch-to, not etch-through).epitaxycell list of regrowth epitaxial layers, same as standard epitaxy
sim2D:0for full 3D EME, FDTD, or CHARGE,1for YZ FDE or CHARGE,2for XY varFDTD, FDTD, or CHARGE; default2etchMat: material for etches, default'etch'simX:[min, max]longitudinal simulation span, default epitaxy extentssimY:[min, max]transverse simulation span, default epitaxy extents less PMLsimZ:[min, max]vertical simulation span, default epitaxy extent plus buffersimZlayer: calculate minimum Z extent as this epitaxial layer, overrides simZsimBuffer: buffers for ports, monitors, etc; default1[µm]simAccuracy:auto-mesh accuracy setting, where applicable; default4simRes: mesh size in normal regions [µm], can be matrix of[res,yMin,yMax,[xMin,xMax]]; default0.25simResSub: mesh size in substrate region [µm], default0.25simResFine: maximum mesh size in guiding region [µm], default0.05simMon: output port/monitor, cell of structures.typeOptical:'port','E','n','mov','time'; CHARGE:'Q','E','BS','I'- Optional fields:
.geo'x','z','y','point','xy','yz', or'xz'; optical default'yz', CHARGE default'z'.xx location or span; defaultsimXormax(simX), can specify'in'or'out'.yy location or span; defaultsimYormean(simX).zz location or span; defaultsimZormean(simZ).namename of monitor; default'mon_<#>_<type>'
- Optional fields for '
port' only:.polE-field polarization, where applicable,0for TE (+y),1for TM (+z); default0.rotinput rotation around z axis [degrees]; default0.ampmodify relative amplitude; default1.phasephase offset for this port.mfduse gaussian source with this MFD [µm], <0 for plane wave; if 3-vector, use[MFD, y, z]for recentering- Custom Field (where applicable):
.yy spatial vector, also sets location.zz spatial vector, also sets location.powerspatial matrix defining modal power.field3- or 6-dimensional matrix defining[Ex, Ey, Ez, (Hx, Hy, Hz)]fields, overrides.powerand.pol
- Default
simMon, always included: - CHARGE:{ {'type': 'Q', 'loc': [0,0,0]}, {'type': 'E', 'loc': [0,0,0]}, {'type': 'BS', 'loc': [0,0,0]} }- Optical: Index and Field for xy plane, input, and output, name<location><type>
monYZ: global default[simMon.y, simMon.z]; default[simY, simZ]- For all optical solvers
lambda: wavelength [µm] (partially implemented); default1.03simPol: polarization of simulation for 2D simulations;0for TE (+y),1for TM (+z), default0simPML: number of mesh periods for PML border, where applicable; default8inPort: input port settings, cell of structures as with 'simMon', type'port'only- Optional fields:
.xx location; defaultmin(simX).yy location or span; defaultsimYormean(simX).zz location or span; defaultsimZormean(simZ).namename of monitor; default'port_<#>'.polE-field polarization, where applicable,0for TE (+y),1for TM (+z); default0.rotinput rotation around z axis [degrees]; default0.ampmodify relative amplitude; default1.phasephase offset for this port.mfduse gaussian source with this MFD [µm], <0 for plane wave; if 3-vector, use[MFD, y, z]for recentering- Custom Field (where applicable):
.yy spatial vector, also sets location.zz spatial vector, also sets location.powerspatial matrix defining modal power.field3- or 6-dimensional matrix defining[Ex, Ey, Ez, (Hx, Hy, Hz)]fields, overrides.powerand.pol
- Default
inPort:{{'pol': '0'}}
- Optional fields:
- For EME and FDE only
simModes: number of modes to search; linearly impacts memory, default250simModeN: search near this index, if provided positive number; default-1('near max n')simBend: enable bend radius for given segments,[xMin, xMax, radius]
Detailed Lumerical script usage
Units: µm lengths, cm^-1 loss, 1e18 cm^-3 doping
Run lum_analyze; after setting desired variables.
- Required:
- none
- Optional:
resultFile: filename to save analysis toresultVars: matrix or string to save to the same line before standard outputsmatFile: filename to export data todataRes: Cartesian resolution to interpolate data [µm], default0.05outField: output field to compare to; structure with fields:.yy spatial vector, also sets location.zz spatial vector, also sets location.polpolarization;0for TE (+y),1for TM (+z), default0; will rotate.fieldif nonzero.rotrotation around z axis [degrees]; default0- One of:
.mfdgenerate gaussian source with this MFD [µm], <0 for plane wave, optionally[mfd, dy, dz].powerspatial matrix defining modal power.E3-dimensional matrix defining [Ex, Ey, Ez] fields
- EME and FDE only
maxModesmaximum number of modes to save; default all computed modesemeGroupSpanset EME group spans before running
- Output products, where applicable:
resultsstructure with summarized results as:portNamescell list of port names referred to by numbersS##S parameters between all ports, using inputField and outputField where possibleP##power overlap between all ports, using inputField and outputField where possibleO##complex power overlap between all portsPtrtotal power transmission fractionPoutpower overlap of output field and outField, if specified; modal vector for FDEmodeN[FDE only] vector mapping position in list to mode numbermodeL[FDE only] vector of modal lossmodeNeff[FDE only] vector of modal effective indexmodePol[FDE only] polarization of mode, TE =0
simDatastructure of monitors and ports (and solver for CHARGE) as structures with fields:.namename of port/monitor.x,.y,.zCartesian geometry vectors for interpolated data.<data>full return of<data>(varies by monitor) in Cartesian format.<data>_rawraw fem data, if present.vtxfem vertices, if present.elemfem element/connectivity definition, if present.IDfem element ID, if present.loss[FDE only] propagation loss of mode.pol[FDE only] polarization of mode, TE =0.neff[FDE only] effective index.ng[FDE only] group index.overlap[FDE only] overlap with outField, if specified
Note:
remote-slurmis not in a cohesive state and is not currently documented here. It should be functional with some customization to your environment, and is provided as a template. Comments describing the purpose and usage are provided in the assorted scripts.
The remote-dedicated set of scripts simplifies the execution of Lumerical simulations on remote hosts. This can work via:
- Simple dispatch from a local Lumerical instance executing work files. Batch files for Windows are provided.
- Remote queueing and execution of script definitions tied in to the
common/Lumerical scripts.- This can be combined with the MATLAB scripts for easy parameter search execution and analysis.
The scripts should all be copied to ~/lumerical/ on the remote host, or the path can be altered in the headers of each script.
Note:
lumerical_setup.shis not used during execution, but provides an optional brief guide to installing Lumerical andpueueon a Debian host.
The run_<solver>.sh set of bash scripts will execute simulation files for the appropriate solver. Verify that the paths for the CAD and ENG variables are correct. To use, copy a simulation file to the remote host and run, e.g.:
./run_fde.sh test.lmsA set of dispatch-<solver>.cmd files are also provided to automate the dispatch, execution, and retrieval from Lumerical clients on Windows. Before use, modify them to use the appropriate PuTTY session in the login variable, or otherwise change the SSH command. A few-line shell script can provide equivalent functionality on Linux clients.
To dispatch jobs directly to the remote host from a Lumerical instance running, add a a new remote 'Resource' with the 'Custom' job preset. Select 'bypass mpi on localhost' and 'no default options', entering in the appropriate dispatch-<solver>.cmd file. Press 'Run tests' to verify functionality.
The Lumerical client will now treat the remote host as a valid solver, and queue jobs on it when executing a local batch.
For further flexibility including automated simulation file generation from scripts in the common/ Lumerical scripts, Q_parallel.sh and Q_selected.sh can be used to submit entire directories of script files for generation, execution, and analysis at once. These use the pueue daemon with pueue groups "cad", "engine", and "fdtd-engine" - set group execution limits as desired. pueue_remaining.sh is provided for easily monitoring queue progress.
This integrates nicely with the MATLAB scripts for executing large sweeps at once, or overnight, on a dedicated solver machine.
Verify that the paths for the CAD and ENG variables are correct in the run_<solver>.sh scripts, that pueue is installed successfully with the groups "cad", "engine", and "fdtd-engine", that xvnc is a valid command, and that Lumerical is installed and properly licensed. Copy the common/ scripts to the remote host's /home/nickersonm/lumerical/common directory.
With one or more .lsf Lumerical scripts on the remote machine, the scripts can then be used simply:
# Run one FDE simulation defined with a script
~/lumerical/Q_selected.sh fde ~/lumerical/tmp/test.lsf
# Build the simulation file, but don't execute or prepare analysis files
BUILDONLY=1 ~/lumerical/Q_selected.sh fde ~/lumerical/tmp/test.lsf
# Build the simulation file, don't execute, but prepare analysis files
PREBUILD=1 ~/lumerical/Q_selected.sh fde ~/lumerical/tmp/test.lsf
# Manually execute the one simulation file
~/lumerical/run_fde.sh ~/lumerical/tmp/test.lms
# Analyze previously prepared and executed script
POSTBUILD=1 ~/lumerical/Q_selected.sh fde ~/lumerical/tmp/test.lsf
# Run a bunch of scripts forming a sweep of a parameter
~/lumerical/Q_parallel.sh fde ~/lumerical/tmp/sweeps/test_*.lsf
# Also run a CHARGE analysis of the same scripts
# Temporary *_working_<solver>.lsf Lumerical scripts will have been created by the previous command, so don't queue those
~/lumerical/Q_parallel.sh charge ~/lumerical/tmp/sweeps/test_(^*_fde).lsf
# Watch remaining task count
~/lumerical/pueue_remaining.shDependencies are
appendstruct,figureSize,figureTitle,smoothGrid, andtitlewrapfunctions from my MATLAB-utilities repository and the 3rd partysmoothnandsubplot_tightfunctions.
The set of MATLAB functions and scripts in MATLAB/ provide both a script-construction template for parameter searches and various utilities for analyzing results:
- General photonics utility functions
fieldModeArea: effective modal area of a given fieldfieldMsq: M^2 calculations for x-normal fields, computed by the method in https://doi.org/10.1109/JLT.2005.863337fieldOverlap: complex overlap between two fieldsanalyticalModelGaAs: GaAs phase modulation and optical absorption model given an optical and electrical field. Assumes pure GaAs.
- Utility functions for dealing with
lum_analyzeresults:plotMQW: plot results from amqwstructure that is generated by specifying.qwlayers in theepitaxyplotResultYZ: plot FDE and/or CHARGE results, optionally both simultaneouslyplotResult3D: plot x-propagation results from EME, varFDTD, or FDTD simulations
- A set of scripts to generate many Lumerical scripts sweeping specified parameters, optionally enqueue to a remote host, and analyze the results:
buildScriptAndEnqueue,buildSweepAndEnqueue,retrieveCompleted, andsweepPlots_Base
The first two categories are fairly self explanatory, with further documentation provided in the function headers.
First make sure to update the
dirCommonvariable in the header ofbuildScriptAndEnqueue.
The functions buildScriptAndEnqueue and buildSweepAndEnqueue enable easy sweeping of any parameter(s) defined in a Lumerical script by generating many variants of such script. Simply pass a sweep name, the script contents as a string, and a cell list consisting of variable name and value pairs, such as:
% Sweep the "x" variable in "myscript.lsf"
script = string(fileread("myscript.lsf"));
buildSweepAndEnqueue("test_sweep", script, ["x", linspace(0,10,101)], 'submitjob', 1, 'session', 'PuTTY-session-name');Optionally alter the default session parameter to point to the correct PuTTY session, or even change the plink and pscp parameters to use SSH instead.
For large sweeps, it may be faster to simply generate the script variants locally:
buildSweepAndEnqueue("test_sweep", script, ["x", linspace(0,10,101)], 'submitjob', 0);Then copy the files to the remote host and queue them all at once:
~/lumerical/Q_parallel.sh fde ~/lumerical/tmp/sweeps/test_sweep/*.lsfFor either method, the completed results (.mat files) can either be manually moved back to the original sweep directory, or retrieveCompleted() can be used to read the locally-generated log of submitted files, submitted.log.
Analysis can be performed in MATLAB on many .mat file results of Lumerical sweeps with sweepPlots_Base.m. Optional variables are described in the file header, but required variables are:
componentName: the name of the test, for use in plotsoutDir: the directory to write results toresFiles: the list of result files as an array of strings, without extensionsresExts: the extension(s) of result files- These two are combined to look for actual files; for combined electro-optical results incorporating
analyticalModelGaAs, a list of files without the typical_<solver>.mattail can be provided forresFilesand["_FDE.mat", "_CHARGE.mat"]can be set forresExts
- These two are combined to look for actual files; for combined electro-optical results incorporating
params: a list of simulation parameters via strings toeval, typically based on the results which are loaded into variableR, such asR.wWGandR.outField.polmetrics: a list of result metrics via strings toeval, in the same manner, such asmin(R.results.modeL)for the lowest mode loss orR.results.modeL(find(R.results.Pout == max(R.results.Pout), 1))for the loss of the highest-output-overlap mode.
Each file will be analyzed for all params and metrics, and results will be plotted for any that vary across the group. FDE results have additional default processing added, visible in the loadDataFile function of sweepPlots_Base.m.
Included in the MATLAB/template/ folder are a set of sample scripts for a MATLAB-based Lumerical script templating system for geometry construction and analysis. A typical Lumerical script has been broken into several parts, several of which can be easily swapped out to define alternate components. This allows easy assembly of a set of related simulations, such as multiple components based on the same process and epitaxy.
The provided Lumerical script pieces are in the MATLAB/template/lsf/ folder, and include:
10_header_template.lsfto provide a standard header.20_etch_<material>_WG.lsfto provide a standard initial waveguide definition and defaults for a given epitaxy; this is something that is likely to be typical across an entire process.22_etch_<material>_<component>.lsfto provide specific component definitions that either build on or replace the_WGdefinition.30_epi_<epi>.lsfto define the specific epitaxy.40_inst_<material>.lsfto define typical 'instrumentation' used in an epitaxy, e.g. ports or common variations of options.90_footer_template.lsfto provide a standard conclusion to the script, including callinglum_setup;.
Each component is assigned a directory, and then consists of 3 MATLAB files:
def_<material>_<component>_<epi>.mto define the component by assembling the whole script file and setting default variables forbuildSweepAndEnqueue.sweep_<material>_dev_<epi>.mthat loads the definition, sets custom sweep parameters, and then callsbuildSweepAndEnqueueto create a sweep of Lumerical scripts, that can then be processed with the remote-host execution scripts on a remote host.plot_<material>_dev_<epi>.mthat loads the definition, sets analysis variables, and then callssweepPlots_Base.mto load all resulting.matfiles and analyze the sweep results.
In my usage, the sweep_*.m files are fairly short with most lines being commented out past sweeps for easy reference, and the remainder defining the most recent sweep, such as:
sweep = {"sim2D", 2, ...
"wWG1", [1.5, 2.0, 3.0], ...
"wgBR", linspace(50, 300, 51)};
sweepName = "AR8_dev_Sbend_varFDTD_1";
buildSweepAndEnqueue(scriptName, script, sweep, 'allvars', setVars, 'sweepname', sweepName, ...
'submitjob', 0, 'randomize', 0*0.02);By convention, directories starting with dev are 3D photonic devices or components like MMIs and s-bends, analyzed with varFDTD and 3D FDTD, while directories starting with wg are waveguide cross-sections analyzed with MODE and sometimes CHARGE.
With this templating system, the workflow for developing a new epitaxy, process, and PIC component becomes:
- For active epitaxies, possibly develop MQWs with
MQW_peaks. - Define possible epitaxy and basic waveguide structure.
- Develop epitaxy with
epi1Dor similar to determine the optimal epitaxy parameters. - Optimize etch depths and cross sections with
wgPassive,wgMod, andwgActive. - Develop waveguide components by creating a new
22_etch_<material>_<dev>.lsfdefinition anddev<Component>set of MATLAB scripts for each one and sweep parameters.
Simply exploring the provided scripts may be helpful for a better understanding.