new tutorials: MSL_NotchFilter & CRLH_Extraction
parent
dd7269d40a
commit
d3d9db2933
|
@ -0,0 +1,151 @@
|
||||||
|
%
|
||||||
|
% Tutorials / CRLH_Extraction
|
||||||
|
%
|
||||||
|
% Describtion at:
|
||||||
|
% http://openems.de/index.php/Tutorial:_CRLH_Extraction
|
||||||
|
%
|
||||||
|
% Tested with
|
||||||
|
% - Matlab 2009b
|
||||||
|
% - openEMS v0.0.23
|
||||||
|
%
|
||||||
|
% (C) 2011 Thorsten Liebig <thorsten.liebig@gmx.de>
|
||||||
|
|
||||||
|
close all
|
||||||
|
clear
|
||||||
|
clc
|
||||||
|
|
||||||
|
%% setup the simulation %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
physical_constants;
|
||||||
|
unit = 1e-6; % specify everything in um
|
||||||
|
|
||||||
|
feed_length = 30000;
|
||||||
|
|
||||||
|
substrate_thickness = [1524 101 254];
|
||||||
|
substrate_epr = [3.48 3.48 3.48];
|
||||||
|
|
||||||
|
CRLH.LL = 14e3; %CRLH totel (line) length
|
||||||
|
CRLH.LW = 4e3; %CRLH unit cell width (without the stubs)
|
||||||
|
CRLH.GLB = 1950; %CRLH gap width bottom layer
|
||||||
|
CRLH.GLT = 4700; %CRLH gap width top layer
|
||||||
|
CRLH.SL = 7800; %CRLH stub length (bottom layer, both sides)
|
||||||
|
CRLH.SW = 1000; %CRLH stub width (bottom layer, both sides)
|
||||||
|
CRLH.VR = 250; %CRLH via hole radius (stub -> ground)
|
||||||
|
CRLH.TopSig = sum(substrate_thickness); %top layer height
|
||||||
|
CRLH.BottomSig = CRLH.TopSig - substrate_thickness(end); %bottom layer height
|
||||||
|
|
||||||
|
% frequency range of interest
|
||||||
|
f_start = 0.8e9;
|
||||||
|
f_stop = 6e9;
|
||||||
|
|
||||||
|
%% setup FDTD parameters & excitation function %%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
FDTD = InitFDTD( 20000, 1e-6, 'OverSampling', 10 );
|
||||||
|
FDTD = SetGaussExcite( FDTD, (f_start+f_stop)/2, (f_stop-f_start)/2 );
|
||||||
|
BC = {'PML_8' 'PML_8' 'MUR' 'MUR' 'PEC' 'PML_8'};
|
||||||
|
FDTD = SetBoundaryCond( FDTD, BC );
|
||||||
|
|
||||||
|
%% Setup a basic mesh and create the CRLH unit cell
|
||||||
|
CSX = InitCSX();
|
||||||
|
resolution = c0/(f_stop*sqrt(max(substrate_epr)))/unit /30; % resolution of lambda/30
|
||||||
|
|
||||||
|
mesh.x = [-feed_length-CRLH.LL/2 0 feed_length+CRLH.LL/2];
|
||||||
|
mesh.y = [-30000 0 30000];
|
||||||
|
substratelines = cumsum(substrate_thickness);
|
||||||
|
mesh.z = [0 cumsum(substrate_thickness) linspace(substratelines(end-1),substratelines(end),4) 20000];
|
||||||
|
|
||||||
|
% create the CRLH unit cell (will define additional fixed mesh lines)
|
||||||
|
[CSX mesh] = CreateCRLH(CSX, mesh, CRLH, resolution/4);
|
||||||
|
|
||||||
|
% Smooth the given mesh
|
||||||
|
mesh.x = SmoothMeshLines(mesh.x, resolution, 1.5, 0);
|
||||||
|
mesh.y = SmoothMeshLines(mesh.y, resolution, 1.5, 0);
|
||||||
|
mesh.z = SmoothMeshLines(mesh.z, resolution, 1.5, 0);
|
||||||
|
CSX = DefineRectGrid( CSX, unit, mesh );
|
||||||
|
|
||||||
|
%% Setup the substrate layer
|
||||||
|
substratelines = [0 substratelines];
|
||||||
|
for n=1:numel(substrate_thickness)
|
||||||
|
CSX = AddMaterial( CSX, ['substrate' int2str(n)] );
|
||||||
|
CSX = SetMaterialProperty( CSX, ['substrate' int2str(n)], 'Epsilon', substrate_epr(n) );
|
||||||
|
start = [mesh.x(1), mesh.y(1), substratelines(n)];
|
||||||
|
stop = [mesh.x(end), mesh.y(end), substratelines(n+1)];
|
||||||
|
CSX = AddBox( CSX, ['substrate' int2str(n)], 0, start, stop );
|
||||||
|
end
|
||||||
|
|
||||||
|
%% add the feeding MSL ports
|
||||||
|
CSX = AddMetal( CSX, 'PEC' );
|
||||||
|
portstart = [ mesh.x(1) , -CRLH.LW/2, substratelines(end)];
|
||||||
|
portstop = [ -CRLH.LL/2, CRLH.LW/2, 0];
|
||||||
|
[CSX,portstruct{1}] = AddMSLPort( CSX, 999, 1, 'PEC', portstart, portstop, 0, [0 0 -1], 'ExcitePort', 'excite', 'FeedShift', 10*resolution(1), 'MeasPlaneShift', feed_length/2);
|
||||||
|
|
||||||
|
portstart = [ mesh.x(end) , -CRLH.LW/2, substratelines(end)];
|
||||||
|
portstop = [ +CRLH.LL/2, CRLH.LW/2, 0];
|
||||||
|
[CSX,portstruct{2}] = AddMSLPort( CSX, 999, 2, 'PEC', portstart, portstop, 0, [0 0 -1], 'MeasPlaneShift', feed_length/2 );
|
||||||
|
|
||||||
|
%% write/show/run the openEMS compatible xml-file
|
||||||
|
Sim_Path = 'tmp';
|
||||||
|
Sim_CSX = 'CRLH.xml';
|
||||||
|
|
||||||
|
[status, message, messageid] = rmdir( Sim_Path, 's' ); % clear previous directory
|
||||||
|
[status, message, messageid] = mkdir( Sim_Path ); % create empty simulation folder
|
||||||
|
|
||||||
|
WriteOpenEMS( [Sim_Path '/' Sim_CSX], FDTD, CSX );
|
||||||
|
CSXGeomPlot( [Sim_Path '/' Sim_CSX] );
|
||||||
|
RunOpenEMS( Sim_Path, Sim_CSX );
|
||||||
|
|
||||||
|
%% post-processing
|
||||||
|
close all
|
||||||
|
f = linspace( f_start, f_stop, 1601 );
|
||||||
|
port{1} = calcPort( portstruct{1}, Sim_Path, f, 'RefPlaneShift', feed_length*unit);
|
||||||
|
port{2} = calcPort( portstruct{2}, Sim_Path, f, 'RefPlaneShift', feed_length*unit);
|
||||||
|
|
||||||
|
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);
|
||||||
|
l = legend('S_{11}','S_{21}','Location','Best');
|
||||||
|
set(l,'FontSize',12);
|
||||||
|
ylabel('S-Parameter (dB)','FontSize',12);
|
||||||
|
xlabel('frequency (GHz) \rightarrow','FontSize',12);
|
||||||
|
ylim([-40 2]);
|
||||||
|
|
||||||
|
%% extract parameter
|
||||||
|
A = ((1+s11).*(1-s11) + s21.*s21)./(2*s21);
|
||||||
|
C = ((1-s11).*(1-s11) - s21.*s21)./(2*s21) ./ port{1}.ZL;
|
||||||
|
|
||||||
|
Y = C;
|
||||||
|
Z = 2*(A-1)./C;
|
||||||
|
|
||||||
|
iZ = imag(Z);
|
||||||
|
iY = imag(Y);
|
||||||
|
|
||||||
|
fse = interp1(iZ,f,0);
|
||||||
|
fsh = interp1(iY,f,0);
|
||||||
|
|
||||||
|
df = f(2)-f(1);
|
||||||
|
fse_idx = find(f>fse,1);
|
||||||
|
fsh_idx = find(f>fsh,1);
|
||||||
|
|
||||||
|
LR = 0.5*(iZ(fse_idx)-iZ(fse_idx-1))./(2*pi*df);
|
||||||
|
CL = 1/(2*pi*fse)^2/LR;
|
||||||
|
|
||||||
|
CR = 0.5*(iY(fsh_idx)-iY(fsh_idx-1))./(2*pi*df);
|
||||||
|
LL = 1/(2*pi*fsh)^2/CR;
|
||||||
|
|
||||||
|
disp([' Series tank: CL = ' num2str(CL*1e12,3) 'pF; LR = ' num2str(LR*1e9,3) 'nH -> f_se = ' num2str(fse*1e-9,3) 'GHz ']);
|
||||||
|
disp([' Shunt tank: CR = ' num2str(CR*1e12,3) 'pF; LL = ' num2str(LL*1e9,3) 'nH -> f_sh = ' num2str(fsh*1e-9,3) 'GHz ']);
|
||||||
|
|
||||||
|
%%
|
||||||
|
figure
|
||||||
|
beta = -angle(s21)/CRLH.LL/unit;
|
||||||
|
plot(abs(beta)*CRLH.LL*unit/pi,f*1e-9,'k-','LineWidth',2)
|
||||||
|
grid on;
|
||||||
|
hold on;
|
||||||
|
plot(2*pi*f./c0*CRLH.LL*unit/pi,f*1e-9,'g-')
|
||||||
|
ylim([1 6])
|
||||||
|
xlabel('|\beta| p / \pi \rightarrow','FontSize',12)
|
||||||
|
ylabel('frequency (GHz) \rightarrow','FontSize',12)
|
||||||
|
l = legend('\beta_{CRLH}','\beta_{light}','Location','Best');
|
||||||
|
set(l,'FontSize',12);
|
|
@ -0,0 +1,55 @@
|
||||||
|
function [CSX mesh] = CreateCRLH(CSX, mesh, CRLH, resolution, translate)
|
||||||
|
% function [CSX mesh] = CreateCRLH(CSX, mesh, CRLH, resolution, translate)
|
||||||
|
%
|
||||||
|
% support function to create a CRLH unit cell
|
||||||
|
%
|
||||||
|
% currently used by Tutorials/CRLH_Extraction
|
||||||
|
%
|
||||||
|
% Tested with
|
||||||
|
% - Matlab 2009b
|
||||||
|
% - openEMS v0.0.23
|
||||||
|
%
|
||||||
|
% (C) 2011 Thorsten Liebig <thorsten.liebig@gmx.de>
|
||||||
|
|
||||||
|
if (nargin<5)
|
||||||
|
translate = [0 0 0];
|
||||||
|
end
|
||||||
|
|
||||||
|
CSX = AddMetal(CSX, 'metal_top');
|
||||||
|
one_two_third = [-resolution/3 2*resolution/3];
|
||||||
|
|
||||||
|
start = [-CRLH.LL/2 -CRLH.LW/2 CRLH.TopSig]+translate;
|
||||||
|
stop = [-CRLH.GLT/2 CRLH.LW/2 CRLH.TopSig]+translate;
|
||||||
|
CSX = AddBox(CSX, 'metal_top', 10, start, stop);
|
||||||
|
mesh.x = [mesh.x start(1) stop(1)+one_two_third];
|
||||||
|
mesh.y = [mesh.y start(2)-one_two_third stop(2)+one_two_third];
|
||||||
|
|
||||||
|
start = [+CRLH.LL/2 -CRLH.LW/2 CRLH.TopSig]+translate;
|
||||||
|
stop = [+CRLH.GLT/2 CRLH.LW/2 CRLH.TopSig]+translate;
|
||||||
|
CSX = AddBox(CSX, 'metal_top', 10, start, stop);
|
||||||
|
mesh.x = [mesh.x start(1) stop(1)-one_two_third];
|
||||||
|
|
||||||
|
CSX = AddMetal(CSX, 'metal_bot');
|
||||||
|
start = [-(CRLH.LL-CRLH.GLB)/2 -CRLH.LW/2 CRLH.BottomSig]+translate;
|
||||||
|
stop = [+(CRLH.LL-CRLH.GLB)/2 CRLH.LW/2 CRLH.BottomSig]+translate;
|
||||||
|
CSX = AddBox(CSX, 'metal_bot', 10, start, stop);
|
||||||
|
mesh.x = [mesh.x start(1)-one_two_third stop(1)+one_two_third];
|
||||||
|
|
||||||
|
start = [-CRLH.SW/2 -CRLH.LW/2-CRLH.SL CRLH.BottomSig]+translate;
|
||||||
|
stop = [+CRLH.SW/2 CRLH.LW/2+CRLH.SL CRLH.BottomSig]+translate;
|
||||||
|
CSX = AddBox(CSX, 'metal_bot', 10, start, stop);
|
||||||
|
mesh.x = [mesh.x start(1)-one_two_third stop(1)+one_two_third];
|
||||||
|
mesh.y = [mesh.y start(2) stop(2)];
|
||||||
|
|
||||||
|
CSX = AddMetal(CSX, 'via');
|
||||||
|
start = [0 -CRLH.LW/2-CRLH.SL+CRLH.SW/2 0]+translate;
|
||||||
|
stop = [0 -CRLH.LW/2-CRLH.SL+CRLH.SW/2 CRLH.BottomSig]+translate;
|
||||||
|
CSX = AddCylinder(CSX, 'via', 10, start, stop, CRLH.VR);
|
||||||
|
mesh.x = [mesh.x start(1)+[-1 0 1]*CRLH.VR];
|
||||||
|
mesh.y = [mesh.y start(2)+[-1 0 1]*CRLH.VR];
|
||||||
|
|
||||||
|
start(2) = -start(2);
|
||||||
|
stop(2) = -stop(2);
|
||||||
|
CSX = AddCylinder(CSX, 'via', 10, start, stop, CRLH.VR);
|
||||||
|
mesh.y = [mesh.y start(2)+[-1 0 1]*CRLH.VR];
|
||||||
|
end
|
|
@ -0,0 +1,82 @@
|
||||||
|
close all
|
||||||
|
clear
|
||||||
|
clc
|
||||||
|
|
||||||
|
%% setup the simulation %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
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;
|
||||||
|
|
||||||
|
%% setup FDTD parameters & excitation function %%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
FDTD = InitFDTD( 20000, 1e-6, 'OverSampling', 10 );
|
||||||
|
FDTD = SetGaussExcite( FDTD, f_max/2, f_max/2 );
|
||||||
|
BC = {'PML_8' 'PML_8' 'MUR' 'MUR' 'PEC' 'MUR'};
|
||||||
|
FDTD = SetBoundaryCond( FDTD, BC );
|
||||||
|
|
||||||
|
%% setup CSXCAD geometry & mesh %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
CSX = InitCSX();
|
||||||
|
resolution = c0/(f_max*sqrt(substrate_epr))/unit /50; % resolution of lambda/50
|
||||||
|
mesh.x = SmoothMeshLines( [0 MSL_width/2+[resolution/3 -resolution/3*2]/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 15*MSL_width+stub_length], resolution, 1.5 ,0);
|
||||||
|
mesh.z = SmoothMeshLines( [linspace(0,substrate_thickness,5) 10*substrate_thickness], resolution );
|
||||||
|
CSX = DefineRectGrid( CSX, unit, mesh );
|
||||||
|
|
||||||
|
%% substrate
|
||||||
|
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 port
|
||||||
|
CSX = AddMetal( CSX, 'PEC' );
|
||||||
|
portstart = [ mesh.x(1), -MSL_width/2, substrate_thickness];
|
||||||
|
portstop = [ 0, MSL_width/2, 0];
|
||||||
|
[CSX,portstruct{1}] = AddMSLPort( CSX, 999, 1, 'PEC', portstart, portstop, 0, [0 0 -1], 'ExcitePort', 'excite', 'FeedShift', 10*resolution, 'MeasPlaneShift', MSL_length/3);
|
||||||
|
|
||||||
|
portstart = [mesh.x(end), -MSL_width/2, substrate_thickness];
|
||||||
|
portstop = [0 , MSL_width/2, 0];
|
||||||
|
[CSX,portstruct{2}] = AddMSLPort( CSX, 999, 2, 'PEC', portstart, portstop, 0, [0 0 -1], 'MeasPlaneShift', MSL_length/3 );
|
||||||
|
|
||||||
|
%% Filter-stub
|
||||||
|
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 );
|
||||||
|
|
||||||
|
%% write/show/run the openEMS compatible xml-file
|
||||||
|
Sim_Path = 'tmp';
|
||||||
|
Sim_CSX = 'msl.xml';
|
||||||
|
|
||||||
|
[status, message, messageid] = rmdir( Sim_Path, 's' ); % clear previous directory
|
||||||
|
[status, message, messageid] = mkdir( Sim_Path ); % create empty simulation folder
|
||||||
|
|
||||||
|
WriteOpenEMS( [Sim_Path '/' Sim_CSX], FDTD, CSX );
|
||||||
|
CSXGeomPlot( [Sim_Path '/' Sim_CSX] );
|
||||||
|
RunOpenEMS( Sim_Path, Sim_CSX );
|
||||||
|
|
||||||
|
%% post-processing
|
||||||
|
close all
|
||||||
|
f = linspace( 1e6, f_max, 1601 );
|
||||||
|
port{1} = calcPort( portstruct{1}, Sim_Path, f, 'RefImpedance', 50);
|
||||||
|
port{2} = calcPort( portstruct{2}, 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);
|
||||||
|
l = legend('S_{11}','S_{21}','Location','Best');
|
||||||
|
set(l,'FontSize',12);
|
||||||
|
ylabel('S-Parameter (dB)','FontSize',12);
|
||||||
|
xlabel('frequency (GHz) \rightarrow','FontSize',12);
|
||||||
|
ylim([-40 2]);
|
||||||
|
|
Loading…
Reference in New Issue