diff options
Diffstat (limited to 'openEMS/matlab/examples/transmission_lines')
6 files changed, 842 insertions, 0 deletions
diff --git a/openEMS/matlab/examples/transmission_lines/CPW_Line.m b/openEMS/matlab/examples/transmission_lines/CPW_Line.m new file mode 100644 index 0000000..6dac636 --- /dev/null +++ b/openEMS/matlab/examples/transmission_lines/CPW_Line.m @@ -0,0 +1,125 @@ +% +% Tutorials / CPW_Line +% +% Describtion at: +% +% Tested with +% - Octave 3.8.1 +% - openEMS v0.0.32 +% +% (C) 2014 Thorsten Liebig <thorsten.liebig@gmx.de> + +close all +clear +clc + +%% setup the simulation %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +physical_constants; +unit = 1e-6; % specify everything in um +CPW_length = 40000; +CPW_port_length = 10000; +CPW_width = 1000; +CPW_gap = 140; +substrate_thickness = 512; +substrate_width = 5000 +substrate_epr = 3.66; +f_max = 10e9; +air_spacing = 7000 + +% use a finite line CPW waveguide +if 1 + feed_R = 50; + pml_add_cells = [8 8 8 8 8 8]; + feed_shift_cells = 0; + x_spacing = air_spacing; +else % or use a waveguide with start/end in a pml + feed_R = inf; % CPW ends in a pml --> disable termination resitance + feed_shift_cells = 10; % CPW ends in an 8 cells thick pml --> shift feed 10 cells + pml_add_cells = [0 0 8 8 8 8]; % do not add air-space in x-direction + x_spacing = 0; % do not add air-space in x-direction +end + +%% setup FDTD parameters & excitation function %%%%%%%%%%%%%%%%%%%%%%%%%%%% +FDTD = InitFDTD('EndCriteria', 1e-4); +FDTD = SetGaussExcite( FDTD, f_max/2, f_max/2 ); +BC = [2 2 2 2 2 2]; +FDTD = SetBoundaryCond( FDTD, BC ); + +%% setup CSXCAD geometry & mesh %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +CSX = InitCSX(); +resolution = c0/(f_max*sqrt(substrate_epr))/unit /30; % resolution of lambda/50 +edge_res = 40; +mesh.x = SmoothMeshLines( [0 CPW_length/2 CPW_length/2+x_spacing], resolution, 1.5 ,0 ); +mesh.x = unique(sort([-mesh.x mesh.x])); +mesh.y = SmoothMeshLines( [CPW_width/2+[-edge_res/3 +edge_res/3*2] CPW_gap+CPW_width/2+[-edge_res/3*2 +edge_res/3]], edge_res , 1.5 ,0); +mesh.y = SmoothMeshLines( [0 mesh.y], edge_res*2, 1.3 ,0); +mesh.y = SmoothMeshLines( [0 mesh.y substrate_width/2 substrate_width/2+air_spacing], resolution, 1.3 ,0); +mesh.y = unique(sort([-mesh.y mesh.y])); +mesh.z = SmoothMeshLines( [-air_spacing linspace(0,substrate_thickness,5) substrate_thickness+air_spacing], resolution ); + +mesh = AddPML(mesh, pml_add_cells); +CSX = DefineRectGrid( CSX, unit, mesh ); + +%% substrate +CSX = AddMaterial( CSX, 'RO4350B' ); +CSX = SetMaterialProperty( CSX, 'RO4350B', 'Epsilon', substrate_epr ); +start = [-CPW_length/2, -substrate_width/2, 0]; +stop = [+CPW_length/2, +substrate_width/2, substrate_thickness]; +CSX = AddBox( CSX, 'RO4350B', 0, start, stop ); + +%% +CSX = AddMetal( CSX, 'CPW_PORT' ); + +%% CPW port, with the measurement plane at the end of each port +portstart = [ -CPW_length/2 , -CPW_width/2, substrate_thickness]; +portstop = [ -CPW_length/2+CPW_port_length, CPW_width/2, substrate_thickness]; +[CSX,port{1}] = AddCPWPort( CSX, 999, 1, 'CPW_PORT', portstart, portstop, CPW_gap, 'x', [0 1 0], 'ExcitePort', true, 'FeedShift', feed_shift_cells*resolution, 'MeasPlaneShift', CPW_port_length, 'Feed_R', feed_R); + +portstart = [ CPW_length/2 , -CPW_width/2, substrate_thickness]; +portstop = [ CPW_length/2-CPW_port_length, CPW_width/2, substrate_thickness]; +[CSX,port{2}] = AddCPWPort( CSX, 999, 2, 'CPW_PORT', portstart, portstop, CPW_gap, 'x', [0 1 0], 'MeasPlaneShift', CPW_port_length, 'Feed_R', feed_R); + +%% CPW +CSX = AddMetal( CSX, 'CPW'); +start = [ -CPW_length/2+CPW_port_length, -CPW_width/2, substrate_thickness]; +stop = [ +CPW_length/2-CPW_port_length, CPW_width/2, substrate_thickness]; +CSX = AddBox(CSX, 'CPW', 999, start, stop); + +%% CPW grounds +CSX = AddMetal( CSX, 'GND' ); +start = [-CPW_length/2, -CPW_width/2-CPW_gap, substrate_thickness]; +stop = [+CPW_length/2, -substrate_width/2 , substrate_thickness]; +CSX = AddBox(CSX, 'GND', 999, start, stop); + +start = [-CPW_length/2, +CPW_width/2+CPW_gap, substrate_thickness]; +stop = [+CPW_length/2, +substrate_width/2 , substrate_thickness]; +CSX = AddBox(CSX, 'GND', 999, start, stop); + +%% write/show/run the openEMS compatible xml-file +Sim_Path = 'tmp'; +Sim_CSX = 'CPW.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 = 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); + + diff --git a/openEMS/matlab/examples/transmission_lines/Finite_Stripline.m b/openEMS/matlab/examples/transmission_lines/Finite_Stripline.m new file mode 100644 index 0000000..da2b4a3 --- /dev/null +++ b/openEMS/matlab/examples/transmission_lines/Finite_Stripline.m @@ -0,0 +1,91 @@ +% example demonstrating the use of a stripline terminated by a resistance +% (c) 2013 Thorsten Liebig + +close all +clear +clc + +%% setup the simulation %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +physical_constants; +unit = 1e-6; % specify everything in um +SL_length = 50000; +SL_width = 520; +SL_height = 500; +substrate_thickness = SL_height; +substrate_epr = 3.66; +f_max = 7e9; + +Air_Spacer = 20000; + +%% setup FDTD parameters & excitation function %%%%%%%%%%%%%%%%%%%%%%%%%%%% +FDTD = InitFDTD(); +FDTD = SetGaussExcite( FDTD, f_max/2, f_max/2 ); +BC = {'MUR' 'MUR' 'MUR' 'MUR' 'MUR' '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( [-SL_length/2 0 SL_length/2], resolution, 1.5 ,0 ); +mesh.y = SmoothMeshLines( [0 SL_width/2+[-resolution/3 +resolution/3*2]/4], resolution/4 , 1.5 ,0); +mesh.y = SmoothMeshLines( [-10*SL_width -mesh.y mesh.y 10*SL_width], resolution, 1.3 ,0); +mesh.z = linspace(0,substrate_thickness,5); +mesh.z = sort(unique([mesh.z -mesh.z])); + +%% substrate +CSX = AddMaterial( CSX, 'RO4350B' ); +CSX = SetMaterialProperty( CSX, 'RO4350B', 'Epsilon', substrate_epr ); +start = [mesh.x(1), mesh.y(1), mesh.z(1)]; +stop = [mesh.x(end), mesh.y(end), mesh.z(end)]; +CSX = AddBox( CSX, 'RO4350B', 0, start, stop ); + +%% add air spacer +mesh.x = [mesh.x mesh.x(1)-Air_Spacer mesh.x(end)+Air_Spacer]; +mesh.y = [mesh.y mesh.y(1)-Air_Spacer mesh.y(end)+Air_Spacer]; +mesh.z = [mesh.z mesh.z(1)-Air_Spacer mesh.z(end)+Air_Spacer]; +mesh = SmoothMesh(mesh, c0/f_max/unit/20); +CSX = DefineRectGrid( CSX, unit, mesh ); + +%% SL port +CSX = AddMetal( CSX, 'PEC' ); +portstart = [ -SL_length/2, -SL_width/2, 0]; +portstop = [ 0, SL_width/2, 0]; +[CSX,port{1}] = AddStripLinePort( CSX, 999, 1, 'PEC', portstart, portstop, SL_height, 'x', [0 0 -1], 'ExcitePort', true, 'Feed_R', 50, 'MeasPlaneShift', SL_length/3); + +portstart = [+SL_length/2, -SL_width/2, 0]; +portstop = [0 , SL_width/2, 0]; +[CSX,port{2}] = AddStripLinePort( CSX, 999, 2, 'PEC', portstart, portstop, SL_height, 'x', [0 0 -1], 'MeasPlaneShift', SL_length/3, 'Feed_R', 50); + +% bottom PEC plane +CSX = AddBox(CSX, 'PEC', 999, [-SL_length/2 -10*SL_width -SL_height],[+SL_length/2 +10*SL_width -SL_height]); +% top PEC plane +CSX = AddBox(CSX, 'PEC', 999, [-SL_length/2 -10*SL_width SL_height],[+SL_length/2 +10*SL_width SL_height]); + +%% write/show/run the openEMS compatible xml-file +Sim_Path = ['tmp_' mfilename]; +Sim_CSX = 'stripline.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 = 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([-50 2]); + diff --git a/openEMS/matlab/examples/transmission_lines/MSL.m b/openEMS/matlab/examples/transmission_lines/MSL.m new file mode 100644 index 0000000..b6ec0b3 --- /dev/null +++ b/openEMS/matlab/examples/transmission_lines/MSL.m @@ -0,0 +1,185 @@ +% +% EXAMPLE / microstrip / MSL +% +% Microstrip line on air "substrate" in z-direction. +% +% This example demonstrates: +% - simple microstrip geometry +% - characteristic impedance +% - material grading function +% - geometric priority concept +% +% +% Tested with +% - Matlab 2009b +% - Octave 3.3.52 +% - openEMS v0.0.14 +% +% (C) 2010 Thorsten Liebig <thorsten.liebig@uni-due.de> + +close all +clear +clc + +%% setup the simulation +physical_constants; +unit = 1e-3; % all length in mm + +% geometry +abs_length = 100; % absorber length +length = 600; +width = 400; +height = 200; +MSL_width = 50; +MSL_height = 10; + +%% prepare simulation folder +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 + +%% setup FDTD parameter & excitation function %%%%%%%%%%%%%%%%%%%%%%%%%%%%% +max_timesteps = 2000; +min_decrement = 1e-5; % equivalent to -50 dB +f0 = 2e9; % center frequency +fc = 1e9; % 10 dB corner frequency (in this case 1e9 Hz - 3e9 Hz) +FDTD = InitFDTD( max_timesteps, min_decrement ); +FDTD = SetGaussExcite( FDTD, f0, fc ); +BC = {'PMC' 'PMC' 'PEC' 'PMC' 'PEC' 'PEC'}; +FDTD = SetBoundaryCond( FDTD, BC ); + +%% setup CSXCAD geometry & mesh +% very simple mesh +CSX = InitCSX(); +resolution = c0/(f0+fc)/unit /15; % resolution of lambda/15 +mesh.x = SmoothMeshLines( [-width/2, width/2, -MSL_width/2, MSL_width/2], resolution ); % create smooth lines from fixed lines +mesh.y = SmoothMeshLines( [linspace(0,MSL_height,5) MSL_height+1 height], resolution ); +mesh.z = SmoothMeshLines( [0 length], resolution ); +CSX = DefineRectGrid( CSX, unit, mesh ); + +%% create MSL +% attention! the skin effect is not simulated, because the MSL is +% discretized with only one cell! +CSX = AddMaterial( CSX, 'copper' ); +CSX = SetMaterialProperty( CSX, 'copper', 'Kappa', 56e6 ); +start = [-MSL_width/2, MSL_height, 0]; +stop = [ MSL_width/2, MSL_height+1, length]; +priority = 100; % the geometric priority is set to 100 +CSX = AddBox( CSX, 'copper', priority, start, stop ); + +%% add excitation below the strip +start = [-MSL_width/2, 0 , mesh.z(1)]; +stop = [ MSL_width/2, MSL_height, mesh.z(1)]; +CSX = AddExcitation( CSX, 'excite', 0, [0 -1 0] ); +CSX = AddBox( CSX, 'excite', 0, start, stop ); + +%% fake pml +% this "pml" is a normal material with graded losses +% electric and magnetic losses are related to give low reflection +% for normally incident TEM waves +finalKappa = 1/abs_length^2; +finalSigma = finalKappa*MUE0/EPS0; +CSX = AddMaterial( CSX, 'fakepml' ); +CSX = SetMaterialProperty( CSX, 'fakepml', 'Kappa', finalKappa ); +CSX = SetMaterialProperty( CSX, 'fakepml', 'Sigma', finalSigma ); +CSX = SetMaterialWeight( CSX, 'fakepml', 'Kappa', ['pow(z-' num2str(length-abs_length) ',2)'] ); +CSX = SetMaterialWeight( CSX, 'fakepml', 'Sigma', ['pow(z-' num2str(length-abs_length) ',2)'] ); +start = [mesh.x(1) mesh.y(1) length-abs_length]; +stop = [mesh.x(end) mesh.y(end) length]; +% the geometric priority is set to 0, which is lower than the priority +% of the MSL, thus the MSL (copper) has precendence +priority = 0; +CSX = AddBox( CSX, 'fakepml', priority, start, stop ); + +%% define dump boxes +start = [mesh.x(1), MSL_height/2, mesh.z(1)]; +stop = [mesh.x(end), MSL_height/2, mesh.z(end)]; +CSX = AddDump( CSX, 'Et_', 'DumpMode', 2 ); % cell interpolated +CSX = AddBox( CSX, 'Et_', 0, start, stop ); +CSX = AddDump( CSX, 'Ht_', 'DumpType', 1, 'DumpMode', 2 ); % cell interpolated +CSX = AddBox( CSX, 'Ht_', 0, start, stop ); + +%% define voltage calc box +% voltage calc boxes will automatically snap to the next mesh-line +CSX = AddProbe( CSX, 'ut1', 0 ); +zidx = interp1( mesh.z, 1:numel(mesh.z), length/2, 'nearest' ); +start = [0 MSL_height mesh.z(zidx)]; +stop = [0 0 mesh.z(zidx)]; +CSX = AddBox( CSX, 'ut1', 0, start, stop ); +% add a second voltage probe to compensate space offset between voltage and +% current +CSX = AddProbe( CSX, 'ut2', 0 ); +start = [0 MSL_height mesh.z(zidx+1)]; +stop = [0 0 mesh.z(zidx+1)]; +CSX = AddBox( CSX, 'ut2', 0, start, stop ); + +%% define current calc box +% current calc boxes will automatically snap to the next dual mesh-line +CSX = AddProbe( CSX, 'it1', 1 ); +xidx1 = interp1( mesh.x, 1:numel(mesh.x), -MSL_width/2, 'nearest' ); +xidx2 = interp1( mesh.x, 1:numel(mesh.x), MSL_width/2, 'nearest' ); +xdelta = diff(mesh.x); +yidx1 = interp1( mesh.y, 1:numel(mesh.y), MSL_height, 'nearest' ); +yidx2 = interp1( mesh.y, 1:numel(mesh.y), MSL_height+1, 'nearest' ); +ydelta = diff(mesh.y); +zdelta = diff(mesh.z); +start = [mesh.x(xidx1)-xdelta(xidx1-1)/2, mesh.y(yidx1)-ydelta(yidx1-1)/2, mesh.z(zidx)+zdelta(zidx)/2]; +stop = [mesh.x(xidx2)+xdelta(xidx2)/2, mesh.y(yidx2)+ydelta(yidx2)/2, mesh.z(zidx)+zdelta(zidx)/2]; +CSX = AddBox( CSX, 'it1', 0, start, stop ); + +%% write openEMS compatible xml-file +WriteOpenEMS( [Sim_Path '/' Sim_CSX], FDTD, CSX ); + +%% show the structure +CSXGeomPlot( [Sim_Path '/' Sim_CSX] ); + +%% run openEMS +openEMS_opts = ''; +openEMS_opts = [openEMS_opts ' --engine=fastest']; +% openEMS_opts = [openEMS_opts ' --debug-material']; +% openEMS_opts = [openEMS_opts ' --debug-boxes']; +RunOpenEMS( Sim_Path, Sim_CSX, openEMS_opts ); + +%% postprocess +freq = linspace( f0-fc, f0+fc, 501 ); +U = ReadUI( {'ut1','ut2','et'}, 'tmp/', freq ); % time domain/freq domain voltage +I = ReadUI( 'it1', 'tmp/', freq ); % time domain/freq domain current (half time step offset is corrected) + +% plot time domain voltage +figure +[ax,h1,h2] = plotyy( U.TD{1}.t/1e-9, U.TD{1}.val, U.TD{3}.t/1e-9, U.TD{3}.val ); +set( h1, 'Linewidth', 2 ); +set( h1, 'Color', [1 0 0] ); +set( h2, 'Linewidth', 2 ); +set( h2, 'Color', [0 0 0] ); +grid on +title( 'time domain voltage' ); +xlabel( 'time t / ns' ); +ylabel( ax(1), 'voltage ut1 / V' ); +ylabel( ax(2), 'voltage et / V' ); +% now make the y-axis symmetric to y=0 (align zeros of y1 and y2) +y1 = ylim(ax(1)); +y2 = ylim(ax(2)); +ylim( ax(1), [-max(abs(y1)) max(abs(y1))] ); +ylim( ax(2), [-max(abs(y2)) max(abs(y2))] ); + +% calculate characteristic impedance +% arithmetic mean of ut1 and ut2 -> voltage in the middle of ut1 and ut2 +U = (U.FD{1}.val + U.FD{2}.val) / 2; +Z = U ./ I.FD{1}.val; + +% plot characteristic impedance +figure +plot( freq/1e6, real(Z), 'k-', 'Linewidth', 2 ); +hold on +grid on +plot( freq/1e6, imag(Z), 'r--', 'Linewidth', 2 ); +title( 'characteristic impedance of MSL' ); +xlabel( 'frequency f / MHz' ); +ylabel( 'characteristic impedance Z / Ohm' ); +legend( 'real', 'imag' ); + +%% visualize electric and magnetic fields +% you will find vtk dump files in the simulation folder (tmp/) +% use paraview to visualize them diff --git a/openEMS/matlab/examples/transmission_lines/MSL_Losses.m b/openEMS/matlab/examples/transmission_lines/MSL_Losses.m new file mode 100644 index 0000000..95cad7b --- /dev/null +++ b/openEMS/matlab/examples/transmission_lines/MSL_Losses.m @@ -0,0 +1,102 @@ +% +% examples / microstrip / MSL_Losses +% +% This example demonstrates how to model sheet conductor losses +% +% Tested with +% - Matlab 2013a / Octave 3.8.1+ +% - openEMS v0.0.32 +% +% (C) 2012-2014 Thorsten Liebig <thorsten.liebig@gmx.de> + +close all +clear +clc + +%% setup the simulation %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +physical_constants; +unit = 1e-6; % specify everything in um +MSL.length = 10000; +MSL.port_dist = 5000; +MSL.width = 225; +MSL.conductivity = 41e6; +MSL.thickness = 35e-6; + +substrate.thickness = 250; +substrate.epr = 9.8; + +f_start = 0e9; +f_stop = 25e9; + +lambda = c0/f_stop; + +%% setup FDTD parameters & excitation function %%%%%%%%%%%%%%%%%%%%%%%%%%%% +FDTD = InitFDTD('endCriteria',1e-4); +FDTD = SetGaussExcite(FDTD,0.5*(f_start+f_stop),0.5*(f_stop-f_start)); +BC = {'PML_8' 'PML_8' 'PML_8' 'PML_8' 'PEC' 'PML_8'}; +FDTD = SetBoundaryCond( FDTD, BC ); + +%% setup CSXCAD geometry & mesh %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +CSX = InitCSX(); +resolution = c0/(f_stop*sqrt(substrate.epr))/unit /20; +mesh.x = SmoothMeshLines( [-MSL.length*0.5-MSL.port_dist 0 MSL.length*0.5+MSL.port_dist], resolution, 1.3 ,0 ); +mesh.y = SmoothMeshLines2( [0 MSL.width/2], resolution/6 , 1.3); +mesh.y = SmoothMeshLines( [-0.5*lambda/unit -mesh.y mesh.y 0.5*lambda/unit], resolution, 1.4); +mesh.z = SmoothMeshLines( [linspace(0,substrate.thickness,10) 0.5*lambda/unit], 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 ports and lossy line +CSX = AddConductingSheet( CSX, 'gold', MSL.conductivity, MSL.thickness ); +portstart = [ mesh.x(1), -MSL.width/2, substrate.thickness]; +portstop = [ mesh.x(1)+MSL.port_dist, MSL.width/2, 0]; +[CSX, port{1}] = AddMSLPort( CSX, 999, 1, 'gold', portstart, portstop, 0, [0 0 -1], 'ExcitePort', true, 'FeedShift', 10*resolution, 'MeasPlaneShift', MSL.port_dist); + +portstart = [mesh.x(end), -MSL.width/2, substrate.thickness]; +portstop = [mesh.x(end)-MSL.port_dist, MSL.width/2, 0]; +[CSX, port{2}] = AddMSLPort( CSX, 999, 2, 'gold', portstart, portstop, 0, [0 0 -1], 'MeasPlaneShift', MSL.port_dist ); + +start = [mesh.x(1)+MSL.port_dist, -MSL.width/2, substrate.thickness]; +stop = [mesh.x(end)-MSL.port_dist, MSL.width/2, substrate.thickness]; +CSX = AddBox(CSX,'gold',500,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( f_start, f_stop, 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(s21)),'r--','LineWidth',2); +grid on; +hold on; +ylabel('-|S_21| (dB)','Interpreter','None'); +xlabel('frequency (GHz)'); + +%% plot 35um thickness loss model curve +% values extracted from http://wcalc.sourceforge.net/cgi-bin/microstrip.cgi +model.f = [1 2 2.5 3 4 5 7.5 10 12.5 15 17.5 20 25 ]; % frequency in GHz +model.loss = [3.0 4.2 4.7 5.2 5.9 6.6 8.1 9.38 10.5 11.5 12.4 13.2 14.65]; % loss in db/m + +plot(model.f, model.loss * MSL.length * unit ,'k-','LineWidth',1); +legend('FDTD simulated attenuation','t=35um, loss model by E. Hammerstad & F. Bekkadal','Location','NorthWest'); + + diff --git a/openEMS/matlab/examples/transmission_lines/Stripline.m b/openEMS/matlab/examples/transmission_lines/Stripline.m new file mode 100644 index 0000000..71fd774 --- /dev/null +++ b/openEMS/matlab/examples/transmission_lines/Stripline.m @@ -0,0 +1,78 @@ +% example demonstrating the use of a stripline terminated by the pml +% (c) 2013 Thorsten Liebig + +close all +clear +clc + +%% setup the simulation %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +physical_constants; +unit = 1e-6; % specify everything in um +SL_length = 50000; +SL_width = 520; +SL_height = 500; +substrate_thickness = SL_height; +substrate_epr = 3.66; +f_max = 7e9; + +%% setup FDTD parameters & excitation function %%%%%%%%%%%%%%%%%%%%%%%%%%%% +FDTD = InitFDTD(); +FDTD = SetGaussExcite( FDTD, f_max/2, f_max/2 ); +BC = {'PML_8' 'PML_8' 'PMC' 'PMC' 'PEC' 'PEC'}; +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( [-SL_length/2 0 SL_length/2], resolution, 1.5 ,0 ); +mesh.y = SmoothMeshLines( [0 SL_width/2+[-resolution/3 +resolution/3*2]/4], resolution/4 , 1.5 ,0); +mesh.y = SmoothMeshLines( [-10*SL_width -mesh.y mesh.y 10*SL_width], resolution, 1.3 ,0); +mesh.z = linspace(0,substrate_thickness,5); +mesh.z = sort(unique([mesh.z -mesh.z])); +CSX = DefineRectGrid( CSX, unit, mesh ); + +%% substrate +CSX = AddMaterial( CSX, 'RO4350B' ); +CSX = SetMaterialProperty( CSX, 'RO4350B', 'Epsilon', substrate_epr ); +start = [mesh.x(1), mesh.y(1), mesh.z(1)]; +stop = [mesh.x(end), mesh.y(end), mesh.z(end)]; +CSX = AddBox( CSX, 'RO4350B', 0, start, stop ); + +%% SL port +CSX = AddMetal( CSX, 'PEC' ); +portstart = [ mesh.x(1), -SL_width/2, 0]; +portstop = [ 0, SL_width/2, 0]; +[CSX,port{1}] = AddStripLinePort( CSX, 999, 1, 'PEC', portstart, portstop, SL_height, 'x', [0 0 -1], 'ExcitePort', true, 'FeedShift', 10*resolution, 'MeasPlaneShift', SL_length/3); + +portstart = [mesh.x(end), -SL_width/2, 0]; +portstop = [0 , SL_width/2, 0]; +[CSX,port{2}] = AddStripLinePort( CSX, 999, 2, 'PEC', portstart, portstop, SL_height, 'x', [0 0 -1], 'MeasPlaneShift', SL_length/3 ); + +%% write/show/run the openEMS compatible xml-file +Sim_Path = ['tmp_' mfilename]; +Sim_CSX = 'stripline.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 = 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([-50 2]); + diff --git a/openEMS/matlab/examples/transmission_lines/directional_coupler.m b/openEMS/matlab/examples/transmission_lines/directional_coupler.m new file mode 100644 index 0000000..8ba86f2 --- /dev/null +++ b/openEMS/matlab/examples/transmission_lines/directional_coupler.m @@ -0,0 +1,261 @@ +function directional_coupler +% +% EXAMPLE / microstrip / directional_coupler +% +% Stacked directional coupler in microstrip technology. +% +% This example demonstrates: +% - simple microstrip geometry +% - S-parameter calculation using the ypar-method +% - display of coupler parameters +% - display of S11 (smith chart) +% +% +% Tested with +% - Matlab 2010b +% - Octave 3.2.4 +% - openEMS v0.0.17 +% +% (C) 2010 Sebastian Held <sebastian.held@gmx.de> + +clear +close all +clc + +% sim settings +showStructure = 1; +runSimulation = 1; + +for n=1:4 + if n > 1, showStructure = 0; end + ports{n} = sim( n, showStructure, runSimulation ); +end +postprocess( ports ); + + + + +function ports = sim( simnr, showStructure, runSimulation ) +physical_constants + +% setup the simulation +drawingunit = 1e-6; % specify everything in um +Sim_Path = ['tmp' int2str(simnr)]; +Sim_CSX = 'tmp.xml'; +f_max = 100e6; +lambda = c0/f_max; + +% specify the coupler +pcb1.w = 147000; +pcb1.h = 54500; +pcb1.t = 1524; +pcb1.epr = 3; +msl1.w = 135000; +msl1.h = 2800; +pcb2.w = 107000; +pcb2.h = 14000; +pcb2.t = 1524; +pcb2.epr = 3; +msl2.w = 95000; +msl2.h = 4000; + + +CSX = InitCSX(); + +% create the mesh +mesh.x = [-pcb1.w/2 pcb1.w/2 -pcb2.w/2 pcb2.w/2 -msl1.w/2 msl1.w/2 -msl2.w/2 msl2.w/2]; +mesh.x = [mesh.x linspace(-msl2.w/2,-msl2.w/2+msl2.h, 5) linspace(msl2.w/2,msl2.w/2-msl2.h, 5)]; +mesh.y = [-pcb1.h/2 pcb1.h/2 -pcb2.h/2 pcb2.h/2 -msl1.h/2 msl1.h/2 -msl2.h/2 msl2.h/2]; +mesh.z = [linspace(0,pcb1.t,5) linspace(pcb1.t,pcb1.t+pcb2.t,5)]; +mesh.z = [mesh.z mesh.z(end)+10*(mesh.z(end)-mesh.z(1))]; % add space above pcb +res = lambda/sqrt(max([pcb1.epr,pcb2.epr])) / 20 / drawingunit; +mesh.x = SmoothMeshLines2(mesh.x,res); +mesh.y = SmoothMeshLines2(mesh.y,res); +mesh.z = SmoothMeshLines2(mesh.z,res); +mesh = AddPML( mesh, [8 8 8 8 8 8] ); % add space for PML +CSX = DefineRectGrid( CSX, drawingunit, mesh ); + +%% create the structure + +% microstrip +CSX = AddMetal( CSX, 'PEC' ); +start = [-msl1.w/2, -msl1.h/2, pcb1.t]; +stop = [ msl1.w/2, msl1.h/2, pcb1.t]; +priority = 100; % the geometric priority is set to 100 +CSX = AddBox( CSX, 'PEC', priority, start, stop ); + +% ground plane +CSX = AddMetal( CSX, 'PEC_ground' ); +start = [-pcb1.w/2, -pcb1.h/2, 0]; +stop = [ pcb1.w/2, pcb1.h/2, 0]; +CSX = AddBox( CSX, 'PEC_ground', priority, start, stop ); + +% substrate 1 +start = [-pcb1.w/2, -pcb1.h/2, 0]; +stop = [ pcb1.w/2, pcb1.h/2, pcb1.t]; +priority = 10; +CSX = AddMaterial( CSX, 'substrate1' ); +CSX = SetMaterialProperty( CSX, 'substrate1', 'Epsilon', pcb1.epr ); +CSX = AddBox( CSX, 'substrate1', priority, start, stop ); + +% substrate 2 +start = [-pcb2.w/2, -pcb2.h/2, pcb1.t]; +stop = [ pcb2.w/2, pcb2.h/2, pcb1.t+pcb2.t]; +priority = 10; +CSX = AddMaterial( CSX, 'substrate2' ); +CSX = SetMaterialProperty( CSX, 'substrate2', 'Epsilon', pcb2.epr ); +CSX = AddBox( CSX, 'substrate2', priority, start, stop ); + +% stripline +start = [-msl2.w/2, -msl2.h/2, pcb1.t+pcb2.t]; +stop = [ msl2.w/2, msl2.h/2, pcb1.t+pcb2.t]; +priority = 100; +CSX = AddBox( CSX, 'PEC', priority, start, stop ); + +% connections +start = [-msl2.w/2, -msl2.h/2, pcb1.t+pcb2.t]; +stop = [-msl2.w/2+msl2.h, -pcb2.h/2, pcb1.t+pcb2.t]; +priority = 100; +CSX = AddBox( CSX, 'PEC', priority, start, stop ); +start = [ msl2.w/2, -msl2.h/2, pcb1.t+pcb2.t]; +stop = [ msl2.w/2-msl2.h, -pcb2.h/2, pcb1.t+pcb2.t]; +priority = 100; +CSX = AddBox( CSX, 'PEC', priority, start, stop ); + +%% ports +% this project needs 4 simulations +for n=1:4 + portexcite{n} = []; +end +portexcite{simnr} = 'excite'; + +% port 1: input port +start = [-msl1.w/2, 0, pcb1.t]; +stop = [-msl1.w/2, 0, 0]; +[CSX ports{1}] = AddCurvePort( CSX, 999, 1, 50, start, stop, portexcite{1} ); +% port 2: output port +start = [msl1.w/2, 0, pcb1.t]; +stop = [msl1.w/2, 0, 0]; +[CSX ports{2}] = AddCurvePort( CSX, 999, 2, 50, start, stop, portexcite{2} ); +% port 3: coupled port +start = [-msl2.w/2+msl2.h/2, -pcb2.h/2, pcb1.t+pcb2.t]; +stop = [-msl2.w/2+msl2.h/2, -pcb2.h/2, 0]; +[CSX ports{3}] = AddCurvePort( CSX, 999, 3, 50, start, stop, portexcite{3} ); +% port 4: isolated port +start = [msl2.w/2-msl2.h/2, -pcb2.h/2, pcb1.t+pcb2.t]; +stop = [msl2.w/2-msl2.h/2, -pcb2.h/2, 0]; +[CSX ports{4}] = AddCurvePort( CSX, 999, 4, 50, start, stop, portexcite{4} ); + +%% setup FDTD parameters & excitation function +max_timesteps = 50000; +min_decrement = 1e-6; +FDTD = InitFDTD( max_timesteps, min_decrement ); +FDTD = SetGaussExcite( FDTD, 0, f_max ); +BC = {'PML_8' 'PML_8' 'PML_8' 'PML_8' 'PML_8' 'PML_8'}; +BC = {'MUR' 'MUR' 'MUR' 'MUR' 'MUR' 'MUR'}; % faster +FDTD = SetBoundaryCond( FDTD, BC ); + +%% Write openEMS compatible xml-file +if runSimulation + [dummy,dummy,dummy] = rmdir(Sim_Path,'s'); +end +[dummy,dummy,dummy] = mkdir(Sim_Path); +WriteOpenEMS([Sim_Path '/' Sim_CSX],FDTD,CSX); + +if showStructure + CSXGeomPlot( [Sim_Path '/' Sim_CSX] ); +end + +%% run openEMS +openEMS_opts = ''; +openEMS_opts = [openEMS_opts ' --engine=fastest']; +% openEMS_opts = [openEMS_opts ' --debug-material']; +% openEMS_opts = [openEMS_opts ' --debug-boxes']; +if runSimulation + RunOpenEMS( Sim_Path, Sim_CSX, openEMS_opts ); +end + + + + +function postprocess( ports ) +f = linspace( 0, 100e6, 201 ); +Y = calc_ypar( f, ports{1}, 'tmp' ); +R = 50; +S = y2s(Y,R); + +% insertion loss +IL_dB = -20 * log10(abs(squeeze(S(2,1,:)))); + +% coupling factor +CF_dB = -20 * log10(abs(squeeze(S(3,1,:)))); + +% isolation +I_dB = -20 * log10(abs(squeeze(S(4,1,:)))); + +% directivity +D_dB = -20 * log10(abs(squeeze(S(4,1,:) ./ S(3,1,:)))); + +figure +plot( f, [IL_dB CF_dB I_dB D_dB] ); +legend( {'insertion loss','coupling factor','isolation','directivity'} ); +title( ['performance of the coupler for a termination resistance of R=' num2str(R)] ); +grid on + +smithchart +S11 = squeeze(S(1,1,:)); +plot( real(S11), imag(S11) ); +legend( 'S_{11}' ); +title( ['performance of the coupler for a termination resistance of R=' num2str(R)] ); +axis( [-1 1 -1 1] ); + + + +function smithchart +% smith chart +figure +if exist( 'smith', 'file' ) + % smith chart + % www.ece.rutgers.edu/~orfanidi/ewa + % or cmt toolbox from git.ate.uni-duisburg.de + smith +else + % poor man smith chart + color = [.6 .6 .6]; + h = plot( sin(0:0.01:2*pi), cos(0:0.01:2*pi), 'Color', color ); + hg = hggroup; + set( h,'Parent',hg ); + hold on + plot( hg, 0.25+0.75*sin(0:0.01:2*pi), 0.75*cos(0:0.01:2*pi), 'Color', color ); + plot( hg, 0.5+0.5*sin(0:0.01:2*pi), 0.5*cos(0:0.01:2*pi), 'Color', color ); + plot( hg, 0.75+0.25*sin(0:0.01:2*pi), 0.25*cos(0:0.01:2*pi), 'Color', color ); + plot( hg, [-1 1], [0 0], 'Color', color ); + axis equal + axis off +end + + +function s = y2s(y, ZL) +% S = y2s(Y, ZL) +% +% Admittance to Scattering transformation +% for square matrices at multiple frequencies +% +% ZL defaults to 50 Ohm + +if nargin < 2 + ZL = 50; +end + +if size(size(y),2) > 2 + nF = size(y,3); +else + nF = 1; +end + +I = diag(ones(1, size(y,2)))/ZL; + +for i=1:nF + %s(:,:,i) = inv(I+y(:,:,i)) * (I-y(:,:,i)); + s(:,:,i) = (I+y(:,:,i)) \ (I-y(:,:,i)); +end |