今日は友達にopenEMSの使い方を教えるために、簡単なバンドパスフィルタをシミュレーションした。 最初にQucsを使って適当にマイクロストリップのフィルタを作ってみた。基板はFR4で誘電率4.4、厚さ1.6 mmとした。マイクロストリップの幅は3 mmでだいたい50 Ωになる。長さ34 mmで2.4 GHz付近で共振するはず。λ/4だけカップリングさせて、はじっこは折り曲げたあと長さ10 mmのフィードラインを通してポートに接続した。
Qucsのシミュレーション結果は下のようになった。センターは2.4 GHzよりちょっと低い2.34 GHzくらいになった。これをあとでopenEMSのシミュレーション結果と比較する。
久々のopenEMSだったが、なんとかなった。記事の一番下にOctaveのスクリプトを載せる。openEMSでは3DモデルをOctave/Matlabのスクリプトで描く必要があり、最初は結構これに苦労するのだが、その分シミュレーションが動いたときの達成感も大きい。メッシュは金属のエッジ付近を細かく、何もないところは粗くするようにした。最初にDetectEdges関数でメタルのエッジを検出したあと、resolution/5だけずらしたものを加えて、さらにDetectEdges関数で全体のエッジを検出し、SmoothMesh関数で滑らかにメッシュを分割した。
openEMSのシミュレーション結果は下のようになった。センターは2.31 GHzくらいでQucsの結果より若干低い。S21の落ち方がQucsよりゆるいかんじ。
フィールドダンプを加えて電界分布をParaViewで表示させてみた。いいね。
close all clear clc physical_constants; unit = 1e-3; % Design parameters W = 3; % MSL width L = 34; % MSL length S = 1; % MSL spacing t = 1.6; % FR4 substrate thickness H = 10; % Simulation box height Lf = 10; % Feeding line length Ws = 50; % Substrate width Ls = 90; % Substrate length epsilon_r = 4.4; % FR4 dielectric constant f0 = 2.4e9; % Center frequency fc = 1e9; % Simulation frequency range % Setup FDTD FDTD = InitFDTD('EndCriteria', 1e-5, 'NrTS', 50000); %FDTD = InitFDTD('EndCriteria', 1e-5, 'NrTS', 20000, 'OverSampling', 50); FDTD = SetGaussExcite(FDTD, f0, fc); BC = { 'MUR' 'MUR' 'MUR' 'MUR' 'PEC' 'MUR' }; FDTD = SetBoundaryCond(FDTD, BC); % Setup CSX CSX = InitCSX(); % Materials % FR4 CSX = AddMaterial(CSX, 'FR4'); CSX = SetMaterialProperty(CSX, 'FR4', 'Epsilon', epsilon_r); % Metal CSX = AddMetal(CSX, 'PEC'); % Substrate start = [-Ws/2 -Ls/2 0]; stop = [Ws/2 Ls/2 t]; CSX = AddBox(CSX, 'FR4', 1, start, stop); % MSL start = [-W/2 -L/2 t]; stop = [W/2 L/2 t]; CSX = AddBox(CSX, 'PEC', 999, start, stop); start = [W/2+S 0 t]; stop = [1.5*W+S L t]; CSX = AddBox(CSX, 'PEC', 999, start, stop); start = [-W/2-S 0 t]; stop = [-1.5*W-S -L t]; CSX = AddBox(CSX, 'PEC', 999, start, stop); start = [1.5*W+S L t]; stop = [1.5*W+S+Lf L-W t]; CSX = AddBox(CSX, 'PEC', 999, start, stop); start = [-1.5*W-S -L t]; stop = [-1.5*W-S-Lf -L+W t]; CSX = AddBox(CSX, 'PEC', 999, start, stop); % Lumped ports % Port 1 start = [-1.5*W-S-Lf -L+W t]; stop = [-1.5*W-S-Lf -L 0]; [CSX port{1}] = AddLumpedPort(CSX, 999, 1, 50, start, stop, [0 0 1], true); % Port 2 start = [1.5*W+S+Lf L-W t]; stop = [1.5*W+S+Lf L 0]; [CSX port{2}] = AddLumpedPort(CSX, 999, 2, 50, start, stop, [0 0 1], false); % Field dump start = [-Ws/2 -Ls/2 t/2]; stop = [Ws/2 Ls/2 t/2]; CSX = AddDump(CSX, 'Et'); CSX = AddBox(CSX, 'Et', 0, start, stop); % Mesh mesh.x = []; mesh.y = []; mesh.z = []; mesh = DetectEdges(CSX, mesh, 'SetPropertyType', {'Metal', 'Excitation'}); resolution = 1; mesh.x = [mesh.x-resolution/5 mesh.x mesh.x+resolution/5]; mesh.y = [mesh.y-resolution/5 mesh.y mesh.y+resolution/5]; mesh.z = [mesh.z resolution/5 t-resolution/5 t+resolution/5 H]; mesh = DetectEdges(CSX, mesh); mesh = SmoothMesh(mesh, resolution); CSX = DefineRectGrid(CSX, unit, mesh); % Write openEMS compatible xml-file Sim_Path = 'tmp'; Sim_CSX = 'BandpassFilter2400MHz.xml'; [status message messageid] = rmdir(Sim_Path, 's'); [status message messageid] = mkdir(Sim_Path); WriteOpenEMS([Sim_Path '/' Sim_CSX], FDTD, CSX); CSXGeomPlot([Sim_Path '/' Sim_CSX]); RunOpenEMS(Sim_Path, Sim_CSX, ''); % Post processing f = linspace(f0-fc, f0+fc, 401); port = calcPort(port, Sim_Path, f, 'RefImpedance', 50); S11 = port{1}.uf.ref ./ port{1}.uf.inc; S21 = port{2}.uf.ref ./ port{1}.uf.inc; figure('Position', [100 100 480 320]); plot(f/1e9, 20*log10(abs(S11)), 'r-', 'DisplayName', 'S_{11}'); hold on plot(f/1e9, 20*log10(abs(S21)), 'b-', 'DisplayName', 'S_{21}'); grid on legend('Location', 'southeast'); xlabel('Frequency (GHz)'); ylabel('S Parameters (dB)'); xlim([f0-fc f0+fc]/1e9);