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 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
import argparse
import numpy as np
from meep.materials import Ag
import meep as mp
parser = argparse.ArgumentParser()
parser.add_argument("-res", type=int, default=50, help="resolution (pixels/um)")
parser.add_argument("-nf", type=int, default=500, help="number of frequencies")
parser.add_argument(
"-nsrc",
type=int,
default=15,
help="number of line sources with cosine Fourier series amplitude function (method 3)",
)
parser.add_argument(
"-textured",
action="store_true",
default=False,
help="flat (default) or textured surface",
)
parser.add_argument(
"-method",
type=int,
choices=[2, 3],
default=2,
help="type of method: (2) single dipole with 1 run per dipole or (3) line source with cosine Fourier series amplitude function",
)
args = parser.parse_args()
resolution = args.res
dpml = 1.0
dair = 0.9
hrod = 0.6
wrod = 0.8
dsub = 5.4
dAg = 0.4
sx = 1.5
sy = dpml + dair + hrod + dsub + dAg
cell_size = mp.Vector3(sx, sy)
pml_layers = [mp.PML(direction=mp.Y, thickness=dpml, side=mp.High)]
fcen = 1.0
df = 0.2
nfreq = args.nf
nsrc = args.nsrc
ndipole = int(sx * resolution)
run_time = 2 * nfreq / df
geometry = [
mp.Block(
material=mp.Medium(index=3.45),
center=mp.Vector3(0, 0.5 * sy - dpml - dair - hrod - 0.5 * dsub),
size=mp.Vector3(mp.inf, dsub, mp.inf),
),
mp.Block(
material=Ag,
center=mp.Vector3(0, -0.5 * sy + 0.5 * dAg),
size=mp.Vector3(mp.inf, dAg, mp.inf),
),
]
if args.textured:
geometry.append(
mp.Block(
material=mp.Medium(index=3.45),
center=mp.Vector3(0, 0.5 * sy - dpml - dair - 0.5 * hrod),
size=mp.Vector3(wrod, hrod, mp.inf),
)
)
def src_amp_func(n):
def _src_amp_func(p):
if n == 0:
return 1 / np.sqrt(sx)
else:
return np.sqrt(2 / sx) * np.cos(n * np.pi * (p.x + 0.5 * sx) / sx)
return _src_amp_func
def compute_flux(m, n):
if m == 2:
sources = [
mp.Source(
mp.GaussianSource(fcen, fwidth=df),
component=mp.Ez,
center=mp.Vector3(
sx * (-0.5 + n / ndipole), -0.5 * sy + dAg + 0.5 * dsub
),
)
]
else:
sources = [
mp.Source(
mp.GaussianSource(fcen, fwidth=df),
component=mp.Ez,
center=mp.Vector3(0, -0.5 * sy + dAg + 0.5 * dsub),
size=mp.Vector3(sx, 0),
amp_func=src_amp_func(n),
)
]
sim = mp.Simulation(
cell_size=cell_size,
resolution=resolution,
k_point=mp.Vector3(),
boundary_layers=pml_layers,
geometry=geometry,
sources=sources,
)
flux_mon = sim.add_flux(
fcen,
df,
nfreq,
mp.FluxRegion(center=mp.Vector3(0, 0.5 * sy - dpml), size=mp.Vector3(sx)),
)
sim.run(until=run_time)
flux = mp.get_fluxes(flux_mon)
freqs = mp.get_flux_freqs(flux_mon)
return freqs, flux
if args.method == 2:
fluxes = np.zeros((nfreq, ndipole))
for d in range(ndipole):
freqs, fluxes[:, d] = compute_flux(2, d)
else:
fluxes = np.zeros((nfreq, nsrc))
for d in range(nsrc):
freqs, fluxes[:, d] = compute_flux(3, d)
if mp.am_master():
with open(
f'method{args.method}_{"textured" if args.textured else "flat"}_res{resolution}_nfreq{nfreq}_{"ndipole" if args.method == 2 else "nsrc"}{ndipole if args.method == 2 else nsrc}.npz',
"wb",
) as f:
np.savez(f, freqs=freqs, fluxes=fluxes)
|