|
| 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 | + |
0 commit comments