import meep as mp import math resolution = 20 # pixels/um nglass = 1.5 glass = mp.Medium(index=nglass) dsub = 3 # substrate thickness dair = 3 # air padding between grating and pml gp = 10.0 # grating period gh = 0.5 # grating height gdc = 0.5 # grating duty cycle lambda_min = 0.4 # vacuum wavelength lambda_max = 0.8 # vacuum wavelength fmin = 1 / lambda_max fmax = 1 / lambda_min fcen = 0.5 * (fmin + fmax) df = fmax - fmin dpml = lambda_max # PML thickness sx = dpml + dsub + gh + dair + dpml sy = gp cell_size = mp.Vector3(sx, sy, 0) pml_layers = [mp.PML(thickness=dpml, direction=mp.X)] geometry = [ mp.Block(material=glass, size=mp.Vector3(dpml + dsub, mp.inf, mp.inf),
def test_extra_materials(self): sim = self.init_simple_simulation() sim.extra_materials = [mp.Medium(epsilon=5), mp.Medium(epsilon=10)] sim.run(mp.at_end(lambda sim: None), until=5)
nr = 0.9999432732358271 ni = 6.7430E-06 real_epsilon = nr**2 - ni**2 imag_epsilon = 2*nr*ni conductivity=2 * np.pi * f *imag_epsilon / (real_epsilon*8.85e-12) # real_ind = 1 - 1.1676e-5 # imag_ind = 3.9765e-7 # real_epsilon = real_ind**2 - imag_ind**2 # imag_epsilon = 2*real_ind*imag_ind # omega = 2*np.pi*f*1e10 # conductivity = omega*imag_epsilon # factor = (1e-10/3e8)/(real_epsilon*8.85e-12) # D_conductivity = factor*conductivity mat = mp.Medium(epsilon=real_epsilon, D_conductivity=conductivity) # geometry = [mp.Sphere(radius=SphereRadius, material=mat)] geometry = [] # geometry = [mp.Block(mp.Vector3(SphereRadius,SphereRadius,SphereRadius), # center=mp.Vector3(), # material=mat)] # sources = [mp.Source(mp.GaussianSource(f, fwidth=df), # component=mp.Ez, # center=mp.Vector3(-sx/2), # size=mp.Vector3(y=sy, z=sz)), # mp.Source(mp.GaussianSource(f, fwidth=df),
sy = 32 # size of cell in Y direction cell = mp.Vector3(sx, sy, 0) dpml = 1.0 pml_layers = [mp.PML(dpml)] pad = 4 # padding distance between waveguide and cell edge w = 1 # width of waveguide wvg_xcen = 0.5 * (sx - w - 2 * pad) # x center of vert. wvg wvg_ycen = -0.5 * (sy - w - 2 * pad) # y center of horiz. wvg geometry = [ mp.Block(size=mp.Vector3(mp.inf, w, mp.inf), center=mp.Vector3(0, wvg_ycen, 0), material=mp.Medium(epsilon=12)) ] fcen = 0.15 # pulse center frequency df = 0.1 # pulse width (in frequency) sources = [ mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ez, center=mp.Vector3(-0.5 * sx + dpml, wvg_ycen, 0), size=mp.Vector3(0, w, 0)) ] sim = mp.Simulation(cell_size=cell, boundary_layers=pml_layers, geometry=geometry,
def compute_resonant_mode(res, default_mat=False): cell_size = mp.Vector3(1, 1, 0) rad = 0.301943 fcen = 0.3 df = 0.2 * fcen sources = [ mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Hz, center=mp.Vector3(-0.1057, 0.2094, 0)) ] k_point = mp.Vector3(0.3892, 0.1597, 0) design_shape = mp.Vector3(1, 1, 0) design_region_resolution = 50 Nx = int(design_region_resolution * design_shape.x) Ny = int(design_region_resolution * design_shape.y) x = np.linspace(-0.5 * design_shape.x, 0.5 * design_shape.x, Nx) y = np.linspace(-0.5 * design_shape.y, 0.5 * design_shape.y, Ny) xv, yv = np.meshgrid(x, y) design_params = np.sqrt(np.square(xv) + np.square(yv)) < rad filtered_design_params = gaussian_filter(design_params, sigma=3.0, output=np.double) matgrid = mp.MaterialGrid(mp.Vector3(Nx, Ny), mp.air, mp.Medium(index=3.5), weights=filtered_design_params, do_averaging=True, beta=1000, eta=0.5) geometry = [ mp.Block(center=mp.Vector3(), size=mp.Vector3(design_shape.x, design_shape.y, 0), material=matgrid) ] sim = mp.Simulation( resolution=res, cell_size=cell_size, default_material=matgrid if default_mat else mp.Medium(), geometry=geometry if not default_mat else [], sources=sources, k_point=k_point) h = mp.Harminv(mp.Hz, mp.Vector3(0.3718, -0.2076), fcen, df) sim.run(mp.after_sources(h), until_after_sources=200) try: for m in h.modes: print("harminv:, {}, {}, {}".format(res, m.freq, m.Q)) freq = h.modes[0].freq except: print("No resonant modes found.") sim.reset_meep() return freq
def pol_grating(d,ph,gp,nmode): sx = dpml+dsub+d+d+dpad+dpml sy = gp cell_size = mp.Vector3(sx,sy,0) pml_layers = [mp.PML(thickness=dpml,direction=mp.X)] # twist angle of nematic director; from equation 1b def phi(p): xx = p.x-(-0.5*sx+dpml+dsub) if (xx >= 0) and (xx <= d): return math.pi*p.y/gp + ph*xx/d else: return math.pi*p.y/gp - ph*xx/d + 2*ph # return the anisotropic permittivity tensor for a uniaxial, twisted nematic liquid crystal def lc_mat(p): # rotation matrix for rotation around x axis Rx = mp.Matrix(mp.Vector3(1,0,0),mp.Vector3(0,math.cos(phi(p)),math.sin(phi(p))),mp.Vector3(0,-math.sin(phi(p)),math.cos(phi(p)))) lc_epsilon = Rx * epsilon_diag * Rx.transpose() lc_epsilon_diag = mp.Vector3(lc_epsilon[0].x,lc_epsilon[1].y,lc_epsilon[2].z) lc_epsilon_offdiag = mp.Vector3(lc_epsilon[1].x,lc_epsilon[2].x,lc_epsilon[2].y) return mp.Medium(epsilon_diag=lc_epsilon_diag,epsilon_offdiag=lc_epsilon_offdiag) geometry = [mp.Block(center=mp.Vector3(-0.5*sx+0.5*(dpml+dsub)),size=mp.Vector3(dpml+dsub,mp.inf,mp.inf),material=mp.Medium(index=n_0)), mp.Block(center=mp.Vector3(-0.5*sx+dpml+dsub+d),size=mp.Vector3(2*d,mp.inf,mp.inf),material=lc_mat)] # linear-polarized planewave pulse source src_pt = mp.Vector3(-0.5*sx+dpml+0.3*dsub,0,0) sources = [mp.Source(mp.GaussianSource(fcen,fwidth=0.05*fcen), component=mp.Ez, center=src_pt, size=mp.Vector3(0,sy,0)), mp.Source(mp.GaussianSource(fcen,fwidth=0.05*fcen), component=mp.Ey, center=src_pt, size=mp.Vector3(0,sy,0))] sim = mp.Simulation(resolution=resolution, cell_size=cell_size, boundary_layers=pml_layers, k_point=k_point, sources=sources, default_material=mp.Medium(index=n_0)) refl_pt = mp.Vector3(-0.5*sx+dpml+0.5*dsub,0,0) refl_flux = sim.add_flux(fcen, 0, 1, mp.FluxRegion(center=refl_pt, size=mp.Vector3(0,sy,0))) sim.run(until_after_sources=100) input_flux = mp.get_fluxes(refl_flux) input_flux_data = sim.get_flux_data(refl_flux) sim.reset_meep() sim = mp.Simulation(resolution=resolution, cell_size=cell_size, boundary_layers=pml_layers, k_point=k_point, sources=sources, geometry=geometry) refl_flux = sim.add_flux(fcen, 0, 1, mp.FluxRegion(center=refl_pt, size=mp.Vector3(0,sy,0))) sim.load_minus_flux_data(refl_flux,input_flux_data) tran_pt = mp.Vector3(0.5*sx-dpml-0.5*dpad,0,0) tran_flux = sim.add_flux(fcen, 0, 1, mp.FluxRegion(center=tran_pt, size=mp.Vector3(0,sy,0))) sim.run(until_after_sources=300) res1 = sim.get_eigenmode_coefficients(tran_flux, range(1,nmode+1), eig_parity=mp.ODD_Z+mp.EVEN_Y) res2 = sim.get_eigenmode_coefficients(tran_flux, range(1,nmode+1), eig_parity=mp.EVEN_Z+mp.ODD_Y) angles = [math.degrees(math.acos(kdom.x/fcen)) for kdom in res1.kdom] return input_flux[0], angles, res1.alpha[:,0,0], res2.alpha[:,0,0];
import numpy as np import gdspy from matplotlib import pyplot as plt import importlib import meep as mp # core and cladding materials Si = mp.Medium(index=3.4) SiO2 = mp.Medium(index=1.4) # layer numbers for GDS file RING_LAYER = 0 SOURCE0_LAYER = 1 SOURCE1_LAYER = 2 MONITOR_LAYER = 3 SIMULATION_LAYER = 4 resolution = 50 # pixels/μm dpml = 1 # thickness of PML zmin = 0 # minimum z value of simulation domain (0 for 2D) zmax = 0 # maximum z value of simulation domain (0 for 2D) def create_ring_gds(radius, width): # Reload the library each time to prevent gds library name clashes importlib.reload(gdspy) ringCell = gdspy.Cell("ring_resonator_r{}_w{}".format(radius, width)) # Draw the ring ringCell.add(
frq_max = 1 / minwvl frq_cen = 0.5 * (frq_min + frq_max) dfrq = frq_max - frq_min nfrq = 100 resolution = 110 # this value will change dpml = 2 #wavelength resolution problem #transmittance ratio is low #silicon dioxide #titanium dio pml_layers = [ mp.PML(dpml, direction=mp.Y, side=mp.High), mp.Absorber(dpml, direction=mp.Y, side=mp.Low) ] block_number = 6 # here this number determines how many dielectric material has been used Material = mp.Medium(epsilon=12) block_thicknessy = 0.1 block_thicknessx = 0.1 #thickness of each block cellx = block_thicknessx celly = 2 * dpml + block_number * 2 * (block_thicknessy) geometry = [] sources = [ mp.Source(mp.GaussianSource(frq_cen, fwidth=dfrq), center=mp.Vector3(0, -0.5 * celly + dpml), size=mp.Vector3(block_thicknessx, 0), component=mp.Ez) ] #polarization? sim = mp.Simulation(resolution=resolution, cell_size=mp.Vector3(cellx, celly), boundary_layers=pml_layers,
import matplotlib.pyplot as plt from meep.materials import Cu wid = 1 sq1 = 10 sq2 = 20 cell = mp.Vector3(2 * sq2, 2 * sq2, 0) gap = 2 cell = cell = mp.Vector3(1.5 * sq2, 1.5 * sq2, 0) #first square #vertial sq1_1 = mp.Block(mp.Vector3(sq1, wid, mp.inf), center=mp.Vector3(0, -sq1 / 2), material=mp.Medium(epsilon=10)) sq1_2 = mp.Block(mp.Vector3(sq1, wid, mp.inf), center=mp.Vector3(0, sq1 / 2), material=mp.Medium(epsilon=10)) #horizontal sq1_3 = mp.Block(mp.Vector3(wid, sq1 + wid, mp.inf), center=mp.Vector3(sq1 / 2, 0), material=mp.Medium(epsilon=10)) #sides from the split on first square #length of split side split_1 = abs(sq1 / 2 - gap / 2) sq1_4 = mp.Block(mp.Vector3(wid, (sq1 / 2) - (gap / 2), mp.inf), center=mp.Vector3(-sq1 / 2, (sq1 - split_1 + wid) / 2), material=mp.Medium(epsilon=10))
eps_Si=12 eps=4 T_Si=1 T_Arc=float(args.v) cell = mp.Vector3(sx, sy, 0) pml_layers = [mp.PML(1.0)] resolution = 10 nfreq = 100 fcen = 0.15 # pulse center frequency df = 0.1 # pulse width (in frequency) print(T_Arc) if args.no_ARC: geometry = [mp.Block(mp.Vector3(sx, sy, mp.inf), center=mp.Vector3(0, 0), material=mp.Medium(epsilon=1))] else: geometry = [mp.Block(mp.Vector3(T_Si, sy, mp.inf), center=mp.Vector3(0, 0), material=mp.Medium(epsilon=eps_Si)), mp.Block(mp.Vector3(T_Arc, sy, mp.inf), center=mp.Vector3(-0.5 * (T_Si + T_Arc), 0), material=mp.Medium(epsilon=eps))] sources = [mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ez, center=mp.Vector3(2 + (-0.5 * sx), 0), size=mp.Vector3(0, 1))] sim = mp.Simulation(cell_size=cell, boundary_layers=pml_layers, geometry=geometry, sources=sources, resolution=resolution) if args.no_ARC:
# size of computational cell #---------------------------------------------------------------------- w_wvg = args.w_wvg h_wvg = args.h_wvg w_hole = args.w_hole L = max(6.0 * dpml + 2.0 * w_hole, 3.0 / fcen) sx = dpml + L + dpml sy = dpml + dair + w_wvg + dair + dpml sz = 0.0 if h_wvg == 0.0 else dpml + dair + h_wvg + dair + dpml cell_size = v3(sx, sy, sz) #---------------------------------------------------------------------- # geometric objects (material bodies), not including the design object #---------------------------------------------------------------------- wvg = mp.Block(center=V3(ORIGIN), material=mp.Medium(epsilon=args.eps_wvg), size=V3(sx, w_wvg, h_wvg)) #---------------------------------------------------------------------- #- objective regions, objective quantities, objective function #---------------------------------------------------------------------- w_flux = (0.5 * dair + w_wvg + 0.5 * dair) h_flux = 0.0 if h_wvg == 0.0 else (0.5 * dair + h_wvg + 0.5 * dair) flux_size = v3(0, w_flux, h_flux) d_flux = w_hole + dpml # distance from origin to centers of flux cells east = Subregion(name='east', center=v3(+d_flux, 0, 0), size=flux_size, dir=mp.X) west = Subregion(name='west', center=v3(-d_flux, 0, 0),
# ---------------------------------------------------------------------------- # # Import libraries # ---------------------------------------------------------------------------- # import meep as mp from meep import mpb import matplotlib.pyplot as plt import numpy as np # ---------------------------------------------------------------------------- # # Materials, constants, and common cimulation params # ---------------------------------------------------------------------------- # Si = mp.Medium(index=3.4757) SiO2 = mp.Medium(index=1.444) ww = 0.5 # waveguide width (microns) wh = 0.22 # waveguide height (microns) rradius = 5 # ring radius (microns) gap = .1 # gap between ring and bus (microns) conLen = 5 # connector length (microns) resolution = 10 PML = 2.0 pml_layers = [mp.PML(PML)] cellWidth = 3*rradius + 2*PML cellHeight = 3*rradius + 2*PML cell = mp.Vector3(cellWidth,cellHeight,0)
def mat_func(p): return mp.Medium()
def test_check_material_frequencies(self): mat = mp.Medium(valid_freq_range=mp.FreqRange(min=10, max=20)) invalid_sources = [ [mp.Source(mp.GaussianSource(5, fwidth=1), mp.Ez, mp.Vector3())], [ mp.Source(mp.ContinuousSource(10, fwidth=1), mp.Ez, mp.Vector3()) ], [mp.Source(mp.GaussianSource(10, width=1), mp.Ez, mp.Vector3())], [mp.Source(mp.GaussianSource(20, width=1), mp.Ez, mp.Vector3())], ] cell_size = mp.Vector3(5, 5) resolution = 5 def check_warnings(sim, should_warn=True): with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") sim.run(until=5) if should_warn: self.assertEqual(len(w), 1) self.assertIn("material", str(w[-1].message)) else: self.assertEqual(len(w), 0) geom = [mp.Sphere(0.2, material=mat)] for s in invalid_sources: # Check for invalid extra_materials sim = mp.Simulation(cell_size=cell_size, resolution=resolution, sources=s, extra_materials=[mat]) check_warnings(sim) # Check for invalid geometry materials sim = mp.Simulation(cell_size=cell_size, resolution=resolution, sources=s, geometry=geom) check_warnings(sim) valid_sources = [[ mp.Source(mp.GaussianSource(15, fwidth=1), mp.Ez, mp.Vector3()) ], [mp.Source(mp.ContinuousSource(15, width=5), mp.Ez, mp.Vector3())]] for s in valid_sources: sim = mp.Simulation(cell_size=cell_size, resolution=resolution, sources=s, extra_materials=[mat]) check_warnings(sim, False) # Check DFT frequencies # Invalid extra_materials sim = mp.Simulation(cell_size=cell_size, resolution=resolution, sources=valid_sources[0], extra_materials=[mat]) fregion = mp.FluxRegion(center=mp.Vector3(0, 1), size=mp.Vector3(2, 2), direction=mp.X) sim.add_flux(15, 6, 2, fregion) check_warnings(sim) # Invalid geometry material sim = mp.Simulation(cell_size=cell_size, resolution=resolution, sources=valid_sources[0], geometry=geom) sim.add_flux(15, 6, 2, fregion) check_warnings(sim)
# -*- coding: utf-8 -*- import meep as mp from meep import mpb import numpy as np import matplotlib.pyplot as plt resolution = 128 # pixels/μm Si = mp.Medium(index=3.45) syz = 10 geometry_lattice = mp.Lattice(size=mp.Vector3(0, syz, syz)) k_points = [mp.Vector3(0.5)] num_bands = 1 tolerance = 1e-9 a = 1.0 # waveguide width def parallel_waveguide(s, yodd): geometry = [ mp.Block(center=mp.Vector3(0, -0.5 * (s + a), 0), size=mp.Vector3(mp.inf, a, a), material=Si), mp.Block(center=mp.Vector3(0, 0.5 * (s + a), 0), size=mp.Vector3(mp.inf, a, a), material=Si) ]
def main(args): resolution = 30 nSiO2 = 1.4 SiO2 = mp.Medium(index=nSiO2) # conversion factor for eV to 1/um eV_um_scale = 1 / 1.23984193 # W, from Rakic et al., Applied Optics, vol. 32, p. 5274 (1998) W_eps_inf = 1 W_plasma_frq = 13.22 * eV_um_scale W_f0 = 0.206 W_frq0 = 1e-10 W_gam0 = 0.064 * eV_um_scale W_sig0 = W_f0 * W_plasma_frq**2 / W_frq0**2 W_f1 = 0.054 W_frq1 = 1.004 * eV_um_scale # 1.235 um W_gam1 = 0.530 * eV_um_scale W_sig1 = W_f1 * W_plasma_frq**2 / W_frq1**2 W_f2 = 0.166 W_frq2 = 1.917 * eV_um_scale # 0.647 W_gam2 = 1.281 * eV_um_scale W_sig2 = W_f2 * W_plasma_frq**2 / W_frq2**2 W_susc = [ mp.DrudeSusceptibility(frequency=W_frq0, gamma=W_gam0, sigma=W_sig0), mp.LorentzianSusceptibility(frequency=W_frq1, gamma=W_gam1, sigma=W_sig1), mp.LorentzianSusceptibility(frequency=W_frq2, gamma=W_gam2, sigma=W_sig2) ] W = mp.Medium(epsilon=W_eps_inf, E_susceptibilities=W_susc) # crystalline Si, from M.A. Green, Solar Energy Materials and Solar Cells, vol. 92, pp. 1305-1310 (2008) # fitted Lorentzian parameters, only for 600nm-1100nm Si_eps_inf = 9.14 Si_eps_imag = -0.0334 Si_eps_imag_frq = 1 / 1.55 Si_frq = 2.2384 Si_gam = 4.3645e-02 Si_sig = 14.797 / Si_frq**2 Si = mp.Medium(epsilon=Si_eps_inf, D_conductivity=2 * math.pi * Si_eps_imag_frq * Si_eps_imag / Si_eps_inf, E_susceptibilities=[ mp.LorentzianSusceptibility(frequency=Si_frq, gamma=Si_gam, sigma=Si_sig) ]) a = args.a # lattice periodicity cone_r = args.cone_r # cone radius cone_h = args.cone_h # cone height wire_w = args.wire_w # metal-grid wire width wire_h = args.wire_h # metal-grid wire height trench_w = args.trench_w # trench width trench_h = args.trench_h # trench height Np = args.Np # number of periods in supercell dair = 1.0 # air gap thickness dmcl = 1.7 # micro lens thickness dsub = 3000.0 # substrate thickness dpml = 1.0 # PML thickness sxy = Np * a sz = dpml + dair + dmcl + dsub + dpml cell_size = mp.Vector3(sxy, sxy, sz) boundary_layers = [ mp.PML(dpml, direction=mp.Z, side=mp.High), mp.Absorber(dpml, direction=mp.Z, side=mp.Low) ] geometry = [] if args.substrate: geometry = [ mp.Sphere(material=SiO2, radius=dmcl, center=mp.Vector3(0, 0, 0.5 * sz - dpml - dair - dmcl)), mp.Block(material=Si, size=mp.Vector3(mp.inf, mp.inf, dsub + dpml), center=mp.Vector3(0, 0, -0.5 * sz + 0.5 * (dsub + dpml))), mp.Block( material=W, size=mp.Vector3(mp.inf, wire_w, wire_h), center=mp.Vector3(0, -0.5 * sxy + 0.5 * wire_w, -0.5 * sz + dpml + dsub + 0.5 * wire_h)), mp.Block( material=W, size=mp.Vector3(mp.inf, wire_w, wire_h), center=mp.Vector3(0, +0.5 * sxy - 0.5 * wire_w, -0.5 * sz + dpml + dsub + 0.5 * wire_h)), mp.Block( material=W, size=mp.Vector3(wire_w, mp.inf, wire_h), center=mp.Vector3(-0.5 * sxy + 0.5 * wire_w, 0, -0.5 * sz + dpml + dsub + 0.5 * wire_h)), mp.Block(material=W, size=mp.Vector3(wire_w, mp.inf, wire_h), center=mp.Vector3(+0.5 * sxy - 0.5 * wire_w, 0, -0.5 * sz + dpml + dsub + 0.5 * wire_h)) ] if args.substrate and args.texture: for nx in range(Np): for ny in range(Np): cx = -0.5 * sxy + (nx + 0.5) * a cy = -0.5 * sxy + (ny + 0.5) * a geometry.append( mp.Cone(material=SiO2, radius=0, radius2=cone_r, height=cone_h, center=mp.Vector3( cx, cy, 0.5 * sz - dpml - dair - dmcl - 0.5 * cone_h))) if args.substrate: geometry.append( mp.Block(material=SiO2, size=mp.Vector3(mp.inf, trench_w, trench_h), center=mp.Vector3( 0, -0.5 * sxy + 0.5 * trench_w, 0.5 * sz - dpml - dair - dmcl - 0.5 * trench_h))) geometry.append( mp.Block(material=SiO2, size=mp.Vector3(mp.inf, trench_w, trench_h), center=mp.Vector3( 0, +0.5 * sxy - 0.5 * trench_w, 0.5 * sz - dpml - dair - dmcl - 0.5 * trench_h))) geometry.append( mp.Block(material=SiO2, size=mp.Vector3(trench_w, mp.inf, trench_h), center=mp.Vector3( -0.5 * sxy + 0.5 * trench_w, 0, 0.5 * sz - dpml - dair - dmcl - 0.5 * trench_h))) geometry.append( mp.Block(material=SiO2, size=mp.Vector3(trench_w, mp.inf, trench_h), center=mp.Vector3( +0.5 * sxy - 0.5 * trench_w, 0, 0.5 * sz - dpml - dair - dmcl - 0.5 * trench_h))) k_point = mp.Vector3(0, 0, 0) lambda_min = 0.7 # minimum source wavelength lambda_max = 1.0 # maximum source wavelength fmin = 1 / lambda_max fmax = 1 / lambda_min fcen = 0.5 * (fmin + fmax) df = fmax - fmin sources = [ mp.Source(mp.GaussianSource(fcen, fwidth=df), component=mp.Ex, center=mp.Vector3(0, 0, 0.5 * sz - dpml - 0.5 * dair), size=mp.Vector3(sxy, sxy, 0)) ] sim = mp.Simulation(resolution=resolution, cell_size=cell_size, boundary_layers=boundary_layers, geometry=geometry, dimensions=3, k_point=k_point, sources=sources) nfreq = 50 refl = sim.add_flux( fcen, df, nfreq, mp.FluxRegion(center=mp.Vector3(0, 0, 0.5 * sz - dpml), size=mp.Vector3(sxy, sxy, 0))) trans_grid = sim.add_flux( fcen, df, nfreq, mp.FluxRegion(center=mp.Vector3(0, 0, -0.5 * sz + dpml + dsub + wire_h), size=mp.Vector3(sxy, sxy, 0))) trans_sub_top = sim.add_flux( fcen, df, nfreq, mp.FluxRegion(center=mp.Vector3(0, 0, -0.5 * sz + dpml + dsub), size=mp.Vector3(sxy, sxy, 0))) trans_sub_bot = sim.add_flux( fcen, df, nfreq, mp.FluxRegion(center=mp.Vector3(0, 0, -0.5 * sz + dpml), size=mp.Vector3(sxy, sxy, 0))) sim.run(mp.at_beginning(mp.output_epsilon), until=0) if args.substrate: 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 + 0.5 * dsub), 1e-9)) if not args.substrate: sim.save_flux('refl-flux', refl) sim.display_fluxes(refl, trans_grid, trans_sub_top, trans_sub_bot)
dpad = 32 # padding between last hole and PML edge dpml = 0.5 / (fcen - 0.5 * df) # PML thickness (> half the largest wavelength) sx = 2 * (dpad + dpml + N) + d - 1 # size of cell in x direction d1 = 0.2 # y-distance from waveguide edge to near2far surface d2 = 2.0 # y-distance from near2far surface to far-field line sy = w + 2 * (d1 + d2 + dpml ) # size of cell in y direction (perpendicular to wvg.) cell = mp.Vector3(sx, sy, 0) geometry = [ mp.Block(center=mp.Vector3(), size=mp.Vector3(mp.inf, w, mp.inf), material=mp.Medium(epsilon=eps)) ] for i in range(N): geometry.append(mp.Cylinder(r, center=mp.Vector3(d / 2 + i))) geometry.append(mp.Cylinder(r, center=mp.Vector3(d / -2 - i))) pml_layers = [mp.PML(dpml)] sources = [ mp.Source(src=mp.GaussianSource(fcen, fwidth=df), component=mp.Hz, center=mp.Vector3()) ] symmetries = [mp.Mirror(mp.X, phase=-1), mp.Mirror(mp.Y, phase=-1)]
cSi_sig3 = -0.107 cSi_susc = [ mp.LorentzianSusceptibility(frequency=cSi_frq1, gamma=cSi_gam1, sigma=cSi_sig1), mp.LorentzianSusceptibility(frequency=cSi_frq2, gamma=cSi_gam2, sigma=cSi_sig2), mp.LorentzianSusceptibility(frequency=cSi_frq3, gamma=cSi_gam3, sigma=cSi_sig3) ] cSi = mp.Medium(epsilon=1.0, E_susceptibilities=cSi_susc, valid_freq_range=cSi_range) #------------------------------------------------------------------ # amorphous silicon (a-Si) from Horiba Technical Note 08: Lorentz Dispersion Model # ref: http://www.horiba.com/fileadmin/uploads/Scientific/Downloads/OpticalSchool_CN/TN/ellipsometer/Lorentz_Dispersion_Model.pdf # wavelength range: 0.21 - 0.83 um aSi_range = mp.FreqRange(min=1 / 0.83, max=1 / 0.21) aSi_frq1 = 1 / (0.315481407124682 * um_scale) aSi_gam1 = 1 / (0.645751005208333 * um_scale) aSi_sig1 = 14.571 aSi_susc = [
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 __init__(self, cell_size, resolution, geometry=[], sources=[], eps_averaging=True, dimensions=2, boundary_layers=[], symmetries=[], verbose=False, force_complex_fields=False, default_material=mp.Medium(), m=0, k_point=False, extra_materials=[], material_function=None, epsilon_func=None, epsilon_input_file='', progress_interval=4, subpixel_tol=1e-4, subpixel_maxeval=100000, ensure_periodicity=False, num_chunks=0, courant=0.5, accurate_fields_near_cylorigin=False, filename_prefix='', output_volume=None, output_single_precision=False): self.cell_size = cell_size self.geometry = geometry self.sources = sources self.resolution = resolution self.dimensions = dimensions self.boundary_layers = boundary_layers self.symmetries = symmetries self.geometry_center = Vector3() self.eps_averaging = eps_averaging self.subpixel_tol = subpixel_tol self.subpixel_maxeval = subpixel_maxeval self.ensure_periodicity = ensure_periodicity self.extra_materials = extra_materials self.default_material = default_material self.epsilon_input_file = epsilon_input_file self.num_chunks = num_chunks self.courant = courant self.global_d_conductivity = 0 self.global_b_conductivity = 0 self.special_kz = False self.k_point = k_point self.fields = None self.structure = None self.accurate_fields_near_cylorigin = accurate_fields_near_cylorigin self.m = m self.force_complex_fields = force_complex_fields self.verbose = verbose self.progress_interval = progress_interval self.init_fields_hooks = [] self.run_index = 0 self.filename_prefix = '' self.output_append_h5 = None self.output_single_precision = output_single_precision self.output_volume = output_volume self.last_eps_filename = '' self.output_h5_hook = lambda fname: False self.interactive = False self.is_cylindrical = False self.material_function = material_function self.epsilon_func = epsilon_func
fcen = (maxf + minf) / 2 df = maxf - minf nfreq = 100 resolution = 100 sources = [ mp.Source(mp.GaussianSource(fcen, fwidth=df, is_integrated=True), component=mp.Ey, center=mp.Vector3(-0.05, 0, 0), size=mp.Vector3(0, 0.12, 0)) ] sim = mp.Simulation(cell_size=cell, boundary_layers=pml_layers, k_point=mp.Vector3(), sources=sources, default_material=mp.Medium(epsilon=1.78), resolution=resolution) #for i in (np.arange(1,3)): # r=i*0.01 r = 0.02 sim = mp.Simulation(cell_size=cell, boundary_layers=pml_layers, sources=sources, resolution=resolution) left_fr = mp.FluxRegion(center=mp.Vector3(x=-r), size=mp.Vector3(0, 2 * r, 0)) left_monitor = sim.add_flux(fcen, df, nfreq, left_fr) right_fr = mp.FluxRegion(center=mp.Vector3(x=r), size=mp.Vector3(0, 2 * r, 0)) right_monitor = sim.add_flux(fcen, df, nfreq, right_fr)
def main(): # Prefix all output files with the command line argument file_prefix = sys.argv[1] # Number of pixels per micron resolution = 150 # Simulation volume (um) cell_x = 2 cell_y = 2 cell_z = 2.5 # Refractive indicies index_si = 3.6 # previously 3.4467 index_sio2 = 1.444 # Durations in units of micron/c duration = round(1.5 * cell_x + 2) num_timesteps = duration * resolution # Absorbing layer on boundary pml = 0.5 # Geometry src_buffer = pml / 16 nbn_buffer = src_buffer nbn_length = cell_x - 2 * pml - src_buffer - nbn_buffer nbn_center_x = (src_buffer + nbn_buffer) / 2 wavelength = 1.55 waveguide_width = 0.750 # 750 nm waveguide_height = 0.110 # 110 nm plane_shift_y = 0 # nbn is 10/8 times thicker than in reality to have enough simulation pixels # so we reduce its absorption by a factor of 5/4 to compensate nbn_thickness_comp = 250 / resolution nbn_thickness = 0.008 * nbn_thickness_comp # Actually 8 nm, but simulating this for 2 grid points nbn_width = 0.100 # 100 nm nbn_spacing = 0.120 # 120 nm # Also compensate the difference in index by the same amount nbn_base_index = 5.23 # Taken from Hu thesis p86 nbn_index = (5.23 - index_si) / nbn_thickness_comp + index_si nbn_base_k = 5.82 # Taken from Hu thesis p86 nbn_k = nbn_base_k / nbn_thickness_comp conductivity = 2 * math.pi * wavelength * nbn_k / nbn_index flux_length = cell_x - 2 * pml - 4 * src_buffer # Generate simulation obejcts cell = mp.Vector3(cell_x, cell_y, cell_z) freq = 1 / wavelength src_pt = mp.Vector3(-cell_x / 2 + pml + src_buffer, 0, 0) output_slice = mp.Volume(center=mp.Vector3(y=(3 * waveguide_height / 4) + plane_shift_y), size=(cell_x, 0, cell_z)) # Log important quantities print('ABSORBING RUN') print('File prefix: {}'.format(file_prefix)) print('Duration: {}'.format(duration)) print('Resolution: {}'.format(resolution)) print('Dimensions: {} um, {} um, {} um'.format(cell_x, cell_y, cell_z)) print('Wavelength: {} um'.format(wavelength)) print('Si thickness: {} um'.format(waveguide_height)) print('NbN thickness: {} um'.format(nbn_thickness)) print('Si index: {}; SiO2 index: {}'.format(index_si, index_sio2)) print('Absorber dimensions: {} um, {} um, {} um'.format( nbn_length, nbn_thickness, nbn_width)) print('Absorber n (base value): {} ({}), k: {} ({})'.format( nbn_index, nbn_base_index, nbn_k, nbn_base_k)) print('Absorber compensation for thickness: {}'.format(nbn_thickness_comp)) print('Flux length: {} um'.format(flux_length)) print('\n\n**********\n\n') default_material = mp.Medium(epsilon=1) # Physical geometry of the simulation geometry = [ mp.Block(mp.Vector3(mp.inf, cell_y, mp.inf), center=mp.Vector3(0, -cell_y / 2 + plane_shift_y, 0), material=mp.Medium(epsilon=index_sio2)), mp.Block(mp.Vector3(mp.inf, waveguide_height, waveguide_width), center=mp.Vector3(0, waveguide_height / 2 + plane_shift_y, 0), material=mp.Medium(epsilon=index_si)) ] # Absorber will only be appended to geometry for the second simulation absorber = [ mp.Block(mp.Vector3(nbn_length, nbn_thickness, nbn_width), center=mp.Vector3( nbn_center_x, waveguide_height + nbn_thickness / nbn_thickness_comp / 2 + plane_shift_y, nbn_spacing / 2), material=mp.Medium(epsilon=nbn_index, D_conductivity=conductivity)), mp.Block(mp.Vector3(nbn_length, nbn_thickness, nbn_width), center=mp.Vector3( nbn_center_x, waveguide_height + nbn_thickness / nbn_thickness_comp / 2 + plane_shift_y, -nbn_spacing / 2), material=mp.Medium(epsilon=nbn_index, D_conductivity=conductivity)), ] # geometry += absorber # Calculate eigenmode source src_max_y = cell_y - 2 * pml src_max_z = cell_z - 2 * pml src_y = src_max_y src_z = src_max_z # min(3 * waveguide_width, src_max_z) src_center_y = 0 # plane_shift_y sources = [ mp.EigenModeSource(src=mp.ContinuousSource(frequency=freq), center=mp.Vector3(-cell_x / 2 + pml + src_buffer, src_center_y, 0), size=mp.Vector3(0, src_y, src_z), eig_match_freq=True, eig_parity=mp.ODD_Z, eig_band=1) ] pml_layers = [mp.PML(pml)] # Pass all simulation parameters to meep sim = mp.Simulation( cell_size=cell, boundary_layers=pml_layers, geometry=geometry, sources=sources, resolution=resolution, # eps_averaging=False, default_material=default_material, symmetries=[mp.Mirror(mp.Z, phase=-1)]) # Create flux monitors to calculate transmission and absorption fr_y = cell_y - 2 * pml fr_z = cell_z - 2 * pml # Reflected flux refl_fr = mp.FluxRegion(center=mp.Vector3( -0.5 * cell_x + pml + 2 * src_buffer, 0, 0), size=mp.Vector3(0, fr_y, fr_z)) refl = sim.add_flux(freq, 0, 1, refl_fr) # Transmitted flux tran_fr = mp.FluxRegion(center=mp.Vector3( 0.5 * cell_x - pml - 2 * src_buffer, 0, 0), size=mp.Vector3(0, fr_y, fr_z)) tran = sim.add_flux(freq, 0, 1, tran_fr) # Run simulation, outputting the epsilon distribution and the fields in the # x-y plane every 0.25 microns/c sim.run(mp.at_beginning(mp.output_epsilon), mp.to_appended( "ez_z0", mp.in_volume(output_slice, mp.at_every(2 / resolution, mp.output_efield_z))), until=duration) print('\n\n**********\n\n') sim.fields.synchronize_magnetic_fields() # For normalization run, save flux fields data for reflection plane no_absorber_refl_data = sim.get_flux_data(refl) # Save incident power for transmission plane no_absorber_tran_flux = mp.get_fluxes(tran) print("Flux: {}".format(no_absorber_tran_flux[0])) eps_data = sim.get_array(center=mp.Vector3(z=(nbn_spacing + nbn_width) / 2), size=mp.Vector3(cell_x, cell_y, 0), component=mp.Dielectric) eps_cross_data = sim.get_array(center=mp.Vector3(x=cell_x / 4), size=mp.Vector3(0, cell_y, cell_z), component=mp.Dielectric) max_field = 1.5 # Plot epsilon distribution if mp.am_master(): plt.figure() plt.imshow(eps_data.transpose(), interpolation='spline36', cmap='binary') plt.axis('off') plt.savefig(file_prefix + '_Eps_A.png', dpi=300) print('Saved ' + file_prefix + '_Eps_A.png') # Plot field on x-y plane ez_data = sim.get_array(center=mp.Vector3(), size=mp.Vector3(cell_x, cell_y, 0), component=mp.Ez) if mp.am_master(): plt.figure() plt.imshow(eps_data.transpose(), interpolation='spline36', cmap='binary') plt.imshow(ez_data.transpose(), interpolation='spline36', cmap='RdBu', alpha=0.9) plt.axis('off') plt.savefig(file_prefix + '_Ez_A.png', dpi=300) print('Saved ' + file_prefix + '_Ez_A.png') energy_side_data = sim.get_array(center=mp.Vector3(), size=mp.Vector3(cell_x, cell_y, 0), component=mp.EnergyDensity) if mp.am_master(): plt.figure() plt.imshow(eps_data.transpose(), interpolation='spline36', cmap='binary') plt.imshow(energy_side_data.transpose(), interpolation='spline36', cmap='hot', alpha=0.9) plt.axis('off') plt.savefig(file_prefix + '_Pwr0_A.png', dpi=300) print('Saved ' + file_prefix + '_Pwr0_A.png') # Plot energy density on y-z plane energy_data = sim.get_array(center=mp.Vector3(), size=mp.Vector3(0, cell_y, cell_z), component=mp.EnergyDensity) if mp.am_master(): plt.figure() plt.imshow(eps_cross_data, interpolation='spline36', cmap='binary') plt.imshow(energy_data, interpolation='spline36', cmap='hot', alpha=0.9) plt.axis('off') plt.savefig(file_prefix + '_Pwr1_A.png', dpi=300) print('Saved ' + file_prefix + '_Pwr1_A.png') energy_data = sim.get_array(center=mp.Vector3(x=cell_x / 4), size=mp.Vector3(0, cell_y, cell_z), component=mp.EnergyDensity) if mp.am_master(): plt.figure() plt.imshow(eps_cross_data, interpolation='spline36', cmap='binary') plt.imshow(energy_data, interpolation='spline36', cmap='hot', alpha=0.9) plt.axis('off') plt.savefig(file_prefix + '_Pwr2_A.png', dpi=300) print('Saved ' + file_prefix + '_Pwr2_A.png') # Plot cross-sectional fields at several locations to ensure seeing nonzero fields num_x = 4 num_y = 3 fig, ax = plt.subplots(num_x, num_y) fig.suptitle('Cross Sectional Ez Fields') for i in range(num_x * num_y): monitor_x = i * (cell_x / 4) / (num_x * num_y) ez_cross_data = sim.get_array(center=mp.Vector3(x=monitor_x), size=mp.Vector3(0, cell_y, cell_z), component=mp.Ez) ax_num = i // num_y, i % num_y if mp.am_master(): ax[ax_num].imshow(eps_cross_data, interpolation='spline36', cmap='binary') ax[ax_num].imshow(ez_cross_data, interpolation='spline36', cmap='RdBu', alpha=0.9, norm=ZeroNormalize(vmax=np.max(max_field))) ax[ax_num].axis('off') ax[ax_num].set_title('x = {}'.format( round(cell_x / 4 + i / resolution, 3))) if mp.am_master(): plt.savefig(file_prefix + '_Ez_CS_A.png', dpi=300) print('Saved ' + file_prefix + '_Ez_CS_A.png') fig_e, ax_e = plt.subplots(num_x, num_y) fig_e.suptitle('Cross Sectional Energy Density') for i in range(num_x * num_y): monitor_x = i * (cell_x / 4) / (num_x * num_y) energy_cross_data = sim.get_array(center=mp.Vector3(x=monitor_x), size=mp.Vector3(0, cell_y, cell_z), component=mp.EnergyDensity) ax_num = i // num_y, i % num_y if mp.am_master(): ax_e[ax_num].imshow(eps_cross_data, interpolation='spline36', cmap='binary') ax_e[ax_num].imshow(energy_cross_data, interpolation='spline36', cmap='hot', alpha=0.9) ax_e[ax_num].axis('off') ax_e[ax_num].set_title('x = {}'.format( round(cell_x / 4 + i / resolution, 3))) if mp.am_master(): plt.savefig(file_prefix + '_Pwr_CS_A.png', dpi=300) print('Saved ' + file_prefix + '_Pwr_CS_A.png') print('\n\n**********\n\n') # Reset simulation for absorption run """ sim.reset_meep() geometry += absorber sim = mp.Simulation(cell_size=cell, boundary_layers=pml_layers, geometry=geometry, sources=sources, resolution=resolution, eps_averaging=False, default_material=default_material, symmetries=[mp.Mirror(mp.Z, phase=-1)]) refl = sim.add_flux(freq, 0, 1, refl_fr) tran = sim.add_flux(freq, 0, 1, tran_fr) sim.load_minus_flux_data(refl, no_absorber_refl_data) # Run simulation with absorber sim.run(mp.at_beginning(mp.output_epsilon), mp.to_appended("ez_z0", mp.in_volume(output_slice, mp.at_every(0.25, mp.output_efield_z))), until=duration) print('\n\n**********\n\n') # Calculate transmission and absorption absorber_refl_flux = mp.get_fluxes(refl) absorber_tran_flux = mp.get_fluxes(tran) transmittance = absorber_tran_flux[0] / no_absorber_tran_flux[0] reflectance = absorber_refl_flux[0] / no_absorber_tran_flux[0] absorption = 1 - transmittance penetration_depth = - nbn_length / math.log(transmittance) print('Flux: {}'.format(absorber_tran_flux[0])) print("Transmittance: %f" % transmittance) print("Reflectance: %f" % reflectance) print("Absorption: {} over {} um".format(absorption, nbn_length)) print("lambda = {} mm".format(penetration_depth / 1000)) eps_data = sim.get_array(center=mp.Vector3(z=(nbn_spacing + nbn_width) / 2), size=mp.Vector3(cell_x, cell_y, 0), component=mp.Dielectric) max_field = 1 # Plot epsilon distribution with absorber if mp.am_master(): plt.figure() plt.imshow(eps_data.transpose(), interpolation='spline36', cmap='binary') plt.axis('off') plt.savefig(file_prefix + '_Eps_B.png', dpi=300) print('Saved ' + file_prefix + '_Eps_B.png') # Plot fields in x-y plane with absorber ez_data = sim.get_array(center=mp.Vector3(), size=mp.Vector3(cell_x, cell_y, 0), component=mp.Ez) if mp.am_master(): plt.figure() plt.imshow(eps_data.transpose(), interpolation='spline36', cmap='binary') plt.imshow(ez_data.transpose(), interpolation='spline36', cmap='RdBu', alpha=0.9) plt.axis('off') plt.savefig(file_prefix + '_Ez_B.png', dpi=300) print('Saved ' + file_prefix + '_Ez_B.png') # Plot field cross sections with absorber eps_cross_data = sim.get_array(center=mp.Vector3(x=cell_x/4), size=mp.Vector3(0, cell_y, cell_z), component=mp.Dielectric) num_x = 4 num_y = 3 fig, ax = plt.subplots(num_x, num_y) fig.suptitle('Cross Sectional Ez Fields') for i in range(num_x * num_y): monitor_x = cell_x/4 + i / resolution ez_cross_data = sim.get_array(center=mp.Vector3(x=monitor_x), size=mp.Vector3(0, cell_y, cell_z), component=mp.Ez) ax_num = i // num_y, i % num_y if mp.am_master(): ax[ax_num].imshow(eps_cross_data, interpolation='spline36', cmap='binary') ax[ax_num].imshow(ez_cross_data, interpolation='spline36', cmap='RdBu', alpha=0.9, norm=ZeroNormalize(vmax=np.max(max_field))) ax[ax_num].axis('off') ax[ax_num].set_title('x = {}'.format(round(cell_x/4 + i / resolution, 3))) if mp.am_master(): plt.savefig(file_prefix + '_Ez_CS_B.png', dpi=300) print('Saved ' + file_prefix + '_Ez_CS_B.png') print('\n\n**********\n\n') """ print('Program finished.')
from scipy import constants import matplotlib.pyplot as plt import matplotlib.animation as animation import matplotlib as mpl import meep import meep_ext import pinboard job = pinboard.pinboard() nm = 1e-9 um = 1e-6 ### geometry radius = 75 * nm gold = meep_ext.material.Au() gold = meep.Medium(index=3.5) sep = 400 * nm p1 = meep.Vector3(-sep / 2, 0, 0) p2 = meep.Vector3(sep / 2, 0, 0) geometry = [ meep.Sphere(center=p1, radius=radius, material=gold), meep.Sphere(center=p2, radius=radius, material=gold) ] ### source fcen, df = meep_ext.freq_data(1 / (400 * nm), 1 / (1000 * nm)) nfreq = 40 src_time = meep.GaussianSource(frequency=1.3 / um, fwidth=4.0 / um) polarization = meep.Ex # used in convergence check 'decay_by' source = lambda sim: meep_ext.x_polarized_plane_wave(sim, src_time)
freqs = mp.get_flux_freqs(box_x1) box_x1_data = sim.get_flux_data(box_x1) box_x2_data = sim.get_flux_data(box_x2) box_y1_data = sim.get_flux_data(box_y1) box_y2_data = sim.get_flux_data(box_y2) box_z1_data = sim.get_flux_data(box_z1) box_z2_data = sim.get_flux_data(box_z2) box_x1_flux0 = mp.get_fluxes(box_x1) sim.reset_meep() n_sphere = 2.0 geometry = [ mp.Sphere(material=mp.Medium(index=n_sphere), center=mp.Vector3(), radius=r) ] sim = mp.Simulation(resolution=resolution, cell_size=cell_size, boundary_layers=pml_layers, sources=sources, k_point=mp.Vector3(), symmetries=symmetries, geometry=geometry) box_x1 = sim.add_flux( frq_cen, dfrq, nfrq, mp.FluxRegion(center=mp.Vector3(x=-r), size=mp.Vector3(0, 2 * r, 2 * r)))
epsn, f0, gamma, sn, b0 = 1.5, 4.0, 4e-6, 0.4, 1.8 fcen, df, alpha = 0.2, 0.5, 1e-5 df1 = f0 - 1j * fcen * alpha df2 = fcen + 1j * gamma muperp = epsn + sn * df1 / (df1**2 - df2**2) xi = sn * df2 / (df1**2 - df2**2) susc = [ mp.GyrotropicSaturatedSusceptibility(frequency=f0, gamma=gamma, sigma=sn, bias=mp.Vector3(0, 0, b0)) ] mat = mp.Medium( epsilon=1, mu=epsn, H_susceptibilities=susc) #gyroelectric medium; this is just a dot cell #-------------------------------------------------------# # Set up simulation cell: #-------------------------------------------------------# tmax, L = 100, 20 #tmax: number of time steps over which sim will run cell, src_z, pml_layers = mp.Vector3(1, 1, 1), mp.Vector3(0, 0, -10), [mp.PML(1.0, mp.Z)] #df: frequency width of source #-------------------------------------------------------#
def __init__(self, resolution=10, is_negative_epsilon_ok=False, eigensolver_flops=0, eigensolver_flags=68, use_simple_preconditioner=False, force_mu=False, mu_input_file='', epsilon_input_file='', mesh_size=3, target_freq=0.0, tolerance=1.0e-7, num_bands=1, k_points=[], ensure_periodicity=True, geometry=[], geometry_lattice=mp.Lattice(), geometry_center=mp.Vector3(0, 0, 0), default_material=mp.Medium(epsilon=1), dimensions=3, random_fields=False, filename_prefix='', deterministic=False, verbose=False, optimize_grid_size=True, eigensolver_nwork=3, eigensolver_block_size=-11): self.mode_solver = None self.resolution = resolution self.eigensolver_flags = eigensolver_flags self.k_points = k_points self.geometry = geometry self.geometry_lattice = geometry_lattice self.geometry_center = mp.Vector3(*geometry_center) self.default_material = default_material self.random_fields = random_fields self.filename_prefix = filename_prefix self.optimize_grid_size = optimize_grid_size self.parity = '' self.iterations = 0 self.all_freqs = None self.freqs = [] self.band_range_data = [] self.total_run_time = 0 self.current_k = mp.Vector3() self.k_split_num = 1 self.k_split_index = 0 self.eigensolver_iters = [] grid_size = self._adjust_grid_size() if type(self.default_material) is not mp.Medium and callable( self.default_material): init_do_averaging(self.default_material) self.default_material.eps = False self.mode_solver = mode_solver( num_bands, self.resolution, self.geometry_lattice, tolerance, mesh_size, self.default_material, deterministic, target_freq, dimensions, verbose, ensure_periodicity, eigensolver_flops, is_negative_epsilon_ok, epsilon_input_file, mu_input_file, force_mu, use_simple_preconditioner, grid_size, eigensolver_nwork, eigensolver_block_size, )
weight=+1), mp.Near2FarRegion(center=mp.Vector3(z=+2*r), size=mp.Vector3(4*r,4*r,0), weight=-1)) sim.run(until_after_sources=10) input_flux = mp.get_fluxes(box_flux)[0] nearfield_box_data = sim.get_near2far_data(nearfield_box) # Watch it! Now we're also using 'get_near2far_data' sim.reset_meep() #%% SECOND RUN: FULL CONFIGURATION :) geometry = [mp.Sphere(material=mp.Medium(index=n_sphere), center=mp.Vector3(), radius=r)] sim = mp.Simulation(resolution=resolution, cell_size=cell_size, boundary_layers=pml_layers, sources=sources, k_point=mp.Vector3(), geometry=geometry) #%% SECOND RUN: FULL SIMULATION :D nearfield_box = sim.add_near2far(frq_cen, 0, 1, mp.Near2FarRegion(center=mp.Vector3(x=-2*r), size=mp.Vector3(0,4*r,4*r),
try: import meep.adjoint as mpa except: import adjoint as mpa import numpy as np from autograd import numpy as npa from autograd import tensor_jacobian_product import unittest from enum import Enum mp.quiet(True) 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
import matplotlib as mpl import meep import meep_ext from numpipe import scheduler, pbar import miepy job = scheduler() nm = 1e-9 um = 1e-6 ### Parameters W = 160 * nm H = 120 * nm material = meep_ext.material.Au() material = meep.Medium(index=3.5) geometry = [] q = miepy.quaternion.from_spherical_coords(0, 0) R = miepy.quaternion.as_rotation_matrix(q) X = W / np.sqrt(2 * (1 - np.cos(2 * np.pi / 3))) vertices = [ meep.Vector3(X, 0, 0), meep.Vector3(-X / 2, np.sqrt(3) / 2 * X, 0), meep.Vector3(-X / 2, -np.sqrt(3) / 2 * X, 0) ] geometry.append( meep.Prism(center=meep.Vector3(0, 0, 0), height=H,
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, sxz) 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, 0), material=thylakoid_material) cytoplasm_region = mp.Sphere(radius=cell_radius - thylakoid_thickness, center=mp.Vector3(0, 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, 0), # x, ,y ,z size=mp.Vector3(0, sxy, sxz), 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, ) def output_fields(sim): ez_output = open(base_directory + "Ez Field 430 HiAbs" + ".npy", 'wb') ez_array = sim.get_array(component=mp.Ez, cmplx=complex_f) ez_field_output = np.asarray(ez_array) np.save(ez_output, ez_field_output) ez_output.close() # ey_output = open(base_directory + "Ey Field 300 Std" + ".npy", 'wb') # ey_array = sim.get_array(component=mp.Ey, cmplx=complex_f) # ey_field_output = np.asarray(ey_array) # np.save(ey_output, ey_field_output) # ey_output.close() # # ex_output = open(base_directory + "Ex Field 300 std abs" + ".npy", 'wb') # ex_array = sim.get_array(component=mp.Ex, cmplx=complex_f) # ex_field_output = np.asarray(ex_array) # np.save(ex_output, ex_field_output) # ex_output.close() # eps_output = open(base_directory + "Refractive Index" + ".npy", 'wb') # eps_array = sim.get_array(component=mp.Dielectric, cmplx=complex_f) # np.save(eps_output, eps_array) # eps_output.close() sim.use_output_directory(self.base_directory) sim.run(mp.at_every(1, output_fields), until=t)