### Initialize LumOpt Optimization Source: https://lumopt.readthedocs.io/en/latest/tutorial.html Python setup for defining spectral range and base simulation scripts for LumOpt. ```Python """ Copyright chriskeraly Copyright (c) 2019 Lumerical Inc. """ ######## IMPORTS ######## # General purpose imports import os import numpy as np import scipy as sp from lumopt.utilities.wavelengths import Wavelengths from lumopt.geometries.polygon import FunctionDefinedPolygon from lumopt.figures_of_merit.modematch import ModeMatch from lumopt.optimizers.generic_optimizers import ScipyOptimizers from lumopt.optimization import Optimization ######## DEFINE SPECTRAL RANGE ######### wavelengths = Wavelengths(start = 1550e-9, stop = 1550e-9, points = 1) ######## DEFINE BASE SIMULATION ######## # Use the same script for both simulations, but it's just to keep the example simple. You could use two. script_1 = os.path.join(os.path.dirname(__file__), 'splitter_base_TE_modematch.lsf') script_2 = os.path.join(os.path.dirname(__file__), 'splitter_base_TE_modematch_25nmoffset.lsf') ######## DEFINE OPTIMIZABLE GEOMETRY ######## ``` -------------------------------- ### Run 2D Waveguide Y-branch Optimization Source: https://lumopt.readthedocs.io/en/latest/install.html Navigate to the example directory and run the 2D waveguide Y-branch optimization script from the terminal. This will open Lumerical windows and perform the optimization. ```bash cd examples/splitter python splitter_opt_2D.py ``` -------------------------------- ### Clone LumOpt Repository and Install Source: https://lumopt.readthedocs.io/en/latest/install.html Clone the LumOpt repository and install it in develop mode. Ensure the Lumerical API (lumapi) is added to your Python path. ```bash git clone https://github.com/chriskeraly/LumOpt.git python setup.py -develop ``` -------------------------------- ### Lumerical Setup Script for Splitter Optimization Source: https://lumopt.readthedocs.io/en/latest/tutorial.html This Lumerical script defines the base simulation environment, including physical dimensions, mesh settings, and accuracy. It serves as the foundation upon which LumOpt adds the optimizable geometry. ```lsf # Copyright chriskeraly # Copyright (c) 2019 Lumerical Inc. switchtolayout; selectall; delete; ## SIM PARAMS size_x=3e-6; size_y=3e-6; mesh_x=20e-9; mesh_y=20e-9; finer_mesh_size=2.5e-6; mesh_accuracy=2; ``` -------------------------------- ### Configure FDTD Source Source: https://lumopt.readthedocs.io/en/latest/tutorial.html Sets up a mode source for the simulation. ```Lumerical Script addmode; set('direction','Forward'); set('injection axis','x-axis'); #set('polarization angle',0); set('y',0.0); set('y span',size_y); set('x',-1.25e-6); set('override global source settings',false); set('mode selection','fundamental TE mode'); ``` -------------------------------- ### Define Monitors Source: https://lumopt.readthedocs.io/en/latest/tutorial.html Sets up power monitors for optimization fields and figure of merit calculation. ```Lumerical Script addpower; set('name','opt_fields'); set('monitor type','2D Z-normal'); set('x',0); set('x span',finer_mesh_size); set('y',0); set('y span',finer_mesh_size); ``` ```Lumerical Script addpower; set('name','fom'); set('monitor type','2D X-normal'); set('x',finer_mesh_size/2.0); set('y',0.0); set('y span',size_y); ``` -------------------------------- ### Initialize Geometry Objects Source: https://lumopt.readthedocs.io/en/latest/tutorial.html Create FunctionDefinedPolygon instances for the splitters. ```python bounds = [(0.2e-6, 0.9e-6)] * initial_points_y.size # guess from splitter_opt_2D.py optimization initial_params = np.array([2.44788514e-07, 2.65915795e-07, 2.68748023e-07, 4.42233947e-07, 6.61232152e-07, 6.47561406e-07, 6.91473099e-07, 6.17511522e-07, 6.70669074e-07, 5.86141086e-07]) geometry_1 = FunctionDefinedPolygon(func = taper_splitter_1, initial_params = initial_points_y, bounds = bounds, z = 0.0, depth = 220e-9, eps_out = 1.44 ** 2, eps_in = 2.8 ** 2, edge_precision = 5, dx = 0.1e-9) geometry_2 = FunctionDefinedPolygon(func = taper_splitter_2, initial_params = initial_points_y + dy, bounds = bounds, z = 0.0, depth = 220e-9, eps_out = 1.44 ** 2, eps_in = 2.8 ** 2, edge_precision = 5, dx = 0.1e-9) ``` -------------------------------- ### ModeMatch Class Initialization Source: https://lumopt.readthedocs.io/en/latest/foms.html Initializes the ModeMatch class to calculate figures of merit based on mode overlap. ```APIDOC ## Class: ModeMatch ### Description Calculates the figure of merit from an overlap integral between the fields recorded by a field monitor and the selected mode. A mode expansion monitor is added to the field monitor to calculate the overlap result, which appears as T_forward in the list of mode expansion monitor results. ### Method __init__ ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **monitor_name** (string) - Required - name of the field monitor that records the fields to be used in the mode overlap calculation. - **mode_number** (integer) - Required - mode number in the list of modes generated by the mode expansion monitor. - **direction** (string) - Required - direction of propagation (‘Forward’ or ‘Backward’) of the mode injected by the source. - **multi_freq_src** (boolean) - Optional - bool flag to enable / disable a multi-frequency mode calculation and injection for the adjoint source. Defaults to False. - **target_T_fwd** (function) - Optional - function describing the target T_forward vs wavelength (see documentation for mode expansion monitors). Defaults to a lambda function. - **norm_p** (integer) - Optional - exponent of the p-norm used to generate the figure of merit; use to generate the FOM. Defaults to 1. ### Request Example ```json { "monitor_name": "fom_monitor", "mode_number": 1, "direction": "Forward", "multi_freq_src": false, "target_T_fwd": "lambda wl: 1.0", "norm_p": 1 } ``` ### Response #### Success Response (200) This method does not return a value directly, but configures the object for FOM calculation. #### Response Example None ``` -------------------------------- ### Define Waveguide Geometry Source: https://lumopt.readthedocs.io/en/latest/tutorial.html Creates rectangular waveguide structures using Lumerical script commands. ```Lumerical Script addrect; set('name','input wg'); set('x span',3e-6); set('y span',0.5e-6); set('z span',220e-9); set('y',0); set('x',-2.5e-6); set('index',2.8); ``` ```Lumerical Script addrect; set('name','output wg top'); set('x span',3e-6); set('y span',0.5e-6); set('z span',220e-9); set('y',0.35e-6); set('x',2.5e-6); set('index',2.8); addrect; set('name','output wg bottom'); set('x span',3e-6); set('y span',0.5e-6); set('z span',220e-9); set('y',-0.35e-6); set('x',2.5e-6); set('index',2.8); ``` -------------------------------- ### Run Combined Optimization Source: https://lumopt.readthedocs.io/en/latest/tutorial.html Combine the two optimization objects and execute the run method. ```python ######## PUT EVERYTHING TOGETHER ######## opt_1 = Optimization(base_script = script_1, wavelengths = wavelengths, fom = fom_1, geometry = geometry_1, optimizer = optimizer_1, hide_fdtd_cad = False, use_deps = True) opt_2 = Optimization(base_script = script_2, wavelengths = wavelengths, fom = fom_2, geometry = geometry_2, optimizer = optimizer_2, hide_fdtd_cad = False, use_deps = True) opt = opt_1 + opt_2 ######## RUN THE OPTIMIZER ######## opt.run() ``` -------------------------------- ### Define Figures of Merit and Optimizers Source: https://lumopt.readthedocs.io/en/latest/tutorial.html Create separate ModeMatch and ScipyOptimizers objects for each splitter. ```python ######## DEFINE FIGURE OF MERIT ######## # Although we are optimizing for the same thing, two separate fom objects must be create fom_1 = ModeMatch(monitor_name = 'fom', mode_number = 3, direction = 'Forward', multi_freq_src = False, target_T_fwd = lambda wl: np.ones(wl.size), norm_p = 1) fom_2 = ModeMatch(monitor_name = 'fom', mode_number = 3, direction = 'Forward', multi_freq_src = False, target_T_fwd = lambda wl: np.ones(wl.size), norm_p = 1) ######## DEFINE OPTIMIZATION ALGORITHM ######## #For the optimizer, they should all be set the same, but different objects. Eventually this will be improved optimizer_1 = ScipyOptimizers(max_iter = 40, method = 'L-BFGS-B', scaling_factor = 1e6, pgtol = 1e-9) optimizer_2 = ScipyOptimizers(max_iter = 40, method = 'L-BFGS-B', scaling_factor = 1e6, pgtol = 1e-9) ``` -------------------------------- ### lumopt.utilities.load_lumerical_scripts.load_from_lsf Source: https://lumopt.readthedocs.io/en/latest/all_others.html Loads a LSF script file and returns its content as a string, with all comments removed. ```APIDOC ## load_from_lsf /api/utilities/load_lumerical_scripts ### Description Loads the provided script file as a string and strips out all comments. ### Method N/A (Function) ### Endpoint N/A (Function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) - **script_content** (string) - The content of the script file without comments. #### Response Example None ``` -------------------------------- ### ScipyOptimizers Source: https://lumopt.readthedocs.io/en/latest/optimizers.html Wrapper for optimizers in SciPy's optimize package. Supports Quasi-Newton methods but requires caution due to potential gradient noise. ```APIDOC ## Class: ScipyOptimizers ### Description Wrapper for the optimizers in SciPy’s optimize package. Some optimization algorithms can approximate the Hessian from different optimization steps (Quasi-Newton Optimization). While this is very powerful, the figure of merit gradient calculated from a simulation using a continuous adjoint method can be noisy. This can point Quasi-Newton methods in the wrong direction, so use them with caution. ### Parameters - **max_iter** (int) - maximum number of iterations; each iteration can make multiple figure of merit and gradient evaluations. - **method** (str) - string with the chosen minimization algorithm. Defaults to 'L-BFGS-G'. - **scaling_factor** (float or list) - scalar or a vector of the same length as the optimization parameters; typically used to scale the optimization parameters so that they have magnitudes in the range zero to one. - **pgtol** (float) - projected gradient tolerance parameter ‘gtol’ (see ‘BFGS’ or ‘L-BFGS-G’ documentation). - **ftol** (float) - tolerance parameter ‘ftol’ which allows to stop optimization when changes in the FOM are less than this. - **target_fom** (float) - A target value for the figure of merit. This allows to print/plot the distance of the current design from a target value. - **scale_initial_gradient_to** (float or None) - Scales the initial gradient to a specified value. ``` -------------------------------- ### Configure FDTD Region Source: https://lumopt.readthedocs.io/en/latest/tutorial.html Defines the simulation domain and boundary conditions. ```Lumerical Script addfdtd; set('dimension','2D'); set('background index',1.44); set('mesh accuracy',mesh_accuracy); set('x',0.0); set('x span',size_x); set('y',0.0); set('y span',size_y); set('force symmetric y mesh',true); set('y min bc','Anti-Symmetric'); set('pml layers',12); ``` -------------------------------- ### lumopt.utilities.simulation.Simulation Source: https://lumopt.readthedocs.io/en/latest/all_others.html Manages the FDTD CAD session, including launching, saving, and running simulations. ```APIDOC ## Simulation Class /api/utilities/simulation ### Description Object to manage the FDTD CAD. Launches FDTD CAD and stores a handle. ### Method N/A (Class) ### Endpoint N/A (Class) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) - **Simulation Object** - An instance of the Simulation class. #### Response Example None ``` ```APIDOC ## run Method /api/utilities/simulation/run ### Description Saves the simulation file and runs the simulation. ### Method N/A (Method) ### Endpoint N/A (Method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **name** (string) - The name of the simulation. - **iter** (integer) - The iteration number of the simulation. ### Request Example None ### Response #### Success Response (200) - **status** (string) - Indicates the status of the simulation run. #### Response Example None ``` -------------------------------- ### load_from_lsf Function Source: https://lumopt.readthedocs.io/en/latest/helpers.html Loads the provided script as a string and strips out all comments. ```APIDOC ## `lumopt.utilities.load_lumerical_scripts.load_from_lsf` ### Description Loads the provided script as a string and strips out all comments. ### Method Not applicable (Python function) ### Endpoint Not applicable (Python function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python from lumopt.utilities.load_lumerical_scripts import load_from_lsf script_content = load_from_lsf('path/to/your/script.lsf') print(script_content) ``` ### Response #### Success Response (200) - **script_content** (string) - The content of the LSF script file with comments removed. #### Response Example ```json { "script_content": "# This is a comment\nprint('Hello, World!')\n" } ``` ``` -------------------------------- ### lumopt.utilities.plotter.SnapShots Source: https://lumopt.readthedocs.io/en/latest/all_others.html Grabs image information from a figure and saves it as a movie frame. ```APIDOC ## SnapShots Class /api/utilities/plotter/snapshots ### Description Grabs the image information from the figure and saves it as a movie frame. ### Method N/A (Class) ### Endpoint N/A (Class) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **extra_args** (dict) - Additional arguments to pass. ### Request Example None ### Response #### Success Response (200) - **SnapShots Object** - An instance of the SnapShots class. #### Response Example None ``` ```APIDOC ## grab_frame Method /api/utilities/plotter/snapshots/grab_frame ### Description All keyword arguments in fig_kwargs are passed on to the ‘savefig’ command that saves the figure. ### Method N/A (Method) ### Endpoint N/A (Method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **fig_kwargs** (dict) - Keyword arguments passed to the ‘savefig’ command. ### Request Example None ### Response #### Success Response (200) - **frame** (image data) - The saved movie frame. #### Response Example None ``` ```APIDOC ## setup Method /api/utilities/plotter/snapshots/setup ### Description Perform setup for writing the movie file. ### Method N/A (Method) ### Endpoint N/A (Method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **fig** (matplotlib.figure.Figure) - The figure to grab the rendered frames from. - **dpi** (number, optional) - The dpi of the output file. This, with the figure size, controls the size in pixels of the resulting movie file. Default is fig.dpi. - **frame_prefix** (str, optional) - The filename prefix to use for temporary files. Defaults to `'_tmp'`. - **clear_temp** (bool, optional) - If the temporary files should be deleted after stitching the final result. Setting this to `False` can be useful for debugging. Defaults to `True`. ### Request Example None ### Response #### Success Response (200) - **setup status** (string) - Indicates successful setup. #### Response Example None ``` ```APIDOC ## finish Method /api/utilities/plotter/snapshots/finish ### Description Finish any processing for writing the movie file. ### Method N/A (Method) ### Endpoint N/A (Method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) - **completion status** (string) - Indicates completion of movie file processing. #### Response Example None ``` -------------------------------- ### AdaptiveGradientDescent Source: https://lumopt.readthedocs.io/en/latest/optimizers.html Similar to FixedStepGradientDescent, but the step size (dx) adaptively changes based on the figure of merit improvement. ```APIDOC ## Class: AdaptiveGradientDescent ### Description Almost identical to FixedStepGradientDescent, except that dx changes according to the following rule: `dx = min(max_dx, dx * dx_regrowth_factor)` while `newfom < oldfom` `dx = dx / 2` if `dx < min_dx`: `dx = min_dx` return `newfom` ### Parameters - **max_dx** (float) - maximum allowed change of a parameter per iteration. - **min_dx** (float) - minimum step size (for the largest parameter changing) allowed. - **dx_regrowth_factor** (float) - by how much dx will be increased at each iteration. - **max_iter** (int) - maximum number of iterations to run. - **all_params_equal** (bool) - if true, all parameters will be changed by +/- dx depending on the sign of their associated shape derivative. - **scaling_factor** (float or list) - scalar or vector of the same length as the optimization parameters; typically used to scale the optimization parameters so that they have magnitudes in the range zero to one. ``` -------------------------------- ### Class: SuperOptimization Source: https://lumopt.readthedocs.io/en/latest/optimization.html Orchestrates multiple co-optimizations targeting different figures of merit that share the same parameters. ```APIDOC ## Class: SuperOptimization ### Description Optimization super class to run two or more co-optimizations targeting different figures of merit that take the same parameters. The addition operator can be used to aggregate multiple optimizations. ### Parameters - **optimizations** (list) - Required - List of co-optimizations (each of class Optimization). ``` -------------------------------- ### Class: Optimization Source: https://lumopt.readthedocs.io/en/latest/optimization.html Acts as the primary orchestrator for optimization tasks, requiring a base script, figure of merit, geometry, and an optimizer. ```APIDOC ## Class: Optimization ### Description Acts as orchestrator for all the optimization pieces. Calling the member function run will perform the optimization. ### Parameters - **base_script** (callable/string) - Required - Script to generate the base simulation. - **wavelengths** (float/Wavelengths) - Required - Spectral range for all simulations. - **fom** (ModeMatch) - Required - Figure of merit object. - **geometry** (FunctionDefinedPolygon) - Required - Optimizable geometry. - **optimizer** (ScipyOptimizers) - Required - SciPy minimizer wrapper. - **use_var_fdtd** (bool) - Optional - Default: False. - **hide_fdtd_cad** (bool) - Optional - Flag to run FDTD CAD in the background. - **use_deps** (bool) - Optional - Flag to use numerical derivatives calculated from FDTD. - **plot_history** (bool) - Optional - Plot the history of all parameters and gradients. - **store_all_simulations** (bool) - Optional - Indicates if the project file for each iteration should be stored. ``` -------------------------------- ### lumopt.utilities.plotter.Plotter Source: https://lumopt.readthedocs.io/en/latest/all_others.html Orchestrates the generation of plots during the optimization process. ```APIDOC ## Plotter Class /api/utilities/plotter ### Description Orchestrates the generation of plots during the optimization. ### Method N/A (Class) ### Endpoint N/A (Class) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **movie** (boolean) - Indicates if the evolution of parameters should be recorded as a movie. Defaults to True. - **plot_history** (boolean) - Indicates if we should plot the history of the parameters and gradients. Should be set to False for large numbers of parameters. Defaults to True. ### Request Example None ### Response #### Success Response (200) - **Plotter Object** - An instance of the Plotter class. #### Response Example None ``` -------------------------------- ### Define Splitter Geometry Functions Source: https://lumopt.readthedocs.io/en/latest/tutorial.html Functions to generate polygon points for two splitters with a 25nm offset. ```python initial_points_x = np.linspace(-1.0e-6, 1.0e-6, 10) initial_points_y = np.linspace(0.25e-6, 0.6e-6, initial_points_x.size) def taper_splitter_1(params = initial_points_y): points_x = np.concatenate(([initial_points_x.min() - 0.01e-6], initial_points_x, [initial_points_x.max() + 0.01e-6])) points_y = np.concatenate(([initial_points_y.min()], params, [initial_points_y.max()])) n_interpolation_points = 100 polygon_points_x = np.linspace(min(points_x), max(points_x), n_interpolation_points) interpolator = sp.interpolate.interp1d(points_x, points_y, kind = 'cubic') polygon_points_y = interpolator(polygon_points_x) polygon_points_up = [(x, y) for x, y in zip(polygon_points_x, polygon_points_y)] polygon_points_down = [(x, -y) for x, y in zip(polygon_points_x, polygon_points_y)] polygon_points = np.array(polygon_points_up[::-1] + polygon_points_down) return polygon_points dy = 25.0e-9 def taper_splitter_2(params = initial_points_y + dy): points_x = np.concatenate(([initial_points_x.min() - 0.01e-6], initial_points_x, [initial_points_x.max() + 0.01e-6])) points_y = np.concatenate(([initial_points_y.min() + dy], params, [initial_points_y.max() + dy])) n_interpolation_points = 100 polygon_points_x = np.linspace(min(points_x), max(points_x), n_interpolation_points) interpolator = sp.interpolate.interp1d(points_x, points_y, kind = 'cubic') polygon_points_y = interpolator(polygon_points_x) polygon_points_up = [(x, y) for x, y in zip(polygon_points_x, polygon_points_y)] polygon_points_down = [(x, -y) for x, y in zip(polygon_points_x, polygon_points_y)] polygon_points = np.array(polygon_points_up[::-1] + polygon_points_down) return polygon_points ``` -------------------------------- ### FunctionDefinedPolygon Class Source: https://lumopt.readthedocs.io/en/latest/geometries.html Constructs a polygon from a user defined function that takes the optimization parameters and returns a set of vertices defining a polygon. ```APIDOC ## FunctionDefinedPolygon Class ### Description Constructs a polygon from a user defined function that takes the optimization parameters and returns a set of vertices defining a polygon. The polygon vertices returned by the function must be defined as a numpy array of coordinate pairs np.array([(x0,y0),…,(xn,yn)]). THE VERTICES MUST BE ORDERED IN A COUNTER CLOCKWISE DIRECTION. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **func** (function) - Required - function that takes the optimization parameter values and returns a polygon. - **initial_params** (list) - Required - initial optimization parameter values. - **bounds** (list of tuples) - Required - bounding ranges (min/max pairs) for each optimization parameter. - **z** (float) - Required - center of polygon along the z-axis. - **depth** (float) - Required - span of polygon along the z-axis. - **eps_out** (float) - Required - permittivity of the material around the polygon. - **eps_in** (float) - Required - permittivity of the polygon material. - **edge_precision** (int) - Optional - number of quadrature points along each edge for computing the FOM gradient using the shape derivative approximation method. Defaults to 5. - **dx** (float) - Optional - step size for computing the FOM gradient using permittivity perturbations. Defaults to 1e-10. ### Request Example ```json { "func": "my_polygon_function", "initial_params": [0.5, 0.5], "bounds": [[0, 1], [0, 1]], "z": 0.0, "depth": 1.0, "eps_out": 1.0, "eps_in": 10.0, "edge_precision": 10, "dx": 1e-9 } ``` ### Response #### Success Response (200) This class does not have a direct API endpoint for request/response. It is a class definition. #### Response Example None ``` -------------------------------- ### FixedStepGradientDescent Source: https://lumopt.readthedocs.io/en/latest/optimizers.html Gradient descent with options for noise and parameter scaling. The update equation is defined based on the gradient and a step size. ```APIDOC ## Class: FixedStepGradientDescent ### Description Gradient descent with the option to add noise and a parameter scaling. The update equation is: `Delta p_i = (dFOM/dp_i) / max_j(|dFOM/dp_j|) * Delta x + noise_i` If `all_params_equal = True`, then the update equation is: `Delta p_i = sign(dFOM/dp_i) * Delta x + noise_i` If the optimization has many local optima: `noise = rand([-1,1]) * noise_magnitude`. ### Parameters - **max_dx** (float) - maximum allowed change of a parameter per iteration. - **max_iter** (int) - maximum number of iterations to run. - **all_params_equal** (bool) - if true, all parameters will be changed by +/- dx depending on the sign of their associated shape derivative. - **noise_magnitude** (float) - amplitude of the noise. - **scaling_factor** (float or list) - scalar or vector of the same length as the optimization parameters; typically used to scale the optimization parameters so that they have magnitudes in the range zero to one. ``` -------------------------------- ### Material Class Definition Source: https://lumopt.readthedocs.io/en/latest/materials.html Defines the Material class used to set permittivity and material names for geometric primitives. ```APIDOC ## Class: lumopt.utilities.materials.Material ### Description Represents the permittivity of a material associated with a geometric primitive in FDTD Solutions. Materials can be defined by a database name or by a base permittivity value. ### Parameters - **name** (string) - Optional - A valid material name from the material database (e.g., 'Si (Silicon) - Palik'). Defaults to ''. - **base_epsilon** (scalar) - Optional - The base permittivity value. Used when name is set to ''. Defaults to 1.0. - **mesh_order** (integer) - Optional - The order of material resolution for overlapping primitives. ``` -------------------------------- ### Define Splitter Geometry with LumOpt Source: https://lumopt.readthedocs.io/en/latest/tutorial.html Defines a customizable splitter geometry using a function that interpolates points to create a smooth polygon. This geometry is parameterized by y-coordinates of spline knots and includes bounds and material properties for simulation. ```python """ Copyright chriskeraly Copyright (c) 2019 Lumerical Inc. """ ######## IMPORTS ######## # General purpose imports import os import numpy as np import scipy as sp # Optimization specific imports from lumopt.utilities.wavelengths import Wavelengths from lumopt.geometries.polygon import FunctionDefinedPolygon from lumopt.figures_of_merit.modematch import ModeMatch from lumopt.optimizers.generic_optimizers import ScipyOptimizers from lumopt.optimization import Optimization ######## DEFINE BASE SIMULATION ######## base_script = os.path.join(os.path.dirname(__file__), 'splitter_base_TE_modematch.lsf') ######## DEFINE SPECTRAL RANGE ######### # Global wavelength/frequency range for all the simulations wavelengths = Wavelengths(start = 1300e-9, stop = 1800e-9, points = 21) ######## DEFINE OPTIMIZABLE GEOMETRY ######## # The class FunctionDefinedPolygon needs a parameterized Polygon (with points ordered # in a counter-clockwise direction). Here the geometry is defined by 10 parameters defining # the knots of a spline, and the resulting Polygon has 200 edges, making it quite smooth. initial_points_x = np.linspace(-1.0e-6, 1.0e-6, 10) initial_points_y = np.linspace(0.25e-6, 0.6e-6, initial_points_x.size) def taper_splitter(params = initial_points_y): ''' Defines a taper where the paramaters are the y coordinates of the nodes of a cubic spline. ''' points_x = np.concatenate(([initial_points_x.min() - 0.01e-6], initial_points_x, [initial_points_x.max() + 0.01e-6])) points_y = np.concatenate(([initial_points_y.min()], params, [initial_points_y.max()])) n_interpolation_points = 100 polygon_points_x = np.linspace(min(points_x), max(points_x), n_interpolation_points) interpolator = sp.interpolate.interp1d(points_x, points_y, kind = 'cubic') polygon_points_y = interpolator(polygon_points_x) polygon_points_up = [(x, y) for x, y in zip(polygon_points_x, polygon_points_y)] polygon_points_down = [(x, -y) for x, y in zip(polygon_points_x, polygon_points_y)] polygon_points = np.array(polygon_points_up[::-1] + polygon_points_down) return polygon_points # The geometry will pass on the bounds and initial parameters to the optimizer. bounds = [(0.2e-6, 0.8e-6)] * initial_points_y.size # The permittivity of the material making the optimizable geometry and the permittivity of the material surrounding # it must be defined. Since this is a 2D simulation, the depth has no importance. The edge precision defines the # discretization of the edges forming the optimizable polygon. It should be set such there are at least a few points # per mesh cell. An effective index of 2.8 is user to simulate a 2D slab of 220 nm thickness. geometry = FunctionDefinedPolygon(func = taper_splitter, initial_params = initial_points_y, bounds = bounds, z = 0.0, depth = 220e-9, eps_out = 1.44 ** 2, eps_in = 2.8 ** 2, edge_precision = 5, dx = 1e-9) ######## DEFINE FIGURE OF MERIT ######## # The base simulation script defines a field monitor named 'fom' at the point where we want to modematch to the 3rd mode (fundamental TE mode). fom = ModeMatch(monitor_name = 'fom', mode_number = 2, direction = 'Forward', multi_freq_src = True, target_T_fwd = lambda wl: np.ones(wl.size), norm_p = 1) ######## DEFINE OPTIMIZATION ALGORITHM ######## # This will run Scipy's implementation of the L-BFGS-B algoithm for at least 40 iterations. Since the variables are on the # order of 1e-6, thery are scale up to be on the order of 1. optimizer = ScipyOptimizers(max_iter = 30, method = 'L-BFGS-B', scaling_factor = 1e6, pgtol = 1e-5) ######## PUT EVERYTHING TOGETHER ######## opt = Optimization(base_script = base_script, wavelengths = wavelengths, fom = fom, geometry = geometry, optimizer = optimizer, hide_fdtd_cad = False, use_deps = True) ######## RUN THE OPTIMIZER ######## opt.run() ``` -------------------------------- ### lumopt.utilities.fields.Fields Class Source: https://lumopt.readthedocs.io/en/latest/all_others.html Represents a container for raw field data from a field monitor. It facilitates interpolation and evaluation of fields at any point in space. It is recommended to use the `get_fields` method from `lumopt.lumerical_methods.lumerical_scripts` to create instances of this class. ```APIDOC ## Class lumopt.utilities.fields.Fields ### Description Container for the raw fields from a field monitor. Several interpolation objects are created internally to evaluate the fields at any point in space. Use the auxiliary :method:lumopt.lumerical_methods.lumerical_scripts.get_fields to create this object. ### Parameters - **x** - Description of x parameter - **y** - Description of y parameter - **z** - Description of z parameter - **wl** - Description of wl parameter - **E** - Description of E parameter - **D** - Description of D parameter - **H** - Description of H parameter - **eps** - Description of eps parameter ## Method: scale ### Description Scales the E, D and H field arrays along the specified dimension using the provided weighting factors. ### Parameters #### Path Parameters - **dimension** (int) - 0 (x-axis), 1 (y-axis), 2 (z-axis), (3) frequency and (4) vector component. - **factors** (list or vector) - list or vector of weighting factors of the same size as the target field dimension. ### Request Example ```json { "dimension": 0, "factors": [1.0, 0.5, 1.0] } ``` ### Response #### Success Response (200) - **Scaled Fields** (object) - The fields object with scaled E, D, and H arrays. #### Response Example ```json { "scaled_E": [...], "scaled_D": [...], "scaled_H": [...] } ``` ``` -------------------------------- ### lumopt.utilities.scipy_wrappers.wrapped_GridInterpolator Source: https://lumopt.readthedocs.io/en/latest/all_others.html A wrapper around SciPy's RegularGridInterpolator for handling interpolation with potentially uneven grid spacing. ```APIDOC ## wrapped_GridInterpolator Function /api/utilities/scipy_wrappers ### Description This is a wrapper around Scipy’s RegularGridInterpolator so that it can deal with entries of 1 dimension. Original doc: The data must be defined on a regular grid; the grid spacing however may be uneven. Linear and nearest-neighbour interpolation are supported. After setting up the interpolator object, the interpolation method (_linear_ or _nearest_) may be chosen at each evaluation. ### Method N/A (Function) ### Endpoint N/A (Function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **points** (tuple of ndarray of float) - The points defining the regular grid in n dimensions. Shapes: (m1, ), …, (mn, ). - **values** (array_like) - The data on the regular grid in n dimensions. Shape: (m1, …, mn, …). - **method** (str, optional) - The method of interpolation to perform. Supported are “linear” and “nearest”. This parameter will become the default for the object’s `__call__` method. Default is “linear”. - **bounds_error** (bool, optional) - If True, when interpolated values are requested outside of the domain of the input data, a ValueError is raised. If False, then fill_value is used. Default is True. - **fill_value** (number, optional) - If provided, the value to use for points outside of the interpolation domain. If None, values outside the domain are extrapolated. ### Request Example None ### Response #### Success Response (200) - **Interpolator Object** - An interpolator object that can be called to perform interpolation. #### Response Example None ``` -------------------------------- ### lumopt.utilities.gradients.GradientFields Class Source: https://lumopt.readthedocs.io/en/latest/all_others.html Combines forward and adjoint fields to compute the integral for the partial derivatives of the figure of merit (FOM) with respect to shape parameters. ```APIDOC ## Class lumopt.utilities.gradients.GradientFields ### Description Combines the forward and adjoint fields (collected by the constructor) to generate the integral used to compute the partial derivatives of the figure of merit (FOM) with respect to the shape parameters. ### Parameters - **forward_fields** - Description of forward_fields parameter - **adjoint_fields** - Description of adjoint_fields parameter ## Method: boundary_perturbation_integrand ### Description Generates the integral kernel in equation 5.28 of Owen Miller’s thesis used to approximate the partial derivatives of the FOM with respect to the optimization parameters. ### Request Example ```json { "message": "Call boundary_perturbation_integrand" } ``` ### Response #### Success Response (200) - **Integrand Kernel** (float) - The computed value of the integral kernel. #### Response Example ```json { "integrand_value": 1.2345 } ``` ``` -------------------------------- ### Define Mesh Refinement Source: https://lumopt.readthedocs.io/en/latest/tutorial.html Adds a mesh refinement region over the optimizable area. ```Lumerical Script addmesh; set('x',0); set('x span',finer_mesh_size+2.0*mesh_x); set('y',0); set('y span',finer_mesh_size); set('dx',mesh_x); set('dy',mesh_y); ``` -------------------------------- ### Polygon Class Source: https://lumopt.readthedocs.io/en/latest/geometries.html Defines a polygon with vertices on the (x,y)-plane that are extruded along the z direction to create a 3-D shape. ```APIDOC ## Polygon Class ### Description Defines a polygon with vertices on the (x,y)-plane that are extruded along the z direction to create a 3-D shape. The vertices are defined as a numpy array of coordinate pairs np.array([(x0,y0),…,(xn,yn)]). THE VERTICES MUST BE ORDERED IN A COUNTER CLOCKWISE DIRECTION. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **points** (array) - Required - array of shape (N,2) defining N polygon vertices. - **z** (float) - Required - center of polygon along the z-axis. - **depth** (float) - Required - span of polygon along the z-axis. - **eps_out** (float) - Required - permittivity of the material around the polygon. - **eps_in** (float) - Required - permittivity of the polygon material. - **edge_precision** (int) - Required - number of quadrature points along each edge for computing the FOM gradient using the shape derivative approximation method. ### Request Example ```json { "points": [[0,0], [1,0], [1,1], [0,1]], "z": 0.0, "depth": 1.0, "eps_out": 1.0, "eps_in": 10.0, "edge_precision": 10 } ``` ### Response #### Success Response (200) This class does not have a direct API endpoint for request/response. It is a class definition. #### Response Example None ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.