def test_co_optimization_in_2D(self):
     print("2D TE-TM co-optimization (use_deps = True): ")
     #base_script, wavelengths, fom, geometry, optimizer, use_var_fdtd = False, hide_fdtd_cad = False, use_deps = True, plot_history = True, store_all_simulations = True
     optTE = Optimization(base_script=self.base_TE_sim,
                          wavelengths=self.wavelengths,
                          fom=self.fom,
                          geometry=self.geometry,
                          optimizer=self.optimizer,
                          use_var_fdtd=False,
                          hide_fdtd_cad=True,
                          use_deps=True,
                          plot_history=False,
                          store_all_simulations=False)
     optTM = Optimization(base_script=self.base_TM_sim,
                          wavelengths=self.wavelengths,
                          fom=self.fom,
                          geometry=self.geometry,
                          optimizer=self.optimizer,
                          use_var_fdtd=False,
                          hide_fdtd_cad=True,
                          use_deps=True,
                          plot_history=False,
                          store_all_simulations=False)
     opt = optTE + optTM
     fom, params = opt.run()
     self.assertGreaterEqual(fom, 1.99990)
     reference_value = self.wg_width / 2.0 * self.optimizer.scaling_factor[0]
     self.assertAlmostEqual(params[0], reference_value)
     self.assertAlmostEqual(params[1], reference_value)
Example #2
0
 def test_shape_boundary_approximation_in_3D(self):
     print(
         "3D optimization with shape boundary approximation (use_deps = False): "
     )
     self.geometry.bounds = [(0.0, self.wg_width / 2.0 - self.mesh_del)
                             ] * len(self.geometry.bounds)
     # Note: bounds are tweaked since the shape boundary approximation method does not work
     #       when the shape under optimization touches the boundary of the FDTD region.
     opt = Optimization(base_script=self.base_script +
                        "setnamed('FDTD','dimension','3D');",
                        wavelengths=self.wavelengths,
                        fom=self.fom,
                        geometry=self.geometry,
                        optimizer=self.optimizer,
                        hide_fdtd_cad=True,
                        use_deps=False,
                        plot_history=False,
                        store_all_simulations=False)
     fom, params = opt.run()
     self.assertGreaterEqual(fom, 0.972)
     self.assertAlmostEqual(params[0],
                            (self.wg_width / 2.0 - self.mesh_del) *
                            self.optimizer.scaling_factor)
     self.assertAlmostEqual(params[1],
                            (self.wg_width / 2.0 - self.mesh_del) *
                            self.optimizer.scaling_factor)
Example #3
0
 def test_shape_boundary_approximation(self):
     print(
         "varFDTD optimization with shape boundary approximation (use_deps = False): "
     )
     self.geometry.bounds = [
         (self.mesh_del, self.wg_width / 2.0 - self.mesh_del)
     ] * len(self.geometry.bounds)
     opt = Optimization(base_script=self.base_script,
                        wavelengths=self.wavelengths,
                        fom=self.fom,
                        geometry=self.geometry,
                        optimizer=self.optimizer,
                        use_var_fdtd=True,
                        hide_fdtd_cad=True,
                        use_deps=False,
                        plot_history=False,
                        store_all_simulations=False)
     fom, params = opt.run()
     self.assertGreaterEqual(fom, 0.972)
     self.assertAlmostEqual(params[0],
                            (self.wg_width / 2.0 - self.mesh_del) *
                            self.optimizer.scaling_factor)
     self.assertAlmostEqual(params[1],
                            (self.wg_width / 2.0 - self.mesh_del) *
                            self.optimizer.scaling_factor)
