summaryrefslogtreecommitdiff
path: root/openEMS/matlab/AddCoaxialPort.m
diff options
context:
space:
mode:
Diffstat (limited to 'openEMS/matlab/AddCoaxialPort.m')
-rw-r--r--openEMS/matlab/AddCoaxialPort.m232
1 files changed, 232 insertions, 0 deletions
diff --git a/openEMS/matlab/AddCoaxialPort.m b/openEMS/matlab/AddCoaxialPort.m
new file mode 100644
index 0000000..45c0d2b
--- /dev/null
+++ b/openEMS/matlab/AddCoaxialPort.m
@@ -0,0 +1,232 @@
+function [CSX,port] = AddCoaxialPort( CSX, prio, portnr, pec_name, materialname, start, stop, dir, r_i, r_o, r_os, varargin )
+% function [CSX,port] = AddCoaxialPort( CSX, prio, portnr, pec_name, materialname, start, stop, dir, r_i, r_o, r_os, varargin )
+%
+% CSX: CSX-object created by InitCSX()
+% prio: priority for excitation and probe boxes
+% portnr: (integer) number of the port
+% pec_name: metal property for coaxial inner/outer conductor (created by AddMetal())
+% materialname: substrate property for coaxial line (created by AddMaterial())
+% Note: this may be empty for an "air filled" coaxial line
+% start: 3D start rowvector for coaxial cable axis
+% stop: 3D end rowvector for coaxial cable axis
+% dir: direction of wave propagation (choices: 0, 1, 2 or 'x','y','z')
+% r_i: inner coaxial radius (in drawing unit)
+% r_o: outer coaxial radius (in drawing unit)
+% r_os: outer shell coaxial radius (in drawing unit)
+%
+% variable input:
+% varargin: optional additional excitations options, see also AddExcitation
+% 'ExciteAmp' excitation amplitude of transversal electric field profile,
+% set to 0 (default) for a passive port
+% 'FeedShift' shift to port from start by a given distance in drawing
+% units. Default is 0. Only active if 'ExciteAmp' is set!
+% 'Feed_R' Specifiy a lumped port resistance. Default is no lumped
+% port resistance --> port has to end in an ABC.
+% 'MeasPlaneShift' Shift the measurement plane from start t a given distance
+% in drawing units. Default is the middle of start/stop.
+% 'PortNamePrefix' a prefix to the port name
+%
+% the mesh must be already initialized
+%
+% example:
+%
+% openEMS matlab interface
+% -----------------------
+% Thorsten Liebig <thorsten.liebig@gmx.de> (c) 2013
+%
+% See also InitCSX AddMetal AddMaterial AddExcitation calcPort
+
+%% validate arguments %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%check mesh
+if ~isfield(CSX,'RectilinearGrid')
+ error 'mesh needs to be defined! Use DefineRectGrid() first!';
+end
+if (~isfield(CSX.RectilinearGrid,'XLines') || ~isfield(CSX.RectilinearGrid,'YLines') || ~isfield(CSX.RectilinearGrid,'ZLines'))
+ error 'mesh needs to be defined! Use DefineRectGrid() first!';
+end
+
+% check dir
+dir = DirChar2Int(dir);
+
+%set defaults
+feed_shift = 0;
+feed_R = inf; %(default is open, no resitance)
+excite_amp = 0;
+measplanepos = nan;
+PortNamePrefix = '';
+
+excite_args = {};
+
+%% read optional arguments %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+for n=1:2:numel(varargin)
+ if (strcmp(varargin{n},'FeedShift')==1);
+ feed_shift = varargin{n+1};
+ if (numel(feed_shift)>1)
+ error 'FeedShift must be a scalar value'
+ end
+ elseif (strcmp(varargin{n},'Feed_R')==1);
+ feed_R = varargin{n+1};
+ if (numel(feed_shift)>1)
+ error 'Feed_R must be a scalar value'
+ end
+ elseif (strcmp(varargin{n},'MeasPlaneShift')==1);
+ measplanepos = varargin{n+1};
+ if (numel(feed_shift)>1)
+ error 'MeasPlaneShift must be a scalar value'
+ end
+ elseif (strcmp(varargin{n},'ExciteAmp')==1);
+ excite_amp = varargin{n+1};
+ elseif (strcmpi(varargin{n},'PortNamePrefix'))
+ PortNamePrefix = varargin{n+1};
+ else
+ excite_args{end+1} = varargin{n};
+ excite_args{end+1} = varargin{n+1};
+ end
+end
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% determine index (1, 2 or 3) of propagation (length of MSL)
+idx_prop_n = dir + 1;
+idx_prop_nP = mod((dir+1),3)+1;
+idx_prop_nPP = mod((dir+2),3)+1;
+
+% direction of propagation
+if stop(idx_prop_n)-start(idx_prop_n) > 0
+ direction = +1;
+else
+ direction = -1;
+end
+
+% create the metal for the coaxial line
+CSX = AddCylinder( CSX, pec_name, prio, start, stop, r_i );
+CSX = AddCylindricalShell( CSX, pec_name, prio, start, stop, 0.5*(r_o+r_os), r_os-r_o );
+
+% create the material filling for the coaxial line
+if (~isempty(materialname))
+ CSX = AddCylindricalShell( CSX, materialname, prio-1, start, stop, 0.5*(r_o+r_i), r_o-r_i );
+end
+
+if isnan(measplanepos)
+ measplanepos = (start(idx_prop_n)+stop(idx_prop_n))/2;
+else
+ measplanepos = start(idx_prop_n)+direction*measplanepos;
+end
+
+% calculate position of the voltage probes
+mesh{1} = sort(unique(CSX.RectilinearGrid.XLines));
+mesh{2} = sort(unique(CSX.RectilinearGrid.YLines));
+mesh{3} = sort(unique(CSX.RectilinearGrid.ZLines));
+meshlines = interp1( mesh{idx_prop_n}, 1:numel(mesh{idx_prop_n}), measplanepos, 'nearest' );
+meshlines = mesh{idx_prop_n}(meshlines-1:meshlines+1); % get three lines (approx. at center)
+if direction == -1
+ meshlines = fliplr(meshlines);
+end
+v1_start(idx_prop_n) = meshlines(1);
+v1_start(idx_prop_nP) = start(idx_prop_nP)+r_i;
+v1_start(idx_prop_nPP) = start(idx_prop_nPP);
+v1_stop = v1_start;
+v1_stop(idx_prop_nP) = start(idx_prop_nP)+r_o;
+v2_start = v1_start;
+v2_stop = v1_stop;
+v2_start(idx_prop_n) = meshlines(2);
+v2_stop(idx_prop_n) = meshlines(2);
+v3_start = v2_start;
+v3_stop = v2_stop;
+v3_start(idx_prop_n) = meshlines(3);
+v3_stop(idx_prop_n) = meshlines(3);
+
+% calculate position of the current probes
+i1_start(idx_prop_n) = 0.5*(meshlines(1)+meshlines(2));
+i1_start(idx_prop_nP) = start(idx_prop_nP)-r_i-0.1*(r_o-r_i);
+i1_start(idx_prop_nPP) = start(idx_prop_nPP)-r_i-0.1*(r_o-r_i);
+i1_stop = i1_start;
+i1_stop(idx_prop_nP) = start(idx_prop_nP)+r_i+0.1*(r_o-r_i);
+i1_stop(idx_prop_nPP) = start(idx_prop_nPP)+r_i+0.1*(r_o-r_i);
+
+i2_start = i1_start;
+i2_stop = i1_stop;
+i2_start(idx_prop_n) = 0.5*(meshlines(2)+meshlines(3));
+i2_stop(idx_prop_n) = 0.5*(meshlines(2)+meshlines(3));
+
+% create the probes
+port.U_filename{1} = [PortNamePrefix 'port_ut' num2str(portnr) 'A'];
+weight = 1;
+CSX = AddProbe( CSX, port.U_filename{1}, 0, 'weight', weight );
+CSX = AddBox( CSX, port.U_filename{1}, prio, v1_start, v1_stop );
+port.U_filename{2} = [PortNamePrefix 'port_ut' num2str(portnr) 'B'];
+CSX = AddProbe( CSX, port.U_filename{2}, 0, 'weight', weight );
+CSX = AddBox( CSX, port.U_filename{2}, prio, v2_start, v2_stop );
+port.U_filename{3} = [PortNamePrefix 'port_ut' num2str(portnr) 'C'];
+CSX = AddProbe( CSX, port.U_filename{3}, 0, 'weight', weight );
+CSX = AddBox( CSX, port.U_filename{3}, prio, v3_start, v3_stop );
+
+weight = direction;
+port.I_filename{1} = [PortNamePrefix 'port_it' num2str(portnr) 'A'];
+CSX = AddProbe( CSX, port.I_filename{1}, 1, 'weight', weight );
+CSX = AddBox( CSX, port.I_filename{1}, prio, i1_start, i1_stop );
+port.I_filename{2} = [PortNamePrefix 'port_it' num2str(portnr) 'B'];
+CSX = AddProbe( CSX, port.I_filename{2}, 1,'weight', weight );
+CSX = AddBox( CSX, port.I_filename{2}, prio, i2_start, i2_stop );
+
+% create port structure
+port.LengthScale = 1;
+port.nr = portnr;
+port.type = 'Coaxial';
+port.drawingunit = CSX.RectilinearGrid.ATTRIBUTE.DeltaUnit;
+port.v_delta = diff(meshlines)*port.LengthScale;
+port.i_delta = diff( meshlines(1:end-1) + diff(meshlines)/2 )*port.LengthScale;
+port.direction = direction;
+port.excite = 0;
+port.measplanepos = abs(v2_start(idx_prop_n) - start(idx_prop_n))*port.LengthScale;
+
+port.r_i = r_i;
+port.r_o = r_o;
+
+% create excitation (if enabled) and port resistance
+meshline = interp1( mesh{idx_prop_n}, 1:numel(mesh{idx_prop_n}), start(idx_prop_n) + feed_shift*direction, 'nearest' );
+min_cell_prop = min(diff(mesh{idx_prop_n}));
+ex_start = start;
+ex_start(idx_prop_n) = mesh{idx_prop_n}(meshline) - 0.01*min_cell_prop;
+ex_stop = ex_start;
+ex_stop(idx_prop_n) = mesh{idx_prop_n}(meshline) + 0.01*min_cell_prop;
+
+port.excite = 0;
+if (excite_amp~=0)
+ dir_names={'x','y','z'};
+ nameX = ['(' dir_names{idx_prop_nP} '-' num2str(start(idx_prop_nP)) ')'];
+ nameY = ['(' dir_names{idx_prop_nPP} '-' num2str(start(idx_prop_nPP)) ')'];
+
+ func_Ex = [ nameX '/(' nameX '*' nameX '+' nameY '*' nameY ') * (sqrt(' nameX '*' nameX '+' nameY '*' nameY ')<' num2str(r_o) ') * (sqrt(' nameX '*' nameX '+' nameY '*' nameY ')>' num2str(r_i) ')'];
+ func_Ey = [ nameY '/(' nameX '*' nameX '+' nameY '*' nameY ') * (sqrt(' nameX '*' nameX '+' nameY '*' nameY ')<' num2str(r_o) ') * (sqrt(' nameX '*' nameX '+' nameY '*' nameY ')>' num2str(r_i) ')'];
+
+ func_E{idx_prop_n} = 0;
+ func_E{idx_prop_nP} = func_Ex;
+ func_E{idx_prop_nPP} = func_Ey;
+
+ port.excite = 1;
+ evec = [1 1 1];
+ evec(idx_prop_n) = 0;
+
+ CSX = AddExcitation( CSX, [PortNamePrefix 'port_excite_' num2str(portnr)], 0, evec, excite_args{:} );
+ CSX = SetExcitationWeight(CSX, [PortNamePrefix 'port_excite_' num2str(portnr)], func_E );
+ CSX = AddCylindricalShell(CSX,[PortNamePrefix 'port_excite_' num2str(portnr)],0 ,ex_start,ex_stop,0.5*(r_i+r_o),(r_o-r_i));
+end
+
+%% resitance at start of coaxial line
+ex_start = start;
+ex_stop = stop;
+ex_stop(idx_prop_n) = ex_start(idx_prop_n);
+
+if (feed_R > 0) && ~isinf(feed_R)
+ error 'feed_R not yet implemented'
+elseif isinf(feed_R)
+ % do nothing --> open port
+elseif feed_R == 0
+ %port "resistance" as metal
+ CSX = AddBox( CSX, pec_name, prio, ex_start, ex_stop );
+ CSX = AddCylindricalShell(CSX, pec_name, prio ,ex_start, ex_stop, 0.5*(r_i+r_o),(r_o-r_i));
+else
+ error('openEMS:AddMSLPort','MSL port with resitance <= 0 it not possible');
+end
+end