Skip to content

Commit cb31b04

Browse files
committed
Merge branch 'master' of https://github.com/fastalgorithms/chunkie into chunkerkernevalmat-upsample
2 parents 7503c39 + e140385 commit cb31b04

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+3171
-410
lines changed

chunkie/+chnk/+helm1d/green.m

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
function [val,grad,hess] = green(zkE,src,targ)
2+
%CHNK.HELM1D.GREEN evaluate the 1D helmholtz green's function
3+
% for the given sources and targets
4+
5+
[~,ns] = size(src);
6+
[~,nt] = size(targ);
7+
8+
xs = repmat(src(1,:),nt,1);
9+
ys = repmat(src(2,:),nt,1);
10+
11+
xt = repmat(targ(1,:).',1,ns);
12+
yt = repmat(targ(2,:).',1,ns);
13+
14+
rx = xt-xs;
15+
ry = yt-ys;
16+
17+
rx2 = rx.*rx;
18+
ry2 = ry.*ry;
19+
20+
r2 = rx2+ry2;
21+
22+
r = sqrt(r2);
23+
24+
25+
if nargout > 0
26+
val = exp(1j*zkE*r);
27+
end
28+
29+
[m,n] = size(xs);
30+
31+
if nargout > 1
32+
grad = zeros(m,n,2);
33+
34+
grad(:,:,1) = (1/2).*(rx./r).*exp(1j*zkE*r);
35+
grad(:,:,2) = (1/2).*(ry./r).*exp(1j*zkE*r);
36+
grad = 2*1j*zkE*grad;
37+
end
38+
39+
if nargout > 2
40+
41+
hess = zeros(m,n,3);
42+
43+
r3 = r.^3;
44+
45+
hess(:,:,1) = (1./(2*r3)).*(1j*zkE*r.*rx2 - rx2 + r2).*exp(1j*zkE*r);
46+
hess(:,:,2) = (1./(2*r3)).*(1j*zkE*r.*rx.*ry - rx.*ry).*exp(1j*zkE*r);
47+
hess(:,:,3) = (1./(2*r3)).*(1j*zkE*r.*ry2 - ry2 + r2).*exp(1j*zkE*r);
48+
hess = 2*1j*zkE*hess;
49+
end

chunkie/+chnk/+helm1d/kern.m

Lines changed: 295 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,295 @@
1+
function submat= kern(zkE,srcinfo,targinfo,type,varargin)
2+
%CHNK.HELM1D.KERN standard Helmholtz layer potential kernels in 1D
3+
%
4+
% Syntax: submat = chnk.heml1d.kern(zkE,srcinfo,targingo,type,varargin)
5+
%
6+
% Let x be targets and y be sources for these formulas, with
7+
% n_x and n_y the corresponding unit normals at those points
8+
% (if defined). Note that the normal information is obtained
9+
% by taking the perpendicular to the provided tangential deriviative
10+
% info and normalizing
11+
%
12+
% Kernels based on G(x,y) = e^{iE|x-y|}
13+
%
14+
% D(x,y) = \nabla_{n_y} G(x,y)
15+
% S(x,y) = G(x,y)
16+
% S'(x,y) = \nabla_{n_x} G(x,y)
17+
% D'(x,y) = \nabla_{n_x} \nabla_{n_y} G(x,y)
18+
%
19+
% Input:
20+
% zkE - complex number, Helmholtz wave number
21+
% srcinfo - description of sources in ptinfo struct format, i.e.
22+
% ptinfo.r - positions (2,:) array
23+
% ptinfo.d - first derivative in underlying
24+
% parameterization (2,:)
25+
% ptinfo.d2 - second derivative in underlying
26+
% parameterization (2,:)
27+
% targinfo - description of targets in ptinfo struct format,
28+
% if info not relevant (d/d2) it doesn't need to
29+
% be provided. sprime requires tangent info in
30+
% targinfo.d
31+
% type - string, determines kernel type
32+
% type == 'd', double layer kernel D
33+
% type == 's', single layer kernel S
34+
% type == 'sprime', normal derivative of single
35+
% layer S'
36+
% type == 'dprime', normal derivative of double layer D'
37+
% type == 'c', combined layer kernel coef(1) D + coef(2) S
38+
% type == 'stau', tangential derivative of single layer
39+
% type == 'all', returns all four layer potentials,
40+
% [coef(1,1)*D coef(1,2)*S; coef(2,1)*D' coef(2,2)*S']
41+
% type == 'c2trans' returns the combined field, and the
42+
% normal derivative of the combined field
43+
% [coef(1)*D + coef(2)*S; coef(1)*D' + coef(2)*S']
44+
% type == 'trans_rep' returns the potential corresponding
45+
% to the transmission representation
46+
% [coef(1)*D coef(2)*S]
47+
% type == 'trans_rep_prime' returns the normal derivative
48+
% corresponding to the transmission representation
49+
% [coef(1)*D' coef(2)*S']
50+
% type == 'trans_rep_grad' returns the gradient corresponding
51+
% to the transmission representation
52+
% [coef(1)*d_x D coef(2)*d_x S;
53+
% coef(1)*d_y D coef(2)*d_y S]
54+
%
55+
% varargin{1} - coef: length 2 array in the combined layer
56+
% formula, 2x2 matrix for all kernels
57+
% otherwise does nothing
58+
%
59+
% Output:
60+
% submat - the evaluation of the selected kernel for the
61+
% provided sources and targets. the number of
62+
% rows equals the number of targets and the
63+
% number of columns equals the number of sources
64+
%
65+
% see also CHNK.HELM1D.GREEN
66+
67+
src = srcinfo.r;
68+
targ = targinfo.r;
69+
70+
[~,ns] = size(src);
71+
[~,nt] = size(targ);
72+
73+
% double layer
74+
if strcmpi(type,'d')
75+
srcnorm = srcinfo.n;
76+
[~,grad] = chnk.helm1d.green(zkE,src,targ);
77+
nx = repmat(srcnorm(1,:),nt,1);
78+
ny = repmat(srcnorm(2,:),nt,1);
79+
submat = -(grad(:,:,1).*nx + grad(:,:,2).*ny);
80+
end
81+
82+
% normal derivative of single layer
83+
if strcmpi(type,'sprime')
84+
targnorm = targinfo.n;
85+
[~,grad] = chnk.helm1d.green(zkE,src,targ);
86+
nx = repmat((targnorm(1,:)).',1,ns);
87+
ny = repmat((targnorm(2,:)).',1,ns);
88+
89+
submat = (grad(:,:,1).*nx + grad(:,:,2).*ny);
90+
end
91+
92+
93+
% Tangential derivative of single layer
94+
if strcmpi(type,'stau')
95+
targtan = targinfo.d;
96+
[~,grad] = chnk.helm1d.green(zkE,src,targ);
97+
dx = repmat((targtan(1,:)).',1,ns);
98+
dy = repmat((targtan(2,:)).',1,ns);
99+
ds = sqrt(dx.*dx+dy.*dy);
100+
submat = (grad(:,:,1).*dx + grad(:,:,2).*dy)./ds;
101+
end
102+
103+
% single layer
104+
if strcmpi(type,'s')
105+
submat = chnk.helm1d.green(zkE,src,targ);
106+
end
107+
108+
% normal derivative of double layer
109+
if strcmpi(type,'dprime')
110+
targnorm = targinfo.n;
111+
srcnorm = srcinfo.n;
112+
[~,~,hess] = chnk.helm1d.green(zkE,src,targ);
113+
nxsrc = repmat(srcnorm(1,:),nt,1);
114+
nysrc = repmat(srcnorm(2,:),nt,1);
115+
nxtarg = repmat((targnorm(1,:)).',1,ns);
116+
nytarg = repmat((targnorm(2,:)).',1,ns);
117+
submat = -(hess(:,:,1).*nxsrc.*nxtarg + hess(:,:,2).*(nysrc.*nxtarg+nxsrc.*nytarg)...
118+
+ hess(:,:,3).*nysrc.*nytarg);
119+
end
120+
121+
% Combined field
122+
if strcmpi(type,'c')
123+
srcnorm = srcinfo.n;
124+
coef = ones(2,1);
125+
if(nargin == 5); coef = varargin{1}; end
126+
[submats,grad] = chnk.helm1d.green(zkE,src,targ);
127+
nx = repmat(srcnorm(1,:),nt,1);
128+
ny = repmat(srcnorm(2,:),nt,1);
129+
submatd = -(grad(:,:,1).*nx + grad(:,:,2).*ny);
130+
submat = coef(1)*submatd + coef(2)*submats;
131+
end
132+
133+
% normal derivative of combined field
134+
if strcmpi(type,'cprime')
135+
coef = ones(2,1);
136+
if(nargin == 5); coef = varargin{1}; end
137+
targnorm = targinfo.n;
138+
srcnorm = srcinfo.n;
139+
140+
141+
142+
% Get gradient and hessian info
143+
[~,grad,hess] = chnk.helm1d.green(zkE,src,targ);
144+
145+
nxsrc = repmat(srcnorm(1,:),nt,1);
146+
nysrc = repmat(srcnorm(2,:),nt,1);
147+
nxtarg = repmat((targnorm(1,:)).',1,ns);
148+
nytarg = repmat((targnorm(2,:)).',1,ns);
149+
150+
% D'
151+
submatdp = -(hess(:,:,1).*nxsrc.*nxtarg ...
152+
+ hess(:,:,2).*(nysrc.*nxtarg+nxsrc.*nytarg)...
153+
+ hess(:,:,3).*nysrc.*nytarg);
154+
% S'
155+
submatsp = (grad(:,:,1).*nxtarg + grad(:,:,2).*nytarg);
156+
157+
submat = coef(1)*submatdp + coef(2)*submatsp;
158+
end
159+
160+
161+
% Dirichlet and neumann data corresponding to combined field
162+
if strcmpi(type,'c2trans')
163+
coef = ones(2,1);
164+
if(nargin == 5); coef = varargin{1}; end
165+
targnorm = targinfo.n;
166+
srcnorm = srcinfo.n;
167+
168+
% Get gradient and hessian info
169+
[submats,grad,hess] = chnk.helm1d.green(zkE,src,targ);
170+
171+
nxsrc = repmat(srcnorm(1,:),nt,1);
172+
nysrc = repmat(srcnorm(2,:),nt,1);
173+
nxtarg = repmat((targnorm(1,:)).',1,ns);
174+
nytarg = repmat((targnorm(2,:)).',1,ns);
175+
176+
% D'
177+
submatdp = -(hess(:,:,1).*nxsrc.*nxtarg ...
178+
+ hess(:,:,2).*(nysrc.*nxtarg+nxsrc.*nytarg)...
179+
+ hess(:,:,3).*nysrc.*nytarg);
180+
% S'
181+
submatsp = (grad(:,:,1).*nxtarg + grad(:,:,2).*nytarg);
182+
% D
183+
submatd = -(grad(:,:,1).*nxsrc + grad(:,:,2).*nysrc);
184+
185+
submat = zeros(2*nt,ns);
186+
187+
submat(1:2:2*nt,:) = coef(1)*submatd + coef(2)*submats;
188+
submat(2:2:2*nt,:) = coef(1)*submatdp + coef(2)*submatsp;
189+
190+
end
191+
192+
193+
% all kernels, [c11 D, c12 S; c21 D', c22 S']
194+
if strcmpi(type,'all')
195+
196+
targnorm = targinfo.n;
197+
srcnorm = srcinfo.n;
198+
cc = varargin{1};
199+
200+
submat = zeros(2*nt,2*ns);
201+
202+
% Get gradient and hessian info
203+
[submats,grad,hess] = chnk.helm1d.green(zkE,src,targ);
204+
205+
nxsrc = repmat(srcnorm(1,:),nt,1);
206+
nysrc = repmat(srcnorm(2,:),nt,1);
207+
nxtarg = repmat((targnorm(1,:)).',1,ns);
208+
nytarg = repmat((targnorm(2,:)).',1,ns);
209+
210+
submatdp = -(hess(:,:,1).*nxsrc.*nxtarg ...
211+
+ hess(:,:,2).*(nysrc.*nxtarg+nxsrc.*nytarg)...
212+
+ hess(:,:,3).*nysrc.*nytarg);
213+
% S'
214+
submatsp = (grad(:,:,1).*nxtarg + grad(:,:,2).*nytarg);
215+
% D
216+
submatd = -(grad(:,:,1).*nxsrc + grad(:,:,2).*nysrc);
217+
218+
219+
submat(1:2:2*nt,1:2:2*ns) = submatd*cc(1,1);
220+
submat(1:2:2*nt,2:2:2*ns) = submats*cc(1,2);
221+
submat(2:2:2*nt,1:2:2*ns) = submatdp*cc(2,1);
222+
submat(2:2:2*nt,2:2:2*ns) = submatsp*cc(2,2);
223+
end
224+
225+
% Dirichlet data/potential correpsonding to transmission rep
226+
if strcmpi(type,'trans_rep')
227+
228+
coef = ones(2,1);
229+
if(nargin == 5); coef = varargin{1}; end;
230+
srcnorm = srcinfo.n;
231+
[submats,grad] = chnk.helm1d.green(zkE,src,targ);
232+
nx = repmat(srcnorm(1,:),nt,1);
233+
ny = repmat(srcnorm(2,:),nt,1);
234+
submatd = -(grad(:,:,1).*nx + grad(:,:,2).*ny);
235+
236+
submat = zeros(1*nt,2*ns);
237+
submat(1:1:1*nt,1:2:2*ns) = coef(1)*submatd;
238+
submat(1:1:1*nt,2:2:2*ns) = coef(2)*submats;
239+
end
240+
241+
% Neumann data corresponding to transmission rep
242+
if strcmpi(type,'trans_rep_prime')
243+
coef = ones(2,1);
244+
if(nargin == 5); coef = varargin{1}; end;
245+
targnorm = targinfo.n;
246+
srcnorm = srcinfo.n;
247+
248+
submat = zeros(nt,ns);
249+
250+
% Get gradient and hessian info
251+
[submats,grad,hess] = chnk.helm1d.green(zkE,src,targ);
252+
253+
nxsrc = repmat(srcnorm(1,:),nt,1);
254+
nysrc = repmat(srcnorm(2,:),nt,1);
255+
nxtarg = repmat((targnorm(1,:)).',1,ns);
256+
nytarg = repmat((targnorm(2,:)).',1,ns);
257+
258+
% D'
259+
submatdp = -(hess(:,:,1).*nxsrc.*nxtarg ...
260+
+ hess(:,:,2).*(nysrc.*nxtarg+nxsrc.*nytarg)...
261+
+ hess(:,:,3).*nysrc.*nytarg);
262+
% S'
263+
submatsp = (grad(:,:,1).*nxtarg + grad(:,:,2).*nytarg);
264+
submat = zeros(nt,2*ns)
265+
submat(1:1:1*nt,1:2:2*ns) = coef(1)*submatdp;
266+
submat(1:1:1*nt,2:2:2*ns) = coef(2)*submatsp;
267+
end
268+
269+
270+
% Gradient correpsonding to transmission rep
271+
if strcmpi(type,'trans_rep_grad')
272+
coef = ones(2,1);
273+
if(nargin == 5); coef = varargin{1}; end;
274+
275+
srcnorm = srcinfo.n;
276+
277+
submat = zeros(nt,ns,6);
278+
% S
279+
[submats,grad,hess] = chnk.helm1d.green(zkE,src,targ);
280+
281+
nxsrc = repmat(srcnorm(1,:),nt,1);
282+
nysrc = repmat(srcnorm(2,:),nt,1);
283+
% D
284+
submatd = -(grad(:,:,1).*nxsrc + grad(:,:,2).*nysrc);
285+
286+
submat = zeros(2*nt,2*ns);
287+
288+
submat(1:2:2*nt,1:2:2*ns) = -coef(1)*(hess(:,:,1).*nxsrc + hess(:,:,2).*nysrc);
289+
submat(1:2:2*nt,2:2:2*ns) = coef(2)*grad(:,:,1);
290+
291+
submat(2:2:2*nt,1:2:2*ns) = -coef(1)*(hess(:,:,2).*nxsrc + hess(:,:,3).*nysrc);
292+
submat(2:2:2*nt,2:2:2*ns) = coef(2)*grad(:,:,2);
293+
end
294+
295+

chunkie/+chnk/+helm1d/sweep.m

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
function pot = sweep(uin,inds,ts,wts,zkE)
2+
%sweeping algorithm for preconditioner
3+
4+
vexpsp = exp(1i*diff(ts)*zkE);
5+
6+
u = zeros([numel(wts),1]);
7+
u(inds) = uin;
8+
9+
nt = numel(u);
10+
chrg = u.*(wts);
11+
12+
voutp = zeros([nt,1]);
13+
voutp(1) = chrg(1);
14+
15+
for i=2:nt
16+
voutp(i) = vexpsp(i-1)*voutp(i-1)+chrg(i);
17+
end
18+
19+
voutm = zeros([nt,1]);
20+
chrg = flipud(chrg);
21+
vexpsp= flipud(vexpsp);
22+
23+
for i=2:nt
24+
voutm(i) = vexpsp(i-1)*(voutm(i-1)+chrg(i-1));
25+
end
26+
27+
pot = voutp + flipud(voutm);
28+
end

chunkie/+chnk/+helm2d/fmm.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
%
4747
% Optional Output:
4848
% pot - potential/neumann data corresponding to the kernel at the target locations
49-
% grad - gradient at target locations
49+
% grad - gradient at target locations
5050
% hess - hessian at target locations
5151

5252
if ( nargout == 0 )

0 commit comments

Comments
 (0)