% solve interior/exterior BVP with double-layer potential: Laplace and Helmholtz
% barnett 10/31/08

w = 3; a = 0.3;
R = @(t) 1 + a*cos(w*t); Rp = @(t) -a*w*sin(w*t);   % wobbly shape
Rpp = @(t) -a*w*w*cos(w*t);
%for k=0.1:0.1:4 % ................ uncomment for k-sweep
k = 6;                       % k=0 laplace (int only), k>0 helmholtz (int,ext)
ext = 1;                                            % ext=0,1: interior,exterior
g = -1.3:0.02:1.3;                                  % viewing grid
%g = 1;                                             % single pt (for N-loop)
N = 50;                                             % quad pts
%for N=20:20:300 % -------------- uncomment for N-loop
verb = 0; tauone = 0; % verb=0:quiet, 1:show stuff. set tauone=1 to test tau=1
if k==0
  f = @(x1,x2) cos(x1).*exp(x2);                    % Dirichlet data, laplace
else   % H0 source at (0,2) or (0,.5) if need exterior case; Helmholtz
  f = @(x1,x2) 5i*besselh(0,k*sqrt(x1.^2 + (x2 - (2-1.5*ext)).^2));
end
   
if tauone, f = @(x1,x2) -ones(size(x1)); end      % interior val for tau=1
t = (1:N)/N*2*pi; sp = sqrt(Rp(t).^2 + R(t).^2);  % speed func
w = ones(size(t))*2*pi/N;                         % weights, peri trap quad
y = [R(t).*cos(t); R(t).*sin(t)];
% compute n_y * speed:
nysp = [0 1;-1 0]*[Rp(t).*cos(t) - R(t).*sin(t); Rp(t).*sin(t) + R(t).*cos(t)];
ypp = [-R(t).*cos(t) - 2*Rp(t).*sin(t) + Rpp(t).*cos(t); ...
       -R(t).*sin(t) + 2*Rp(t).*cos(t) + Rpp(t).*sin(t)];
ny = nysp./repmat(sp, [2 1]);           % unit vector normal n_y
kappa = -sum(ny.*ypp,1)./sp.^2;
if verb                                 % show geometry, normals
  figure; plot(y(1,:), y(2,:), 'k.'); hold on; l=0.1; axis equal;
  plot([y(1,:); y(1,:)+l*ny(1,:)], [y(2,:); y(2,:)+l*ny(2,:)],'-'); 
  figure; plot(t, kappa, '-');
end
% The next 9 lines are in lieu of a separate function for filling kernel...
y1 = repmat(y(1,:), [N 1]); y2 = repmat(y(2,:), [N 1]);
ny1 = repmat(ny(1,:), [N 1]); ny2 = repmat(ny(2,:), [N 1]);
r = sqrt((y1-y1').^2+(y2-y2').^2); r(diagind(r)) = 1; % dummy diag
costh = -(ny1.*(y1-y1') + ny2.*(y2-y2'))./r;
if k==0
  K = (1/2/pi)* costh ./ r;
else
  K = (k*1i/4)* costh .* besselh(1, k*r);
end
K(diagind(K)) = -kappa/(4*pi);
K = K * diag(w.*sp);                        % scale cols, weights and speed
if verb, figure; imagesc(t, t, real(K)); colorbar; drawnow; end
if ext, A = eye(N) + 2*K; else A = eye(N) - 2*K; end    % matrix
fprintf('N=%d, k=%g, A filled: cond # = %g\n', N, k, cond(A))
b = -2*f(y(1,:),y(2,:)).'; if ext, b = -b; end   % rhs
tau = A \ b;                                    % linear solve
if tauone, tau = ones(size(tau)); end              % use const tau

[xx1 xx2] = meshgrid(g);     % plot solution (slow)
xx = [xx1(:) xx2(:)]';
u = 0*xx1(:)'; n = numel(u);
for j=1:N           % sum density * weight * fund sol w/o prefac
  d = xx - repmat(y(:,j), [1 n]);           % array of displacements 2-by-n
  if k==0 
    u = u + tau(j) * w(j) * sum(repmat(nysp(:,j), [1 n]).*d,1) ./ sum(d.^2,1) / 2/pi;
  else
    r = sqrt(sum(d.^2,1));
    costh = sum(repmat(nysp(:,j), [1 n]).*d,1)./r; 
    u = u + tau(j) * w(j) * (k*1i/4) * costh .* besselh(1,k*r);
  end
end
u = reshape(u,size(xx1));          % make rect array

if numel(u)==1, fprintf('\tRe u = %.16g\n', real(u)); end
%end  % ----------- uncomment to end N loop

uex = f(xx1,xx2); if verb
figure; imagesc(g, g, real(uex)); caxis([-3 3]); axis equal; colormap(jet(256))
xlabel('x_1'); ylabel('x_2'); title('exact u'); colorbar;
figure; imagesc(g, g, real(u)); caxis([-3 3]); axis equal; colormap(jet(256))
xlabel('x_1'); ylabel('x_2'); title('DLP soln'); colorbar;
end
figure; imagesc(g, g, log10(abs(u-uex))); caxis([-16 0]); axis equal;
colormap(jet(256)); colorbar;
xlabel('x_1'); ylabel('x_2'); title('DLP soln: log_{10} error');
if numel(g)>1
  fprintf('err @ an interior pt = %g\n', abs((u(70,70)-uex(70,70))/uex(70,70)));
end
