def forward_simulation(design_params): matgrid = mp.MaterialGrid(mp.Vector3(Nr, 0, Nz), SiO2, Si, weights=design_params.reshape(Nr, 1, Nz)) geometry = [ mp.Block(center=mp.Vector3(design_r / 2, 0, 0), size=mp.Vector3(design_r, 0, design_z), material=matgrid) ] sim = mp.Simulation(resolution=resolution, cell_size=cell_size, boundary_layers=boundary_layers, sources=source, geometry=geometry, dimensions=dimensions, m=m) frequencies = [fcen] far_x = [mp.Vector3(5, 0, 20)] mode = sim.add_near2far( frequencies, 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)) sim.run(until_after_sources=1200) Er = sim.get_farfield(mode, far_x[0]) sim.reset_meep() return abs(Er[0])**2
def forward_simulation(design_params, mon_type, frequencies=None, mat2=silicon): matgrid = mp.MaterialGrid(mp.Vector3(Nx, Ny), mp.air, mat2, weights=design_params.reshape(Nx, Ny)) matgrid_geometry = [ mp.Block(center=mp.Vector3(), size=mp.Vector3(design_region_size.x, design_region_size.y, 0), 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] if mon_type.name == 'EIGENMODE': mode = sim.add_mode_monitor( frequencies, mp.ModeRegion(center=mp.Vector3(0.5 * sxy - dpml - 0.1), size=mp.Vector3(0, sxy - 2 * dpml, 0)), yee_grid=True, eig_parity=eig_parity) elif mon_type.name == 'DFT': mode = sim.add_dft_fields([mp.Ez], frequencies, center=mp.Vector3(1.25), size=mp.Vector3(0.25, 1, 0), yee_grid=False) sim.run(until_after_sources=mp.stop_when_dft_decayed()) if mon_type.name == 'EIGENMODE': coeff = sim.get_eigenmode_coefficients(mode, [1], eig_parity).alpha[0, :, 0] S12 = np.power(np.abs(coeff), 2) elif mon_type.name == 'DFT': Ez2 = [] for f in range(len(frequencies)): Ez_dft = sim.get_dft_array(mode, mp.Ez, f) Ez2.append(np.power(np.abs(Ez_dft[4, 10]), 2)) Ez2 = np.array(Ez2) sim.reset_meep() if mon_type.name == 'EIGENMODE': return S12 elif mon_type.name == 'DFT': return Ez2
def compute_resonant_mode(res): cell_size = mp.Vector3(1, 1, 0) rad = 0.301943 fcen = 0.3 df = 0.2 * fcen sources = [ mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Hz, center=mp.Vector3(-0.1057, 0.2094, 0)) ] k_point = mp.Vector3(0.3892, 0.1597, 0) design_shape = mp.Vector3(1, 1, 0) design_region_resolution = 50 Nx = int(design_region_resolution * design_shape.x) Ny = int(design_region_resolution * design_shape.y) x = np.linspace(-0.5 * design_shape.x, 0.5 * design_shape.x, Nx) y = np.linspace(-0.5 * design_shape.y, 0.5 * design_shape.y, Ny) xv, yv = np.meshgrid(x, y) design_params = np.sqrt(np.square(xv) + np.square(yv)) < rad filtered_design_params = gaussian_filter(design_params, sigma=3.0, output=np.double) matgrid = mp.MaterialGrid(mp.Vector3(Nx, Ny), mp.air, mp.Medium(index=3.5), weights=filtered_design_params, do_averaging=True, beta=1000, eta=0.5) geometry = [ mp.Block(center=mp.Vector3(), size=mp.Vector3(design_shape.x, design_shape.y, 0), material=matgrid) ] sim = mp.Simulation(resolution=res, cell_size=cell_size, geometry=geometry, sources=sources, k_point=k_point) h = mp.Harminv(mp.Hz, mp.Vector3(0.3718, -0.2076), fcen, df) sim.run(mp.after_sources(h), until_after_sources=200) try: for m in h.modes: print("harminv:, {}, {}, {}".format(res, m.freq, m.Q)) freq = h.modes[0].freq except: print("No resonant modes found.") sim.reset_meep() return freq
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 setUp(self): resolution = 60 self.cell_size = mp.Vector3(1.0, 1.0, 0) matgrid_resolution = 200 matgrid_size = mp.Vector3(1.0, 1.0, mp.inf) Nx, Ny = int(matgrid_size.x * matgrid_resolution), int( matgrid_size.y * matgrid_resolution) x = np.linspace(-0.5 * matgrid_size.x, 0.5 * matgrid_size.x, Nx) y = np.linspace(-0.5 * matgrid_size.y, 0.5 * matgrid_size.y, Ny) xv, yv = np.meshgrid(x, y) rad = 0.201943 w = 0.104283 weights = np.logical_and( np.sqrt(np.square(xv) + np.square(yv)) > rad, np.sqrt(np.square(xv) + np.square(yv)) < rad + w, dtype=np.double) matgrid = mp.MaterialGrid(mp.Vector3(Nx, Ny), mp.air, mp.Medium(index=3.5), weights=weights, do_averaging=False, beta=0, eta=0.5) geometry = [ mp.Cylinder(center=mp.Vector3(0.35, 0.1), radius=0.1, height=mp.inf, material=mp.Medium(index=1.5)), mp.Block(center=mp.Vector3(-0.15, -0.2), size=mp.Vector3(0.2, 0.24, mp.inf), material=SiN), mp.Block(center=mp.Vector3(-0.2, 0.2), size=mp.Vector3(0.4, 0.4, mp.inf), material=matgrid), mp.Prism(vertices=[ mp.Vector3(0.05, 0.45), mp.Vector3(0.32, 0.22), mp.Vector3(0.15, 0.10) ], height=0.5, material=Co) ] self.sim = mp.Simulation(resolution=resolution, cell_size=self.cell_size, geometry=geometry, eps_averaging=False) self.sim.init_sim()
def forward_simulation(design_params,mon_type): matgrid = mp.MaterialGrid(mp.Vector3(Nx,Ny), mp.air, silicon, design_parameters=design_params.reshape(Nx,Ny), grid_type='U_SUM') matgrid_geometry = [mp.Block(center=mp.Vector3(), size=mp.Vector3(design_shape.x,design_shape.y,0), 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': mode = sim.add_mode_monitor(fcen, 0, 1, mp.ModeRegion(center=mp.Vector3(0.5*sxy-dpml),size=mp.Vector3(0,sxy,0)), yee_grid=True) elif mon_type.name == 'DFT': mode = sim.add_dft_fields([mp.Ez], fcen, 0, 1, center=mp.Vector3(0.5*sxy-dpml), size=mp.Vector3(0,sxy), yee_grid=False) sim.run(until_after_sources=20) if mon_type.name == 'EIGENMODE': coeff = sim.get_eigenmode_coefficients(mode,[1],eig_parity).alpha[0,0,0] S12 = abs(coeff)**2 elif mon_type.name == 'DFT': Ez_dft = sim.get_dft_array(mode, mp.Ez, 0) Ez2 = abs(Ez_dft[63])**2 sim.reset_meep() if mon_type.name == 'EIGENMODE': return S12 elif mon_type.name == 'DFT': return Ez2
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
def forward_simulation(design_params): matgrid = mp.MaterialGrid(mp.Vector3(Nx, Ny), mp.air, silicon, design_parameters=design_params.reshape( Nx, Ny), grid_type='U_SUM') matgrid_geometry = [ mp.Block(center=mp.Vector3(), size=mp.Vector3(design_shape.x, design_shape.y, 0), material=matgrid) ] geometry = waveguide_geometry + matgrid_geometry sim = mp.Simulation(resolution=resolution, cell_size=cell_size, boundary_layers=boundary_layers, sources=sources, geometry=geometry) mode = sim.add_mode_monitor( fcen, 0, 1, mp.ModeRegion(center=mp.Vector3(0.5 * sxy - dpml), size=mp.Vector3(0, sxy, 0)), yee_grid=True) sim.run(until_after_sources=20) # mode coefficients coeff = sim.get_eigenmode_coefficients(mode, [1], eig_parity).alpha[0, 0, 0] # S parameters S12 = abs(coeff)**2 sim.reset_meep() return S12
def forward_simulation_complex_fields(design_params, frequencies=None): matgrid = mp.MaterialGrid(mp.Vector3(Nx, Ny), mp.air, silicon, weights=design_params.reshape(Nx, Ny)) geometry = [ mp.Block(center=mp.Vector3(), size=mp.Vector3(design_region_size.x, design_region_size.y, 0), 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] mode = sim.add_dft_fields([mp.Ez], frequencies, center=mp.Vector3(0.9), size=mp.Vector3(0.2, 0.5), yee_grid=False) sim.run(until_after_sources=mp.stop_when_dft_decayed()) Ez2 = [] for f in range(len(frequencies)): Ez_dft = sim.get_dft_array(mode, mp.Ez, f) Ez2.append(np.power(np.abs(Ez_dft[3, 9]), 2)) Ez2 = np.array(Ez2) sim.reset_meep() return Ez2
def forward_simulation_damping(design_params, frequencies=None, mat2=silicon): matgrid = mp.MaterialGrid(mp.Vector3(Nx, Ny), mp.air, mat2, weights=design_params.reshape(Nx, Ny), damping=3.14 * fcen) matgrid_geometry = [ mp.Block(center=mp.Vector3(), size=mp.Vector3(design_region_size.x, design_region_size.y, 0), 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] mode = sim.add_mode_monitor(frequencies, mp.ModeRegion( center=mp.Vector3(0.5 * sxy - dpml - 0.1), size=mp.Vector3(0, sxy - 2 * dpml, 0)), yee_grid=True, eig_parity=eig_parity) sim.run(until_after_sources=mp.stop_when_dft_decayed()) coeff = sim.get_eigenmode_coefficients(mode, [1], eig_parity).alpha[0, :, 0] S12 = np.power(np.abs(coeff), 2) sim.reset_meep() return S12
def compute_transmittance(matgrid_symmetry=False): resolution = 25 cell_size = mp.Vector3(6, 6, 0) boundary_layers = [mp.PML(thickness=1.0)] matgrid_size = mp.Vector3(2, 2, 0) matgrid_resolution = 2 * resolution Nx, Ny = int(matgrid_size.x * matgrid_resolution), int(matgrid_size.y * matgrid_resolution) # ensure reproducible results rng = np.random.RandomState(2069588) w = rng.rand(Nx, Ny) weights = 0.5 * (w + np.fliplr(w)) if not matgrid_symmetry else w matgrid = mp.MaterialGrid(mp.Vector3(Nx, Ny), mp.air, mp.Medium(index=3.5), weights=weights, do_averaging=False, grid_type='U_MEAN') geometry = [ mp.Block(center=mp.Vector3(), size=mp.Vector3(mp.inf, 1.0, mp.inf), material=mp.Medium(index=3.5)), mp.Block(center=mp.Vector3(), size=mp.Vector3(matgrid_size.x, matgrid_size.y, 0), material=matgrid) ] if matgrid_symmetry: geometry.append( mp.Block(center=mp.Vector3(), size=mp.Vector3(matgrid_size.x, matgrid_size.y, 0), material=matgrid, e2=mp.Vector3(y=-1))) eig_parity = mp.ODD_Y + mp.EVEN_Z fcen = 0.65 df = 0.2 * fcen sources = [ mp.EigenModeSource(src=mp.GaussianSource(fcen, fwidth=df), center=mp.Vector3(-2.0, 0), size=mp.Vector3(0, 4.0), eig_parity=eig_parity) ] sim = mp.Simulation(resolution=resolution, cell_size=cell_size, boundary_layers=boundary_layers, sources=sources, geometry=geometry) mode_mon = sim.add_flux( fcen, 0, 1, mp.FluxRegion(center=mp.Vector3(2.0, 0), size=mp.Vector3(0, 4.0))) sim.run(until_after_sources=mp.stop_when_dft_decayed()) mode_coeff = sim.get_eigenmode_coefficients(mode_mon, [1], eig_parity).alpha[0, :, 0][0] tran = np.power(np.abs(mode_coeff), 2) print('tran:, {}, {}'.format("sym" if matgrid_symmetry else "nosym", tran)) return tran
def gen_sim(self): resolution = 10 # pixels/um cell_size = mp.Vector3(14, 14) pml_layers = [mp.PML(thickness=2)] w = 3.0 # width of waveguide m1 = SiO2 m2 = Si n = 10 gs = mp.Vector3(n, n) np.random.seed(1) dp = np.random.rand(n * n) mg = mp.MaterialGrid(gs, m1, m2, dp, "U_SUM") geometry = [] rot_angle = np.radians(0) geometry += [ mp.Block(center=mp.Vector3(), size=mp.Vector3(w, w, mp.inf), e1=mp.Vector3(x=1).rotate(mp.Vector3(z=1), rot_angle), e2=mp.Vector3(y=1).rotate(mp.Vector3(z=1), rot_angle), material=mg) ] geometry += [ mp.Block(center=mp.Vector3(), size=mp.Vector3(w, w, mp.inf), e1=mp.Vector3(x=-1).rotate(mp.Vector3(z=1), np.pi / 2), e2=mp.Vector3(y=1).rotate(mp.Vector3(z=1), np.pi / 2), material=mg) ] fsrc = 1 / 1.55 # frequency of eigenmode or constant-amplitude source bnum = 1 # band number of eigenmode kpoint = mp.Vector3(x=1).rotate(mp.Vector3(z=1), rot_angle) compute_flux = True # compute flux (True) or plot the field profile (False) eig_src = True # eigenmode (True) or constant-amplitude (False) source if eig_src: sources = [ mp.EigenModeSource( src=mp.GaussianSource(fsrc, fwidth=0.2 * fsrc) if compute_flux else mp.ContinuousSource(fsrc), center=mp.Vector3(), size=mp.Vector3(y=3 * w), direction=mp.NO_DIRECTION, eig_kpoint=kpoint, eig_band=bnum, eig_parity=mp.EVEN_Y + mp.ODD_Z if rot_angle == 0 else mp.ODD_Z, eig_match_freq=True) ] else: sources = [ mp.Source(src=mp.GaussianSource(fsrc, fwidth=0.2 * fsrc) if compute_flux else mp.ContinuousSource(fsrc), center=mp.Vector3(), size=mp.Vector3(y=3 * w), component=mp.Ez) ] sim = mp.Simulation(cell_size=cell_size, resolution=resolution, boundary_layers=pml_layers, sources=sources, extra_materials=[m1, m2], geometry=geometry) return sim
def compute_resonant_mode_3d(use_matgrid=True): resolution = 25 wvl = 1.27 fcen = 1 / wvl df = 0.02 * fcen nSi = 3.45 Si = mp.Medium(index=nSi) nSiO2 = 1.45 SiO2 = mp.Medium(index=nSiO2) s = 1.0 cell_size = mp.Vector3(s, s, s) rad = 0.34 # radius of sphere if use_matgrid: matgrid_resolution = 2 * resolution N = int(s * matgrid_resolution) coord = np.linspace(-0.5 * s, 0.5 * s, N) xv, yv, zv = np.meshgrid(coord, coord, coord) weights = np.sqrt(np.square(xv) + np.square(yv) + np.square(zv)) < rad filtered_weights = gaussian_filter(weights, sigma=4 / resolution, output=np.double) matgrid = mp.MaterialGrid(mp.Vector3(N, N, N), SiO2, Si, weights=filtered_weights, do_averaging=True, beta=1000, eta=0.5) geometry = [ mp.Block(center=mp.Vector3(), size=cell_size, material=matgrid) ] else: geometry = [mp.Sphere(center=mp.Vector3(), radius=rad, material=Si)] sources = [ mp.Source(src=mp.GaussianSource(fcen, fwidth=df), size=mp.Vector3(), center=mp.Vector3(0.13, 0.25, 0.06), component=mp.Ez) ] k_point = mp.Vector3(0.23, -0.17, 0.35) sim = mp.Simulation(resolution=resolution, cell_size=cell_size, sources=sources, default_material=SiO2, k_point=k_point, geometry=geometry) h = mp.Harminv(mp.Ez, mp.Vector3(-0.2684, 0.1185, 0.0187), fcen, df) sim.run(mp.after_sources(h), until_after_sources=200) try: for m in h.modes: print("harminv:, {}, {}, {}".format(resolution, m.freq, m.Q)) freq = h.modes[0].freq except: raise RuntimeError("No resonant modes found.") return freq
def compute_resonant_mode_2d(res, default_mat=False): cell_size = mp.Vector3(1, 1, 0) rad = 0.301943 fcen = 0.3 df = 0.2 * fcen sources = [ mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Hz, center=mp.Vector3(-0.1057, 0.2094, 0)) ] k_point = mp.Vector3(0.3892, 0.1597, 0) matgrid_size = mp.Vector3(1, 1, 0) matgrid_resolution = 1200 # for a fixed resolution, compute the number of grid points # necessary which are defined on the corners of the voxels Nx, Ny = int(matgrid_size.x * matgrid_resolution), int(matgrid_size.y * matgrid_resolution) x = np.linspace(-0.5 * matgrid_size.x, 0.5 * matgrid_size.x, Nx) y = np.linspace(-0.5 * matgrid_size.y, 0.5 * matgrid_size.y, Ny) xv, yv = np.meshgrid(x, y) weights = np.sqrt(np.square(xv) + np.square(yv)) < rad filtered_weights = gaussian_filter(weights, sigma=3.0, output=np.double) matgrid = mp.MaterialGrid(mp.Vector3(Nx, Ny), mp.air, mp.Medium(index=3.5), weights=filtered_weights, do_averaging=True, beta=1000, eta=0.5) geometry = [ mp.Block(center=mp.Vector3(), size=mp.Vector3(matgrid_size.x, matgrid_size.y, 0), material=matgrid) ] sim = mp.Simulation( resolution=res, cell_size=cell_size, default_material=matgrid if default_mat else mp.Medium(), geometry=geometry if not default_mat else [], sources=sources, k_point=k_point) h = mp.Harminv(mp.Hz, mp.Vector3(0.3718, -0.2076), fcen, df) sim.run(mp.after_sources(h), until_after_sources=200) try: for m in h.modes: print("harminv:, {}, {}, {}".format(res, m.freq, m.Q)) freq = h.modes[0].freq except: raise RuntimeError("No resonant modes found.") return freq
monitor_position = 400 medium_width = 10 mask = np.ones((sx, sy, medium_width), dtype=np.int8) mask[70:-70,70:-70,:] = 0 # mask = load_mask('0.png', (sx, sy, medium_width)) # define metal-mesh pattern from image. medium = { 0: [ mp.Block( size=mp.Vector3(sx, sy, medium_width), center=mp.Vector3(0,0,0), material=mp.MaterialGrid( grid_size=mp.Vector3(sx, sy, medium_width), medium1=mp.Medium( epsilon_diag=mp.Vector3(1.69**2, 1.54**2, 1.54**2) ), medium2=mp.perfect_electric_conductor, weights=mask ) ) ], 90: [ mp.Block( size=mp.Vector3(sx, sy, medium_width), center=mp.Vector3(0,0,0), material=mp.MaterialGrid( grid_size=mp.Vector3(sx, sy, medium_width), medium1=mp.Medium( epsilon_diag=mp.Vector3(1.54**2, 1.69**2, 1.54**2) ), medium2=mp.perfect_electric_conductor,
def get_signal(straight_refl_data): eps = [ mp.Vector3(1.69**2, 1.54**2, 1.54**2), # 0 deg mp.Vector3(1.54**2, 1.69**2, 1.54**2), # 90 deg ] mask = np.ones((sx, sy, w), dtype=np.int8) mask[60:-60,60:-60,:] = 0 # mask = load_mask('0.png', (sx, sy, w)) # define metal-mesh pattern from image. masks = [ mask, # 0 deg np.rot90(mask, axes=(0, 1), k=-1) # 90 deg ] deg = [0, 90] data = [] for i in range(len(eps)): e = eps[i] mask = masks[i] material = mp.MaterialGrid( grid_size=mp.Vector3(sx, sy, w), medium1=mp.Medium(epsilon_diag=e), medium2=mp.perfect_electric_conductor, weights=mask ) geometry = [ mp.Block( size=mp.Vector3(sx, sy, w), center=mp.Vector3(0,0,0), material=material ), ] sim = mp.Simulation(cell_size=cell, boundary_layers=pml_layers, geometry=geometry, sources=sources, resolution=resolution, k_point=mp.Vector3()) tran_fr = mp.FluxRegion(center=mp.Vector3(0,0,400), direction=mp.Y) refl_fr = mp.FluxRegion(center=mp.Vector3(0,0,-400), direction=mp.Y, weight=-1) nfreq = 300 # number of frequencies at which to compute flux refl = sim.add_flux(fcen, df, nfreq, refl_fr) tran = sim.add_flux(fcen, df, nfreq, tran_fr) sim.load_minus_flux_data(refl, straight_refl_data) pt = mp.Vector3(0,0,-400) # sim.run(until_after_sources=mp.stop_when_fields_decayed(50,mp.Ex,pt,1e-3)) sim.run(until=time) tran_flux = sim.get_flux_data(tran) refl_flux = sim.get_flux_data(refl) data.append([tran_flux, refl_flux]) sim.plot2D(fields=mp.Ex, output_plane=mp.Volume(center=mp.Vector3(0,0,0), size=mp.Vector3(sx, 0, sz))) plt.savefig('Ex_xz_{}.png'.format(deg[i])) sim.plot2D(fields=mp.Ex, output_plane=mp.Volume(center=mp.Vector3(0,0,0), size=mp.Vector3(0, sy, sz))) plt.savefig('Ex_yz_{}.png'.format(deg[i])) sim.plot2D(fields=mp.Ex, output_plane=mp.Volume(center=mp.Vector3(0,0,0), size=mp.Vector3(sx, sy, 0))) plt.savefig('Ex_xy_{}.png'.format(deg[i])) return data, mp.get_flux_freqs(tran)
def build_straight_wg_simulation( wg_width=0.5, wg_padding=1.0, wg_length=1.0, pml_width=1.0, source_to_pml=0.5, source_to_monitor=0.1, frequencies=[1 / 1.55], gaussian_rel_width=0.2, sim_resolution=20, design_region_resolution=20, ): """Builds a simulation of a straight waveguide with a design region segment.""" design_region_shape = (1.0, wg_width) # Simulation domain size sx = 2 * pml_width + 2 * wg_length + design_region_shape[0] sy = 2 * pml_width + 2 * wg_padding + max( wg_width, design_region_shape[1], ) # Mean / center frequency fmean = onp.mean(frequencies) si = mp.Medium(index=3.4) sio2 = mp.Medium(index=1.44) sources = [ mp.EigenModeSource( mp.GaussianSource(frequency=fmean, fwidth=fmean * gaussian_rel_width), eig_band=1, direction=mp.NO_DIRECTION, eig_kpoint=mp.Vector3(1, 0, 0), size=mp.Vector3(0, wg_width + 2 * wg_padding, 0), center=[-sx / 2 + pml_width + source_to_pml, 0, 0], ), mp.EigenModeSource( mp.GaussianSource(frequency=fmean, fwidth=fmean * gaussian_rel_width), eig_band=1, direction=mp.NO_DIRECTION, eig_kpoint=mp.Vector3(-1, 0, 0), size=mp.Vector3(0, wg_width + 2 * wg_padding, 0), center=[sx / 2 - pml_width - source_to_pml, 0, 0], ), ] nx, ny = int(design_region_shape[0] * design_region_resolution), int( design_region_shape[1] * design_region_resolution) mat_grid = mp.MaterialGrid( mp.Vector3(nx, ny), sio2, si, grid_type='U_DEFAULT', ) design_regions = [ mpa.DesignRegion( mat_grid, volume=mp.Volume( center=mp.Vector3(), size=mp.Vector3( design_region_shape[0], design_region_shape[1], 0, ), ), ) ] geometry = [ mp.Block(center=mp.Vector3(x=-design_region_shape[0] / 2 - wg_length / 2 - pml_width / 2), material=si, size=mp.Vector3(wg_length + pml_width, wg_width, 0)), # left wg mp.Block(center=mp.Vector3(x=+design_region_shape[0] / 2 + wg_length / 2 + pml_width / 2), material=si, size=mp.Vector3(wg_length + pml_width, wg_width, 0)), # right wg mp.Block(center=design_regions[0].center, size=design_regions[0].size, material=mat_grid), # design region ] simulation = mp.Simulation( cell_size=mp.Vector3(sx, sy), boundary_layers=[mp.PML(pml_width)], geometry=geometry, sources=sources, resolution=sim_resolution, ) monitor_centers = [ mp.Vector3(-sx / 2 + pml_width + source_to_pml + source_to_monitor), mp.Vector3(sx / 2 - pml_width - source_to_pml - source_to_monitor), ] monitor_size = mp.Vector3(y=wg_width + 2 * wg_padding) monitors = [ mpa.EigenmodeCoefficient(simulation, mp.Volume(center=center, size=monitor_size), mode=1, forward=forward) for center in monitor_centers for forward in [True, False] ] return simulation, sources, monitors, design_regions, frequencies
src = mp.GaussianSource(frequency=fcen, fwidth=fwidth) source = [ mp.EigenModeSource(src, eig_band=1, direction=mp.NO_DIRECTION, eig_kpoint=kpoint, size=source_size, center=source_center) ] design_region_resolution = 10 Nx = design_region_resolution Ny = design_region_resolution design_variables = mp.MaterialGrid(mp.Vector3(Nx, Ny), SiO2, Si, grid_type='U_SUM') design_region = mpa.DesignRegion(design_variables, volume=mp.Volume(center=mp.Vector3(), size=mp.Vector3(1, 1, 0))) geometry = [ mp.Block(center=mp.Vector3(x=-Sx / 4), material=Si, size=mp.Vector3(Sx / 2, 0.5, 0)), # horizontal waveguide mp.Block(center=mp.Vector3(y=Sy / 4), material=Si, size=mp.Vector3(0.5, Sy / 2, 0)), # vertical waveguide mp.Block(center=design_region.center, size=design_region.size, material=design_variables), # design region