Waveguide cutoff

Below which frequency does a waveguide stop carrying a wave? Each mode of a hollow metal guide has a cutoff frequency, below which it does not propagate. For a mode whose field across the guide is \(\psi\), the cutoff follows from the eigenvalue problem \(\nabla^2 \psi + k_c^2 \psi = 0\) over the guide’s section, \(f_c = c\,k_c / (2\pi)\). The TE modes take \(\partial\psi/\partial n = 0\) on the wall and the TM modes \(\psi = 0\). For a rectangle \(a \times b\), \(k_c = \pi\sqrt{(m/a)^2 + (n/b)^2}\), so the standard WR-90 guide, 22.86 × 10.16 mm, has its lowest mode TE10 at \(c/(2a) = 6.557\) GHz. A round guide of radius \(r\) has TE11 at \(1.8412\,c/(2\pi r)\) and TM01 at \(2.4048\,c/(2\pi r)\), from the zeros of Bessel functions.

Here, NGSolve finds the cutoffs of both and checks them against the closed forms, then those of a ridge waveguide, whose ridge pulls the lowest cutoff down where no formula is left.

The electric field of the lowest mode in a rectangular, a ridge and a round waveguide, gathered in the ridge's gap

[1]:
import math

import ngsolve as ngs
import numpy as np
import planex as px
import scipy.sparse as sp
from scipy.sparse.linalg import eigsh

The cutoffs of a section

cutoffs solves the eigenvalue problem over a section in millimeters, for the TE modes with a free wall or the TM modes with \(\psi = 0\) on it, and returns the lowest cutoff frequencies in GHz with the modes. A TE section has one eigenvalue zero, the constant, which is no mode and is left out:

[3]:
c = 299_792_458e3  # mm/s


def cutoffs(section, kind, count=4):
    mesh = ngs.Mesh(px.OCCGeometry(section).GenerateMesh(maxh=1.0))
    mesh.Curve(3)
    V = ngs.H1(mesh, order=4, dirichlet=".*" if kind == "TM" else "")
    u, v = V.TnT()
    stiffness = ngs.BilinearForm(ngs.grad(u) * ngs.grad(v) * ngs.dx).Assemble()
    mass = ngs.BilinearForm(u * v * ngs.dx).Assemble()
    free = np.array(list(V.FreeDofs()), dtype=bool)
    K = sp.csr_matrix(stiffness.mat.CSR(), shape=(V.ndof, V.ndof))[free][:, free]
    M = sp.csr_matrix(mass.mat.CSR(), shape=(V.ndof, V.ndof))[free][:, free]
    values, vectors = eigsh(K, k=count + 1, M=M, sigma=-1e-3, which="LM")
    order = np.argsort(values)[1:] if kind == "TE" else np.argsort(values)[:count]
    modes = []
    for k in order:
        mode = ngs.GridFunction(V)
        mode.vec.FV().NumPy()[free] = vectors[:, k]
        modes.append(mode)
    return [c * math.sqrt(values[k]) / (2 * math.pi) / 1e9 for k in order], modes, mesh

A rectangular and a round guide

The WR-90 guide is 22.86 × 10.16 mm. Its TE modes TE10, TE20 and TE01 follow the closed form, and so do the round guide’s TE11 and TM01, for a radius of 10 mm:

[4]:
wr90 = px.QuickSketch().RectangleC(22.86, 10.16).Face()
te, wr90_modes, wr90_mesh = cutoffs(wr90, "TE")
for (m, n), f in zip(((1, 0), (2, 0), (0, 1)), te):
    print(f"TE{m}{n}", round(f, 4), "GHz | closed form", round(c / 2 * math.hypot(m / 22.86, n / 10.16) / 1e9, 4))

round_guide = px.Circle((0, 0), 10).Face()
te11, round_modes, round_mesh = cutoffs(round_guide, "TE")
tm01, _, _ = cutoffs(round_guide, "TM")
print("TE11", round(te11[0], 4), "GHz | closed form", round(1.841184 * c / (2 * math.pi * 10) / 1e9, 4))
print("TM01", round(tm01[0], 4), "GHz | closed form", round(2.404826 * c / (2 * math.pi * 10) / 1e9, 4))
TE10 6.5571 GHz | closed form 6.5571
TE20 13.1143 GHz | closed form 13.1143
TE01 14.7536 GHz | closed form 14.7536
TE11 8.7849 GHz | closed form 8.7849
TM01 11.4743 GHz | closed form 11.4743

A ridge waveguide

A ridge down the middle of the broad wall leaves a narrow gap, which carries the lowest mode’s field like a capacitor and lowers its cutoff, while the next mode stays nearly where it was. The guide carries a single mode over a wider band. The example is the WR-90 section with a ridge 6 mm wide reaching down to a gap of 3 mm. Across the guide, a TE mode’s electric field has the strength \(|\nabla\psi|\), here 1 in the middle of each guide and of the ridge’s gap. In the plain guide it is strongest in the middle and vanishes at the narrow walls. In the ridged guide it gathers in the gap and grows without bound at the ridge’s sharp corners (Figure 1):

[5]:
ridge = px.QuickSketch((0, 10.16 / 2 - (10.16 - 3) / 2)).RectangleC(6, 10.16 - 3).Face()
ridged = wr90 - ridge
te_ridge, ridge_modes, ridge_mesh = cutoffs(ridged, "TE")
print("lowest cutoff", round(te_ridge[0], 4), "GHz against", round(te[0], 4), "| next", round(te_ridge[1], 4),
      "GHz against", round(te[1], 4))
print("single-mode band", round(te_ridge[1] / te_ridge[0], 3), "against", round(te[1] / te[0], 3))
lowest cutoff 3.7663 GHz against 6.5571 | next 12.406 GHz against 13.1143
single-mode band 3.294 against 2.0
WR-90, TE10
(a) WR-90, TE10
Round, TE11
(b) Round, TE11
Ridged, the lowest mode
(c) Ridged, the lowest mode
Figure 1: The electric field of the lowest mode in the three guides