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

Geometry schematic of the MSL notch filter

Microstrip notch filter geometry — open-ended stub on a microstrip line

S-parameters over frequency

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 at end of stub — mesh lines deliberately offset from conductor edges

Mesh at T-junction

Mesh at T-junction — 1/3 : 2/3 offset applied at the stub branch point

Mesh in the vertical direction

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.