comparison +scheme/Elastic2dCurvilinear.m @ 1122:b8bd54332763 feature/poroelastic

Bugfix Elastic2dCurve
author Martin Almquist <malmquist@stanford.edu>
date Fri, 10 May 2019 15:26:47 -0700
parents 1f6b2fb69225
children 60c875c18de3
comparison
equal deleted inserted replaced
1118:07d0caf915e4 1122:b8bd54332763
1 classdef Elastic2dCurvilinear < scheme.Scheme 1 classdef Elastic2dCurvilinear < scheme.Scheme
2 2
3 % Discretizes the elastic wave equation in curvilinear coordinates. 3 % Discretizes the elastic wave equation in curvilinear coordinates.
4 % 4 %
5 % Untransformed equation: 5 % Untransformed equation:
6 % rho u_{i,tt} = di lambda dj u_j + dj mu di u_j + dj mu dj u_i 6 % rho u_{i,tt} = di lambda dj u_j + dj mu di u_j + dj mu dj u_i
7 % 7 %
8 % Transformed equation: 8 % Transformed equation:
9 % J*rho u_{i,tt} = dk J b_ik lambda b_jl dl u_j 9 % J*rho u_{i,tt} = dk J b_ik lambda b_jl dl u_j
10 % + dk J b_jk mu b_il dl u_j 10 % + dk J b_jk mu b_il dl u_j
11 % + dk J b_jk mu b_jl dl u_i 11 % + dk J b_jk mu b_jl dl u_i
12 % opSet should be cell array of opSets, one per dimension. This 12 % opSet should be cell array of opSets, one per dimension. This
13 % is useful if we have periodic BC in one direction. 13 % is useful if we have periodic BC in one direction.
14 14
15 properties 15 properties
16 m % Number of points in each direction, possibly a vector 16 m % Number of points in each direction, possibly a vector
47 gamma % Borrowing constant for d1 from M 47 gamma % Borrowing constant for d1 from M
48 H11 % First element of H 48 H11 % First element of H
49 e_l, e_r 49 e_l, e_r
50 d1_l, d1_r % Normal derivatives at the boundary 50 d1_l, d1_r % Normal derivatives at the boundary
51 E % E{i}^T picks out component i 51 E % E{i}^T picks out component i
52 52
53 H_boundary_l, H_boundary_r % Boundary inner products 53 H_boundary_l, H_boundary_r % Boundary inner products
54 54
55 % Kroneckered norms and coefficients 55 % Kroneckered norms and coefficients
56 RHOi_kron 56 RHOi_kron
57 Ji_kron, J_kron 57 Ji_kron, J_kron
143 xmax = max(ops{1}.x); 143 xmax = max(ops{1}.x);
144 ymax = max(ops{2}.x); 144 ymax = max(ops{2}.x);
145 opSetMetric{1} = sbp.D2Variable(m(1), {0, xmax}, order); 145 opSetMetric{1} = sbp.D2Variable(m(1), {0, xmax}, order);
146 opSetMetric{2} = sbp.D2Variable(m(2), {0, ymax}, order); 146 opSetMetric{2} = sbp.D2Variable(m(2), {0, ymax}, order);
147 D1Metric{1} = kron(opSetMetric{1}.D1, I{2}); 147 D1Metric{1} = kron(opSetMetric{1}.D1, I{2});
148 D1Metric{2} = kron(I{1}, opSetMetric{2}.D1); 148 D1Metric{2} = kron(I{1}, opSetMetric{2}.D1);
149 149
150 x_xi = D1Metric{1}*x; 150 x_xi = D1Metric{1}*x;
151 x_eta = D1Metric{2}*x; 151 x_eta = D1Metric{2}*x;
152 y_xi = D1Metric{1}*y; 152 y_xi = D1Metric{1}*y;
153 y_eta = D1Metric{2}*y; 153 y_eta = D1Metric{2}*y;
154 154
155 J = x_xi.*y_eta - x_eta.*y_xi; 155 J = x_xi.*y_eta - x_eta.*y_xi;
156 156
157 b = cell(dim,dim); 157 b = cell(dim,dim);
158 b{1,1} = y_eta./J; 158 b{1,1} = y_eta./J;
159 b{1,2} = -x_eta./J; 159 b{2,1} = -x_eta./J;
160 b{2,1} = -y_xi./J; 160 b{1,2} = -y_xi./J;
161 b{2,2} = x_xi./J; 161 b{2,2} = x_xi./J;
162 162
163 % Scale factors for boundary integrals 163 % Scale factors for boundary integrals
164 beta = cell(dim,1); 164 beta = cell(dim,1);
165 beta{1} = sqrt(x_eta.^2 + y_eta.^2); 165 beta{1} = sqrt(x_eta.^2 + y_eta.^2);
325 T_l{j}{i,k} = sparse(m_tot,m_tot); 325 T_l{j}{i,k} = sparse(m_tot,m_tot);
326 T_r{j}{i,k} = sparse(m_tot,m_tot); 326 T_r{j}{i,k} = sparse(m_tot,m_tot);
327 327
328 for m = 1:dim 328 for m = 1:dim
329 for l = 1:dim 329 for l = 1:dim
330 T_l{j}{i,k} = T_l{j}{i,k} + ... 330 T_l{j}{i,k} = T_l{j}{i,k} + ...
331 -d(k,l)* J*b{i,j}*b{k,m}*LAMBDA*(d(m,j)*e_l{m}*d1_l{m}' + db(m,j)*D1{m}) ... 331 -d(k,l)* J*b{i,j}*b{k,m}*LAMBDA*(d(m,j)*e_l{m}*d1_l{m}' + db(m,j)*D1{m}) ...
332 -d(k,l)* J*b{k,j}*b{i,m}*MU*(d(m,j)*e_l{m}*d1_l{m}' + db(m,j)*D1{m}) ... 332 -d(k,l)* J*b{k,j}*b{i,m}*MU*(d(m,j)*e_l{m}*d1_l{m}' + db(m,j)*D1{m}) ...
333 -d(i,k)* J*b{l,j}*b{l,m}*MU*(d(m,j)*e_l{m}*d1_l{m}' + db(m,j)*D1{m}); 333 -d(i,k)* J*b{l,j}*b{l,m}*MU*(d(m,j)*e_l{m}*d1_l{m}' + db(m,j)*D1{m});
334 334
335 T_r{j}{i,k} = T_r{j}{i,k} + ... 335 T_r{j}{i,k} = T_r{j}{i,k} + ...
336 d(k,l)* J*b{i,j}*b{k,m}*LAMBDA*(d(m,j)*e_r{m}*d1_r{m}' + db(m,j)*D1{m}) + ... 336 d(k,l)* J*b{i,j}*b{k,m}*LAMBDA*(d(m,j)*e_r{m}*d1_r{m}' + db(m,j)*D1{m}) + ...
337 d(k,l)* J*b{k,j}*b{i,m}*MU*(d(m,j)*e_r{m}*d1_r{m}' + db(m,j)*D1{m}) + ... 337 d(k,l)* J*b{k,j}*b{i,m}*MU*(d(m,j)*e_r{m}*d1_r{m}' + db(m,j)*D1{m}) + ...
338 d(i,k)* J*b{l,j}*b{l,m}*MU*(d(m,j)*e_r{m}*d1_r{m}' + db(m,j)*D1{m}); 338 d(i,k)* J*b{l,j}*b{l,m}*MU*(d(m,j)*e_r{m}*d1_r{m}' + db(m,j)*D1{m});
339 end 339 end
340 end 340 end
341 341
342 T_l{j}{i,k} = inv(beta{j})*T_l{j}{i,k}; 342 T_l{j}{i,k} = inv(beta{j})*T_l{j}{i,k};
343 T_r{j}{i,k} = inv(beta{j})*T_r{j}{i,k}; 343 T_r{j}{i,k} = inv(beta{j})*T_r{j}{i,k};
344 344
345 tau_l{j}{i} = tau_l{j}{i} + T_l{j}{i,k}*E{k}'; 345 tau_l{j}{i} = tau_l{j}{i} + T_l{j}{i,k}*E{k}';
346 tau_r{j}{i} = tau_r{j}{i} + T_r{j}{i,k}*E{k}'; 346 tau_r{j}{i} = tau_r{j}{i} + T_r{j}{i,k}*E{k}';
347 end 347 end
348 348
421 421
422 d = @kroneckerDelta; % Kronecker delta 422 d = @kroneckerDelta; % Kronecker delta
423 db = @(i,j) 1-d(i,j); % Logical not of Kronecker delta 423 db = @(i,j) 1-d(i,j); % Logical not of Kronecker delta
424 alpha = @(i,j) tuning*( d(i,j)* a_lambda*LAMBDA ... 424 alpha = @(i,j) tuning*( d(i,j)* a_lambda*LAMBDA ...
425 + d(i,j)* a_mu_i*MU ... 425 + d(i,j)* a_mu_i*MU ...
426 + db(i,j)*a_mu_ij*MU ); 426 + db(i,j)*a_mu_ij*MU );
427 427
428 % Loop over components that Dirichlet penalties end up on 428 % Loop over components that Dirichlet penalties end up on
429 for i = 1:dim 429 for i = 1:dim
430 C = T{k,i}; 430 C = T{k,i};
431 A = -d(i,k)*alpha(i,j); 431 A = -d(i,k)*alpha(i,j);
432 B = A + C; 432 B = A + C;
433 closure = closure + E{i}*RHOi*Hi*Ji*B'*e*H_gamma*(e'*E{k}' ); 433 closure = closure + E{i}*RHOi*Hi*Ji*B'*e*H_gamma*(e'*E{k}' );
434 penalty = penalty - E{i}*RHOi*Hi*Ji*B'*e*H_gamma; 434 penalty = penalty - E{i}*RHOi*Hi*Ji*B'*e*H_gamma;
435 end 435 end
436 436
437 % Free boundary condition 437 % Free boundary condition
438 case {'F','f','Free','free','traction','Traction','t','T'} 438 case {'F','f','Free','free','traction','Traction','t','T'}
439 closure = closure - E{k}*RHOi*Ji*Hi*e*H_gamma* (e'*tau{k} ); 439 closure = closure - E{k}*RHOi*Ji*Hi*e*H_gamma* (e'*tau{k} );
440 penalty = penalty + E{k}*RHOi*Ji*Hi*e*H_gamma; 440 penalty = penalty + E{k}*RHOi*Ji*Hi*e*H_gamma;
441 441
442 % Unknown boundary condition 442 % Unknown boundary condition
443 otherwise 443 otherwise
444 error('No such boundary condition: type = %s',type); 444 error('No such boundary condition: type = %s',type);
462 462
463 % Operators and quantities that correspond to the own domain only 463 % Operators and quantities that correspond to the own domain only
464 Hi = obj.Hi; 464 Hi = obj.Hi;
465 RHOi = obj.RHOi; 465 RHOi = obj.RHOi;
466 dim = obj.dim; 466 dim = obj.dim;
467 467
468 %--- Other operators ---- 468 %--- Other operators ----
469 m_tot_u = obj.grid.N(); 469 m_tot_u = obj.grid.N();
470 E = obj.E; 470 E = obj.E;
471 LAMBDA_u = obj.LAMBDA; 471 LAMBDA_u = obj.LAMBDA;
472 MU_u = obj.MU; 472 MU_u = obj.MU;
478 LAMBDA_v = neighbour_scheme.LAMBDA; 478 LAMBDA_v = neighbour_scheme.LAMBDA;
479 MU_v = neighbour_scheme.MU; 479 MU_v = neighbour_scheme.MU;
480 lambda_v = e_v'*LAMBDA_v*e_v; 480 lambda_v = e_v'*LAMBDA_v*e_v;
481 mu_v = e_v'*MU_v*e_v; 481 mu_v = e_v'*MU_v*e_v;
482 %------------------------- 482 %-------------------------
483 483
484 % Borrowing constants 484 % Borrowing constants
485 phi_u = obj.phi{j}; 485 phi_u = obj.phi{j};
486 h_u = obj.h(j); 486 h_u = obj.h(j);
487 h11_u = obj.H11{j}*h_u; 487 h11_u = obj.H11{j}*h_u;
488 gamma_u = obj.gamma{j}; 488 gamma_u = obj.gamma{j};
491 h_v = neighbour_scheme.h(j_v); 491 h_v = neighbour_scheme.h(j_v);
492 h11_v = neighbour_scheme.H11{j_v}*h_v; 492 h11_v = neighbour_scheme.H11{j_v}*h_v;
493 gamma_v = neighbour_scheme.gamma{j_v}; 493 gamma_v = neighbour_scheme.gamma{j_v};
494 494
495 % E > sum_i 1/(2*alpha_ij)*(tau_i)^2 495 % E > sum_i 1/(2*alpha_ij)*(tau_i)^2
496 function [alpha_ii, alpha_ij] = computeAlpha(phi,h,h11,gamma,lambda,mu) 496 function [alpha_ii, alpha_ij] = computeAlpha(phi,h,h11,gamma,lambda,mu)
497 th1 = h11/(2*dim); 497 th1 = h11/(2*dim);
498 th2 = h11*phi/2; 498 th2 = h11*phi/2;
499 th3 = h*gamma; 499 th3 = h*gamma;
500 a1 = ( (th1 + th2)*th3*lambda + 4*th1*th2*mu ) / (2*th1*th2*th3); 500 a1 = ( (th1 + th2)*th3*lambda + 4*th1*th2*mu ) / (2*th1*th2*th3);
501 a2 = ( 16*(th1 + th2)*lambda*mu ) / (th1*th2*th3); 501 a2 = ( 16*(th1 + th2)*lambda*mu ) / (th1*th2*th3);
503 503
504 alpha_ij = mu*(2/h11 + 1/(phi*h11)); 504 alpha_ij = mu*(2/h11 + 1/(phi*h11));
505 end 505 end
506 506
507 [alpha_ii_u, alpha_ij_u] = computeAlpha(phi_u,h_u,h11_u,gamma_u,lambda_u,mu_u); 507 [alpha_ii_u, alpha_ij_u] = computeAlpha(phi_u,h_u,h11_u,gamma_u,lambda_u,mu_u);
508 [alpha_ii_v, alpha_ij_v] = computeAlpha(phi_v,h_v,h11_v,gamma_v,lambda_v,mu_v); 508 [alpha_ii_v, alpha_ij_v] = computeAlpha(phi_v,h_v,h11_v,gamma_v,lambda_v,mu_v);
509 sigma_ii = tuning*(alpha_ii_u + alpha_ii_v)/4; 509 sigma_ii = tuning*(alpha_ii_u + alpha_ii_v)/4;
510 sigma_ij = tuning*(alpha_ij_u + alpha_ij_v)/4; 510 sigma_ij = tuning*(alpha_ij_u + alpha_ij_v)/4;
511 511
512 d = @kroneckerDelta; % Kronecker delta 512 d = @kroneckerDelta; % Kronecker delta
513 db = @(i,j) 1-d(i,j); % Logical not of Kronecker delta 513 db = @(i,j) 1-d(i,j); % Logical not of Kronecker delta
525 closure = closure - 1/2*E{i}*RHOi*Hi*e*H_gamma*e'*tau{i}; 525 closure = closure - 1/2*E{i}*RHOi*Hi*e*H_gamma*e'*tau{i};
526 penalty = penalty - 1/2*E{i}*RHOi*Hi*e*H_gamma*e_v'*tau_v{i}; 526 penalty = penalty - 1/2*E{i}*RHOi*Hi*e*H_gamma*e_v'*tau_v{i};
527 527
528 % Loop over components that we have interface conditions on 528 % Loop over components that we have interface conditions on
529 for k = 1:dim 529 for k = 1:dim
530 closure = closure + 1/2*E{i}*RHOi*Hi*T{k,i}'*e*H_gamma*e'*E{k}'; 530 closure = closure + 1/2*E{i}*RHOi*Hi*T{k,i}'*e*H_gamma*e'*E{k}';
531 penalty = penalty - 1/2*E{i}*RHOi*Hi*T{k,i}'*e*H_gamma*e_v'*E_v{k}'; 531 penalty = penalty - 1/2*E{i}*RHOi*Hi*T{k,i}'*e*H_gamma*e_v'*E_v{k}';
532 end 532 end
533 end 533 end
534 end 534 end
535 535
536 % Returns the coordinate number and outward normal component for the boundary specified by the string boundary. 536 % Returns the coordinate number and outward normal component for the boundary specified by the string boundary.
537 function [j, nj] = get_boundary_number(obj, boundary) 537 function [j, nj] = get_boundary_number(obj, boundary)
585 varargout{i} = obj.d1_l{j}; 585 varargout{i} = obj.d1_l{j};
586 case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'} 586 case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'}
587 varargout{i} = obj.d1_r{j}; 587 varargout{i} = obj.d1_r{j};
588 end 588 end
589 case 'H' 589 case 'H'
590 switch boundary 590 switch boundary
591 case {'w','W','west','West','s','S','south','South'} 591 case {'w','W','west','West','s','S','south','South'}
592 varargout{i} = obj.H_boundary_l{j}; 592 varargout{i} = obj.H_boundary_l{j};
593 case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'} 593 case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'}
594 varargout{i} = obj.H_boundary_r{j}; 594 varargout{i} = obj.H_boundary_r{j};
595 end 595 end
604 switch boundary 604 switch boundary
605 case {'w','W','west','West','s','S','south','South'} 605 case {'w','W','west','West','s','S','south','South'}
606 varargout{i} = obj.tau_l{j}; 606 varargout{i} = obj.tau_l{j};
607 case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'} 607 case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'}
608 varargout{i} = obj.tau_r{j}; 608 varargout{i} = obj.tau_r{j};
609 end 609 end
610 otherwise 610 otherwise
611 error(['No such operator: operator = ' op{i}]); 611 error(['No such operator: operator = ' op{i}]);
612 end 612 end
613 end 613 end
614 614