comparison +scheme/LaplaceCurvilinear.m @ 1342:d1dad4fbfe22 feature/D2_boundary_opt

Add support for glue interpolation operators, and separate wave speeds across interfaces
author Vidar Stiernström <vidar.stiernstrom@it.uu.se>
date Fri, 26 Aug 2022 14:19:29 +0200
parents 84200bbae101
children
comparison
equal deleted inserted replaced
1341:663eb90a4559 1342:d1dad4fbfe22
101 Dv = kr(I_u,D1_v); 101 Dv = kr(I_u,D1_v);
102 obj.Hu = kr(H_u,I_v); 102 obj.Hu = kr(H_u,I_v);
103 obj.Hv = kr(I_u,H_v); 103 obj.Hv = kr(I_u,H_v);
104 obj.Hiu = kr(Hi_u,I_v); 104 obj.Hiu = kr(Hi_u,I_v);
105 obj.Hiv = kr(I_u,Hi_v); 105 obj.Hiv = kr(I_u,Hi_v);
106 obj.H_u = H_u;
107 obj.H_v = H_v;
106 108
107 e_w = kr(e_l_u,I_v); 109 e_w = kr(e_l_u,I_v);
108 e_e = kr(e_r_u,I_v); 110 e_e = kr(e_r_u,I_v);
109 e_s = kr(I_u,e_l_v); 111 e_s = kr(I_u,e_l_v);
110 e_n = kr(I_u,e_r_v); 112 e_n = kr(I_u,e_r_v);
287 default_struct('type', defaultType); 289 default_struct('type', defaultType);
288 290
289 switch type.interpolation 291 switch type.interpolation
290 case {'none', ''} 292 case {'none', ''}
291 [closure, penalty] = interfaceStandard(obj,boundary,neighbour_scheme,neighbour_boundary,type); 293 [closure, penalty] = interfaceStandard(obj,boundary,neighbour_scheme,neighbour_boundary,type);
292 case {'op','OP'} 294 case {'op','OP','glue'}
293 [closure, penalty] = interfaceNonConforming(obj,boundary,neighbour_scheme,neighbour_boundary,type); 295 [closure, penalty] = interfaceNonConforming(obj,boundary,neighbour_scheme,neighbour_boundary,type);
294 otherwise 296 otherwise
295 error('Unknown type of interpolation: %s ', type.interpolation); 297 error('Unknown type of interpolation: %s ', type.interpolation);
296 end 298 end
297 end 299 end
364 % Find the number of grid points along the interface 366 % Find the number of grid points along the interface
365 m_u = size(e_u, 2); 367 m_u = size(e_u, 2);
366 m_v = size(e_v, 2); 368 m_v = size(e_v, 2);
367 369
368 Hi = obj.Hi; 370 Hi = obj.Hi;
369 a = obj.a;
370 371
371 u = obj; 372 u = obj;
372 v = neighbour_scheme; 373 v = neighbour_scheme;
374
375 a_u = u.a;
376 a_v = v.a;
373 377
374 b1_u = gamm_u*u.lambda(I_u)./u.a11(I_u).^2; 378 b1_u = gamm_u*u.lambda(I_u)./u.a11(I_u).^2;
375 b2_u = gamm_u*u.lambda(I_u)./u.a22(I_u).^2; 379 b2_u = gamm_u*u.lambda(I_u)./u.a22(I_u).^2;
376 b1_v = gamm_v*v.lambda(I_v)./v.a11(I_v).^2; 380 b1_v = gamm_v*v.lambda(I_v)./v.a11(I_v).^2;
377 b2_v = gamm_v*v.lambda(I_v)./v.a22(I_v).^2; 381 b2_v = gamm_v*v.lambda(I_v)./v.a22(I_v).^2;
382 tau_u = tuning * spdiag(tau_u); 386 tau_u = tuning * spdiag(tau_u);
383 tau_v = tuning * spdiag(tau_v); 387 tau_v = tuning * spdiag(tau_v);
384 beta_u = tau_v; 388 beta_u = tau_v;
385 389
386 % Build interpolation operators 390 % Build interpolation operators
387 intOps = interpOpSet(m_u, m_v, obj.order, neighbour_scheme.order); 391 switch type.interpolation
388 Iu2v = intOps.Iu2v; 392 case {'op','OP','MC','mc'}
389 Iv2u = intOps.Iv2u; 393 intOps = interpOpSet(m_u, m_v, obj.order, neighbour_scheme.order);
390 394 Iu2v = intOps.Iu2v;
391 closure = a*Hi*e_u*tau_u*H_b_u*e_u' + ... 395 Iv2u = intOps.Iv2u;
392 a*Hi*e_u*H_b_u*Iv2u.bad*beta_u*Iu2v.good*e_u' + ... 396 case 'glue'
393 a*1/2*Hi*d_u*H_b_u*e_u' + ... 397 optype = type.optype; % TODO: Should be stored by the scheme?
394 -a*1/2*Hi*e_u*H_b_u*d_u'; 398 xu = obj.getBoundaryGrid(boundary);
395 399 xv = neighbour_scheme.getBoundaryGrid(neighbour_boundary);
396 penalty = -a*Hi*e_u*tau_u*H_b_u*Iv2u.good*e_v' + ... 400 hu = obj.getBoundaryGridSpacing(boundary);
397 -a*Hi*e_u*H_b_u*Iv2u.bad*beta_u*e_v' + ... 401 hv = neighbour_scheme.getBoundaryGridSpacing(neighbour_boundary);
398 -a*1/2*Hi*d_u*H_b_u*Iv2u.good*e_v' + ... 402 glueOps = interpOpSet(xu, xv, hu, hv, obj.order, neighbour_scheme.order, optype, optype);
399 -a*1/2*Hi*e_u*H_b_u*Iv2u.bad*d_v'; 403 Iu2v = glueOps.Iu2v;
404 Iv2u = glueOps.Iv2u;
405 otherwise
406 error();
407 end
408
409 closure = a_u*Hi*e_u*tau_u*H_b_u*e_u' + ...
410 a_v*Hi*e_u*H_b_u*Iv2u.bad*beta_u*Iu2v.good*e_u' + ...
411 a_u*1/2*Hi*d_u*H_b_u*e_u' + ...
412 -a_u*1/2*Hi*e_u*H_b_u*d_u';
413
414 penalty = -a_u*Hi*e_u*tau_u*H_b_u*Iv2u.good*e_v' + ...
415 -a_v*Hi*e_u*H_b_u*Iv2u.bad*beta_u*e_v' + ...
416 -a_u*1/2*Hi*d_u*H_b_u*Iv2u.good*e_v' + ...
417 -a_v*1/2*Hi*e_u*H_b_u*Iv2u.bad*d_v';
400 418
401 end 419 end
402 420
403 % Returns the boundary operator op for the boundary specified by the string boundary. 421 % Returns the boundary operator op for the boundary specified by the string boundary.
404 % op -- string 422 % op -- string
449 case {'s','n'} 467 case {'s','n'}
450 gamm = obj.gamm_v; 468 gamm = obj.gamm_v;
451 end 469 end
452 end 470 end
453 471
472 function xb = getBoundaryGrid(obj, boundary)
473 assertIsMember(boundary, {'w', 'e', 's', 'n'})
474 if isa(obj.grid,'grid.Cartesian')
475 lg = obj.grid;
476 elseif isa(obj.grid,'grid.Curvilinear')
477 lg = obj.grid.logicalGrid();
478 else
479 error('Grid type not supported');
480 end
481 switch boundary
482 case {'w','e'}
483 xb = lg.x{2};
484 case {'s','n'}
485 xb = lg.x{1};
486 end
487 end
488
489 function hb = getBoundaryGridSpacing(obj, boundary)
490 h = obj.grid.scaling();
491 switch boundary
492 case {'w','e'}
493 hb = h(2);
494 case {'s','n'}
495 hb = h(1);
496 end
497 end
498
454 function N = size(obj) 499 function N = size(obj)
455 N = prod(obj.m); 500 N = prod(obj.m);
456 end 501 end
457 end 502 end
458 end 503 end