def runSim(params,
           eps_bg,
           eps_wg,
           x_pos,
           y_pos,
           size_x,
           filter_R,
           beta_start=1):

    ######## DEFINE A 2D TOPOLOGY OPTIMIZATION REGION ########
    geometry = TopologyOptimization2D(params=params,
                                      eps_min=eps_bg,
                                      eps_max=eps_wg,
                                      x=x_pos,
                                      y=y_pos,
                                      z=0,
                                      filter_R=filter_R,
                                      beta=beta_start)

    ######## DEFINE FIGURE OF MERIT ########
    # The base simulation script defines a field monitor named 'fom' at the point where we want to modematch to the fundamental TE mode
    fom = ModeMatch(monitor_name='fom',
                    mode_number='Fundamental TE mode',
                    direction='Forward',
                    norm_p=2)

    ######## DEFINE OPTIMIZATION ALGORITHM ########
    optimizer = ScipyOptimizers(max_iter=50,
                                method='L-BFGS-B',
                                scaling_factor=1,
                                pgtol=1e-6,
                                ftol=1e-4,
                                target_fom=0.5,
                                scale_initial_gradient_to=0.25)

    ######## LOAD TEMPLATE SCRIPT AND SUBSTITUTE PARAMETERS ########
    script = load_from_lsf(
        os.path.join(CONFIG['root'],
                     'examples/Ysplitter/splitter_base_2D_TE_topology.lsf'))
    script = script.replace('opt_size_x=3.5e-6',
                            'opt_size_x={:1.6g}'.format(size_x))

    wavelengths = Wavelengths(start=1450e-9, stop=1650e-9, points=11)
    opt = Optimization(base_script=script,
                       wavelengths=wavelengths,
                       fom=fom,
                       geometry=geometry,
                       optimizer=optimizer,
                       use_deps=False,
                       hide_fdtd_cad=True,
                       plot_history=False,
                       store_all_simulations=False)

    ######## RUN THE OPTIMIZER ########
    opt.run()
Example #5
0
 def setUp(self):
     # base script
     self.base_script = load_from_lsf(os.path.join(self.file_dir, 'modematch_parallel_plate_waveguide_TM_base.lsf'))
     # bandwidth        
     self.wavelengths = Wavelengths(start = 1540e-9, stop = 1560e-9, points = 3)
     # simulation
     self.sim = Simulation(workingDir = self.file_dir, hide_fdtd_cad = True)
     self.sim.fdtd.eval(self.base_script)
     Optimization.set_global_wavelength(self.sim, self.wavelengths)
     # reference
     self.ref_fom = 0.6643986
Example #6
0
 def test_broadband(self):
     print("Broadband optimization results:")
     opt = Optimization(base_script = self.base_script, 
                        wavelengths = self.wavelengths,
                        fom = self.fom,
                        geometry = self.geometry,
                        optimizer = self.optimizer,
                        hide_fdtd_cad = True,
                        use_deps = True)
     fom, params = opt.run()
     self.assertAlmostEqual(params[0], 2.050400e-7 * self.optimizer.scaling_factor, 5)
     self.assertGreaterEqual(fom, 0.4618)
Example #7
0
 def test_no_forward_injection_in_2D(self):
     """ Test no forward injection in 2D with mode source in vacuum. """
     self.fom = ModeMatch(monitor_name = 'figure_of_merit',
                          mode_number = 2, # evanescent mode
                          direction = 'Forward',
                          multi_freq_src = False,
                          target_T_fwd = lambda wl: np.ones(wl.size),
                          norm_p = 1)
     Optimization.set_source_wavelength(self.sim, 'source', self.fom.multi_freq_src, len(self.wavelengths))
     self.sim.fdtd.setnamed('FDTD','dimension','2D')
     self.fom.add_to_sim(self.sim)
     self.sim.run(name = 'modematch_no_forward_injection_in_2D', iter = 3)
     FOM = self.fom.get_fom(self.sim)
     self.assertAlmostEqual(FOM, 0.0, 5)
 def test_broadband_optimization(self):
     print("Broadband optimization results (use_deps = True):")
     opt = Optimization(base_script=self.base_script,
                        wavelengths=self.wavelengths,
                        fom=self.fom,
                        geometry=self.geometry,
                        optimizer=self.optimizer,
                        use_var_fdtd=False,
                        hide_fdtd_cad=True,
                        use_deps=True,
                        plot_history=False,
                        store_all_simulations=False)
     fom, params = opt.run()
     self.assertAlmostEqual(params[0],
                            2.050375e-7 * self.optimizer.scaling_factor[0],
                            4)
     self.assertGreaterEqual(fom, 0.461815)
 def test_forward_injection_in_2D(self):
     """ Test forward injection in 2D with mode source in vacuum. """
     self.fom = ModeMatch(monitor_name='figure_of_merit',
                          mode_number=1,
                          direction='Forward',
                          multi_freq_src=True,
                          target_T_fwd=lambda wl: np.ones(wl.size),
                          norm_p=1)
     Optimization.set_source_wavelength(self.sim, 'source',
                                        self.fom.multi_freq_src,
                                        len(self.wavelengths))
     self.sim.fdtd.setnamed('FDTD', 'dimension', '2D')
     self.fom.initialize(self.sim)
     self.fom.make_forward_sim(self.sim)
     self.sim.run(name='modematch_forward_injection_in_2D', iter=2)
     FOM = self.fom.get_fom(self.sim)
     self.assertAlmostEqual(FOM, self.ref_fom, 4)
