comparison +scheme/Elastic2dStaggeredAnisotropic.m @ 1279:546ee16760d5 feature/poroelastic

Add interfaces in Elastic2dStaggeredAnisotropic
author Martin Almquist <malmquist@stanford.edu>
date Sun, 07 Jun 2020 11:30:49 -0700
parents e61083f178be
children
comparison
equal deleted inserted replaced
1278:ce422ba8964e 1279:546ee16760d5
101 for a = 1:nGrids 101 for a = 1:nGrids
102 for i = 1:dim 102 for i = 1:dim
103 for j = 1:dim 103 for j = 1:dim
104 for k = 1:dim 104 for k = 1:dim
105 for l = 1:dim 105 for l = 1:dim
106 C_mat{a}{i,j,k,l} = spdiag(grid.evalOn(g_s{a}, C{i,j,k,l})); 106 if numel(C) == nGrids
107 C_mat{a}{i,j,k,l} = spdiag(C{a}{i,j,k,l});
108 else
109 C_mat{a}{i,j,k,l} = spdiag(grid.evalOn(g_s{a}, C{i,j,k,l}));
110 end
107 end 111 end
108 end 112 end
109 end 113 end
110 end 114 end
111 end 115 end
228 obj.e_s_s = e_s_s; 232 obj.e_s_s = e_s_s;
229 obj.e_n_s = e_n_s; 233 obj.e_n_s = e_n_s;
230 234
231 235
232 % D1_u2s{a, b}{i} approximates ddi and 236 % D1_u2s{a, b}{i} approximates ddi and
233 %takes from u grid number b to s grid number a 237 % takes from u grid number b to s grid number a
234 % Some of D1_x2y{a, b} are 0. 238 % Some of D1_x2y{a, b} are 0.
235 D1_u2s = cell(nGrids, nGrids); 239 D1_u2s = cell(nGrids, nGrids);
236 D1_s2u = cell(nGrids, nGrids); 240 D1_s2u = cell(nGrids, nGrids);
237 241
238 N_u = cell(nGrids, 1); 242 N_u = cell(nGrids, 1);
541 m_tot = obj.N; 545 m_tot = obj.N;
542 546
543 % Preallocate 547 % Preallocate
544 [~, col] = size(tau{1}{1}); 548 [~, col] = size(tau{1}{1});
545 closure = sparse(m_tot, m_tot); 549 closure = sparse(m_tot, m_tot);
546 penalty = cell(nGrids, 1); 550 penalty = cell(1, nGrids);
547 for a = 1:nGrids 551 for a = 1:nGrids
548 [~, col] = size(e_u{a}); 552 [~, col] = size(e_u{a});
549 penalty{a} = sparse(m_tot, col); 553 penalty{a} = sparse(m_tot, col);
550 end 554 end
551 555
617 621
618 % Unknown boundary condition 622 % Unknown boundary condition
619 otherwise 623 otherwise
620 error('No such boundary condition: type = %s',type); 624 error('No such boundary condition: type = %s',type);
621 end 625 end
626
627 penalty = cell2mat(penalty);
622 end 628 end
623 629
624 % type Struct that specifies the interface coupling. 630 % type Struct that specifies the interface coupling.
625 % Fields: 631 % Fields:
626 % -- tuning: penalty strength, defaults to 1.0 632 % -- tuning: penalty strength, defaults to 1.0
649 655
650 u = obj; 656 u = obj;
651 v = neighbour_scheme; 657 v = neighbour_scheme;
652 658
653 % Operators, u side 659 % Operators, u side
654 e_u = u.getBoundaryOperatorForScalarField('e', boundary); 660 eu_u = u.getBoundaryOperatorForScalarField('e_u', boundary);
661 es_u = u.getBoundaryOperatorForScalarField('e_s', boundary);
655 tau_u = u.getBoundaryOperator('tau', boundary); 662 tau_u = u.getBoundaryOperator('tau', boundary);
656 h11_u = u.getBorrowing(boundary);
657 nu_u = u.getNormal(boundary); 663 nu_u = u.getNormal(boundary);
658 664
659 E_u = u.E; 665 G_u = u.G;
666 U_u = u.U;
660 C_u = u.C; 667 C_u = u.C;
661 m_tot_u = u.grid.N(); 668 m_tot_u = u.N;
662 669
663 % Operators, v side 670 % Operators, v side
664 e_v = v.getBoundaryOperatorForScalarField('e', neighbour_boundary); 671 eu_v = v.getBoundaryOperatorForScalarField('e_u', neighbour_boundary);
672 es_v = v.getBoundaryOperatorForScalarField('e_s', neighbour_boundary);
665 tau_v = v.getBoundaryOperator('tau', neighbour_boundary); 673 tau_v = v.getBoundaryOperator('tau', neighbour_boundary);
666 h11_v = v.getBorrowing(neighbour_boundary);
667 nu_v = v.getNormal(neighbour_boundary); 674 nu_v = v.getNormal(neighbour_boundary);
668 675
669 E_v = v.E; 676 G_v = v.G;
677 U_v = v.U;
670 C_v = v.C; 678 C_v = v.C;
671 m_tot_v = v.grid.N(); 679 m_tot_v = v.N;
672
673 % Fix {'e', 's'}, {'w', 'n'}, and {'x','x'} couplings
674 flipFlag = false;
675 e_v_flip = e_v;
676 if (strcmp(boundary,'s') && strcmp(neighbour_boundary,'e')) || ...
677 (strcmp(boundary,'e') && strcmp(neighbour_boundary,'s')) || ...
678 (strcmp(boundary,'w') && strcmp(neighbour_boundary,'n')) || ...
679 (strcmp(boundary,'n') && strcmp(neighbour_boundary,'w')) || ...
680 (strcmp(boundary,'s') && strcmp(neighbour_boundary,'s')) || ...
681 (strcmp(boundary,'n') && strcmp(neighbour_boundary,'n')) || ...
682 (strcmp(boundary,'w') && strcmp(neighbour_boundary,'w')) || ...
683 (strcmp(boundary,'e') && strcmp(neighbour_boundary,'e'))
684
685 flipFlag = true;
686 e_v_flip = fliplr(e_v);
687
688 t1 = tau_v(:,1:2:end-1);
689 t2 = tau_v(:,2:2:end);
690
691 t1 = fliplr(t1);
692 t2 = fliplr(t2);
693
694 tau_v(:,1:2:end-1) = t1;
695 tau_v(:,2:2:end) = t2;
696 end
697 680
698 % Operators that are only required for own domain 681 % Operators that are only required for own domain
699 Hi = u.Hi_kron; 682 % Hi = u.Hi_kron;
700 RHOi = u.RHOi_kron; 683 % RHOi = u.RHOi_kron;
701 e_kron = u.getBoundaryOperator('e', boundary); 684 % e_kron = u.getBoundaryOperator('e', boundary);
685 H = u.H_u;
686 RHO = u.RHO;
702 T_u = u.getBoundaryTractionOperator(boundary); 687 T_u = u.getBoundaryTractionOperator(boundary);
703 688
704 % Shared operators 689 % Shared operators
705 H_gamma = u.getBoundaryQuadratureForScalarField(boundary); 690 H_gamma = u.getBoundaryQuadratureForScalarField(boundary);
706 H_gamma_kron = u.getBoundaryQuadrature(boundary); 691 % H_gamma_kron = u.getBoundaryQuadrature(boundary);
707 dim = u.dim; 692 dim = u.dim;
693 nGrids = obj.nGrids;
708 694
709 % Preallocate 695 % Preallocate
710 [~, m_int] = size(H_gamma); 696 % [~, m_int] = size(H_gamma);
711 closure = sparse(dim*m_tot_u, dim*m_tot_u); 697 closure = sparse(m_tot_u, m_tot_u);
712 penalty = sparse(dim*m_tot_u, dim*m_tot_v); 698 penalty = sparse(m_tot_u, m_tot_v);
713 699
714 % ---- Continuity of displacement ------ 700 %---- Grid layout -------
715 701 % gu1 = xp o yp;
716 % Y: symmetrizing part of penalty 702 % gu2 = xd o yd;
717 % Z: symmetric part of penalty 703 % gs1 = xd o yp;
718 % X = Y + Z. 704 % gs2 = xp o yd;
719 705 %------------------------
720 % Loop over components to couple across interface 706
707 switch boundary
708 case {'w', 'e'}
709 switch neighbour_boundary
710 case {'w', 'e'}
711 gridCombos = {{1,1,1}, {2,2,2}};
712 case {'s', 'n'}
713 gridCombos = {{1,1,2}, {2,2,1}};
714 end
715 case {'s', 'n'}
716 switch neighbour_boundary
717 case {'s', 'n'}
718 gridCombos = {{2,1,1}, {1,2,2}};
719 case {'w', 'e'}
720 gridCombos = {{2,1,2}, {1,2,1}};
721 end
722 end
723
724 % Symmetrizing part
725 for c = 1:nGrids
726 for m = 1:numel(gridCombos)
727 gc = gridCombos{m};
728 a = gc{1};
729 b = gc{2};
730
731 for i = 1:dim
732 for j = 1:dim
733 Y = 1/2*T_u{a,c}{j,i}';
734 closure = closure + G_u{c}*U_u{c}{i}*((RHO{c}*H{c})\(Y'*H_gamma{a}*(eu_u{b}'*U_u{b}{j}'*G_u{b}') ));
735 penalty = penalty - G_u{c}*U_u{c}{i}*((RHO{c}*H{c})\(Y'*H_gamma{a}*(eu_v{b}'*U_v{b}{j}'*G_v{b}') ));
736 end
737 end
738 end
739 end
740
741 % Symmetric part
742 for m = 1:numel(gridCombos)
743 gc = gridCombos{m};
744 a = gc{1};
745 b = gc{2};
746 bv = gc{3};
747
748 h11_u = u.getBorrowing(b, boundary);
749 h11_v = v.getBorrowing(bv, neighbour_boundary);
750
751 for i = 1:dim
752 for j = 1:dim
753 Z_u = 0*es_u{b}'*es_u{b};
754 Z_v = 0*es_v{bv}'*es_v{bv};
755 for l = 1:dim
756 for k = 1:dim
757 Z_u = Z_u + es_u{b}'*nu_u(l)*C_u{b}{l,i,k,j}*nu_u(k)*es_u{b};
758 Z_v = Z_v + es_v{bv}'*nu_v(l)*C_v{bv}{l,i,k,j}*nu_v(k)*es_v{bv};
759 end
760 end
761 Z = -tuning*dim*( 1/(4*h11_u)*Z_u + 1/(4*h11_v)*Z_v );
762 % X = es_u{b}'*Z*es_u{b};
763 % X = Z;
764 closure = closure + G_u{a}*U_u{a}{i}*((RHO{a}*H{a})\(eu_u{a}*Z'*H_gamma{b}*(eu_u{a}'*U_u{a}{j}'*G_u{a}' ) ));
765 penalty = penalty - G_u{a}*U_u{a}{i}*((RHO{a}*H{a})\(eu_u{a}*Z'*H_gamma{b}*(eu_v{a}'*U_v{a}{j}'*G_v{a}' ) ));
766 end
767 end
768 end
769
770 % Continuity of traction
721 for j = 1:dim 771 for j = 1:dim
722 772 for m = 1:numel(gridCombos)
723 % Loop over components that penalties end up on 773 gc = gridCombos{m};
724 for i = 1:dim 774 a = gc{1};
725 Y = 1/2*T_u{j,i}'; 775 b = gc{2};
726 Z_u = sparse(m_int, m_int); 776 bv = gc{3};
727 Z_v = sparse(m_int, m_int); 777 closure = closure - 1/2*G_u{a}*U_u{a}{j}*(RHO{a}\(H{a}\(eu_u{a}*H_gamma{b}*tau_u{b}{j}')));
728 for l = 1:dim 778 penalty = penalty - 1/2*G_u{a}*U_u{a}{j}*(RHO{a}\(H{a}\(eu_u{a}*H_gamma{b}*tau_v{bv}{j}')));
729 for k = 1:dim 779 end
730 Z_u = Z_u + e_u'*nu_u(l)*C_u{l,i,k,j}*nu_u(k)*e_u; 780 end
731 Z_v = Z_v + e_v'*nu_v(l)*C_v{l,i,k,j}*nu_v(k)*e_v;
732 end
733 end
734
735 if flipFlag
736 Z_v = rot90(Z_v,2);
737 end
738
739 Z = -tuning*dim*( 1/(4*h11_u)*Z_u + 1/(4*h11_v)*Z_v );
740 X = Y + Z*e_u';
741 closure = closure + E_u{i}*X'*H_gamma*e_u'*E_u{j}';
742 penalty = penalty - E_u{i}*X'*H_gamma*e_v_flip'*E_v{j}';
743
744 end
745 end
746
747 % ---- Continuity of traction ------
748 closure = closure - 1/2*e_kron*H_gamma_kron*tau_u';
749 penalty = penalty - 1/2*e_kron*H_gamma_kron*tau_v';
750
751 % ---- Multiply by inverse of density x quadraure ----
752 closure = RHOi*Hi*closure;
753 penalty = RHOi*Hi*penalty;
754 781
755 end 782 end
756 783
757 function [closure, penalty] = interfaceNonConforming(obj,boundary,neighbour_scheme,neighbour_boundary,type) 784 function [closure, penalty] = interfaceNonConforming(obj,boundary,neighbour_scheme,neighbour_boundary,type)
758 error('Non-conforming interfaces not implemented yet.'); 785 error('Non-conforming interfaces not implemented yet.');
869 896
870 H_b = obj.(['H_', boundary, '_s']); 897 H_b = obj.(['H_', boundary, '_s']);
871 end 898 end
872 899
873 function N = size(obj) 900 function N = size(obj)
874 N = obj.dim*prod(obj.m); 901 N = length(obj.D);
875 end 902 end
876 end 903 end
877 end 904 end