方形導波管モードの分散特性¶
In [1]:
import numpy as np # 数値計算ライブラリ NumPy を読み込む
import matplotlib # グラフ描画ライブラリ matplotlib を読み込む
#matplotlib.use('Agg') # GUIなし環境用に 'Agg' バックエンドを指定(画像ファイル出力専用)
import matplotlib.pyplot as plt # グラフ描画用の pyplot モジュールを読み込む
import pandas as pd
In [2]:
# Constants
CCC = 299.79
pi = np.pi
In [3]:
# Waveguide dimensions [mm]
a = 22.90
b = 10.20
In [4]:
# Mode index range (adjust as needed)
max_m = 2
max_n = 2
モード生成関数¶
In [5]:
def generate_modes(max_m, max_n):
modes = []
for m in range(0, max_m + 1):
for n in range(0, max_n + 1):
if m == 0 and n == 0:
continue
# TE mode (m or n may be zero, but not both)
modes.append(('TE', m, n))
# TM mode (both m and n must be > 0)
if m > 0 and n > 0:
modes.append(('TM', m, n))
return modes
In [6]:
modes = generate_modes(2, 2)
print(modes)
[('TE', 0, 1), ('TE', 0, 2), ('TE', 1, 0), ('TE', 1, 1), ('TM', 1, 1), ('TE', 1, 2), ('TM', 1, 2), ('TE', 2, 0), ('TE', 2, 1), ('TM', 2, 1), ('TE', 2, 2), ('TM', 2, 2)]
方形導波管TE$_{mn}$,TM$_{mn}$モードのカットオフ波数¶
\begin{gather*} k_c = \pi \sqrt{\left(\frac{m}{a}\right)^2 + \left(\frac{n}{b}\right)^2} \end{gather*}In [7]:
def cutoff_wavenumber(m, n, a, b):
"""k_c = π * sqrt((m/a)^2 + (n/b)^2)"""
return pi * np.sqrt((m / a) ** 2 + (n / b) ** 2)
カットオフ周波数¶
In [8]:
def cutoff_frequency(kc):
"""f_c = (c / (2π)) * k_c"""
return (CCC / (2 * pi)) * kc
カットオフ波数・カットオフ周波数・カットオフ波長を一覧表示する関数¶
In [9]:
def mode_table_():
modes = generate_modes(max_m, max_n)
rows = []
for mode, m, n in modes:
kc = cutoff_wavenumber(m, n, a, b)
f_c = cutoff_frequency(kc) # [GHz]
lambda_c = CCC / f_c # [mm]
rows.append((mode, m, n, kc, f_c, lambda_c))
# Sort by cutoff wavenumber (ascending)
rows.sort(key=lambda x: x[3])
print(f"{'Mode':<6} {'m':>2} {'n':>2} {'k_c (1/m)':>12} {'f_c (GHz)':>12} {'λ_c (mm)':>12}")
for mode, m, n, kc, fGHz, lam_mm in rows:
print(f"{mode:<6} {m:2d} {n:2d} {kc:12.4e} {fGHz:12.4f} {lam_mm:12.4f}")
In [10]:
def mode_table(max_m, max_n, a, b):
modes = generate_modes(max_m, max_n)
rows = []
for mode, m, n in modes:
kc = cutoff_wavenumber(m, n, a, b)
f_c = cutoff_frequency(kc) # [GHz]
lambda_c = CCC / f_c # [mm]
rows.append({
"Mode": f"{mode}$_{{{m}{n}}}$", # LaTeX風の添字表記
"m": m,
"n": n,
"k_c (1/mm)": kc,
"f_c (GHz)": f_c,
"λ_c (mm)": lambda_c
})
# DataFrame に変換して k_c で昇順ソート
df = pd.DataFrame(rows)
df = df.sort_values(by="k_c (1/mm)").reset_index(drop=True)
return df
In [11]:
def plot_dispersion():
modes = generate_modes(max_m, max_n)
fmin = 0.000001 # 0 Hzは避ける(k0=0で割り算が発生)
fmax = 30
freq = np.linspace(fmin, fmax, 1000)
k0 = 2 * pi * freq / CCC
# (mode, m, n, kc, f_c) の一覧を作り,f_c 昇順に
mode_info = []
for mode, m, n in modes:
kc = cutoff_wavenumber(m, n, a, b)
f_c = cutoff_frequency(kc) # Hz
mode_info.append((mode, m, n, kc, f_c))
mode_info.sort(key=lambda x: x[4])
plt.figure(figsize=(8, 6))
for mode, m, n, kc, f_c in mode_info:
# 表示レンジ外のモードはスキップ
if f_c >= fmax:
continue
# 伝搬領域のみ(f >= f_c)のマスク
mask = freq >= f_c
if np.count_nonzero(mask) < 2:
continue
beta_norm = np.sqrt(1.0 - (kc / k0[mask])**2)
# カットオフ点 (f_c, 0) を先頭に足して連続描画
freq_plot = np.concatenate(([f_c], freq[mask]))
beta_plot = np.concatenate(([0.0], beta_norm))
# 凡例ラベルは数式モードで添え字表示
label = rf"$\mathrm{{{mode}}}_{{{m}{n}}}$"
plt.plot(freq_plot, beta_plot, label=label)
# 体裁
plt.xlim(0, fmax)
plt.ylim(0, 1)
plt.xlabel("Frequency [GHz]")
plt.ylabel(r"Normalized Phase Constant $\beta/k_0$")
plt.title("Dispersion Characteristics of Rectangular Waveguide")
plt.grid(True, alpha=0.4)
# 中身があるラインだけで凡例表記
handles, labels = plt.gca().get_legend_handles_labels()
filtered = [(h, l) for h, l in zip(handles, labels)
if hasattr(h, "get_xdata") and len(h.get_xdata()) > 0]
if filtered:
plt.legend([h for h, _ in filtered],
[l for _, l in filtered],
fontsize='small', ncol=1)
plt.tight_layout()
plt.savefig("waveguide_dispersion.pdf")
# plt.show() # 'Agg'バックエンドでは表示しない
数値表示¶
In [12]:
print("=== Cutoff Characteristics ===")
mode_table_()
=== Cutoff Characteristics === Mode m n k_c (1/m) f_c (GHz) λ_c (mm) TE 1 0 1.3719e-01 6.5456 45.8000 TE 2 0 2.7437e-01 13.0913 22.9000 TE 0 1 3.0800e-01 14.6956 20.4000 TE 1 1 3.3717e-01 16.0874 18.6350 TM 1 1 3.3717e-01 16.0874 18.6350 TE 2 1 4.1249e-01 19.6810 15.2325 TM 2 1 4.1249e-01 19.6810 15.2325 TE 0 2 6.1600e-01 29.3912 10.2000 TE 1 2 6.3109e-01 30.1112 9.9561 TM 1 2 6.3109e-01 30.1112 9.9561 TE 2 2 6.7434e-01 32.1749 9.3175 TM 2 2 6.7434e-01 32.1749 9.3175
Pandas¶
In [13]:
df = mode_table(max_m, max_n, a, b)
print(df)
Mode m n k_c (1/mm) f_c (GHz) λ_c (mm) 0 TE$_{10}$ 1 0 0.137187 6.545633 45.800000 1 TE$_{20}$ 2 0 0.274375 13.091266 22.900000 2 TE$_{01}$ 0 1 0.307999 14.695588 20.400000 3 TE$_{11}$ 1 1 0.337171 16.087437 18.635038 4 TM$_{11}$ 1 1 0.337171 16.087437 18.635038 5 TE$_{21}$ 2 1 0.412487 19.680995 15.232461 6 TM$_{21}$ 2 1 0.412487 19.680995 15.232461 7 TE$_{02}$ 0 2 0.615999 29.391176 10.200000 8 TE$_{12}$ 1 2 0.631090 30.111237 9.956084 9 TM$_{12}$ 1 2 0.631090 30.111237 9.956084 10 TE$_{22}$ 2 2 0.674341 32.174874 9.317519 11 TM$_{22}$ 2 2 0.674341 32.174874 9.317519
In [14]:
df
Out[14]:
Mode | m | n | k_c (1/mm) | f_c (GHz) | λ_c (mm) | |
---|---|---|---|---|---|---|
0 | TE$_{10}$ | 1 | 0 | 0.137187 | 6.545633 | 45.800000 |
1 | TE$_{20}$ | 2 | 0 | 0.274375 | 13.091266 | 22.900000 |
2 | TE$_{01}$ | 0 | 1 | 0.307999 | 14.695588 | 20.400000 |
3 | TE$_{11}$ | 1 | 1 | 0.337171 | 16.087437 | 18.635038 |
4 | TM$_{11}$ | 1 | 1 | 0.337171 | 16.087437 | 18.635038 |
5 | TE$_{21}$ | 2 | 1 | 0.412487 | 19.680995 | 15.232461 |
6 | TM$_{21}$ | 2 | 1 | 0.412487 | 19.680995 | 15.232461 |
7 | TE$_{02}$ | 0 | 2 | 0.615999 | 29.391176 | 10.200000 |
8 | TE$_{12}$ | 1 | 2 | 0.631090 | 30.111237 | 9.956084 |
9 | TM$_{12}$ | 1 | 2 | 0.631090 | 30.111237 | 9.956084 |
10 | TE$_{22}$ | 2 | 2 | 0.674341 | 32.174874 | 9.317519 |
11 | TM$_{22}$ | 2 | 2 | 0.674341 | 32.174874 | 9.317519 |
分散特性の作図¶
In [15]:
print("\n=== Dispersion Plot ===")
plot_dispersion()
=== Dispersion Plot ===
In [ ]:
In [ ]: