def adjoint_solver(design_params, mon_type): matgrid = mp.MaterialGrid(mp.Vector3(Nx,Ny), mp.air, silicon, design_parameters=np.ones((Nx,Ny))) matgrid_region = mpa.DesignRegion(matgrid, volume=mp.Volume(center=mp.Vector3(), size=mp.Vector3(design_shape.x,design_shape.y,0))) matgrid_geometry = [mp.Block(center=matgrid_region.center, size=matgrid_region.size, material=matgrid)] geometry = waveguide_geometry + matgrid_geometry sim = mp.Simulation(resolution=resolution, cell_size=cell_size, boundary_layers=boundary_layers, sources=sources, geometry=geometry) if mon_type.name == 'EIGENMODE': obj_list = [mpa.EigenmodeCoefficient(sim, mp.Volume(center=mp.Vector3(0.5*sxy-dpml), size=mp.Vector3(0,sxy,0)),1)] def J(mode_mon): return npa.abs(mode_mon)**2 elif mon_type.name == 'DFT': obj_list = [mpa.FourierFields(sim, mp.Volume(center=mp.Vector3(0.5*sxy-dpml), size=mp.Vector3(0,sxy,0)), mp.Ez)] def J(mode_mon): return npa.abs(mode_mon[0,63])**2 opt = mpa.OptimizationProblem( simulation = sim, objective_functions = J, objective_arguments = obj_list, design_regions = [matgrid_region], frequencies=[fcen], decay_fields=[mp.Ez]) f, dJ_du = opt([design_params]) sim.reset_meep() return f, dJ_du
def adjoint_solver_damping(design_params, frequencies=None, mat2=silicon): matgrid = mp.MaterialGrid(mp.Vector3(Nx, Ny), mp.air, mat2, weights=np.ones((Nx, Ny)), damping=3.14 * fcen) matgrid_region = mpa.DesignRegion( matgrid, volume=mp.Volume(center=mp.Vector3(), size=mp.Vector3(design_region_size.x, design_region_size.y, 0))) matgrid_geometry = [ mp.Block(center=matgrid_region.center, size=matgrid_region.size, material=matgrid) ] geometry = waveguide_geometry + matgrid_geometry sim = mp.Simulation(resolution=resolution, cell_size=cell_size, boundary_layers=pml_xy, sources=wvg_source, geometry=geometry) if not frequencies: frequencies = [fcen] obj_list = [ mpa.EigenmodeCoefficient(sim, mp.Volume( center=mp.Vector3(0.5 * sxy - dpml - 0.1), size=mp.Vector3(0, sxy - 2 * dpml, 0)), 1, eig_parity=eig_parity) ] def J(mode_mon): return npa.power(npa.abs(mode_mon), 2) opt = mpa.OptimizationProblem(simulation=sim, objective_functions=J, objective_arguments=obj_list, design_regions=[matgrid_region], frequencies=frequencies, minimum_run_time=150) f, dJ_du = opt([design_params]) sim.reset_meep() return f, dJ_du
def adjoint_solver_complex_fields(design_params, frequencies=None): matgrid = mp.MaterialGrid(mp.Vector3(Nx, Ny), mp.air, silicon, weights=np.ones((Nx, Ny))) matgrid_region = mpa.DesignRegion( matgrid, volume=mp.Volume(center=mp.Vector3(), size=mp.Vector3(design_region_size.x, design_region_size.y, 0))) geometry = [ mp.Block(center=matgrid_region.center, size=matgrid_region.size, material=matgrid) ] sim = mp.Simulation(resolution=resolution, cell_size=cell_size, k_point=k_point, boundary_layers=pml_x, sources=pt_source, geometry=geometry) if not frequencies: frequencies = [fcen] obj_list = [ mpa.FourierFields( sim, mp.Volume(center=mp.Vector3(0.9), size=mp.Vector3(0.2, 0.5)), mp.Ez) ] def J(dft_mon): return npa.power(npa.abs(dft_mon[:, 3, 9]), 2) opt = mpa.OptimizationProblem(simulation=sim, objective_functions=J, objective_arguments=obj_list, design_regions=[matgrid_region], frequencies=frequencies) f, dJ_du = opt([design_params]) sim.reset_meep() return f, dJ_du
def adjoint_solver(design_params): design_variables = mp.MaterialGrid(mp.Vector3(Nr, 0, Nz), SiO2, Si) design_region = mpa.DesignRegion( design_variables, volume=mp.Volume(center=mp.Vector3(design_r / 2, 0, 0), size=mp.Vector3(design_r, 0, design_z))) geometry = [ mp.Block(center=design_region.center, size=design_region.size, material=design_variables) ] sim = mp.Simulation(cell_size=cell_size, boundary_layers=boundary_layers, geometry=geometry, sources=source, resolution=resolution, dimensions=dimensions, m=m) far_x = [mp.Vector3(5, 0, 20)] NearRegions = [ mp.Near2FarRegion(center=mp.Vector3( design_r / 2, 0, (sz / 2 - dpml + design_z / 2) / 2), size=mp.Vector3(design_r, 0, 0), weight=+1) ] FarFields = mpa.Near2FarFields(sim, NearRegions, far_x) ob_list = [FarFields] def J(alpha): return npa.abs(alpha[0, 0, 0])**2 opt = mpa.OptimizationProblem(simulation=sim, objective_functions=J, objective_arguments=ob_list, design_regions=[design_region], fcen=fcen, df=0, nf=1, maximum_run_time=1200) f, dJ_du = opt([design_params]) sim.reset_meep() return f, dJ_du
TE_top = mpa.EigenmodeCoefficient(sim, mp.Volume(center=mp.Vector3(0, 1, 0), size=mp.Vector3(x=2)), mode=1) ob_list = [TE_top] def J(alpha): return npa.abs(alpha)**2 opt = mpa.OptimizationProblem(simulation=sim, objective_functions=J, objective_arguments=ob_list, design_regions=[design_region], fcen=fcen, df=0, nf=1, decay_fields=[mp.Ez]) #Plot initial geometry x0 = 0.5 * np.ones((Nx * Ny, )) opt.update_design([x0]) opt.plot2D(True) plt.show() #Define the cost function #note the use of the gradient, which is unnecessary for current implementation of the optimizer with GPyOpt evaluation_history = []