0001 function [fmdl,rm_elems] = mat_idx_to_electrode(fmdl, mat_idxes)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 if ischar(fmdl) && strcmp(fmdl,'UNIT_TEST'); do_unit_test; return; end
0026
0027 elec_faces = true;
0028 try
0029 elec_faces = ~fmdl.mat_idx_to_electrode.nodes_electrode;
0030 end
0031
0032 rm_elems = [];
0033 for i = 1:length(mat_idxes)
0034 if elec_faces
0035 [fmdl,rm_elemi] = create_electrode_faces_from_mat_idx(fmdl, mat_idxes{i});
0036 else
0037 [fmdl,rm_elemi] = create_electrode_nodes_from_mat_idx(fmdl, mat_idxes{i});
0038 end
0039 rm_elems = union(rm_elems,rm_elemi);
0040 end
0041
0042 fmdl = remove_unused_nodes(fmdl);
0043 if any(fmdl.boundary(:) == 0)
0044 keyboard
0045 end
0046
0047
0048
0049
0050 function [fmdl,femobj] = create_electrode_nodes_from_mat_idx(fmdl,nmat_idx);
0051 zc = 1e-5;
0052 try zc = fmdl.mat_idx_to_electrode.z_contact;
0053 end
0054 femobj = vertcat(fmdl.mat_idx{nmat_idx});
0055 faces = calc_elec_faces(fmdl.elems,femobj);
0056
0057 femobjnodes = fmdl.elems(femobj,:);
0058 [fmdl,faces] = rm_elems( fmdl, femobj, faces);
0059
0060 fmdl.boundary = unique([fmdl.boundary;faces],'rows');
0061
0062 vt = find_bdynodes(fmdl,femobjnodes);
0063 elstr = struct('nodes',vt(:)','z_contact',zc);
0064 fmdl = add_elec(fmdl, elstr);
0065
0066 function [fmdl,faces] = rm_elems( fmdl, femobj, faces);
0067
0068 for i=1:length(fmdl.mat_idx)
0069 els = false(num_elems(fmdl),1);
0070 els(fmdl.mat_idx{i}) = true;
0071 els(femobj) = [];
0072 fmdl.mat_idx{i} = find(els);
0073 end
0074 fmdl.elems(femobj,:) = [];
0075
0076 if nargin>2
0077 inels = reshape(...
0078 ismember(faces(:),fmdl.elems(:)), size(faces));
0079 faces(any(~inels,2),:) = [];
0080 end
0081
0082
0083
0084
0085 function [fmdl,femobj] = create_electrode_faces_from_mat_idx(fmdl,nmat_idx);
0086 zc = 1e-5;
0087 try zc = fmdl.mat_idx_to_electrode.z_contact;
0088 end
0089 femobj = vertcat(fmdl.mat_idx{nmat_idx});
0090 faces = calc_elec_faces(fmdl.elems,femobj);
0091 [fmdl,faces] = rm_elems( fmdl, femobj, faces);
0092 fmdl.boundary = unique([fmdl.boundary;faces],'rows');
0093
0094 elstr = struct('nodes',[],'z_contact',zc,'faces',faces);
0095
0096 fmdl = add_elec(fmdl, elstr);
0097
0098 function fmdl = add_elec(fmdl, elstr)
0099 if isfield(fmdl,'electrode')
0100
0101 if isfield(elstr,'faces') && ~isfield(fmdl.electrode,'faces');
0102 [fmdl.electrode(:).faces] = deal([]);
0103 end
0104 fmdl.electrode(end+1) = elstr;
0105 else
0106 fmdl.electrode( 1) = elstr;
0107 end
0108
0109 function faces = calc_elec_faces(elems,femobj);
0110 thisels = elems(femobj,:);
0111 switch size(thisels,2)
0112 case 2;
0113 allfaces = thisels;
0114 case 3;
0115 allfaces = [thisels(:,[1,2]);
0116 thisels(:,[2,3]);
0117 thisels(:,[1,3])];
0118 case 4;
0119 allfaces = [thisels(:,[1,2,3]);
0120 thisels(:,[1,2,4]);
0121 thisels(:,[1,3,4]);
0122 thisels(:,[2,3,4])];
0123 otherwise;
0124 error 'Dimensions of elems';
0125 end
0126 allfaces = sort(allfaces,2);
0127
0128 [faces,ia,ib] = unique(allfaces,'rows');
0129 exist_faces = sparse(1,ib,1);
0130 faces(exist_faces>1,:) = [];
0131
0132 function vt = find_bdynodes(fmdl,femobjnodes)
0133
0134
0135
0136 usenodes = reshape( ismember( ...
0137 fmdl.elems, femobjnodes), size(fmdl.elems));
0138 fmdl.elems(~any(usenodes,2),:) = [];
0139 vt = intersect(femobjnodes,find_boundary(fmdl));
0140
0141
0142 function do_unit_test
0143 clf; subplot(221);
0144 do_unit_test_2d(true)
0145 do_unit_test_2d(false)
0146 subplot(223);
0147
0148
0149 function do_unit_test_2d(nodes_electrode)
0150 fmdl = getfield(mk_common_model('a2c2',1),'fwd_model');
0151 fmdl.mat_idx_to_electrode.nodes_electrode = nodes_electrode;
0152 fmdl.electrode(1).nodes = 26:41;
0153 fmdl.mat_idx{1} = [1:4];
0154 fmdl= mat_idx_to_electrode(fmdl, {1});
0155 unit_test_cmp('a2c2-01',num_elems(fmdl),64-4);
0156 if nodes_electrode;
0157 unit_test_cmp('a2c2-02',length(fmdl.electrode(2).nodes),4);
0158 else
0159 unit_test_cmp('a2c2-02a',length(fmdl.electrode(2).nodes),0);
0160 unit_test_cmp('a2c2-02b',size(fmdl.electrode(2).faces),[4,2]);
0161 end
0162
0163 fmdl.stimulation = stim_meas_list([1,2,1,2]);
0164 img = mk_image(fmdl,1);
0165 img.fwd_solve.get_all_meas = true;
0166 vh = fwd_solve(img);
0167
0168 img = rmfield(img,'elem_data');
0169 img.node_data = vh.volt;
0170
0171 img.fwd_model = rmfield(img.fwd_model,'electrode');
0172 show_fem(img,[0,0,2]);
0173
0174 unit_test_cmp('a2c2-03', std(vh.volt(13:24)),0,0.002);
0175 vd = mean(vh.volt(5:12)) - mean(vh.volt(13:24));
0176 unit_test_cmp('a2c2-03', vd,0.065251,1e-6);
0177
0178
0179
0180 function do_unit_test_3d_netgen
0181 extra={'ball_inside','ball_surface', [ ...
0182 'solid ball_inside = sphere(-0.4,0,0.5;0.05);' ...
0183 'solid ball_surface = sphere( 0.4,0,1.0;0.05) -maxh=.005;' ...
0184 ]};
0185 fmdl= ng_mk_cyl_models(1,[8,.5],[.1],extra);
0186 fmdl.mat_idx_to_electrode.nodes_electrode = true;
0187
0188 fmd_= mat_idx_to_electrode(fmdl, {2,3});
0189 unit_test_cmp('cyl_models 01',num_elecs(fmd_),10);
0190
0191 fmd_= mat_idx_to_electrode(fmdl, {2:3});
0192 unit_test_cmp('cyl_models 02',num_elecs(fmd_),9);
0193
0194 fmd_= mat_idx_to_electrode(fmdl, {2});
0195 unit_test_cmp('cyl_models 03',num_elecs(fmd_),9);
0196
0197 img = mk_image(fmd_,1);
0198 img.elem_data(fmd_.mat_idx{3})= 1.1;
0199 img.calc_colours.ref_level = 1;
0200 unit_test_cmp('cyl_models 04',num_elecs(img),9);
0201
0202 img = mk_image(fmdl,1);
0203 img.elem_data(vertcat(fmdl.mat_idx{2:3}))= 1.1;
0204 [img.fwd_model,rm_elems]= mat_idx_to_electrode( ...
0205 img.fwd_model, {2});
0206 img.elem_data(rm_elems) = [];
0207 unit_test_cmp('cyl_models 05',num_elecs(img),9);
0208 vol = get_elem_volume(img);
0209 vvs = sum(vol(find(img.elem_data == 1.1)));
0210 unit_test_cmp('cyl_models 05a',vvs,4/3*pi*.05^3,1e-5);
0211
0212
0213
0214 img.calc_colours.ref_level = 1;
0215 show_fem(img); view(3,12);
0216