Example #10
0
 def test_backward_injection_in_3D(self):
     """ Test backward injection in 3D with mode source in dielectric region. """
     self.fom = ModeMatch(monitor_name = 'figure_of_merit',
                          mode_number = 1,
                          direction = 'Backward',
                          multi_freq_src = True,
                          target_T_fwd = lambda wl: np.ones(wl.size),
                          norm_p = 1)
     Optimization.set_source_wavelength(self.sim, 'source', self.fom.multi_freq_src, len(self.wavelengths))
     self.sim.fdtd.setnamed('FDTD','dimension','3D')
     self.sim.fdtd.setnamed('source', 'x', -self.sim.fdtd.getnamed('source','x'))
     self.sim.fdtd.setnamed('source','direction','Backward')
     self.sim.fdtd.setnamed('figure_of_merit','x', -self.sim.fdtd.getnamed('figure_of_merit','x'))
     self.fom.add_to_sim(self.sim)
     self.sim.run(name = 'modematch_backward_injection_in_3D', iter = 1)
     FOM = self.fom.get_fom(self.sim)
     self.assertAlmostEqual(FOM, self.ref_fom, 5)
Example #11
0
 def test_single_frequency(self):
     print("Single frequency optimization results:")
     self.fom.target_T_fwd = lambda wl: np.ones(wl.size)
     self.fom.multi_freq_src = False
     self.wavelengths = 1550.0e-9
     self.optimizer.scaling_factor = 2.0e7
     self.optimizer.pgtol = 3.1e-2
     opt = Optimization(base_script = self.base_script, 
                        wavelengths = self.wavelengths,
                        fom = self.fom,
                        geometry = self.geometry,
                        optimizer = self.optimizer,
                        hide_fdtd_cad = True,
                        use_deps = True)
     fom, params = opt.run()
     self.assertAlmostEqual(params[0], 2.058006e-7 * self.optimizer.scaling_factor, 5)
     self.assertGreaterEqual(fom, 0.9192)
 def test_permittivity_derivatives_in_2D(self):
     print(
         "2D optimization with permittivity derivatives (use_deps = True): "
     )
     opt = Optimization(base_script=self.base_script +
                        "setnamed('FDTD','dimension','2D');",
                        wavelengths=self.wavelengths,
                        fom=self.fom,
                        geometry=self.geometry,
                        optimizer=self.optimizer,
                        hide_fdtd_cad=True,
                        use_deps=True)
     fom, params = opt.run()
     self.assertGreaterEqual(fom, 0.99991)
     self.assertAlmostEqual(
         params[0], self.wg_width / 2.0 * self.optimizer.scaling_factor)
     self.assertAlmostEqual(
         params[1], self.wg_width / 2.0 * self.optimizer.scaling_factor)
