|
| 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