Mercurial > repos > public > sbplib
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 |