def test_geometric_objects_lattice_duplicates(self): geometry_lattice = mp.Lattice(size=mp.Vector3(1, 7), basis1=mp.Vector3(math.sqrt(3) / 2, 0.5), basis2=mp.Vector3(math.sqrt(3) / 2, -0.5)) eps = 12 r = 0.2 geometry = [mp.Cylinder(r, material=mp.Medium(epsilon=eps))] geometry = mp.geometric_objects_lattice_duplicates(geometry_lattice, geometry) med = mp.Medium(epsilon=12) expected = [ mp.Cylinder(0.2, material=med, center=mp.Vector3(y=3.0)), mp.Cylinder(0.2, material=med, center=mp.Vector3(y=2.0)), mp.Cylinder(0.2, material=med, center=mp.Vector3(y=1.0)), mp.Cylinder(0.2, material=med, center=mp.Vector3(y=0.0)), mp.Cylinder(0.2, material=med, center=mp.Vector3(y=-1.0)), mp.Cylinder(0.2, material=med, center=mp.Vector3(y=-2.0)), mp.Cylinder(0.2, material=med, center=mp.Vector3(y=-3.0)), ] for exp, res in zip(expected, geometry): self.assertEqual(exp.center, res.center) self.assertEqual(exp.radius, res.radius)
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 test_geometric_objects_lattice_duplicates(self): geometry_lattice = mp.Lattice(size=mp.Vector3(1, 7), basis1=mp.Vector3(math.sqrt(3) / 2, 0.5), basis2=mp.Vector3( math.sqrt(3) / 2, -0.5)) eps = 12 r = 0.2 geometry = [mp.Cylinder(r, material=mp.Medium(epsilon=eps))] geometry = mp.geometric_objects_lattice_duplicates( geometry_lattice, geometry) med = mp.Medium(epsilon=12) expected = [ mp.Cylinder(0.2, material=med, center=mp.Vector3(y=3.0)), mp.Cylinder(0.2, material=med, center=mp.Vector3(y=2.0)), mp.Cylinder(0.2, material=med, center=mp.Vector3(y=1.0)), mp.Cylinder(0.2, material=med, center=mp.Vector3(y=0.0)), mp.Cylinder(0.2, material=med, center=mp.Vector3(y=-1.0)), mp.Cylinder(0.2, material=med, center=mp.Vector3(y=-2.0)), mp.Cylinder(0.2, material=med, center=mp.Vector3(y=-3.0)), ] for exp, res in zip(expected, geometry): self.assertEqual(exp.center, res.center) self.assertEqual(exp.radius, res.radius)
def test_point_defect_state(self): ms = self.init_solver() ms.geometry_lattice = mp.Lattice(size=mp.Vector3(5, 5)) ms.geometry = [mp.Cylinder(0.2, material=mp.Medium(epsilon=12))] ms.geometry = mp.geometric_objects_lattice_duplicates( ms.geometry_lattice, ms.geometry) ms.geometry.append(mp.Cylinder(0.2, material=mp.air)) ms.resolution = 16 ms.k_points = [mp.Vector3(0.5, 0.5)] ms.num_bands = 50 ms.run_tm() mpb.fix_efield_phase(ms, 25) mpb.output_efield_z(ms, 25) mpb.fix_dfield_phase(ms, 25) ms.get_dfield(25) ms.compute_field_energy() c = mp.Cylinder(1.0, material=mp.air) e = ms.compute_energy_in_objects([c]) self.assertAlmostEqual(0.6227482574427817, e, places=3) ms.num_bands = 1 ms.target_freq = (0.2812 + 0.4174) / 2 ms.tolerance = 1e-8 ms.run_tm() expected_brd = [ ((0.37730041222979477, mp.Vector3(0.5, 0.5, 0.0)), (0.37730041222979477, mp.Vector3(0.5, 0.5, 0.0))), ] self.check_band_range_data(expected_brd, ms.band_range_data) old_geometry = ms.geometry # save the 5x5 grid with a missing rod def rootfun(eps): ms.geometry = old_geometry + [ mp.Cylinder(0.2, material=mp.Medium(epsilon=eps)) ] ms.run_tm() return ms.get_freqs()[0] - 0.314159 rooteps = ridder(rootfun, 1, 12) rootval = rootfun(rooteps) self.assertAlmostEqual(5.288830111797463, rooteps, places=3) self.assertAlmostEqual(9.300716530269426e-9, rootval, places=3)
# within the band gap, much like the analogous waveguide in a square # lattice of rods (see "Photonic Crystals" by Joannopoulos et al.). supercell_y = 7 # the (odd) number of lateral supercell periods geometry_lattice = mp.Lattice(size=mp.Vector3(1, supercell_y), basis1=mp.Vector3(math.sqrt(3) / 2, 0.5), 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
print_heading('Anisotropic complete 2d gap') ms.geometry = [mp.Cylinder(0.3, material=mp.Medium(epsilon_diag=mp.Vector3(1, 1, 12)))] ms.default_material = mp.Medium(epsilon_diag=mp.Vector3(12, 12, 1)) ms.num_bands = 8 ms.run() # just use run, instead of run_te or run_tm, to find the complete gap # Finding a Point-defect State print_heading('5x5 point defect') ms.geometry_lattice = mp.Lattice(size=mp.Vector3(5, 5)) ms.geometry = [mp.Cylinder(0.2, material=mp.Medium(epsilon=12))] ms.geometry = mp.geometric_objects_lattice_duplicates(ms.geometry_lattice, ms.geometry) ms.geometry.append(mp.Cylinder(0.2, material=mp.air)) ms.resolution = 16 ms.k_points = [mp.Vector3(0.5, 0.5)] ms.num_bands = 50 ms.run_tm() mpb.output_efield_z(ms, 25) ms.get_dfield(25) # compute the D field for band 25 ms.compute_field_energy() # compute the energy density from D c = mp.Cylinder(1.0, material=mp.air) print("energy in cylinder: {}".format(ms.compute_energy_in_objects([c])))
freqss = [] gapss = [] for index in integer_list: # Loop over kz_list theta_list = [] theta2_list = [] geometry = [] geometry_lattice = mp.Lattice(size=mp.Vector3(1, 1)) ms = mpb.ModeSolver(num_bands=num_bands, k_points=k_vectors[index], geometry=geometry, geometry_lattice=geometry_lattice, resolution=resolution) # Create ModeSolver object ms.default_material = mp.Medium(epsilon = pc_epsilon) # Define background material to be that of the photonic crystal if question == 'y': ms.target_freq = omega_prime ms.geometry_lattice = mp.Lattice(size=mp.Vector3(L, L)) # Creates an L x L lattice ms.geometry = [mp.Block(material=mp.air, size=mp.Vector3(r,r,mp.inf))] # One hole at each lattice point ms.geometry = mp.geometric_objects_lattice_duplicates(ms.geometry_lattice, ms.geometry) # Duplicate geometry all over the lattice if block == 'y': ms.geometry.append(mp.Block(material=mp.Medium(epsilon=core_epsilon), size=mp.Vector3(l_core, l_core, mp.inf))) # Inserts core into the center of the photonic crystal ms.run() freqs = ms.all_freqs freqss.append(freqs) gaps = ms.gap_list # List of band gaps and their boundaries gapss.append(gaps) real_gaps = [] # List of gap-midgap ratios, expressed as percentages gap_bounds = [] gap_bounds_freqs = [] midgaps = [] midgap_freqs = []