Microstrip waveguide - vary gap

Contents

Microstrip waveguide - vary gap#

In this example we calculate effective epsilon of the microstrip waveguides from [1]

Hide 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
Hide code cell output
  0%|          | 0/7 [00:00<?, ?it/s]

  0%|          | 0/16 [00:00<?, ?it/s]


  6%|▋         | 1/16 [00:01<00:16,  1.11s/it]


 12%|█▎        | 2/16 [00:02<00:14,  1.05s/it]


 19%|█▉        | 3/16 [00:03<00:13,  1.03s/it]


 25%|██▌       | 4/16 [00:04<00:12,  1.08s/it]


 31%|███▏      | 5/16 [00:05<00:12,  1.11s/it]


 38%|███▊      | 6/16 [00:06<00:11,  1.13s/it]


 44%|████▍     | 7/16 [00:07<00:10,  1.15s/it]


 50%|█████     | 8/16 [00:08<00:09,  1.16s/it]


 56%|█████▋    | 9/16 [00:10<00:08,  1.18s/it]


 62%|██████▎   | 10/16 [00:11<00:07,  1.19s/it]


 69%|██████▉   | 11/16 [00:12<00:06,  1.21s/it]


 75%|███████▌  | 12/16 [00:13<00:04,  1.21s/it]


 81%|████████▏ | 13/16 [00:15<00:03,  1.21s/it]


 88%|████████▊ | 14/16 [00:16<00:02,  1.21s/it]


 94%|█████████▍| 15/16 [00:17<00:01,  1.22s/it]


100%|██████████| 16/16 [00:18<00:00,  1.22s/it]


                                               

 14%|█▍        | 1/7 [00:19<01:55, 19.26s/it]

  0%|          | 0/16 [00:00<?, ?it/s]


  6%|▋         | 1/16 [00:01<00:15,  1.02s/it]


 12%|█▎        | 2/16 [00:02<00:14,  1.00s/it]


 19%|█▉        | 3/16 [00:02<00:12,  1.01it/s]


 25%|██▌       | 4/16 [00:04<00:12,  1.06s/it]


 31%|███▏      | 5/16 [00:05<00:12,  1.11s/it]


 38%|███▊      | 6/16 [00:06<00:11,  1.13s/it]


 44%|████▍     | 7/16 [00:07<00:10,  1.16s/it]


 50%|█████     | 8/16 [00:08<00:09,  1.17s/it]


 56%|█████▋    | 9/16 [00:10<00:08,  1.18s/it]


 62%|██████▎   | 10/16 [00:11<00:07,  1.20s/it]


 69%|██████▉   | 11/16 [00:12<00:06,  1.20s/it]


 75%|███████▌  | 12/16 [00:13<00:04,  1.21s/it]


 81%|████████▏ | 13/16 [00:15<00:03,  1.22s/it]


 88%|████████▊ | 14/16 [00:16<00:02,  1.22s/it]


 94%|█████████▍| 15/16 [00:17<00:01,  1.22s/it]


100%|██████████| 16/16 [00:18<00:00,  1.22s/it]


                                               

 29%|██▊       | 2/7 [00:38<01:36, 19.21s/it]

  0%|          | 0/16 [00:00<?, ?it/s]


  6%|▋         | 1/16 [00:00<00:14,  1.06it/s]


 12%|█▎        | 2/16 [00:01<00:13,  1.07it/s]


 19%|█▉        | 3/16 [00:02<00:12,  1.06it/s]


 25%|██▌       | 4/16 [00:03<00:12,  1.00s/it]


 31%|███▏      | 5/16 [00:05<00:11,  1.04s/it]


 38%|███▊      | 6/16 [00:06<00:10,  1.06s/it]


 44%|████▍     | 7/16 [00:07<00:09,  1.08s/it]


 50%|█████     | 8/16 [00:08<00:08,  1.09s/it]


 56%|█████▋    | 9/16 [00:09<00:07,  1.11s/it]


 62%|██████▎   | 10/16 [00:10<00:06,  1.12s/it]


 69%|██████▉   | 11/16 [00:11<00:05,  1.13s/it]


 75%|███████▌  | 12/16 [00:12<00:04,  1.13s/it]


 81%|████████▏ | 13/16 [00:14<00:03,  1.14s/it]


 88%|████████▊ | 14/16 [00:15<00:02,  1.14s/it]


 94%|█████████▍| 15/16 [00:16<00:01,  1.15s/it]


