|
| 1 | +function [val,grad,hess,der3,der4,der5] = hkdiffgreen_ff(k,src,targ,opts) |
| 2 | + |
| 3 | +prefac = 1i/(2*sqrt(2*pi))*exp(-1i*pi/4); |
| 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 | +rt = sqrt(xt.^2+yt.^2); |
| 14 | + |
| 15 | +xt = xt./rt; |
| 16 | +yt = yt./rt; |
| 17 | + |
| 18 | +dp = xt.*xs+yt.*ys; |
| 19 | + |
| 20 | +g0 = prefac*exp(-1i*dp*k); |
| 21 | + |
| 22 | + |
| 23 | +% evaluate potential and derivatives |
| 24 | + |
| 25 | +if nargout > 0 |
| 26 | + val = g0; |
| 27 | +end |
| 28 | +if nargout > 1 |
| 29 | + grad(:,:,1) = -1i*k*g0.*xt; |
| 30 | + grad(:,:,2) = -1i*k*g0.*yt; |
| 31 | + grad = -grad; |
| 32 | +end |
| 33 | +if nargout > 2 |
| 34 | + hess(:,:,1) = (-1i*k)^2*g0.*xt.^2; |
| 35 | + hess(:,:,2) = (-1i*k)^2*g0.*xt.*yt; |
| 36 | + hess(:,:,3) = (-1i*k)^2*g0.*yt.^2; |
| 37 | +end |
| 38 | +if nargout > 3 |
| 39 | + der3(:,:,1) = (-1i*k)^3*g0.*(xt.^3); |
| 40 | + der3(:,:,2) = (-1i*k)^3*g0.*(xt.^2).*yt; |
| 41 | + der3(:,:,3) = (-1i*k)^3*g0.*(yt.^2).*xt; |
| 42 | + der3(:,:,4) = (-1i*k)^3*g0.*(yt.^3); |
| 43 | + der3 = -der3; |
| 44 | +end |
| 45 | + |
| 46 | +if nargout > 4 |
| 47 | + der4(:,:,1) = (-1i*k)^4*g0.*(xt.^4); |
| 48 | + der4(:,:,2) = (-1i*k)^4*g0.*(xt.^3).*(yt); |
| 49 | + der4(:,:,3) = (-1i*k)^4*g0.*(xt.^2).*(yt.^2); |
| 50 | + der4(:,:,4) = (-1i*k)^4*g0.*(xt).*(yt.^3); |
| 51 | + der4(:,:,5) = (-1i*k)^4*g0.*(yt.^4); |
| 52 | +end |
| 53 | + |
| 54 | +if nargout > 5 |
| 55 | + der5(:,:,1) = (-1i*k)^5*g0.*(xt.^5); |
| 56 | + der5(:,:,2) = (-1i*k)^5*g0.*(xt.^4).*(yt); |
| 57 | + der5(:,:,3) = (-1i*k)^5*g0.*(xt.^3).*(yt.^2); |
| 58 | + der5(:,:,4) = (-1i*k)^5*g0.*(xt.^2).*(yt.^3); |
| 59 | + der5(:,:,5) = (-1i*k)^5*g0.*(xt.^1).*(yt.^4); |
| 60 | + der5(:,:,6) = (-1i*k)^5*g0.*(yt.^5); |
| 61 | + der5 = -der5; |
| 62 | +end |
| 63 | + |
| 64 | +end |
| 65 | + |
| 66 | +function [g0,g1,g21,g321,g4321,g54321] = diff_h0k0_and_rders(k,r,r2logrfac) |
| 67 | +% g0 = g |
| 68 | +% g1 = g' |
| 69 | +% g21 = g'' - g'/r |
| 70 | +% g321 = g''' - 3*g''/r + 3g'/r^2 = g''' - 3*g21/r |
| 71 | +% g4321 = g'''' - 6*g'''/r + 15*g''/r^2 - 15*g'/r^3 |
| 72 | +% = g''''- 6 g321/r - 3 g21/r^2 |
| 73 | +% g54321 = g''''' - 10g''''/r + 45g'''/r^2 -105g''/r^3 + 105g'/r^4 |
| 74 | +% = g5 - 10g4321/r - 15 g321/r^2 |
| 75 | + |
| 76 | +g0 = zeros(size(r)); |
| 77 | +g1 = zeros(size(r)); |
| 78 | +g321 = zeros(size(r)); |
| 79 | +g4321 = zeros(size(r)); |
| 80 | +g54321 = zeros(size(r)); |
| 81 | +g21 = zeros(size(r)); |
| 82 | + |
| 83 | +io4 = 1i*0.25; |
| 84 | +o2p = 1/(2*pi); |
| 85 | + |
| 86 | +isus = abs(k)*r < 1; |
| 87 | +%isus = false(size(r)); |
| 88 | +%isus = true(size(r)); |
| 89 | + |
| 90 | +% straightforward formulas for sufficiently large |
| 91 | + |
| 92 | +rnot = r(~isus); |
| 93 | + |
| 94 | +kr = k*rnot; |
| 95 | + |
| 96 | +h0 = besselh(0,1,kr); |
| 97 | +h1 = besselh(1,1,kr); |
| 98 | +h0i = besselh(0,1,1i*kr); |
| 99 | +h1i = besselh(1,1,1i*kr); |
| 100 | + |
| 101 | +rm1 = 1./rnot; |
| 102 | +rm2 = rm1.*rm1; |
| 103 | +rm3 = rm1.*rm2; |
| 104 | +rm4 = rm1.*rm3; |
| 105 | + |
| 106 | +r2fac = (1-r2logrfac)*k*k*0.5*o2p; |
| 107 | +logr = log(rnot); |
| 108 | +g0(~isus) = io4*(h0 - h0i) - r2fac*rnot.*rnot.*logr; |
| 109 | +g1(~isus) = io4*(-k*h1 + 1i*k*h1i) - r2fac*(rnot+2*rnot.*logr); |
| 110 | +g21(~isus) = io4*(-k*k*h0 + k*h1.*rm1 - k*k*h0i - 1i*k*h1i.*rm1) ... |
| 111 | + - r2fac*(3+2*logr) - g1(~isus).*rm1; |
| 112 | +g321(~isus) = io4*(k*k*h0.*rm1 + k*(k*k-2*rm2).*h1 ... |
| 113 | + + k*k*h0i.*rm1 - 1i*k*(-k*k-2*rm2).*h1i) - r2fac*2*rm1 - 3*g21(~isus).*rm1; |
| 114 | +g4321(~isus) = io4*(k*(3*rm2-k*k).*(2*h1.*rm1-k*h0) - ... |
| 115 | + 1i*k*(3*rm2+k*k).*(2*h1i.*rm1-1i*k*h0i)) + r2fac*2*rm2 - 6*g321(~isus).*rm1 ... |
| 116 | + - 3*g21(~isus).*rm2; |
| 117 | +g54321(~isus) = io4*(k*( (12*k*rm3-2*k^3*rm1).*h0 + ... |
| 118 | + (-24*rm4+7*k*k*rm2-k^4).*h1) - 1i*k*( (12*1i*k*rm3+1i*2*k^3*rm1).*h0i + ... |
| 119 | + (-24*rm4-7*k*k*rm2-k^4).*h1i)) - r2fac*4*rm3 - 10*g4321(~isus).*rm1 - ... |
| 120 | + 15*g321(~isus).*rm2; |
| 121 | + |
| 122 | +% manually cancel when small |
| 123 | + |
| 124 | +rsus = r(isus); |
| 125 | +rm1 = 1./rsus; |
| 126 | +rm2 = rm1.*rm1; |
| 127 | +rm3 = rm1.*rm2; |
| 128 | +rm4 = rm1.*rm3; |
| 129 | +rm5 = rm1.*rm4; |
| 130 | + |
| 131 | +r2 = rsus.*rsus; |
| 132 | +r4 = r2.*r2; |
| 133 | + |
| 134 | +nterms = 7; |
| 135 | + |
| 136 | +% relevant parts of hankel function represented as power series |
| 137 | +[cf1,cf2] = chnk.flex2d.besselkikdiff_etc_pscoefs(nterms); |
| 138 | +cf1(1) = cf1(1)*r2logrfac; |
| 139 | +kpow = k*k*(k.^(4*(0:(nterms-1)))); % k^2, k^6, k^10, ... |
| 140 | +cf1 = cf1(:).*kpow(:); cf2 = cf2(:).*kpow(:); |
| 141 | + |
| 142 | + |
| 143 | +jdiff = chnk.flex2d.pseval(cf1,r4).*r2; |
| 144 | +f = chnk.flex2d.pseval(cf2,r4).*r2; |
| 145 | + |
| 146 | +% differentiate power series to get derivatives |
| 147 | +fac = 2+4*(0:(nterms-1)).'; |
| 148 | +jdiffd1 = chnk.flex2d.pseval(cf1.*fac,r4).*rsus; |
| 149 | +fd1 = chnk.flex2d.pseval(cf2.*fac,r4).*rsus; |
| 150 | +d = fac.*(fac-1)-fac; |
| 151 | +jdiffd21 = chnk.flex2d.pseval(cf1.*d,r4); |
| 152 | +fd21 = chnk.flex2d.pseval(cf2.*d,r4); |
| 153 | +% third deriv and higher the first term is dead (this is subtle but true |
| 154 | +% for the 21, 321, 4321, etc derivative) |
| 155 | +cf1 = cf1(2:end); cf2 = cf2(2:end); fac = fac(2:end); |
| 156 | +d = fac.*(fac-1).*(fac-2) - 3*(fac.*(fac-1)-fac); |
| 157 | +jdiffd321 = chnk.flex2d.pseval(cf1.*d,r4).*rsus.*r2; |
| 158 | +fd321 = chnk.flex2d.pseval(cf2.*d,r4).*rsus.*r2; |
| 159 | +% g4321 = g'''' - 6*g'''/r + 15*g''/r^2 - 15*g'/r^3 |
| 160 | +d = fac.*(fac-1).*(fac-2).*(fac-3)-6*fac.*(fac-1).*(fac-2)+15*(fac.*(fac-1)-fac); |
| 161 | +jdiffd4321 = chnk.flex2d.pseval(cf1.*d,r4).*r2; |
| 162 | +fd4321 = chnk.flex2d.pseval(cf2.*d,r4).*r2; |
| 163 | +% g54321 = g''''' - 10g''''/r + 45g'''/r^2 -105g''/r^3 + 105g'/r^4 |
| 164 | +d = fac.*(fac-1).*(fac-2).*(fac-3).*(fac-4) - ... |
| 165 | + 10*fac.*(fac-1).*(fac-2).*(fac-3) + 45*fac.*(fac-1).*(fac-2) - ... |
| 166 | + 105*(fac.*(fac-1)-fac); |
| 167 | +jdiffd54321 = chnk.flex2d.pseval(cf1.*d,r4).*rsus; |
| 168 | +fd54321 = chnk.flex2d.pseval(cf2.*d,r4).*rsus; |
| 169 | + |
| 170 | +% combine to get derivative of i/4 H - K/2pi |
| 171 | +gam = 0.57721566490153286060651209; |
| 172 | +logr = log(rsus) + log(k) - log(2) + gam; |
| 173 | +const1 = (1-r2logrfac)*o2p*(log(k)+gam-log(2))*k*k/2; |
| 174 | + |
| 175 | +j0 = besselj(0,k*rsus); |
| 176 | +j1 = besselj(1,k*rsus); |
| 177 | +j2 = besselj(2,k*rsus); |
| 178 | +j3 = besselj(3,k*rsus); |
| 179 | +j4 = besselj(4,k*rsus); |
| 180 | +j5 = besselj(5,k*rsus); |
| 181 | +g0(isus) = io4*j0 - o2p*(f + logr.*jdiff) + const1*r2; |
| 182 | +g1(isus) = io4*(-k*j1) - o2p*(fd1 + logr.*jdiffd1 + jdiff.*rm1) + 2*const1*rsus; |
| 183 | +g21(isus) = io4*(k*k*j2) - o2p*(fd21 + logr.*jdiffd21 + 2*jdiffd1.*rm1 - 2*jdiff.*rm2); |
| 184 | +g321(isus) = io4*(-k^3*j3) - o2p*(fd321 + logr.*jdiffd321 + 3*jdiffd21.*rm1 - ... |
| 185 | + 6*jdiffd1.*rm2 + 8*jdiff.*rm3); |
| 186 | +g4321(isus) = io4*(k^4*j4)- o2p*(fd4321 + logr.*jdiffd4321 + 4*jdiffd321.*rm1 - ... |
| 187 | + 12*jdiffd21.*rm2 + 32*jdiffd1.*rm3 - 48*jdiff.*rm4); |
| 188 | +g54321(isus) = io4*(-k^5*j5) - o2p*(fd54321 + logr.*jdiffd54321 + ... |
| 189 | + 5*jdiffd4321.*rm1 - 20*jdiffd321.*rm2 + 80*jdiffd21.*rm3 - 240*jdiffd1.*rm4 + 384*jdiff.*rm5); |
| 190 | + |
| 191 | +end |
| 192 | + |
0 commit comments