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:
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-
1719xs = repmat(src(1 ,: ),ntarg ,1 );
1820ys = repmat(src(2 ,: ),ntarg ,1 );
1921
2325rx = xt - xs ;
2426ry = yt - ys ;
2527
28+
29+ rx = rx(: );
30+ ry = ry(: );
31+
32+
2633nx = fix(rx / d );
2734rx = rx - nx * d ;
2835
3441
3542r = sqrt(r2 );
3643
37- rx = rx(: );
38- ry = ry(: );
39- r = r(: );
40-
4144npt = size(r ,1 );
4245
43- ythresh = d / 2 ;
44- % ythresh = d/10;
46+ ythresh = 2 * d / 2 ;
4547iclose = abs(ry ) < ythresh ;
4648ifar = ~iclose ;
4749
5254ryclose = ry(iclose );
5355rclose = r(iclose );
5456
57+ nxclose = nx(iclose );
58+ nptclose = size(rxclose , 1 );
59+
5560nkappa = length(kappa );
5661
5762val = zeros(nkappa ,npt ,1 );
7681% beta = sqrt((xi_m.^2-zk^2));
7782beta = 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;
8084fhat = exp(-beta .* sqrt(ryfar .^ 2 ) + 1i * xi_m .* rxfar )./(2 * beta );
8185val(: ,ifar ,: ) = sum(fhat ,3 )/(d );
8286if nargout > 1
8387grad(: ,ifar ,1 ) = sum(1i * xi_m .* fhat ,3 )/d ;
8488grad(: ,ifar ,2 ) = sum(-beta .*(sqrt(ryfar .^ 2 )./ryfar ).*fhat ,3 )/d ;
85- % grad(:,ifar,:) =[gx,gy];
8689end
8790
8891if nargout > 2
8992hess(: ,ifar ,1 ) = sum(-xi_m .^ 2 .* fhat ,3 )/d ;
9093hess(: ,ifar ,2 ) = sum(-1i * xi_m .* beta .*(sqrt(ryfar .^ 2 )./ryfar ).*fhat ,3 )/d ;
9194hess(: ,ifar ,3 ) = sum((beta .*(sqrt(ryfar .^ 2 )./ryfar )).^2 .* fhat ,3 )/d ;
92- % hess(:,ifar,:) = [hxx,hxy,hyy];
9395end
9496
95-
9697end
9798
9899alpha = (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 ;
103105if ~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 );
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 ;
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
194203end
195204
196205quasi_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