0001 function opt = ng_write_opt(varargin)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061 if nargin == 1 && ischar(varargin{1}) && strcmp(varargin{1},'UNIT_TEST')
0062 do_unit_test; return; end
0063
0064 if nargin == 1 && ischar(varargin{1}) && exist(varargin{1},'file')
0065 copyfile(varargin{1},'ng.opt');
0066 return
0067 end
0068
0069
0070 if nargin == 1 && ischar(varargin{1}) && strcmp(varargin{1},'EXIST:ng.opt')
0071 opt = isfile('./ng.opt');
0072 return
0073 end
0074
0075 nargs = nargin;
0076
0077 str = {};
0078
0079 if nargs >= 1 && ischar(varargin{1}) && ~any(varargin{1} == '.') ...
0080 && isempty(strfind(varargin{1},'MSZ'))
0081 str = varargin(1);
0082 varargin(1) = [];
0083 nargs = nargs - 1;
0084 end
0085
0086
0087 opt = default_opt(str{:});
0088
0089 if nargs == 0
0090 usr = struct;
0091 end
0092
0093 if nargs == 1 && isstruct(varargin{1})
0094 usr = varargin{1};
0095 end
0096 if nargs > 1
0097 usr = process_input(varargin{:});
0098 end
0099 opt = copy_field(opt,usr);
0100
0101 if nargout == 1
0102 return
0103 end
0104
0105
0106 write_ng_file(opt);
0107
0108 function opt = process_input(varargin)
0109 if mod(nargin,2)~=0
0110 error('EIDORS:WrongInput','Even number of inputs expected');
0111 end
0112 mszpoints = [];
0113 for i = 1:nargin/2
0114 idx = (i-1)*2 +1;
0115 val = varargin{idx+1};
0116 switch varargin{idx}
0117
0118 case 'MSZPOINTS'
0119
0120 mszpoints = [mszpoints;val];
0121 case 'MSZBRICK'
0122 mszpoints = [mszpoints; msz_brick(val)];;
0123 case 'MSZSPHERE'
0124 mszpoints = [mszpoints; msz_sphere(val)];;
0125 case 'MSZCYLINDER'
0126 mszpoints = [mszpoints; msz_cylinder(val)];;
0127 case 'MSZZPLANE'
0128 xyz=val(1:3);
0129 planeval = [xyz-[0,0,1e-6],xyz+[0,0,1e-6],val(4:5)];
0130 mszpoints = [mszpoints; msz_cylinder(planeval)];
0131 otherwise
0132 eval(sprintf('opt.%s = val;',varargin{idx}));
0133 end
0134 end
0135 if ~isempty(mszpoints);
0136 tmpname = write_tmp_mszfile( mszpoints );
0137 opt.options.meshsizefilename = tmpname;
0138 end
0139
0140 function val = msz_brick(val)
0141
0142 maxh = val(7);
0143 xpts= floor(abs(diff(val(1:2))/maxh))+1;
0144 ypts= floor(abs(diff(val(3:4))/maxh))+1;
0145 zpts= floor(abs(diff(val(5:6))/maxh))+1;
0146 xsp= linspace(val(1),val(2), xpts);
0147 ysp= linspace(val(3),val(4), ypts);
0148 zsp= linspace(val(5),val(6), zpts);
0149 [xsp,ysp,zsp] = ndgrid(xsp,ysp,zsp);
0150 val = [xsp(:),ysp(:),zsp(:), maxh+0*xsp(:)];
0151
0152 function val = msz_sphere(val)
0153
0154 maxh = val(5);
0155 radius = val(4);
0156 npts= floor(2*radius/maxh)+1;
0157 xsp= linspace(val(1) - radius, val(1) + radius, npts);
0158 ysp= linspace(val(2) - radius, val(2) + radius, npts);
0159 zsp= linspace(val(3) - radius, val(3) + radius, npts);
0160 [xsp,ysp,zsp] = ndgrid(xsp,ysp,zsp);
0161 s_idx = ((xsp-val(1)).^2 + ...
0162 (ysp-val(2)).^2 + ...
0163 (zsp-val(3)).^2) < radius^2;
0164 s_idx = s_idx(:);
0165 val = [xsp(s_idx),ysp(s_idx),zsp(s_idx), maxh+0*xsp(s_idx)];
0166
0167
0168 function pts = space_around_zero(lim,maxh);
0169 pts = 0:maxh:lim;
0170 pts = [-fliplr(pts(2:end)),pts];
0171
0172 function val = msz_cylinder(val)
0173
0174 len2= norm(val(1:3) - val(4:6))/2;
0175 ctr = (val(1:3) + val(4:6))/2;
0176 radius = val(7);
0177 maxh = min(val(8),radius);
0178 xsp= space_around_zero(radius, maxh);
0179 ysp= space_around_zero(radius, maxh);
0180 zsp= space_around_zero(len2, maxh);
0181 [xsp,ysp,zsp] = ndgrid(xsp,ysp,zsp);
0182 s_idx = (xsp.^2 + ysp.^2) < radius^2;
0183 xsp = xsp(s_idx(:));
0184 ysp = ysp(s_idx(:));
0185 zsp = zsp(s_idx(:));
0186
0187
0188 ab = [0;0;2*len2] + [val(4:6)-val(1:3)]';
0189 R=2*ab*ab'/(ab'*ab) - eye(3);
0190 val = [xsp,ysp,zsp]*R + ctr;
0191 val(:,4) = maxh;
0192
0193 function fname = write_tmp_mszfile( mszpoints )
0194
0195
0196
0197
0198 n_pts_elecs= size(mszpoints,1);
0199 fname = [tempname,'.msz'];
0200 fname = strrep(fname,'\','/');
0201 fid=fopen(fname,'w');
0202 fprintf(fid,'%d\n',n_pts_elecs);
0203
0204
0205
0206
0207 fprintf(fid,'%10f %10f %10f %10f\n', mszpoints');
0208 fprintf(fid,'0\n');
0209 fclose(fid);
0210
0211
0212
0213 function opt = copy_field(opt,usr)
0214 optnms = fieldnames(opt);
0215 usrnms = fieldnames(usr);
0216 for i = 1:length(usrnms)
0217
0218 if ~ismember(usrnms{i},optnms)
0219 error('Unsupported option %s',usrnms{i});
0220 end
0221 if isstruct(usr.(usrnms{i}))
0222 opt.(usrnms{i}) = copy_field(opt.(usrnms{i}), usr.(usrnms{i}) );
0223 else
0224 opt.(usrnms{i}) = usr.(usrnms{i});
0225 end
0226 end
0227
0228
0229
0230 function write_ng_file(opt)
0231 fid = fopen('ng.opt','w');
0232 flds = fieldnames(opt);
0233 write_field(fid,opt,[]);
0234 fclose(fid);
0235
0236
0237
0238 function write_field(fid,s,str)
0239 if isstruct(s)
0240 if isempty(str)
0241 str = '';
0242 else
0243 str = [str '.'];
0244 end
0245 flds = fieldnames(s);
0246 for i = 1:length(flds)
0247 write_field(fid,s.(flds{i}),[str flds{i}]);
0248 end
0249 elseif ischar(s)
0250 fprintf(fid,'%s %s\n', str, s);
0251 elseif round(s) == s
0252 fprintf(fid,'%s %d\n', str, s);
0253 else
0254 fprintf(fid,'%s %f\n', str, s);
0255 end
0256
0257
0258 function opt = default_opt(varargin)
0259 if nargin == 0
0260 str = 'moderate';
0261 else
0262 str = varargin{1};
0263 end
0264 switch str
0265 case 'very_coarse'
0266
0267 v = [6, 1.0, 0.3, 0.7, 0.25, 0.8, 0.20, 0.5, 0.25, 1.0];
0268 case 'coarse'
0269
0270 v = [6, 1.5, 0.5, 0.5, 0.50, 1.0, 0.35, 1.0, 0.50, 1.5];
0271 case 'moderate'
0272
0273 v = [6, 2.0, 1.0, 0.3, 1.00, 1.5, 0.50, 2.0, 1.00, 2.0];
0274 case 'fine'
0275
0276 v = [6, 3.0, 2.0, 0.2, 1.50, 2.0, 1.50, 3.5, 1.50, 3.0];
0277 case 'very_fine'
0278
0279 v = [6, 5.0, 3.0, 0.1, 3.00, 5.0, 3.00, 5.0, 3.00, 5.0];
0280 otherwise
0281
0282 v = [6, 2.0, 1.0, 0.3, 1.00, 1.5, 0.50, 2.0, 1.00, 2.0];
0283 end
0284
0285 opt.dirname = '.';
0286 opt.loadgeomtypevar = '"All Geometry types (*.stl,*.stlb,*.step,*.stp,...)"';
0287 opt.exportfiletype = '"Neutral Format"';
0288 opt.meshoptions.fineness = v(1);
0289 opt.meshoptions.firststep = 'ag';
0290 opt.meshoptions.laststep = 'ov';
0291 opt.options.localh = 1;
0292 opt.options.delaunay = 1;
0293 opt.options.checkoverlap = 1;
0294 opt.options.checkchartboundary = 1;
0295 opt.options.startinsurface = 0;
0296 opt.options.blockfill = 1;
0297 opt.options.debugmode = 0;
0298 opt.options.dooptimize = 1;
0299 opt.options.parthread = 1;
0300 opt.options.elsizeweight = 0.2;
0301 opt.options.secondorder = 0;
0302 opt.options.elementorder = 1;
0303 opt.options.quad = 0;
0304 opt.options.inverttets = 0;
0305 opt.options.inverttrigs = 0;
0306 opt.options.autozrefine = 0;
0307 opt.options.meshsize = 1000;
0308 opt.options.minmeshsize = 0;
0309 opt.options.curvaturesafety = v(2);
0310 opt.options.segmentsperedge = v(3);
0311 opt.options.meshsizefilename = '';
0312 opt.options.badellimit = 175;
0313 opt.options.optsteps2d = 3;
0314 opt.options.optsteps3d = 5;
0315 opt.options.opterrpow = 2;
0316 opt.options.grading = v(4);
0317 opt.options.printmsg = 2;
0318 opt.geooptions.drawcsg = 1;
0319 opt.geooptions.detail = 0.001;
0320 opt.geooptions.accuracy = 1e-6;
0321 opt.geooptions.facets = 20;
0322 opt.geooptions.minx = -1000;
0323 opt.geooptions.miny = -1000;
0324 opt.geooptions.minz = -1000;
0325 opt.geooptions.maxx = 1000;
0326 opt.geooptions.maxy = 1000;
0327 opt.geooptions.maxz = 1000;
0328 opt.viewoptions.specpointvlen = 0.3;
0329 opt.viewoptions.light.amb = 0.3;
0330 opt.viewoptions.light.diff = 0.7;
0331 opt.viewoptions.light.spec = 1;
0332 opt.viewoptions.light.locviewer = 0;
0333 opt.viewoptions.mat.shininess = 50;
0334 opt.viewoptions.mat.transp = 0.3;
0335 opt.viewoptions.colormeshsize = 0;
0336 opt.viewoptions.whitebackground = 1;
0337 opt.viewoptions.drawcolorbar = 1;
0338 opt.viewoptions.drawcoordinatecross = 1;
0339 opt.viewoptions.drawnetgenlogo = 1;
0340 opt.viewoptions.stereo = 0;
0341 opt.viewoptions.drawfilledtrigs = 1;
0342 opt.viewoptions.drawedges = 0;
0343 opt.viewoptions.drawbadels = 0;
0344 opt.viewoptions.centerpoint = 0;
0345 opt.viewoptions.drawelement = 0;
0346 opt.viewoptions.drawoutline = 1;
0347 opt.viewoptions.drawtets = 0;
0348 opt.viewoptions.drawprisms = 0;
0349 opt.viewoptions.drawpyramids = 0;
0350 opt.viewoptions.drawhexes = 0;
0351 opt.viewoptions.drawidentified = 0;
0352 opt.viewoptions.drawpointnumbers = 0;
0353 opt.viewoptions.drawededges = 1;
0354 opt.viewoptions.drawedpoints = 1;
0355 opt.viewoptions.drawedpointnrs = 0;
0356 opt.viewoptions.drawedtangents = 0;
0357 opt.viewoptions.shrink = 1;
0358 opt.stloptions.showtrias = 0;
0359 opt.stloptions.showfilledtrias = 1;
0360 opt.stloptions.showedges = 1;
0361 opt.stloptions.showmarktrias = 0;
0362 opt.stloptions.showactivechart = 0;
0363 opt.stloptions.yangle = 30;
0364 opt.stloptions.contyangle = 20;
0365 opt.stloptions.edgecornerangle = 60;
0366 opt.stloptions.chartangle = 15;
0367 opt.stloptions.outerchartangle = 70;
0368 opt.stloptions.usesearchtree = 0;
0369 opt.stloptions.chartnumber = 1;
0370 opt.stloptions.charttrignumber = 1;
0371 opt.stloptions.chartnumberoffset = 0;
0372 opt.stloptions.atlasminh = 0.1;
0373 opt.stloptions.resthsurfcurvfac = v(5);
0374 opt.stloptions.resthsurfcurvenable = 0;
0375 opt.stloptions.resthatlasfac = 2;
0376 opt.stloptions.resthatlasenable = 1;
0377 opt.stloptions.resthchartdistfac = v(6);
0378 opt.stloptions.resthchartdistenable = 0;
0379 opt.stloptions.resthlinelengthfac = v(7);
0380 opt.stloptions.resthlinelengthenable = 1;
0381 opt.stloptions.resthcloseedgefac = v(8);
0382 opt.stloptions.resthcloseedgeenable = 1;
0383 opt.stloptions.resthedgeanglefac = v(9);
0384 opt.stloptions.resthedgeangleenable = 0;
0385 opt.stloptions.resthsurfmeshcurvfac = v(10);
0386 opt.stloptions.resthsurfmeshcurvenable = 0;
0387 opt.stloptions.recalchopt = 1;
0388 opt.visoptions.subdivisions = 1;
0389
0390 function do_unit_test
0391 test_main_options()
0392 unit_test_MSZ()
0393
0394
0395 function test_caching()
0396 for test=0:10; switch test
0397 case 0; fclose(fopen('ng.opt','w'));
0398 delete('ng.opt');
0399 eidors_cache clear
0400 nel_ = 1599;
0401 case 1; ng_write_opt('moderate');
0402 nel_ = 1599;
0403 case 2; ng_write_opt('coarse');
0404 nel_ = 570;
0405 case 3; ng_write_opt('MSZCYLINDER',[0,0,.1,0,0,.2,1,0.05]);
0406 nel_ = 43861;
0407 otherwise; break;
0408 end
0409 fmdl= ng_mk_cyl_models(1,[2,0.5],0.1);
0410 nel = num_elems(fmdl);
0411 show_fem(fmdl); title(sprintf('Nel=%d',nel))
0412 unit_test_cmp(sprintf( ...
0413 'Cache: ng.opt #%d',test), nel, nel_);
0414 end
0415
0416 function test_main_options()
0417 opt.meshoptions.fineness = 6;
0418 ng_write_opt(opt);
0419 fid = fopen('ng.opt','r'); str= fread(fid,[1,inf],'uint8=>char'); fclose(fid);
0420 unit_test_cmp('fineness=6',isempty( ...
0421 strfind(str, 'meshoptions.fineness 6')), 0);
0422
0423 ng_write_opt('meshoptions.fineness',4,'meshoptions.firststep','aaa');
0424 fid = fopen('ng.opt','r'); str= fread(fid,[1,inf],'uint8=>char'); fclose(fid);
0425 unit_test_cmp('firststep=aaa',isempty( ...
0426 strfind(str, 'meshoptions.firststep aaa')), 0);
0427
0428
0429 opt = ng_write_opt('meshoptions.fineness',4,'meshoptions.firststep','bbb');
0430 fid = fopen('ng.opt','r'); str= fread(fid,[1,inf],'uint8=>char'); fclose(fid);
0431 unit_test_cmp('firststep=bbb',isempty( ...
0432 strfind(str, 'meshoptions.firststep bbb')), 1);
0433
0434 function unit_test_MSZ
0435 shape_str = ...
0436 'solid mainobj = orthobrick(-9,-9,-9;9,9,9);';
0437 i=0; while(true); i=i+1; switch i
0438 case 1; n_exp = 8;
0439 ng_write_opt('very_coarse');
0440 case 2; n_exp = 22;
0441 ng_write_opt('fine');
0442 case 3; n_exp = 59;
0443 ng_write_opt('very_fine');
0444 case 4; n_exp = 8;
0445 ng_write_opt('moderate');
0446 case 5; n_exp = 746;
0447 ng_write_opt('MSZSPHERE',[5,5,5,4,1]);
0448 case 6; n_exp = 106;
0449 ng_write_opt('MSZBRICK',[5,5,5,9,9,9,1]);
0450 case 7; n_exp = 544;
0451 ng_write_opt('MSZCYLINDER',[5,5,5,8,8,8,5,1]);
0452 case 8; n_exp = 23;
0453 ng_write_opt('MSZCYLINDER',[5,5,5,8,8,8,5,5]);
0454 case 9; n_exp = 135;
0455 ng_write_opt('MSZCYLINDER',[5,5,5,5,5,8,1,5]);
0456 case 10; n_exp = 9876;
0457 ng_write_opt('MSZSPHERE',[6,6,6,2.2,0.2]);
0458 case 11; n_exp = 13242;
0459 ng_write_opt('fine','MSZSPHERE',[6,6,6,2.2,0.2]);
0460 case 12; n_exp = 3303;
0461 ng_write_opt('MSZSPHERE',[8,8,0,1.1,0.2],'MSZSPHERE',[-8,-8,0,1.1,0.2]);
0462 case 13; n_exp = 14821;
0463 ng_write_opt('fine','MSZSPHERE',[6,6,6,2.2,0.2],'MSZPOINTS',[0,0,0,0.1]);
0464 case 14; n_exp = 3051;
0465 ng_write_opt('MSZZPLANE',[5,5,5,1,.1]);
0466 otherwise; break
0467 end
0468 eidors_cache clear
0469 fmdl = ng_mk_gen_models(shape_str,[],[],'');
0470 unit_test_cmp('opt:', num_nodes(fmdl), n_exp)
0471
0472 end