Skip to content

Commit e35cd0f

Browse files
committed
added file for laplace modal greens functions
1 parent 7f674f8 commit e35cd0f

File tree

1 file changed

+248
-0
lines changed

1 file changed

+248
-0
lines changed
Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
function [gvals, gdzs, gdrs, gdrps] = g0funcall(r, rp, dr, z, zp, dz, maxm)
2+
%
3+
% chnk.axissymlap2d.g0funcall evaluates a collection of axisymmetric Laplace
4+
% Green's functions, defined by the expression:
5+
%
6+
% gfunc(n) = pi*rp * \int_0^{2\pi} 1/|x - x'| e^(-i n t) dt
7+
%
8+
% The extra factor of rp (and maybe pi?) out front makes subsequent interfacing
9+
% with RCIP slightly easier. Modes 0 through maxm are returned, with gval(1) =
10+
% mode 0 and gval(maxm+1) = mode maxm. The function is even, so g_{-n} = g_n.
11+
%
12+
% The above scaling should be consistent with what is in
13+
% chnk.axissymlap2d.gfunc, which is for merely the zero-mode
14+
%
15+
16+
twopi = 2*pi;
17+
fourpi = 4*pi;
18+
done = 1.0;
19+
ima = 1i;
20+
21+
22+
%r = targ(1)
23+
%z = targ(2)
24+
r0 = rp;
25+
z0 = zp;
26+
rzero = sqrt(r*r + r0*r0 + dz*dz);
27+
alpha = 2*r*r0/rzero^2;
28+
x = 1/alpha;
29+
xminus = (dr*dr + dz*dz)/2/r/r0;
30+
31+
dxdr = (r^2 - r0^2 - (dz)^2)/2/r0/r^2
32+
dxdz = 2*(dz)/2/r/r0
33+
dxdr0 = (r0^2 - r^2 - (dz)^2)/2/r/r0^2
34+
dxdz0 = -dxdz
35+
36+
%!
37+
%! if xminus is very small, use the forward recurrence
38+
%!
39+
40+
%!!!!print *, 'inside g0mall, x = ', x
41+
42+
43+
iffwd = 0
44+
if (x < 1.005)
45+
iffwd = 1
46+
if ((x >= 1.0005d0) && (maxm > 163))
47+
iffwd = 0;
48+
end
49+
50+
if ((x >= 1.00005d0) && (maxm > 503))
51+
iffwd = 0;
52+
end
53+
54+
if ((x >= 1.000005d0) && (maxm > 1438))
55+
iffwd = 0;
56+
end
57+
58+
if ((x >= 1.0000005d0) && (maxm > 4380))
59+
iffwd = 0;
60+
end
61+
62+
if ((x >= 1.00000005d0) && (maxm > 12307))
63+
iffwd = 0;
64+
end
65+
66+
end
67+
68+
69+
if (iffwd = 1)
70+
71+
%!!xminus = .000005d0
72+
%!!x = 1 + xminus
73+
74+
call axi_q2lege01(x, xminus, q0, q1, dq0, dq1)
75+
76+
done = 1
77+
half = done/2
78+
%pi = 4*atan(done)
79+
80+
fac = done/sqrt(r*r0)/4/pi^2
81+
vals(0) = q0
82+
vals(1) = q1
83+
84+
derprev = dq0
85+
der = dq1
86+
87+
grads(1,0) = (dq0*dxdr - q0/2/r)
88+
grads(1,1) = (dq1*dxdr - q1/2/r)
89+
90+
grads(2,0) = dq0*dxdz
91+
grads(2,1) = dq1*dxdz
92+
93+
grad0s(1,0) = (dq0*dxdr0 - q0/2/r0)
94+
grad0s(1,1) = (dq1*dxdr0 - q1/2/r0)
95+
96+
grad0s(2,0) = dq0*dxdz0
97+
grad0s(2,1) = dq1*dxdz0
98+
99+
for i = 1:(maxm-1)
100+
vals(i+1) = (2*i*x*vals(i) - (i-half)*vals(i-1))/(i+half)
101+
dernext = (2*i*(vals(i)+x*der) - (i-half)*derprev)/(i+half)
102+
grads(1,i+1) = (dernext*dxdr - vals(i+1)/2/r)
103+
grads(2,i+1) = dernext*dxdz
104+
grad0s(1,i+1) = (dernext*dxdr0 - vals(i+1)/2/r0)
105+
grad0s(2,i+1) = dernext*dxdz0
106+
derprev = der
107+
der = dernext
108+
%! if (abs(vals(i+1)) > abs(vals(i))) then
109+
%! print *
110+
%! print *
111+
%! call prin2('x = *', x, 1)
112+
%! call prinf('i = *', i, 1)
113+
%! call prin2('vals(i+1) = *', vals(i+1), 1)
114+
%! call prin2('vals(i) = *', vals(i), 1)
115+
%! stop
116+
%! endif
117+
end
118+
119+
for i = 0:maxm
120+
vals(i) = vals(i)*fac
121+
grads(1,i) = grads(1,i)*fac
122+
grads(2,i) = grads(2,i)*fac
123+
grad0s(1,i) = grad0s(1,i)*fac
124+
grad0s(2,i) = grad0s(2,i)*fac
125+
vals(-i) = vals(i)
126+
grads(1,-i) = grads(1,i)
127+
grads(2,-i) = grads(2,i)
128+
grad0s(1,-i) = grad0s(1,i)
129+
grad0s(2,-i) = grad0s(2,i)
130+
end
131+
132+
return
133+
end
134+
135+
%!
136+
%! if here, xminus > .005, so run forward and backward recurrence
137+
%!
138+
139+
%!
140+
%! run the recurrence, starting from maxm, until it has exploded
141+
%! for BOTH the values and derivatives
142+
%!
143+
done = 1
144+
half = done/2
145+
f = 1
146+
fprev = 0
147+
der = 1
148+
derprev = 0
149+
maxiter = 100000
150+
upbound = 1.0d19
151+
152+
for i = maxm:maxiter
153+
fnext = (2*i*x*f - (i-half)*fprev)/(i+half)
154+
dernext = (2*i*(x*der+f) - (i-half)*derprev)/(i+half)
155+
if (abs(fnext) .ge. upbound)
156+
if (abs(dernext) .ge. upbound)
157+
nterms = i+1
158+
exit
159+
end
160+
end
161+
fprev = f
162+
f = fnext
163+
derprev = der
164+
der = dernext
165+
end
166+
167+
%!
168+
%! now start at nterms and recurse down to maxm
169+
%!
170+
171+
if (nterms .lt. 10) then
172+
nterms = 10
173+
end
174+
175+
fnext = 0
176+
f = 1
177+
dernext = 0
178+
der = 1
179+
180+
181+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
182+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%555
183+
% Make correct downwrd recurrence
184+
185+
for i = nterm,maxm,-1
186+
fprev = (2*i*x*f - (i+half)*fnext)/(i-half)
187+
fnext = f
188+
f = fprev
189+
derprev = (2*i*(x*der+f) - (i+half)*dernext)/(i-half)
190+
dernext = der
191+
der = derprev
192+
enddo
193+
194+
vals(maxm-1) = f
195+
vals(maxm) = fnext
196+
197+
ders(maxm-1) = der
198+
ders(maxm) = dernext
199+
200+
do i = maxm-1,1,-1
201+
vals(i-1) = (2*i*x*vals(i) - (i+half)*vals(i+1))/(i-half)
202+
ders(i-1) = (2*i*(x*ders(i)+vals(i)) &
203+
- (i+half)*ders(i+1))/(i-half)
204+
end do
205+
206+
207+
!
208+
! normalize the values, and use a formula for the derivatives
209+
!
210+
call axi_q2lege01(x, xminus, q0, q1, dq0, dq1)
211+
212+
done = 1
213+
pi = 4*atan(done)
214+
ratio = q0/vals(0)
215+
216+
do i = 0,maxm
217+
vals(i) = vals(i)*ratio
218+
enddo
219+
220+
ders(0) = dq0
221+
ders(1) = dq1
222+
do i = 2,maxm
223+
ders(i) = -(i-.5d0)*(vals(i-1) - x*vals(i))/(1+x)/xminus
224+
end do
225+
226+
!
227+
! and scale everyone...
228+
!
229+
fac = 1/sqrt(r*r0)/4/pi^2
230+
231+
do i = 0,maxm
232+
grads(1,i) = (ders(i)*dxdr - vals(i)/2/r)*fac
233+
grads(2,i) = ders(i)*dxdz*fac
234+
grad0s(1,i) = (ders(i)*dxdr0 - vals(i)/2/r0)*fac
235+
grad0s(2,i) = ders(i)*dxdz0*fac
236+
vals(i) = vals(i)*fac
237+
vals(-i) = vals(i)
238+
grads(1,-i) = grads(1,i)
239+
grads(2,-i) = grads(2,i)
240+
grad0s(1,-i) = grad0s(1,i)
241+
grad0s(2,-i) = grad0s(2,i)
242+
end do
243+
244+
245+
246+
247+
248+
end

0 commit comments

Comments
 (0)