def empty_run(self, sx, sy, animate=False): sources, refl_fr, trans_fr = self.set_source(sx, sy) sim = mp.Simulation(cell_size=mp.Vector3(sx, sy, self.sz), geometry=[], sources=sources, boundary_layers=self.pml_layers, k_point=self.k, resolution=self.resolution) refl = sim.add_flux(self.fcen, self.df, self.nfreq, refl_fr) trans = sim.add_flux(self.fcen, self.df, self.nfreq, trans_fr) if animate: sim.run(mp.at_beginning(mp.output_epsilon), mp.to_appended("ex", mp.at_every(0.6, mp.output_efield_z)), until_after_sources=mp.stop_when_fields_decayed(25, mp.Ey, self.pt, 1e-3)) else: sim.run(until_after_sources=mp.stop_when_fields_decayed(25, mp.Ey, self.pt, 1e-3)) # for normalization run, save flux fields data for reflection plane self.store['straight_refl_data'] = sim.get_flux_data(refl) # save incident power for transmission plane self.store['flux_freqs'] = mp.get_flux_freqs(refl) self.store['straight_tran_flux'] = mp.get_fluxes(trans) self.store['straight_refl_flux'] = mp.get_fluxes(refl)
def refl_planar(self, theta, special_kz): resolution = 100 # pixels/um dpml = 1.0 sx = 3+2*dpml sy = 1/resolution cell_size = mp.Vector3(sx,sy) pml_layers = [mp.PML(dpml,direction=mp.X)] fcen = 1.0 # source wavelength = 1 um k_point = mp.Vector3(z=math.sin(theta)).scale(fcen) sources = [mp.Source(mp.GaussianSource(fcen,fwidth=0.2*fcen), component=mp.Ez, center=mp.Vector3(-0.5*sx+dpml), size=mp.Vector3(y=sy))] sim = mp.Simulation(cell_size=cell_size, boundary_layers=pml_layers, sources=sources, k_point=k_point, special_kz=special_kz, resolution=resolution) refl_fr = mp.FluxRegion(center=mp.Vector3(-0.25*sx), size=mp.Vector3(y=sy)) refl = sim.add_flux(fcen,0,1,refl_fr) sim.run(until_after_sources=mp.stop_when_fields_decayed(50,mp.Ez,mp.Vector3(),1e-9)) empty_flux = mp.get_fluxes(refl) empty_data = sim.get_flux_data(refl) sim.reset_meep() geometry = [mp.Block(material=mp.Medium(index=3.5), size=mp.Vector3(0.5*sx,mp.inf,mp.inf), center=mp.Vector3(0.25*sx))] sim = mp.Simulation(cell_size=cell_size, boundary_layers=pml_layers, geometry=geometry, sources=sources, k_point=k_point, special_kz=special_kz, resolution=resolution) refl = sim.add_flux(fcen,0,1,refl_fr) sim.load_minus_flux_data(refl,empty_data) sim.run(until_after_sources=mp.stop_when_fields_decayed(50,mp.Ez,mp.Vector3(),1e-9)) refl_flux = mp.get_fluxes(refl) Rmeep = -refl_flux[0]/empty_flux[0] return Rmeep
def test_chunks(self): sxy = 10 cell = mp.Vector3(sxy, sxy, 0) fcen = 1.0 # pulse center frequency df = 0.1 # pulse width (in frequency) sources = [mp.Source(mp.GaussianSource(fcen, fwidth=df), mp.Ez, mp.Vector3())] dpml = 1.0 pml_layers = [mp.PML(dpml)] resolution = 10 sim = mp.Simulation(cell_size=cell, boundary_layers=pml_layers, sources=sources, resolution=resolution, split_chunks_evenly=False) sim.use_output_directory(temp_dir) top = mp.FluxRegion(center=mp.Vector3(0,+0.5*sxy-dpml), size=mp.Vector3(sxy-2*dpml,0), weight=+1.0) bot = mp.FluxRegion(center=mp.Vector3(0,-0.5*sxy+dpml), size=mp.Vector3(sxy-2*dpml,0), weight=-1.0) rgt = mp.FluxRegion(center=mp.Vector3(+0.5*sxy-dpml,0), size=mp.Vector3(0,sxy-2*dpml), weight=+1.0) lft = mp.FluxRegion(center=mp.Vector3(-0.5*sxy+dpml,0), size=mp.Vector3(0,sxy-2*dpml), weight=-1.0) tot_flux = sim.add_flux(fcen, 0, 1, top, bot, rgt, lft) sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, mp.Vector3(), 1e-5)) sim.save_flux('tot_flux', tot_flux) sim1 = sim geometry = [mp.Block(center=mp.Vector3(), size=mp.Vector3(sxy, sxy, mp.inf), material=mp.Medium(index=3.5)), mp.Block(center=mp.Vector3(), size=mp.Vector3(sxy-2*dpml, sxy-2*dpml, mp.inf), material=mp.air)] sim = mp.Simulation(cell_size=cell, geometry=geometry, boundary_layers=pml_layers, sources=sources, resolution=resolution, chunk_layout=sim1) sim.use_output_directory(temp_dir) tot_flux = sim.add_flux(fcen, 0, 1, top, bot, rgt, lft) sim.load_minus_flux('tot_flux', tot_flux) sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, mp.Vector3(), 1e-5)) self.assertAlmostEqual(86.90826609300862, mp.get_fluxes(tot_flux)[0])
def runSimulation(thetaDegrees): thetaRadians = np.radians(thetaDegrees) kVector = mp.Vector3(np.sin(thetaRadians), 0, np.cos(thetaRadians)).scale(minimumFrequency) simulation = mp.Simulation(cell_size=cellSize, sources=sources, resolution=resolution, boundary_layers=pmlLayers, k_point=kVector) incidentFluxMonitor = simulation.add_flux(frequency, frequencyWidth, numberFrequencies, incidentRegion) simulation.run(until_after_sources=mp.stop_when_fields_decayed( 20, mp.Ex, transmissionMonitorLocation, powerDecayTarget)) incidentFluxToSubtract = simulation.get_flux_data(incidentFluxMonitor) simulation = mp.Simulation(cell_size=cellSize, sources=sources, resolution=resolution, boundary_layers=pmlLayers, geometry=geometry, k_point=kVector) transmissionRegion = mp.FluxRegion(center=transmissionMonitorLocation) transmissionFluxMonitor = simulation.add_flux(frequency, frequencyWidth, numberFrequencies, transmissionRegion) reflectionRegion = incidentRegion reflectionFluxMonitor = simulation.add_flux(frequency, frequencyWidth, numberFrequencies, reflectionRegion) simulation.load_minus_flux_data(reflectionFluxMonitor, incidentFluxToSubtract) simulation.run(until_after_sources=mp.stop_when_fields_decayed( 20, mp.Ex, transmissionMonitorLocation, powerDecayTarget)) incidentFlux = np.array(mp.get_fluxes(incidentFluxMonitor)) transmittedFlux = np.array(mp.get_fluxes(transmissionFluxMonitor)) reflectedFlux = np.array(mp.get_fluxes(reflectionFluxMonitor)) R = np.array(-reflectedFlux / incidentFlux) T = np.array(transmittedFlux / incidentFlux) frequencies = np.array(mp.get_flux_freqs(reflectionFluxMonitor)) kx = kVector.x angles = np.arcsin(kx / frequencies) return angles, frequencies, R, T
def test_chunks(self): sxy = 10 cell = mp.Vector3(sxy, sxy, 0) fcen = 1.0 # pulse center frequency df = 0.1 # pulse width (in frequency) sources = [mp.Source(mp.GaussianSource(fcen, fwidth=df), mp.Ez, mp.Vector3())] dpml = 1.0 pml_layers = [mp.PML(dpml)] resolution = 10 sim = mp.Simulation(cell_size=cell, boundary_layers=pml_layers, sources=sources, resolution=resolution, split_chunks_evenly=False) top = mp.FluxRegion(center=mp.Vector3(0,+0.5*sxy-dpml), size=mp.Vector3(sxy-2*dpml,0), weight=+1.0) bot = mp.FluxRegion(center=mp.Vector3(0,-0.5*sxy+dpml), size=mp.Vector3(sxy-2*dpml,0), weight=-1.0) rgt = mp.FluxRegion(center=mp.Vector3(+0.5*sxy-dpml,0), size=mp.Vector3(0,sxy-2*dpml), weight=+1.0) lft = mp.FluxRegion(center=mp.Vector3(-0.5*sxy+dpml,0), size=mp.Vector3(0,sxy-2*dpml), weight=-1.0) tot_flux = sim.add_flux(fcen, 0, 1, top, bot, rgt, lft) sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, mp.Vector3(), 1e-5)) sim.save_flux('tot_flux', tot_flux) sim1 = sim geometry = [mp.Block(center=mp.Vector3(), size=mp.Vector3(sxy, sxy, mp.inf), material=mp.Medium(index=3.5)), mp.Block(center=mp.Vector3(), size=mp.Vector3(sxy-2*dpml, sxy-2*dpml, mp.inf), material=mp.air)] sim = mp.Simulation(cell_size=cell, geometry=geometry, boundary_layers=pml_layers, sources=sources, resolution=resolution, chunk_layout=sim1) tot_flux = sim.add_flux(fcen, 0, 1, top, bot, rgt, lft) sim.load_minus_flux('tot_flux', tot_flux) sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, mp.Vector3(), 1e-5)) self.assertAlmostEqual(86.90826609300862, mp.get_fluxes(tot_flux)[0])
def scat_sim(): """perform scattering simulation""" scat = meep.Simulation(cell_size=cell, boundary_layers=[pml], geometry=geometry, default_material=medium, resolution=resolution) scat.init_fields() source(scat) flux_box_absorb = meep_ext.add_flux_box(scat, fcen, df, nfreq, [0, 0, 0], monitor_size) flux_box_scat = meep_ext.add_flux_box(scat, fcen, df, nfreq, [0, 0, 0], monitor_size) scat.load_minus_flux(norm_file_ext, flux_box_scat) scat.run(until_after_sources=meep.stop_when_fields_decayed( .5 * um, decay, pt=meep.Vector3(0, 0, monitor_size[2] / 2), decay_by=1e-5)) return { 'scattering': np.array(meep.get_fluxes(flux_box_scat)), 'absorption': -np.array(meep.get_fluxes(flux_box_absorb)), 'frequency': np.array(meep.get_flux_freqs(flux_box_scat)) }
def dimer_scat(): """perform scattering simulation""" scat = meep.Simulation(cell_size=cell, boundary_layers=[pml], geometry=geometry, resolution=resolution) scat.init_fields() source(scat) L = 2 * radius + 2 * particle_monitor_gap Fx = meep_ext.add_force_box(scat, fcen, df, nfreq, p2, [L, L, L], meep.X) Fy = meep_ext.add_force_box(scat, fcen, df, nfreq, p2, [L, L, L], meep.Y) Fz = meep_ext.add_force_box(scat, fcen, df, nfreq, p2, [L, L, L], meep.Z) # scat.run(until_after_sources=8*um) scat.run(until_after_sources=meep.stop_when_fields_decayed( .5 * um, meep.Ex, pt=p2 - meep.Vector3(0, 0, L / 2), decay_by=1e-7)) return { 'Fx': np.array(meep.get_forces(Fx)), 'Fy': np.array(meep.get_forces(Fy)), 'Fz': np.array(meep.get_forces(Fz)), 'frequency': np.array(meep.get_force_freqs(Fx)) }
def norm_sim(): """perform normalization simulation""" norm = meep.Simulation(cell_size=cell, boundary_layers=[pml], geometry=[], default_material=medium, resolution=resolution) norm.init_fields() source(norm) flux_box_inc = meep_ext.add_flux_box(norm, fcen, df, nfreq, [0, 0, 0], monitor_size) flux_inc = meep_ext.add_flux_plane(norm, fcen, df, nfreq, [0, 0, 0], [box[0], box[1], 0]) norm.run(until_after_sources=meep.stop_when_fields_decayed( .5 * um, decay, pt=meep.Vector3(0, 0, monitor_size[2] / 2), decay_by=1e-3)) norm.save_flux(norm_file_ext, flux_box_inc) return { 'frequency': np.array(meep.get_flux_freqs(flux_inc)), 'area': box[0] * box[1], 'incident': np.asarray(meep.get_fluxes(flux_inc)) }
def main(args): resolution = 40 cell_size = mp.Vector3(z=10) boundary_layers = [ mp.PML(1, direction=mp.Z) if args.pml else mp.Absorber(1, direction=mp.Z) ] sources = [ mp.Source(src=mp.GaussianSource(1 / 0.803, fwidth=0.1), center=mp.Vector3(), component=mp.Ex) ] def print_stuff(sim): p = sim.get_field_point(mp.Ex, mp.Vector3()) print("ex:, {}, {}".format(sim.meep_time(), p.real)) sim = mp.Simulation(cell_size=cell_size, resolution=resolution, dimensions=1, default_material=Al, boundary_layers=boundary_layers, sources=sources) sim.run(mp.at_every(10, print_stuff), until_after_sources=mp.stop_when_fields_decayed( 50, mp.Ex, mp.Vector3(), 1e-6))
def sim(separation): """perform scattering simulation""" L = separation + 2*radius + 2*pml_monitor_gap + 2*particle_monitor_gap + 2*pml.thickness cell = meep.Vector3(L,L,L) p1 = meep.Vector3(-separation/2, 0, 0) p2 = meep.Vector3(separation/2, 0, 0) geometry = [meep.Sphere(center=p1, radius=radius, material=gold), meep.Sphere(center=p2, radius=radius, material=gold)] scat = meep.Simulation(cell_size=cell, boundary_layers=[pml], geometry=geometry, resolution=resolution) scat.init_fields() source(scat) L = 2*radius + 2*particle_monitor_gap Fx = meep_ext.add_force_box(scat, fcen, 0, 1, p2, [L,L,L], meep.X) Fy = meep_ext.add_force_box(scat, fcen, 0, 1, p2, [L,L,L], meep.Y) Fz = meep_ext.add_force_box(scat, fcen, 0, 1, p2, [L,L,L], meep.Z) # scat.run(until_after_sources=8*um) scat.run(until_after_sources=meep.stop_when_fields_decayed(.5*um, meep.Ex, pt=p2-meep.Vector3(0,0,L/2), decay_by=1e-5)) return {'Fx': np.array(meep.get_forces(Fx))[0], 'Fy': np.array(meep.get_forces(Fy))[0], 'Fz': np.array(meep.get_forces(Fz))[0]}
def norm_sim(monitor_size, unique_id): """perform normalization simulation with a given box size""" monitor_size = np.asarray(monitor_size) cell_size = monitor_size + 2 * pml_monitor_gap + 2 * pml.thickness cell = meep.Vector3(*cell_size) norm = meep.Simulation(cell_size=cell, boundary_layers=[pml], geometry=[], resolution=resolution) norm.init_fields() source(norm) flux_inc = meep_ext.add_flux_plane(norm, fcen, 0, 1, [0, 0, 0], [2 * radius, 2 * radius, 0]) flux_box_inc = meep_ext.add_flux_box(norm, fcen, 0, 1, [0, 0, 0], monitor_size) norm.run(until_after_sources=meep.stop_when_fields_decayed( .5 * um, meep.Ex, pt=meep.Vector3(0, 0, monitor_size[2] / 2), decay_by=1e-3)) norm.save_flux(norm_file_ext.format(unique_id), flux_box_inc) return { 'area': (2 * radius)**2, 'norm': np.asarray(meep.get_fluxes(flux_inc)) }
def sim(separation, monitor_size, unique_id): """perform scattering simulation""" monitor_size = np.asarray(monitor_size) cell_size = monitor_size + 2*pml_monitor_gap + 2*pml.thickness cell = meep.Vector3(*cell_size) p1 = meep.Vector3(-separation/2, 0, 0) p2 = meep.Vector3(separation/2, 0, 0) geometry = [meep.Sphere(center=p1, radius=radius, material=gold), meep.Sphere(center=p2, radius=radius, material=gold)] scat = meep.Simulation(cell_size=cell, boundary_layers=[pml], geometry=geometry, default_material=medium, resolution=resolution) scat.init_fields() source(scat) flux_box_absorb = meep_ext.add_flux_box(scat, fcen, 0, 1, [0,0,0], monitor_size) flux_box_scat = meep_ext.add_flux_box(scat, fcen, 0, 1, [0,0,0], monitor_size) scat.load_minus_flux(norm_file_ext.format(unique_id), flux_box_scat) # scat.run(until_after_sources=8*um) scat.run(until_after_sources=meep.stop_when_fields_decayed(.5*um, polarization, pt=p2 - meep.Vector3(0,0,monitor_size[2]/2), decay_by=1e-4)) return {'scattering': np.array(meep.get_fluxes(flux_box_scat)), 'absorption': -np.array(meep.get_fluxes(flux_box_absorb))}
def force_sim(): """perform scattering simulation""" sim = meep.Simulation(cell_size=cell, boundary_layers=[pml], geometry=geometry, default_material=medium, resolution=resolution) sim.init_fields() source(sim) L = 2**.5 * W + 2 * particle_monitor_gap p = meep.Vector3(sep / 2, 0, 0) Fx_mon = meep_ext.add_force_box(sim, fcen, df, nfreq, p, [L, L, L], meep.X) Fy_mon = meep_ext.add_force_box(sim, fcen, df, nfreq, p, [L, L, L], meep.Y) Fz_mon = meep_ext.add_force_box(sim, fcen, df, nfreq, p, [L, L, L], meep.Z) sim.run(until_after_sources=meep.stop_when_fields_decayed( .5 * um, decay, pt=meep.Vector3(0, 0, monitor_size[2] / 2), decay_by=1e-5)) Fx = np.array(meep.get_forces(Fx_mon)) Fy = np.array(meep.get_forces(Fy_mon)) Fz = np.array(meep.get_forces(Fz_mon)) frequency = np.array(meep.get_force_freqs(Fx_mon)) return dict(frequency=frequency, Fx=Fx, Fy=Fy, Fz=Fz)
def test_ldos(self): self.sim.run( mp.dft_ldos(self.fcen, 0, 1), until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, mp.Vector3(), 1e-6) ) self.assertAlmostEqual(self.sim.ldos_data[0], 1.011459560620368)
def sim(): """perform scattering simulation""" sim = meep.Simulation(cell_size=cell, boundary_layers=[pml], geometry=geometry, default_material=medium, resolution=resolution) sim.init_fields() sim.init_sim() source(sim) freq = 1 / (600 * nm) # dft = sim.add_dft_fields([meep.Ex, meep.Ey, meep.Ez], freq, freq, 1, center=meep.Vector3(0,0,0), # size=meep.Vector3(L,L,0)) vol = meep.volume(meep.vec(-L / 2, -L / 2, 0), meep.vec(L / 2, L / 2, 0)) dft = sim.fields.add_dft_fields([meep.Ex, meep.Ey, meep.Ez], vol, freq, freq, 1) sim.run(until_after_sources=meep.stop_when_fields_decayed( .5 * um, decay, pt=meep.Vector3(0, 0, box[2] / 2), decay_by=1e-5)) # for i in range(100): # sim.fields.step() Ex = sim.get_dft_array(dft, meep.Ex, 0) Ey = sim.get_dft_array(dft, meep.Ey, 0) Ez = sim.get_dft_array(dft, meep.Ez, 0) E = np.array([Ex, Ey, Ez]) return dict(E=E)
def run_with_straight_waveguide(self): self.init(no_bend=True) self.sim.run(until_after_sources=mp.stop_when_fields_decayed( 50, mp.Ez, self.pt, 1e-3)) self.sim.save_flux('refl-flux', self.refl) expected = [ (0.1, 3.65231563251e-05, 3.68932495077e-05), (0.10101010101, 5.55606718876e-05, 5.6065539588e-05), (0.10202020202, 8.38211697478e-05, 8.44909864736e-05), (0.10303030303, 0.000125411162229, 0.000126268639045), (0.10404040404, 0.000186089117531, 0.000187135303398), (0.105050505051, 0.000273848867869, 0.000275039134667), (0.106060606061, 0.000399674037745, 0.000400880269423), (0.107070707071, 0.00057849953593, 0.000579454087881), (0.108080808081, 0.000830418432986, 0.000830635406881), (0.109090909091, 0.00118217282661, 0.00118084271347), (0.110101010101, 0.00166896468348, 0.00166481944189), (0.111111111111, 0.00233661613864, 0.00232776318321), (0.112121212121, 0.00324409729096, 0.00322782257917), (0.113131313131, 0.00446642217385, 0.00443896468822), (0.114141414141, 0.0060978895019, 0.0060541922825), (0.115151515152, 0.00825561352398, 0.00818906047274), (0.116161616162, 0.0110832518495, 0.010985404883), (0.117171717172, 0.0147547920552, 0.0146151488236), (0.118181818182, 0.0194782085272, 0.0192840042241), (0.119191919192, 0.0254987474079, 0.0252348211592), ] res = list( zip(mp.get_flux_freqs(self.trans), mp.get_fluxes(self.trans), mp.get_fluxes(self.refl))) np.testing.assert_allclose(expected, res[:20])
def test_absorber(self): self.sim.run(until_after_sources=mp.stop_when_fields_decayed( 50, mp.Ex, mp.Vector3(), 1e-6)) f = self.sim.get_field_point(mp.Ex, mp.Vector3()) self.assertAlmostEqual(f.real, 4.789444250711607e-10, places=6)
def force_sim(): """perform scattering simulation""" sim = meep.Simulation(cell_size=cell, boundary_layers=[pml], geometry=geometry, default_material=medium, resolution=resolution) sim.init_fields() source(sim) L = 2*radius + 2*particle_monitor_gap forces = {} for i in range(9): p = meep.Vector3(x[i], y[i], z[i]) key = 'N{i}_F{c}' forces[key.format(i=i, c='x')] = meep_ext.add_force_box(sim, fcen, df, nfreq, p, [L,L,L], meep.X) forces[key.format(i=i, c='y')] = meep_ext.add_force_box(sim, fcen, df, nfreq, p, [L,L,L], meep.Y) forces[key.format(i=i, c='z')] = meep_ext.add_force_box(sim, fcen, df, nfreq, p, [L,L,L], meep.Z) sim.run(until_after_sources=meep.stop_when_fields_decayed(.5*um, decay, pt=meep.Vector3(0,0,monitor_size[2]/2), decay_by=1e-8)) ret = {} for i in range(9): for c in ['x', 'y', 'z']: key = f'N{i}_F{c}' ret[key] = np.array(meep.get_forces(forces[key])) ret['frequency'] = np.array(meep.get_force_freqs(forces['N1_Fx'])) return ret
def test_absorber(self): self.sim.run(until_after_sources=mp.stop_when_fields_decayed( 50, mp.Ex, mp.Vector3(), 1e-6)) f = self.sim.get_field_point(mp.Ex, mp.Vector3()) self.assertAlmostEqual(f.real, 3.218846961494622e-13, places=6)
def test_ldos_user_object(self): ldos = mp.Ldos(self.fcen, 0, 1) self.sim.run(mp.dft_ldos(ldos=ldos), until_after_sources=mp.stop_when_fields_decayed( 50, mp.Ez, mp.Vector3(), 1e-6)) self.assertAlmostEqual(self.sim.ldos_data[0], 1.011459560620368) self.assertEqual(len(mp.get_ldos_freqs(ldos)), 1)
def main(args): resolution = 20 cell_size = mp.Vector3(z=10) dimensions = 1 # conversion factor fro eV to 1/um eV_um_scale = 1 / 1.23984193 # Al, from Rakic et al., Applied Optics, vol. 32, p. 5274 (1998) Al_eps_inf = 1 Al_plasma_frq = 14.98 * eV_um_scale Al_f0 = 0.523 Al_frq0 = 1e-10 Al_gam0 = 0.047 * eV_um_scale Al_sig0 = (Al_f0 * math.sqrt(Al_plasma_frq)) / (math.sqrt(Al_frq0)) Al_f1 = 0.050 Al_frq1 = 1.544 * eV_um_scale # 803 nm Al_gam1 = 0.312 * eV_um_scale Al_sig1 = (Al_f1 * math.sqrt(Al_plasma_frq)) / (math.sqrt(Al_frq1)) E_susceptibilities = [ mp.DrudeSusceptibility(frequency=Al_frq0, gamma=Al_gam0, sigma=Al_sig0), mp.LorentzianSusceptibility(frequency=Al_frq1, gamma=Al_gam1, sigma=Al_sig1) ] Al = mp.Medium(epsilon=Al_eps_inf, E_susceptibilities=E_susceptibilities) pml_layers = [ mp.PML(1, direction=mp.Z) if args.pml else mp.Absorber(1, direction=mp.Z) ] sources = [ mp.Source(src=mp.GaussianSource(1 / 0.803, fwidth=0.1), center=mp.Vector3(), component=mp.Ex) ] def print_stuff(sim): print("ex:, {}, {}".format(sim.meep_time(), sim.get_field_point(mp.Ex, mp.Vector3()))) sim = mp.Simulation(cell_size=cell_size, resolution=resolution, dimensions=dimensions, default_material=Al, boundary_layers=pml_layers, sources=sources) sim.run(mp.at_every(10, print_stuff), until_after_sources=mp.stop_when_fields_decayed( 50, mp.Ex, mp.Vector3(), 1e-6))
def test_farfield(self): expected = [ (0j, 0j, 0.013561672901190156 - 0.014417985982674887j, -0.007972091889832573 + 0.008474039259808384j, -0.010972504173533907 + 0.011663526883728901j, 0j), (0j, 0j, 0.013580605154131353 - 0.014437805790483897j, -0.00727747760452799 + 0.007735510886150803j, -0.011467448148229137 + 0.01218937654274057j, 0j), (0j, 0j, 0.013623909088910181 - 0.0144248508451555j, -0.006563855061778871 + 0.0069485969930299695j, -0.011939764884917667 + 0.012639701096677738j, 0j), (0j, 0j, 0.01366551237281673 - 0.014382588988355682j, -0.005818861980069385 + 0.006123274021053104j, -0.012366016128341942 + 0.013012805294365515j, 0j), (0j, 0j, 0.013680914029322 - 0.014330104120260687j, -0.00503658263321274 + 0.005274864846985408j, -0.012721298907853191 + 0.013322780730790889j, 0j), (0j, 0j, 0.013666069573084385 - 0.014288938849212545j, -0.004223325784559204 + 0.004415251197679649j, -0.01299830976630439 + 0.0135885339986728j, 0j), (0j, 0j, 0.013636004904245425 - 0.014270749446931172j, -0.003391403389081595 + 0.003548797079942323j, -0.013208708739843122 + 0.013821337222637264j, 0j), (0j, 0j, 0.013609442340491029 - 0.014273698854090303j, -0.0025503938754594265 + 0.0026744729386901805j, -0.013369492605877786 + 0.014019798855923278j, 0j), (0j, 0j, 0.013595569402532206 - 0.014287439152148014j, -0.0017041572263699332 + 0.001790574472119783j, -0.013489487541122221 + 0.014173702684166192j, 0j), (0j, 0j, 0.01359208053488311 - 0.014300667598824968j, -8.535506874711307e-4 + 8.978801355605307e-4j, -0.01356639388716244 + 0.01427136892007339j, 0j) ] self.sim.run(until_after_sources=mp.stop_when_fields_decayed(50, self.src_cmpt, mp.Vector3(), 1e-8)) r = 1000 npts = 100 result = [] for n in range(npts): ff = self.sim.get_farfield( self.nearfield, mp.Vector3(r * math.cos(2 * math.pi * (n / npts)), r * math.sin(2 * math.pi * (n / npts)))) result.append(ff) np.testing.assert_allclose(expected, result[-10:])
def test_force(self): self.sim.run(until_after_sources=mp.stop_when_fields_decayed( 50, mp.Ez, mp.Vector3(), 1e-6)) self.sim.display_forces(self.myforce) f = mp.get_forces(self.myforce) self.assertAlmostEqual(f[0], -0.11039089113393187)
def monitor_until(geo=None, until=None, **kwargs): geo = kwargs_to_geo(geo, **kwargs) stop_kwarg = dict() if until is None: monitor_point = mp.Vector3(monitor_x(geo), 0, 0) stop_kwarg['until_after_sources'] = mp.stop_when_fields_decayed( 20, mp.Ey, monitor_point, 1e-3) else: stop_kwarg['until'] = until return stop_kwarg
def main(args): resolution = args.res sz = args.sz cell_size = mp.Vector3(0, 0, sz) lambda_min = 0.4 lambda_max = 0.8 fmax = 1 / lambda_min fmin = 1 / lambda_max fcen = 0.5 * (fmax + fmin) df = fmax - fmin dpml = 1.0 pml_layers = [mp.PML(dpml)] sources = [ mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ex, center=mp.Vector3(0, 0, -0.5 * sz + dpml)) ] if args.empty: geometry = [] else: geometry = [ mp.Block(mp.Vector3(mp.inf, mp.inf, 0.5 * sz), center=mp.Vector3(0, 0, 0.25 * sz), material=fused_quartz) ] sim = mp.Simulation(cell_size=cell_size, boundary_layers=pml_layers, geometry=geometry, sources=sources, dimensions=1, k_point=mp.Vector3(0, 0, 0), resolution=resolution) refl_fr = mp.FluxRegion(center=mp.Vector3(0, 0, -0.25 * sz)) nfreq = 50 refl = sim.add_flux(fcen, df, nfreq, refl_fr) if not args.empty: sim.load_minus_flux('refl-flux', refl) sim.run(until_after_sources=mp.stop_when_fields_decayed( 50, mp.Ex, mp.Vector3(0, 0, -0.5 * sz + dpml), 1e-9)) if args.empty: sim.save_flux('refl-flux', refl) sim.display_fluxes(refl)
def test_ldos_user_object(self): ldos = mp.Ldos(self.fcen, 0, 1) self.sim.run(mp.dft_ldos(ldos=ldos), until_after_sources=mp.stop_when_fields_decayed( 50, mp.Ez, mp.Vector3(), 1e-6)) self.assertAlmostEqual(self.sim.ldos_data[0], 1.011459560620368) freqs = ldos.freqs() self.assertEqual(ldos.freq_min, freqs[0] * 2 * math.pi) self.assertEqual(ldos.nfreq, 1) self.assertEqual(ldos.dfreq, 0)
def main(args): sz = 100 # size of cell in z direction fcen = 1 / 3.0 # center frequency of source df = fcen / 20.0 # frequency width of source amp = args.amp # amplitude of source k = 10**args.logk # Kerr susceptibility dpml = 1.0 # PML thickness # We'll use an explicitly 1d simulation. Setting dimensions=1 will actually # result in faster execution than just using two no-size dimensions. However, # in this case Meep requires us to use E in the x direction (and H in y), # and our one no-size dimension must be z. dimensions = 1 cell = mp.Vector3(0, 0, sz) pml_layers = mp.PML(dpml) resolution = 20 # to put the same material in all space, we can just set the default material # and pass it to the Simulation constructor default_material = mp.Medium(index=1, chi3=k) sources = mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ex, center=mp.Vector3(0, 0, -0.5 * sz + dpml), amplitude=amp) # frequency range for flux calculation nfreq = 400 fmin = fcen / 2.0 fmax = fcen * 4 sim = mp.Simulation(cell_size=cell, geometry=[], sources=[sources], boundary_layers=[pml_layers], default_material=default_material, resolution=resolution, dimensions=dimensions) # trans = sim.add_flux(0.5 * (fmin + fmax), fmax - fmin, nfreq, # mp.FluxRegion(mp.Vector3(0, 0, 0.5*sz - dpml - 0.5))) trans1 = sim.add_flux( fcen, 0, 1, mp.FluxRegion(mp.Vector3(0, 0, 0.5 * sz - dpml - 0.5))) trans3 = sim.add_flux( 3 * fcen, 0, 1, mp.FluxRegion(mp.Vector3(0, 0, 0.5 * sz - dpml - 0.5))) sim.run(until_after_sources=mp.stop_when_fields_decayed( 50, mp.Ex, mp.Vector3(0, 0, 0.5 * sz - dpml - 0.5), 1e-6)) # sim.display_fluxes(trans) print("harmonics:, {}, {}, {}, {}".format(k, amp, mp.get_fluxes(trans1)[0], mp.get_fluxes(trans3)[0]))
def test_ldos_user_object(self): ldos = mp.Ldos(self.fcen, 0, 1) self.sim.run( mp.dft_ldos(ldos=ldos), until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, mp.Vector3(), 1e-6) ) self.assertAlmostEqual(self.sim.ldos_data[0], 1.011459560620368) freqs = ldos.freqs() self.assertEqual(ldos.freq_min, freqs[0] * 2 * math.pi) self.assertEqual(ldos.nfreq, 1) self.assertEqual(ldos.dfreq, 0)
def test_force(self): self.sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, mp.Vector3(), 1e-6)) # Test store and load of force as numpy array fdata = self.sim.get_force_data(self.myforce) self.sim.load_force_data(self.myforce, fdata) self.sim.display_forces(self.myforce) f = mp.get_forces(self.myforce) self.assertAlmostEqual(f[0], -0.11039089113393187)
def test_force(self): self.sim.run(until_after_sources=mp.stop_when_fields_decayed( 50, mp.Ez, mp.Vector3(), 1e-6)) # Test store and load of force as numpy array fdata = self.sim.get_force_data(self.myforce) self.sim.load_force_data(self.myforce, fdata) self.sim.display_forces(self.myforce) f = mp.get_forces(self.myforce) self.assertAlmostEqual(f[0], -0.11039089113393187)
def test_3rd_harm_1d(self): expected_harmonics = [0.01, 1.0, 221.89548712071553, 1.752960413399477] self.sim.run( until_after_sources=mp.stop_when_fields_decayed( 50, mp.Ex, mp.Vector3(0, 0, (0.5 * self.sz) - self.dpml - 0.5), 1e-6 ) ) harmonics = [self.k, self.amp, mp.get_fluxes(self.trans1)[0], mp.get_fluxes(self.trans3)[0]] np.testing.assert_allclose(expected_harmonics, harmonics)
def main(args): sz = 100 # size of cell in z direction fcen = 1 / 3.0 # center frequency of source df = fcen / 20.0 # frequency width of source amp = args.amp # amplitude of source k = 10**args.logk # Kerr susceptibility dpml = 1.0 # PML thickness # We'll use an explicitly 1d simulation. Setting dimensions=1 will actually # result in faster execution than just using two no-size dimensions. However, # in this case Meep requires us to use E in the x direction (and H in y), # and our one no-size dimension must be z. dimensions = 1 cell = mp.Vector3(0, 0, sz) pml_layers = mp.PML(dpml) resolution = 20 # to put the same material in all space, we can just set the default material # and pass it to the Simulation constructor default_material = mp.Medium(index=1, chi3=k) sources = mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ex, center=mp.Vector3(0, 0, -0.5*sz + dpml), amplitude=amp) # frequency range for flux calculation nfreq = 400 fmin = fcen / 2.0 fmax = fcen * 4 sim = mp.Simulation(cell_size=cell, geometry=[], sources=[sources], boundary_layers=[pml_layers], default_material=default_material, resolution=resolution, dimensions=dimensions) # trans = sim.add_flux(0.5 * (fmin + fmax), fmax - fmin, nfreq, # mp.FluxRegion(mp.Vector3(0, 0, 0.5*sz - dpml - 0.5))) trans1 = sim.add_flux(fcen, 0, 1, mp.FluxRegion(mp.Vector3(0, 0, 0.5*sz - dpml - 0.5))) trans3 = sim.add_flux(3 * fcen, 0, 1, mp.FluxRegion(mp.Vector3(0, 0, 0.5*sz - dpml - 0.5))) sim.run(until_after_sources=mp.stop_when_fields_decayed( 50, mp.Ex, mp.Vector3(0, 0, 0.5*sz - dpml - 0.5), 1e-6)) # sim.display_fluxes(trans) print("harmonics:, {}, {}, {}, {}".format(k, amp, mp.get_fluxes(trans1)[0], mp.get_fluxes(trans3)[0]))
def test_3rd_harm_1d(self): expected_harmonics = [0.01, 1.0, 221.89548712071553, 1.752960413399477] self.sim.run( until_after_sources=mp.stop_when_fields_decayed( 50, mp.Ex, mp.Vector3(0, 0, (0.5 * self.sz) - self.dpml - 0.5), 1e-6 ) ) harmonics = [self.k, self.amp, mp.get_fluxes(self.trans1)[0], mp.get_fluxes(self.trans3)[0]] tol = 3e-5 if mp.is_single_precision() else 1e-7 self.assertClose(expected_harmonics, harmonics, epsilon=tol)
def test_ninety_degree_bend(self): # We have to run the straight waveguide version first to generate the 'refl-flux' # file that this test uses. We can't just prepend run_with_straight_waveguide # with 'test_' because execution order of unit tests isn't deterministic. self.run_with_straight_waveguide() self.sim = None self.init() self.sim.load_minus_flux('refl-flux', self.refl) self.sim.run(until_after_sources=mp.stop_when_fields_decayed( 50, mp.Ez, self.pt, 1e-3)) expected = [ (0.09999999999999999, 1.8392235204829767e-5, -7.259467687598002e-6), (0.10101010101010101, 2.7629932558236724e-5, -1.1107162110079347e-5), (0.10202020202020202, 4.1001228946782745e-5, -1.687561915798036e-5), (0.10303030303030304, 6.018966076122556e-5, -2.5425779493709066e-5), (0.10404040404040406, 8.758554071933231e-5, -3.794958119189475e-5), (0.10505050505050507, 1.2656696778129198e-4, -5.612512808928115e-5), (0.10606060606060609, 1.817948859871414e-4, -8.232188174309142e-5), (0.10707070707070711, 2.594514094902856e-4, -1.1981531280672989e-4), (0.10808080808080812, 3.6736164837695035e-4, -1.7300125173897737e-4), (0.10909090909090914, 5.150131339048232e-4, -2.476730940385436e-4), (0.11010101010101016, 7.136181099374187e-4, -3.5145561406042276e-4), (0.11111111111111117, 9.76491765781944e-4, -4.944142331545938e-4), (0.11212121212121219, 0.001320033637882244, -6.897357105189368e-4), (0.11313131313131321, 0.0017653940714397098, -9.543556354451615e-4), (0.11414141414141422, 0.0023404727796352857, -0.0013095604571818236), (0.11515151515151524, 0.0030813962415392098, -0.00178176942635486), (0.11616161616161626, 0.00403238648982478, -0.0024036650652026112), (0.11717171717171727, 0.005243320443599316, -0.003215529845495731), (0.11818181818181829, 0.0067654019326068, -0.004266367104375331), (0.11919191919191931, 0.008646855439680507, -0.005614491919262783), ] res = list( zip(mp.get_flux_freqs(self.trans), mp.get_fluxes(self.trans), mp.get_fluxes(self.refl))) np.testing.assert_allclose(expected, res[:20])
def test_3rd_harm_1d(self): expected_harmonics = [0.01, 1.0, 221.89548712071553, 1.752960413399477] self.sim.run(until_after_sources=mp.stop_when_fields_decayed( 50, mp.Ex, mp.Vector3(0, 0, (0.5 * self.sz) - self.dpml - 0.5), 1e-6)) harmonics = [ self.k, self.amp, mp.get_fluxes(self.trans1)[0], mp.get_fluxes(self.trans3)[0] ] np.testing.assert_allclose(expected_harmonics, harmonics)
def main(args): resolution = 40 cell_size = mp.Vector3(z=10) boundary_layers = [mp.PML(1, direction=mp.Z) if args.pml else mp.Absorber(1, direction=mp.Z)] sources = [mp.Source(src=mp.GaussianSource(1 / 0.803, fwidth=0.1), center=mp.Vector3(), component=mp.Ex)] def print_stuff(sim): p = sim.get_field_point(mp.Ex, mp.Vector3()) print("ex:, {}, {}".format(sim.meep_time(), p.real)) sim = mp.Simulation(cell_size=cell_size, resolution=resolution, dimensions=1, default_material=Al, boundary_layers=boundary_layers, sources=sources) sim.run(mp.at_every(10, print_stuff), until_after_sources=mp.stop_when_fields_decayed(50, mp.Ex, mp.Vector3(), 1e-6))
vertices = [mp.Vector3(-0.5*sx-1,0.5*w1), mp.Vector3(0.5*sx+1,0.5*w1), mp.Vector3(0.5*sx+1,-0.5*w1), mp.Vector3(-0.5*sx-1,-0.5*w1)] sim = mp.Simulation(resolution=resolution, cell_size=cell_size, boundary_layers=boundary_layers, geometry=[mp.Prism(vertices,height=mp.inf,material=Si)], sources=sources, symmetries=symmetries) mon_pt = mp.Vector3(-0.5*sx+dpml_x+0.7*Lw) flux = sim.add_flux(fcen,0,1,mp.FluxRegion(center=mon_pt,size=mp.Vector3(y=sy-2*dpml_y))) sim.run(until_after_sources=mp.stop_when_fields_decayed(50,mp.Ez,mon_pt,1e-9)) res = sim.get_eigenmode_coefficients(flux,[1],eig_parity=mp.ODD_Z+mp.EVEN_Y) incident_coeffs = res.alpha incident_flux = mp.get_fluxes(flux) incident_flux_data = sim.get_flux_data(flux) sim.reset_meep() # linear taper vertices = [mp.Vector3(-0.5*sx-1,0.5*w1), mp.Vector3(-0.5*Lt,0.5*w1), mp.Vector3(0.5*Lt,0.5*w2), mp.Vector3(0.5*sx+1,0.5*w2), mp.Vector3(0.5*sx+1,-0.5*w2), mp.Vector3(0.5*Lt,-0.5*w2),
symmetries=symmetries, boundary_layers=pml_layers) nearfield_box = sim.add_near2far(fcen, 0, 1, mp.Near2FarRegion(mp.Vector3(y=0.5*sxy), size=mp.Vector3(sxy)), mp.Near2FarRegion(mp.Vector3(y=-0.5*sxy), size=mp.Vector3(sxy), weight=-1), mp.Near2FarRegion(mp.Vector3(0.5*sxy), size=mp.Vector3(y=sxy)), mp.Near2FarRegion(mp.Vector3(-0.5*sxy), size=mp.Vector3(y=sxy), weight=-1)) flux_box = sim.add_flux(fcen, 0, 1, mp.FluxRegion(mp.Vector3(y=0.5*sxy), size=mp.Vector3(sxy)), mp.FluxRegion(mp.Vector3(y=-0.5*sxy), size=mp.Vector3(sxy), weight=-1), mp.FluxRegion(mp.Vector3(0.5*sxy), size=mp.Vector3(y=sxy)), mp.FluxRegion(mp.Vector3(-0.5*sxy), size=mp.Vector3(y=sxy), weight=-1)) sim.run(until_after_sources=mp.stop_when_fields_decayed(50, src_cmpt, mp.Vector3(), 1e-8)) near_flux = mp.get_fluxes(flux_box)[0] r = 1000/fcen # half side length of far-field square box OR radius of far-field circle res_ff = 1 # resolution of far fields (points/μm) far_flux_box = (nearfield_box.flux(mp.Y, mp.Volume(center=mp.Vector3(y=r), size=mp.Vector3(2*r)), res_ff)[0] - nearfield_box.flux(mp.Y, mp.Volume(center=mp.Vector3(y=-r), size=mp.Vector3(2*r)), res_ff)[0] + nearfield_box.flux(mp.X, mp.Volume(center=mp.Vector3(r), size=mp.Vector3(y=2*r)), res_ff)[0] - nearfield_box.flux(mp.X, mp.Volume(center=mp.Vector3(-r), size=mp.Vector3(y=2*r)), res_ff)[0]) npts = 100 # number of points in [0,2*pi) range of angles angles = 2*math.pi/npts*np.arange(npts) E = np.zeros((npts,3),dtype=np.complex128) H = np.zeros((npts,3),dtype=np.complex128)
def test_absorber(self): self.sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ex, mp.Vector3(), 1e-6)) f = self.sim.get_field_point(mp.Ex, mp.Vector3()) self.assertAlmostEqual(f.real, 3.218846961494622e-13, places=6)
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 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, 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_after_sources=mp.stop_when_fields_decayed(50, mp.Hz, mp.Vector3(0.12, -0.37), 1e-8)) d2 = 20 h = 4 sim.output_farfields(nearfield, "spectra-{}-{}-{}".format(d1, d2, h), resolution, where=mp.Volume(mp.Vector3(0, (0.5 * w) + d2 + (0.5 * h)), size=mp.Vector3(sx - 2 * dpml, h)))
fcen = 0.5*(fmax+fmin) df = fmax-fmin nfreq = 50 sources = [ mp.Source(mp.GaussianSource(fcen,fwidth=df), component=mp.Ex, center=mp.Vector3(0,0,-0.5*sz+dpml)) ] sim = mp.Simulation(cell_size=cell_size, boundary_layers=pml_layers, sources=sources, dimensions=1, resolution=resolution) refl_fr = mp.FluxRegion(center=mp.Vector3(0,0,-0.25*sz)) refl = sim.add_flux(fcen, df, nfreq, refl_fr) sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ex, mp.Vector3(), 1e-9)) empty_flux = mp.get_fluxes(refl) empty_data = sim.get_flux_data(refl) sim.reset_meep() geometry = [ mp.Block(mp.Vector3(mp.inf,mp.inf,0.5*sz), center=mp.Vector3(0,0,0.25*sz), material=fused_quartz) ] sim = mp.Simulation(cell_size=cell_size, boundary_layers=pml_layers, geometry=geometry, sources=sources, dimensions=1, resolution=resolution) refl = sim.add_flux(fcen, df, nfreq, refl_fr)
def test_transmission_spectrum(self): expected = [ (0.15, 7.218492264696595e-6), (0.1504008016032064, 6.445696315927592e-6), (0.1508016032064128, 5.140949243632777e-6), (0.15120240480961922, 3.6159747936427164e-6), (0.15160320641282563, 2.263940553705969e-6), (0.15200400801603203, 1.4757165844336744e-6), (0.15240480961923844, 1.5491803919142815e-6), (0.15280561122244485, 2.612053246626972e-6), (0.15320641282565126, 4.577504371188737e-6), (0.15360721442885766, 7.1459089162998185e-6), (0.15400801603206407, 9.856622013418823e-6), (0.15440881763527048, 1.2182309227954296e-5), (0.1548096192384769, 1.3647726444709649e-5), (0.1552104208416833, 1.3947420613633674e-5), (0.1556112224448897, 1.303466755716231e-5), (0.1560120240480961, 1.115807915037775e-5), (0.15641282565130252, 8.832335196969796e-6), (0.15681362725450892, 6.743645773127985e-6), (0.15721442885771533, 5.605913756087576e-6), (0.15761523046092174, 5.996668564026961e-6), (0.15801603206412815, 8.209400611614078e-6), (0.15841683366733456, 1.2158641936828497e-5), (0.15881763527054096, 1.73653230513453e-5), (0.15921843687374737, 2.303382576477893e-5), (0.15961923847695378, 2.821180350795834e-5), (0.1600200400801602, 3.200359292911769e-5), (0.1604208416833666, 3.3792624373001934e-5), (0.160821643286573, 3.342171394788991e-5), (0.1612224448897794, 3.1284866146526904e-5), (0.16162324649298582, 2.830022088581398e-5), (0.16202404809619222, 2.5758413657344014e-5), (0.16242484969939863, 2.506899997971769e-5), (0.16282565130260504, 2.7453508915303887e-5), (0.16322645290581145, 3.365089813497114e-5), (0.16362725450901786, 4.370486834112e-5), (0.16402805611222426, 5.689050715055283e-5), (0.16442885771543067, 7.181133157470506e-5), (0.16482965931863708, 8.666168027415369e-5), (0.16523046092184349, 9.961094123261317e-5), (0.1656312625250499, 1.0923388232657953e-4), (0.1660320641282563, 1.1489334204708105e-4), (0.1664328657314627, 1.1698318060032011e-4), (0.16683366733466912, 1.169621456132733e-4), (0.16723446893787552, 1.1714995241571987e-4), (0.16763527054108193, 1.2030783847222252e-4), (0.16803607214428834, 1.2907652919660887e-4), ] self.sim.sources = [ mp.Source(mp.GaussianSource(self.fcen, fwidth=self.df), mp.Ey, mp.Vector3(self.dpml + (-0.5 * self.sx)), size=mp.Vector3(0, self.w)) ] self.sim.symmetries = [mp.Mirror(mp.Y, phase=-1)] freg = mp.FluxRegion(center=mp.Vector3((0.5 * self.sx) - self.dpml - 0.5), size=mp.Vector3(0, 2 * self.w)) trans = self.sim.add_flux(self.fcen, self.df, self.nfreq, freg) self.sim.run( until_after_sources=mp.stop_when_fields_decayed( 50, mp.Ey, mp.Vector3((0.5 * self.sx) - self.dpml - 0.5, 0), 1e-1) ) res = zip(mp.get_flux_freqs(trans), mp.get_fluxes(trans)) for e, r in zip(expected, res): np.testing.assert_allclose(e, r)
def run_bend_flux(self, from_gdsii_file): # Normalization run self.init(no_bend=True, gdsii=from_gdsii_file) self.sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, self.pt, 1e-3)) # Save flux data for use in real run below fdata = self.sim.get_flux_data(self.refl) expected = [ (0.1, 3.65231563251e-05, 3.68932495077e-05), (0.10101010101, 5.55606718876e-05, 5.6065539588e-05), (0.10202020202, 8.38211697478e-05, 8.44909864736e-05), (0.10303030303, 0.000125411162229, 0.000126268639045), (0.10404040404, 0.000186089117531, 0.000187135303398), (0.105050505051, 0.000273848867869, 0.000275039134667), (0.106060606061, 0.000399674037745, 0.000400880269423), (0.107070707071, 0.00057849953593, 0.000579454087881), (0.108080808081, 0.000830418432986, 0.000830635406881), (0.109090909091, 0.00118217282661, 0.00118084271347), (0.110101010101, 0.00166896468348, 0.00166481944189), (0.111111111111, 0.00233661613864, 0.00232776318321), (0.112121212121, 0.00324409729096, 0.00322782257917), (0.113131313131, 0.00446642217385, 0.00443896468822), (0.114141414141, 0.0060978895019, 0.0060541922825), (0.115151515152, 0.00825561352398, 0.00818906047274), (0.116161616162, 0.0110832518495, 0.010985404883), (0.117171717172, 0.0147547920552, 0.0146151488236), (0.118181818182, 0.0194782085272, 0.0192840042241), (0.119191919192, 0.0254987474079, 0.0252348211592), ] res = list(zip(mp.get_flux_freqs(self.trans), mp.get_fluxes(self.trans), mp.get_fluxes(self.refl))) tolerance = 1e-2 if from_gdsii_file else 1e-3 compare_arrays(self, np.array(expected), np.array(res[:20]), tol=tolerance) # Real run self.sim = None self.init(gdsii=from_gdsii_file) # Load flux data obtained from normalization run self.sim.load_minus_flux_data(self.refl, fdata) self.sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, self.pt, 1e-3)) expected = [ (0.09999999999999999, 1.8392235204829767e-5, -7.259467687598002e-6), (0.10101010101010101, 2.7629932558236724e-5, -1.1107162110079347e-5), (0.10202020202020202, 4.1001228946782745e-5, -1.687561915798036e-5), (0.10303030303030304, 6.018966076122556e-5, -2.5425779493709066e-5), (0.10404040404040406, 8.758554071933231e-5, -3.794958119189475e-5), (0.10505050505050507, 1.2656696778129198e-4, -5.612512808928115e-5), (0.10606060606060609, 1.817948859871414e-4, -8.232188174309142e-5), (0.10707070707070711, 2.594514094902856e-4, -1.1981531280672989e-4), (0.10808080808080812, 3.6736164837695035e-4, -1.7300125173897737e-4), (0.10909090909090914, 5.150131339048232e-4, -2.476730940385436e-4), (0.11010101010101016, 7.136181099374187e-4, -3.5145561406042276e-4), (0.11111111111111117, 9.76491765781944e-4, -4.944142331545938e-4), (0.11212121212121219, 0.001320033637882244, -6.897357105189368e-4), (0.11313131313131321, 0.0017653940714397098, -9.543556354451615e-4), (0.11414141414141422, 0.0023404727796352857, -0.0013095604571818236), (0.11515151515151524, 0.0030813962415392098, -0.00178176942635486), (0.11616161616161626, 0.00403238648982478, -0.0024036650652026112), (0.11717171717171727, 0.005243320443599316, -0.003215529845495731), (0.11818181818181829, 0.0067654019326068, -0.004266367104375331), (0.11919191919191931, 0.008646855439680507, -0.005614491919262783), ] res = list(zip(mp.get_flux_freqs(self.trans), mp.get_fluxes(self.trans), mp.get_fluxes(self.refl))) tolerance = 1e-2 if from_gdsii_file else 1e-3 compare_arrays(self, np.array(expected), np.array(res[:20]), tol=tolerance)
def test_refl_angular(self): resolution = 100 dpml = 1.0 sz = 10 sz = sz + 2 * dpml cell_size = mp.Vector3(z=sz) pml_layers = [mp.PML(dpml)] wvl_min = 0.4 wvl_max = 0.8 fmin = 1 / wvl_max fmax = 1 / wvl_min fcen = 0.5 * (fmin + fmax) df = fmax - fmin nfreq = 50 theta_r = math.radians(0) k = mp.Vector3(math.sin(theta_r), 0, math.cos(theta_r)).scale(fcen) dimensions = 1 sources = [mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ex, center=mp.Vector3(z=-0.5 * sz + dpml))] sim = mp.Simulation(cell_size=cell_size, boundary_layers=pml_layers, sources=sources, k_point=k, dimensions=dimensions, resolution=resolution) refl_fr = mp.FluxRegion(center=mp.Vector3(z=-0.25 * sz)) refl = sim.add_flux(fcen, df, nfreq, refl_fr) sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ex, mp.Vector3(z=-0.5 * sz + dpml), 1e-9)) empty_data = sim.get_flux_data(refl) sim.reset_meep() geometry = [mp.Block(mp.Vector3(mp.inf, mp.inf, 0.5 * sz), center=mp.Vector3(z=0.25 * sz), material=mp.Medium(index=3.5))] sim = mp.Simulation(cell_size=cell_size, geometry=geometry, boundary_layers=pml_layers, sources=sources, k_point=k, dimensions=dimensions, resolution=resolution) refl = sim.add_flux(fcen, df, nfreq, refl_fr) sim.load_minus_flux_data(refl, empty_data) sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ex, mp.Vector3(z=-0.5 * sz + dpml), 1e-9)) refl_flux = mp.get_fluxes(refl) freqs = mp.get_flux_freqs(refl) expected = [ (1.25, -1.123696883299492e-6), (1.2755102040816326, -2.5749667658387866e-6), (1.3010204081632653, -5.70480204599006e-6), (1.3265306122448979, -1.2220464827582253e-5), (1.3520408163265305, -2.531247480206961e-5), (1.3775510204081631, -5.069850309492639e-5), (1.4030612244897958, -9.819256552437341e-5), (1.4285714285714284, -1.8390448659017395e-4), (1.454081632653061, -3.330762066794769e-4), (1.4795918367346936, -5.833650417163753e-4), (1.5051020408163263, -9.8807834237052e-4), (1.5306122448979589, -0.001618472171445976), (1.5561224489795915, -0.0025638388059825985), (1.5816326530612241, -0.003927863989816029), (1.6071428571428568, -0.005819831283556752), (1.6326530612244894, -0.008339881000982728), (1.658163265306122, -0.011558769654206626), (1.6836734693877546, -0.015494308354153143), (1.7091836734693873, -0.02008850084337135), (1.73469387755102, -0.025190871516857616), (1.7602040816326525, -0.030553756123198477), (1.7857142857142851, -0.03584404966066722), (1.8112244897959178, -0.040672967700428275), (1.8367346938775504, -0.04464118393086191), (1.862244897959183, -0.047392712128477496), (1.8877551020408156, -0.048667403362887635), (1.9132653061224483, -0.048341494285878264), (1.938775510204081, -0.04644739000778679), (1.9642857142857135, -0.043168390293742316), (1.9897959183673462, -0.0388094755730579), (2.0153061224489788, -0.03375052221907117), (2.0408163265306114, -0.02839209067703472), (2.066326530612244, -0.023104245646230648), (2.0918367346938767, -0.01818725699718267), (2.1173469387755093, -0.013849270759480073), (2.142857142857142, -0.010201733597436358), (2.1683673469387745, -0.007269616609175294), (2.193877551020407, -0.005011210495189995), (2.21938775510204, -0.0033417192031464896), (2.2448979591836724, -0.0021557351734376256), (2.270408163265305, -0.0013453062176115673), (2.2959183673469377, -8.121742663131631e-4), (2.3214285714285703, -4.7433135191915683e-4), (2.346938775510203, -2.6799188013374266e-4), (2.3724489795918355, -1.464781343401766e-4), (2.397959183673468, -7.745339273024636e-5), (2.423469387755101, -3.9621374769542025e-5), (2.4489795918367334, -1.9608458558430508e-5), (2.474489795918366, -9.38818477949983e-6), (2.4999999999999987, -4.3484671364929225e-6), ] np.testing.assert_allclose(expected, list(zip(freqs, refl_flux)), rtol=1e-6)
def main(args): resolution = 20 # pixels/um 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 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), component=mp.Hz, center=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), component=mp.Ey, center=mp.Vector3(-0.5*sx+dpml), 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), 1e-3)) sim.display_fluxes(trans) # print out the flux spectrum
def test_farfield(self): resolution = 50 sxy = 4 dpml = 1 cell = mp.Vector3(sxy+2*dpml,sxy+2*dpml,0) pml_layers = mp.PML(dpml) fcen = 1.0 df = 0.4 sources = mp.Source(src=mp.GaussianSource(fcen,fwidth=df), center=mp.Vector3(), component=mp.Ez) symmetries = [mp.Mirror(mp.X), mp.Mirror(mp.Y)] sim = mp.Simulation(cell_size=cell, resolution=resolution, sources=[sources], symmetries=symmetries, boundary_layers=[pml_layers]) nearfield_box = sim.add_near2far(fcen, 0, 1, mp.Near2FarRegion(mp.Vector3(y=0.5*sxy), size=mp.Vector3(sxy)), mp.Near2FarRegion(mp.Vector3(y=-0.5*sxy), size=mp.Vector3(sxy), weight=-1), mp.Near2FarRegion(mp.Vector3(0.5*sxy), size=mp.Vector3(y=sxy)), mp.Near2FarRegion(mp.Vector3(-0.5*sxy), size=mp.Vector3(y=sxy), weight=-1)) flux_box = sim.add_flux(fcen, 0, 1, mp.FluxRegion(mp.Vector3(y=0.5*sxy), size=mp.Vector3(sxy)), mp.FluxRegion(mp.Vector3(y=-0.5*sxy), size=mp.Vector3(sxy), weight=-1), mp.FluxRegion(mp.Vector3(0.5*sxy), size=mp.Vector3(y=sxy)), mp.FluxRegion(mp.Vector3(-0.5*sxy), size=mp.Vector3(y=sxy), weight=-1)) sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, mp.Vector3(), 1e-8)) near_flux = mp.get_fluxes(flux_box)[0] r = 1000/fcen # radius of far field circle npts = 100 # number of points in [0,2*pi) range of angles E = np.zeros((npts,3),dtype=np.complex128) H = np.zeros((npts,3),dtype=np.complex128) for n in range(npts): ff = sim.get_farfield(nearfield_box, mp.Vector3(r*math.cos(2*math.pi*n/npts), r*math.sin(2*math.pi*n/npts))) E[n,:] = [np.conj(ff[j]) for j in range(3)] H[n,:] = [ff[j+3] for j in range(3)] Px = np.real(np.multiply(E[:,1],H[:,2])-np.multiply(E[:,2],H[:,1])) Py = np.real(np.multiply(E[:,2],H[:,0])-np.multiply(E[:,0],H[:,2])) Pr = np.sqrt(np.square(Px)+np.square(Py)) far_flux_circle = np.sum(Pr)*2*np.pi*r/len(Pr) rr = 20/fcen # length of far field square box far_flux_square = (nearfield_box.flux(mp.Y, mp.Volume(center=mp.Vector3(y=0.5*rr), size=mp.Vector3(rr)), resolution)[0] - nearfield_box.flux(mp.Y, mp.Volume(center=mp.Vector3(y=-0.5*rr), size=mp.Vector3(rr)), resolution)[0] + nearfield_box.flux(mp.X, mp.Volume(center=mp.Vector3(0.5*rr), size=mp.Vector3(y=rr)), resolution)[0] - nearfield_box.flux(mp.X, mp.Volume(center=mp.Vector3(-0.5*rr), size=mp.Vector3(y=rr)), resolution)[0]) print("flux:, {:.6f}, {:.6f}, {:.6f}".format(near_flux,far_flux_circle,far_flux_square)) self.assertAlmostEqual(near_flux, far_flux_circle, places=2) self.assertAlmostEqual(far_flux_circle, far_flux_square, places=2) self.assertAlmostEqual(far_flux_square, near_flux, places=2)
def test_mode_decomposition(self): resolution = 10 w1 = 1 w2 = 2 Lw = 2 dair = 3.0 dpml = 5.0 sy = dpml + dair + w2 + dair + dpml half_w1 = 0.5 * w1 half_w2 = 0.5 * w2 Si = mp.Medium(epsilon=12.0) boundary_layers = [mp.PML(dpml)] lcen = 6.67 fcen = 1 / lcen symmetries = [mp.Mirror(mp.Y)] Lt = 2 sx = dpml + Lw + Lt + Lw + dpml cell_size = mp.Vector3(sx, sy, 0) prism_x = sx + 1 half_Lt = 0.5 * Lt src_pt = mp.Vector3(-0.5 * sx + dpml + 0.2 * Lw, 0, 0) sources = [mp.EigenModeSource(src=mp.GaussianSource(fcen, fwidth=0.2 * fcen), component=mp.Ez, center=src_pt, size=mp.Vector3(0, sy - 2 * dpml, 0), eig_match_freq=True, eig_parity=mp.ODD_Z + mp.EVEN_Y)] vertices = [mp.Vector3(-prism_x, half_w1), mp.Vector3(prism_x, half_w1), mp.Vector3(prism_x, -half_w1), mp.Vector3(-prism_x, -half_w1)] sim = mp.Simulation(resolution=resolution, cell_size=cell_size, boundary_layers=boundary_layers, geometry=[mp.Prism(vertices, height=mp.inf, material=Si)], sources=sources, symmetries=symmetries) mon_pt = mp.Vector3(-0.5 * sx + dpml + 0.5 * Lw, 0, 0) flux = sim.add_flux(fcen, 0, 1, mp.FluxRegion(center=mon_pt, size=mp.Vector3(0, sy - 2 * dpml, 0))) sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, src_pt, 1e-9)) res = sim.get_eigenmode_coefficients(flux, [1], eig_parity=mp.ODD_Z + mp.EVEN_Y) incident_coeffs = res.alpha incident_flux = mp.get_fluxes(flux) incident_flux_data = sim.get_flux_data(flux) sim.reset_meep() vertices = [mp.Vector3(-prism_x, half_w1), mp.Vector3(-half_Lt, half_w1), mp.Vector3(half_Lt, half_w2), mp.Vector3(prism_x, half_w2), mp.Vector3(prism_x, -half_w2), mp.Vector3(half_Lt, -half_w2), mp.Vector3(-half_Lt, -half_w1), mp.Vector3(-prism_x, -half_w1)] sim = mp.Simulation(resolution=resolution, cell_size=cell_size, boundary_layers=boundary_layers, geometry=[mp.Prism(vertices, height=mp.inf, material=Si)], sources=sources, symmetries=symmetries) refl_flux = sim.add_flux(fcen, 0, 1, mp.FluxRegion(center=mon_pt, size=mp.Vector3(0, sy - 2 * dpml, 0))) sim.load_minus_flux_data(refl_flux, incident_flux_data) sim.run(until_after_sources=mp.stop_when_fields_decayed(50, mp.Ez, src_pt, 1e-9)) res = sim.get_eigenmode_coefficients(refl_flux, [1], eig_parity=mp.ODD_Z + mp.EVEN_Y) coeffs = res.alpha taper_flux = mp.get_fluxes(refl_flux) self.assertAlmostEqual(abs(coeffs[0, 0, 1])**2 / abs(incident_coeffs[0, 0, 0])**2, -taper_flux[0] / incident_flux[0], places=4)