0001 function test_2d_resistor(opt)
0002
0003
0004
0005 if nargin>0 && strcmp(opt,'UNIT_TEST'); do_unit_test; return; end
0006
0007 resistor_test;
0008
0009 function img = this_mdl(conduc, z_contact, current);
0010 nn= 12;
0011 ww=3;
0012 scale = .35;
0013 mdl=mk_grid_model([],3+scale*(1:ww), scale*(1:nn/ww));
0014 mdl= rmfield(mdl,'coarse2fine');
0015
0016 mdl.gnd_node = 1;
0017 elec_nodes= [1:ww];
0018 elec(1).nodes= elec_nodes; elec(1).z_contact= z_contact;
0019 elec(2).nodes= nn-elec_nodes+1; elec(2).z_contact= z_contact;
0020 stim.stim_pattern= [-1;1]*current;
0021 stim.meas_pattern= [-1,1];
0022 mdl.stimulation= stim;
0023 mdl.electrode= elec;
0024 n_el = size(mdl.elems,1);
0025 img= eidors_obj('image','2D rectangle', ...
0026 'elem_data', ones(n_el,1) * conduc );
0027 img.fwd_model = mdl;
0028 img.fwd_model.normalize_measurements = 0;
0029
0030 function V = analytic_soln(img);
0031
0032 nodes = img.fwd_model.nodes;
0033 wid_len= max(nodes) - min(nodes);
0034 conduc = mean(img.elem_data);
0035 Block_R = wid_len(2) / wid_len(1) / conduc;
0036
0037
0038
0039
0040
0041 z_contact = sum([img.fwd_model.electrode(:).z_contact]);
0042 current = max(img.fwd_model.stimulation(1).stim_pattern(:));
0043 Contact_R = z_contact/wid_len(1);
0044 R = Block_R + Contact_R;
0045
0046 V= current*R;
0047 fprintf('Solver %s: %f\n', 'analytic', V);
0048 fprintf('Solver %s: %f\n', 'analytic (no z_contact)', V - 2*Contact_R*current);
0049
0050 function V = first_order_solver( img );
0051
0052 img.fwd_model.solve = @fwd_solve_1st_order;
0053 img.fwd_model.system_mat = @system_mat_1st_order;
0054 fsol= fwd_solve(img);
0055 fprintf('Solver %s: %f\n', fsol.name, fsol.meas);
0056 V = fsol.meas;
0057
0058 function vals = RC_test;
0059
0060 current= 4;
0061 conduc= .4 + 2*pi*j*10;
0062 z_contact= 1e-1;
0063 img = this_mdl( conduc, z_contact, current);
0064
0065 vals.analytic = analytic_soln(img);
0066 vals.aa_solver = first_order_solver(img);
0067
0068 function vals = resistor_test;
0069
0070 current= 4;
0071 conduc= .4;
0072 z_contact= 1e-1;
0073 img = this_mdl( conduc, z_contact, current);
0074
0075 show_fem(img.fwd_model);
0076
0077 vals.analytic = analytic_soln(img);
0078
0079
0080 vals.aa_solver = first_order_solver(img);
0081
0082 warn_state = warning('query','EIDORS:Deprecated');
0083 warning('off','EIDORS:Deprecated');
0084
0085
0086
0087 img.fwd_model.solve = @np_fwd_solve;
0088 img.fwd_model.system_mat = @np_calc_system_mat;
0089 fsol= fwd_solve(img);
0090 fprintf('Solver %s: %f\n', fsol.name, fsol.meas);
0091 vals.np_solver = fsol.meas;
0092
0093
0094 img.fwd_model.solve = @np_fwd_solve;
0095 img.fwd_model.jacobian = @np_calc_jacobian;
0096
0097 img.elem_data= ones(num_elems(img),1) * conduc ;
0098 Jnp= calc_jacobian(img);
0099
0100 img.fwd_model.jacobian = @jacobian_perturb;
0101 Jp1= calc_jacobian(img);
0102
0103 img.elem_data= ones(num_elems(img),1) * conduc ;
0104 Jp2= zeros(size(Jnp));
0105 delta= 1e-8;
0106 for i=1:num_elems(img)
0107 fsol_h= fwd_solve(img);
0108 img.elem_data(i) = img.elem_data(i) + delta;
0109 fsol_i= fwd_solve(img);
0110 Jp2(:,i) = (fsol_i.meas - fsol_h.meas)/delta;
0111 end
0112
0113 mdl.solve = @fwd_solve_1st_order;
0114 mdl.jacobian = @jacobian_adjoint;
0115 Jaa= calc_jacobian(img);
0116
0117
0118 fprintf('Jacobians: Cols by Jaa, Jnp, Jp1, Jp2:\n')
0119 JJ = [Jaa;Jnp;Jp1;Jp2];
0120 disp(JJ(:,1:6))
0121
0122
0123
0124
0125
0126 nn= 12;
0127 ww=2;
0128 if ~exist('conduc');conduc= .4;end
0129 current= 4;
0130 z_contact= 1e-2;
0131 scale = .35;
0132 mdl=mk_grid_model([],3+scale*(1:ww), scale*(1:nn/ww));
0133 xdelta= .05*mdl.nodes(1:ww:nn,2);
0134 mdl.nodes(1:ww:nn,1) = mdl.nodes(1:ww:nn,1) + xdelta;
0135 mdl.nodes(2:ww:nn,1) = mdl.nodes(2:ww:nn,1) - xdelta;
0136 mdl.gnd_node = 1;
0137 elec_nodes= [1:ww];
0138 elec(1).nodes= elec_nodes; elec(1).z_contact= z_contact;
0139 elec(2).nodes= nn-elec_nodes+1; elec(2).z_contact= z_contact;
0140 stim.stim_pattern= [-1;1]*current;
0141 stim.meas_pattern= [-1,1];
0142 mdl.stimulation= stim;
0143 mdl.electrode= elec;
0144 show_fem(mdl);
0145 n_el = size(mdl.elems,1);
0146 img= eidors_obj('image','2D rectangle', 'fwd_model',mdl, ...
0147 'elem_data', ones(n_el,1) * conduc );
0148
0149 mdl.solve = @fwd_solve_1st_order;
0150 mdl.system_mat = @system_mat_1st_order;
0151 img.fwd_model = mdl;
0152 fsol= fwd_solve(img);
0153 fprintf('Solver %s: %f\n', fsol.name, fsol.meas);
0154
0155 mdl.solve = @np_fwd_solve;
0156 mdl.system_mat = @np_calc_system_mat;
0157 fsol= fwd_solve(img);
0158 fprintf('Solver %s: %f\n', fsol.name, fsol.meas);
0159
0160
0161 e1= mdl.nodes(mdl.electrode(1).nodes,:);
0162 d1= sqrt( sum(( [1,-1]*e1 ).^2 ));
0163 e2= mdl.nodes(mdl.electrode(2).nodes,:);
0164 d2= sqrt( sum(( [1,-1]*e2 ).^2 ));
0165 hig= max(mdl.nodes(:,2)) - min(mdl.nodes(:,2));
0166
0167
0168
0169
0170
0171 R = (log(d2)-log(d1))*hig/(d2-d1)/conduc + 2*z_contact/scale;
0172 V= current*R;
0173 fprintf('Solver %s: %f\n', 'analytic', V);
0174 fprintf('Analytic is not expected to be same in last case\n');
0175
0176 warning(warn_state.state,'EIDORS:Deprecated');
0177
0178
0179 function do_unit_test
0180 vals = resistor_test;
0181
0182 unit_test_cmp('Analytic vs AA', vals.analytic, vals.aa_solver, 1e-10);
0183 unit_test_cmp('Analytic vs NP', vals.analytic, vals.np_solver, 1e-10);
0184
0185 vals = RC_test;
0186
0187 unit_test_cmp('Analytic vs AA', vals.analytic, vals.aa_solver, 1e-10);
0188