Mercurial > repos > public > sbplib
comparison +scheme/elasticVariable.m @ 679:247b58a4dbe8 feature/poroelastic
Add support for Dirichlet and Traction BC on different components at the same boundary. Remove some unused variables and improve comments.
author | Martin Almquist <malmquist@stanford.edu> |
---|---|
date | Mon, 05 Feb 2018 14:45:26 -0800 |
parents | 06676c40e77f |
children | b035902869a8 |
comparison
equal
deleted
inserted
replaced
678:06676c40e77f | 679:247b58a4dbe8 |
---|---|
1 classdef elasticVariable < scheme.Scheme | 1 classdef elasticVariable < scheme.Scheme |
2 | 2 |
3 % Discretizes the elastic wave equation: | 3 % Discretizes the elastic wave equation: |
4 % rho u_{i,tt} = di lambda dj u_j + dj mu di u_j + dj mu dj u_i | 4 % rho u_{i,tt} = di lambda dj u_j + dj mu di u_j + dj mu dj u_i |
5 | |
6 | 5 |
7 properties | 6 properties |
8 m % Number of points in each direction, possibly a vector | 7 m % Number of points in each direction, possibly a vector |
9 h % Grid spacing | 8 h % Grid spacing |
10 | 9 |
14 order % Order of accuracy for the approximation | 13 order % Order of accuracy for the approximation |
15 | 14 |
16 % Diagonal matrices for varible coefficients | 15 % Diagonal matrices for varible coefficients |
17 LAMBDA % Variable coefficient, related to dilation | 16 LAMBDA % Variable coefficient, related to dilation |
18 MU % Shear modulus, variable coefficient | 17 MU % Shear modulus, variable coefficient |
19 RHO, RHOi % Density | 18 RHO, RHOi % Density, variable |
20 | 19 |
21 D % Total operator | 20 D % Total operator |
22 D1 % First derivatives | 21 D1 % First derivatives |
23 | 22 |
24 % Second derivatives | 23 % Second derivatives |
29 T_l, T_r | 28 T_l, T_r |
30 tau_l, tau_r | 29 tau_l, tau_r |
31 | 30 |
32 H, Hi % Inner products | 31 H, Hi % Inner products |
33 phi % Borrowing constant for (d1 - e^T*D1) from R | 32 phi % Borrowing constant for (d1 - e^T*D1) from R |
33 gamma % Borrowing constant for d1 from M | |
34 H11 % First element of H | 34 H11 % First element of H |
35 e_l, e_r | 35 e_l, e_r |
36 d1_l, d1_r % Normal derivatives at the boundary | 36 d1_l, d1_r % Normal derivatives at the boundary |
37 E % E{i}^T picks out component i | 37 E % E{i}^T picks out component i |
38 | 38 |
39 H_boundary % Boundary inner products | 39 H_boundary % Boundary inner products |
40 | 40 |
41 LAMBDA_boundary_l % Variable coefficients at boundaries | |
42 LAMBDA_boundary_r | |
43 MU_boundary_l | |
44 MU_boundary_r | |
45 | |
46 % Kroneckered norms and coefficients | 41 % Kroneckered norms and coefficients |
47 RHOi_kron | 42 RHOi_kron |
48 Hi_kron | 43 Hi_kron |
49 end | 44 end |
50 | 45 |
51 methods | 46 methods |
52 % Implements the shear part of the elastic wave equation, i.e. | |
53 % rho u_{i,tt} = d_i a d_j u_j + d_j a d_j u_i | |
54 % where a = mu. | |
55 | 47 |
56 function obj = elasticVariable(g ,order, lambda_fun, mu_fun, rho_fun, opSet) | 48 function obj = elasticVariable(g ,order, lambda_fun, mu_fun, rho_fun, opSet) |
57 default_arg('opSet',@sbp.D2Variable); | 49 default_arg('opSet',@sbp.D2Variable); |
58 default_arg('lambda_fun', @(x,y) 0*x+1); | 50 default_arg('lambda_fun', @(x,y) 0*x+1); |
59 default_arg('mu_fun', @(x,y) 0*x+1); | 51 default_arg('mu_fun', @(x,y) 0*x+1); |
79 | 71 |
80 % Borrowing constants | 72 % Borrowing constants |
81 beta = ops{1}.borrowing.R.delta_D; | 73 beta = ops{1}.borrowing.R.delta_D; |
82 obj.H11 = ops{1}.borrowing.H11; | 74 obj.H11 = ops{1}.borrowing.H11; |
83 obj.phi = beta/obj.H11; | 75 obj.phi = beta/obj.H11; |
76 obj.gamma = ops{1}.borrowing.M.d1; | |
84 | 77 |
85 I = cell(dim,1); | 78 I = cell(dim,1); |
86 D1 = cell(dim,1); | 79 D1 = cell(dim,1); |
87 D2 = cell(dim,1); | 80 D2 = cell(dim,1); |
88 H = cell(dim,1); | 81 H = cell(dim,1); |
165 obj.H = kron(H{1},H{2}); | 158 obj.H = kron(H{1},H{2}); |
166 obj.Hi = inv(obj.H); | 159 obj.Hi = inv(obj.H); |
167 obj.H_boundary = cell(dim,1); | 160 obj.H_boundary = cell(dim,1); |
168 obj.H_boundary{1} = H{2}; | 161 obj.H_boundary{1} = H{2}; |
169 obj.H_boundary{2} = H{1}; | 162 obj.H_boundary{2} = H{1}; |
170 | |
171 % Boundary coefficient matrices | |
172 obj.LAMBDA_boundary_l = cell(dim,1); | |
173 obj.LAMBDA_boundary_r = cell(dim,1); | |
174 obj.MU_boundary_l = cell(dim,1); | |
175 obj.MU_boundary_r = cell(dim,1); | |
176 for i = 1:dim | |
177 obj.LAMBDA_boundary_l{i} = obj.e_l{i}'*LAMBDA*obj.e_l{i}; | |
178 obj.LAMBDA_boundary_r{i} = obj.e_r{i}'*LAMBDA*obj.e_r{i}; | |
179 obj.MU_boundary_l{i} = obj.e_l{i}'*MU*obj.e_l{i}; | |
180 obj.MU_boundary_r{i} = obj.e_r{i}'*MU*obj.e_r{i}; | |
181 end | |
182 | 163 |
183 % E{i}^T picks out component i. | 164 % E{i}^T picks out component i. |
184 E = cell(dim,1); | 165 E = cell(dim,1); |
185 I = speye(m_tot,m_tot); | 166 I = speye(m_tot,m_tot); |
186 for i = 1:dim | 167 for i = 1:dim |
275 | 256 |
276 | 257 |
277 % Closure functions return the operators applied to the own domain to close the boundary | 258 % Closure functions return the operators applied to the own domain to close the boundary |
278 % Penalty functions return the operators to force the solution. In the case of an interface it returns the operator applied to the other doamin. | 259 % Penalty functions return the operators to force the solution. In the case of an interface it returns the operator applied to the other doamin. |
279 % boundary is a string specifying the boundary e.g. 'l','r' or 'e','w','n','s'. | 260 % boundary is a string specifying the boundary e.g. 'l','r' or 'e','w','n','s'. |
280 % type is a string specifying the type of boundary condition if there are several. | 261 % type is a cell array of strings specifying the type of boundary condition for each component. |
281 % data is a function returning the data that should be applied at the boundary. | 262 % data is a function returning the data that should be applied at the boundary. |
282 % neighbour_scheme is an instance of Scheme that should be interfaced to. | 263 % neighbour_scheme is an instance of Scheme that should be interfaced to. |
283 % neighbour_boundary is a string specifying which boundary to interface to. | 264 % neighbour_boundary is a string specifying which boundary to interface to. |
284 function [closure, penalty] = boundary_condition(obj, boundary, type, parameter) | 265 function [closure, penalty] = boundary_condition(obj, boundary, type, parameter) |
285 default_arg('type','free'); | 266 default_arg('type',{'free','free'}); |
286 default_arg('parameter', []); | 267 default_arg('parameter', []); |
287 | 268 |
288 % j is the coordinate direction of the boundary | 269 % j is the coordinate direction of the boundary |
289 % nj: outward unit normal component. | 270 % nj: outward unit normal component. |
290 % nj = -1 for west, south, bottom boundaries | 271 % nj = -1 for west, south, bottom boundaries |
308 H_gamma = obj.H_boundary{j}; | 289 H_gamma = obj.H_boundary{j}; |
309 LAMBDA = obj.LAMBDA; | 290 LAMBDA = obj.LAMBDA; |
310 MU = obj.MU; | 291 MU = obj.MU; |
311 RHOi = obj.RHOi; | 292 RHOi = obj.RHOi; |
312 | 293 |
313 phi = obj.phi; | |
314 H11 = obj.H11; | |
315 h = obj.h; | |
316 dim = obj.dim; | 294 dim = obj.dim; |
317 m_tot = obj.grid.N(); | 295 m_tot = obj.grid.N(); |
318 | 296 |
319 RHOi_kron = obj.RHOi_kron; | 297 RHOi_kron = obj.RHOi_kron; |
320 Hi_kron = obj.Hi_kron; | 298 Hi_kron = obj.Hi_kron; |
321 | 299 |
300 % Preallocate | |
322 closure = sparse(dim*m_tot, dim*m_tot); | 301 closure = sparse(dim*m_tot, dim*m_tot); |
323 penalty = cell(dim,1); | 302 penalty = cell(dim,1); |
324 switch type | 303 for k = 1:dim |
304 penalty{k} = sparse(dim*m_tot, m_tot/obj.m(j)); | |
305 end | |
306 | |
307 % Loop over components that we (potentially) have different BC on | |
308 for k = 1:dim | |
309 switch type{k} | |
310 | |
325 % Dirichlet boundary condition | 311 % Dirichlet boundary condition |
326 case {'D','d','dirichlet'} | 312 case {'D','d','dirichlet','Dirichlet'} |
327 error('not implemented') | 313 |
328 tuning = 1.2; | 314 tuning = 1.2; |
329 phi = obj.phi; | 315 phi = obj.phi; |
330 | 316 h = obj.h(j); |
331 sigma = tuning * obj.dim/(H11*h(j)) +... | 317 h11 = obj.H11*h; |
332 tuning * 1/(H11*h(j)*phi); | 318 gamma = obj.gamma; |
333 | 319 |
334 closure = - sigma*E{j}*RHOi*Hi*A*e{j}*H_gamma*e{j}'*E{j}' ... | 320 a_lambda = dim/h11 + 1/(h11*phi); |
335 + nj*RHOi_kron*Hi_kron*Div'*A*e{j}*H_gamma*e{j}'*E{j}'; | 321 a_mu_i = 2/(gamma*h); |
336 | 322 a_mu_ij = 2/h11 + 1/(h11*phi); |
337 penalty = + sigma*E{j}*RHOi*Hi*A*e{j}*H_gamma ... | 323 |
338 - nj*RHOi_kron*Hi_kron*Div'*A*e{j}*H_gamma; | 324 d = @kroneckerDelta; % Kronecker delta |
325 db = @(i,j) 1-d(i,j); % Logical not of Kronecker delta | |
326 alpha = @(i,j) tuning*( d(i,j)* a_lambda*LAMBDA ... | |
327 + d(i,j)* a_mu_i*MU ... | |
328 + db(i,j)*a_mu_ij*MU ); | |
329 | |
330 % Loop over components that Dirichlet penalties end up on | |
331 for i = 1:dim | |
332 C = T{k,i}; | |
333 A = -d(i,k)*alpha(i,j); | |
334 B = A + C; | |
335 closure = closure + E{i}*RHOi*Hi*B'*e{j}*H_gamma*(e{j}'*E{k}' ); | |
336 penalty{k} = penalty{k} - E{i}*RHOi*Hi*B'*e{j}*H_gamma; | |
337 end | |
339 | 338 |
340 % Free boundary condition | 339 % Free boundary condition |
341 case {'F','f','Free','free'} | 340 case {'F','f','Free','free','traction','Traction','t','T'} |
342 | 341 closure = closure - E{k}*RHOi*Hi*e{j}*H_gamma* (e{j}'*tau{k} ); |
343 % Loop over components of traction | 342 penalty{k} = penalty{k} + E{k}*RHOi*Hi*e{j}*H_gamma; |
344 for i = 1:dim | |
345 closure = closure - E{i}*RHOi*Hi*e{j}*H_gamma* (e{j}'*tau{i} ); | |
346 penalty{i} = E{i}*RHOi*Hi*e{j}*H_gamma; | |
347 end | |
348 | |
349 | 343 |
350 % Unknown boundary condition | 344 % Unknown boundary condition |
351 otherwise | 345 otherwise |
352 error('No such boundary condition: type = %s',type); | 346 error('No such boundary condition: type = %s',type); |
347 end | |
353 end | 348 end |
354 end | 349 end |
355 | 350 |
356 function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary) | 351 function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary) |
357 % u denotes the solution in the own domain | 352 % u denotes the solution in the own domain |