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:23,  1.56s/it]


 12%|█▎        | 2/16 [00:03<00:21,  1.50s/it]


 19%|█▉        | 3/16 [00:04<00:19,  1.47s/it]


 25%|██▌       | 4/16 [00:06<00:18,  1.55s/it]


 31%|███▏      | 5/16 [00:07<00:17,  1.59s/it]


 38%|███▊      | 6/16 [00:09<00:16,  1.62s/it]


 44%|████▍     | 7/16 [00:11<00:14,  1.64s/it]


 50%|█████     | 8/16 [00:12<00:13,  1.66s/it]


 56%|█████▋    | 9/16 [00:14<00:11,  1.67s/it]


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


 69%|██████▉   | 11/16 [00:17<00:08,  1.70s/it]


 75%|███████▌  | 12/16 [00:19<00:06,  1.71s/it]


 81%|████████▏ | 13/16 [00:21<00:05,  1.72s/it]


 88%|████████▊ | 14/16 [00:23<00:03,  1.72s/it]


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


100%|██████████| 16/16 [00:26<00:00,  1.72s/it]


                                               

 14%|█▍        | 1/7 [00:27<02:42, 27.14s/it]

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


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


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


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


 25%|██▌       | 4/16 [00:05<00:15,  1.32s/it]


 31%|███▏      | 5/16 [00:06<00:15,  1.37s/it]


 38%|███▊      | 6/16 [00:08<00:13,  1.39s/it]


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


 50%|█████     | 8/16 [00:11<00:11,  1.44s/it]


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


 62%|██████▎   | 10/16 [00:13<00:08,  1.46s/it]


 69%|██████▉   | 11/16 [00:15<00:07,  1.47s/it]


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


 81%|████████▏ | 13/16 [00:18<00:04,  1.49s/it]


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


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


100%|██████████| 16/16 [00:22<00:00,  1.49s/it]


                                               

 29%|██▊       | 2/7 [00:50<02:04, 24.95s/it]

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


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


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


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


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


 31%|███▏      | 5/16 [00:06<00:14,  1.32s/it]


 38%|███▊      | 6/16 [00:07<00:13,  1.36s/it]


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


 50%|█████     | 8/16 [00:10<00:11,  1.41s/it]


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


 62%|██████▎   | 10/16 [00:13<00:08,  1.43s/it]


 69%|██████▉   | 11/16 [00:15<00:07,  1.44s/it]


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


 81%|████████▏ | 13/16 [00:18<00:04,  1.45s/it]


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


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


100%|██████████| 16/16 [00:22<00:00,  1.46s/it]


                                               

 43%|████▎     | 3/7 [01:13<01:36, 24.02s/it]

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


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


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


 19%|█▉        | 3/16 [00:04<00:18,  1.39s/it]


 25%|██▌       | 4/16 [00:05<00:17,  1.49s/it]


 31%|███▏      | 5/16 [00:07<00:17,  1.58s/it]


 38%|███▊      | 6/16 [00:09<00:16,  1.61s/it]


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


 50%|█████     | 8/16 [00:12<00:13,  1.64s/it]


 56%|█████▋    | 9/16 [00:14<00:11,  1.64s/it]


 62%|██████▎   | 10/16 [00:15<00:09,  1.65s/it]


 69%|██████▉   | 11/16 [00:17<00:08,  1.66s/it]


 75%|███████▌  | 12/16 [00:19<00:06,  1.67s/it]


 81%|████████▏ | 13/16 [00:20<00:05,  1.68s/it]


 88%|████████▊ | 14/16 [00:22<00:03,  1.68s/it]


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


100%|██████████| 16/16 [00:26<00:00,  1.69s/it]


                                               

 57%|█████▋    | 4/7 [01:40<01:15, 25.02s/it]

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


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


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


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


 25%|██▌       | 4/16 [00:05<00:15,  1.33s/it]


 31%|███▏      | 5/16 [00:06<00:15,  1.41s/it]


 38%|███▊      | 6/16 [00:08<00:14,  1.46s/it]


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


 50%|█████     | 8/16 [00:11<00:12,  1.52s/it]


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


 62%|██████▎   | 10/16 [00:14<00:09,  1.56s/it]


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


 75%|███████▌  | 12/16 [00:17<00:06,  1.59s/it]


 81%|████████▏ | 13/16 [00:19<00:04,  1.60s/it]


 88%|████████▊ | 14/16 [00:21<00:03,  1.61s/it]


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


100%|██████████| 16/16 [00:24<00:00,  1.61s/it]


                                               

 71%|███████▏  | 5/7 [02:05<00:50, 25.01s/it]

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


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


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


 19%|█▉        | 3/16 [00:04<00:17,  1.37s/it]


 25%|██▌       | 4/16 [00:05<00:16,  1.37s/it]


 31%|███▏      | 5/16 [00:07<00:15,  1.45s/it]


 38%|███▊      | 6/16 [00:08<00:15,  1.50s/it]


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


 50%|█████     | 8/16 [00:11<00:12,  1.58s/it]


 56%|█████▋    | 9/16 [00:13<00:11,  1.60s/it]


 62%|██████▎   | 10/16 [00:15<00:09,  1.62s/it]


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


 75%|███████▌  | 12/16 [00:18<00:06,  1.64s/it]


 81%|████████▏ | 13/16 [00:20<00:04,  1.65s/it]


 88%|████████▊ | 14/16 [00:21<00:03,  1.65s/it]


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


100%|██████████| 16/16 [00:25<00:00,  1.67s/it]


                                               

 86%|████████▌ | 6/7 [02:30<00:25, 25.30s/it]

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


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


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


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


 25%|██▌       | 4/16 [00:05<00:16,  1.39s/it]


 31%|███▏      | 5/16 [00:06<00:15,  1.44s/it]


 38%|███▊      | 6/16 [00:08<00:14,  1.47s/it]


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


 50%|█████     | 8/16 [00:11<00:12,  1.52s/it]


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


 62%|██████▎   | 10/16 [00:14<00:09,  1.56s/it]


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


 75%|███████▌  | 12/16 [00:17<00:06,  1.57s/it]


 81%|████████▏ | 13/16 [00:19<00:04,  1.57s/it]


 88%|████████▊ | 14/16 [00:21<00:03,  1.57s/it]


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


100%|██████████| 16/16 [00:24<00:00,  1.59s/it]


                                               

100%|██████████| 7/7 [02:55<00:00, 25.15s/it]
100%|██████████| 7/7 [02:55<00:00, 25.10s/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/acc9cdd12eea0b215524a5ca0a79da387beaa6606dc8ed71069a2d9be6c290d7.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.