#The waveguide is specified by a Block (parallelepiped) of size ∞×1×∞, with ε=12 #centered at (0,0) which is the center of the cell. By default, any place where #there are no objects there is air (ε=1) sources = [ mp.Source(mp.ContinuousSource(frequency=0.15), component=mp.Ez, center=mp.Vector3(-7, 0)) ] #We gave the source a frequency of 0.15, and specified a ContinuousSource which is #just a fixed-frequency sinusoid exp(−iωt) that by default is turned on at t=0 # frequency is specified in units of 2πc, which is equivalent to the inverse of the #vacuum wavelength. Thus, 0.15 corresponds to a vacuum wavelength of about 1/0.15=6.67 μm, #or a wavelength of about 2 μm in the ε=12 material pml_layers = [mp.PML(1.0)] #boundry conditions that absorb around the cell #absorbing boundries handled by perfectly matched layers (PML) #this adds absorbing layer thickness of 1 um around all sides of cell resolution = 10 #this gives resolution of 10 pixels per um sim = mp.Simulation(cell_size=cell, boundary_layers=pml_layers, geometry=geometry, sources=sources, resolution=resolution) #this is the simulation based on all previously defined objects sim.run(until=200)
w2 = 2.0 # width of waveguide 2 Lw = 10.0 # length of waveguides 1 and 2 # lengths of waveguide taper Lts = [2**m for m in range(5)] dair = 3.0 # length of air region dpml_x = 6.0 # length of PML in x direction dpml_y = 2.0 # length of PML in y direction sy = dpml_y + dair + w2 + dair + dpml_y Si = mp.Medium(epsilon=12.0) boundary_layers = [ mp.PML(dpml_x, direction=mp.X), mp.PML(dpml_y, direction=mp.Y) ] lcen = 6.67 # mode wavelength fcen = 1 / lcen # mode frequency symmetries = [mp.Mirror(mp.Y)] R_coeffs = [] R_flux = [] for Lt in Lts: sx = dpml_x + Lw + Lt + Lw + dpml_x cell_size = mp.Vector3(sx, sy, 0)
def __init__(self, dir_name, wavelength, thy_absorb, cyt_absorb): self.base_directory = base_directory + str(dir_name) self.wavelength = wavelength self.thy_absorb = thy_absorb self.cyt_absorb = cyt_absorb self.frequency = 1 / wavelength # Calculate wavelengths dependent on RI self.wavelength_in_media = wavelength / ri_media self.wavelength_in_cytoplasm = wavelength / ri_cytoplasm self.wavelength_in_thylakoid = wavelength / ri_thylakoid max_freq = self.frequency - 0.01 min_freq = self.frequency + 0.01 self.pulse_width = abs(max_freq - min_freq) cell = mp.Vector3(sxx, sxy, 0) pml_layers = [mp.PML(dpml)] thylakoid_material = mp.Medium(index=ri_thylakoid, D_conductivity=2 * math.pi * self.frequency * (thy_absorb / (ri_thylakoid**2))) cytoplasm_material = mp.Medium(index=ri_cytoplasm, D_conductivity=2 * math.pi * self.frequency * (cyt_absorb / (ri_cytoplasm**2))) thylakoid_region = mp.Sphere(radius=cell_radius, center=mp.Vector3(0, 0), material=thylakoid_material) cytoplasm_region = mp.Sphere(radius=cell_radius - thylakoid_thickness, center=mp.Vector3(0, 0), material=cytoplasm_material) geometry = [thylakoid_region, cytoplasm_region] # Sources kdir = mp.Vector3(1, 0, 0) # direction of k (length is irrelevant) n = ri_media # refractive index of material containing the source k = kdir.unit().scale(2 * math.pi * self.frequency * n) # k with correct length def pw_amp(k, x0): def _pw_amp(x): return cmath.exp(1j * k.dot(x + x0)) return _pw_amp source = [ mp.Source( mp.ContinuousSource(frequency=self.frequency, fwidth=self.pulse_width), # along x axis component=mp.Ez, center=mp.Vector3(-0.5 * simulation_size, 0), # x, ,y ,z size=mp.Vector3(0, sxy, 0), amp_func=pw_amp(k, mp.Vector3(x=-0.5 * simulation_size))) ] sim = mp.Simulation( cell_size=cell, sources=source, boundary_layers=pml_layers, resolution=resolution, geometry=geometry, default_material=mp.Medium(index=ri_media), force_complex_fields=complex_f, eps_averaging=eps_av, ) sim.use_output_directory(self.base_directory) sim.run(mp.at_every( 0.6, mp.output_png(mp.Ez, "-Zc/data/home/bt16268/simInput/customColour.txt")), until=t)
pos_z = height + 0.005 pt = mp.Vector3(pos_x, pos_y, pos_z) resolution = 150 numx = int(width_cal * resolution) numy = int(height_cal * resolution) x_list = np.linspace(-width_cal / 2, width_cal / 2, numx) y_list = np.linspace(-height_cal / 2, height_cal / 2, numy) x_grid, y_grid = np.meshgrid(x_list, y_list) # %% cell_size = mp.Vector3(length_cal, width_cal, height_cal) pml_layers = [ mp.Absorber(thickness=t_pml, direction=mp.Y), mp.PML(thickness=t_pml, direction=mp.Z), mp.PML(thickness=t_pml, direction=mp.X) ] # Y dipole source = [ mp.Source(mp.ContinuousSource(frequency=omega), component=mp.Ey, center=pt) ] # We first calculate the normalized power sim0 = mp.Simulation(resolution=resolution, cell_size=cell_size, boundary_layers=pml_layers, default_material=mp.Medium(index=index_SiN), sources=source, eps_averaging=False,
from autograd import numpy as npa from autograd import tensor_jacobian_product import unittest from enum import Enum MonitorObject = Enum('MonitorObject', 'EIGENMODE DFT') resolution = 25 silicon = mp.Medium(epsilon=12) sxy = 5.0 cell_size = mp.Vector3(sxy,sxy,0) dpml = 1.0 boundary_layers = [mp.PML(thickness=dpml)] eig_parity = mp.EVEN_Y + mp.ODD_Z design_shape = mp.Vector3(1.5,1.5) design_region_resolution = int(2*resolution) Nx = int(design_region_resolution*design_shape.x) Ny = int(design_region_resolution*design_shape.y) ## ensure reproducible results np.random.seed(9861548) ## random design region p = np.random.rand(Nx*Ny) ## random epsilon perturbation for design region
def main(): n = 3.4 # index of waveguide r = 1 a = r # inner radius of ring w = 1 # width of waveguide b = a + w # outer radius of ring pad = 4 # padding between waveguide and edge of PML dpml = 2 # thickness of PML pml_layers = [mp.PML(dpml)] resolution = 100 sr = b + pad + dpml # radial size (cell is from 0 to sr) dimensions = mp.CYLINDRICAL # coordinate system is (r,phi,z) instead of (x,y,z) cell = mp.Vector3(sr, 0, 0) m = 4 geometry = [ mp.Block(center=mp.Vector3(a + (w / 2)), size=mp.Vector3(w, 1e20, 1e20), material=mp.Medium(index=n)) ] # Finding a resonance mode with a high Q-value (calculated with Harminv) fcen = 0.15 # pulse center frequency df = 0.1 # pulse width (in frequency) sources = [ mp.Source(mp.GaussianSource(fcen, fwidth=df), mp.Hz, mp.Vector3(r + 0.1), amplitude=1) ] sim = mp.Simulation(cell_size=cell, geometry=geometry, boundary_layers=pml_layers, resolution=resolution, sources=sources, dimensions=dimensions, m=m) h = mp.Harminv(mp.Hz, mp.Vector3(r + 0.1), fcen, df) sim.run(mp.after_sources(h), until_after_sources=200) Harminv_freq_at_R = h.modes[0].freq sim.reset_meep() # now running the simulation that will be used with perturbation theory to calculate dw/dR fcen = Harminv_freq_at_R df = 0.01 sources = [ mp.Source(mp.GaussianSource(fcen, fwidth=df), mp.Hz, mp.Vector3(r + 0.1), amplitude=1) ] sim = mp.Simulation(cell_size=cell, geometry=geometry, boundary_layers=pml_layers, resolution=resolution, sources=sources, dimensions=dimensions, m=m) sim.run(until_after_sources=200) # now need to calculate the surface integrals that go into dw/dR. Fields parallel and perpendicular to the interface # AND at the inner and outer surfaces are treated differently, so each will be calculated separately. # section for fields at inner surface npts_inner = 10 angles_inner = 2 * np.pi / npts_inner * np.arange(npts_inner) deps_inner = 1 - n**2 deps_inv_inner = 1 - 1 / (n**2) # section for fields parallel to interface (Ez and Ep) parallel_fields_inner = [] for angle in angles_inner: point = mp.Vector3(a, angle) e_z_field = abs(sim.get_field_point(mp.Ez, point))**2 e_p_field = abs(sim.get_field_point(mp.Ep, point))**2 e_parallel_field = e_z_field + e_p_field # fields have to be multiplied by Δε e_parallel_field = deps_inner * e_parallel_field parallel_fields_inner.append(e_parallel_field) # section for fields perpendicular to interface (Er) perpendicular_fields_inner = [] for angle in angles_inner: point = mp.Vector3(a, angle) e_r_field = abs(sim.get_field_point(mp.Er, point))**2 e_perpendicular_field = e_r_field # fields have to be multiplied by Δ(1/ε) and ε**2 e_perpendicular_field = deps_inv_inner * (abs( sim.get_epsilon_point(point, Harminv_freq_at_R))** 2) * e_perpendicular_field perpendicular_fields_inner.append(e_perpendicular_field) # section for fields at outer surface npts_outer = npts_inner angles_outer = 2 * np.pi / npts_outer * np.arange(npts_outer) deps_outer = n**2 - 1 deps_inv_outer = -1 + 1 / (n**2) # section for fields parallel to interface (Ez and Ep) parallel_fields_outer = [] parallel_fields_outer = [] for angle in angles_outer: point = mp.Vector3(b, angle) e_z_field = abs(sim.get_field_point(mp.Ez, point))**2 e_p_field = abs(sim.get_field_point(mp.Ep, point))**2 e_parallel_field = e_z_field + e_p_field # fields have to be multiplied by Δε e_parallel_field = deps_outer * e_parallel_field parallel_fields_outer.append(e_parallel_field) # section for fields perpendicular to interface (Er) perpendicular_fields_outer = [] for angle in angles_inner: point = mp.Vector3(b, angle) e_r_field = abs(sim.get_field_point(mp.Er, point)) e_perpendicular_field = e_r_field**2 # fields have to be multiplied by Δ(1/ε) and ε**2 e_perpendicular_field = deps_inv_outer * (abs( sim.get_epsilon_point(point, Harminv_freq_at_R))** 2) * e_perpendicular_field perpendicular_fields_outer.append(e_perpendicular_field) numerator_surface_integral = 2 * np.pi * b * ( mean([mean(parallel_fields_inner), mean(parallel_fields_outer)]) - mean([ mean(perpendicular_fields_inner), mean(perpendicular_fields_outer) ])) denominator_surface_integral = sim.electric_energy_in_box( center=mp.Vector3((b + pad / 2) / 2), size=mp.Vector3(b + pad / 2)) perturb_theory_dw_dR = -Harminv_freq_at_R * numerator_surface_integral / ( 4 * denominator_surface_integral) center_diff_dw_dR = [] Harminv_freqs_at_R_plus_dR = [] drs = np.logspace(start=-3, stop=-1, num=10) for dr in drs: sim.reset_meep() w = 1 + dr # width of waveguide b = a + w print(f'The current dr is dr={dr}') if len(Harminv_freqs_at_R_plus_dR) == 0: fcen = Harminv_freq_at_R else: fcen = Harminv_freqs_at_R_plus_dR[-1] df = 0.01 sources = [ mp.Source(mp.GaussianSource(fcen, fwidth=df), mp.Hz, mp.Vector3(r + 0.1)) ] geometry = [ mp.Block(center=mp.Vector3(a + (w / 2)), size=mp.Vector3(w, 1e20, 1e20), material=mp.Medium(index=n)) ] sim = mp.Simulation(cell_size=cell, geometry=geometry, boundary_layers=pml_layers, resolution=resolution, sources=sources, dimensions=dimensions, m=m) h = mp.Harminv(mp.Hz, mp.Vector3(r + 0.1), fcen, df) sim.run(mp.after_sources(h), until_after_sources=200) Harminv_freq_at_R_plus_dR = h.modes[0].freq Harminv_freqs_at_R_plus_dR.append(Harminv_freq_at_R_plus_dR) dw_dR = (Harminv_freq_at_R_plus_dR - Harminv_freq_at_R) / dr center_diff_dw_dR.append(dw_dR) relative_errors_dw_dR = [ abs((dw_dR - perturb_theory_dw_dR) / dw_dR) for dw_dR in center_diff_dw_dR ] perturb_predicted_freqs_at_R_plus_dR = [ dr * perturb_theory_dw_dR + Harminv_freq_at_R for dr in drs ] relative_errors_freqs_at_R_plus_dR = [ abs((perturb_predicted_freqs_at_R_plus_dR[i] - Harminv_freqs_at_R_plus_dR[i]) / Harminv_freqs_at_R_plus_dR[i]) for i in range(len(Harminv_freqs_at_R_plus_dR)) ] if mp.am_master(): plt.figure(dpi=150) plt.loglog(drs, relative_errors_dw_dR, 'bo-', label='relative error') plt.grid(True, which='both', ls='-') plt.xlabel('perturbation amount $dr$') plt.ylabel('relative error between $dω/dR$') plt.legend(loc='upper right') plt.title( 'Comparison of Perturbation Theory and \nCenter-Difference Calculations in Finding $dω/dR$' ) plt.tight_layout() # plt.show() plt.savefig('ring_Hz_perturbation_theory.dw_dR_error.png') plt.clf() plt.figure(dpi=150) plt.loglog(drs, relative_errors_freqs_at_R_plus_dR, 'bo-', label='relative error') plt.grid(True, which='both', ls='-') plt.xlabel('perturbation amount $dr$') plt.ylabel('relative error between $ω(R+dR)$') plt.legend(loc='upper left') plt.title( 'Comparison of resonance frequencies at $R+dR$ predicted by\nperturbation theory and found with Harminv' ) plt.tight_layout() # plt.show() plt.savefig('ring_Hz_perturbation_theory.freqs_error.png') plt.clf()
def setup_sim(zDim=0): cell = mp.Vector3(16, 8, zDim) # A simple waveguide geometry = [ mp.Block(mp.Vector3(mp.inf, 1, 1), center=mp.Vector3(), material=mp.Medium(epsilon=12)) ] # Add point sources sources = [ mp.Source(mp.ContinuousSource(frequency=0.15), component=mp.Ez, center=mp.Vector3(-5, 0), size=mp.Vector3(0, 0, 2)), mp.Source(mp.ContinuousSource(frequency=0.15), component=mp.Ez, center=mp.Vector3(0, 2), size=mp.Vector3(0, 0, 2)), mp.Source(mp.ContinuousSource(frequency=0.15), component=mp.Ez, center=mp.Vector3(-1, 1), size=mp.Vector3(0, 0, 2)), mp.Source(mp.ContinuousSource(frequency=0.15), component=mp.Ez, center=mp.Vector3(-2, -2, 1), size=mp.Vector3(0, 0, 0)), ] # Add line sources sources += [ mp.Source(mp.ContinuousSource(frequency=0.15), component=mp.Ez, size=mp.Vector3(0, 2, 2), center=mp.Vector3(-6, 0)), mp.Source(mp.ContinuousSource(frequency=0.15), component=mp.Ez, size=mp.Vector3(0, 2, 2), center=mp.Vector3(0, 1)) ] # Add plane sources sources += [ mp.Source(mp.ContinuousSource(frequency=0.15), component=mp.Ez, size=mp.Vector3(2, 2, 2), center=mp.Vector3(-3, 0)), mp.Source(mp.ContinuousSource(frequency=0.15), component=mp.Ez, size=mp.Vector3(2, 2, 2), center=mp.Vector3(0, -2)) ] # Different pml layers pml_layers = [ mp.PML(2.0, mp.X), mp.PML(1.0, mp.Y, mp.Low), mp.PML(1.5, mp.Y, mp.High), mp.PML(1.5, mp.Z) ] resolution = 10 sim = mp.Simulation(cell_size=cell, boundary_layers=pml_layers, geometry=geometry, sources=sources, resolution=resolution) # Line monitor sim.add_flux( 1, 0, 1, mp.FluxRegion(center=mp.Vector3(5, 0, 0), size=mp.Vector3(0, 4, 4), direction=mp.X)) # Plane monitor sim.add_flux( 1, 0, 1, mp.FluxRegion(center=mp.Vector3(2, 0, 0), size=mp.Vector3(4, 4, 4), direction=mp.X)) return sim
def main(args): resolution = 30 nSi = 3.45 Si = mp.Medium(index=nSi) dpml = 1.0 sx = 5 sy = 3 cell = mp.Vector3(sx + 2 * dpml, sy + 2 * dpml) pml_layers = mp.PML(dpml) a = 1.0 # waveguide width s = args.s # waveguide separation distance geometry = [ mp.Block(center=mp.Vector3(-0.5 * (s + a)), size=mp.Vector3(a, a, 1e20), material=Si), mp.Block(center=mp.Vector3(0.5 * (s + a)), size=mp.Vector3(a, a, 1e20), material=Si) ] xodd = args.xodd symmetries = [ mp.Mirror(mp.X, phase=-1.0 if xodd else 1.0), mp.Mirror(mp.Y, phase=-1.0) ] beta = 0.5 k_point = mp.Vector3(z=beta) fcen = 0.22 df = 0.06 sources = [ mp.Source(src=mp.GaussianSource(fcen, fwidth=df), component=mp.Ey, center=mp.Vector3(-0.5 * (s + a)), size=mp.Vector3(a, a)), mp.Source(src=mp.GaussianSource(fcen, fwidth=df), component=mp.Ey, center=mp.Vector3(0.5 * (s + a)), size=mp.Vector3(a, a), amplitude=-1.0 if xodd else 1.0) ] sim = mp.Simulation(resolution=resolution, cell_size=cell, boundary_layers=[pml_layers], geometry=geometry, symmetries=symmetries, k_point=k_point, sources=sources, dimensions=3) h = mp.Harminv(mp.Ey, mp.Vector3(0.5 * (s + a)), fcen, df) sim.run(mp.after_sources(h), until_after_sources=200) f = h.modes[0].freq print("freq:, {}, {}".format(s, f)) sim.reset_meep() new_sources = [ mp.EigenModeSource(src=mp.GaussianSource(f, fwidth=df), component=mp.Ey, size=mp.Vector3(a, a), center=mp.Vector3(-0.5 * (s + a)), eig_kpoint=k_point, eig_match_freq=True, eig_parity=mp.ODD_Y), mp.EigenModeSource(src=mp.GaussianSource(f, fwidth=df), component=mp.Ey, size=mp.Vector3(a, a), center=mp.Vector3(0.5 * (s + a)), eig_kpoint=k_point, eig_match_freq=True, eig_parity=mp.ODD_Y, amplitude=-1.0 if xodd else 1.0) ] sim.change_sources(new_sources) flx_reg = mp.FluxRegion(direction=mp.Z, center=mp.Vector3(), size=mp.Vector3(1.2 * (2 * a + s), 1.2 * a)) wvg_pwr = sim.add_flux(f, 0, 1, flx_reg) frc_reg1 = mp.ForceRegion(mp.Vector3(0.5 * s), mp.X, weight=1.0, size=mp.Vector3(y=a)) frc_reg2 = mp.ForceRegion(mp.Vector3(0.5 * s + a), mp.X, weight=-1.0, size=mp.Vector3(y=a)) wvg_force = sim.add_force(f, 0, 1, frc_reg1, frc_reg2) runtime = 5000 sim.run(until_after_sources=runtime) sim.display_fluxes(wvg_pwr) sim.display_forces(wvg_force)
def diff(ht,wvl_cen): import meep as mp import numpy as np import math import random #450 1.674 #550 1.642 #650 1.629 if (wvl_cen == 0.45): photoresist = mp.Medium(index=1.674) #波长为450nm时光刻胶的折射率 elif (wvl_cen == 0.55): photoresist = mp.Medium(index=1.642) #波长为550nm时光刻胶的折射率 else: photoresist = mp.Medium(index=1.629) #波长为650nm时光刻胶的折射率 ## at least 8 pixels per smallest wavelength, i.e. np.floor(8/wvl_min) resolution = 25.0 dpml=1.0 #PML厚度 dpad =2.0 #透镜与PML间距 dsub = 2.0 # substrate thickness width = 0.5 #环的宽度 r= width*len(ht) #透镜的半径 50um focal_length = 100.0 #焦距 spot_length=100 #far-field line length ff_res = 10.0 #far-field resoluton h = 1.25 NA = math.sin(math.atan(r/focal_length)) NA = round(NA, 3) pml_layers = [mp.PML(thickness=dpml)] sr=r+dpad+dpml sz=dpml+dpad+h+dpad+dpml #sz=dpml+dsub+h+dpad+dpml cell_size =mp.Vector3(sr,0,sz) #glass = mp.Medium(index=1.5) # substrate #geometry = [mp.Block(material=glass, # size=mp.Vector3(sr,0,dpml+dsub), # center=mp.Vector3(0.5*sr,0,-0.5*sz+0.5*(dpml+dsub)))] # #for n in range (len(ht)): # geometry.append(mp.Block(material=photoresist, # size=mp.Vector3(width,0,ht[n]), # center=mp.Vector3(width*n+0.5*width,0,-0.5*sz+dpml+dsub+0.5*ht[n]))) #透镜的结构 #geometry = [mp.Block(material=photoresist, # size=mp.Vector3(width,0,ht[0]), # center=mp.Vector3(0.5*width,0,-0.5*sz+dpml+dpad+0.5*ht[0]))] #for n in range (1,len(ht)): # geometry.append(mp.Block(material=photoresist, # size=mp.Vector3(width,0,ht[n]), # center=mp.Vector3(width*n+0.5*width,0,-0.5*sz+dpml+dpad+0.5*ht[n]))) #透镜的结构 geometry = [mp.Block(material=photoresist, size=mp.Vector3(sr,0,dpml+dsub), center=mp.Vector3(0.5*sr,0,-0.5*sz+0.5*(dpml+dsub)))] for n in range (0,len(ht)): geometry.append(mp.Block(material=photoresist, size=mp.Vector3(width,0,ht[n]), center=mp.Vector3((width*(n)+0.5*width),0,-0.5*sz+dpml+dsub+0.5*ht[n]))) #透镜的结构 #wvl_cen = 0.5 frq_cen = 1/wvl_cen dfrq = 0.2*frq_cen sources = [mp.Source(mp.GaussianSource(frq_cen,fwidth=dfrq,is_integrated=True), component=mp.Er, center=mp.Vector3(0.5*(sr),0,-0.5*sz+dpml), size=mp.Vector3(sr)), mp.Source(mp.GaussianSource(frq_cen,fwidth=dfrq,is_integrated=True), component=mp.Ep, center=mp.Vector3(0.5*(sr),0,-0.5*sz+dpml), size=mp.Vector3(sr), amplitude=-1j)] sim = mp.Simulation(cell_size=cell_size, boundary_layers=pml_layers, resolution=resolution, sources=sources, geometry=geometry, dimensions=mp.CYLINDRICAL, m=-1) ## near-field monitor n2f_obj = sim.add_near2far(frq_cen, 0, 1, mp.Near2FarRegion(center=mp.Vector3(0.5*(sr-dpml),0,0.5*sz-dpml),size=mp.Vector3(sr-dpml))) # mp.Near2FarRegion(center=mp.Vector3(sr-dpml,0,0.5*sz-0.5*(dsub+zh+dpad)),size=mp.Vector3(z=dsub+zh+dpad))) sim.run(until_after_sources=100) ff_r = sim.get_farfields(n2f_obj, ff_res, center=mp.Vector3(0.5*(sr-dpml),0,-0.5*sz+dpml+dsub+h+focal_length),size=mp.Vector3(sr-dpml)) E2_r = np.absolute(ff_r['Ex'])**2+np.absolute(ff_r['Ey'])**2+np.absolute(ff_r['Ez'])**2 E_sum = sum(E2_r) n = round((1.5*(wvl_cen/(2*NA)))/(r/(len(E2_r)-1))) #print ('n = %d' % n) E = 0.0 for i in range (n): E += E2_r[i] return E/E_sum
def test_dft_energy(self): resolution = 20 cell = mp.Vector3(10, 5) geom = [ mp.Block(size=mp.Vector3(mp.inf, 1, mp.inf), material=mp.Medium(epsilon=12)) ] pml = [mp.PML(1)] fsrc = 0.15 sources = [ mp.EigenModeSource(src=mp.GaussianSource(frequency=fsrc, fwidth=0.2 * fsrc), center=mp.Vector3(-3), size=mp.Vector3(y=5), eig_band=1, eig_parity=mp.ODD_Z + mp.EVEN_Y, eig_match_freq=True) ] sim = mp.Simulation(resolution=resolution, cell_size=cell, geometry=geom, boundary_layers=pml, sources=sources, symmetries=[mp.Mirror(direction=mp.Y)]) flux = sim.add_flux(fsrc, 0, 1, mp.FluxRegion(center=mp.Vector3(3), size=mp.Vector3(y=5)), decimation_factor=1) energy = sim.add_energy(fsrc, 0, 1, mp.EnergyRegion(center=mp.Vector3(3), size=mp.Vector3(y=5)), decimation_factor=1) energy_decimated = sim.add_energy(fsrc, 0, 1, mp.EnergyRegion( center=mp.Vector3(3), size=mp.Vector3(y=5)), decimation_factor=10) sim.run(until_after_sources=100) res = sim.get_eigenmode_coefficients(flux, [1], eig_parity=mp.ODD_Z + mp.EVEN_Y) mode_vg = res.vgrp[0] poynting_flux = mp.get_fluxes(flux)[0] e_energy = mp.get_electric_energy(energy)[0] ratio_vg = (0.5 * poynting_flux) / e_energy m_energy = mp.get_magnetic_energy(energy)[0] t_energy = mp.get_total_energy(energy)[0] self.assertAlmostEqual(m_energy + e_energy, t_energy) self.assertAlmostEqual(ratio_vg, mode_vg, places=3) e_energy_decimated = mp.get_electric_energy(energy_decimated)[0] m_energy_decimated = mp.get_magnetic_energy(energy_decimated)[0] self.assertAlmostEqual(e_energy, e_energy_decimated, places=1) self.assertAlmostEqual(m_energy, m_energy_decimated, places=1)
def _create_boundary_layers(self): return [mp.PML(self.pml)]
def get_simulation( component: Component, extend_ports_length: Optional[float] = 4.0, layer_stack: LayerStack = LAYER_STACK, res: int = 20, t_clad_top: float = 1.0, t_clad_bot: float = 1.0, tpml: float = 1.0, clad_material: str = "SiO2", is_3d: bool = False, wl_min: float = 1.5, wl_max: float = 1.6, wl_steps: int = 50, dfcen: float = 0.2, port_source_name: str = 1, port_field_monitor_name: str = 2, port_margin: float = 0.5, distance_source_to_monitors: float = 0.2, ) -> Dict[str, Any]: """Returns Simulation dict from gdsfactory.component based on meep directional coupler example https://meep.readthedocs.io/en/latest/Python_Tutorials/GDSII_Import/ https://support.lumerical.com/hc/en-us/articles/360042095873-Metamaterial-S-parameter-extraction Args: component: gf.Component extend_ports_function: function to extend the ports for a component to ensure it goes beyond the PML layer_to_thickness: Dict of layer number (int, int) to thickness (um) res: resolution (pixels/um) For example: (10: 100nm step size) t_clad_top: thickness for cladding above core t_clad_bot: thickness for cladding below core tpml: PML thickness (um) clad_material: material for cladding is_3d: if True runs in 3D wavelengths: iterable of wavelengths to simulate dfcen: delta frequency sidewall_angle: in degrees port_source_name: input port name port_field_monitor_name: port_margin: margin on each side of the port distance_source_to_monitors: in (um) source goes before Returns: sim: simulation object Make sure you visualize the simulation region with gf.before you simulate a component .. code:: import gdsfactory as gf import gmeep as gm c = gf.components.bend_circular() margin = 2 cm = gm.add_monitors(c) gf.show(cm) """ layer_to_thickness = layer_stack.get_layer_to_thickness() layer_to_material = layer_stack.get_layer_to_material() layer_to_zmin = layer_stack.get_layer_to_zmin() layer_to_sidewall_angle = layer_stack.get_layer_to_sidewall_angle() wavelengths = np.linspace(wl_min, wl_max, wl_steps) if port_source_name not in component.ports: warnings.warn( f"port_source_name={port_source_name} not in {component.ports.keys()}" ) port_source = component.get_ports_list()[0] port_source_name = port_source.name warnings.warn(f"Selecting port_source_name={port_source_name} instead.") if port_field_monitor_name not in component.ports: warnings.warn( f"port_field_monitor_name={port_field_monitor_name} not in {component.ports.keys()}" ) port_field_monitor = ( component.get_ports_list()[0] if len(component.ports) < 2 else component.get_ports_list()[1] ) port_field_monitor_name = port_field_monitor.name warnings.warn( f"Selecting port_field_monitor_name={port_field_monitor_name} instead." ) assert isinstance( component, Component ), f"component needs to be a gf.Component, got Type {type(component)}" component_extended = ( gf.components.extension.extend_ports( component=component, length=extend_ports_length, centered=True ) if extend_ports_length else component ) component = component.ref() component.x = 0 component.y = 0 gf.show(component_extended) component_extended.flatten() component_extended = component_extended.ref() # geometry_center = [component_extended.x, component_extended.y] # geometry_center = [0, 0] # print(geometry_center) layers_thickness = [ layer_to_thickness[layer] for layer in component.get_layers() if layer in layer_to_thickness ] t_core = max(layers_thickness) cell_thickness = tpml + t_clad_bot + t_core + t_clad_top + tpml if is_3d else 0 cell_size = mp.Vector3( component.xsize + 2 * tpml, component.ysize + 2 * tpml, cell_thickness, ) geometry = [] layer_to_polygons = component_extended.get_polygons(by_spec=True) for layer, polygons in layer_to_polygons.items(): if layer in layer_to_thickness and layer in layer_to_material: height = layer_to_thickness[layer] if is_3d else mp.inf zmin_um = layer_to_zmin[layer] if is_3d else 0 # center = mp.Vector3(0, 0, (zmin_um + height) / 2) for polygon in polygons: vertices = [mp.Vector3(p[0], p[1], zmin_um) for p in polygon] material_name = layer_to_material[layer] material = get_material(name=material_name) geometry.append( mp.Prism( vertices=vertices, height=height, sidewall_angle=layer_to_sidewall_angle[layer], material=material, # center=center ) ) freqs = 1 / wavelengths fcen = np.mean(freqs) frequency_width = dfcen * fcen # Add source port = component.ports[port_source_name] angle = port.orientation width = port.width + 2 * port_margin size_x = width * abs(np.sin(angle * np.pi / 180)) size_y = width * abs(np.cos(angle * np.pi / 180)) size_x = 0 if size_x < 0.001 else size_x size_y = 0 if size_y < 0.001 else size_y size_z = cell_thickness - 2 * tpml if is_3d else 20 size = [size_x, size_y, size_z] center = port.center.tolist() + [0] # (x, y, z=0) field_monitor_port = component.ports[port_field_monitor_name] field_monitor_point = field_monitor_port.center.tolist() + [0] # (x, y, z=0) sources = [ mp.EigenModeSource( src=mp.GaussianSource(fcen, fwidth=frequency_width), size=size, center=center, eig_band=1, eig_parity=mp.NO_PARITY if is_3d else mp.EVEN_Y + mp.ODD_Z, eig_match_freq=True, ) ] sim = mp.Simulation( resolution=res, cell_size=cell_size, boundary_layers=[mp.PML(tpml)], sources=sources, geometry=geometry, default_material=get_material(name=clad_material), # geometry_center=geometry_center, ) # Add port monitors dict monitors = {} for port_name in component.ports.keys(): port = component.ports[port_name] angle = port.orientation width = port.width + 2 * port_margin size_x = width * abs(np.sin(angle * np.pi / 180)) size_y = width * abs(np.cos(angle * np.pi / 180)) size_x = 0 if size_x < 0.001 else size_x size_y = 0 if size_y < 0.001 else size_y size = mp.Vector3(size_x, size_y, size_z) size = [size_x, size_y, size_z] # if monitor has a source move monitor inwards length = -distance_source_to_monitors if port_name == port_source_name else 0 xy_shifted = move_polar_rad_copy( np.array(port.center), angle=angle * np.pi / 180, length=length ) center = xy_shifted.tolist() + [0] # (x, y, z=0) m = sim.add_mode_monitor(freqs, mp.ModeRegion(center=center, size=size)) m.z = 0 monitors[port_name] = m return dict( sim=sim, cell_size=cell_size, freqs=freqs, monitors=monitors, sources=sources, field_monitor_point=field_monitor_point, port_source_name=port_source_name, )
from __future__ import division, print_function import meep as mp import math 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 src_cmpt = mp.Ez sources = mp.Source(src=mp.GaussianSource(fcen, fwidth=df), center=mp.Vector3(), component=src_cmpt) if src_cmpt == mp.Ex: symmetries = [mp.Mirror(mp.Y)] elif src_cmpt == mp.Ey: symmetries = [mp.Mirror(mp.X)] elif src_cmpt == mp.Ez: symmetries = [mp.Mirror(mp.X), mp.Mirror(mp.Y)] sim = mp.Simulation(cell_size=cell, resolution=resolution, sources=[sources], symmetries=symmetries,
sources = [ mp.Source( mp.GaussianSource(frequency=frequency, fwidth=frequencyWidth), component=mp.Ex, center=mp.Vector3(0, 0, -materialThickness / 2), ) ] geometry = [ mp.Block(mp.Vector3(mp.inf, mp.inf, materialThickness + pmlThickness), center=mp.Vector3(0, 0, materialThickness / 2 + pmlThickness / 2), material=mp.Medium(index=2)) ] pmlLayers = [mp.PML(1.0)] simulation = mp.Simulation(cell_size=cellSize, sources=sources, resolution=resolution, boundary_layers=pmlLayers, k_point=kVector) incidentRegion = mp.FluxRegion(center=mp.Vector3(0, 0, -materialThickness / 4)) incidentFluxMonitor = simulation.add_flux(frequency, frequencyWidth, numberFrequencies, incidentRegion) simulation.run(until_after_sources=mp.stop_when_fields_decayed( 20, mp.Ex, transmissionMonitorLocation, powerDecayTarget)) fieldEx = np.real( simulation.get_array(center=mp.Vector3(0, 0, 0),
import meep as mp import numpy as np import matplotlib.pyplot as plt resolution = 50 # pixels/μm cell_size = mp.Vector3(14, 14) pml_layers = [mp.PML(thickness=2)] # rotation angle (in degrees) of waveguide, counter clockwise (CCW) around z-axis rot_angle = np.radians(20) w = 1.0 # width of waveguide geometry = [ mp.Block(center=mp.Vector3(), size=mp.Vector3(mp.inf, w, mp.inf), e1=mp.Vector3(1).rotate(mp.Vector3(z=1), rot_angle), e2=mp.Vector3(y=1).rotate(mp.Vector3(z=1), rot_angle), material=mp.Medium(epsilon=12)) ] fsrc = 0.15 # frequency of eigenmode or constant-amplitude source kx = 0.4 # initial guess for wavevector in x-direction of eigenmode bnum = 1 # band number of eigenmode kpoint = mp.Vector3(kx).rotate(mp.Vector3(z=1), rot_angle) compute_flux = True # compute flux (True) or plot the field profile (False)
from __future__ import division import meep as mp import numpy as np import matplotlib.pyplot as plt import math from meep.materials import Au pml_layers = [mp.PML(0.4)] #Au = mp.Medium(index=math.pow(6.9,(1/2))) dpml = 0.4 minwavelength = 0.4 maxwavelength = 0.8 minf = 1 / maxwavelength maxf = 1 / minwavelength fcen = (maxf + minf) / 2 df = maxf - minf nfreq = 100 resolution = 100 upperside_without_flux = [] otherside_without_flux = [] upperside_with_flux = [] lightside_with_flux = [] otherside_with_flux = [] indecentflux = [] for i in (np.arange(1, 5)): r = i * 0.005 sx = 12 * r + 2 * dpml cell = mp.Vector3(sx, sx)
import meep as mp import numpy as np import matplotlib.pyplot as plt import PyMieScatt as ps r = 1.0 # radius of sphere frq_cen = 1.0 resolution = 20 # pixels/um dpml = 0.5 dair = 1.5 # at least 0.5/frq_cen padding between source and near-field monitor pml_layers = [mp.PML(thickness=dpml)] s = 2 * (dpml + dair + r) cell_size = mp.Vector3(s, s, s) # circularly-polarized source with propagation axis along x # is_integrated=True necessary for any planewave source extending into PML sources = [ mp.Source(mp.GaussianSource(frq_cen, fwidth=0.2 * frq_cen, is_integrated=True), center=mp.Vector3(-0.5 * s + dpml), size=mp.Vector3(0, s, s), component=mp.Ez), mp.Source(mp.GaussianSource(frq_cen, fwidth=0.2 * frq_cen, is_integrated=True),
from meep.simulation import at_every import numpy as np results = [] for j in range(1, 10): simruntime = 60 CdSe = mp.Medium(index=2.52) Glass = mp.Medium(index=1.5) ZnO = mp.Medium(index=2.21) celly = 4 fingersize = 0.05 * j cell = mp.Vector3(7.5, celly) polarization = mp.Ez pml_layers = [mp.Absorber(1, mp.X, mp.Low), mp.PML(1, mp.X, mp.High)] resolution = 80 sources = [ mp.Source(mp.ContinuousSource(wavelength=0.550, end_time=20), component=polarization, center=mp.Vector3(-1.5, 0)) ] # sources.append(mp.Source(mp.ContinuousSource(wavelength=0.550, end_time=20), # component=polarization, # center=mp.Vector3(-1.6, 3))) # sources.append(mp.Source(mp.ContinuousSource(wavelength=0.550, end_time=20), # component=polarization,
period_line=period_line, period_plane=period_plane, plane_center=plane_center, line_center=line_center, plane_size=plane_size, line_size=line_size, time_is_after_source=time_is_after_source, run_time=run_time, series=series, home=home) #%% LAYOUT CONFIGURATION cell_size = mp.Vector3(cell_width, cell_width, cell_width) boundary_layers = [mp.PML(thickness=pml_width)] source_center = -0.5*cell_width + pml_width sources = [mp.Source(mp.ContinuousSource(wavelength=wlen, is_integrated=is_integrated), center=mp.Vector3(source_center), size=mp.Vector3(0, cell_width, cell_width), component=mp.Ez)] symmetries = [mp.Mirror(mp.Y), mp.Mirror(mp.Z, phase=-1)] enlapsed = [] path = os.path.join(home, folder, "{}Results".format(series)) if not os.path.isdir(path): vs.new_dir(path) file = lambda f : os.path.join(path, f)
def _simulate( wlens: List[float], sim_region: goos.Box3d, pml_thickness: List[float], geometry: List[mp.GeometricObject], resolution: float, sources: List[SimSourceImpl], outputs: List[SimOutputImpl], sim_timing: SimulationTiming, adjoint_grad_val: goos.ArrayFlow.Grad = None, adjoint_sources: List[SimOutput] = None, adjoint: bool = False, ) -> Tuple[List[goos.Flow], List[SimOutput]]: """Runs Meep EM simulation. This function factors out the core Meep simulation functionality so that we can run the simulation in another process. The idea is to pickle (dill) the arguments to this function, which is sent to another process(es) to run the simulation. """ # Note that we have to compute PML here because apparently `mp.PML` is # a SWIG object, which cannot be pickled. pml_layers = [] for thickness, direction, side in zip( pml_thickness, [mp.X, mp.X, mp.Y, mp.Y, mp.Z, mp.Z], [mp.Low, mp.High, mp.Low, mp.High, mp.Low, mp.High]): pml_layers.append(mp.PML(thickness, direction=direction, side=side)) sim = mp.Simulation( cell_size=sim_region.extents, geometry_center=sim_region.center, boundary_layers=pml_layers, geometry=geometry, sources=[], resolution=resolution, force_complex_fields=adjoint, ) # Add the sources. Because the sources may depend on the permittivity # distribution, we call `init_sim` to setup permittivity and then call # `change_sources` to add the new source list. sim.init_sim() for src in sources: src.before_sim(sim) if adjoint: for out, g in zip(adjoint_sources, adjoint_grad_val): out.before_adjoint_sim(sim, g) for out in outputs: out.before_sim(sim) stop_conds = [sim_timing.max_timesteps] + [ cond.build() for cond in _generate_stopping_conds(sim_timing.stopping_conditions) ] if sim_timing.until_after_sources: sim.run(until_after_sources=stop_conds) else: sim.run(until=stop_conds) results = [out.eval(sim) for out in outputs] for out in outputs: out.after_sim() return results, outputs
def test_get_point(self): sxy = 6 # cell size dpml = 1 # thickness of PML def sinusoid(p): r = (p.x**2+p.y**2)**0.5 return mp.Medium(index=1.0+math.sin(2*math.pi*r)**2) geometry = [mp.Block(center=mp.Vector3(), size=mp.Vector3(sxy,sxy), material=sinusoid)] src = [mp.Source(mp.GaussianSource(1.0, fwidth=0.1), component=mp.Ez, center=mp.Vector3())] sim = mp.Simulation(cell_size=mp.Vector3(sxy,sxy), geometry=geometry, sources=src, k_point=mp.Vector3(), resolution=20, symmetries=[mp.Mirror(mp.X),mp.Mirror(mp.Y)], boundary_layers=[mp.PML(dpml)]) sim.run(until_after_sources=100) ## reference values for Ez and epsilon from serial run ez_ref = [ -0.0002065983, -0.0001954795, -0.0000453570, 0.0000311267, -0.0000121473, -0.0000410032, -0.0000341301, -0.0000275021, -0.0000397990, -0.0000351730, 0.0000079602, 0.0000227437, -0.0001092821, -0.0002202751, -0.0001408186, 0.0006325076, 0.0024890489, 0.0027476069, 0.0014815873, 0.0004714913, -0.0004332029, -0.0007101315, -0.0003818581, -0.0000748507, 0.0001408819, 0.0001119776, 0.0000395008, 0.0000078844, -0.0000010431 ] eps_ref = [ 1.6458346134, 1.2752837068, 1.0974010956, 1.0398089537, 1.0465784716, 1.0779924737, 1.1059439286, 1.1135579291, 1.0971979186, 1.0653178566, 1.0391657283, 1.0513779677, 1.1466009312, 1.3882154483, 1.8496939317, 2.5617731415, 3.3788212533, 3.9019494270, 3.6743431894, 2.7285622651, 1.6635165033, 1.0891237010, 1.1485969863, 1.9498398061, 3.3100416367, 3.9038800599, 2.8471862395, 1.4742605488, 1.0370162714 ] x = np.linspace(-0.865692,2.692867,29) for j in range(x.size): self.assertAlmostEqual(np.real(sim.get_field_point(mp.Ez, mp.Vector3(x[j],-0.394862))),ez_ref[j],places=10) self.assertAlmostEqual(sim.get_epsilon_point(mp.Vector3(x[j],2.967158)),eps_ref[j],places=10)
def binary_grating_diffraction(gp, gh, gdc, theta): resolution = 50 # pixels/μm dpml = 1.0 # PML thickness dsub = 3.0 # substrate thickness dpad = 3.0 # length of padding between grating and PML sx = dpml + dsub + gh + dpad + dpml sy = gp cell_size = mp.Vector3(sx, sy, 0) pml_layers = [mp.PML(thickness=dpml, direction=mp.X)] wvl = 0.5 # center wavelength fcen = 1 / wvl # center frequency df = 0.05 * fcen # frequency width ng = 1.5 glass = mp.Medium(index=ng) # rotation angle of incident planewave; counter clockwise (CCW) about Z axis, 0 degrees along +X axis theta_in = math.radians(theta) eig_parity = mp.EVEN_Z # k (in source medium) with correct length (plane of incidence: XY) k = mp.Vector3(fcen * ng).rotate(mp.Vector3(z=1), theta_in) if theta_in == 0: k = mp.Vector3() eig_parity += mp.ODD_Y def pw_amp(k, x0): def _pw_amp(x): return cmath.exp(1j * 2 * math.pi * k.dot(x + x0)) return _pw_amp src_pt = mp.Vector3(-0.5 * sx + dpml, 0, 0) sources = [ mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Hz, center=src_pt, size=mp.Vector3(0, sy, 0), amp_func=pw_amp(k, src_pt)) ] sim = mp.Simulation(resolution=resolution, cell_size=cell_size, boundary_layers=pml_layers, k_point=k, default_material=glass, sources=sources) tran_pt = mp.Vector3(0.5 * sx - dpml, 0, 0) tran_mon = sim.add_flux( fcen, 0, 1, mp.FluxRegion(center=tran_pt, size=mp.Vector3(0, sy, 0))) sim.run(until_after_sources=50) input_flux = mp.get_fluxes(tran_mon) sim.reset_meep() geometry = [ mp.Block(material=glass, size=mp.Vector3(dpml + dsub, mp.inf, mp.inf), center=mp.Vector3(-0.5 * sx + 0.5 * (dpml + dsub), 0, 0)), mp.Block(material=glass, size=mp.Vector3(gh, gdc * gp, mp.inf), center=mp.Vector3(-0.5 * sx + dpml + dsub + 0.5 * gh, 0, 0)) ] sim = mp.Simulation(resolution=resolution, cell_size=cell_size, boundary_layers=pml_layers, geometry=geometry, k_point=k, sources=sources) tran_mon = sim.add_mode_monitor( fcen, 0, 1, mp.FluxRegion(center=tran_pt, size=mp.Vector3(0, sy, 0))) sim.run(until_after_sources=100) # number of (non-evanescent) transmitted orders nm_t = np.floor((fcen - k.y) * gp) - np.ceil((-fcen - k.y) * gp) if theta_in == 0: nm_t = nm_t / 2 nm_t = int(nm_t) + 1 bands = range(1, nm_t + 1) if theta_in == 0: orders = range(0, nm_t) else: orders = range(int(np.ceil((-fcen - k.y) * gp)), int(np.floor((fcen - k.y) * gp)) + 1) eig_sum = 0 dp_sum = 0 for band, order in zip(bands, orders): res = sim.get_eigenmode_coefficients(tran_mon, [band], eig_parity=eig_parity) if res is not None: tran_eig = abs(res.alpha[0, 0, 0])**2 / input_flux[0] if theta_in == 0: tran_eig = 0.5 * tran_eig else: tran_eig = 0 eig_sum += tran_eig res = sim.get_eigenmode_coefficients( tran_mon, mp.DiffractedPlanewave((0, order, 0), mp.Vector3(0, 1, 0), 0, 1)) if res is not None: tran_dp = abs(res.alpha[0, 0, 0])**2 / input_flux[0] if (theta_in == 0) and (order == 0): tran_dp = 0.5 * tran_dp else: tran_dp = 0 dp_sum += tran_dp if theta_in == 0: err = abs(tran_eig - tran_dp) / tran_eig print("tran:, {:2d}, {:.8f}, {:2d}, {:.8f}, {:.8f}".format( band, tran_eig, order, tran_dp, err)) else: print("tran:, {:2d}, {:.8f}, {:2d}, {:.8f}".format( band, tran_eig, order, tran_dp)) flux = mp.get_fluxes(tran_mon) t_flux = flux[0] / input_flux[0] if (theta_in == 0): t_flux = 0.5 * t_flux err = abs(dp_sum - t_flux) / t_flux print("flux:, {:.8f}, {:.8f}, {:.8f}, {:.8f}".format( eig_sum, dp_sum, t_flux, err))
import math resolution = 60 # pixels/μm dpml = 1.0 # PML thickness dsub = 3.0 # substrate thickness dpad = 3.0 # padding between grating and PML gp = 10.0 # grating period gh = 0.5 # grating height gdc = 0.5 # grating duty cycle sx = dpml + dsub + gh + dpad + dpml sy = gp cell_size = mp.Vector3(sx, sy, 0) pml_layers = [mp.PML(thickness=dpml, direction=mp.X)] wvl_min = 0.4 # min wavelength wvl_max = 0.6 # max wavelength fmin = 1 / wvl_max # min frequency fmax = 1 / wvl_min # max frequency fcen = 0.5 * (fmin + fmax) # center frequency df = fmax - fmin # frequency width src_pt = mp.Vector3(-0.5 * sx + dpml + 0.5 * dsub, 0, 0) sources = [ mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ez, center=src_pt, size=mp.Vector3(0, sy, 0)) ]
def main(args): cell_zmax = 0.5 * cell_thickness if args.three_d else 0 cell_zmin = -0.5 * cell_thickness if args.three_d else 0 si_zmax = 0.5 * t_Si if args.three_d else 10 si_zmin = -0.5 * t_Si if args.three_d else -10 # read cell size, volumes for source region and flux monitors, # and coupler geometry from GDSII file upper_branch = mp.get_GDSII_prisms(silicon, gdsII_file, UPPER_BRANCH_LAYER, si_zmin, si_zmax) lower_branch = mp.get_GDSII_prisms(silicon, gdsII_file, LOWER_BRANCH_LAYER, si_zmin, si_zmax) cell = mp.GDSII_vol(gdsII_file, CELL_LAYER, cell_zmin, cell_zmax) p1 = mp.GDSII_vol(gdsII_file, PORT1_LAYER, si_zmin, si_zmax) p2 = mp.GDSII_vol(gdsII_file, PORT2_LAYER, si_zmin, si_zmax) p3 = mp.GDSII_vol(gdsII_file, PORT3_LAYER, si_zmin, si_zmax) p4 = mp.GDSII_vol(gdsII_file, PORT4_LAYER, si_zmin, si_zmax) src_vol = mp.GDSII_vol(gdsII_file, SOURCE_LAYER, si_zmin, si_zmax) # displace upper and lower branches of coupler (as well as source and flux regions) if args.d != default_d: delta_y = 0.5 * (args.d - default_d) delta = mp.Vector3(y=delta_y) p1.center += delta p2.center -= delta p3.center += delta p4.center -= delta src_vol.center += delta cell.size += 2 * delta for np in range(len(lower_branch)): lower_branch[np].center -= delta for nv in range(len(lower_branch[np].vertices)): lower_branch[np].vertices[nv] -= delta for np in range(len(upper_branch)): upper_branch[np].center += delta for nv in range(len(upper_branch[np].vertices)): upper_branch[np].vertices[nv] += delta geometry = upper_branch + lower_branch if args.three_d: oxide_center = mp.Vector3(z=-0.5 * t_oxide) oxide_size = mp.Vector3(cell.size.x, cell.size.y, t_oxide) oxide_layer = [ mp.Block(material=oxide, center=oxide_center, size=oxide_size) ] geometry = geometry + oxide_layer sources = [ mp.EigenModeSource( src=mp.GaussianSource(fcen, fwidth=df), volume=src_vol, eig_parity=mp.NO_PARITY if args.three_d else mp.EVEN_Y + mp.ODD_Z) ] sim = mp.Simulation(resolution=args.res, cell_size=cell.size, boundary_layers=[mp.PML(dpml)], sources=sources, geometry=geometry) mode1 = sim.add_mode_monitor(fcen, 0, 1, mp.ModeRegion(volume=p1)) mode2 = sim.add_mode_monitor(fcen, 0, 1, mp.ModeRegion(volume=p2)) mode3 = sim.add_mode_monitor(fcen, 0, 1, mp.ModeRegion(volume=p3)) mode4 = sim.add_mode_monitor(fcen, 0, 1, mp.ModeRegion(volume=p4)) sim.run(until_after_sources=100) # S parameters p1_coeff = sim.get_eigenmode_coefficients( mode1, [1], eig_parity=mp.NO_PARITY if args.three_d else mp.EVEN_Y + mp.ODD_Z).alpha[0, 0, 0] p2_coeff = sim.get_eigenmode_coefficients( mode2, [1], eig_parity=mp.NO_PARITY if args.three_d else mp.EVEN_Y + mp.ODD_Z).alpha[0, 0, 1] p3_coeff = sim.get_eigenmode_coefficients( mode3, [1], eig_parity=mp.NO_PARITY if args.three_d else mp.EVEN_Y + mp.ODD_Z).alpha[0, 0, 0] p4_coeff = sim.get_eigenmode_coefficients( mode4, [1], eig_parity=mp.NO_PARITY if args.three_d else mp.EVEN_Y + mp.ODD_Z).alpha[0, 0, 0] # transmittance p2_trans = abs(p2_coeff)**2 / abs(p1_coeff)**2 p3_trans = abs(p3_coeff)**2 / abs(p1_coeff)**2 p4_trans = abs(p4_coeff)**2 / abs(p1_coeff)**2 print("trans:, {:.2f}, {:.6f}, {:.6f}, {:.6f}".format( args.d, p2_trans, p3_trans, p4_trans))
def main(args): resolution = 20 # pixels/um eps = 13 # epsilon of waveguide w = 1.2 # width of the waveguide dpml = 1 # PML thickness largC = 16 # largura da celula altC = 16 # altura da celula sx = largC + dpml sy = altC + dpml fcen = args.fcen # pulse centger frequency df = args.df # pulse frequency width cell = mp.Vector3(sx,sy,0) def epsP(p): valorIm = -0.5 + math.pow(math.cos((p.y)*(2*math.pi/(altC/4))),2) return mp.Medium(epsilon=3, D_conductivity=2*math.pi*fcen*(valorIm)/3) epsP.do_averaging = True blk = mp.Block(size=mp.Vector3(mp.inf,mp.inf,mp.inf), material=mp.Medium(epsilon=eps)) geometry = [blk] # AQUI ESTÁ A LINHA DE TESTE: USAMOS A FUNCAO PARA DEFINIR O EPSILON # geometry.append(mp.Block(size=mp.Vector3(mp.inf,w,mp.inf))) geometry.append(mp.Block(center=mp.Vector3(),size=mp.Vector3(mp.inf,altC,mp.inf),material=epsP)) pml_layers = [mp.PML(1.0)] src = [mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ey, center=mp.Vector3(-0.5*sx+dpml), # fonte na esquerda; para colocar na direita usar 0.5*sx - dpml size=mp.Vector3(0,w))] sim = mp.Simulation(cell_size=cell, geometry=geometry, boundary_layers=pml_layers, sources=src, #symmetries=sym, resolution=resolution) sim.run(mp.at_beginning(mp.output_epsilon), mp.to_appended("hz",mp.at_every(0.4,mp.output_hfield_z)), until=300) epsilon0 = sim.get_array(center=mp.Vector3(), size=cell, component=mp.Dielectric) plt.figure() plt.imshow(epsilon0.transpose(), interpolation='spline36', cmap='RdBu') plt.axis('off') plt.savefig('epsilon.png',format='png') plt.show()
decay = meep.Ex else: source = lambda sim: meep_ext.y_polarized_plane_wave(sim, src_time) decay = meep.Ey ### monitor info particle_monitor_gap = 50 * nm pml_monitor_gap = 50 * nm norm_file_ext = 'norm_box' monitor_size = [ box[0] + 2 * particle_monitor_gap, box[1] + 2 * particle_monitor_gap, box[2] + 2 * particle_monitor_gap ] ### grid pml = meep.PML(15 / resolution) lx = box[0] + 2 * particle_monitor_gap + 2 * pml_monitor_gap + 2 * pml.thickness ly = box[1] + 2 * particle_monitor_gap + 2 * pml_monitor_gap + 2 * pml.thickness lz = box[2] + 2 * particle_monitor_gap + 2 * pml_monitor_gap + 2 * pml.thickness cell = meep.Vector3(lx, ly, lz) Nx, Ny, Nz = map(round, cell * resolution) @job.cache def norm_sim(): """perform normalization simulation""" norm = meep.Simulation(cell_size=cell, boundary_layers=[pml], geometry=[], default_material=medium, resolution=resolution)
cell = mp.Vector3(sx, sy, 0) blk = mp.Block(size=mp.Vector3(1e20, w, 1e20), material=mp.Medium(epsilon=eps)) geometry = [blk] for i in range(3): geometry.append(mp.Cylinder(r, center=mp.Vector3(d / 2 + i))) for i in range(3): geometry.append(mp.Cylinder(r, center=mp.Vector3(d / -2 - i))) sim = mp.Simulation(cell_size=cell, geometry=geometry, sources=[], boundary_layers=[mp.PML(dpml)], resolution=20) # add sources sim.sources = [ mp.Source(mp.GaussianSource(fcen, fwidth=df), mp.Hz, mp.Vector3()) ] # run until sources are finished (and no later) sim._run_sources_until(0, []) # get 1D and 2D array slices xMin = -0.25 * sx xMax = +0.25 * sx yMin = -0.15 * sy yMax = +0.15 * sy
from utils import ApproxComparisonTestCase MonitorObject = Enum('MonitorObject', 'EIGENMODE DFT') resolution = 30 silicon = mp.Medium(epsilon=12) sapphire = mp.Medium(epsilon_diag=(10.225, 10.225, 9.95), epsilon_offdiag=(-0.825, -0.55 * np.sqrt(3 / 2), 0.55 * np.sqrt(3 / 2))) sxy = 5.0 cell_size = mp.Vector3(sxy, sxy, 0) dpml = 1.0 pml_xy = [mp.PML(thickness=dpml)] pml_x = [mp.PML(thickness=dpml, direction=mp.X)] eig_parity = mp.EVEN_Y + mp.ODD_Z design_region_size = mp.Vector3(1.5, 1.5) design_region_resolution = int(2 * resolution) Nx, Ny = int(design_region_size.x * design_region_resolution), int( design_region_size.y * design_region_resolution) ## ensure reproducible results rng = np.random.RandomState(9861548) ## random design region p = 0.5 * rng.rand(Nx * Ny)
import matplotlib.pyplot as plt # In[5]: 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)]
def _load_dump_structure(self, chunk_file=False, chunk_sim=False): from meep.materials import Al resolution = 50 cell = mp.Vector3(5, 5) sources = mp.Source(src=mp.GaussianSource(1, fwidth=0.2), center=mp.Vector3(), component=mp.Ez) one_by_one = mp.Vector3(1, 1, mp.inf) geometry = [ mp.Block(material=Al, center=mp.Vector3(), size=one_by_one), mp.Block(material=mp.Medium(epsilon=13), center=mp.Vector3(1), size=one_by_one) ] pml_layers = [mp.PML(0.5)] symmetries = [mp.Mirror(mp.Y)] sim1 = mp.Simulation(resolution=resolution, cell_size=cell, boundary_layers=pml_layers, geometry=geometry, symmetries=symmetries, sources=[sources]) sample_point = mp.Vector3(0.12, -0.29) ref_field_points = [] def get_ref_field_point(sim): p = sim.get_field_point(mp.Ez, sample_point) ref_field_points.append(p.real) sim1.run(mp.at_every(5, get_ref_field_point), until=50) dump_fn = 'test_load_dump_structure.h5' dump_chunk_fname = None chunk_layout = None sim1.dump_structure(dump_fn) if chunk_file: dump_chunk_fname = 'test_load_dump_structure_chunks.h5' sim1.dump_chunk_layout(dump_chunk_fname) chunk_layout = dump_chunk_fname if chunk_sim: chunk_layout = sim1 sim = mp.Simulation(resolution=resolution, cell_size=cell, boundary_layers=pml_layers, sources=[sources], symmetries=symmetries, chunk_layout=chunk_layout, load_structure=dump_fn) field_points = [] def get_field_point(sim): p = sim.get_field_point(mp.Ez, sample_point) field_points.append(p.real) sim.run(mp.at_every(5, get_field_point), until=50) for ref_pt, pt in zip(ref_field_points, field_points): self.assertAlmostEqual(ref_pt, pt) mp.all_wait() if mp.am_master(): os.remove(dump_fn) if dump_chunk_fname: os.remove(dump_chunk_fname)