Example #13
0
 def test_permittivity_derivatives(self):
     print(
         "varFDTD optimization with permittivity derivatives (use_deps = True): "
     )
     opt = Optimization(base_script=self.base_script,
                        wavelengths=self.wavelengths,
                        fom=self.fom,
                        geometry=self.geometry,
                        optimizer=self.optimizer,
                        use_var_fdtd=True,
                        hide_fdtd_cad=True,
                        use_deps=True,
                        plot_history=False,
                        store_all_simulations=False)
     fom, params = opt.run()
     self.assertGreaterEqual(fom, 0.99991)
     self.assertAlmostEqual(
         params[0], self.wg_width / 2.0 * self.optimizer.scaling_factor)
     self.assertAlmostEqual(
         params[1], self.wg_width / 2.0 * self.optimizer.scaling_factor)
 def test_single_wavelength_legacy_optimization(self):
     print("Single wavelength optimization results (use_deps = False):")
     self.fom.target_T_fwd = lambda wl: np.ones(wl.size)
     self.fom.multi_freq_src = False
     self.wavelengths = 1550.0e-9
     self.optimizer.scaling_factor = np.array(2.0e7)
     self.optimizer.pgtol = 3.1e-2
     opt = Optimization(base_script=self.base_script,
                        wavelengths=self.wavelengths,
                        fom=self.fom,
                        geometry=self.geometry,
                        optimizer=self.optimizer,
                        use_var_fdtd=False,
                        hide_fdtd_cad=True,
                        use_deps=False,
                        plot_history=False,
                        store_all_simulations=False)
     fom, params = opt.run()
     self.assertAlmostEqual(params[0],
                            2.05609116e-7 * self.optimizer.scaling_factor,
                            4)
     self.assertGreaterEqual(fom, 0.91905)
    def __init__(self, max_iter, method, scaling_factor, pgtol, ftol,
                 wavelength_start, wavelength_stop, wavelength_points,
                 build_simulation, fom, geometry, hide_fdtd_cad):

        # The optimizer must be generated anew at each iteration
        self._new_local_optimizer = ScipyOptimizers(
            max_iter=max_iter,
            method=method,
            scaling_factor=scaling_factor,
            ftol=ftol,
            pgtol=pgtol)

        self._wl = Wavelengths(start=wavelength_start,
                               stop=wavelength_stop,
                               points=wavelength_points)

        self._optimization = Optimization(base_script=build_simulation,
                                          wavelengths=self._wl,
                                          fom=fom,
                                          geometry=geometry,
                                          optimizer=self._new_local_optimizer,
                                          hide_fdtd_cad=hide_fdtd_cad,
                                          use_deps=True)
Example #16
0
######## 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)

######## 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()
Example #17
0
                                      eps_out=1.44**2,
                                      eps_in=2.8**2,
                                      bounds=bounds,
                                      depth=220e-9,
                                      edge_precision=5)

######## DEFINE FIGURE OF MERIT ########
# Although we are optimizing for the same thing, two separate fom objects must be create

fom_1 = ModeMatch(modeorder=3)
fom_2 = ModeMatch(modeorder=3)

######## 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,
                     fom=fom_1,
                     geometry=geometry_1,
                     optimizer=optimizer_1)
opt_2 = Optimization(base_script=script_2,
                     fom=fom_2,
                     geometry=geometry_2,
                     optimizer=optimizer_2)

opt = opt_1 + opt_2

