Skip to content

Commit d0f8ee3

Browse files
authored
Merge pull request #143 from fastalgorithms/quasi_periodic_shapes
Update shape of vector valued quasiperiodic kernels
2 parents 6a46b90 + 0e5ec8c commit d0f8ee3

File tree

11 files changed

+472
-177
lines changed

11 files changed

+472
-177
lines changed

chunkie/+chnk/+helm2d/kern.m

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
% [coef(1,1)*D coef(1,2)*S; coef(2,1)*D' coef(2,2)*S']
4141
% type == 'c2trans' returns the combined field, and the
4242
% normal derivative of the combined field
43-
% [coef(1)*D + coef(2)*S; coef(1)*D' + coef(2)*S']
43+
% [coef(1,1)*D + coef(1,2)*S; coef(2,1)*D' + coef(2,2)*S']
4444
% type == 'trans_rep' returns the potential corresponding
4545
% to the transmission representation
4646
% [coef(1)*D coef(2)*S]
@@ -274,6 +274,7 @@
274274
case {'c2trans', 'c2t', 'c2tr'}
275275
coef = ones(2,1);
276276
if(nargin == 5); coef = varargin{1}; end
277+
if numel(coef) == 2, coef = repmat(coef(:).',2,1); end
277278
targnorm = targinfo.n(:,:);
278279
srcnorm = srcinfo.n(:,:);
279280

@@ -296,8 +297,8 @@
296297

297298
submat = zeros(2*nt,ns);
298299

299-
submat(1:2:2*nt,:) = coef(1)*submatd + coef(2)*submats;
300-
submat(2:2:2*nt,:) = coef(1)*submatdp + coef(2)*submatsp;
300+
submat(1:2:2*nt,:) = coef(1,1)*submatd + coef(1,2)*submats;
301+
submat(2:2:2*nt,:) = coef(2,1)*submatdp + coef(2,2)*submatsp;
301302

302303

303304
% Dirichlet and Neumann data corresponding to combined field (difference)

chunkie/+chnk/+helm2dquas/green.m

Lines changed: 101 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
function [val,grad,hess] = green(src,targ,zk,kappa,d,sn,l)
2-
%CHNK.HELM2DQUAS.GREEN evaluate the quasiperiodic helmholtz green's function
1+
function [val,grad,hess] = green(src,targ,zk,kappa,d,sn,l,ising)
2+
%CHNK.HELM2DQUAS.GREEN evaluate the quasiperiodic Helmholtz Green's function
33
% for the given sources and targets
44
%
55
% Input:
@@ -8,12 +8,14 @@
88
% d - period
99
% sn - precomputed lattice sum integrals
1010
% (see chnk.helm2dquas.latticecoefs)
11+
% l - number of periodic copies computed explicitly
12+
% ising - if set to 0, only include the periodic copies. If set to 1,
13+
% include the free-space part
1114
%
1215
% see also CHNK.HELM2DQUAS.KERN
1316
[~,nsrc] = size(src);
1417
[~,ntarg] = size(targ);
1518

16-
1719
xs = repmat(src(1,:),ntarg,1);
1820
ys = repmat(src(2,:),ntarg,1);
1921

@@ -23,6 +25,11 @@
2325
rx = xt-xs;
2426
ry = yt-ys;
2527

28+
29+
rx = rx(:);
30+
ry = ry(:);
31+
32+
2633
nx = fix(rx/d);
2734
rx = rx - nx*d;
2835

@@ -34,14 +41,9 @@
3441

3542
r = sqrt(r2);
3643

37-
rx = rx(:);
38-
ry = ry(:);
39-
r = r(:);
40-
4144
npt = size(r,1);
4245

43-
ythresh = d/2;
44-
% ythresh = d/10;
46+
ythresh = 2*d/2;
4547
iclose = abs(ry) < ythresh;
4648
ifar = ~iclose;
4749

@@ -52,6 +54,9 @@
5254
ryclose = ry(iclose);
5355
rclose = r(iclose);
5456

57+
nxclose = nx(iclose);
58+
nptclose = size(rxclose, 1);
59+
5560
nkappa = length(kappa);
5661

5762
val = zeros(nkappa,npt,1);
@@ -76,55 +81,57 @@
7681
% beta = sqrt((xi_m.^2-zk^2));
7782
beta = sqrt(1i*(xi_m-zk)).*sqrt(-1i*(xi_m+zk));
7883

79-
% fhat = exp(-beta.*sqrt(ryfar.^2))./beta.*exp(1i*xi_m.*rxfar)/2;
8084
fhat = exp(-beta.*sqrt(ryfar.^2) + 1i*xi_m.*rxfar)./(2*beta);
8185
val(:,ifar,:) = sum(fhat,3)/(d);
8286
if nargout > 1
8387
grad(:,ifar,1) = sum(1i*xi_m.*fhat,3)/d;
8488
grad(:,ifar,2) = sum(-beta.*(sqrt(ryfar.^2)./ryfar).*fhat,3)/d;
85-
% grad(:,ifar,:) =[gx,gy];
8689
end
8790

8891
if nargout >2
8992
hess(:,ifar,1) = sum(-xi_m.^2.*fhat,3)/d;
9093
hess(:,ifar,2) = sum(-1i*xi_m.*beta.*(sqrt(ryfar.^2)./ryfar).*fhat,3)/d;
9194
hess(:,ifar,3) = sum((beta.*(sqrt(ryfar.^2)./ryfar)).^2.*fhat,3)/d;
92-
% hess(:,ifar,:) = [hxx,hxy,hyy];
9395
end
9496

95-
9697
end
9798

9899
alpha = (exp(1i*kappa(:)*d));
99100

100-
val_near=0;
101-
grad_near = zeros(1,1,2);
102-
hess_near = zeros(1,1,3);
101+
val_near= zeros(nkappa,nptclose);
102+
grad_near = zeros(nkappa,nptclose,2);
103+
hess_near = zeros(nkappa,nptclose,3);
104+
ls = -l:l;
103105
if ~isempty(rxclose)
104-
for i = -l:l
106+
for i = ls
107+
if ising == 1
108+
iuse = true(nptclose,1);
109+
else
110+
iuse = nxclose ~= -i;
111+
end
112+
105113
rxi = rxclose - i*d;
106114
if nargout>2
107115
[vali,gradi,hessi] = chnk.helm2d.green(zk,[0;0],[rxi.';ryclose.']);
108116
vali = reshape(vali,1,[],1);
109117
gradi = reshape(gradi,1,[],2);
110118
hessi = reshape(hessi,1,[],3);
111-
val_near = val_near + vali.*alpha.^i;
112-
grad_near = grad_near + gradi.*alpha.^i;
113-
hess_near = hess_near + hessi.*alpha.^i;
119+
val_near(:,iuse) = val_near(:,iuse) + vali(:,iuse).*alpha.^i;
120+
grad_near(:,iuse,:) = grad_near(:,iuse,:) + gradi(:,iuse,:).*alpha.^i;
121+
hess_near(:,iuse,:) = hess_near(:,iuse,:) + hessi(:,iuse,:).*alpha.^i;
114122
elseif nargout > 1
115123
[vali,gradi] = chnk.helm2d.green(zk,[0;0],[rxi.';ryclose.']);
116124
vali = reshape(vali,1,[],1);
117125
gradi = reshape(gradi,1,[],2);
118-
val_near = val_near + vali.*alpha.^i;
119-
grad_near = grad_near + gradi.*alpha.^i;
126+
val_near(:,iuse) = val_near(:,iuse) + vali(:,iuse).*alpha.^i;
127+
grad_near(:,iuse,:) = grad_near(:,iuse,:) + gradi(:,iuse,:).*alpha.^i;
120128
else
121129
vali = chnk.helm2d.green(zk,[0;0],[rxi.';ryclose.']);
122130
vali = reshape(vali,1,[],1);
123-
val_near = val_near + vali.*alpha.^i;
131+
val_near(:,iuse) = val_near(:,iuse) + vali(:,iuse).*alpha.^i;
124132
end
125133
end
126-
127-
% sn = sn.';
134+
128135
N = size(sn,2)-1;
129136
ns = (0:N);
130137
ns_use = (0:N+2);
@@ -139,25 +146,26 @@
139146
Js(:,i) = besselj(ns_use(i),zk*rclose);
140147
end
141148
end
149+
% t1 = tic;
142150
eip = (rxclose+1i*ryclose)./rclose;
143151
eipn = reshape(eip.^ns,1,[], N+1);
144152
cs = (eipn+1./eipn)/2;
145153

146154
Js = reshape(Js,1,[],N+3);
147155
sn = reshape(sn,nkappa, 1, N+1);
148156

149-
val_far = 0.25*1i*Js(:,:,1).*sn(:,:,1) + 0.5*1i*sum(sn(:,:,2:end).*Js(:,:,2:end-2).*cs(:,:,2:end),3);
157+
tmp = reshape(Js(:,:,2:end-2).*cs(:,:,2:end),[],N);
158+
val_far = 0.25*1i*Js(:,:,1).*sn(:,:,1) + 0.5*1i*sn(:,2:end)*tmp.';
150159
val(:,iclose) = val_near+val_far;
151160

152-
153-
154-
155161
if nargout >1
156162
DJs = cat(3,-Js(:,:,2),.5*(Js(:,:,1:end-3)-Js(:,:,3:end-1)))*zk;
157163
ss = (eipn-1./eipn)/2i;
158164

159-
grad_far_p = 0.25*1i*DJs(:,:,1).*sn(:,:,1) + 0.5*1i*sum(sn(:,:,2:end).*DJs(:,:,2:end).*cs(:,:,2:end),3);
160-
grad_far_t = (0.5*1i*sum(-reshape((1:N),1,1,[]).*sn(:,:,2:end).*Js(:,:,2:end-2).*ss(:,:,2:end),3))./rclose.';
165+
tmp = reshape(DJs(:,:,2:end).*cs(:,:,2:end),[],N);
166+
grad_far_p = 0.25*1i*DJs(:,:,1).*sn(:,:,1) + 0.5*1i*sn(:,2:end)*tmp.';
167+
tmp = reshape(Js(:,:,2:end-2).*ss(:,:,2:end),[],N)./rclose;
168+
grad_far_t = (0.5*1i*((-reshape((1:N),1,[]).*sn(:,2:end))*tmp.'));
161169

162170
grad_far = cat(3,cs(:,:,2).*grad_far_p - ss(:,:,2).*grad_far_t, ss(:,:,2).*grad_far_p + cs(:,:,2).*grad_far_t);
163171
grad(:,iclose,:) = grad_near + grad_far;
@@ -172,37 +180,85 @@
172180
tmp_n = rclose.^(-4).*(-ns.*ryclose.*Js(:,:,1:end-2).*(ns.*ryclose.*cs+2*rxclose.*ss)+ ...
173181
rclose.*ryclose.*(ryclose.*cs + 2*ns.*rxclose.*ss).*DJs+ ...
174182
rclose.^2.*rxclose.^2.*cs.*DDJs);
175-
hess_far_xx = 0.25*1i*tmp_n(:,:,1).*sn(:,:,1)+.5*1i*sum(sn(:,:,2:end).*tmp_n(:,:,2:end),3);
183+
tmp_n = reshape(tmp_n,[],N+1);
184+
hess_far_xx = 0.25*1i*tmp_n(:,1).'.*sn(:,1)+.5*1i*sn(:,2:end)*tmp_n(:,2:end).';
176185

177186
tmp_n = ns.*Js(:,:,1:end-2).*(ns.*rxclose.*ryclose.*cs+(rxclose.^2-ryclose.^2).*ss).*rclose.^(-4) ...
178187
+rclose.^(-3).*(-(rxclose.*ryclose.*cs+ns.*(rxclose.^2-ryclose.^2).*ss).*DJs+...
179188
rclose.*rxclose.*ryclose.*cs.*DDJs);
180189

181-
182-
hess_far_xy = 0.25*1i*tmp_n(:,:,1).*sn(:,:,1)+.5*1i*sum(sn(:,:,2:end).*tmp_n(:,:,2:end),3);
190+
tmp_n = reshape(tmp_n,[],N+1);
191+
hess_far_xy = 0.25*1i*tmp_n(:,1).'.*sn(:,1)+.5*1i*sn(:,2:end)*tmp_n(:,2:end).';
183192

184193
tmp_n = rclose.^(-4).*(-ns.*rxclose.*Js(:,:,1:end-2).*(ns.*rxclose.*cs-2*ryclose.*ss)+ ...
185194
rclose.*rxclose.*(rxclose.*cs - 2*ns.*ryclose.*ss).*DJs+ ...
186195
rclose.^2.*ryclose.^2.*cs.*DDJs);
187-
hess_far_yy = 0.25*1i*tmp_n(:,:,1).*sn(:,:,1)+.5*1i*sum(sn(:,:,2:end).*tmp_n(:,:,2:end),3);
196+
tmp_n = reshape(tmp_n,[],N+1);
197+
hess_far_yy = 0.25*1i*tmp_n(:,1).'.*sn(:,1)+.5*1i*sn(:,2:end)*tmp_n(:,2:end).';
188198

189199
hess_far = cat(3,hess_far_xx, hess_far_xy, hess_far_yy);
190200

191-
192201
hess(:,iclose,:) = hess_near + hess_far;
193202
end
194203
end
195204

196205
quasi_phase = exp(1i*kappa(:)*nx(:).'*d);
197206

198-
val = reshape(quasi_phase.*val,nkappa*ntarg,nsrc);
199-
if nargout>1
200-
grad = reshape(quasi_phase.*grad,nkappa*ntarg,nsrc,2);
201-
end
202-
if nargout>2
203-
hess = reshape(quasi_phase.*hess,nkappa*ntarg,nsrc,3);
204-
end
205-
% end
206207

207-
end
208+
if nargout == 1
209+
val = quasi_phase.*val;
210+
211+
if ising == 0
212+
isub = (abs(nx(:)) > max(ls)) | ifar;
213+
214+
if any(isub)
215+
vali = chnk.helm2d.green(zk,[0;0],[rx(isub).'+ nx(isub).'*d;ry(isub).']);
216+
vali = reshape(vali,1,[],1);
217+
val(:,isub,:) = val(:,isub,:) - vali;
218+
end
219+
end
208220

221+
val = reshape(val,nkappa*ntarg,nsrc);
222+
elseif nargout == 2
223+
val = quasi_phase.*val;
224+
grad = quasi_phase.*grad;
225+
226+
if ising == 0
227+
isub = (abs(nx(:)) > max(ls)) | ifar;
228+
229+
if any(isub)
230+
[vali, gradi] = chnk.helm2d.green(zk,[0;0],[rx(isub).' + nx(isub).'*d;ry(isub).']);
231+
vali = reshape(vali,1,[],1);
232+
gradi = reshape(gradi,1,[],2);
233+
val(:,isub,:) = val(:,isub,:) - vali;
234+
grad(:,isub,:) = grad(:,isub,:) - gradi;
235+
end
236+
end
237+
238+
val = reshape(val,nkappa*ntarg,nsrc);
239+
grad = reshape(grad,nkappa*ntarg,nsrc,2);
240+
elseif nargout == 3
241+
val = quasi_phase.*val;
242+
grad = quasi_phase.*grad;
243+
hess = quasi_phase.*hess;
244+
245+
if ising == 0
246+
isub = (abs(nx(:)) > max(ls)) | ifar;
247+
248+
if any(isub)
249+
[vali, gradi, hessi] = chnk.helm2d.green(zk,[0;0],[rx(isub).' + nx(isub).'*d;ry(isub).']);
250+
vali = reshape(vali,1,[],1);
251+
gradi = reshape(gradi,1,[],2);
252+
hessi = reshape(hessi,1,[],3);
253+
254+
val(:,isub,:) = val(:,isub,:) - vali;
255+
grad(:,isub,:) = grad(:,isub,:) - gradi;
256+
hess(:,isub,:) = hess(:,isub,:) - hessi;
257+
end
258+
end
259+
260+
val = reshape(val,nkappa*ntarg,nsrc);
261+
grad = reshape(grad,nkappa*ntarg,nsrc,2);
262+
hess = reshape(hess,nkappa*ntarg,nsrc,3);
263+
end
264+
end

0 commit comments

Comments
 (0)