def main(args): n = 3.4 # index of waveguide w = 1 # width of waveguide r = 1 # inner radius of ring pad = 4 # padding between waveguide and edge of PML dpml = 32 # thickness of PML sr = r + w + pad + dpml # radial size (cell is from 0 to sr) dimensions = mp.CYLINDRICAL cell = mp.Vector3(sr, 0, 0) # in cylindrical coordinates, the phi (angular) dependence of the fields # is given by exp(i m phi), where m is given by: m = args.m geometry = [mp.Block(center=mp.Vector3(r + (w / 2)), size=mp.Vector3(w, mp.inf, mp.inf), material=mp.Medium(index=n))] pml_layers = [mp.PML(dpml)] resolution = 20 # If we don't want to excite a specific mode symmetry, we can just # put a single point source at some arbitrary place, pointing in some # arbitrary direction. We will only look for Ez-polarized modes. fcen = args.fcen # pulse center frequency df = args.df # pulse frequency width sources = [mp.Source(src=mp.GaussianSource(fcen, fwidth=df), component=mp.Ez, center=mp.Vector3(r + 0.1))] # note that the r -> -r mirror symmetry is exploited automatically sim = mp.Simulation(cell_size=cell, geometry=geometry, boundary_layers=pml_layers, resolution=resolution, sources=sources, dimensions=dimensions, m=m) sim.run(mp.after_sources(mp.Harminv(mp.Ez, mp.Vector3(r + 0.1), fcen, df)), until_after_sources=200) # Output fields for one period at the end. (If we output # at a single time, we might accidentally catch the Ez field when it is # almost zero and get a distorted view.) We'll append the fields # to a file to get an r-by-t picture. We'll also output from -sr to -sr # instead of from 0 to sr. sim.run(mp.in_volume(mp.Volume(center=mp.Vector3(), size=mp.Vector3(2 * sr)), mp.at_beginning(mp.output_epsilon), mp.to_appended("ez", mp.at_every(1 / fcen / 20, mp.output_efield_z))), until=1 / fcen)
def test_eigsrc_kz(self): resolution = 30 # pixels/um cell_size = mp.Vector3(14, 14) pml_layers = [mp.PML(thickness=2)] geometry = [ mp.Block(center=mp.Vector3(), size=mp.Vector3(mp.inf, 1, mp.inf), material=mp.Medium(epsilon=12)) ] fsrc = 0.3 # frequency of eigenmode or constant-amplitude source bnum = 1 # band number of eigenmode kz = 0.2 # fixed out-of-plane wavevector component sources = [ mp.EigenModeSource(src=mp.GaussianSource(fsrc, fwidth=0.2 * fsrc), center=mp.Vector3(), size=mp.Vector3(y=14), eig_band=bnum, eig_parity=mp.EVEN_Y, eig_match_freq=True) ] sim = mp.Simulation(cell_size=cell_size, resolution=resolution, boundary_layers=pml_layers, sources=sources, geometry=geometry, symmetries=[mp.Mirror(mp.Y)], k_point=mp.Vector3(z=kz), special_kz=True) tran = sim.add_flux( fsrc, 0, 1, mp.FluxRegion(center=mp.Vector3(x=5), size=mp.Vector3(y=14))) sim.run(until_after_sources=50) res = sim.get_eigenmode_coefficients(tran, [1, 2], eig_parity=mp.EVEN_Y) total_flux = mp.get_fluxes(tran)[0] mode1_flux = abs(res.alpha[0, 0, 0])**2 mode2_flux = abs(res.alpha[1, 0, 0])**2 mode1_frac = 0.99 self.assertGreater(mode1_flux / total_flux, mode1_frac) self.assertLess(mode2_flux / total_flux, 1 - mode1_frac) d = 3.5 ez1 = sim.get_field_point(mp.Ez, mp.Vector3(2.3, -5.7, 4.8)) ez2 = sim.get_field_point(mp.Ez, mp.Vector3(2.3, -5.7, 4.8 + d)) ratio_ez = ez2 / ez1 phase_diff = cmath.exp(1j * 2 * cmath.pi * kz * d) self.assertAlmostEqual(ratio_ez.real, phase_diff.real, places=10) self.assertAlmostEqual(ratio_ez.imag, phase_diff.imag, places=10)
def geo2D_ellipsoid_pc(n_matrix, n_substrate, film_xsize, substrate_xsize, film_ysize, n_layers, film_base_x, ellipsex, ellipsey, ellipse_spacing, layer_offset, ellipse_x_offset=0): """ Generate a layered structure with spheres. Within a layer the spheres are hexagonally packed """ matrix_block = mp.Block(size=mp.Vector3(film_xsize, film_ysize, 1e20), center=mp.Vector3(film_base_x - film_xsize / 2), material=mp.Medium(epsilon=n_matrix**2)) si_block = mp.Block(size=mp.Vector3(substrate_xsize, film_ysize, 1e20), center=mp.Vector3(film_base_x + substrate_xsize / 2, 0, 0), material=mp.Medium(epsilon=n_substrate**2)) print(n_substrate) spheres = [si_block, matrix_block] #spheres = [] for n in range(n_layers): x = film_base_x - film_xsize * (n + 0.5) / n_layers + ellipse_x_offset offset = layer_offset[n] num_spheres = int(film_ysize / ellipse_spacing) sphere_layer = [ mp.Ellipsoid(size=mp.Vector3(ellipsex, ellipsey, 1e20), center=mp.Vector3(x, y + offset - film_ysize / 2, 0), material=mp.Medium(epsilon=1)) for y in np.linspace(0, film_ysize, num_spheres) ] spheres = spheres + sphere_layer return spheres
def _check(med, expected, default=mp.Medium()): geometry = [mp.Block(center=mp.Vector3(), size=mp.Vector3(1, 1), material=med)] sim = mp.Simulation(cell_size=mp.Vector3(5, 5), resolution=10, geometry=geometry, default_material=default) result = sim.has_mu() if expected: self.assertTrue(result) else: self.assertFalse(result) print("Estimated memory usage: {}".format(sim.get_estimated_memory_usage()))
def geo1D_thin_film_si(film_n, si_n, ps_thickness, si_thickness, pos=0, bare_substrate=False): ps_block = mp.Block(size=mp.Vector3(1, 1, ps_thickness), center=mp.Vector3( 0, 0, pos - (si_thickness + ps_thickness / 2)), material=mp.Medium(epsilon=film_n**2)) si_block = mp.Block(size=mp.Vector3(1, 1, si_thickness), center=mp.Vector3(0, 0, pos - si_thickness / 2), material=mp.Medium(epsilon=si_n**2)) if bare_substrate: geometry = [si_block] else: geometry = [ps_block, si_block] return geometry
def get_fragment_stats(self, block_size, cell_size, dims, box_center=mp.Vector3(), dft_vecs=None, def_mat=mp.air, sym=[], geom=None, pml=[]): mat = mp.Medium(epsilon=12, epsilon_offdiag=mp.Vector3(z=1), mu_offdiag=mp.Vector3(x=20), E_chi2_diag=mp.Vector3(1, 1), H_chi3_diag=mp.Vector3(z=1), E_susceptibilities=[ mp.LorentzianSusceptibility(), mp.NoisyLorentzianSusceptibility() ], H_susceptibilities=[mp.DrudeSusceptibility()], D_conductivity_diag=mp.Vector3(y=1), B_conductivity_diag=mp.Vector3(x=1, z=1)) if geom is None: geom = [mp.Block(size=block_size, center=box_center, material=mat)] sim = mp.Simulation(cell_size=cell_size, resolution=10, geometry=geom, dimensions=dims, default_material=def_mat, symmetries=sym, boundary_layers=pml) if dft_vecs: if dft_vecs['flux_regions']: sim.add_flux(1, 0.5, 5, *dft_vecs['flux_regions']) if dft_vecs['n2f_regions']: sim.add_near2far(1, 0.5, 7, *dft_vecs['n2f_regions']) if dft_vecs['force_regions']: sim.add_force(1, 0.5, 9, *dft_vecs['force_regions']) if dft_vecs['fields_components']: sim.add_dft_fields(dft_vecs['fields_components'], 0, 1, 5, where=dft_vecs['fields_where'], center=dft_vecs['fields_center'], size=dft_vecs['fields_size']) gv = sim._create_grid_volume(False) stats = sim._compute_fragment_stats(gv) return stats
def createDiffractionSlit(): cell = mp.Vector3(globalVariables.waveguideXSize, globalVariables.waveguideYSize, 0) geometry = [mp.Block(mp.Vector3(1e20, 1, 1e20), center=mp.Vector3(0, 0), material=mp.Medium(epsilon=globalVariables.epsilonOfMaterial)), mp.Block(mp.Vector3(globalVariables.blockXSize,globalVariables.blockYSize,0), center=mp.Vector3(0,(globalVariables.blockYSize-globalVariables.waveguideYSize)/2.0,0), material=mp.Medium(epsilon=globalVariables.epsilonOfBoundary)), mp.Block(mp.Vector3(globalVariables.blockXSize,globalVariables.blockYSize,0), center=mp.Vector3(0,(globalVariables.waveguideYSize-globalVariables.blockYSize)/2.0,0), material=mp.Medium(epsilon=globalVariables.epsilonOfBoundary))] sources = [mp.Source(mp.ContinuousSource(frequency=0.15), component=mp.Ez, center=mp.Vector3(-globalVariables.waveguideXSize/2+1,0,0))] pml_layers = [mp.PML(1.0)] return cell,geometry,sources,pml_layers
def set_geometry(self, args: dict): if args['coordinates']['z'] == 0: args['coordinates']['z'] = mp.inf self.sim_data['geometry'] = [ mp.Block(mp.Vector3(args['coordinates']['x'], args['coordinates']['y'], args['coordinates']['z']), center=mp.Vector3(args['center']['x'], args['center']['y']), material=mp.Medium(epsilon=args['material'])) ]
def get_xs(wg_width=0.35, two_wg_gap=None, encapsulation=None): geometry = [] # Cladding geometry.append(mp.Block(size=mp.Vector3(mp.inf, mp.inf, t_top), center=mp.Vector3(z=t_top/2), material=Cladding)) # BOX geometry.append(mp.Block(size=mp.Vector3(mp.inf, mp.inf, t_box), center=mp.Vector3(z=-t_box/2), material=SiO2)) if encapsulation is not None: t_ped_encap = t_ped + encapsulation t_rib_encap = t_si + encapsulation geometry.append(mp.Block(size=mp.Vector3(mp.inf, mp.inf, t_ped_encap), center=mp.Vector3(z=t_ped_encap/2), material=SiO2)) geometry.append(mp.Block(size=mp.Vector3(mp.inf, wg_width + 2*encapsulation, t_rib_encap), center=mp.Vector3(z=t_rib_encap/2), material=SiO2)) # partial geometry.append(mp.Block(size=mp.Vector3(mp.inf, w_ped, t_ped), center=mp.Vector3(z=t_ped/2), material=ColdSi)) # core if two_wg_gap is None: offsets = [0] else: offsets = np.array([-1, 1]) * (wg_width + two_wg_gap)/2 for offset in offsets: geometry.append(mp.Block(size=mp.Vector3(mp.inf, wg_width, t_si), center=mp.Vector3(y=offset, z=t_si/2), material=ColdSi)) return geometry
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(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 main(): n = 3.4 # index of waveguide r = 1 a = r # inner radius of ring w = 1 # width of waveguide b = a + w # outer radius of ring pad = 4 # padding between waveguide and edge of PML dpml = 2 # thickness of PML pml_layers = [mp.PML(dpml)] resolution = 100 sr = b + pad + dpml # radial size (cell is from 0 to sr) dimensions = mp.CYLINDRICAL # coordinate system is (r,phi,z) instead of (x,y,z) cell = mp.Vector3(sr, 0, 0) m = 4 geometry = [ mp.Block(center=mp.Vector3(a + (w / 2)), size=mp.Vector3(w, 1e20, 1e20), material=mp.Medium(index=n)) ] # Finding a resonance mode with a high Q-value (calculated with Harminv) fcen = 0.15 # pulse center frequency df = 0.1 # pulse width (in frequency) sources = [ mp.Source(mp.GaussianSource(fcen, fwidth=df), mp.Hz, mp.Vector3(r + 0.1), amplitude=1) ] sim = mp.Simulation(cell_size=cell, geometry=geometry, boundary_layers=pml_layers, resolution=resolution, sources=sources, dimensions=dimensions, m=m) h = mp.Harminv(mp.Hz, mp.Vector3(r + 0.1), fcen, df) sim.run(mp.after_sources(h), until_after_sources=200) print(f'Harminv found {len(h.modes)} resonant modes(s).') for mode in h.modes: print(f'The resonant mode with f={mode.freq} has Q={mode.Q}')
def get_freqs(hx, hy, a, w): wz = 0.22 res = 20 mode = "zEyO" resolution = res # pixels/a, taken from simpetus example # a = round(a,3) # units of um # h = round(wz, 3) # units of um # w = round(wy, 3) # units of um # hx = round(hx, 3) # hy = round(hy, 3) h = wz h = h / a # units of "a" w = w / a # units of "a" hx = hx / a # units of "a" hy = hy / a # units of "a" nSi = 3.45 Si = mp.Medium(index=nSi) geometry_lattice = mp.Lattice(size=mp.Vector3( 1, 4, 4)) # dimensions of lattice taken from simpetus example geometry = [ mp.Block(center=mp.Vector3(), size=mp.Vector3(mp.inf, w, h), material=Si), mp.Ellipsoid(material=mp.air, center=mp.Vector3(), size=mp.Vector3(hx, hy, mp.inf)) ] k_points = [mp.Vector3(0.5, 0, 0)] num_bands = 2 # from simpetus example ms = mpb.ModeSolver(geometry_lattice=geometry_lattice, geometry=geometry, k_points=k_points, resolution=resolution, num_bands=num_bands) if mode == "te": ms.run_te() # running for all modes and extracting parities if mode == "zEyO": ms.run_yodd_zeven() return ms.freqs
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 create_sim(self, beta_vector, vacuum=False): args = self.args hwvg = mp.Block(center=origin, material=mp.Medium(epsilon=args.eps), size=mp.Vector3(self.cell_size.x, args.wh)) vwvg = mp.Block(center=origin, material=mp.Medium(epsilon=args.eps), size=mp.Vector3(args.wv, self.cell_size.y)) router = mp.Block( center=self.design_center, size=self.design_size, epsilon_func=self.basis.parameterized_function(beta_vector)) geometry = [hwvg, vwvg, router] envelope = mp.GaussianSource(args.fcen, fwidth=args.df) amp = 1.0 if callable(getattr(envelope, "fourier_transform", None)): amp /= envelope.fourier_transform(args.fcen) sources = [ mp.EigenModeSource(src=envelope, center=self.source_center, size=self.source_size, eig_band=args.source_mode, amplitude=amp) ] sim = mp.Simulation(resolution=args.res, cell_size=self.cell_size, boundary_layers=[mp.PML(self.dpml)], geometry=geometry, sources=sources) if args.complex_fields: sim.force_complex_fields = True return sim
def add_waveguide_1d(geom=None, wvg_width=.65, wvg_height=.25, center=mp.Vector3(0, 0, 0), material=mp.Medium(index=3.45), d_tuning=0, material_tuning=mp.Medium(index=1.025)): """ Creates a 1D waveguide. The LHe shell can be adopted such that N2 ice layers could be investigated as well. """ if geom is None: geom = [] if isinstance(center, mp.Vector3): _center = center elif len(center) == 3: _center = mp.Vector3(center[0], center[1], center[2]) else: warnings.warn("Variable center not understood but passed") _center = center # LHe shell if d_tuning != 0: geom.append( mp.Block(material=index_to_material(material_tuning), center=_center, size=mp.Vector3(mp.inf, wvg_width + 2 * d_tuning, wvg_height + 2 * d_tuning))) # Si waveguide geom.append( mp.Block(material=index_to_material(material), center=_center, size=mp.Vector3(mp.inf, wvg_width, wvg_height))) return geom
def test_custom_em_source(self): resolution = 20 dpml = 2 pml_layers = [mp.PML(thickness=dpml)] sx = 40 sy = 12 cell_size = mp.Vector3(sx + 2 * dpml, sy) v0 = 0.15 # pulse center frequency a = 0.2 * v0 # Gaussian envelope half-width b = -0.1 # linear chirp rate (positive: up-chirp, negative: down-chirp) t0 = 15 # peak time chirp = lambda t: np.exp(1j * 2 * np.pi * v0 * (t - t0)) * np.exp(-a * (t - t0)**2 + 1j * b * (t - t0)**2) geometry = [ mp.Block(center=mp.Vector3(0, 0, 0), size=mp.Vector3(mp.inf, 1, mp.inf), material=mp.Medium(epsilon=12)) ] kx = 0.4 # initial guess for wavevector in x-direction of eigenmode kpoint = mp.Vector3(kx) bnum = 1 sources = [ mp.EigenModeSource(src=mp.CustomSource(src_func=chirp, center_frequency=v0), center=mp.Vector3(-0.5 * sx + dpml + 1), size=mp.Vector3(y=sy), eig_kpoint=kpoint, eig_band=bnum, eig_parity=mp.EVEN_Y + mp.ODD_Z, eig_match_freq=True) ] sim = mp.Simulation(cell_size=cell_size, boundary_layers=pml_layers, resolution=resolution, k_point=mp.Vector3(), sources=sources, geometry=geometry, symmetries=[mp.Mirror(mp.Y)]) t = np.linspace(0, 50, 1000) sim.run(until=t0 + 50)
def gen_particle_geo(loc, theta_x, theta_y, theta_z): R = np.empty((num_crystal, 3, 3)) Rx_matrix = np.empty((num_crystal, 3, 3)) Ry_matrix = np.empty((num_crystal, 3, 3)) Rz_matrix = np.empty((num_crystal, 3, 3)) for i in range(num_crystal): Rx_matrix[i, :, :] = np.array([[1, 0, 0], [0, cos(theta_x[i]), -sin(theta_x[i])], [0, sin(theta_x[i]), cos(theta_x[i])]]) Ry_matrix[i, :, :] = np.array([[cos(theta_y[i]), 0, sin(theta_y[i])], [0, 1, 0], [-sin(theta_y[i]), 0, cos(theta_y[i])]]) Rz_matrix[i, :, :] = np.array([[cos(theta_z[i]), -sin(theta_z[i]), 0], [sin(theta_z[i]), cos(theta_z[i]), 0], [0, 0, 1]]) R[i, :, :] = np.matmul(np.matmul(Ry_matrix[i, :, :], Rx_matrix[i, :, :]), Rz_matrix[i, :, :]) og_x = np.array([[1, 0, 0] for i in range(num_crystal)]) og_y = np.array([[0, 1, 0] for i in range(num_crystal)]) og_z = np.array([[0, 0, 1] for i in range(num_crystal)]) Rx_vector = np.empty((num_crystal, 3)) Ry_vector = np.empty((num_crystal, 3)) Rz_vector = np.empty((num_crystal, 3)) for i in range(num_crystal): Rx_vector[i, :] = np.matmul(R[i, :, :], og_x[i, :]) Ry_vector[i, :] = np.matmul(R[i, :, :], og_y[i, :]) Rz_vector[i, :] = np.matmul(R[i, :, :], og_z[i, :]) geometry = [solid_region,] for i in range(num_crystal): if (np.abs(loc[i, 0]) < size_solid[0] - size_crystal_base[0]/2 and np.abs(loc[i, 1]) < size_solid[1] - size_crystal_base[1]/2 and np.abs(loc[i, 2]) < size_solid[2] - size_crystal_base[2]/2): geometry.append(mp.Block( size_crystal[i], center = mp.Vector3(loc[i, 0], loc[i, 1], loc[i, 2]), e1 = Rx_vector[i, :], e2 = Ry_vector[i, :], e3 = Rz_vector[i, :], material=mp.Medium(epsilon=10.5))) return geometry
def setUpClass(cls): cls.resolution = 30 # pixels/μm cls.dpml = 1.0 # PML thickness cls.dsub = 1.0 # substrate thickness cls.dpad = 1.0 # padding thickness between grating and PML cls.gp = 6.0 # grating period cls.gh = 0.5 # grating height cls.gdc = 0.5 # grating duty cycle cls.sx = cls.dpml + cls.dsub + cls.gh + cls.dpad + cls.dpml cls.sy = cls.gp cls.cell_size = mp.Vector3(cls.sx, cls.sy, 0) # replace anisotropic PML with isotropic Absorber to # attenuate parallel-directed fields of oblique source cls.abs_layers = [mp.Absorber(thickness=cls.dpml, direction=mp.X)] wvl = 0.5 # center wavelength cls.fcen = 1 / wvl # center frequency cls.df = 0.05 * cls.fcen # frequency width cls.ng = 1.5 cls.glass = mp.Medium(index=cls.ng) cls.geometry = [ mp.Block(material=cls.glass, size=mp.Vector3(cls.dpml + cls.dsub, mp.inf, mp.inf), center=mp.Vector3( -0.5 * cls.sx + 0.5 * (cls.dpml + cls.dsub), 0, 0)), mp.Block(material=cls.glass, size=mp.Vector3(cls.gh, cls.gdc * cls.gp, mp.inf), center=mp.Vector3( -0.5 * cls.sx + cls.dpml + cls.dsub + 0.5 * cls.gh, 0, 0)) ]
def main(): # Some parameters to describe the geometry: eps = 13 # dielectric constant of waveguide w = 1.2 # width of waveguide r = 0.36 # radius of holes # The cell dimensions sy = 12 # size of cell in y direction (perpendicular to wvg.) dpml = 1 # PML thickness (y direction only!) cell = mp.Vector3(1, sy) b = mp.Block(size=mp.Vector3(mp.inf, w, mp.inf), material=mp.Medium(epsilon=eps)) c = mp.Cylinder(radius=r) fcen = 0.25 # pulse center frequency df = 1.5 # pulse freq. width: large df = short impulse s = mp.Source(src=mp.GaussianSource(fcen, fwidth=df), component=mp.Hz, center=mp.Vector3(0.1234)) sym = mp.Mirror(direction=mp.Y, phase=-1) sim = mp.Simulation(cell_size=cell, geometry=[b, c], sources=[s], symmetries=[sym], boundary_layers=[mp.PML(dpml, direction=mp.Y)], resolution=20) kx = False # if true, do run at specified kx and get fields k_interp = 19 # # k-points to interpolate, otherwise if kx: sim.k_point = mp.Vector3(kx) sim.run(mp.at_beginning(mp.output_epsilon), mp.after_sources( mp.Harminv(mp.Hz, mp.Vector3(0.1234), fcen, df)), until_after_sources=300) sim.run(mp.at_every(1 / fcen / 20, mp.output_hfield_z), until=1 / fcen) else: sim.run_k_points( 300, mp.interpolate(k_interp, [mp.Vector3(), mp.Vector3(0.5)]))
def parallel_waveguide(s,yodd): geometry = [mp.Block(center=mp.Vector3(0,-0.5*(s+a),0), size=mp.Vector3(mp.inf,a,a), material=Si), mp.Block(center=mp.Vector3(0,0.5*(s+a),0), size=mp.Vector3(mp.inf,a,a), material=Si)] ms = mpb.ModeSolver(resolution=resolution, k_points=k_points, geometry_lattice=geometry_lattice, geometry=geometry, num_bands=1, tolerance=1e-9) if yodd: ms.run_yodd_zodd() else: ms.run_yeven_zodd() f = ms.get_freqs()[0] vg = ms.compute_group_velocity_component(mp.Vector3(1,0,0))[0] return f,vg
def geom2(THICKNESS, sx, sy, g, d1, d2, material, spacer, dpml): Glass = mp.Medium(epsilon=g) diel1 = mp.Medium(epsilon=d1) diel2 = mp.Medium(epsilon=d2) mat = [Au, Al, Ag, Glass, diel1, diel2, Cr, Ti] geometry = [] t = -sy * 0.5 + dpml for i in range(len(THICKNESS)): if THICKNESS[i] == 0: pass else: t += THICKNESS[i] * 0.5 geometry.append( mp.Block(mp.Vector3(mp.inf, THICKNESS[i], mp.inf), center=mp.Vector3(0, t, 0), material=mat[material[i]])) t += THICKNESS[i] * 0.5 geometry.append( mp.Block(mp.Vector3(spacer, THICKNESS[-3] + THICKNESS[-2], mp.inf), center=mp.Vector3( 0, -(THICKNESS[-2] + THICKNESS[-3]) * 0.5 + t - THICKNESS[-1], 0), material=mat[material[-1]])) return (geometry)
def create_plasma(max_eps, lx, ly, resolution): tamx = 1/resolution tamy = ly var = int((lx/2)*resolution) plasma = [] for i in range(var): bloco = mp.Block(mp.Vector3(tamx,tamy,0), center=mp.Vector3(tamx*i,0), material=mp.Medium(epsilon=1+(i*max_eps/var))) plasma.append(bloco) return plasma
def generatePhotonicGrid(numpyArray): photonicArray = numpyArray geometry = [ mp.Block(mp.Vector3(grid.xLength, grid.yLength, 1), center=mp.Vector3(0, 0, 0), material=mp.Medium(epsilon=1)) ] areasWithSilicon = np.argwhere(photonicArray == 1) for i in areasWithSilicon: xindex = i[0] yindex = i[1] x, y = blockIndexToCenter(xindex, yindex) block = createBlockObject(x, y) geometry.append(block) return geometry
def createDiffractionGrating(): cell = mp.Vector3(globalVariables.waveguideXSize, globalVariables.waveguideYSize, 0) geometry = [mp.Block(mp.Vector3(1e20, 1, 1e20), center=mp.Vector3(0, 0), material=mp.Medium(epsilon=globalVariables.epsilonOfMaterial))] for i in range(globalVariables.numberOfSlitsForDiffractionGrating+1): centerXValue , centerYValue = diffractionGratingBlockCenter(i) #centerXValue = np.round(centerXValue) #centerYValue = np.round(centerYValue) blockXSize , blockYSize = diffractionGratingBlockSize() #blockXSize = np.round(blockXSize) #blockYSize = np.round(blockYSize) geometry.append(mp.Block(mp.Vector3(blockXSize,blockYSize,0), center=mp.Vector3(centerXValue,centerYValue,0), material=mp.Medium(epsilon=globalVariables.epsilonOfBoundary))) print(len(geometry),"THIS IS LEN GEOMEETRY") sources = [mp.Source(mp.ContinuousSource(frequency=0.15), component=mp.Ez, center=mp.Vector3(-globalVariables.waveguideXSize/2+1,0,0))] pml_layers = [mp.PML(1.0)] return cell,geometry,sources,pml_layers
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 add_substrate(geom=None, waveguide_height=0.22, substrate_height=5, material=mp.Medium(index=1.44)): """ Creates a (by default SiO2) substrate. If the unlike case occurs that we need to change the center, we could again make everything relative to the center of the substrate. """ if geom is None: geom = [] _center = mp.Vector3(0, 0, -waveguide_height/2-substrate_height/2) geom.append(mp.Block(material=index_to_material(material), center=_center, size=mp.Vector3(mp.inf, mp.inf, substrate_height))) return geom
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 test_dft_energy(self): resolution = 20 cell = mp.Vector3(10, 5) geom = [ mp.Block(size=mp.Vector3(mp.inf, 1, mp.inf), material=mp.Medium(epsilon=12)) ] pml = [mp.PML(1)] fsrc = 0.15 sources = [ mp.EigenModeSource(src=mp.GaussianSource(frequency=fsrc, fwidth=0.2 * fsrc), center=mp.Vector3(-3), size=mp.Vector3(y=5), eig_band=1, eig_parity=mp.ODD_Z + mp.EVEN_Y, eig_match_freq=True) ] sim = mp.Simulation(resolution=resolution, cell_size=cell, geometry=geom, boundary_layers=pml, sources=sources, symmetries=[mp.Mirror(direction=mp.Y)]) flux = sim.add_flux( fsrc, 0, 1, mp.FluxRegion(center=mp.Vector3(3), size=mp.Vector3(y=5))) energy = sim.add_energy( fsrc, 0, 1, mp.EnergyRegion(center=mp.Vector3(3), size=mp.Vector3(y=5))) sim.run(until_after_sources=100) res = sim.get_eigenmode_coefficients(flux, [1], eig_parity=mp.ODD_Z + mp.EVEN_Y) mode_vg = res.vgrp[0] poynting_flux = mp.get_fluxes(flux)[0] e_energy = mp.get_electric_energy(energy)[0] ratio_vg = (0.5 * poynting_flux) / e_energy m_energy = mp.get_magnetic_energy(energy)[0] t_energy = mp.get_total_energy(energy)[0] self.assertAlmostEqual(m_energy + e_energy, t_energy) self.assertAlmostEqual(ratio_vg, mode_vg, places=3)
def main(args): sx = 4.0 #spatial extent along x including pmls (μm) sy = 4 sz = 0 dpml = 1.0 cell = mp.Vector3(sx, sy, sz) pml_layers = [mp.PML(dpml)] geometry = [ mp.Block(mp.Vector3(mp.inf, 0.050, 0), center=mp.Vector3(0, 0.025, 0), material=Ag) ] resolution = args.res wvlmax = 1.0 fmin = 1 / wvlmax wvlmin = 0.100 fmax = 1 / wvlmin wvl = args.wvl fcen = 1 / wvl df = fmax - fmin nfreq = 1 print("wavelength =", wvl, "μm") print("center frequency =", fcen, "1/μm") source = [ mp.Source(mp.GaussianSource(fcen, 0, nfreq), component=mp.Ex, center=mp.Vector3(0, -0.050, 0)) ] symmetries = [mp.Mirror(mp.X), mp.Mirror(mp.Z)] sim = mp.Simulation(cell_size=cell, geometry=geometry, sources=source, resolution=resolution, boundary_layers=pml_layers) pt = mp.Vector3(0, -0.050, 0) sim.run(mp.dft_ldos(fcen, 0, nfreq), until_after_sources=mp.stop_when_fields_decayed( 20, mp.Ex, pt, 1e-3)) eps_data = sim.get_array(center=mp.Vector3(), size=cell, component=mp.Dielectric) ey_data = sim.get_array(center=mp.Vector3(), size=cell, component=mp.Ey)