Microstrip waveguide - vary gap#
In this example we calculate effective epsilon of the microstrip waveguides from [1]
Show code cell source
from collections import OrderedDict
import matplotlib.pyplot as plt
import numpy as np
import scipy.constants
import shapely
import shapely.ops
from shapely.geometry import LineString, box
from skfem import Basis, ElementTriP0
from skfem.io.meshio import from_meshio
from tqdm import tqdm
from femwell.maxwell.waveguide import compute_modes
from femwell.mesh import mesh_from_OrderedDict
def mesh_waveguide_1(filename, wsim, hclad, hsi, wcore_1, wcore_2, hcore, gap):
core_l = box(-wcore_1 - gap / 2, -hcore / 2, -gap / 2, hcore / 2)
core_r = box(gap / 2, -hcore / 2, wcore_2 + gap / 2, hcore / 2)
gap_b = box(-gap / 2, -hcore / 2, gap / 2, hcore / 2)
clad = box(-wsim / 2, -hcore / 2, wsim / 2, -hcore / 2 + hclad)
silicon = box(-wsim / 2, -hcore / 2, wsim / 2, -hcore / 2 - hsi)
combined = shapely.ops.unary_union([clad, silicon])
polygons = OrderedDict(
surface=LineString(combined.exterior),
core_l_interface=core_l.exterior,
core_l=core_l,
core_r_interface=core_r.exterior,
core_r=core_r,
gap_b=gap_b,
clad=clad,
silicon=silicon,
)
resolutions = dict(
core_r={"resolution": 0.0024, "distance": 2},
core_l={"resolution": 0.0024, "distance": 2},
core_r_interface={"resolution": 0.0024, "distance": 2, "SizeMax": 1},
core_l_interface={"resolution": 0.0024, "distance": 2, "SizeMax": 1},
# gap_b={"resolution": 0.001, "distance": .01, "SizeMax": .01},
silicon={"resolution": 0.5, "distance": 5},
)
return mesh_from_OrderedDict(
polygons, resolutions, filename=filename, default_resolution_max=10
)
frequencies = np.linspace(1e9, 16e9, 16)
gaps = [0.02, 0.06, 0.1, 0.2, 0.4, 0.6, 0.8, 1, 1.2, 1.4, 1.6, 1.8, 2]
gaps = gaps[::2]
epsilon_effs = np.zeros((len(gaps), len(frequencies), 2), dtype=complex)
for i, gap in enumerate(tqdm(gaps)):
mesh = from_meshio(
mesh_waveguide_1(
filename="mesh.msh",
wsim=30,
hclad=30,
hsi=0.64,
wcore_1=0.6,
wcore_2=0.6,
hcore=0.005,
gap=gap,
)
)
mesh = mesh.scaled((1e-3,) * 2)
for j, frequency in enumerate(tqdm(frequencies, leave=False)):
basis0 = Basis(mesh, ElementTriP0(), intorder=4)
epsilon = basis0.zeros().astype(complex)
epsilon[basis0.get_dofs(elements="silicon")] = 9.9 + 0.0005
epsilon[basis0.get_dofs(elements="clad")] = 1.0
epsilon[basis0.get_dofs(elements="gap_b")] = 1.0
epsilon[basis0.get_dofs(elements="core_l")] = 1 - 1j * 1 / (
18e-6 * 1e-3
) / scipy.constants.epsilon_0 / (2 * np.pi * frequency)
epsilon[basis0.get_dofs(elements="core_r")] = 1 - 1j * 1 / (
18e-6 * 1e-3
) / scipy.constants.epsilon_0 / (2 * np.pi * frequency)
# basis0.plot(np.real(epsilon), colorbar=True).show()
modes = compute_modes(
basis0,
epsilon,
wavelength=scipy.constants.speed_of_light / frequency,
num_modes=2,
metallic_boundaries=True,
)
# print(f"Gap: {gap}, Frequency: {frequency/1e9} GHz")
# print(f"Effective epsilons {modes.n_effs**2}")
# modes[0].show("E", part="real", plot_vectors=True, colorbar=True)
# modes[1].show("E", part="real", plot_vectors=True, colorbar=True)
epsilon_effs[i, j] = modes.n_effs**2
Show code cell output
0%| | 0/7 [00:00<?, ?it/s]
0%| | 0/16 [00:00<?, ?it/s]
6%|▋ | 1/16 [00:01<00:17, 1.14s/it]
12%|█▎ | 2/16 [00:02<00:15, 1.09s/it]
19%|█▉ | 3/16 [00:03<00:13, 1.07s/it]
25%|██▌ | 4/16 [00:04<00:13, 1.12s/it]
31%|███▏ | 5/16 [00:05<00:12, 1.15s/it]
38%|███▊ | 6/16 [00:06<00:11, 1.16s/it]
44%|████▍ | 7/16 [00:08<00:10, 1.19s/it]
50%|█████ | 8/16 [00:09<00:09, 1.20s/it]
56%|█████▋ | 9/16 [00:10<00:08, 1.21s/it]
62%|██████▎ | 10/16 [00:11<00:07, 1.22s/it]
69%|██████▉ | 11/16 [00:13<00:06, 1.23s/it]
75%|███████▌ | 12/16 [00:14<00:04, 1.23s/it]
81%|████████▏ | 13/16 [00:15<00:03, 1.24s/it]
88%|████████▊ | 14/16 [00:16<00:02, 1.25s/it]
94%|█████████▍| 15/16 [00:18<00:01, 1.25s/it]
100%|██████████| 16/16 [00:19<00:00, 1.25s/it]
14%|█▍ | 1/7 [00:19<01:58, 19.75s/it]
0%| | 0/16 [00:00<?, ?it/s]
6%|▋ | 1/16 [00:01<00:15, 1.04s/it]
12%|█▎ | 2/16 [00:02<00:14, 1.02s/it]
19%|█▉ | 3/16 [00:03<00:13, 1.03s/it]
25%|██▌ | 4/16 [00:04<00:13, 1.08s/it]
31%|███▏ | 5/16 [00:05<00:12, 1.13s/it]
38%|███▊ | 6/16 [00:06<00:11, 1.17s/it]
44%|████▍ | 7/16 [00:07<00:10, 1.19s/it]
50%|█████ | 8/16 [00:09<00:09, 1.21s/it]
56%|█████▋ | 9/16 [00:10<00:08, 1.21s/it]
62%|██████▎ | 10/16 [00:11<00:07, 1.22s/it]
69%|██████▉ | 11/16 [00:12<00:06, 1.23s/it]
75%|███████▌ | 12/16 [00:14<00:04, 1.24s/it]
81%|████████▏ | 13/16 [00:15<00:03, 1.25s/it]
88%|████████▊ | 14/16 [00:16<00:02, 1.25s/it]
94%|█████████▍| 15/16 [00:17<00:01, 1.25s/it]
100%|██████████| 16/16 [00:19<00:00, 1.25s/it]
29%|██▊ | 2/7 [00:39<01:38, 19.70s/it]
0%| | 0/16 [00:00<?, ?it/s]
6%|▋ | 1/16 [00:00<00:14, 1.01it/s]
12%|█▎ | 2/16 [00:01<00:13, 1.04it/s]
19%|█▉ | 3/16 [00:02<00:12, 1.04it/s]
25%|██▌ | 4/16 [00:04<00:12, 1.02s/it]
31%|███▏ | 5/16 [00:05<00:11, 1.06s/it]
38%|███▊ | 6/16 [00:06<00:10, 1.09s/it]
44%|████▍ | 7/16 [00:07<00:10, 1.11s/it]
50%|█████ | 8/16 [00:08<00:08, 1.12s/it]
56%|█████▋ | 9/16 [00:09<00:07, 1.14s/it]
62%|██████▎ | 10/16 [00:10<00:06, 1.15s/it]
69%|██████▉ | 11/16 [00:12<00:05, 1.15s/it]
75%|███████▌ | 12/16 [00:13<00:04, 1.16s/it]
81%|████████▏ | 13/16 [00:14<00:03, 1.17s/it]
88%|████████▊ | 14/16 [00:15<00:02, 1.17s/it]
94%|█████████▍| 15/16 [00:16<00:01, 1.17s/it]
100%|██████████| 16/16 [00:18<00:00, 1.18s/it]
43%|████▎ | 3/7 [00:57<01:16, 19.14s/it]
0%| | 0/16 [00:00<?, ?it/s]
6%|▋ | 1/16 [00:00<00:14, 1.04it/s]
12%|█▎ | 2/16 [00:01<00:13, 1.04it/s]
19%|█▉ | 3/16 [00:02<00:12, 1.04it/s]
25%|██▌ | 4/16 [00:03<00:11, 1.04it/s]
31%|███▏ | 5/16 [00:04<00:11, 1.03s/it]
38%|███▊ | 6/16 [00:06<00:10, 1.07s/it]
44%|████▍ | 7/16 [00:07<00:09, 1.09s/it]
50%|█████ | 8/16 [00:08<00:08, 1.12s/it]
56%|█████▋ | 9/16 [00:09<00:07, 1.13s/it]
62%|██████▎ | 10/16 [00:10<00:06, 1.14s/it]
69%|██████▉ | 11/16 [00:11<00:05, 1.15s/it]
75%|███████▌ | 12/16 [00:13<00:04, 1.16s/it]
81%|████████▏ | 13/16 [00:14<00:03, 1.17s/it]
88%|████████▊ | 14/16 [00:15<00:02, 1.17s/it]
94%|█████████▍| 15/16 [00:16<00:01, 1.17s/it]
100%|██████████| 16/16 [00:17<00:00, 1.17s/it]
57%|█████▋ | 4/7 [01:16<00:56, 18.82s/it]
0%| | 0/16 [00:00<?, ?it/s]
6%|▋ | 1/16 [00:01<00:15, 1.06s/it]
12%|█▎ | 2/16 [00:02<00:14, 1.05s/it]
19%|█▉ | 3/16 [00:03<00:13, 1.05s/it]
25%|██▌ | 4/16 [00:04<00:13, 1.12s/it]
31%|███▏ | 5/16 [00:05<00:12, 1.16s/it]
38%|███▊ | 6/16 [00:06<00:11, 1.19s/it]
44%|████▍ | 7/16 [00:08<00:10, 1.21s/it]
50%|█████ | 8/16 [00:09<00:09, 1.22s/it]
56%|█████▋ | 9/16 [00:10<00:08, 1.23s/it]
62%|██████▎ | 10/16 [00:11<00:07, 1.24s/it]
69%|██████▉ | 11/16 [00:13<00:06, 1.25s/it]
75%|███████▌ | 12/16 [00:14<00:05, 1.25s/it]
81%|████████▏ | 13/16 [00:15<00:03, 1.25s/it]
88%|████████▊ | 14/16 [00:16<00:02, 1.25s/it]
94%|█████████▍| 15/16 [00:18<00:01, 1.25s/it]
100%|██████████| 16/16 [00:19<00:00, 1.25s/it]
71%|███████▏ | 5/7 [01:36<00:38, 19.20s/it]
0%| | 0/16 [00:00<?, ?it/s]
6%|▋ | 1/16 [00:00<00:14, 1.04it/s]
12%|█▎ | 2/16 [00:01<00:13, 1.05it/s]
19%|█▉ | 3/16 [00:02<00:12, 1.05it/s]
25%|██▌ | 4/16 [00:03<00:12, 1.02s/it]
31%|███▏ | 5/16 [00:05<00:11, 1.06s/it]
38%|███▊ | 6/16 [00:06<00:10, 1.09s/it]
44%|████▍ | 7/16 [00:07<00:10, 1.11s/it]
50%|█████ | 8/16 [00:08<00:09, 1.13s/it]
56%|█████▋ | 9/16 [00:09<00:08, 1.15s/it]
62%|██████▎ | 10/16 [00:10<00:06, 1.16s/it]
69%|██████▉ | 11/16 [00:12<00:05, 1.17s/it]
75%|███████▌ | 12/16 [00:13<00:04, 1.17s/it]
81%|████████▏ | 13/16 [00:14<00:03, 1.18s/it]
88%|████████▊ | 14/16 [00:15<00:02, 1.18s/it]
94%|█████████▍| 15/16 [00:16<00:01, 1.18s/it]
100%|██████████| 16/16 [00:18<00:00, 1.19s/it]
86%|████████▌ | 6/7 [01:54<00:18, 18.99s/it]
0%| | 0/16 [00:00<?, ?it/s]
6%|▋ | 1/16 [00:00<00:14, 1.02it/s]
12%|█▎ | 2/16 [00:01<00:13, 1.04it/s]
19%|█▉ | 3/16 [00:02<00:12, 1.03it/s]
25%|██▌ | 4/16 [00:03<00:11, 1.03it/s]
31%|███▏ | 5/16 [00:05<00:11, 1.03s/it]
38%|███▊ | 6/16 [00:06<00:10, 1.08s/it]
44%|████▍ | 7/16 [00:07<00:10, 1.12s/it]
50%|█████ | 8/16 [00:08<00:09, 1.14s/it]
56%|█████▋ | 9/16 [00:09<00:08, 1.16s/it]
62%|██████▎ | 10/16 [00:10<00:07, 1.17s/it]
69%|██████▉ | 11/16 [00:12<00:05, 1.18s/it]
75%|███████▌ | 12/16 [00:13<00:04, 1.18s/it]
81%|████████▏ | 13/16 [00:14<00:03, 1.19s/it]
88%|████████▊ | 14/16 [00:15<00:02, 1.19s/it]
94%|█████████▍| 15/16 [00:16<00:01, 1.20s/it]
100%|██████████| 16/16 [00:18<00:00, 1.20s/it]
100%|██████████| 7/7 [02:13<00:00, 18.89s/it]
100%|██████████| 7/7 [02:13<00:00, 19.05s/it]
Show code cell source
plt.figure(figsize=(10, 14))
plt.xlabel("Frequency / GHz")
plt.ylabel("Effective dielectric constant")
for i, gap in enumerate(gaps):
plt.plot(frequencies / 1e9, epsilon_effs[i, :, 0].real)
plt.annotate(
xy=(frequencies[-1] / 1e9, epsilon_effs[i, :, 0].real[-1]), text=str(gap), va="center"
)
plt.plot(frequencies / 1e9, epsilon_effs[i, :, 1].real)
plt.annotate(
xy=(frequencies[-1] / 1e9, epsilon_effs[i, :, 1].real[-1]), text=str(gap), va="center"
)
plt.show()
Bibliography#
[1]
R.H. Jansen. High-speed computation of single and coupled microstrip parameters including dispersion, high-order modes, loss and finite strip thickness. IEEE Transactions on Microwave Theory and Techniques, 26(2):75–82, February 1978. URL: http://dx.doi.org/10.1109/TMTT.1978.1129316, doi:10.1109/tmtt.1978.1129316.