-
Notifications
You must be signed in to change notification settings - Fork 77
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Squashed commit of several new features and enhancements from Lumerical:
- Support for a broadband figure of merit with no additional FDTD simulations. Uses the time domain simulation to extract a user specified number of frequency samples to compute a figure of merit over a spectrum. Figure of merit is specified as the mean of the target spectrum minus the error p-norm - Restored the fixed and adaptive step gradient descent optimization algorithms as alternatives to SciPy - Added a new example of a splitter with output arms included in the optimized shape - Improved performance of mesh (use_deps=True) by only producing mesh at a single frequency - Added flag to hide FDTD Solutions graphical interface
- Loading branch information
1 parent
c9447b7
commit 8f779f8
Showing
42 changed files
with
1,833 additions
and
861 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import os as _os | ||
import unittest as _unittest | ||
import xmlrunner | ||
|
||
TestCase = _unittest.TestCase | ||
|
||
def run(filenames): | ||
for filename in filenames: | ||
_os.chdir(_os.path.abspath(_os.path.dirname(filename))) | ||
filename = _os.path.basename(filename) | ||
module_name = filename.replace(".py", "") | ||
suite = _unittest.TestLoader().loadTestsFromName(module_name) | ||
with open(module_name+".xml", "w") as output: | ||
xmlrunner.XMLTestRunner(output=output, verbosity=2).run(suite) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
""" Copyright chriskeraly | ||
Copyright (c) 2019 Lumerical Inc. """ | ||
|
||
######## IMPORTS ######## | ||
# General purpose imports | ||
import os | ||
import numpy as np | ||
import scipy as sp | ||
|
||
from lumopt.utilities.load_lumerical_scripts import load_from_lsf | ||
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 = load_from_lsf(os.path.join(os.path.dirname(__file__), 'splitter_base_TE_modematch.lsf')) | ||
script_2 = load_from_lsf(os.path.join(os.path.dirname(__file__), 'splitter_base_TE_modematch_25nmoffset.lsf')) | ||
|
||
######## DEFINE OPTIMIZABLE GEOMETRY ######## | ||
|
||
## Here the two splitters just have a 25nm offset from each other, so that the result is robust | ||
def taper_splitter_1(params,n_points=10): | ||
points_x = np.concatenate(([-1.01e-6],np.linspace(-1.1e-6,0.9e-6,10),[1.01e-6])) | ||
points_y = np.concatenate(([0.25e-6],params,[0.6e-6])) | ||
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 = [max(min(point,1e-6),-1e-6) for point in 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 | ||
|
||
dx=25e-9 | ||
def taper_splitter_2(params,n_points=10): | ||
points_x = np.concatenate(([-1.01e-6],np.linspace(-1.1e-6,0.9e-6,10),[1.01e-6])) | ||
points_y = np.concatenate(([0.25e-6+dx],params+dx,[0.6e-6+dx])) | ||
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 = [max(min(point,1e-6),-1e-6) for point in 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 | ||
|
||
bounds = [(0.2e-6, 1e-6)]*10 | ||
# final value 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_params, 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_params, 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) | ||
|
||
######## 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') | ||
fom_2 = ModeMatch(monitor_name = 'fom', mode_number = 3, direction = 'Forward') | ||
|
||
######## 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) | ||
optimizer_2 = ScipyOptimizers(max_iter = 40) | ||
|
||
######## PUT EVERYTHING TOGETHER ######## | ||
opt_1 = Optimization(base_script = script_1, wavelengths = wavelengths, fom = fom_1, geometry = geometry_1, optimizer = optimizer_1) | ||
opt_2 = Optimization(base_script = script_2, wavelengths = wavelengths, fom = fom_2, geometry = geometry_2, optimizer = optimizer_2) | ||
opt = opt_1 + opt_2 | ||
|
||
######## RUN THE OPTIMIZER ######## | ||
opt.run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
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; | ||
|
||
## GEOMETRY | ||
|
||
#INPUT WAVEGUIDE | ||
|
||
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); | ||
|
||
#OUTPUT WAVEGUIDES | ||
|
||
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); | ||
|
||
## SOURCE | ||
addmode; | ||
set('direction','Forward'); | ||
set('injection axis','x-axis'); | ||
#set('polarization angle',0); | ||
set('y',0); | ||
set('x',-1.25e-6); | ||
set('override global source settings',false); | ||
set('mode selection','fundamental TE mode'); | ||
|
||
## FDTD | ||
addfdtd; | ||
set('dimension','2D'); | ||
set('background index',1.44); | ||
set('mesh accuracy',4); | ||
set('x min',-size_x/2); | ||
set('x max',size_x/2); | ||
set('y min',-size_y/2); | ||
set('y max',size_y/2); | ||
set('force symmetric y mesh',1); | ||
|
||
## MESH IN OPTIMIZABLE REGION | ||
addmesh; | ||
set('x',0); | ||
set('x span',finer_mesh_size); | ||
set('y',0); | ||
set('y span',finer_mesh_size); | ||
set('dx',mesh_x); | ||
set('dy',mesh_y); | ||
|
||
## OPTIMIZATION FIELDS MONITOR IN OPTIMIZABLE REGION | ||
addpower; | ||
set('name','opt_fields'); | ||
set('monitor type','2D Z-normal'); | ||
set('x min',-size_x/2); | ||
set('x max',1.1e-6); | ||
set('y min',-size_y/2); | ||
set('y max',size_y/2); | ||
|
||
## FOM FIELDS | ||
|
||
addpower; | ||
set('name','fom'); | ||
set('monitor type','2D X-normal'); | ||
set('x',1.25e-6); | ||
set('y min',-1e-6); | ||
set('y max',1e-6); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
switchtolayout; | ||
selectall; | ||
delete; | ||
|
||
## SIM PARAMS | ||
size_x=3e-6; | ||
size_y=3e-6; | ||
mesh_x=10e-9; | ||
mesh_y=10e-9; | ||
finer_mesh_size=2.5e-6; | ||
offset=25e-9; | ||
|
||
## GEOMETRY | ||
|
||
#INPUT WAVEGUIDE | ||
|
||
addrect; | ||
set('name','input wg'); | ||
set('x span',3e-6); | ||
set('y span',0.5e-6+2*offset); | ||
set('z span',220e-9); | ||
set('y',0); | ||
set('x',-2.5e-6); | ||
set('index',2.8); | ||
|
||
#OUTPUT WAVEGUIDES | ||
|
||
addrect; | ||
set('name','output wg top'); | ||
set('x span',3e-6); | ||
set('y span',0.5e-6+2*offset); | ||
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+2*offset); | ||
set('z span',220e-9); | ||
set('y',-0.35e-6); | ||
set('x',2.5e-6); | ||
set('index',2.8); | ||
|
||
## SOURCE | ||
addmode; | ||
set('direction','Forward'); | ||
set('injection axis','x-axis'); | ||
#set('polarization angle',0); | ||
set('y',0); | ||
set('x',-1.25e-6); | ||
set('override global source settings',false); | ||
set('mode selection','fundamental TE mode'); | ||
|
||
## FDTD | ||
addfdtd; | ||
set('dimension','2D'); | ||
set('background index',1.44); | ||
set('mesh accuracy',4); | ||
set('x min',-size_x/2); | ||
set('x max',size_x/2); | ||
set('y min',-size_y/2); | ||
set('y max',size_y/2); | ||
set('force symmetric y mesh',1); | ||
|
||
|
||
## MESH IN OPTIMIZABLE REGION | ||
addmesh; | ||
set('x',0); | ||
set('x span',finer_mesh_size); | ||
set('y',0); | ||
set('y span',finer_mesh_size); | ||
set('dx',mesh_x); | ||
set('dy',mesh_y); | ||
|
||
## OPTIMIZATION FIELDS MONITOR IN OPTIMIZABLE REGION | ||
addpower; | ||
set('name','opt_fields'); | ||
set('monitor type','2D Z-normal'); | ||
set('x min',-size_x/2); | ||
set('x max',1.1e-6); | ||
set('y min',-size_y/2); | ||
set('y max',size_y/2); | ||
|
||
## FOM FIELDS | ||
|
||
addpower; | ||
set('name','fom'); | ||
set('monitor type','2D X-normal'); | ||
set('x',1.25e-6); | ||
set('y min',-1e-6); | ||
set('y max',1e-6); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
switchtolayout; | ||
selectall; | ||
delete; | ||
|
||
###SIM PARAMS | ||
size_x=3e-6; | ||
size_y=2.5e-6; | ||
size_z=1.2e-6; | ||
mesh_x=20e-9; | ||
mesh_y=20e-9; | ||
mesh_z=20e-9; | ||
finer_mesh_size=3e-6; | ||
finer_mesh_size_z=0.6e-6; | ||
|
||
##GEOMETRY | ||
|
||
#INPUT WAVEGUIDE | ||
|
||
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('material','Si (Silicon) - Palik'); | ||
|
||
|
||
##OUTPUT WAVEGUIDES | ||
|
||
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('material','Si (Silicon) - Palik'); | ||
|
||
|
||
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('material','Si (Silicon) - Palik'); | ||
|
||
|
||
#SOURCE | ||
addmode; | ||
set('direction','Forward'); | ||
set('injection axis','x-axis'); | ||
#set('polarization angle',0); | ||
set('y',0); | ||
set('y span',2e-6); | ||
set('x',-1.25e-6); | ||
set('z',0); | ||
set('z span',1e-6); | ||
set('override global source settings',false); | ||
set('mode selection','fundamental TE mode'); | ||
|
||
#FDTD | ||
addfdtd; | ||
set('dimension','3D'); | ||
set('background index',1.44); | ||
set('mesh accuracy',4); | ||
set('x min',-size_x/2); | ||
set('x max',size_x/2); | ||
set('y min',-size_y/2); | ||
set('y max',size_y/2); | ||
set('z min',-size_z/2); | ||
set('z max',size_z/2); | ||
set('force symmetric y mesh',1); | ||
set('force symmetric z mesh',1); | ||
#set('z min bc','Symmetric'); | ||
#set('y min bc','Anti-Symmetric'); | ||
|
||
addmesh; | ||
set('x',0); | ||
set('x span',finer_mesh_size); | ||
set('y',0); | ||
set('y span',finer_mesh_size); | ||
set('z',0); | ||
set('z span',finer_mesh_size_z); | ||
set('dx',mesh_x); | ||
set('dy',mesh_y); | ||
set('dx',mesh_z); | ||
|
||
#Optimization fields | ||
addpower; | ||
set('name','opt_fields'); | ||
set('monitor type','3D'); | ||
set('x min',-size_x/2); | ||
set('x max',1.1e-6); | ||
set('y min',-size_y/2); | ||
set('y max',size_y/2); | ||
set('z min',-0.4e-6); | ||
set('z max',0.4e-6); | ||
|
||
|
||
#FOM FIELDS | ||
|
||
addpower; | ||
set('name','fom'); | ||
set('monitor type','2D X-normal'); | ||
set('x',1.26e-6); | ||
set('y min',-1e-6); | ||
set('y max',1e-6); | ||
set('z min',-0.5e-6); | ||
set('z max',0.5e-6); |
Oops, something went wrong.