######## RUN THE OPTIMIZER ########
opt.run()
Example #18
0
def runGratingOptimization(bandwidth_in_nm, etch_depth, n_grates, params):

    bounds = [(0.1, 1)] * 4
    bounds[0] = (-3, 3)  #< Starting position
    bounds[1] = (0, 0.1)  #< Scaling parameter R
    bounds[2] = (1.5, 3)  #< Parameter a
    bounds[3] = (0, 2)  #< Parameter b

    def grating_params_pos(params,
                           output_waveguide_length=0.5e-6,
                           height=220e-9,
                           y0=0):
        x_begin = -3e-6
        y3 = y0 + height
        y1 = y3 - etch_depth

        x_start = params[0] * 1e-6  #< First parameter is the starting position
        x0 = x_start
        R = params[1] * 1e6  #< second parameter (unit is 1/um)
        a = params[2]  #< Third parameter (dim-less)
        b = params[3]  #< Fourth parameter (dim-less)

        verts = np.array([[x_begin, y0], [x_begin, y3], [x0, y3], [x0, y1]])

        lambda_c = 1.55e-6
        F0 = 0.95

        ## Iterate over all but the last
        for i in range(n_grates - 1):
            F = F0 - R * (x0 - x_start)
            Lambda = lambda_c / (a + F * b)
            x1 = x0 + (1 - F) * Lambda  #< Width of the etched region
            x2 = x0 + Lambda  #< Rest of cell
            verts = np.concatenate(
                (verts, [[x1, y1], [x1, y3], [x2, y3], [x2, y1]]), axis=0)
            x0 = x2

        F = F0 - R * (x0 - x_start)
        Lambda = lambda_c / (a + F * b)
        x1 = x0 + (1 - F) * Lambda  #< Width of the etched region
        x_end = x1 + output_waveguide_length
        verts = np.concatenate(
            (verts, [[x1, y1], [x1, y3], [x_end, y3], [x_end, y0]]), axis=0)

        return verts

    geometry = FunctionDefinedPolygon(func=grating_params_pos,
                                      initial_params=params,
                                      bounds=bounds,
                                      z=0.0,
                                      depth=110e-9,
                                      eps_out=1.44**2,
                                      eps_in=3.47668**2,
                                      edge_precision=5,
                                      dx=1e-3)

    ######## DEFINE FIGURE OF MERIT ########
    fom = ModeMatch(monitor_name='fom',
                    mode_number=1,
                    direction='Backward',
                    target_T_fwd=lambda wl: np.ones(wl.size),
                    norm_p=1)

    ######## DEFINE OPTIMIZATION ALGORITHM ########
    optimizer = ScipyOptimizers(max_iter=25,
                                method='L-BFGS-B',
                                scaling_factor=1,
                                pgtol=1e-6)

    ######## DEFINE BASE SIMULATION ########
    base_script = load_from_lsf(
        os.path.join(os.path.dirname(__file__),
                     'grating_coupler_2D_2etch.lsf'))

    ######## PUT EVERYTHING TOGETHER ########
    lambda_start = 1550 - bandwidth_in_nm / 2
    lambda_end = 1550 + bandwidth_in_nm / 2
    lambda_pts = int(bandwidth_in_nm / 10) + 1
    wavelengths = Wavelengths(start=lambda_start * 1e-9,
                              stop=lambda_end * 1e-9,
                              points=lambda_pts)
    opt = Optimization(base_script=base_script,
                       wavelengths=wavelengths,
                       fom=fom,
                       geometry=geometry,
                       optimizer=optimizer,
                       hide_fdtd_cad=True,
                       use_deps=True)

    ######## RUN THE OPTIMIZER ########
    opt.run()
Example #19
0
    from lumopt.geometries.polygon import function_defined_Polygon
    from lumopt.utilities.materials import Material
    from lumopt import CONFIG
    import scipy

    script = load_from_lsf(os.path.join(CONFIG['root'], 'examples/staight_waveguide/straight_waveguide.lsf'))

    fom = ModeMatch(modeorder=2, precision=50)
    optimizer = ScipyOptimizers(max_iter=20)
    nx=401
    ny=101
    eps = np.ones((nx, ny))*1.44 ** 2
    eps[90, 10] = 10
    geometry = ContinousEpsilon2D(eps=eps, x=np.linspace(-1e-6, 1e-6, nx), y=np.linspace(-0.4e-6, 0.4e-6, ny))
    # function_defined_Polygon(func=waveguide, initial_params=np.linspace(0.25e-6, 0.25e-6, 10),
    #                                     eps_out=Material(1.44 ** 2), eps_in=Material(2.8 ** 2, 2), bounds=bounds,
    #                                     depth=220e-9,
    #                                     edge_precision=5)

    # geometry=Polygon(eps_in=2.8**2,eps_out=1.44**2)
    opt = Optimization(base_script=script, fom=fom, geometry=geometry, optimizer=optimizer)
    # opt.run()
    ##
    opt.initialize()
    eps,x,y,z=opt.geometry.get_eps()

    x_geo=opt.geometry.x
    y_geo=opt.geometry.y


    print 'ha'
Example #20
0
######## DEFINE OPTIMIZATION ALGORITHM ########
#For the optimizer, they should all be set the same, but different objects. Eventually this will be improved
optimizer_1550 = ScipyOptimizers(max_iter=40,
                                 method='L-BFGS-B',
                                 scaling_factor=1e6,
                                 pgtol=1e-9)
optimizer_1310 = ScipyOptimizers(max_iter=40,
                                 method='L-BFGS-B',
                                 scaling_factor=1e6,
                                 pgtol=1e-9)

######## PUT EVERYTHING TOGETHER ########
opt_1550 = Optimization(base_script=script_1550,
                        wavelengths=wavelengths_1551,
                        fom=fom_1550,
                        geometry=geometry_1550,
                        optimizer=optimizer_1550,
                        hide_fdtd_cad=False,
                        use_deps=True)
