1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
import meep as mp
import numpy as np
import argparse
def main(args):
if args.perpendicular:
src_cmpt = mp.Hz
fcen = 0.21 # pulse center frequency
else:
src_cmpt = mp.Ez
fcen = 0.17 # pulse center frequency
n = 3.4 # index of waveguide
w = 1 # ring width
r = 1 # inner radius of ring
pad = 4 # padding between waveguide and edge of PML
dpml = 2 # thickness of PML
m = 5 # angular dependence
pml_layers = [mp.PML(dpml)]
sr = r + w + 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)
geometry = [mp.Block(center=mp.Vector3(r + (w / 2)),
size=mp.Vector3(w, mp.inf, mp.inf),
material=mp.Medium(index=n))]
# find resonant frequency of unperturbed geometry using broadband source
df = 0.2*fcen # pulse width (in frequency)
sources = [mp.Source(mp.GaussianSource(fcen,fwidth=df),
component=src_cmpt,
center=mp.Vector3(r+0.1))]
sim = mp.Simulation(cell_size=cell,
geometry=geometry,
boundary_layers=pml_layers,
resolution=args.res,
sources=sources,
dimensions=dimensions,
m=m)
h = mp.Harminv(src_cmpt, mp.Vector3(r+0.1), fcen, df)
sim.run(mp.after_sources(h),
until_after_sources=100)
frq_unperturbed = h.modes[0].freq
sim.reset_meep()
# unperturbed geometry with narrowband source centered at resonant frequency
fcen = frq_unperturbed
df = 0.05*fcen
sources = [mp.Source(mp.GaussianSource(fcen,fwidth=df),
component=src_cmpt,
center=mp.Vector3(r+0.1))]
sim = mp.Simulation(cell_size=cell,
geometry=geometry,
boundary_layers=pml_layers,
resolution=args.res,
sources=sources,
dimensions=dimensions,
m=m)
sim.run(until_after_sources=100)
deps = 1 - n**2
deps_inv = 1 - 1/n**2
if args.perpendicular:
para_integral = deps*2*np.pi*(r*abs(sim.get_field_point(mp.Ep, mp.Vector3(r)))**2 - (r+w)*abs(sim.get_field_point(mp.Ep, mp.Vector3(r+w)))**2)
perp_integral = deps_inv*2*np.pi*(-r*abs(sim.get_field_point(mp.Dr, mp.Vector3(r)))**2 + (r+w)*abs(sim.get_field_point(mp.Dr, mp.Vector3(r+w)))**2)
numerator_integral = para_integral + perp_integral
else:
numerator_integral = deps*2*np.pi*(r*abs(sim.get_field_point(mp.Ez, mp.Vector3(r)))**2 - (r+w)*abs(sim.get_field_point(mp.Ez, mp.Vector3(r+w)))**2)
denominator_integral = sim.electric_energy_in_box(center=mp.Vector3(0.5*sr), size=mp.Vector3(sr))
perturb_theory_dw_dR = -frq_unperturbed * numerator_integral / (4 * denominator_integral)
sim.reset_meep()
# perturbed geometry with narrowband source
dr = 0.01
sources = [mp.Source(mp.GaussianSource(fcen,fwidth=df),
component=src_cmpt,
center=mp.Vector3(r + dr + 0.1))]
geometry = [mp.Block(center=mp.Vector3(r + dr + (w / 2)),
size=mp.Vector3(w, mp.inf, mp.inf),
material=mp.Medium(index=n))]
sim = mp.Simulation(cell_size=cell,
geometry=geometry,
boundary_layers=pml_layers,
resolution=args.res,
sources=sources,
dimensions=dimensions,
m=m)
h = mp.Harminv(src_cmpt, mp.Vector3(r+dr+0.1), fcen, df)
sim.run(mp.after_sources(h),
until_after_sources=100)
frq_perturbed = h.modes[0].freq
finite_diff_dw_dR = (frq_perturbed - frq_unperturbed) / dr
print("dwdR:, {} (pert. theory), {} (finite diff.)".format(perturb_theory_dw_dR,finite_diff_dw_dR))
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-perpendicular', action='store_true', help='use perpendicular field source (default: parallel field source)')
parser.add_argument('-res', type=int, default=100, help='resolution (default: 100 pixels/um)')
args = parser.parse_args()
main(args)
|