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