def test_get_array_output(self): sim = self.init_simple_simulation() sim.symmetries = [] sim.geometry = [mp.Cylinder(0.2, material=mp.Medium(index=3))] sim.filename_prefix = 'test_get_array_output' sim.run(until=20) mp.output_epsilon(sim) mp.output_efield_z(sim) mp.output_tot_pwr(sim) mp.output_efield(sim) eps_arr = sim.get_epsilon() efield_z_arr = sim.get_efield_z() energy_arr = sim.get_tot_pwr() efield_arr = sim.get_efield() fname_fmt = "test_get_array_output-{}-000020.00.h5" with h5py.File(fname_fmt.format('eps'), 'r') as f: eps = f['eps'].value with h5py.File(fname_fmt.format('ez'), 'r') as f: efield_z = f['ez'].value with h5py.File(fname_fmt.format('energy'), 'r') as f: energy = f['energy'].value with h5py.File(fname_fmt.format('e'), 'r') as f: ex = f['ex'].value ey = f['ey'].value ez = f['ez'].value efield = np.stack([ex, ey, ez], axis=-1) np.testing.assert_allclose(eps, eps_arr) np.testing.assert_allclose(efield_z, efield_z_arr) np.testing.assert_allclose(energy, energy_arr) np.testing.assert_allclose(efield, efield_arr)
def test_load_dump_structure(self): resolution = 10 cell = mp.Vector3(10, 10) pml_layers = mp.PML(1.0) fcen = 1.0 df = 1.0 sources = mp.Source(src=mp.GaussianSource(fcen, fwidth=df), center=mp.Vector3(), component=mp.Hz) geometry = mp.Cylinder(0.2, material=mp.Medium(index=3)) sim = mp.Simulation(resolution=resolution, cell_size=cell, default_material=mp.Medium(index=1), geometry=[geometry], boundary_layers=[pml_layers], sources=[sources]) sim.run(until=200) ref_field = sim.get_field_point(mp.Hz, mp.Vector3(z=2)) dump_fn = 'test_load_dump_structure.h5' sim.dump_structure(dump_fn) sim = mp.Simulation(resolution=resolution, cell_size=cell, default_material=mp.Medium(index=1), geometry=[], boundary_layers=[pml_layers], sources=[sources], load_structure=dump_fn) sim.run(until=200) field = sim.get_field_point(mp.Hz, mp.Vector3(z=2)) self.assertAlmostEqual(ref_field, field) mp.all_wait() if mp.am_master(): os.remove(dump_fn)
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)
def test_set_materials(self): def change_geom(sim): t = sim.meep_time() fn = t * 0.02 geom = [mp.Cylinder(radius=3, material=mp.Medium(index=3.5), center=mp.Vector3(fn, fn)), mp.Ellipsoid(size=mp.Vector3(1, 2, mp.inf), center=mp.Vector3(fn, fn))] sim.set_materials(geometry=geom) c = mp.Cylinder(radius=3, material=mp.Medium(index=3.5)) e = mp.Ellipsoid(size=mp.Vector3(1, 2, mp.inf)) sources = mp.Source(src=mp.GaussianSource(1, fwidth=0.1), component=mp.Hz, center=mp.Vector3()) symmetries = [mp.Mirror(mp.X, -1), mp.Mirror(mp.Y, -1)] sim = mp.Simulation(cell_size=mp.Vector3(10, 10), geometry=[c, e], boundary_layers=[mp.PML(1.0)], sources=[sources], symmetries=symmetries, resolution=16) eps = {'arr1': None, 'arr2': None} def get_arr1(sim): eps['arr1'] = sim.get_array(mp.Volume(mp.Vector3(), mp.Vector3(10, 10)), component=mp.Dielectric) def get_arr2(sim): eps['arr2'] = sim.get_array(mp.Volume(mp.Vector3(), mp.Vector3(10, 10)), component=mp.Dielectric) sim.run(mp.at_time(50, get_arr1), mp.at_time(100, change_geom), mp.at_end(get_arr2), until=200) self.assertFalse(np.array_equal(eps['arr1'], eps['arr2']))
def test_geometric_objects_duplicates(self): rad = 1 s = mp.Sphere(rad) c = mp.Cylinder(rad) res = mp.geometric_objects_duplicates(mp.Vector3(1, 1, 1), 1, 5, [s, c]) expected = [ mp.Sphere(rad, center=mp.Vector3(5, 5, 5)), mp.Sphere(rad, center=mp.Vector3(4, 4, 4)), mp.Sphere(rad, center=mp.Vector3(3, 3, 3)), mp.Sphere(rad, center=mp.Vector3(2, 2, 2)), mp.Sphere(rad, center=mp.Vector3(1, 1, 1)), mp.Cylinder(rad, center=mp.Vector3(5, 5, 5)), mp.Cylinder(rad, center=mp.Vector3(4, 4, 4)), mp.Cylinder(rad, center=mp.Vector3(3, 3, 3)), mp.Cylinder(rad, center=mp.Vector3(2, 2, 2)), mp.Cylinder(rad, center=mp.Vector3(1, 1, 1)), ] for r, e in zip(res, expected): self.assertEqual(r.center, e.center)
def run_test(self, nfreqs): eps = 13 w = 1.2 r = 0.36 d = 1.4 N = 3 sy = 6 pad = 2 dpml = 1 sx = 2 * (pad + dpml + N) + d - 1 cell = mp.Vector3(sx, sy, 0) geometry = [mp.Block(center=mp.Vector3(), size=mp.Vector3(mp.inf, w, mp.inf), material=mp.Medium(epsilon=eps))] for i in range(N): geometry.append(mp.Cylinder(r, center=mp.Vector3(d / 2 + i))) geometry.append(mp.Cylinder(r, center=mp.Vector3(d / -2 - i))) pml_layers = mp.PML(dpml) resolution = 10 fcen = 0.25 df = 0.2 sources = mp.Source(src=mp.GaussianSource(fcen, fwidth=df), component=mp.Hz, center=mp.Vector3()) symmetries = [mp.Mirror(mp.Y, phase=-1), mp.Mirror(mp.X, phase=-1)] d1 = 0.2 sim = mp.Simulation(cell_size=cell, geometry=geometry, sources=[sources], symmetries=symmetries, boundary_layers=[pml_layers], resolution=resolution) nearfield = sim.add_near2far( fcen, 0.1, nfreqs, mp.Near2FarRegion(mp.Vector3(0, 0.5 * w + d1), size=mp.Vector3(2 * dpml - sx)), mp.Near2FarRegion(mp.Vector3(-0.5 * sx + dpml, 0.5 * w + 0.5 * d1), size=mp.Vector3(0, d1), weight=-1.0), mp.Near2FarRegion(mp.Vector3(0.5 * sx - dpml, 0.5 * w + 0.5 * d1), size=mp.Vector3(0, d1)) ) sim.run(until=200) d2 = 20 h = 4 vol = mp.Volume(mp.Vector3(0, (0.5 * w) + d2 + (0.5 * h)), size=mp.Vector3(sx - 2 * dpml, h)) result = sim.get_farfields(nearfield, resolution, where=vol) fname = 'cavity-farfield.h5' if nfreqs == 1 else 'cavity-farfield-4-freqs.h5' ref_file = os.path.join(self.data_dir, fname) with h5py.File(ref_file, 'r') as f: # Get reference data into memory ref_ex = mp.complexarray(f['ex.r'][()], f['ex.i'][()]) ref_ey = mp.complexarray(f['ey.r'][()], f['ey.i'][()]) ref_ez = mp.complexarray(f['ez.r'][()], f['ez.i'][()]) ref_hx = mp.complexarray(f['hx.r'][()], f['hx.i'][()]) ref_hy = mp.complexarray(f['hy.r'][()], f['hy.i'][()]) ref_hz = mp.complexarray(f['hz.r'][()], f['hz.i'][()]) np.testing.assert_allclose(ref_ex, result['Ex']) np.testing.assert_allclose(ref_ey, result['Ey']) np.testing.assert_allclose(ref_ez, result['Ez']) np.testing.assert_allclose(ref_hx, result['Hx']) np.testing.assert_allclose(ref_hy, result['Hy']) np.testing.assert_allclose(ref_hz, result['Hz'])
def main(args): # Some parameters to describe the geometry: eps = 13 # dielectric constant of waveguide w = 1.2 # width of waveguide r = 0.36 # radius of holes d = 1.4 # defect spacing (ordinary spacing = 1) N = args.N # number of holes on either side of defect # The cell dimensions sy = args.sy # size of cell in y direction (perpendicular to wvg.) pad = 2 # padding between last hole and PML edge dpml = 1 # PML thickness sx = 2 * (pad + dpml + N) + d - 1 # size of cell in x direction cell = mp.Vector3(sx, sy, 0) blk = mp.Block(size=mp.Vector3(mp.inf, w, mp.inf), material=mp.Medium(epsilon=eps)) geometry = [blk] for i in range(N): geometry.append(mp.Cylinder(r, center=mp.Vector3(d / 2 + i))) geometry.append(mp.Cylinder(r, center=mp.Vector3(-(d / 2 + i)))) fcen = args.fcen # pulse center frequency df = args.df # pulse frequency width nfreq = 500 # number of frequencies at which to compute flux sim = mp.Simulation(cell_size=cell, geometry=geometry, sources=[], boundary_layers=[mp.PML(dpml)], resolution=20) if args.resonant_modes: sim.sources.append( mp.Source(mp.GaussianSource(fcen, fwidth=df), mp.Hz, mp.Vector3())) sim.symmetries.append(mp.Mirror(mp.Y, phase=-1)) sim.symmetries.append(mp.Mirror(mp.X, phase=-1)) sim.run( # mp.at_beginning(mp.output_epsilon), mp.after_sources(mp.Harminv(mp.Hz, mp.Vector3(), fcen, df)), until_after_sources=400) # sim.run(mp.at_every(1 / fcen / 20, mp.output_hfield_z), until=1 / fcen) else: sim.sources.append( mp.Source(mp.GaussianSource(fcen, fwidth=df), mp.Ey, mp.Vector3(dpml + (-0.5 * sx)), size=mp.Vector3(0, w))) sim.symmetries.append(mp.Mirror(mp.Y, phase=-1)) freg = mp.FluxRegion(center=mp.Vector3((0.5 * sx) - dpml - 0.5), size=mp.Vector3(0, 2 * w)) # transmitted flux trans = sim.add_flux(fcen, df, nfreq, freg) vol = mp.Volume(mp.Vector3(), size=mp.Vector3(sx)) sim.run(mp.at_beginning(mp.output_epsilon), mp.during_sources( mp.in_volume( vol, mp.to_appended("hz-slice", mp.at_every(0.4, mp.output_hfield_z)))), until_after_sources=mp.stop_when_fields_decayed( 50, mp.Ey, mp.Vector3((0.5 * sx) - dpml - 0.5, 0), 1e-3)) sim.display_fluxes(trans) # print out the flux spectrum
pt = mp.Vector3(0.5 * cxs - pmlsize - 0.5) sim.run( until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, pt, 1e-3)) # for normalization run, save flux fields data for reflection plane straight_refl_data = sim.get_flux_data(refl) # save incident power for transmission plane straight_tran_flux = mp.get_fluxes(tran) print(straight_tran_flux) sim.reset_meep() geometry = [ mp.Cylinder(material=mp.Medium(index=6.9), radius=r, center=mp.Vector3(0, 0, 0)) ] sim = mp.Simulation(cell_size=cell, boundary_layers=pml_layers, geometry=geometry, sources=sources, resolution=resolution) refl = sim.add_flux(1 / cwl, 1 / ww, nfreq, refl_fr) tran_fr = mp.FluxRegion(center=mp.Vector3(0.5 * cxs - pmlsize - 0.5, 0, 0), size=mp.Vector3(0, 2 * r, 0)) tran = sim.add_flux(1 / cwl, 1 / ww, nfreq, tran_fr)
d = 1.4 # defect spacing (ordinary spacing = 1) N = 3 # number of holes on either side of defect # size of cell in y direction (perpendicular to wvg.) sy = 6 pad = 2 # padding between last hole and PML edge dpml = 1 # PML thickness sx = 2 * (pad + dpml + N) + d - 1 # size of cell in x direction cell = mp.Vector3(sx, sy, 0) geometry = [mp.Block(center=mp.Vector3(), size=mp.Vector3(mp.inf, w, mp.inf), material=mp.Medium(epsilon=eps))] for i in range(N): geometry.append(mp.Cylinder(r, center=mp.Vector3(d / 2 + i))) geometry.append(mp.Cylinder(r, center=mp.Vector3(d / -2 - i))) pml_layers = mp.PML(dpml) resolution = 20 fcen = 0.25 # pulse center frequency df = 0.2 # pulse width (in frequency) sources = mp.Source(src=mp.GaussianSource(fcen, fwidth=df), component=mp.Hz, center=mp.Vector3()) symmetries = [mp.Mirror(mp.Y, phase=-1), mp.Mirror(mp.X, phase=-1)] d1 = 0.2
n = 3.4 w = 1 r = 1 pad = 4 dpml = 2 sxy = 2*(r+w+pad+dpml) cell_size = mp.Vector3(sxy,sxy) pml_layers = [mp.PML(dpml)] nonpml_vol = mp.Volume(mp.Vector3(), size=mp.Vector3(sxy-2*dpml,sxy-2*dpml)) geometry = [mp.Cylinder(radius=r+w, material=mp.Medium(index=n)), mp.Cylinder(radius=r)] fcen = 0.118 src = [mp.Source(mp.ContinuousSource(fcen), component=mp.Ez, center=mp.Vector3(r+0.1)), mp.Source(mp.ContinuousSource(fcen), component=mp.Ez, center=mp.Vector3(-(r+0.1)), amplitude=-1)] symmetries = [mp.Mirror(mp.X,phase=-1), mp.Mirror(mp.Y,phase=+1)]
# 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()
import numpy as np import meep as mp import matplotlib.pyplot as plt eps = 13 w = 1.2 r = 0.36 # cell dimensions sy = 12 dpml = 1 # here the periodicity equals to 1 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, material=mp.Medium(index=1)) resolution = 50 pml_layers = mp.PML(dpml, direction=mp.Y) fcen = 0.8838 df = 0.1 # TODO: why a Hz-polarized odd-symmetry modes (recalling the pseudovector subtlety discussed above) ??? sym = mp.Mirror(direction=mp.Y, phase=-1) s = mp.Source(src=mp.GaussianSource(fcen, fwidth=df), size=mp.Vector3(1, 0, 0),
mp.Vector3(0.3, 0.0, 0.0), mp.Vector3(0.4, 0.0, 0.0), mp.Vector3(0.5, 0, 0), mp.Vector3(0.5, 0.1, 0.0), mp.Vector3(0.5, 0.2, 0.0), mp.Vector3(0.5, 0.3, 0.0), mp.Vector3(0.5, 0.4, 0.0), mp.Vector3(0.5, 0.5, 0), mp.Vector3(0.4, 0.4, 0.0), mp.Vector3(0.3, 0.3, 0.0), mp.Vector3(0.2, 0.2, 0.0), mp.Vector3(0.1, 0.1, 0.0), mp.Vector3(0, 0, 0) ] 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) #import sys #sys.exit(0) #print_heading("Square lattice of rods: TE bands")
sy = 6 # size of cell in y direction (perpendicular to wvg.) pad = 2 # padding between last hole and PML edge dpml = 1 # PML thickness sx = 2 * (pad + dpml + N) + d - 1 # size of cell in x direction cell = mp.Vector3(sx, sy, 0) pml_layers = mp.PML(dpml) geometry = [ mp.Block(center=mp.Vector3(), size=mp.Vector3(mp.inf, w, mp.inf), material=mp.Medium(epsilon=eps)) ] for i in range(N): geometry.append(mp.Cylinder(r, center=mp.Vector3(0.5 * d + i))) geometry.append(mp.Cylinder(r, center=mp.Vector3(-0.5 * d - i))) fcen = 0.25 # pulse center frequency df = 0.2 # pulse width (in frequency) sources = mp.Source(src=mp.GaussianSource(fcen, fwidth=df), component=mp.Hz, center=mp.Vector3()) symmetries = [mp.Mirror(mp.X, phase=-1), mp.Mirror(mp.Y, phase=-1)] sim = mp.Simulation(cell_size=cell, geometry=geometry, sources=[sources], symmetries=symmetries,
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, k_points=k_points, default_material=default_material, resolution=resolution, num_bands=num_bands ) def main():
X, Y = np.meshgrid(x, y) x = X.flatten() y = Y.flatten() theta = np.linspace(0, np.pi / 2, 9) phi = np.linspace(0, 2 * np.pi, 9) geometry = [] for i in range(9): axis = meep.Vector3( np.sin(theta[i]) * np.cos(phi[i]), np.sin(theta[i]) * np.sin(phi[i]), np.cos(theta[i])) geometry.append( meep.Cylinder(center=meep.Vector3(x[i], y[i], z[i]), radius=radius, height=height, material=material, axis=axis)) box = [2 * radius + 2 * np.max(x)] * 2 + [2 * radius + 2 * np.max(z)] resolution = 1 / (4 * nm) medium = meep.Medium(index=1) fcen, df = meep_ext.freq_data(1 / (400 * nm), 1 / (1000 * nm)) nfreq = 40 polarization = 'x' src_time = meep.GaussianSource(frequency=1.3 / um, fwidth=4.0 / um) if polarization == 'x': source = lambda sim: meep_ext.x_polarized_plane_wave(sim, src_time) decay = meep.Ex
incedent = sim.add_flux(fcen, df, nfreq, incedent_fr) upperside = sim.add_flux(fcen, df, nfreq, upperside_fr) pt = mp.Vector3(0.5 * sx - dpml - 0.01, 0) sim.run( until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, pt, 1e-9)) lightside_without_flux_data = sim.get_flux_data(lightside) upperside_without_flux_data = sim.get_flux_data(upperside) otherside_without_flux_data = sim.get_flux_data(otherside) indecentflux = np.append(indecentflux, mp.get_fluxes(incedent)) a = mp.get_fluxes(otherside) #a=a[(74+12):(249-75+12)] otherside_without_flux = np.append(otherside_without_flux, a) upperside_without_flux = np.append(upperside_without_flux, mp.get_fluxes(upperside)) sim.reset_meep() geometrys = [mp.Cylinder(material=Au, radius=r, center=mp.Vector3())] sim = mp.Simulation(cell_size=cell, geometry=geometrys, boundary_layers=pml_layers, sources=sources, resolution=resolution) lightside = sim.add_flux(fcen, df, nfreq, lightside_fr) upperside = sim.add_flux(fcen, df, nfreq, upperside_fr) otherside = sim.add_flux(fcen, df, nfreq, otherside_fr) #sim.load_minus_flux_data(otherside,otherside_without_flux_data) #sim.load_minus_flux_data(lightside,lightside_without_flux_data) #sim.load_minus_flux_data(upperside,upperside_without_flux_data) pt = mp.Vector3(0.5 * sx - dpml - 0.01, 0) sim.run( until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, pt, 1e-9))
def first_tm_gap(r): ms.geometry = [mp.Cylinder(r, material=mp.Medium(epsilon=12))] ms.run_tm() return -1 * ms.retrieve_gap(1)
eps_amor_5200 = 3.1978**2 eps_crys_5200 = 4.63**2 eps_si_1515 = 3.479**2 eps_amor_1515 = 3.334**2 eps_crys_1515 = 5.105**2 radius_percentage = 0.95 cell = mp.Vector3(sx, sy, 0) geometry = [] for iterx in range(2 * Nx): for itery in range(2 * Ny): geometry += [ mp.Cylinder(radius=r, center=mp.Vector3((-Nx + iterx + 7 / 2) * a0 + 1 / 3 * radius_percentage, (-Ny + itery + 1 / 2) * 3**0.5 * a0 + 0 * radius_percentage), material=mp.Medium(epsilon=eps_si_5200)), mp.Cylinder(radius=r, center=mp.Vector3((-Nx + iterx + 7 / 2) * a0 + 1 / 6 * radius_percentage, (-Ny + itery + 1 / 2) * 3**0.5 * a0 + 3**0.5 / 6 * radius_percentage), material=mp.Medium(epsilon=eps_si_5200)), mp.Cylinder(radius=r, center=mp.Vector3((-Nx + iterx + 7 / 2) * a0 - 1 / 6 * radius_percentage, (-Ny + itery + 1 / 2) * 3**0.5 * a0 + 3**0.5 / 6 * radius_percentage), material=mp.Medium(epsilon=eps_si_5200)), mp.Cylinder(radius=r,
def test_array_metadata(self): resolution = 25 n = 3.4 w = 1 r = 1 pad = 4 dpml = 2 sxy = 2*(r+w+pad+dpml) cell_size = mp.Vector3(sxy,sxy) nonpml_vol = mp.Volume(mp.Vector3(), size=mp.Vector3(sxy-2*dpml,sxy-2*dpml)) geometry = [mp.Cylinder(radius=r+w, material=mp.Medium(index=n)), mp.Cylinder(radius=r)] fcen = 0.118 df = 0.08 symmetries = [mp.Mirror(mp.X,phase=-1), mp.Mirror(mp.Y,phase=+1)] pml_layers = [mp.PML(dpml)] # CW source src = [mp.Source(mp.ContinuousSource(fcen,fwidth=df), mp.Ez, mp.Vector3(r+0.1)), mp.Source(mp.ContinuousSource(fcen,fwidth=df), mp.Ez, mp.Vector3(-(r+0.1)), amplitude=-1)] sim = mp.Simulation(cell_size=cell_size, geometry=geometry, sources=src, resolution=resolution, force_complex_fields=True, symmetries=symmetries, boundary_layers=pml_layers) sim.init_sim() sim.solve_cw(1e-6, 1000, 10) def electric_energy(r, ez, eps): return np.real(eps * np.conj(ez)*ez) def vec_func(r): return r.x**2 + 2*r.y**2 electric_energy_total = sim.integrate_field_function([mp.Ez,mp.Dielectric],electric_energy,nonpml_vol) electric_energy_max = sim.max_abs_field_function([mp.Ez,mp.Dielectric],electric_energy,nonpml_vol) vec_func_total = sim.integrate_field_function([],vec_func,nonpml_vol) cw_modal_volume = (electric_energy_total / electric_energy_max) * vec_func_total sim.reset_meep() # pulsed source src = [mp.Source(mp.GaussianSource(fcen,fwidth=df), mp.Ez, mp.Vector3(r+0.1)), mp.Source(mp.GaussianSource(fcen,fwidth=df), mp.Ez, mp.Vector3(-(r+0.1)), amplitude=-1)] sim = mp.Simulation(cell_size=cell_size, geometry=geometry, k_point=mp.Vector3(), sources=src, resolution=resolution, symmetries=symmetries, boundary_layers=pml_layers) dft_obj = sim.add_dft_fields([mp.Ez], fcen, 0, 1, where=nonpml_vol) sim.run(until_after_sources=100) Ez = sim.get_dft_array(dft_obj, mp.Ez, 0) (X,Y,Z,W) = sim.get_array_metadata(dft_cell=dft_obj) Eps = sim.get_array(vol=nonpml_vol,component=mp.Dielectric) EpsE2 = np.real(Eps*np.conj(Ez)*Ez) xm, ym = np.meshgrid(X,Y) vec_func_sum = np.sum(W*(xm**2 + 2*ym**2)) pulse_modal_volume = np.sum(W*EpsE2)/np.max(EpsE2) * vec_func_sum self.assertAlmostEqual(cw_modal_volume/pulse_modal_volume, 1.00, places=2)
# cadmium selineid QD geometry.append( mp.Block(mp.Vector3(1, cell.z, cell.z), center=mp.Vector3(-1), material=mp.Medium(index=2.52))) numberof = int(cell.y // (2 * fingersize)) + 1 for i in range(numberof): for j in range(numberof): geometry.append( mp.Cylinder(height=1, radius=fingersize / 2, axis=mp.Vector3(1, 0, 0), center=mp.Vector3(0, (cell.y / 2) + fingersize - (2 * fingersize) * (i + 1), (cell.z / 2) + fingersize - (2 * fingersize) * (j + 1)), material=ZnO)) sources = [ mp.Source(mp.ContinuousSource(wavelength=0.550, end_time=10), component=mp.Ez, center=mp.Vector3(-1, 0, 0)) ] sim = mp.Simulation(cell_size=cell, k_point=mp.Vector3(), boundary_layers=pml_layers, geometry=geometry,
def main(args): print("\nstart time:", datetime.now()) # -------------------------------------------------------------------------- # physical parameters characterizing light source and interface characteris- # tics (must be adjusted - eihter here or via command line interface (CLI)) # -------------------------------------------------------------------------- interface = args.interface s_pol = args.s_pol ref_medium = args.ref_medium n1 = args.n1 n2 = args.n2 kw_0 = args.kw_0 kr_w = args.kr_w kr_c = args.kr_c # angle of incidence chi_deg = args.chi_deg #chi_deg = 1.0*Critical(n1, n2) #chi_deg = 0.95*Brewster(n1, n2) test_output = args.test_output # -------------------------------------------------------------------------- # specific Meep parameters (may need to be adjusted) # -------------------------------------------------------------------------- sx = 5 # size of cell including PML in x-direction sy = 5 # size of cell including PML in y-direction pml_thickness = 0.25 # thickness of PML layer freq = 12 # vacuum frequency of source (5 to 12 is good) runtime = 10 # runs simulation for 10 times freq periods # number of pixels per wavelength in the denser medium (at least 10, # 20 to 30 is a good choice) pixel = 10 # source position with respect to the center (point of impact) in Meep # units (-2.15 good); if equal -r_w, then source position coincides with # waist position source_shift = -2.15 # -------------------------------------------------------------------------- # derived (Meep) parameters (do not change) # -------------------------------------------------------------------------- k_vac = 2 * math.pi * freq k1 = n1 * k_vac n_ref = (1 if ref_medium == 0 else n1 if ref_medium == 1 else n2 if ref_medium == 2 else math.nan) r_w = kr_w / (n_ref * k_vac) w_0 = kw_0 / (n_ref * k_vac) r_c = kr_c / (n_ref * k_vac) shift = source_shift + r_w chi_rad = math.radians(chi_deg) params = dict(W_y=w_0, k=k1) # -------------------------------------------------------------------------- # placement of the dielectric interface within the computational cell # -------------------------------------------------------------------------- # helper functions def alpha(chi_rad): """Angle of inclined plane with y-axis in radians.""" return math.pi/2 - chi_rad def Delta_x(alpha): """Inclined plane offset to the center of the cell.""" sin_alpha = math.sin(alpha) cos_alpha = math.cos(alpha) return (sx/2) * (((math.sqrt(2) - cos_alpha) - sin_alpha) / sin_alpha) cell = mp.Vector3(sx, sy, 0) # geometry-lattice if interface == "planar": default_material = mp.Medium(index=n1) # located at lower right edge for 45 degree geometry = [mp.Block(size=mp.Vector3(mp.inf, sx*math.sqrt(2), mp.inf), center=mp.Vector3(+sx/2 + Delta_x(alpha(chi_rad)), -sy/2), e1=mp.Vector3(1/math.tan(alpha(chi_rad)), 1, 0), e2=mp.Vector3(-1, 1/math.tan(alpha(chi_rad)), 0), e3=mp.Vector3(0, 0, 1), material=mp.Medium(index=n2))] elif interface == "concave": default_material = mp.Medium(index=n2) # move center to the right in order to ensure that the point of impact # is always centrally placed geometry = [mp.Cylinder(center=mp.Vector3(-r_c*math.cos(chi_rad), +r_c*math.sin(chi_rad)), height=mp.inf, radius=r_c, material=mp.Medium(index=n1))] elif interface == "convex": default_material = mp.Medium(index=n1) # move center to the right in order to ensure that the point of impact # is always centrally placed geometry = [mp.Cylinder(center=mp.Vector3(+r_c*math.cos(chi_rad), -r_c*math.sin(chi_rad)), height=mp.inf, radius=r_c, material=mp.Medium(index=n2))] # -------------------------------------------------------------------------- # add absorbing boundary conditions and discretize structure # -------------------------------------------------------------------------- pml_layers = [mp.PML(pml_thickness)] resolution = pixel * (n1 if n1 > n2 else n2) * freq # set Courant factor (mandatory if either n1 or n2 is smaller than 1) Courant = (n1 if n1 < n2 else n2) / 2 # -------------------------------------------------------------------------- # beam profile distribution (field amplitude) at the waist of the beam # -------------------------------------------------------------------------- def Gauss(r, params): """Gauss profile.""" W_y = params['W_y'] return math.exp(-(r.y / W_y)**2) # -------------------------------------------------------------------------- # spectrum amplitude distribution # -------------------------------------------------------------------------- def f_Gauss(k_y, params): """Gaussian spectrum amplitude.""" W_y = params['W_y'] return math.exp(-(k_y*W_y/2)**2) if test_output: print("Gauss spectrum:", f_Gauss(0.2, params)) # -------------------------------------------------------------------------- # plane wave decomposition # (purpose: calculate field amplitude at light source position if not # coinciding with beam waist) # -------------------------------------------------------------------------- def psi(r, x, params): """Field amplitude function.""" try: getattr(psi, "called") except AttributeError: psi.called = True print("Calculating inital field configuration. " "This will take some time...") def phase(k_y, x, y): """Phase function.""" return x*math.sqrt(k1**2 - k_y**2) + k_y*y try: (result, real_tol, imag_tol) = complex_quad(lambda k_y: f_Gauss(k_y, params) * cmath.exp(1j*phase(k_y, x, r.y)), -k1, k1) except Exception as e: print(type(e).__name__ + ":", e) sys.exit() return result # -------------------------------------------------------------------------- # some test outputs (uncomment if needed) # -------------------------------------------------------------------------- if test_output: x, y, z = -2.15, 0.3, 0.5 r = mp.Vector3(0, y, z) print() print("psi :", psi(r, x, params)) sys.exit() # -------------------------------------------------------------------------- # display values of physical variables # -------------------------------------------------------------------------- print() print("Specified variables and derived values:") print("n1:", n1) print("n2:", n2) print("chi: ", chi_deg, " [degree]") print("incl.:", 90 - chi_deg, " [degree]") print("kw_0: ", kw_0) if interface != "planar": print("kr_c: ", kr_c) print("kr_w: ", kr_w) print("k_vac:", k_vac) print("polarisation:", "s" if s_pol else "p") print("interface:", interface) print() # -------------------------------------------------------------------------- # specify current source, output functions and run simulation # -------------------------------------------------------------------------- force_complex_fields = False # default: False eps_averaging = True # default: True filename_prefix = None sources = [mp.Source(src=mp.ContinuousSource(frequency=freq, width=0.5), component=mp.Ez if s_pol else mp.Ey, size=mp.Vector3(0, 2, 0), center=mp.Vector3(source_shift, 0, 0), #amp_func=lambda r: Gauss(r, params) amp_func=lambda r: psi(r, shift, params) ) ] sim = mp.Simulation(cell_size=cell, boundary_layers=pml_layers, default_material=default_material, Courant=Courant, geometry=geometry, sources=sources, resolution=resolution, force_complex_fields=force_complex_fields, eps_averaging=eps_averaging, filename_prefix=filename_prefix ) sim.use_output_directory(interface) # put output files in a separate folder def eSquared(r, ex, ey, ez): """Calculate |E|^2. With |.| denoting the complex modulus if 'force_complex_fields?' is set to true, otherwise |.| gives the Euclidean norm. """ return mp.Vector3(ex, ey, ez).norm()**2 def output_efield2(sim): """Output E-field intensity.""" name = "e2_s" if s_pol else "e2_p" func = eSquared cs = [mp.Ex, mp.Ey, mp.Ez] return sim.output_field_function(name, cs, func, real_only=True) sim.run(mp.at_beginning(mp.output_epsilon), mp.at_end(mp.output_efield_z if s_pol else mp.output_efield_y), mp.at_end(output_efield2), until=runtime) print("\nend time:", datetime.now())
def main(args): sx = 3.0 #spatial extent along x including pmls (μm) sy = 3.0 sz = 3.0 dpml = 1.0 cell = mp.Vector3(sx, sy, sy) pml_layers = [mp.PML(dpml)] geometry = [ mp.Cylinder(center=mp.Vector3(0, 0, 0), height=mp.inf, radius=0.505, axis=mp.Vector3(0, 0, 1), material=Graph), mp.Cylinder(center=mp.Vector3(0, 0, 0), height=mp.inf, radius=0.5, axis=mp.Vector3(0, 0, 1), material=mp.Medium(epsilon=3.9)) ] resolution = args.res wvlmax = 40 fmin = 1 / 40 wvlmin = 20 fmax = 1 / 20 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, df, nfreq), component=mp.Ey, center=mp.Vector3(0, 0.510, 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.510, 0) sim.run(mp.dft_ldos(fcen, df, nfreq), until_after_sources=mp.stop_when_fields_decayed( 20, mp.Ey, pt, 1e-3)) eps_data = sim.get_array(center=mp.Vector3(), size=cell, component=mp.Dielectric) #plot eps_data plt.figure(dpi=160) plt.imshow(eps.data.transpose(), interpolation='spline36', cmap='binary') plt.axis('off') plt.show
N = coupler_width//(circle_diameter+spacing_circles) M = (coupler_length-spacing_circles)//(circle_diameter+spacing_circles) geometry_circles = [] #matrices = np.zeros((int(N),int(M))) matrices = np.ones((int(N),int(M))) i=0 k=0 while (i<M): while (k<N): geometry_circles = geometry_circles + [mp.Cylinder(radius=circle_diameter/2, center=mp.Vector3(-0.5*coupler_length+(i+1)*spacing_circles+circle_diameter*0.5+i*circle_diameter, 0.5*((N-1)*circle_diameter+(N-1)*spacing_circles)-k*(circle_diameter+spacing_circles),0), material=Si3N4_neff_TM if matrices[k][i]==1 else SiO2)] k = k+1 i = i+1 k=0 geometry = [mp.Block(size=mp.Vector3(mp.inf,waveguide_width,mp.inf), center=mp.Vector3(), material=Si3N4_neff_TM)] # aqui define la fuente gaussiana, pensando en capturar el espectro fcen = 1/0.632 # pulse center freq (es 1.58 para wavelength de 632nm ) df = 0.1*fcen # pulse width freq rot_angle = np.radians(0)
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 = 2 # thickness of PML sxy = 2 * (r + w + pad + dpml) # cell size cell = mp.Vector3(sxy, sxy) # Create a ring waveguide by two overlapping cylinders - later objects # take precedence over earlier objects, so we put the outer cylinder first. # and the inner (air) cylinder second. geometry = [ mp.Cylinder(radius=r + w, height=mp.inf, material=mp.Medium(index=n)), mp.Cylinder(radius=r, height=mp.inf, material=mp.air) ] 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 TM modes (E out of the plane). fcen = 0.118 # pulse center frequency df = 0.010 # pulse width (in frequency) sources = [ mp.Source(src=mp.GaussianSource(fcen, fwidth=df), component=mp.Ez,
import meep as mp cell_size = mp.Vector3(6, 6, 0) geometry1 = [ mp.Cylinder(center=mp.Vector3(), radius=1.0, material=mp.Medium(index=3.5)) ] sim1 = mp.Simulation(cell_size=cell_size, geometry=geometry1, resolution=20) sim1.init_sim() geometry2 = [ mp.Cylinder(center=mp.Vector3(1, 1), radius=1.0, material=mp.Medium(index=3.5)) ] sim2 = mp.Simulation(cell_size=cell_size, geometry=geometry2, resolution=20) sim2.init_sim() sim1.fields.phase_in_material(sim2.structure, 10.0) sim1.run(mp.at_beginning(mp.output_epsilon), mp.at_every(0.5, mp.output_epsilon), until=10)
import meep as mp import numpy as np from numpy import linalg as LA import matplotlib.pyplot as plt n = 3.4 w = 1 r = 1 pad = 4 dpml = 2 sxy = 2 * (r + w + pad + dpml) vol = mp.Volume(mp.Vector3(), size=mp.Vector3(sxy - 2 * dpml, sxy - 2 * dpml)) c1 = mp.Cylinder(radius=r + w, material=mp.Medium(index=n)) c2 = mp.Cylinder(radius=r) fcen = 0.118 df = 0.08 src = [ mp.Source(mp.ContinuousSource(fcen, fwidth=df), component=mp.Ez, center=mp.Vector3(r + 0.1)) ] sim = mp.Simulation(cell_size=mp.Vector3(sxy, sxy), geometry=[c1, c2], sources=src, resolution=10, force_complex_fields=True, symmetries=[mp.Mirror(mp.Y)],
resolution = 64 ## Definition discretisation traits horizontaux nbr_points_x = 4 nbr_points_y = 4 ## Repere direct carree 45 geometry_lattice = mp.Lattice() geometry_lattice.basis_size = mp.Vector3(1, 1, 1) geometry_lattice.size = mp.Vector3(1, 1, 0) geometry_lattice.basis1 = mp.Vector3(math.sqrt(2) / 2, -math.sqrt(2) / 2) geometry_lattice.basis2 = mp.Vector3(math.sqrt(2) / 2, +math.sqrt(2) / 2) ## Definition motif default_material = mp.Medium(index=n_hi) C_0 = [mp.Cylinder(ra, material=mp.Medium(index=n_lo))] ## Limites IBZ REPERE RECIPROQUE k_point_gamma = mp.Vector3(0, 0) k_point_M_rec = mp.Vector3(1 / 2, 1 / 2) k_point_K_rec = mp.Vector3(1 / 2, 0) 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)
# rods (c.f. tri_rods.ctl), formed by a row of missing rods along the # "x" direction. (Here, "x" and "y" refer to the first and second # basis directions.) This structure supports a single guided band # 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
def build_geom(sx, sy, dsub, gp, gh, lw, tr, br, sa, material): tw = gh / np.tan( sa * 2 * np.pi / 360) # part to subtract from top of grating width a = (gh - tr) / np.tan( sa * 2 * np.pi / 360) # intermediate for vertex calculation #vertices for trapezoids approximating grating cross-section vtx = [ mp.Vector3(-0.5 * lw - 0.5 * a + gp / 2, -1 * (-0.5 * gh), 0), mp.Vector3(0.5 * lw + 0.5 * a + gp / 2, -1 * (-0.5 * gh), 0), mp.Vector3(0.5 * lw - 0.5 * a + gp / 2, -1 * (0.5 * gh - tr), 0), mp.Vector3(-0.5 * lw + 0.5 * a + gp / 2, -1 * (0.5 * gh - tr), 0) ] vtx2 = [ mp.Vector3(-0.5 * lw - 0.5 * a - gp / 2, -1 * (-0.5 * gh), 0), mp.Vector3(0.5 * lw + 0.5 * a - gp / 2, -1 * (-0.5 * gh), 0), mp.Vector3(0.5 * lw - 0.5 * a - gp / 2, -1 * (0.5 * gh - tr), 0), mp.Vector3(-0.5 * lw + 0.5 * a - gp / 2, -1 * (0.5 * gh - tr), 0) ] #rounded corners for top of trapezoids c1 = mp.Cylinder(radius=tr, height=mp.inf, axis=mp.Vector3(0, 0, 1), center=mp.Vector3(-gp / 2 - lw / 2 + tw / 2 + tr, -1 * (-sy / 2 + dsub + gh - tr), 0), material=material) c2 = mp.Cylinder(radius=tr, height=mp.inf, axis=mp.Vector3(0, 0, 1), center=mp.Vector3(-gp / 2 + lw / 2 - tw / 2 - tr, -1 * (-sy / 2 + dsub + gh - tr), 0), material=material) c3 = mp.Cylinder(radius=tr, height=mp.inf, axis=mp.Vector3(0, 0, 1), center=mp.Vector3(gp / 2 - lw / 2 + tw / 2 + tr, -1 * (-sy / 2 + dsub + gh - tr), 0), material=material) c4 = mp.Cylinder(radius=tr, height=mp.inf, axis=mp.Vector3(0, 0, 1), center=mp.Vector3(gp / 2 + lw / 2 - tw / 2 - tr, -1 * (-sy / 2 + dsub + gh - tr), 0), material=material) #blocks for top of trapezoids inbetween rounded corners b1 = mp.Block(center=mp.Vector3(-gp / 2, -1 * (-sy / 2 + dsub + gh - tr / 2)), size=mp.Vector3(lw - tw - 2 * tr, tr, mp.inf), material=material) b2 = mp.Block(center=mp.Vector3(gp / 2, -1 * (-sy / 2 + dsub + gh - tr / 2)), size=mp.Vector3(lw - tw - 2 * tr, tr, mp.inf), material=material) #ellipsoid cutout to make bottom of grating round e1 = mp.Ellipsoid(center=mp.Vector3(0, -1 * (-sy / 2 + dsub), 0), size=mp.Vector3(gp - lw - a, br, mp.inf), material=mp.Medium(epsilon=1)) e2 = mp.Ellipsoid(center=mp.Vector3(-gp, -1 * (-sy / 2 + dsub), 0), size=mp.Vector3(gp - lw - a, br, mp.inf), material=mp.Medium(epsilon=1)) e3 = mp.Ellipsoid(center=mp.Vector3(gp, -1 * (-sy / 2 + dsub), 0), size=mp.Vector3(gp - lw - a, br, mp.inf), material=mp.Medium(epsilon=1)) geometry = [ mp.Block(material=material, size=mp.Vector3(sx, dsub, mp.inf), center=mp.Vector3(0, -1 * (-0.5 * sy + 0.5 * dsub), 0)), mp.Prism(vtx, height=mp.inf, center=mp.Vector3(0, -1 * (-0.5 * sy + dsub + 0.5 * gh), 0), material=material), mp.Prism(vtx2, height=mp.inf, center=mp.Vector3(0, -1 * (-0.5 * sy + dsub + 0.5 * gh), 0), material=material), c1, c2, c3, c4, b1, b2, e1, e2, e3 ] return geometry