analytic_2d_circle

PURPOSE ^

V = analytic_2d_circle(J, [s_h, s_i, b, a, angl])

SYNOPSIS ^

function V = analytic_2d_circle(I, params)

DESCRIPTION ^

 V = analytic_2d_circle(J, [s_h, s_i, b, a, angl])
 Voltage around a 2D circle with properties
   conductivities: tank(s_h), inclusion(s_i)
   tank radius = 1
   inclusion: radius(a), distance(b) at angle(angl)

 J = current density at a regular sample of nodes on the boundary
    because analytic_2d_circle works on current density, it needs
    to be scaled with the number of sample points, to get I

 Based on eqn 21 in Seagar and Bates (1985).

 (C) Andy Adler 2009. License: GPL V2 or V3
 $Id: analytic_2d_circle.html 2819 2011-09-07 16:43:11Z aadler $

 USAGE EXAMPLE: compare FEM to analytic model

  imdl= mk_common_model('c2c0',16);
 img = calc_jacobian_bkgnd(imdl);
 img.fwd_solve.get_all_meas = 1;
 img.elem_data(1:256)= 0.1;
 vi= fwd_solve(img);
 
 [jnk,maxl] = min(vi.volt(:,1));
 vi= vi.volt(maxl:end,1);
 lv= length(vi);
 
 vol = get_elem_volume(img.fwd_model);
 vt= sum(vol); va= sum(vol(img.elem_data ~=1));
 rad = sqrt(va/vt);
 
 I =  zeros(lv,1); I(1+[0,lv/16]) = [-25,25]*lv/16;
 vsi= analytic_2d_circle(I, [1, 0.1, 0.0, rad, 0]);
 
 plot([vi,vsi]);

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function V = analytic_2d_circle(I, params)
0002 % V = analytic_2d_circle(J, [s_h, s_i, b, a, angl])
0003 % Voltage around a 2D circle with properties
0004 %   conductivities: tank(s_h), inclusion(s_i)
0005 %   tank radius = 1
0006 %   inclusion: radius(a), distance(b) at angle(angl)
0007 %
0008 % J = current density at a regular sample of nodes on the boundary
0009 %    because analytic_2d_circle works on current density, it needs
0010 %    to be scaled with the number of sample points, to get I
0011 %
0012 % Based on eqn 21 in Seagar and Bates (1985).
0013 %
0014 % (C) Andy Adler 2009. License: GPL V2 or V3
0015 % $Id: analytic_2d_circle.html 2819 2011-09-07 16:43:11Z aadler $
0016 %
0017 % USAGE EXAMPLE: compare FEM to analytic model
0018 %
0019 %  imdl= mk_common_model('c2c0',16);
0020 % img = calc_jacobian_bkgnd(imdl);
0021 % img.fwd_solve.get_all_meas = 1;
0022 % img.elem_data(1:256)= 0.1;
0023 % vi= fwd_solve(img);
0024 %
0025 % [jnk,maxl] = min(vi.volt(:,1));
0026 % vi= vi.volt(maxl:end,1);
0027 % lv= length(vi);
0028 %
0029 % vol = get_elem_volume(img.fwd_model);
0030 % vt= sum(vol); va= sum(vol(img.elem_data ~=1));
0031 % rad = sqrt(va/vt);
0032 %
0033 % I =  zeros(lv,1); I(1+[0,lv/16]) = [-25,25]*lv/16;
0034 % vsi= analytic_2d_circle(I, [1, 0.1, 0.0, rad, 0]);
0035 %
0036 % plot([vi,vsi]);
0037 
0038 
0039 if ~all(abs(sum(I,1)) <1e-12); error('net I must be 0'); end
0040 [ll,nv] = size(I);
0041 
0042 IF= fft(I); IF(1)= []; % Don't include zero term
0043 [SM,ll2] = solve_matrix(ll, params);
0044 VF2= SM*IF(ll2);
0045 VF= zeros(size(I));
0046 VF(1+[ll2, ll-ll2],:)= [VF2;conj(VF2)];
0047 V = ifft(VF);
0048 
0049 if norm(imag(V))>1e-9; error('Unexpected Imaginary output - probably a bug'); end
0050 V= real(V);
0051 
0052 
0053 function [SM,ll2] = solve_matrix(ll, params)
0054   ll1= ll-1; % IGNORE DC
0055   ll2 = 1:ceil(ll1/2);
0056 
0057   SM = eidors_obj('get-cache', {ll,params}, 'analytic_2d_circle');
0058   if ~isempty(SM)
0059      eidors_msg('analytic_2d_circle: using cached value', 3);
0060      return
0061   end
0062   
0063    s_h = params(1);
0064    s_i = params(2);
0065    b   = params(3);
0066    a   = params(4);
0067    alp = params(5);
0068 
0069    mll2= max(ll2);
0070    K = ll2(:);
0071    D = spdiags(K,0,mll2,mll2);
0072    iD = spdiags(1./K,0,mll2,mll2); % inv D
0073 
0074    if s_h == s_i 
0075       SM= 1/s_h * iD;
0076       return
0077    end
0078 
0079    mu = (s_h - s_i) / (s_h + s_i);
0080 
0081    if b==0
0082       mua2k = mu*a.^(2*K);
0083       K = K.*(1 - mua2k)./(1 + mua2k);
0084       iD = spdiags(1./K,0,mll2,mll2); % inv(D)
0085 
0086       SM= 1/s_h * iD;
0087       return
0088    end
0089 
0090 
0091 
0092    T = sparse(mll2,mll2);
0093    for m=ll2; for n=ll2
0094      sm= 0;
0095      for p=1:min(m,n)
0096 %      sm=sm+ nchoosek(m-1,p-1)*nchoosek(n,p)*ab2^p;
0097        % stop calculating nchoosek when too small, because
0098        dsm = nchoosek(m-1,p-1)*nchoosek(n,p)*a^(2*p)*b^(m+n-2*p);
0099 %       disp([m,n,p,log10(dsm)])
0100        if dsm < 1e-11; break; end  
0101        sm=sm + dsm;
0102      end
0103 %    T(i,j) = mu*(sm/m)* b^(m+n) * exp(1j*(m-n)*alp);
0104      T(m,n) = mu*(sm/m)* exp(1j*(m-n)*alp);
0105    end; end
0106 
0107    I= speye(mll2);
0108    SM = (I-T*D)\(I+T*D)*iD;
0109 
0110    eidors_obj('set-cache', {ll,params}, 'analytic_2d_circle', SM);
0111    eidors_msg('analytic_2d_circle: setting cached value', 3);

Generated on Tue 09-Aug-2011 11:38:31 by m2html © 2005