opt_1310 = Optimization(base_script=script_1310,
                        wavelengths=wavelengths_1310,
                        fom=fom_1310,
                        geometry=geometry_1310,
                        optimizer=optimizer_1310,
                        hide_fdtd_cad=False,
                        use_deps=True)
opt = opt_1550 + opt_1310

######## RUN THE OPTIMIZER ########
opt.run()
Example #21
0
                                    eps_out=1.44**2,
                                    eps_in='Si (Silicon) - Palik',
                                    bounds=bounds,
                                    depth=220e-9,
                                    edge_precision=5)
# We must define the permittivities of the material making the optimizable
# geometry and of that surrounding it. Since this is a 2D simulation, the depth has no importance.
# edge_precision defines the discretization of the edges forming the optimizable polygon. It should be set such
# that 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 thick

######## DEFINE FIGURE OF MERIT ########

fom = ModeMatch(modeorder=1, monitor_name='fom', wavelength=1550e-9)
# The base simulation script defines a field monitor named 'fom' at the point where we want to
# modematch to the 3rd order mode (fundamental TE mode)

######## DEFINE OPTIMIZATION ALGORITHM ########
optimizer = ScipyOptimizers(max_iter=20, method='L-BFGS-B', scaling_factor=1e6)
# 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, we scale them up to be on the order of 1

######## PUT EVERYTHING TOGETHER ########
opt = Optimization(base_script=script,
                   fom=fom,
                   geometry=geometry,
                   optimizer=optimizer)

######## RUN THE OPTIMIZER ########
opt.run()
Example #22
0
                                          depth=220.0e-9,
                                          eps_out=1.44**2,
                                          eps_in=2.8**2,
                                          edge_precision=5,
                                          dx=0.1e-9)

######## DEFINE FIGURE OF MERIT ########
mode_fom = ModeMatch(monitor_name='fom',
                     mode_number=2,
                     direction='Forward',
                     target_T_fwd=lambda wl: np.ones(wl.size),
                     norm_p=1)

######## DEFINE OPTIMIZATION ALGORITHM ########
scipy_optimizer = ScipyOptimizers(max_iter=20,
                                  method='L-BFGS-B',
                                  scaling_factor=1e6,
                                  pgtol=1e-9)

######## PUT EVERYTHING TOGETHER ########
opt = Optimization(base_script=crossing_base,
                   wavelengths=wavelengths,
                   fom=mode_fom,
                   geometry=polygon_geometry,
                   optimizer=scipy_optimizer,
                   hide_fdtd_cad=False,
                   use_deps=True)

######## RUN THE OPTIMIZER ########
opt.run()
Example #23
0
                                  initial_params=inital_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 ########
# 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=3, direction='Forward')

######## 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-9)

######## PUT EVERYTHING TOGETHER ########
opt = Optimization(base_script=base_script,
                   wavelengths=wavelengths,
                   fom=fom,
                   geometry=geometry,
                   optimizer=optimizer)

######## RUN THE OPTIMIZER ########
opt.run()
Example #24
0
#final value from splitter_opt_2D.py optimization
initial_params=np.linspace(0,0.24e-6,10)
#initial_params=np.linspace(-0.25e-6,0.25e-6,10)
geometry_1550_lower =  function_defined_Polygon(func=lower_coupler_arm,initial_params=initial_params,eps_out=1.44 ** 2, eps_in=2.8 ** 2,bounds=bounds,depth=220e-9,edge_precision=5)
geometry_1550_upper =  function_defined_Polygon(func=upper_coupler_arm,initial_params=initial_params,eps_out=1.44 ** 2, eps_in=2.8 ** 2,bounds=bounds,depth=220e-9,edge_precision=5)
geometry_1550=geometry_1550_lower*geometry_1550_upper
geometry_1310_lower =  function_defined_Polygon(func=lower_coupler_arm,initial_params=initial_params,eps_out=1.44 ** 2, eps_in=2.8 ** 2,bounds=bounds,depth=220e-9,edge_precision=5)
geometry_1310_upper =  function_defined_Polygon(func=upper_coupler_arm,initial_params=initial_params,eps_out=1.44 ** 2, eps_in=2.8 ** 2,bounds=bounds,depth=220e-9,edge_precision=5)
geometry_1310=geometry_1310_lower*geometry_1310_upper