100%|██████████| 16/16 [00:17<00:00,  1.15s/it]


                                               

 43%|████▎     | 3/7 [00:56<01:14, 18.67s/it]

  0%|          | 0/16 [00:00<?, ?it/s]


  6%|▋         | 1/16 [00:00<00:14,  1.07it/s]


 12%|█▎        | 2/16 [00:01<00:12,  1.08it/s]


 19%|█▉        | 3/16 [00:02<00:11,  1.09it/s]


 25%|██▌       | 4/16 [00:03<00:11,  1.07it/s]


 31%|███▏      | 5/16 [00:04<00:10,  1.01it/s]


 38%|███▊      | 6/16 [00:05<00:10,  1.03s/it]


 44%|████▍     | 7/16 [00:07<00:09,  1.06s/it]


 50%|█████     | 8/16 [00:08<00:08,  1.08s/it]


 56%|█████▋    | 9/16 [00:09<00:07,  1.10s/it]


 62%|██████▎   | 10/16 [00:10<00:06,  1.12s/it]


 69%|██████▉   | 11/16 [00:11<00:05,  1.12s/it]


 75%|███████▌  | 12/16 [00:12<00:04,  1.13s/it]


 81%|████████▏ | 13/16 [00:13<00:03,  1.14s/it]


 88%|████████▊ | 14/16 [00:15<00:02,  1.14s/it]


 94%|█████████▍| 15/16 [00:16<00:01,  1.15s/it]


100%|██████████| 16/16 [00:17<00:00,  1.15s/it]


                                               

 57%|█████▋    | 4/7 [01:14<00:55, 18.35s/it]

  0%|          | 0/16 [00:00<?, ?it/s]


  6%|▋         | 1/16 [00:01<00:15,  1.03s/it]


 12%|█▎        | 2/16 [00:02<00:14,  1.02s/it]


 19%|█▉        | 3/16 [00:03<00:13,  1.06s/it]


 25%|██▌       | 4/16 [00:04<00:13,  1.10s/it]


 31%|███▏      | 5/16 [00:05<00:12,  1.13s/it]


 38%|███▊      | 6/16 [00:06<00:11,  1.16s/it]


 44%|████▍     | 7/16 [00:07<00:10,  1.17s/it]


 50%|█████     | 8/16 [00:09<00:09,  1.18s/it]


 56%|█████▋    | 9/16 [00:10<00:08,  1.20s/it]


 62%|██████▎   | 10/16 [00:11<00:07,  1.20s/it]


 69%|██████▉   | 11/16 [00:12<00:06,  1.21s/it]


 75%|███████▌  | 12/16 [00:14<00:04,  1.21s/it]


 81%|████████▏ | 13/16 [00:15<00:03,  1.22s/it]


 88%|████████▊ | 14/16 [00:16<00:02,  1.22s/it]


 94%|█████████▍| 15/16 [00:17<00:01,  1.22s/it]


100%|██████████| 16/16 [00:18<00:00,  1.22s/it]


                                               

 71%|███████▏  | 5/7 [01:33<00:37, 18.73s/it]

  0%|          | 0/16 [00:00<?, ?it/s]


  6%|▋         | 1/16 [00:00<00:14,  1.07it/s]


 12%|█▎        | 2/16 [00:01<00:13,  1.07it/s]


 19%|█▉        | 3/16 [00:02<00:12,  1.07it/s]


 25%|██▌       | 4/16 [00:03<00:11,  1.00it/s]


 31%|███▏      | 5/16 [00:05<00:11,  1.05s/it]


 38%|███▊      | 6/16 [00:06<00:10,  1.08s/it]


 44%|████▍     | 7/16 [00:07<00:09,  1.10s/it]


 50%|█████     | 8/16 [00:08<00:08,  1.11s/it]


 56%|█████▋    | 9/16 [00:09<00:07,  1.12s/it]


 62%|██████▎   | 10/16 [00:10<00:06,  1.13s/it]


 69%|██████▉   | 11/16 [00:11<00:05,  1.14s/it]


 75%|███████▌  | 12/16 [00:13<00:04,  1.14s/it]


 81%|████████▏ | 13/16 [00:14<00:03,  1.15s/it]


 88%|████████▊ | 14/16 [00:15<00:02,  1.16s/it]


 94%|█████████▍| 15/16 [00:16<00:01,  1.16s/it]


100%|██████████| 16/16 [00:17<00:00,  1.15s/it]


                                               

 86%|████████▌ | 6/7 [01:51<00:18, 18.53s/it]

  0%|          | 0/16 [00:00<?, ?it/s]


  6%|▋         | 1/16 [00:00<00:14,  1.03it/s]


 12%|█▎        | 2/16 [00:01<00:13,  1.05it/s]


 19%|█▉        | 3/16 [00:02<00:12,  1.06it/s]


 25%|██▌       | 4/16 [00:03<00:11,  1.06it/s]


 31%|███▏      | 5/16 [00:04<00:11,  1.01s/it]


 38%|███▊      | 6/16 [00:06<00:10,  1.06s/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.15s/it]


 81%|████████▏ | 13/16 [00:14<00:03,  1.16s/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]


                                               

100%|██████████| 7/7 [02:10<00:00, 18.45s/it]
100%|██████████| 7/7 [02:10<00:00, 18.59s/it]

Hide 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()
../../_images/03c90a45dae4414679333f31de14574f3a53d489de2862b09848f86c8f454033.png

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.