Microstrip Notch Filter
A microstrip line (MSL) with an open-ended stub acting as a simple band-stop filter.
This tutorial covers:
Setting up a microstrip line and MSL ports
Applying an inhomogeneous mesh for improved accuracy
Computing S-parameters and identifying the notch frequency
Octave/Matlab Script
Simulation Parameters
Define the physical dimensions of the filter geometry: a 50 mm microstrip on a 254 µm RO4350B substrate with a 12 mm open-ended stub. The maximum frequency is set to 7 GHz to capture the notch and any harmonics.
physical_constants;
unit = 1e-6; % specify everything in um
MSL_length = 50000;
MSL_width = 600;
substrate_thickness = 254;
substrate_epr = 3.66;
stub_length = 12e3;
f_max = 7e9;
FDTD Configuration
A Gaussian pulse centred at f_max/2 excites the full bandwidth in a
single simulation run. PML boundaries on the feed ends absorb outgoing
waves; a PEC plane closes the bottom of the mesh (ground plane).
FDTD = InitFDTD();
FDTD = SetGaussExcite( FDTD, f_max/2, f_max/2 );
BC = {'PML_8' 'PML_8' 'MUR' 'MUR' 'PEC' 'MUR'};
FDTD = SetBoundaryCond( FDTD, BC );
Geometry and Mesh
An inhomogeneous mesh is used: two closely-spaced lines at each conductor
edge (one 1/3 inside, one 2/3 outside) reduce staircasing error, while
SmoothMeshLines() grades smoothly from λ/200 at the edges to λ/50
in the open regions.
CSX = InitCSX();
resolution = c0/(f_max*sqrt(substrate_epr))/unit /50; % resolution of lambda/50
mesh.x = SmoothMeshLines( [0 MSL_width/2+[2*resolution/3 -resolution/3]/4], resolution/4, 1.5 ,0 );
mesh.x = SmoothMeshLines( [-MSL_length -mesh.x mesh.x MSL_length], resolution, 1.5 ,0 );
mesh.y = SmoothMeshLines( [0 MSL_width/2+[-resolution/3 +resolution/3*2]/4], resolution/4 , 1.5 ,0);
mesh.y = SmoothMeshLines( [-15*MSL_width -mesh.y mesh.y stub_length+[-resolution/3 +resolution/3*2]/4 15*MSL_width+stub_length], resolution, 1.3 ,0);
mesh.z = SmoothMeshLines( [linspace(0,substrate_thickness,5) 10*substrate_thickness], resolution );
CSX = DefineRectGrid( CSX, unit, mesh );
Substrate
RO4350B (εr = 3.66) is modeled as a dielectric box filling the full mesh
footprint to substrate_thickness, forming the electrical environment
for the microstrip.
CSX = AddMaterial( CSX, 'RO4350B' );
CSX = SetMaterialProperty( CSX, 'RO4350B', 'Epsilon', substrate_epr );
start = [mesh.x(1), mesh.y(1), 0];
stop = [mesh.x(end), mesh.y(end), substrate_thickness];
CSX = AddBox( CSX, 'RO4350B', 0, start, stop );
MSL Ports
Two AddMSLPort() calls place microstrip ports at either end of the
line; port 1 carries the excitation and both ports record voltage at
MSL_length/3 to measure away from the near-field of the feed.
CSX = AddMetal( CSX, 'PEC' );
portstart = [ mesh.x(1), -MSL_width/2, substrate_thickness];
portstop = [ 0, MSL_width/2, 0];
[CSX,port{1}] = AddMSLPort( CSX, 999, 1, 'PEC', portstart, portstop, 0, [0 0 -1], 'ExcitePort', true, 'FeedShift', 10*resolution, 'MeasPlaneShift', MSL_length/3);
portstart = [mesh.x(end), -MSL_width/2, substrate_thickness];
portstop = [0 , MSL_width/2, 0];
[CSX,port{2}] = AddMSLPort( CSX, 999, 2, 'PEC', portstart, portstop, 0, [0 0 -1], 'MeasPlaneShift', MSL_length/3 );
Filter Stub
A PEC patch on the top metal layer forms the open-ended stub; its
quarter-wave resonance at the frequency determined by stub_length
creates the band-stop notch in S21.
start = [-MSL_width/2, MSL_width/2, substrate_thickness];
stop = [ MSL_width/2, MSL_width/2+stub_length, substrate_thickness];
CSX = AddBox( CSX, 'PEC', 999, start, stop );
Run the Simulation
The geometry is exported to an openEMS XML file; CSXGeomPlot()
allows a visual sanity check before the FDTD solver is invoked.
Sim_Path = 'tmp';
Sim_CSX = 'msl.xml';
CleanupSimPath(Sim_Path);
WriteOpenEMS( [Sim_Path '/' Sim_CSX], FDTD, CSX );
CSXGeomPlot( [Sim_Path '/' Sim_CSX] );
RunOpenEMS( Sim_Path, Sim_CSX );
Post-Processing
calcPort() de-embeds the wave quantities from the time-domain field
recordings referenced to 50 Ω. S11 and S21 are plotted in dB to reveal
the notch frequency and return loss.
close all
f = linspace( 1e6, f_max, 1601 );
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;
plot(f/1e9,20*log10(abs(s11)),'k-','LineWidth',2);
hold on;
grid on;
plot(f/1e9,20*log10(abs(s21)),'r--','LineWidth',2);
legend('S_{11}','S_{21}');
ylabel('S-Parameter (dB)','FontSize',12);
xlabel('frequency (GHz) \rightarrow','FontSize',12);
ylim([-40 2]);
Images
Microstrip notch filter geometry — open-ended stub on a microstrip line
S-parameters showing the notch at the stub resonance frequency
Discussion
This tutorial deliberately mis-aligns the mesh with the edges of the microstrip conductor, using the 1/3 : 2/3 rule: the two mesh lines bracketing each conductor edge are placed one-third and two-thirds of a cell width apart rather than exactly on the edge. This compensates for the surface-current singularity at strip edges — the edge cells effectively capture the current concentration without requiring very small grid cells that would greatly increase the number of time steps.
Mesh at end of stub — mesh lines deliberately offset from conductor edges
Mesh at T-junction — 1/3 : 2/3 offset applied at the stub branch point
Mesh in the vertical (z) direction across the substrate stack
The accuracy benefit is demonstrated by comparing three mesh strategies on a plain MSL without stub (theoretical \(Z_c\) = 47.6 Ω from Transcalc):
Mesh type |
\(Z_c\) (Ω) |
Cells |
|---|---|---|
Thirds (1/3 : 2/3) |
47.8 |
167 k |
Uniform, aligned to edges |
44.0 |
161 k |
Variable (fine near edges) |
45.5 |
192 k |
The thirds mesh is both more accurate and cheaper than the variable mesh. The offset ratio is not critical; values between 0.25 and 0.4 all give acceptable results:
Ratio |
\(Z_c\) (Ω) |
Cells |
|---|---|---|
1/3 : 2/3 |
47.8 |
167 k |
0.4 : 0.6 |
48.6 |
167 k |
1/4 : 3/4 |
45.5 |
167 k |
The accuracy of the edge-current correction also depends on the substrate permittivity — higher \(\varepsilon_r\) concentrates fields more strongly, increasing the cell count needed for a given accuracy:
\(\varepsilon_r\) |
\(Z_c\) sim (Ω) |
\(Z_c\) theory (Ω) |
Cells |
|---|---|---|---|
1 |
76.3 |
80.7 |
65 k |
3.66 |
47.8 |
47.6 |
167 k |
10 |
29.3 |
29.9 |
493 k |
References
W. Heinrich et al., “Optimum mesh grading for finite-difference method,” IEEE Trans. MTT, vol. 44, no. 9, pp. 1569–1574, Sep 1996.
J. H. Oates, R. T. Shin, “Analytical Evaluation of Finite-Difference Time-Domain Transmission Line Properties,” Progress In Electromagnetics Research, PIER 16, pp. 87–115, 1997.
A. Rennings, “Computational Electromagnetics — EC-FDTD,” lecture notes, University of Duisburg-Essen.