######## DEFINE FIGURE OF MERIT ########
# Although we are optimizing for the same thing, two separate fom objects must be create

fom_1550=ModeMatch(modeorder=2,wavelength=1550e-9,monitor_name='fom_1550')
fom_1310=ModeMatch(modeorder=2,wavelength=1310e-9,monitor_name='fom_1310')

######## DEFINE OPTIMIZATION ALGORITHM ########
#For the optimizer, they should all be set the same, but different objects. Eventually this will be improved
optimizer_1550=ScipyOptimizers(max_iter=40)
optimizer_1310=ScipyOptimizers(max_iter=40)

######## PUT EVERYTHING TOGETHER ########
opt_1550=Optimization(base_script=script_1550,fom=fom_1550,geometry=geometry_1550,optimizer=optimizer_1550)
opt_1310=Optimization(base_script=script_1310,fom=fom_1310,geometry=geometry_1310,optimizer=optimizer_1310)

opt=opt_1550+opt_1310

######## RUN THE OPTIMIZER ########
opt.run()
Example #25
0
def runGratingOptimization(bandwidth_in_nm, etch_depth_shallow, etch_depth_deep, n_grates, initial_params = None):
    ### Yet another parametrization which allows to enforce minimum feature size when the optimizer only supports box constraints  
    ### params = [x0, a1, b1, ..., aN]
    if initial_params is None:
        params = np.zeros(4*n_grates)

        for i in range(n_grates):
            params[i*4]   = 0.2     #< Width up
            params[i*4+1] = 0.4*(i/n_grates)     #< Width of the shallow etch
            params[i*4+2] = 0.1    #< Width up
            params[i*4+3] = 0.4*(i/n_grates)     #< Width of the deep etch

        params[0] = 0      #< Overwrite the first since it has a special meaning: Start of the grating at 0um
    else:
        params = initial_params

    bounds = [(0, 1)]*(4*n_grates)  
    bounds[0] = (-3,3)

    def grating_params_pos(params, output_waveguide_length = 0.5e-6, height = 220e-9, y0 = 0):
        x_begin = -3e-6

        y3 = y0+height
        y2 = y3-etch_depth_deep
        y1 = y3-etch_depth_shallow

        x0 = params[0]*1e-6     #< First parameter is the starting position
        verts = np.array( [ [x_begin,y0],[x_begin,y3],[x0,y3],[x0,y1] ] )
        
        ## Iterate over all but the last
        for i in range(n_grates-1):
            x1 = x0 + params[i*4+1]*1e-6    #< Width of the deep etch
            x2 = x1 + params[i*4+2]*1e-6    #< Width up
            x3 = x2 + params[i*4+3]*1e-6    #< Width of the shallow etch
            x4 = x3 + params[i*4+4]*1e-6    #< Width up
            verts = np.concatenate((verts,[[x1,y1],[x1,y3],[x2,y3],[x2,y2],[x3,y2],[x3,y3],[x4,y3],[x4,y1]]),axis=0)
            x0 = x4

        x1 = x0 + params[(n_grates-1)*4+1]*1e-6    #< Width of the deep etch
        x2 = x1 + params[(n_grates-1)*4+2]*1e-6    #< Width up
        x3 = x2 + params[(n_grates-1)*4+3]*1e-6    #< Width of the shallow etch
        x_end   = x3+output_waveguide_length
        verts = np.concatenate((verts,[[x1,y1],[x1,y3],[x2,y3],[x2,y2],[x3,y2],[x3,y3],[x_end,y3],[x_end,y0]]),axis=0) 

        return verts

    geometry = FunctionDefinedPolygon(func = grating_params_pos, initial_params = params, bounds = bounds, z = 0.0, depth = 220e-9, eps_out = 1.44 ** 2, eps_in = 3.47668 ** 2, edge_precision = 5, dx = 1e-3)

    ######## DEFINE FIGURE OF MERIT ########
    fom = ModeMatch(monitor_name = 'fom', mode_number = 1, direction = 'Backward', target_T_fwd = lambda wl: np.ones(wl.size), norm_p = 1)

    ######## DEFINE OPTIMIZATION ALGORITHM ########
    optimizer = ScipyOptimizers(max_iter = 250, method = 'L-BFGS-B', scaling_factor = 1, pgtol = 1e-6) #SLSQP

    ######## DEFINE BASE SIMULATION ########
    base_script = load_from_lsf(os.path.join(os.path.dirname(__file__), 'grating_coupler_2D_2etch.lsf'))

    ######## PUT EVERYTHING TOGETHER ########
    lambda_start = 1550 - bandwidth_in_nm/2
    lambda_end   = 1550 + bandwidth_in_nm/2
    lambda_pts   = int(bandwidth_in_nm/10)+1
    wavelengths = Wavelengths(start = lambda_start*1e-9, stop = lambda_end*1e-9, points = lambda_pts)
    opt = Optimization(base_script = base_script, wavelengths = wavelengths, fom = fom, geometry = geometry, optimizer = optimizer, hide_fdtd_cad = True, use_deps = True)

    ######## RUN THE OPTIMIZER ########
    opt.run()
