Skip to content

Commit

Permalink
add coplanar wavegudie example
Browse files Browse the repository at this point in the history
  • Loading branch information
HelgeGehring committed Mar 14, 2024
1 parent 5562c5e commit 73e5226
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/_toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ parts:
- file: photonics/examples/refinement.py
- file: photonics/examples/propagation_loss.py
- file: electronics/examples/capacitor.py
- file: electronics/examples/coplanar_waveguide.py

- caption: Julia Examples
chapters:
Expand Down
140 changes: 140 additions & 0 deletions docs/electronics/examples/coplanar_waveguide.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# ---
# jupyter:
# jupytext:
# formats: py:percent,md:myst
# text_representation:
# extension: .py
# format_name: percent
# format_version: '1.3'
# jupytext_version: 1.15.0
# kernelspec:
# display_name: Python 3
# name: python3
# ---
# %% [markdown]
# # Coplanar waveguide

# In this example we calculate effective epsilon of the coplanar waveguides from {cite}`Jansen1978`

# %% tags=["hide-input"]

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([core_l, core_r, clad, silicon])

polygons = OrderedDict(
surface=LineString(combined.exterior),
interface=LineString(
[
(-wcore_1 - gap, -hcore / 2),
(wcore_2 + gap, -hcore / 2),
]
),
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.004, "distance": 2},
core_l={"resolution": 0.004, "distance": 2},
gap_b={"resolution": 0.004, "distance": 2},
silicon={"resolution": 0.1, "distance": 5},
interface={"resolution": 0.2, "distance": 1},
)

return mesh_from_OrderedDict(
polygons, resolutions, filename=filename, default_resolution_max=30
)


# %% tags=["hide-output"]
frequencies = np.linspace(1e9, 18e9, 18)
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]
epsilon_effs = np.zeros((len(gaps), len(frequencies), 2), dtype=complex)

for i, gap in enumerate(tqdm(gaps)):
for j, frequency in enumerate(tqdm(frequencies, leave=False)):
mesh = from_meshio(
mesh_waveguide_1(
filename="mesh.msh",
wsim=30,
hclad=100,
hsi=0.64,
wcore_1=0.6,
wcore_2=0.6,
hcore=0.005,
gap=gap,
)
)
mesh = mesh.scaled((1e-3,) * 2)

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 / frequency
)
epsilon[basis0.get_dofs(elements="core_r")] = (
1 - 1j * 1 / (18e-6 * 1e-3) / scipy.constants.epsilon_0 / frequency
)
# basis0.plot(np.real(epsilon), colorbar=True).show()

modes = compute_modes(
basis0,
epsilon,
wavelength=scipy.constants.speed_of_light / frequency,
mu_r=1,
num_modes=2,
metallic_boundaries=True,
)
print("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

# %% tags=["hide-input"]
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()
14 changes: 14 additions & 0 deletions docs/references.bib
Original file line number Diff line number Diff line change
Expand Up @@ -328,3 +328,17 @@ @article{Klenner2016
month = may,
pages = {11043}
}
@article{Jansen1978,
title = {High-Speed Computation of Single and Coupled Microstrip Parameters Including Dispersion, High-Order Modes, Loss and Finite Strip Thickness},
volume = {26},
issn = {0018-9480},
url = {http://dx.doi.org/10.1109/TMTT.1978.1129316},
doi = {10.1109/tmtt.1978.1129316},
number = {2},
journal = {IEEE Transactions on Microwave Theory and Techniques},
publisher = {Institute of Electrical and Electronics Engineers (IEEE)},
author = {Jansen, R.H.},
year = {1978},
month = feb,
pages = {75–82}
}

0 comments on commit 73e5226

Please sign in to comment.