summaryrefslogtreecommitdiff
path: root/CSXCAD/matlab/export_empire.m
diff options
context:
space:
mode:
Diffstat (limited to 'CSXCAD/matlab/export_empire.m')
-rw-r--r--CSXCAD/matlab/export_empire.m305
1 files changed, 305 insertions, 0 deletions
diff --git a/CSXCAD/matlab/export_empire.m b/CSXCAD/matlab/export_empire.m
new file mode 100644
index 0000000..104a0bf
--- /dev/null
+++ b/CSXCAD/matlab/export_empire.m
@@ -0,0 +1,305 @@
+function export_empire( CSX, FDTD, filename, options )
+% export_empire( CSX, FDTD, filename, options )
+%
+% Exports the geometry defined in CSX to filename as an Empire python file.
+%
+% CSX: CSX-object created by InitCSX()
+% FDTD: FDTD-object created by InitFDTD()
+% filename: export filename (e.g. '/tmp/export.py')
+% options (optional): struct
+% options.ignore : cell array with property names to ignore
+%
+% CSXCAD matlab interface
+% -----------------------
+% author: Sebastian Held <sebastian.held@gmx.de>
+% 17. Jun 2010: initial version
+% 28. Sep 2010: rewritten using Empire python scripting
+% See also InitCSX InitFDTD
+
+if nargin < 3
+ options = [];
+end
+
+fid = fopen( filename, 'w' );
+
+% write header
+fprintf( fid, ['# Empire python script\n\n' ...
+ '# start Empire and select File/"Run Script" and select this file\n\n'] );
+fprintf( fid, 'from scripting import *\n\n' );
+export_empire_meshlines( fid, CSX );
+export_empire_settings( fid, CSX, FDTD );
+
+if isfield(CSX.Properties,'Material')
+ % process material
+ Material = CSX.Properties.Material;
+ options.Property = 'Material';
+ process_primitives( fid, Material, options );
+end
+if isfield(CSX.Properties,'Metal')
+ % process PEC
+ Metal = CSX.Properties.Metal;
+ options.Property = 'Metal';
+ process_primitives( fid, Metal, options );
+end
+
+fclose( fid );
+
+% -----------------------------------------------------------------------------
+function str = gym_vect( start,stop )
+str = ['[' num2str(start(1)) ',' num2str(stop(1)) ',' num2str(start(2)) ',' num2str(stop(2)) ',' num2str(start(3)) ',' num2str(stop(3)) ']'];
+function str = gym_vector( v )
+str = ['[' num2str(v(1))];
+for a=2:numel(v), str = [str ', ' num2str(v(a))]; end
+str = [str ']'];
+
+% -----------------------------------------------------------------------------
+function primitive_box( fid, CSX_box, layertype )
+%primitive_box( fid, CSX_box, layertype )
+% layertype may be: 'dielectric Dielectric' or 'conductor Conductor'
+global current_layer_prio
+properties = '';
+if current_layer_prio ~= CSX_box.ATTRIBUTE.Priority
+ properties = [properties ' prio ' num2str(CSX_box.ATTRIBUTE.Priority)];
+end
+if ~isempty(properties)
+ fprintf( fid, 'g.objecttext("%s")\n', [layertype properties] );
+end
+start = [CSX_box.P1.ATTRIBUTE.X CSX_box.P1.ATTRIBUTE.Y CSX_box.P1.ATTRIBUTE.Z];
+stop = [CSX_box.P2.ATTRIBUTE.X CSX_box.P2.ATTRIBUTE.Y CSX_box.P2.ATTRIBUTE.Z];
+fprintf( fid, 'g.layerextrude("z",%g,%g)\n', start(3), stop(3) );
+fprintf( fid, 'g.box(%g,%g,%g,%g)\n', start(1), start(2), stop(1), stop(2) );
+
+% -----------------------------------------------------------------------------
+function primitive_cylinder( fid, CSX_cylinder, layertype )
+%primitive_cylinder( fid, CSX_cylinder, layertype )
+% layertype may be: 'dielectric Dielectric' or 'conductor Conductor'
+global current_layer_prio
+properties = '';
+if current_layer_prio ~= CSX_cylinder.ATTRIBUTE.Priority
+ properties = [properties ' prio ' num2str(CSX_cylinder.ATTRIBUTE.Priority)];
+end
+if ~isempty(properties)
+ fprintf( fid, 'g.objecttext("%s")\n', [layertype properties] );
+end
+
+start = [CSX_cylinder.P1.ATTRIBUTE.X CSX_cylinder.P1.ATTRIBUTE.Y CSX_cylinder.P1.ATTRIBUTE.Z];
+stop = [CSX_cylinder.P2.ATTRIBUTE.X CSX_cylinder.P2.ATTRIBUTE.Y CSX_cylinder.P2.ATTRIBUTE.Z];
+
+radius = CSX_cylinder.ATTRIBUTE.Radius;
+if start([1 2]) == stop([1 2])
+ fprintf( fid, 'g.layerextrude("z",%g,%g)\n', start(3), stop(3) );
+ fprintf( fid, 'g.circle(%g,%g,%g)\n', start(1), start(2), radius );
+elseif start([1 3]) == stop([1 3])
+ fprintf( fid, 'g.layerextrude("y",%g,%g)\n', start(2), stop(2) );
+ fprintf( fid, 'g.circle(%g,%g,%g)\n', start(3), start(1), radius );
+elseif start([2 3]) == stop([2 3])
+ fprintf( fid, 'g.layerextrude("x",%g,%g)\n', start(1), stop(1) );
+ fprintf( fid, 'g.circle(%g,%g,%g)\n', start(2), start(3), radius );
+else
+ disp( ['cylinder coordinates: (' num2str(start) ') -> (' num2str(stop) ')'] );
+ error 'cylinder orientation not supported'
+end
+
+% -----------------------------------------------------------------------------
+function str = primitive_wire( CSX_wire, options )
+radius = CSX_wire.ATTRIBUTE.WireRadius;
+str = ['sphere_sweep { linear_spline, ' num2str(numel(CSX_wire.Vertex))];
+for a=1:numel(CSX_wire.Vertex)
+ % iterate over all vertices
+ v = [CSX_wire.Vertex{a}.ATTRIBUTE.X CSX_wire.Vertex{a}.ATTRIBUTE.Y CSX_wire.Vertex{a}.ATTRIBUTE.Z];
+ str = [str ', ' pov_vect(v) ', ' num2str(radius)];
+end
+str = [str ' ' options '}'];
+
+% -----------------------------------------------------------------------------
+function primitive_polygon( fid, CSX_polygon, layertype )
+%primitive_polygon( fid, CSX_polygon, layertype )
+% layertype may be: 'dielectric Dielectric' or 'conductor Conductor'
+global current_layer_prio
+properties = '';
+if current_layer_prio ~= CSX_polygon.ATTRIBUTE.Priority
+ properties = [properties ' prio ' num2str(CSX_polygon.ATTRIBUTE.Priority)];
+end
+if ~isempty(properties)
+ fprintf( fid, 'g.objecttext("%s")\n', [layertype properties] );
+end
+Elevation = CSX_polygon.ATTRIBUTE.Elevation;
+if (CSX_polygon.NormDir.ATTRIBUTE.X ~= 0)
+ NormDir = 'x';
+elseif (CSX_polygon.NormDir.ATTRIBUTE.Y ~= 0)
+ NormDir = 'y';
+elseif (CSX_polygon.NormDir.ATTRIBUTE.Z ~= 0)
+ NormDir = 'z';
+end
+coords = [];
+for a=1:numel(CSX_polygon.Vertex)
+ % iterate over all vertices
+ coords = [coords CSX_polygon.Vertex{a}.ATTRIBUTE.X1 CSX_polygon.Vertex{a}.ATTRIBUTE.X2];
+end
+fprintf( fid, 'g.layerextrude("%s",%g,%g)\n', NormDir, Elevation, Elevation+1 );
+fprintf( fid, 'g.poly(' );
+for n=1:numel(coords)
+ if n > 1
+ fprintf( fid, ', %g', coords(n) );
+ else
+ fprintf( fid, '%g', coords(n) );
+ end
+end
+fprintf( fid, ')\n' );
+
+
+
+
+% -----------------------------------------------------------------------------
+function process_primitives( fid, prop, options )
+global current_layer_prio
+ignore = {};
+if isfield(options,'ignore'), ignore = options.ignore; end
+
+% iterate over all properties and extract the priority
+prio = [];
+for num=1:numel(prop)
+ if isfield(prop{num}.Primitives,'Box')
+ for a=1:numel(prop{num}.Primitives.Box)
+ % iterate over all boxes
+ prio(end+1) = prop{num}.Primitives.Box{a}.ATTRIBUTE.Priority;
+ end
+ end
+ if isfield(prop{num}.Primitives,'Cylinder')
+ for a=1:numel(prop{num}.Primitives.Cylinder)
+ % iterate over all cylinders
+ prio(end+1) = prop{num}.Primitives.Cylinder{a}.ATTRIBUTE.Priority;
+ end
+ end
+ if isfield(prop{num}.Primitives,'Polygon')
+ for a=1:numel(prop{num}.Primitives.Polygon)
+ % iterate over all polygons
+ prio(end+1) = prop{num}.Primitives.Polygon{a}.ATTRIBUTE.Priority;
+ end
+ end
+end
+% Now prio is a vector full of priorities. Extract the priority, which is
+% most often used.
+u_prios = unique(prio);
+count = histc(prio,u_prios);
+[~,idx] = max(count);
+current_layer_prio = u_prios(idx);
+
+% now export all properties/primitives
+for num=1:numel(prop)
+ Name = prop{num}.ATTRIBUTE.Name;
+ if any( strcmp(Name,ignore) )
+ disp( ['omitting ' Name '...'] );
+ continue
+ end
+
+ disp( ['processing ' prop{num}.ATTRIBUTE.Name '...'] );
+
+ if strcmp(options.Property,'Metal')
+ layertype = 'conductor';
+ properties = [layertype ' sigma infinite sides auto rough 0 prio ' num2str(current_layer_prio) ' automodel auto'];
+ else
+ layertype = 'dielectric';
+ epsr = 1;
+ sigma = 0;
+ if isfield(prop{num},'PropertyX')
+ if isfield(prop{num}.PropertyX.ATTRIBUTE,'Epsilon'), epsr = prop{num}.PropertyX.ATTRIBUTE.Epsilon; end
+ if isfield(prop{num}.PropertyX.ATTRIBUTE,'Kappa'), sigma = prop{num}.PropertyX.ATTRIBUTE.Kappa; end
+ end
+ properties = [layertype ' epsr ' num2str(epsr) ' sigma ' num2str(sigma) ' prio ' num2str(current_layer_prio) ' tand 0 density 0'];
+ end
+
+ export_empire_layer( fid, Name, properties )
+
+ if isfield(prop{num}.Primitives,'Box')
+ for a=1:numel(prop{num}.Primitives.Box)
+ % iterate over all boxes
+ Box = prop{num}.Primitives.Box{a};
+ primitive_box( fid, Box, layertype );
+ end
+ end
+ if isfield(prop{num}.Primitives,'Cylinder')
+ for a=1:numel(prop{num}.Primitives.Cylinder)
+ % iterate over all cylinders
+ Cylinder = prop{num}.Primitives.Cylinder{a};
+ primitive_cylinder( fid, Cylinder, layertype );
+ end
+ end
+ if isfield(prop{num}.Primitives,'Wire')
+ for a=1:numel(prop{num}.Primitives.Wire)
+ % iterate over all wires
+ Wire = prop{num}.Primitives.Wire{a};
+% str = primitive_wire( Wire, obj_modifier );
+% fprintf( fid, '%s\n', str );
+ end
+ warning( 'CSXCAD:export_empire', 'primitive wire currently unsupported' );
+ end
+ if isfield(prop{num}.Primitives,'Polygon')
+ for a=1:numel(prop{num}.Primitives.Polygon)
+ % iterate over all polygons
+ Polygon = prop{num}.Primitives.Polygon{a};
+ primitive_polygon( fid, Polygon, layertype );
+ end
+ end
+
+ fprintf( fid, 'g.load()\n\n' );
+end
+
+
+
+
+function export_empire_layer( fid, name, layertext )
+fprintf( fid, '# create a new layer\n' );
+fprintf( fid, 'g = gmf()\n' );
+fprintf( fid, 'g.layer("%s")\n', name );
+fprintf( fid, 'g.layerextrude("z",0,0)\n' );
+fprintf( fid, 'g.layertext("%s")\n', layertext );
+
+function export_empire_meshlines(fid,CSX)
+fprintf( fid, '# create the mesh\n' );
+fprintf( fid, 'empty_disc()\n' );
+fprintf( fid, 'g = gmf()\n' );
+fprintf( fid, 'g.raw_write("DISC X %g")\n', CSX.RectilinearGrid.XLines );
+fprintf( fid, 'g.raw_write("DISC Y %g")\n', CSX.RectilinearGrid.YLines );
+fprintf( fid, 'g.raw_write("DISC Z %g")\n', CSX.RectilinearGrid.ZLines );
+fprintf( fid, 'g.load()\n\n' );
+
+function empire_BC = convert_BC( openEMS_BC )
+if ischar(openEMS_BC)
+ if strcmp(openEMS_BC,'PEC')
+ empire_BC = 'electric';
+ elseif strcmp(openEMS_BC,'PMC')
+ empire_BC = 'magnetic';
+ elseif strncmp(openEMS_BC,'MUR',3) || strncmp(openEMS_BC,'PML',3)
+ empire_BC = 'pml 6';
+ else
+ empire_BC = 'UNKNOWN';
+ end
+else
+ if openEMS_BC == 0
+ empire_BC = 'electric';
+ elseif openEMS_BC == 1
+ empire_BC = 'magnetic';
+ elseif openEMS_BC == 2 || openEMS_BC == 3
+ empire_BC = 'pml 6';
+ else
+ empire_BC = 'UNKNOWN';
+ end
+end
+
+function export_empire_settings(fid,CSX,FDTD)
+fprintf( fid, '# settings\n' );
+fprintf( fid, 'set_fs_parameter( ''dx'', %g )\n', CSX.RectilinearGrid.ATTRIBUTE.DeltaUnit );
+fprintf( fid, 'set_fs_parameter( ''xmin'', ''%s'' )\n', convert_BC(FDTD.BoundaryCond.ATTRIBUTE.xmin) );
+fprintf( fid, 'set_fs_parameter( ''xmax'', ''%s'' )\n', convert_BC(FDTD.BoundaryCond.ATTRIBUTE.xmax) );
+fprintf( fid, 'set_fs_parameter( ''ymin'', ''%s'' )\n', convert_BC(FDTD.BoundaryCond.ATTRIBUTE.ymin) );
+fprintf( fid, 'set_fs_parameter( ''ymax'', ''%s'' )\n', convert_BC(FDTD.BoundaryCond.ATTRIBUTE.ymax) );
+fprintf( fid, 'set_fs_parameter( ''zmin'', ''%s'' )\n', convert_BC(FDTD.BoundaryCond.ATTRIBUTE.zmin) );
+fprintf( fid, 'set_fs_parameter( ''zmax'', ''%s'' )\n', convert_BC(FDTD.BoundaryCond.ATTRIBUTE.zmax) );
+fprintf( fid, 'set_fs_parameter( ''f_0'', %g )\n', FDTD.Excitation.ATTRIBUTE.f0 );
+fprintf( fid, 'set_fs_parameter( ''f_c'', %g )\n', FDTD.Excitation.ATTRIBUTE.fc );
+f_start = max(0,FDTD.Excitation.ATTRIBUTE.f0 - FDTD.Excitation.ATTRIBUTE.fc);
+f_end = max(0,FDTD.Excitation.ATTRIBUTE.f0 + FDTD.Excitation.ATTRIBUTE.fc);
+fprintf( fid, 'set_fs_parameter( ''F_START'', %g )\n', f_start );
+fprintf( fid, 'set_fs_parameter( ''F_END'', %g )\n', f_end );
+fprintf( fid, 'set_fs_parameter( ''F_MID'', %g )\n', (f_start+f_end)/2 );