def setUp(self): susceptibilities = [ mp.LorentzianSusceptibility(frequency=1.1, gamma=1e-5, sigma=0.5), mp.LorentzianSusceptibility(frequency=0.5, gamma=0.1, sigma=2e-5) ] default_material = mp.Medium(epsilon=2.25, E_susceptibilities=susceptibilities) fcen = 1.0 df = 2.0 sources = mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ez, center=mp.Vector3()) kmin = 0.3 kmax = 2.2 k_interp = 5 self.kpts = mp.interpolate( k_interp, [mp.Vector3(kmin), mp.Vector3(kmax)]) self.sim = mp.Simulation(cell_size=mp.Vector3(), geometry=[], sources=[sources], default_material=default_material, resolution=20)
def test_list_split(self): k_points = [ mp.Vector3(), mp.Vector3(0.5), mp.Vector3(0.5, 0.5), mp.Vector3() ] k_points = mp.interpolate(4, k_points) ms = mpb.ModeSolver() k_split = ms.list_split(k_points, 1, 0) expected_list = [ mp.Vector3(), mp.Vector3(0.10000000000000003), mp.Vector3(0.20000000000000004), mp.Vector3(0.30000000000000004), mp.Vector3(0.4), mp.Vector3(0.5), mp.Vector3(0.5, 0.10000000000000003), mp.Vector3(0.5, 0.20000000000000004), mp.Vector3(0.5, 0.30000000000000004), mp.Vector3(0.5, 0.4), mp.Vector3(0.5, 0.5), mp.Vector3(0.4, 0.4), mp.Vector3(0.30000000000000004, 0.30000000000000004), mp.Vector3(0.2, 0.2), mp.Vector3(0.1, 0.1), mp.Vector3(0.0, 0.0), ] self.assertEqual(k_split[0], 0) for res, exp in zip(k_split[1], expected_list): self.assertTrue(res.close(exp))
def test_interpolate_vectors(self): expected = [ mp.Vector3(), mp.Vector3(0.024999999999999842), mp.Vector3(0.04999999999999984), mp.Vector3(0.07499999999999984), mp.Vector3(0.09999999999999984), mp.Vector3(0.12499999999999983), mp.Vector3(0.14999999999999983), mp.Vector3(0.17499999999999982), mp.Vector3(0.19999999999999982), mp.Vector3(0.2249999999999998), mp.Vector3(0.2499999999999998), mp.Vector3(0.2749999999999998), mp.Vector3(0.2999999999999998), mp.Vector3(0.32499999999999984), mp.Vector3(0.34999999999999987), mp.Vector3(0.3749999999999999), mp.Vector3(0.3999999999999999), mp.Vector3(0.42499999999999993), mp.Vector3(0.44999999999999996), mp.Vector3(0.475), mp.Vector3(0.5) ] res = mp.interpolate(19, [mp.Vector3(), mp.Vector3(0.5)]) np.testing.assert_allclose([v.x for v in expected], [v.x for v in res]) np.testing.assert_allclose([v.y for v in expected], [v.y for v in res]) np.testing.assert_allclose([v.z for v in expected], [v.z for v in res])
def triangular_with_defect(): k_points = [mp.Vector3(), mp.Vector3(0., 0.5), mp.Vector3(-1 / 3, 1 / 3), mp.Vector3()] k_points = mp.interpolate(10, k_points) geometry_lattice = mp.Lattice(size=mp.Vector3(5, 5), basis1=mp.Vector3(math.sqrt(3) / 2, 0.5), basis2=mp.Vector3(math.sqrt(3) / 2, -0.5)) geometry = [mp.Cylinder(0.25, material=gaas)] geometry = mp.geometric_objects_lattice_duplicates(geometry_lattice, geometry) defect = mp.Cylinder(0.2, material=gaas) geometry.append(defect) default_material = bcb resolution = 32 mesh_size = 7 num_bands = 5 ms = mpb.ModeSolver(num_bands=num_bands, k_points=k_points, geometry=geometry, geometry_lattice=geometry_lattice, resolution=resolution, default_material=default_material, mesh_size=mesh_size) return ms
def triangular(): k_points = [mp.Vector3(), mp.Vector3(0., 0.5), mp.Vector3(-1 / 3, 1 / 3), mp.Vector3()] k_points = mp.interpolate(10, k_points) geometry = [mp.Cylinder(0.25, material=gaas)] geometry_lattice = mp.Lattice(size=mp.Vector3(1, 1), basis1=mp.Vector3(math.sqrt(3) / 2, 0.5), basis2=mp.Vector3(math.sqrt(3) / 2, -0.5)) default_material = bcb resolution = 32 mesh_size = 7 num_bands = 5 ms = mpb.ModeSolver(num_bands=num_bands, k_points=k_points, geometry=geometry, geometry_lattice=geometry_lattice, resolution=resolution, default_material=default_material, mesh_size=mesh_size) return ms
def get_freqs_interpolate(hx=0.24, hy=0.24, a=0.33, wy=0.7, h=0.22): ''' Useless ''' import meep as mp from meep import mpb mode = "zEyO" resolution = 20 # pixels/a, taken from simpetus example a = round(a, 3) # units of um h = round(h, 3) # units of um w = round(wy, 3) # units of um hx = round(hx, 3) hy = round(hy, 3) 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)) ] num_k = 20 # from simpetus example, no. of k_points to evaluate the eigen frequency at k_points = mp.interpolate( num_k, [mp.Vector3(0, 0, 0), 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 test_run_k_points(self): all_freqs = self.sim.run_k_points( 5, mp.interpolate(19, [mp.Vector3(), mp.Vector3(0.5)])) expected = [(0.1942497850393511, 0.001381460274205755), (0.19782709203322993, -0.0013233828667934015), (0.1927618763491877, 0.001034260690735336), (0.19335527231544278, 4.6649450258959025e-4)] self.assertTrue(any(l for l in all_freqs)) for (r, i), f in zip(expected, all_freqs[17:21][0]): self.assertAlmostEqual(r, f.real) self.assertAlmostEqual(i, f.imag)
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 test_triangular_lattice(self): expected_brd = [ ((0.0, mp.Vector3(0.0, 0.0, 0.0)), (0.2746902258623623, mp.Vector3(-0.3333333333333333, 0.3333333333333333, 0.0))), ((0.44533108084715683, mp.Vector3(0.0, 0.5, 0.0)), (0.5605181423162835, mp.Vector3(0.0, 0.0, 0.0))), ((0.4902389149027666, mp.Vector3(-0.3333333333333333, 0.3333333333333333, 0.0)), (0.5605607947797747, mp.Vector3(0.0, 0.0, 0.0))), ((0.5932960873585144, mp.Vector3(0.0, 0.0, 0.0)), (0.7907195974443698, mp.Vector3(-0.3333333333333333, 0.3333333333333333, 0.0))), ((0.790832076332758, mp.Vector3(-0.3333333333333333, 0.3333333333333333, 0.0)), (0.8374511167537562, mp.Vector3(0.0, 0.0, 0.0))), ((0.8375948528443267, mp.Vector3(0.0, 0.0, 0.0)), (0.867200926490345, mp.Vector3(-0.2, 0.39999999999999997, 0.0))), ((0.8691349955739203, mp.Vector3(-0.13333333333333336, 0.4333333333333333, 0.0)), (0.9941291022664892, mp.Vector3(0.0, 0.0, 0.0))), ((0.8992499095547049, mp.Vector3(-0.3333333333333333, 0.3333333333333333, 0.0)), (1.098318352915696, mp.Vector3(0.0, 0.0, 0.0))), ] ms = self.init_solver() ms.geometry_lattice = mp.Lattice( size=mp.Vector3(1, 1), basis1=mp.Vector3(math.sqrt(3) / 2, 0.5), basis2=mp.Vector3(math.sqrt(3) / 2, -0.5)) k_points = [ mp.Vector3(), mp.Vector3(y=0.5), mp.Vector3(-1 / 3, 1 / 3), mp.Vector3() ] ms.k_points = mp.interpolate(4, k_points) ms.run_tm() self.check_band_range_data(expected_brd, ms.band_range_data)
def test_material_dispersion_with_user_material(self): susceptibilities = [ mp.LorentzianSusceptibility(frequency=1.1, gamma=1e-5, sigma=0.5), mp.LorentzianSusceptibility(frequency=0.5, gamma=0.1, sigma=2e-5) ] def mat_func(p): return mp.Medium(epsilon=2.25, E_susceptibilities=susceptibilities) fcen = 1.0 df = 2.0 sources = mp.Source( mp.GaussianSource(fcen, fwidth=df), component=mp.Ez, center=mp.Vector3() ) kmin = 0.3 kmax = 2.2 k_interp = 5 kpts = mp.interpolate(k_interp, [mp.Vector3(kmin), mp.Vector3(kmax)]) self.sim = mp.Simulation( cell_size=mp.Vector3(), geometry=[], sources=[sources], material_function=mat_func, default_material=mp.air, resolution=20 ) all_freqs = self.sim.run_k_points(200, kpts) res = [f.real for fs in all_freqs for f in fs] expected = [ 0.1999342026399106, 0.41053963810375294, 0.6202409070451909, 0.8285737385146619, 1.0350739448523063, 1.2392775309110078, 1.4407208712852109, ] np.testing.assert_allclose(expected, res)
def test_interpolate_numbers(self): expected = [ 1.0, 1.0909090909090908, 1.1818181818181819, 1.2727272727272727, 1.3636363636363635, 1.4545454545454546, 1.5454545454545454, 1.6363636363636365, 1.7272727272727273, 1.8181818181818181, 1.9090909090909092, 2.0, 2.090909090909091, 2.1818181818181817, 2.272727272727273, 2.3636363636363638, 2.4545454545454546, 2.5454545454545454, 2.6363636363636362, 2.727272727272727, 2.8181818181818183, 2.909090909090909, 3.0, 3.090909090909091, 3.1818181818181817, 3.272727272727273, 3.3636363636363638, 3.4545454545454546, 3.5454545454545454, 3.6363636363636362, 3.727272727272727, 3.8181818181818183, 3.909090909090909, 4.0, 4.090909090909091, 4.181818181818182, 4.2727272727272725, 4.363636363636363, 4.454545454545454, 4.545454545454546, 4.636363636363637, 4.7272727272727275, 4.818181818181818, 4.909090909090909, 5.0, 5.090909090909091, 5.181818181818182, 5.2727272727272725, 5.363636363636363, 5.454545454545454, 5.545454545454546, 5.636363636363637, 5.7272727272727275, 5.818181818181818, 5.909090909090909, 6.0, 6.090909090909091, 6.181818181818182, 6.2727272727272725, 6.363636363636363, 6.454545454545454, 6.545454545454546, 6.636363636363637, 6.7272727272727275, 6.818181818181818, 6.909090909090909, 7.0, 7.090909090909091, 7.181818181818182, 7.2727272727272725, 7.363636363636363, 7.454545454545454, 7.545454545454546, 7.636363636363637, 7.7272727272727275, 7.818181818181818, 7.909090909090909, 8.0, 8.090909090909092, 8.181818181818182, 8.272727272727273, 8.363636363636363, 8.454545454545455, 8.545454545454545, 8.636363636363637, 8.727272727272727, 8.818181818181818, 8.909090909090908, 9.0, 9.090909090909092, 9.181818181818182, 9.272727272727273, 9.363636363636363, 9.454545454545455, 9.545454545454545, 9.636363636363637, 9.727272727272727, 9.818181818181818, 9.909090909090908, 10.0 ] nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] result = mp.interpolate(10, nums) np.testing.assert_allclose(expected, result)
def test_material_dispersion_with_user_material(self): susceptibilities = [ mp.LorentzianSusceptibility(frequency=1.1, gamma=1e-5, sigma=0.5), mp.LorentzianSusceptibility(frequency=0.5, gamma=0.1, sigma=2e-5) ] def mat_func(p): return mp.Medium(epsilon=2.25, E_susceptibilities=susceptibilities) fcen = 1.0 df = 2.0 sources = mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ez, center=mp.Vector3()) kmin = 0.3 kmax = 2.2 k_interp = 5 kpts = mp.interpolate(k_interp, [mp.Vector3(kmin), mp.Vector3(kmax)]) self.sim = mp.Simulation(cell_size=mp.Vector3(), geometry=[], sources=[sources], material_function=mat_func, default_material=mp.air, resolution=20) all_freqs = self.sim.run_k_points(200, kpts) res = [f.real for fs in all_freqs for f in fs] expected = [ 0.1999342026399106, 0.41053963810375294, 0.6202409070451909, 0.8285737385146619, 1.0350739448523063, 1.2392775309110078, 1.4407208712852109, ] np.testing.assert_allclose(expected, res)
def example_case(): num_bands = 3 resolution = 32 k_point = [ mp.Vector3(), mp.Vector3(0.5), mp.Vector3(0.5, 0.5), mp.Vector3() ] k_points = mp.interpolate(40, k_point) geometry = [mp.Cylinder(0.2, material=mp.Medium(epsilon=12))] geometry_lattice = mp.Lattice(size=mp.Vector3(1, 1)) ms = mpb.ModeSolver(num_bands=num_bands, k_points=k_points, geometry=geometry, geometry_lattice=geometry_lattice, resolution=resolution) ms.run_te() return ms
def init_solver(self, geom=True): num_bands = 8 k_points = [ mp.Vector3(), mp.Vector3(0.5), mp.Vector3(0.5, 0.5), mp.Vector3() ] geometry = [mp.Cylinder(0.2, material=mp.Medium( epsilon=12))] if geom else [] k_points = mp.interpolate(4, k_points) geometry_lattice = mp.Lattice(size=mp.Vector3(1, 1)) resolution = 32 return mpb.ModeSolver(num_bands=num_bands, k_points=k_points, geometry=geometry, geometry_lattice=geometry_lattice, resolution=resolution, filename_prefix=self.filename_prefix, deterministic=True, tolerance=1e-12)
mp.Block(material=mp.Medium(epsilon=eps), size=mp.Vector3(mp.inf, mp.inf, h)), mp.Cylinder(r, material=mp.air, height=supercell_h) ] # 1st Brillouin zone of a triangular lattice: Gamma = mp.Vector3() M = mp.Vector3(y=0.5) K = mp.Vector3(1 / -3, 1 / 3) only_K = False # run with only_K=true to only do this k_point k_interp = 4 # the number of k points to interpolate if only_K: k_points = [K] else: k_points = mp.interpolate(k_interp, [Gamma, M, K, Gamma]) resolution = mp.Vector3(32, 32, 16) num_bands = 9 ms = mpb.ModeSolver(geometry_lattice=geometry_lattice, geometry=geometry, resolution=resolution, num_bands=num_bands, k_points=k_points) def main(): # Run even and odd bands, outputting fields only at the K point: if loweps == 1.0: # we only have even/odd classification for symmetric structure
# k_points = [ # mp.Vector3(), # Gamma # mp.Vector3(y=0.5), # M # mp.Vector3(-1./3, 1./3), # K # mp.Vector3(), # Gamma # ] # ============================================================================= k_points = [ mp.Vector3(-1. / 3, 1. / 3), # K mp.Vector3(), # Gamma mp.Vector3(y=0.5), # M mp.Vector3(-1. / 3, 1. / 3) # K ] k_points = mp.interpolate(50, k_points) ms = mpb.ModeSolver(geometry=geometry, geometry_lattice=geometry_lattice, k_points=k_points, resolution=resolution, num_bands=num_bands) ms.run_tm( mpb.output_at_kpoint(mp.Vector3(-1. / 3, 1. / 3), mpb.fix_efield_phase, mpb.output_efield_z)) tm_freqs = ms.all_freqs tm_gaps = ms.gap_list ms.run_te() te_freqs = ms.all_freqs te_gaps = ms.gap_list
basis1=mp.Vector3(-1, 1, 1), basis2=mp.Vector3(1, -1, 1), basis3=mp.Vector3(1, 1, -1)) # Corners of the irreducible Brillouin zone for the "I" lattice, # in order that matches Maldovan2002 Fig 10 vlist = [ mp.Vector3(0, 0, 0.5), # N mp.Vector3(0.25, 0.25, 0.25), # P mp.Vector3(0, 0, 0), # Gamma mp.Vector3(0, 0, 0.5), # N mp.Vector3(0.5, -0.5, 0.5), # H mp.Vector3(0.25, 0.25, 0.25) # P ] k_points = mp.interpolate(4, vlist) # define a couple of parameters (which we can set from the command_line) #eps = 20.00 # the dielectric constant of the spheres #r = 0.25 # the radius of the spheres #diel = mp.Medium(epsilon=eps) # A diamond lattice has two "atoms" per unit cell: #geometry = [mp.Sphere(r, center=mp.Vector3(0.125, 0.125, 0.125), material=diel), # mp.Sphere(r, center=mp.Vector3(-0.125, -0.125, -0.125), material=diel)] # (A simple fcc lattice would have only one sphere/object at the origin.) resolution = 16 # use a 16x16x16 grid mesh_size = 5
basis3=mp.Vector3(1, 1) ) # Corners of the irreducible Brillouin zone for the fcc lattice, # in a canonical order: vlist = [ mp.Vector3(0, 0.5, 0.5), # X mp.Vector3(0, 0.625, 0.375), # U mp.Vector3(0, 0.5, 0), # L mp.Vector3(0, 0, 0), # Gamma mp.Vector3(0, 0.5, 0.5), # X mp.Vector3(0.25, 0.75, 0.5), # W mp.Vector3(0.375, 0.75, 0.375) # K ] k_points = mp.interpolate(4, vlist) # define a couple of parameters (which we can set from the command_line) eps = 11.56 # the dielectric constant of the spheres r = 0.25 # the radius of the spheres diel = mp.Medium(epsilon=eps) # A diamond lattice has two "atoms" per unit cell: geometry = [mp.Sphere(r, center=mp.Vector3(0.125, 0.125, 0.125), material=diel), mp.Sphere(r, center=mp.Vector3(-0.125, -0.125, -0.125), material=diel)] # (A simple fcc lattice would have only one sphere/object at the origin.) resolution = 16 # use a 16x16x16 grid mesh_size = 5
# far away from the mode field. sc_y = 2 # supercell width (um) sc_z = 2 # supercell height (um) geometry_lattice = mp.Lattice(size=mp.Vector3(0, sc_y, sc_z)) # define the 2d blocks for the strip and substrate geometry = [mp.Block(size=mp.Vector3(mp.inf, mp.inf, 0.5 * (sc_z - h)), center=mp.Vector3(z=0.25 * (sc_z + h)), material=SiO2), mp.Block(size=mp.Vector3(mp.inf, w, h), material=Si)] # The k (i.e. beta, i.e. propagation constant) points to look at, in # units of 2*pi/um. We'll look at num_k points from k_min to k_max. num_k = 9 k_min = 0.1 k_max = 3.0 k_points = mp.interpolate(num_k, [mp.Vector3(k_min), mp.Vector3(k_max)]) resolution = 32 # pixels/um # Increase this to see more modes. (The guided ones are the ones below the # light line, i.e. those with frequencies < kmag / 1.45, where kmag # is the corresponding column in the output if you grep for "freqs:".) num_bands = 4 filename_prefix = 'strip-' # use this prefix for output files ms = mpb.ModeSolver( geometry_lattice=geometry_lattice, geometry=geometry, k_points=k_points, resolution=resolution,
basis2=mp.Vector3(math.sqrt(3) / 2, -0.5)) eps = 12 # the dielectric constant of the rods r = 0.2 # the rod radius in the bulk crystal geometry = [mp.Cylinder(r, material=mp.Medium(epsilon=eps))] # duplicate the bulk crystal rods over the supercell: geometry = mp.geometric_objects_lattice_duplicates(geometry_lattice, geometry) # add a rod of air, to erase a row of rods and form a waveguide: geometry += [mp.Cylinder(r, material=mp.air)] Gamma = mp.Vector3() K_prime = mp.lattice_to_reciprocal(mp.Vector3(0.5), geometry_lattice) # edge of Brillouin zone. k_points = mp.interpolate(4, [Gamma, K_prime]) # the bigger the supercell, the more bands you need to compute to get # to the defect modes (the lowest band is "folded" supercell_y times): extra_bands = 5 # number of extra bands to compute above the gap num_bands = supercell_y + extra_bands resolution = 32 ms = mpb.ModeSolver( geometry_lattice=geometry_lattice, geometry=geometry, k_points=k_points, num_bands=num_bands, resolution=resolution )
import math import sys import os import meep as mp import matplotlib.pyplot as plt from meep import mpb num_bands = 10 interp = 19 # honeycomb: k_points = [mp.Vector3(2 / 3, 1 / 3), mp.Vector3(0, 0), mp.Vector3(0, 0.5)] k_points = mp.interpolate(interp, k_points) # argv[1]: radius of airhole # argv[2]: radius of center # argv[3]: n_back # argv[4]: n_cen # argv[5]: resolution resolution = int(sys.argv[6]) #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!amorphous!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! r_air = 0.001 * int(sys.argv[1]) r_cen1 = 0.001 * int(sys.argv[2]) # r_cen1 = 1/3-r_air r_cen2 = 0.4 * r_cen1 vertices = [
def get_mode_solver_rib( wg_width: float = 0.45, wg_thickness: float = 0.22, slab_thickness: int = 0.0, ncore: float = 3.47, nclad: float = 1.44, sy: float = 2.0, sz: float = 2.0, res: int = 32, nmodes: int = 4, ) -> mpb.ModeSolver: """Returns a mode_solver simulation. Args: wg_width: wg_width (um) wg_thickness: wg height (um) slab_thickness: thickness for the waveguide slab ncore: core material refractive index nclad: clad material refractive index sy: simulation region width (um) sz: simulation region height (um) res: resolution (pixels/um) nmodes: number of modes """ material_core = mp.Medium(index=ncore) material_clad = mp.Medium(index=nclad) # Define the computational cell. We'll make x the propagation direction. # the other cell sizes should be big enough so that the boundaries are # far away from the mode field. geometry_lattice = mp.Lattice(size=mp.Vector3(0, sy, sz)) # define the 2d blocks for the strip and substrate geometry = [ mp.Block( size=mp.Vector3(mp.inf, mp.inf, mp.inf), material=material_clad, ), # uncomment this for air cladded waveguides # mp.Block( # size=mp.Vector3(mp.inf, mp.inf, 0.5 * (sz - wg_thickness)), # center=mp.Vector3(z=0.25 * (sz + wg_thickness)), # material=material_clad, # ), mp.Block( size=mp.Vector3(mp.inf, mp.inf, slab_thickness), material=material_core, center=mp.Vector3(z=-0.5 * slab_thickness), ), mp.Block( size=mp.Vector3(mp.inf, wg_width, wg_thickness), material=material_core, center=mp.Vector3(z=0), ), ] # The k (i.e. beta, i.e. propagation constant) points to look at, in # units of 2*pi/um. We'll look at num_k points from k_min to k_max. num_k = 9 k_min = 0.1 k_max = 3.0 k_points = mp.interpolate(num_k, [mp.Vector3(k_min), mp.Vector3(k_max)]) # Increase this to see more modes. (The guided ones are the ones below the # light line, i.e. those with frequencies < kmag / 1.45, where kmag # is the corresponding column in the output if you grep for "freqs:".) # use this prefix for output files filename_prefix = tmp / f"rib_{wg_width}_{wg_thickness}_{slab_thickness}" mode_solver = mpb.ModeSolver( geometry_lattice=geometry_lattice, geometry=geometry, k_points=k_points, resolution=res, num_bands=nmodes, filename_prefix=str(filename_prefix), ) mode_solver.nmodes = nmodes return mode_solver
geometry_lattice = mp.Lattice(size=mp.Vector3(1, 1)) # 2d cell #geometry = [mp.Cylinder(r, material=GaAs)] #Gamma = mp.Vector3() #X = mp.Vector3(0.5, 0) #M = mp.Vector3(0.5, 0.5) vlist = [ mp.Vector3(0.0, 0.0), # Gamma mp.Vector3(0.5, 0.0), # X mp.Vector3(0.5, 0.5), # M mp.Vector3(0.0, 0.0) # Gamma ] tick_labs = ['$\Gamma$', 'X', 'M', '$\Gamma$'] k_points = mp.interpolate(k_interp, vlist) resolution = 32 num_bands = 8 ms = mpb.ModeSolver( geometry_lattice=geometry_lattice, # geometry=geometry, k_points=k_points, resolution=resolution, num_bands=num_bands, epsilon_input_file='epsilon.h5') def main(): ms.run_te()
#tmax: number of time steps over which sim will run cell, fcen, src_z, pml_layers = mp.Vector3(1,1,1), 0.8, mp.Vector3(0,0,-10), [mp.PML(1.0,mp.Z)] df=2.0 #df: frequency width of source #-------------------------------------------------------# # Create light source: #-------------------------------------------------------# src=[mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ex, center=src_z), mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ey, center=src_z, amplitude=1j)] #-------------------------------------------------------# # Set up k-values over which to plot w(k) frequencies: #-------------------------------------------------------# kz=mp.Vector3(0,0,0.18) kzm, n = mp.Vector3(0,0,-0.18), 30 kpts=mp.interpolate(n, [kzm, kz]) #-------------------------------------------------------# # Create and run sim: #-------------------------------------------------------# #simulate for left-handed polarized light sim=mp.Simulation(cell_size=cell, geometry=[], sources=src, default_material=mp.vacuum, resolution=20) allfreqs=sim.run_k_points(tmax, kpts) print(allfreqs, kpts) print('len(allfreqs)==len(kpts):', len(allfreqs)==len(kpts)) freqs=[] for i in range(len(allfreqs)): freqs+=[allfreqs[i][4]] #freqs: take out first freq of each kpt, put into a list.
mp.LorentzianSusceptibility(frequency=1.1, gamma=1e-5, sigma=0.5), mp.LorentzianSusceptibility(frequency=0.5, gamma=0.1, sigma=2e-5) ] default_material = mp.Medium(epsilon=2.25, E_susceptibilities=susceptibilities) fcen = 1.0 df = 2.0 sources = [mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ez, center=mp.Vector3())] kmin = 0.3 kmax = 2.2 k_interp = 99 kpts = mp.interpolate(k_interp, [mp.Vector3(kmin), mp.Vector3(kmax)]) sim = mp.Simulation( cell_size=cell, geometry=[], sources=sources, default_material=default_material, resolution=resolution ) all_freqs = sim.run_k_points(200, kpts) # a list of lists of frequencies for fs, kx in zip(all_freqs, [v.x for v in kpts]): for f in fs: print("eps:, {:.6g}, {:.6g}, {:.6g}".format(f.real, f.imag, (kx / f)**2))
def main(args): resolution = 30 # pixels/um a_start = args.a_start # starting periodicity a_end = args.a_end # ending periodicity s_cav = args.s_cav # cavity length r = args.r # hole radius (units of a) h = args.hh # waveguide height w = args.w # waveguide width dair = 1.00 # air padding dpml = 1.00 # PML thickness Ndef = args.Ndef # number of defect periods a_taper = mp.interpolate(Ndef, [a_start, a_end]) dgap = a_end - 2 * r * a_end Nwvg = args.Nwvg # number of waveguide periods sx = 2 * (Nwvg * a_start + sum(a_taper)) - dgap + s_cav sy = dpml + dair + w + dair + dpml sz = dpml + dair + h + dair + dpml cell_size = mp.Vector3(sx, sy, sz) boundary_layers = [mp.PML(dpml)] nSi = 3.45 Si = mp.Medium(index=nSi) geometry = [ mp.Block(material=Si, center=mp.Vector3(), size=mp.Vector3(mp.inf, w, h)) ] for mm in range(Nwvg): geometry.append( mp.Cylinder(material=mp.air, radius=r * a_start, height=mp.inf, center=mp.Vector3( -0.5 * sx + 0.5 * a_start + mm * a_start, 0, 0))) geometry.append( mp.Cylinder(material=mp.air, radius=r * a_start, height=mp.inf, center=mp.Vector3( +0.5 * sx - 0.5 * a_start - mm * a_start, 0, 0))) for mm in range(Ndef + 2): geometry.append( mp.Cylinder(material=mp.air, radius=r * a_taper[mm], height=mp.inf, center=mp.Vector3( -0.5 * sx + Nwvg * a_start + (sum(a_taper[:mm]) if mm > 0 else 0) + 0.5 * a_taper[mm], 0, 0))) geometry.append( mp.Cylinder(material=mp.air, radius=r * a_taper[mm], height=mp.inf, center=mp.Vector3( +0.5 * sx - Nwvg * a_start - (sum(a_taper[:mm]) if mm > 0 else 0) - 0.5 * a_taper[mm], 0, 0))) lambda_min = 1.46 # minimum source wavelength lambda_max = 1.66 # maximum source wavelength fmin = 1 / lambda_max fmax = 1 / lambda_min fcen = 0.5 * (fmin + fmax) df = fmax - fmin sources = [ mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ey, center=mp.Vector3()) ] symmetries = [ mp.Mirror(mp.X, +1), mp.Mirror(mp.Y, -1), mp.Mirror(mp.Z, +1) ] sim = mp.Simulation(resolution=resolution, cell_size=cell_size, boundary_layers=boundary_layers, geometry=geometry, sources=sources, dimensions=3, symmetries=symmetries) #sim.run(mp.in_volume(mp.Volume(center=mp.Vector3(), size=mp.Vector3(sx,sy,0)), mp.at_end(mp.output_epsilon, mp.output_efield_y)), # mp.after_sources(mp.Harminv(mp.Ey, mp.Vector3(), fcen, df)), # until_after_sources=500) sim.run(mp.after_sources(mp.Harminv(mp.Ey, mp.Vector3(), fcen, df)), until_after_sources=500)
def get_mode_solver_rib( wg_width: float = 0.45, wg_thickness: float = 0.22, slab_thickness: float = 0.0, ncore: float = 3.47, nclad: float = 1.44, nslab: Optional[float] = None, sy: float = 2.0, sz: float = 2.0, resolution: int = 32, nmodes: int = 4, sidewall_angle: float = None, # sidewall_taper: int = 1, ) -> mpb.ModeSolver: """Returns a mode_solver simulation. Args: wg_width: wg_width (um) wg_thickness: wg height (um) slab_thickness: thickness for the waveguide slab ncore: core material refractive index nclad: clad material refractive index nslab: Optional slab material refractive index. Defaults to ncore. sy: simulation region width (um) sz: simulation region height (um) resolution: resolution (pixels/um) nmodes: number of modes sidewall_angle: waveguide sidewall angle (radians), tapers from wg_width at top of slab, upwards, to top of waveguide :: . = origin __________________________ | | | width | <----------> | ___________ _ _ _ | | | | sz|_____| |_______| | | wg_thickness |slab_thickness | |___________._____________| | | |__________________________ <------------------------> sy """ material_core = mp.Medium(index=ncore) material_clad = mp.Medium(index=nclad) material_slab = mp.Medium(index=nslab or ncore) # Define the computational cell. We'll make x the propagation direction. # the other cell sizes should be big enough so that the boundaries are # far away from the mode field. geometry_lattice = mp.Lattice(size=mp.Vector3(0, sy, sz)) geometry = [] # define the 2d blocks for the strip and substrate if sidewall_angle: geometry.append( mp.Prism( vertices=[ mp.Vector3(y=-wg_width / 2, z=slab_thickness), mp.Vector3(y=wg_width / 2, z=slab_thickness), mp.Vector3(x=1, y=wg_width / 2, z=slab_thickness), mp.Vector3(x=1, y=-wg_width / 2, z=slab_thickness), ], height=wg_thickness - slab_thickness, center=mp.Vector3(z=slab_thickness + (wg_thickness - slab_thickness) / 2, ), # If only 1 angle is specified, use it for all waveguides sidewall_angle=sidewall_angle, # axis=mp.Vector3(z=sidewall_taper), material=material_core, )) else: geometry.append( mp.Block( size=mp.Vector3(mp.inf, wg_width, wg_thickness), material=material_core, center=mp.Vector3(z=wg_thickness / 2), )) # uncomment this for not oxide cladded waveguides # geometry.append( # mp.Block( # size=mp.Vector3(mp.inf, mp.inf, 0.5 * (sz - wg_thickness)), # center=mp.Vector3(z=0.25 * (sz + wg_thickness)), # material=material_clad, # ), # ) geometry += [ mp.Block( size=mp.Vector3(mp.inf, mp.inf, slab_thickness), material=material_slab, center=mp.Vector3(z=slab_thickness / 2), ), ] # The k (i.e. beta, i.e. propagation constant) points to look at, in # units of 2*pi/um. We'll look at num_k points from k_min to k_max. num_k = 9 k_min = 0.1 k_max = 3.0 k_points = mp.interpolate(num_k, [mp.Vector3(k_min), mp.Vector3(k_max)]) # Increase this to see more modes. (The guided ones are the ones below the # light line, i.e. those with frequencies < kmag / 1.45, where kmag # is the corresponding column in the output if you grep for "freqs:".) # use this prefix for output files filename_prefix = tmp / f"rib_{wg_width}_{wg_thickness}_{slab_thickness}" mode_solver = mpb.ModeSolver( geometry_lattice=geometry_lattice, geometry=geometry, k_points=k_points, resolution=resolution, num_bands=nmodes, default_material=material_clad, filename_prefix=str(filename_prefix), ) mode_solver.nmodes = nmodes mode_solver.info = dict( wg_width=wg_width, wg_thickness=wg_thickness, slab_thickness=slab_thickness, ncore=ncore, nclad=nclad, sy=sy, sz=sz, resolution=resolution, nmodes=nmodes, ) return mode_solver
geometry_lattice = mp.Lattice(size=mp.Vector3(1, 1), basis1=mp.Vector3(math.sqrt(3) / 2, 0.5), basis2=mp.Vector3(math.sqrt(3) / 2, -0.5)) kz = 0 # use non-zero kz to consider vertical propagation k_points = [ mp.Vector3(z=kz), # Gamma mp.Vector3(0, 0.5, kz), # M mp.Vector3(1 / -3, 1 / 3, kz), # K mp.Vector3(z=kz) # Gamma ] k_interp = 4 k_points = mp.interpolate(k_interp, k_points) # Now, define the geometry, etcetera: eps = 12 # the dielectric constant of the background r = 0.45 # the hole radius default_material = mp.Medium(epsilon=eps) geometry = [mp.Cylinder(r, material=mp.air)] resolution = 32 num_bands = 8 ms = mpb.ModeSolver( geometry_lattice=geometry_lattice, geometry=geometry,
# Define a function of position p (in the lattice basis) that returns # the material at that position. In this case, we use the function: # index-min + 0.5 * (index-max - index-min) # * (1 + cos(2*pi*x)) # This is periodic, and also has inversion symmetry. def eps_func(p): return mp.Medium(index=index_min + 0.5 * (index_max - index_min) * (1 + math.cos(2 * math.pi * p.x))) geometry_lattice = mp.Lattice(size=mp.Vector3(1)) # 1d cell # We'll just make it the default material, so that it goes everywhere. default_material = eps_func k_points = mp.interpolate(9, [mp.Vector3(), mp.Vector3(x=0.5)]) resolution = 32 num_bands = 8 ms = mpb.ModeSolver(num_bands=num_bands, k_points=k_points, geometry_lattice=geometry_lattice, resolution=resolution, default_material=default_material) def main(): # the TM and TE bands are degenerate, so we only need TM: ms.run_tm()
print("{0} {1} {0}".format(stars, h)) # Our First Band Structure print_heading("Square lattice of rods in air") num_bands = 8 k_points = [ mp.Vector3(), # Gamma mp.Vector3(0.5), # X mp.Vector3(0.5, 0.5), # M mp.Vector3() ] # Gamma k_points = mp.interpolate(4, k_points) geometry = [mp.Cylinder(0.2, material=mp.Medium(epsilon=12))] geometry_lattice = mp.Lattice(size=mp.Vector3(1, 1)) resolution = 32 ms = mpb.ModeSolver(num_bands=num_bands, k_points=k_points, geometry=geometry, geometry_lattice=geometry_lattice, resolution=resolution) print_heading("Square lattice of rods: TE bands") ms.run_te() print_heading("Square lattice of rods: TM bands") ms.run_tm()
# Define a function of position p (in the lattice basis) that returns # the material at that position. In this case, we use the function: # index-min + 0.5 * (index-max - index-min) # * (1 + cos(2*pi*x)) # This is periodic, and also has inversion symmetry. def eps_func(p): return mp.Medium(index=index_min + 0.5 * (index_max - index_min) * (1 + math.cos(2 * math.pi * p.x))) geometry_lattice = mp.Lattice(size=mp.Vector3(1)) # 1d cell # We'll just make it the default material, so that it goes everywhere. default_material = eps_func k_points = mp.interpolate(9, [mp.Vector3(), mp.Vector3(x=0.5)]) resolution = 32 num_bands = 8 ms = mpb.ModeSolver( num_bands=num_bands, k_points=k_points, geometry_lattice=geometry_lattice, resolution=resolution, default_material=default_material ) def main(): # the TM and TE bands are degenerate, so we only need TM:
mp.LorentzianSusceptibility(frequency=1.1, gamma=1e-5, sigma=0.5), mp.LorentzianSusceptibility(frequency=0.5, gamma=0.1, sigma=2e-5) ] default_material = mp.Medium(epsilon=2.25, E_susceptibilities=susceptibilities) fcen = 1.0 df = 2.0 sources = [mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ez, center=mp.Vector3())] kmin = 0.3 kmax = 2.2 k_interp = 99 kpts = mp.interpolate(k_interp, [mp.Vector3(kmin), mp.Vector3(kmax)]) sim = mp.Simulation( cell_size=cell, geometry=[], sources=sources, default_material=default_material, resolution=resolution ) all_freqs = sim.run(kpts, k_points=200) # a list of lists of frequencies for fs, kx in zip(all_freqs, [v.x for v in kpts]): for f in fs: print("eps:, {.6f}, {.6f}, {.6f}".format(f.real, f.imag, (kx / f)**2))
k_point_K_cart = mp.Vector3(math.sqrt(2) / 2, 0) k_point_M_cart = mp.Vector3(math.sqrt(2) / 4, math.sqrt(2) / 4) dk_x = (math.sqrt(2) / 2) / (nbr_points_x + 1) dk_y = (math.sqrt(2) / 4) / (nbr_points_y + 1) seg = [] for j in range(0, nbr_points_y + 2): k_point_gamma_dk_cart = k_point_gamma + mp.Vector3(0, j * dk_y) k_point_K_dk_cart = k_point_K_cart + mp.Vector3(0, j * dk_y) k_point_gamma_dk_rec = mp.cartesian_to_reciprocal(k_point_gamma_dk_cart, geometry_lattice) k_point_K_dk_rec = mp.cartesian_to_reciprocal(k_point_K_dk_cart, geometry_lattice) seg_temp = mp.interpolate(nbr_points_x, [k_point_gamma_dk_rec, k_point_K_dk_rec]) seg = seg + seg_temp def outputgv(ms): global gv gv.append(ms.compute_group_velocities()) gv = [] ms = mpb.ModeSolver() ms.geometry = C_0 ms.geometry_lattice = geometry_lattice ms.resolution = resolution ms.num_bands = Nbands
def print_heading(h): stars = "*" * 10 print("{0} {1} {0}".format(stars, h)) # Our First Band Structure print_heading("Square lattice of rods in air") num_bands = 8 k_points = [mp.Vector3(), # Gamma mp.Vector3(0.5), # X mp.Vector3(0.5, 0.5), # M mp.Vector3()] # Gamma k_points = mp.interpolate(4, k_points) geometry = [mp.Cylinder(0.2, material=mp.Medium(epsilon=12))] geometry_lattice = mp.Lattice(size=mp.Vector3(1, 1)) resolution = 32 ms = mpb.ModeSolver(num_bands=num_bands, k_points=k_points, geometry=geometry, geometry_lattice=geometry_lattice, resolution=resolution) print_heading("Square lattice of rods: TE bands") ms.run_te() print_heading("Square lattice of rods: TM bands") ms.run_tm()
beam = mp.Prism([mp.Vector3(0,-w/2, h/2), mp.Vector3(0,w/2, h/2), mp.Vector3(0,0, -h/2)], a, axis=mp.Vector3(1,0,0), center=None, material=mp.Medium(epsilon=n**2)) #Diamond: n = 2.4063; n^2 = ep_r hole = mp.Ellipsoid(size=[hx, hy, mp.inf], material=mp.Medium(epsilon=1)) geometry = [beam, hole] #Symmetry points k_points = [ mp.Vector3(0,0,0), # Gamma mp.Vector3(0.5,0,0), # X (normalized to a?) ] #how many points to solve for between each specified point above k_points = mp.interpolate(kpt_resolution, k_points) #geometry_center #ModeSolver documentation: https://mpb.readthedocs.io/en/latest/Python_User_Interface/ ms = mpb.ModeSolver( geometry=geometry, geometry_lattice=geometry_lattice, k_points=k_points, resolution=resolution, num_bands=num_bands, ) #https://mpb.readthedocs.io/en/latest/Python_User_Interface/ ms.run_yeven(mpb.output_at_kpoint(mp.Vector3(0.5,0,0), mpb.fix_efield_phase, mpb.output_efield_z)) #This will output the electric field at the xpoint only tm_freqs = ms.all_freqs
####################### df1 = f0 - 1j*fcen*alpha df2 = fcen + 1j*gamma muperp = mu_r + sn * df1/(df1**2 - df2**2) xi = sn * df2 / (df1**2 - df2**2) tmax = 1/f0 kz=mp.Vector3(0,0, 0.5) kzm, n = mp.Vector3(0,0,0.02), 80 kpts=mp.interpolate(n, [kzm, kz]) #simulate for left-handed polarized light sim_left_circ_src=mp.Simulation(cell_size=cell, geometry=geometry, sources=[source], default_material=mat, resolution=20) allfreqs_left_circ=sim_left_circ_src.run_k_points(tmax, kpts) print(allfreqs_left_circ, kpts) print('len(allfreqs_left_circ)==len(kpts):', len(allfreqs_left_circ)==len(kpts)) freqs=[] f=[] data_store=[] for i in range(len(allfreqs_left_circ)): data_store+=[allfreqs_left_circ[i][0].real] f+=data_store
def get_mode_solver_coupler( wg_width: float = 0.5, gap: float = 0.2, wg_widths: Optional[Floats] = None, gaps: Optional[Floats] = None, wg_thickness: float = 0.22, slab_thickness: float = 0.0, ncore: float = 3.47, nclad: float = 1.44, nslab: Optional[float] = None, ymargin: float = 2.0, sz: float = 2.0, resolution: int = 32, nmodes: int = 4, sidewall_angles: Union[Tuple[float, ...], float] = None, # sidewall_taper: int = 1, ) -> mpb.ModeSolver: """Returns a mode_solver simulation. Args: wg_width: wg_width (um) gap: wg_widths: list or tuple of waveguide widths. gaps: list or tuple of waveguide gaps. wg_thickness: wg height (um) slab_thickness: thickness for the waveguide slab ncore: core material refractive index nclad: clad material refractive index nslab: Optional slab material refractive index. Defaults to ncore. ymargin: margin in y. sz: simulation region thickness (um) resolution: resolution (pixels/um) nmodes: number of modes sidewall_angles: waveguide sidewall angle (radians), tapers from wg_width at top of slab, upwards, to top of waveguide :: _____________________________________________________ | | | widths[0] widths[1] | <----------> gaps[0] <----------> | ___________ <-------------> ___________ _ | | | | | | sz|_____| |_______________| |_____| | | wg_thickness |slab_thickness | |___________________________________________________| | |<---> <---> |ymargin ymargin |____________________________________________________ <---------------------------------------------------> sy """ wg_widths = wg_widths or (wg_width, wg_width) gaps = gaps or (gap, ) material_core = mp.Medium(index=ncore) material_clad = mp.Medium(index=nclad) material_slab = mp.Medium(index=nslab or ncore) # Define the computational cell. We'll make x the propagation direction. # the other cell sizes should be big enough so that the boundaries are # far away from the mode field. sy = np.sum(wg_widths) + np.sum(gaps) + 2 * ymargin geometry_lattice = mp.Lattice(size=mp.Vector3(0, sy, sz)) geometry = [] y = -sy / 2 + ymargin gaps = list(gaps) + [0] for i, wg_width in enumerate(wg_widths): if sidewall_angles: geometry.append( mp.Prism( vertices=[ mp.Vector3(y=y, z=slab_thickness), mp.Vector3(y=y + wg_width, z=slab_thickness), mp.Vector3(x=1, y=y + wg_width, z=slab_thickness), mp.Vector3(x=1, y=y, z=slab_thickness), ], height=wg_thickness - slab_thickness, center=mp.Vector3( y=y + wg_width / 2, z=slab_thickness + (wg_thickness - slab_thickness) / 2, ), # If only 1 angle is specified, use it for all waveguides sidewall_angle=sidewall_angles if len( np.unique(sidewall_angles)) == 1 else sidewall_angles[i], # axis=mp.Vector3(z=sidewall_taper), material=material_core, )) else: geometry.append( mp.Block( size=mp.Vector3(mp.inf, wg_width, wg_thickness), material=material_core, center=mp.Vector3(y=y + wg_width / 2, z=wg_thickness / 2), )) y += gaps[i] + wg_width # define the 2D blocks for the strip and substrate geometry += [ mp.Block( size=mp.Vector3(mp.inf, mp.inf, slab_thickness), material=material_slab, center=mp.Vector3(z=slab_thickness / 2), ), ] # The k (i.e. beta, i.e. propagation constant) points to look at, in # units of 2*pi/um. We'll look at num_k points from k_min to k_max. num_k = 9 k_min = 0.1 k_max = 3.0 k_points = mp.interpolate(num_k, [mp.Vector3(k_min), mp.Vector3(k_max)]) # Increase this to see more modes. (The guided ones are the ones below the # light line, i.e. those with frequencies < kmag / 1.45, where kmag # is the corresponding column in the output if you grep for "freqs:".) # use this prefix for output files wg_widths_str = "_".join([str(i) for i in wg_widths]) gaps_str = "_".join([str(i) for i in gaps]) filename_prefix = ( tmp / f"coupler_{wg_widths_str}_{gaps_str}_{wg_thickness}_{slab_thickness}") mode_solver = mpb.ModeSolver( geometry_lattice=geometry_lattice, geometry=geometry, k_points=k_points, resolution=resolution, num_bands=nmodes, filename_prefix=str(filename_prefix), default_material=material_clad, ) mode_solver.nmodes = nmodes mode_solver.info = dict( wg_widths=wg_widths, gaps=gaps, wg_thickness=wg_thickness, slab_thickness=slab_thickness, ncore=ncore, nclad=nclad, sy=sy, sz=sz, resolution=resolution, nmodes=nmodes, ) return mode_solver
eps = 12 # the dielectric constant of the rods r = 0.2 # the rod radius in the bulk crystal geometry = [mp.Cylinder(r, material=mp.Medium(epsilon=eps))] # duplicate the bulk crystal rods over the supercell: geometry = mp.geometric_objects_lattice_duplicates(geometry_lattice, geometry) # add a rod of air, to erase a row of rods and form a waveguide: geometry += [mp.Cylinder(r, material=mp.air)] Gamma = mp.Vector3() K_prime = mp.lattice_to_reciprocal(mp.Vector3(0.5), geometry_lattice) # edge of Brillouin zone. k_points = mp.interpolate(4, [Gamma, K_prime]) # the bigger the supercell, the more bands you need to compute to get # to the defect modes (the lowest band is "folded" supercell_y times): extra_bands = 5 # number of extra bands to compute above the gap num_bands = supercell_y + extra_bands resolution = 32 ms = mpb.ModeSolver(geometry_lattice=geometry_lattice, geometry=geometry, k_points=k_points, num_bands=num_bands, resolution=resolution)
size=mp.Vector3(mp.inf, mp.inf, 0.5 * supercell_h)), mp.Block(material=mp.Medium(epsilon=eps), size=mp.Vector3(mp.inf, mp.inf, h)), mp.Cylinder(r, material=mp.air, height=supercell_h) ] # 1st Brillouin zone of a triangular lattice: Gamma = mp.Vector3() M = mp.Vector3(y=0.5) K = mp.Vector3(1 / -3, 1 / 3) only_K = False # run with only_K=true to only do this k_point k_interp = 4 # the number of k points to interpolate if only_K: k_points = [K] else: k_points = mp.interpolate(k_interp, [Gamma, M, K, Gamma]) resolution = mp.Vector3(32, 32, 16) num_bands = 9 ms = mpb.ModeSolver( geometry_lattice=geometry_lattice, geometry=geometry, resolution=resolution, num_bands=num_bands, k_points=k_points ) def main(): # Run even and odd bands, outputting fields only at the K point:
import meep as mp from meep import mpb import math num_bands = 8 k_points = [mp.Vector3(), mp.Vector3(0., 0.5), mp.Vector3(-1/3, 1/3), mp.Vector3()] k_points = mp.interpolate(10, k_points) geometry = [mp.Cylinder(0.25, material=mp.Medium(epsilon=12.96))] geometry_lattice = mp.Lattice(size=mp.Vector3(1, 1), basis1=mp.Vector3(math.sqrt(3)/2, 0.5), basis2=mp.Vector3(math.sqrt(3)/2, -0.5)) default_material = mp.Medium(epsilon=2.4) resolution = 32 ms = mpb.ModeSolver(num_bands=num_bands, k_points=k_points, geometry=geometry, geometry_lattice=geometry_lattice, resolution=resolution, default_material=default_material) ms.run_tm()
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)]))