Skip to content

Commit b9f0590

Browse files
committed
axisymmetric laplace kernels
1 parent a395c7b commit b9f0590

File tree

15 files changed

+931
-0
lines changed

15 files changed

+931
-0
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
function [rk0,re0] = gaus_agm(x)
2+
3+
eps = 1E-15;
4+
a = sqrt(2./(x+1));
5+
delt = 1./sqrt(1-a.*a);
6+
aa0 = delt + sqrt(delt.*delt-1);
7+
bb0 = 1./(delt+sqrt(delt.*delt-1));
8+
a0 = ones(size(delt));
9+
b0 = 1./delt;
10+
11+
12+
fact = ((a0+b0)/2).^2;
13+
14+
for i=1:1000
15+
a1 = (a0+b0)/2;
16+
b1 = sqrt(a0.*b0);
17+
18+
aa1 = (aa0+bb0)/2;
19+
bb1 = sqrt(aa0.*bb0);
20+
a0 = a1;
21+
b0 = b1;
22+
aa0 = aa1;
23+
bb0 = bb1;
24+
25+
c0 = (a1-b1)/2;
26+
fact = fact-(c0.*c0)*2^(i);
27+
drel = abs(a0-b0)./abs(a0);
28+
drel2= abs(aa0-bb0)./abs(aa0);
29+
if (max(drel+drel2) <2*eps)
30+
break
31+
end
32+
33+
end
34+
35+
rk0 = pi./(2*aa0.*sqrt(1-a.*a));
36+
re0 = pi*fact./(2*a0);
37+
38+
end
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
function [gval,gdz,gdr,gdrp] = gfunc(r,rp,dr,z,zp,dz)
2+
domega3 = 2*pi;
3+
n = 3;
4+
5+
t = (dz.^2+dr.^2)./(2.*r.*rp);
6+
[q0,q1,q0d] = chnk.axissymlap2d.qleg_half(t);
7+
8+
gval = domega3*(rp./r).^((n-2)/2).*q0;
9+
gdz =-domega3*(rp./r).^((n-2)/2).*q0d ...
10+
./(rp.*r).*dz;
11+
12+
rfac = -r*(n-2)/2.*q0+(-(1+t).*r+rp).*q0d;
13+
gdrp = -domega3*(rp./r).^((n-2)/2)./(rp.*r) ...
14+
.*rfac;
15+
rfac = -rp*(n-2)/2.*q0+(-(1+t).*rp+r).*q0d;
16+
gdr = -domega3*(rp./r).^((n-2)/2)./(rp.*r) ...
17+
.*rfac;
18+
end
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
function [gval,gdz,gdr,gdrp] = gfunc_on_axis(r,rp,dr,z,zp,dz)
2+
domega3 = 2*pi;
3+
n = 3;
4+
5+
t = (dz.^2+dr.^2)./(2.*r.*rp);
6+
[q0,q1,q0d] = chnk.axissymlap2d.qleg_half(t);
7+
8+
gval = domega3*(rp./r).^((n-2)/2).*q0;
9+
gdz =-domega3*(rp./r).^((n-2)/2).*q0d ...
10+
./(rp.*r).*dz;
11+
12+
rfac = -r*(n-2)/2.*q0+(-(1+t).*r+rp).*q0d;
13+
gdrp = -domega3*(rp./r).^((n-2)/2)./(rp.*r) ...
14+
.*rfac;
15+
rfac = -rp*(n-2)/2.*q0+(-(1+t).*rp+r).*q0d;
16+
gdr = -domega3*(rp./r).^((n-2)/2)./(rp.*r) ...
17+
.*rfac;
18+
end
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
function [val, grad] = green(src, targ, origin)
2+
%CHNK.AXISSYMHELM2D.GREEN evaluate the Laplace green's function
3+
% for the given sources and targets.
4+
%
5+
% Note: that the first coordinate is r, and the second z.
6+
% The code relies on precomputed tables and hence loops are required for
7+
% computing various pairwise interactions.
8+
% Finally, the code is not efficient in the sense that val, grad, hess
9+
% are always internally computed independent of nargout
10+
%
11+
% Since the kernels are not translationally invariant in r, the size
12+
% of the gradient is 3, for d/dr, d/dr', and d/dz
13+
%
14+
15+
[~, ns] = size(src);
16+
[~, nt] = size(targ);
17+
18+
gtmp = zeros(nt, ns, 3);
19+
20+
rt = repmat(targ(1,:).',1,ns);
21+
rs = repmat(src(1,:),nt,1);
22+
dz = repmat(src(2,:),nt,1)-repmat(targ(2,:).',1,ns);
23+
r = (rt + origin(1));
24+
rp = (rs + origin(1));
25+
dr = (rs-rt);
26+
z = zeros(size(rt));
27+
zp = zeros(size(rt));
28+
[g,gdz,gdr,gdrp] = chnk.axissymlap2d.gfunc(r,rp,dr,z,zp,dz);
29+
30+
val = g;
31+
gtmp(:,:,1) = gdr;
32+
gtmp(:,:,2) = gdrp;
33+
gtmp(:,:,3) = gdz;
34+
grad = gtmp;
35+
36+

chunkie/+chnk/+axissymlap2d/kern.m

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
function submat = kern(srcinfo, targinfo, origin, type)
2+
%CHNK.AXISSYMLAP2D.KERN axissymmetric Laplace layer potential kernels in 2D
3+
%
4+
% Syntax: submat = chnk.axissymlap2d.kern(srcinfo,targingo,type)
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+
% Here the first and second components correspond to the r and z
13+
% coordinates respectively.
14+
%
15+
% Kernels based on G(x,y) = \int_{0}^{\pi} 1/(d(t)) \, dt \,
16+
% where d(t) = \sqrt(r^2 + r'^2 - 2rr' \cos(t) + (z-z')^2) with
17+
% x = (r,z), and y = (r',z')
18+
%
19+
% D(x,y) = \nabla_{n_y} G(x,y)
20+
% S(x,y) = G(x,y)
21+
% S'(x,y) = \nabla_{n_x} G(x,y)
22+
% D'(x,y) = \nabla_{n_x} \nabla_{n_y} G(x,y)
23+
%
24+
% Input:
25+
% srcinfo - description of sources in ptinfo struct format, i.e.
26+
% ptinfo.r - positions (2,:) array
27+
% ptinfo.d - first derivative in underlying
28+
% parameterization (2,:)
29+
% ptinfo.d2 - second derivative in underlying
30+
% parameterization (2,:)
31+
% targinfo - description of targets in ptinfo struct format,
32+
% if info not relevant (d/d2) it doesn't need to
33+
% be provided. sprime requires tangent info in
34+
% targinfo.d
35+
% type - string, determines kernel type
36+
% type == 'd', double layer kernel D
37+
% type == 's', single layer kernel S
38+
% type == 'sprime', normal derivative of single
39+
% layer S'
40+
%
41+
%
42+
% Output:
43+
% submat - the evaluation of the selected kernel for the
44+
% provided sources and targets. the number of
45+
% rows equals the number of targets and the
46+
% number of columns equals the number of sources
47+
%
48+
%
49+
50+
src = srcinfo.r;
51+
targ = targinfo.r;
52+
53+
[~, ns] = size(src);
54+
[~, nt] = size(targ);
55+
56+
if strcmpi(type, 'd')
57+
srcnorm = srcinfo.n;
58+
[~, grad] = chnk.axissymlap2d.green(src, targ, origin);
59+
nx = repmat(srcnorm(1,:), nt, 1);
60+
ny = repmat(srcnorm(2,:), nt, 1);
61+
% Due to lack of translation invariance in r, no sign flip needed,
62+
% as gradient is computed with repsect to r'
63+
submat = (grad(:,:,2).*nx + grad(:,:,3).*ny);
64+
end
65+
66+
if strcmpi(type, 'sprime')
67+
targnorm = targinfo.n;
68+
[~, grad] = chnk.axissymlap2d.green(src, targ, origin);
69+
70+
nx = repmat((targnorm(1,:)).',1,ns);
71+
ny = repmat((targnorm(2,:)).',1,ns);
72+
submat = (grad(:,:,1).*nx - grad(:,:,3).*ny);
73+
74+
end
75+
76+
if strcmpi(type, 's')
77+
submat = chnk.axissymlap2d.green(src, targ, origin);
78+
79+
end
80+
81+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
function [q0] = qeval0_far(x)
2+
3+
coefs = ...
4+
[2.2214414690791831235E0,
5+
0,
6+
0.41652027545234683566E0,
7+
0,
8+
0.22778452563800217575E0,
9+
0,
10+
0.15660186137612649583E0,
11+
0,
12+
0.11928657409509635424E0];
13+
14+
15+
t = 1./x;
16+
t0 = 1./sqrt(x);
17+
q0 = zeros(size(t));
18+
19+
for i=1:9
20+
q0 = q0 + t0*coefs(i);
21+
t0 = t0.*t;
22+
end
23+
24+
end
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
function [q0] = qeval0_near(t)
2+
3+
coefs = ...
4+
[1.7328679513998632735E0,
5+
-0.5000000000000000000E0,
6+
-0.09160849392498290919E0,
7+
0.062500000000000000000E0,
8+
0.019905513916401443210E0,
9+
-0.017578125000000000000E0,
10+
-0.006097834693194945559E0,
11+
0.006103515625000000000E0,
12+
0.0021674343381175963469E0,
13+
-0.0023365020751953125000E0,
14+
-0.0008357538695841108955E0,
15+
0.0009462833404541015625E0,
16+
0.0003390851133264318725E0,
17+
-0.00039757043123245239258E0,
18+
-0.00014242013770157621830E0,
19+
0.00017140153795480728149E0,
20+
0.00006133159221782055041E0,
21+
-0.00007532294148404616863E0];
22+
23+
24+
b = log(t);
25+
v = 1;
26+
27+
q0 = zeros(size(t));
28+
29+
for i=1:9
30+
q0 = q0 + v*coefs(2*i-1)+v.*b*coefs(2*i);
31+
v = v.*t;
32+
end
33+
34+
end
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
function [q0d] = qeval0der_near(t)
2+
3+
coefs = ...
4+
[1.7328679513998632735d0,
5+
-0.5000000000000000000d0,
6+
-0.09160849392498290919d0,
7+
0.062500000000000000000d0,
8+
0.019905513916401443210d0,
9+
-0.017578125000000000000d0,
10+
-0.006097834693194945559d0,
11+
0.006103515625000000000d0,
12+
0.0021674343381175963469d0,
13+
-0.0023365020751953125000d0,
14+
-0.0008357538695841108955d0,
15+
0.0009462833404541015625d0,
16+
0.0003390851133264318725d0,
17+
-0.00039757043123245239258d0,
18+
-0.00014242013770157621830d0,
19+
0.00017140153795480728149d0,
20+
0.00006133159221782055041d0,
21+
-0.00007532294148404616863d0];
22+
23+
b = log(t);
24+
v = 1;
25+
26+
q0d = coefs(2)./t;
27+
28+
for i=2:9
29+
q0d = q0d + (i-1)* ...
30+
(v*coefs(2*i-1)+v.*b*coefs(2*i)) ...
31+
+v*coefs(2*i);
32+
v = v.*t;
33+
end
34+
35+
36+
end
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
function [q1] = qeval1_far(x)
2+
3+
coefs = ...
4+
[0.55536036726979578088E0,
5+
0,
6+
0.26032517215771677229E0,
7+
0,
8+
0.17083839422850163181E0,
9+
0,
10+
0.12723901236810277786E0,
11+
0,
12+
0.10139358798083190111E0];
13+
14+
15+
t = 1./x;
16+
t0 = 1./sqrt(x).^3;
17+
q1 = zeros(size(t));
18+
19+
for i=1:9
20+
q1 = q1 + t0*coefs(i);
21+
t0 = t0.*t;
22+
end
23+
24+
end
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
function [q1] = qeval1_near(t)
2+
3+
coefs = ...
4+
[-0.2671320486001367265d0,
5+
-0.5000000000000000000d0,
6+
0.5248254817749487276d0,
7+
-0.18750000000000000000d0,
8+
-0.04098835652733573868d0,
9+
0.029296875000000000000d0,
10+
0.009513531070472923783d0,
11+
-0.008544921875000000000d0,
12+
-0.0029774361551467310174d0,
13+
0.0030040740966796875000d0,
14+
0.0010682069932178195667d0,
15+
-0.0011565685272216796875d0,
16+
-0.0004138797762860294822d0,
17+
0.00046985596418380737305d0,
18+
0.00016838776925222835322d0,
19+
-0.00019777100533246994019d0,
20+
-0.00007084821236213522235d0,
21+
0.00008536600034858565778d0];
22+
23+
24+
b = log(t);
25+
v = 1;
26+
27+
q1 = zeros(size(t));
28+
29+
for i=1:9
30+
q1 = q1 + v*coefs(2*i-1)+v.*b*coefs(2*i);
31+
v = v.*t;
32+
end
33+
34+
end

0 commit comments

Comments
 (0)