comparison +scheme/Elastic2dVariable.m @ 1108:5ec23b9bf360 feature/laplace_curvilinear_test

Merge with default
author Martin Almquist <malmquist@stanford.edu>
date Wed, 10 Apr 2019 11:00:27 -0700
parents 19d821ddc108
children 60c875c18de3
comparison
equal deleted inserted replaced
1087:867307f4d80f 1108:5ec23b9bf360
427 % u denotes the solution in the own domain 427 % u denotes the solution in the own domain
428 % v denotes the solution in the neighbour domain 428 % v denotes the solution in the neighbour domain
429 % Operators without subscripts are from the own domain. 429 % Operators without subscripts are from the own domain.
430 430
431 % Get boundary operators 431 % Get boundary operators
432 [e, tau] = obj.getBoundaryOperator({'e_tot','tau_tot'}, boundary); 432 e = obj.getBoundaryOperator('e_tot', boundary);
433 [e_v, tau_v] = neighbour_scheme.getBoundaryOperator({'e_tot','tau_tot'}, neighbour_boundary); 433 tau = obj.getBoundaryOperator('tau_tot', boundary);
434
435 e_v = neighbour_scheme.getBoundaryOperator('e_tot', neighbour_boundary);
436 tau_v = neighbour_scheme.getBoundaryOperator('tau_tot', neighbour_boundary);
437
434 H_gamma = obj.getBoundaryQuadrature(boundary); 438 H_gamma = obj.getBoundaryQuadrature(boundary);
435 439
436 % Operators and quantities that correspond to the own domain only 440 % Operators and quantities that correspond to the own domain only
437 Hi = obj.Hi_kron; 441 Hi = obj.Hi_kron;
438 RHOi = obj.RHOi_kron; 442 RHOi = obj.RHOi_kron;
456 error('Non-conforming interfaces not implemented yet.'); 460 error('Non-conforming interfaces not implemented yet.');
457 end 461 end
458 462
459 % Returns the coordinate number and outward normal component for the boundary specified by the string boundary. 463 % Returns the coordinate number and outward normal component for the boundary specified by the string boundary.
460 function [j, nj] = get_boundary_number(obj, boundary) 464 function [j, nj] = get_boundary_number(obj, boundary)
465 assertIsMember(boundary, {'w', 'e', 's', 'n'})
461 466
462 switch boundary 467 switch boundary
463 case {'w','W','west','West', 'e', 'E', 'east', 'East'} 468 case {'w', 'e'}
464 j = 1; 469 j = 1;
465 case {'s','S','south','South', 'n', 'N', 'north', 'North'} 470 case {'s', 'n'}
466 j = 2; 471 j = 2;
467 otherwise
468 error('No such boundary: boundary = %s',boundary);
469 end 472 end
470 473
471 switch boundary 474 switch boundary
472 case {'w','W','west','West','s','S','south','South'} 475 case {'w', 's'}
473 nj = -1; 476 nj = -1;
474 case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'} 477 case {'e', 'n'}
475 nj = 1; 478 nj = 1;
476 end 479 end
477 end 480 end
478 481
479 % Returns the boundary operator op for the boundary specified by the string boundary. 482 % Returns the boundary operator op for the boundary specified by the string boundary.
480 % op: may be a cell array of strings 483 % op -- string
481 % Only operators with name *_tot can be used with multiblock.DiffOp.getBoundaryOperator() 484 % Only operators with name *_tot can be used with multiblock.DiffOp.getBoundaryOperator()
482 function [varargout] = getBoundaryOperator(obj, op, boundary) 485 function [varargout] = getBoundaryOperator(obj, op, boundary)
486 assertIsMember(boundary, {'w', 'e', 's', 'n'})
487 assertIsMember(op, {'e', 'e_tot', 'd', 'T', 'tau', 'tau_tot', 'H', 'alpha', 'alpha_tot'})
483 488
484 switch boundary 489 switch boundary
485 case {'w','W','west','West', 'e', 'E', 'east', 'East'} 490 case {'w', 'e'}
486 j = 1; 491 j = 1;
487 case {'s','S','south','South', 'n', 'N', 'north', 'North'} 492 case {'s', 'n'}
488 j = 2; 493 j = 2;
489 otherwise 494 end
490 error('No such boundary: boundary = %s',boundary); 495
491 end 496 switch op
492 497 case 'e'
493 if ~iscell(op) 498 switch boundary
494 op = {op}; 499 case {'w', 's'}
495 end 500 o = obj.e_l{j};
496 501 case {'e', 'n'}
497 for k = 1:length(op) 502 o = obj.e_r{j};
498 switch op{k} 503 end
499 case 'e' 504
500 switch boundary 505 case 'e_tot'
501 case {'w','W','west','West','s','S','south','South'} 506 e = obj.getBoundaryOperator('e', boundary);
502 varargout{k} = obj.e_l{j}; 507 I_dim = speye(obj.dim, obj.dim);
503 case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'} 508 o = kron(e, I_dim);
504 varargout{k} = obj.e_r{j}; 509
510 case 'd'
511 switch boundary
512 case {'w', 's'}
513 o = obj.d1_l{j};
514 case {'e', 'n'}
515 o = obj.d1_r{j};
516 end
517
518 case 'T'
519 switch boundary
520 case {'w', 's'}
521 o = obj.T_l{j};
522 case {'e', 'n'}
523 o = obj.T_r{j};
524 end
525
526 case 'tau'
527 switch boundary
528 case {'w', 's'}
529 o = obj.tau_l{j};
530 case {'e', 'n'}
531 o = obj.tau_r{j};
532 end
533
534 case 'tau_tot'
535 [e, tau] = obj.getBoundaryOperator({'e', 'tau'}, boundary);
536
537 I_dim = speye(obj.dim, obj.dim);
538 e_tot = kron(e, I_dim);
539 E = obj.E;
540 tau_tot = (e_tot'*E{1}*e*tau{1}')';
541 for i = 2:obj.dim
542 tau_tot = tau_tot + (e_tot'*E{i}*e*tau{i}')';
543 end
544 o = tau_tot;
545
546 case 'H'
547 o = obj.H_boundary{j};
548
549 case 'alpha'
550 % alpha = alpha(i,j) is the penalty strength for displacement BC.
551 e = obj.getBoundaryOperator('e', boundary);
552
553 LAMBDA = obj.LAMBDA;
554 MU = obj.MU;
555
556 dim = obj.dim;
557 theta_R = obj.theta_R{j};
558 theta_H = obj.theta_H{j};
559 theta_M = obj.theta_M{j};
560
561 a_lambda = dim/theta_H + 1/theta_R;
562 a_mu_i = 2/theta_M;
563 a_mu_ij = 2/theta_H + 1/theta_R;
564
565 d = @kroneckerDelta; % Kronecker delta
566 db = @(i,j) 1-d(i,j); % Logical not of Kronecker delta
567 alpha = cell(obj.dim, obj.dim);
568
569 alpha_func = @(i,j) d(i,j)* a_lambda*LAMBDA ...
570 + d(i,j)* a_mu_i*MU ...
571 + db(i,j)*a_mu_ij*MU;
572 for i = 1:obj.dim
573 for l = 1:obj.dim
574 alpha{i,l} = d(i,l)*alpha_func(i,j)*e;
505 end 575 end
506 576 end
507 case 'e_tot' 577
508 e = obj.getBoundaryOperator('e', boundary); 578 o = alpha;
509 I_dim = speye(obj.dim, obj.dim); 579
510 varargout{k} = kron(e, I_dim); 580 case 'alpha_tot'
511 581 % alpha = alpha(i,j) is the penalty strength for displacement BC.
512 case 'd' 582 [e, e_tot, alpha] = obj.getBoundaryOperator({'e', 'e_tot', 'alpha'}, boundary);
513 switch boundary 583 E = obj.E;
514 case {'w','W','west','West','s','S','south','South'} 584 [m, n] = size(alpha{1,1});
515 varargout{k} = obj.d1_l{j}; 585 alpha_tot = sparse(m*obj.dim, n*obj.dim);
516 case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'} 586 for i = 1:obj.dim
517 varargout{k} = obj.d1_r{j}; 587 for l = 1:obj.dim
588 alpha_tot = alpha_tot + (e_tot'*E{i}*e*alpha{i,l}'*E{l}')';
518 end 589 end
519 590 end
520 case 'T' 591 o = alpha_tot;
521 switch boundary 592 end
522 case {'w','W','west','West','s','S','south','South'} 593
523 varargout{k} = obj.T_l{j}; 594 end
524 case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'} 595
525 varargout{k} = obj.T_r{j}; 596 % Returns square boundary quadrature matrix, of dimension
526 end 597 % corresponding to the number of boundary points
527 598 %
528 case 'tau' 599 % boundary -- string
529 switch boundary
530 case {'w','W','west','West','s','S','south','South'}
531 varargout{k} = obj.tau_l{j};
532 case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'}
533 varargout{k} = obj.tau_r{j};
534 end
535
536 case 'tau_tot'
537 [e, tau] = obj.getBoundaryOperator({'e', 'tau'}, boundary);
538
539 I_dim = speye(obj.dim, obj.dim);
540 e_tot = kron(e, I_dim);
541 E = obj.E;
542 tau_tot = (e_tot'*E{1}*e*tau{1}')';
543 for i = 2:obj.dim
544 tau_tot = tau_tot + (e_tot'*E{i}*e*tau{i}')';
545 end
546 varargout{k} = tau_tot;
547
548 case 'H'
549 varargout{k} = obj.H_boundary{j};
550
551 case 'alpha'
552 % alpha = alpha(i,j) is the penalty strength for displacement BC.
553 e = obj.getBoundaryOperator('e', boundary);
554
555 LAMBDA = obj.LAMBDA;
556 MU = obj.MU;
557
558 dim = obj.dim;
559 theta_R = obj.theta_R{j};
560 theta_H = obj.theta_H{j};
561 theta_M = obj.theta_M{j};
562
563 a_lambda = dim/theta_H + 1/theta_R;
564 a_mu_i = 2/theta_M;
565 a_mu_ij = 2/theta_H + 1/theta_R;
566
567 d = @kroneckerDelta; % Kronecker delta
568 db = @(i,j) 1-d(i,j); % Logical not of Kronecker delta
569 alpha = cell(obj.dim, obj.dim);
570
571 alpha_func = @(i,j) d(i,j)* a_lambda*LAMBDA ...
572 + d(i,j)* a_mu_i*MU ...
573 + db(i,j)*a_mu_ij*MU;
574 for i = 1:obj.dim
575 for l = 1:obj.dim
576 alpha{i,l} = d(i,l)*alpha_func(i,j)*e;
577 end
578 end
579
580 varargout{k} = alpha;
581
582 case 'alpha_tot'
583 % alpha = alpha(i,j) is the penalty strength for displacement BC.
584 [e, e_tot, alpha] = obj.getBoundaryOperator({'e', 'e_tot', 'alpha'}, boundary);
585 E = obj.E;
586 [m, n] = size(alpha{1,1});
587 alpha_tot = sparse(m*obj.dim, n*obj.dim);
588 for i = 1:obj.dim
589 for l = 1:obj.dim
590 alpha_tot = alpha_tot + (e_tot'*E{i}*e*alpha{i,l}'*E{l}')';
591 end
592 end
593 varargout{k} = alpha_tot;
594
595 otherwise
596 error(['No such operator: operator = ' op{k}]);
597 end
598 end
599
600 end
601
602 function H = getBoundaryQuadrature(obj, boundary) 600 function H = getBoundaryQuadrature(obj, boundary)
601 assertIsMember(boundary, {'w', 'e', 's', 'n'})
602
603 switch boundary 603 switch boundary
604 case {'w','W','west','West', 'e', 'E', 'east', 'East'} 604 case {'w','e'}
605 j = 1; 605 j = 1;
606 case {'s','S','south','South', 'n', 'N', 'north', 'North'} 606 case {'s','n'}
607 j = 2; 607 j = 2;
608 otherwise
609 error('No such boundary: boundary = %s',boundary);
610 end 608 end
611 H = obj.H_boundary{j}; 609 H = obj.H_boundary{j};
612 I_dim = speye(obj.dim, obj.dim); 610 I_dim = speye(obj.dim, obj.dim);
613 H = kron(H, I_dim); 611 H = kron(H, I_dim);
614 end 612 end