Example #26
0
    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()
Example #27
0
                                  depth=wg_height,
                                  eps_out=1.0**2,
                                  eps_in=3.47668**2,
                                  edge_precision=5,
                                  dx=1.0e-5)

######## DEFINE FIGURE OF MERIT ########
fom = ModeMatch(monitor_name='fom',
                mode_number=3,
                direction='Backward',
                target_T_fwd=lambda wl: 0.5 * np.ones(wl.size),
                norm_p=1)

######## DEFINE OPTIMIZATION ALGORITHM ########
optimizer = ScipyOptimizers(max_iter=200,
                            method='L-BFGS-B',
                            scaling_factor=1.0,
                            pgtol=1.0e-4)

######## PUT EVERYTHING TOGETHER ########
opt = Optimization(base_script=base_sim,
                   wavelengths=wavelengths,
                   fom=fom,
                   geometry=geometry,
                   optimizer=optimizer,
                   hide_fdtd_cad=False,
                   use_deps=True)

######## RUN THE OPTIMIZER ########
opt.run()
class LumericalInverseDesign:
    """
    Wrapper for Lumerical lumopt (part of it)
        
    Parameters
    ----------
    max_iter: int
    method: string
    scaling_factor: float
    pgtol: float
    ftol: float
    wavelength_start: float
    wavelength_stop: float
    wavelength_points: float
    build_simulation: string
    fom: obj
    geometry: obj
    hide_fdtd_cad: bool

    """
    def __init__(self, max_iter, method, scaling_factor, pgtol, ftol,
                 wavelength_start, wavelength_stop, wavelength_points,
                 build_simulation, fom, geometry, hide_fdtd_cad):

        # The optimizer must be generated anew at each iteration
        self._new_local_optimizer = ScipyOptimizers(
            max_iter=max_iter,
            method=method,
            scaling_factor=scaling_factor,
            ftol=ftol,
            pgtol=pgtol)

        self._wl = Wavelengths(start=wavelength_start,
                               stop=wavelength_stop,
                               points=wavelength_points)

        self._optimization = Optimization(base_script=build_simulation,
                                          wavelengths=self._wl,
                                          fom=fom,
                                          geometry=geometry,
                                          optimizer=self._new_local_optimizer,
                                          hide_fdtd_cad=hide_fdtd_cad,
                                          use_deps=True)

    def run(self):
        """
        Run the lumopt optimization
        
        Returns
        -------
        res: array
            The figure of merit of the optimized device
        param: numpy array
            The optimized parameters

        """
        results = self._optimization.run()
        self._optimization.sim.fdtd.close()

        # plot optimization recap figure
        plt.show()

        return [results[0], np.array(results[1])]

    def _cleanup(self):
        ''' Remove all the folders generated by lumopt '''

        # folder for the file
        local_folder = os.path.realpath(
            os.path.join(os.getcwd(), os.path.dirname(__file__)))
        subdir_list = os.listdir(local_folder)

        for folder in subdir_list:
            if folder.startswith('opts_') or (folder.startswith('optimization')
                                              and folder.endswith('.png')):
                shutil.rmtree(local_folder + '\\' + folder, ignore_errors=True)

    def __del__(self):
        # Remove  objects to delete pointers or pickle could have problems
        del self._optimization
        del self._wl
        del self._new_local_optimizer

        self._cleanup()