comparison +scheme/Elastic2dCurvilinearAnisotropic.m @ 1291:a8e730db76e9 feature/poroelastic

Add normal-tangential traction BC ElasticCurvilinearAnisotropic
author Martin Almquist <malmquist@stanford.edu>
date Mon, 29 Jun 2020 15:23:01 -0700
parents 15865fbda16e
children fe712a1fca3f
comparison
equal deleted inserted replaced
1281:01a0500de446 1291:a8e730db76e9
24 D % Total operator 24 D % Total operator
25 25
26 Dx, Dy % Physical derivatives 26 Dx, Dy % Physical derivatives
27 sigma % Cell matrix of physical stress operators 27 sigma % Cell matrix of physical stress operators
28 n_w, n_e, n_s, n_n % Physical normals 28 n_w, n_e, n_s, n_n % Physical normals
29 tangent_w, tangent_e, tangent_s, tangent_n % Physical tangents
29 30
30 % Boundary operators in cell format, used for BC 31 % Boundary operators in cell format, used for BC
31 T_w, T_e, T_s, T_n 32 T_w, T_e, T_s, T_n
32 33
33 % Traction operators 34 % Traction operators
48 e_w, e_e, e_s, e_n % Act on vector field, return vector field at boundary 49 e_w, e_e, e_s, e_n % Act on vector field, return vector field at boundary
49 e1_w, e1_e, e1_s, e1_n % Act on vector field, return scalar field at boundary 50 e1_w, e1_e, e1_s, e1_n % Act on vector field, return scalar field at boundary
50 e2_w, e2_e, e2_s, e2_n % Act on vector field, return scalar field at boundary 51 e2_w, e2_e, e2_s, e2_n % Act on vector field, return scalar field at boundary
51 e_scalar_w, e_scalar_e, e_scalar_s, e_scalar_n; % Act on scalar field, return scalar field 52 e_scalar_w, e_scalar_e, e_scalar_s, e_scalar_n; % Act on scalar field, return scalar field
52 en_w, en_e, en_s, en_n % Act on vector field, return normal component 53 en_w, en_e, en_s, en_n % Act on vector field, return normal component
54 et_w, et_e, et_s, et_n % Act on vector field, return tangential component
53 55
54 % E{i}^T picks out component i 56 % E{i}^T picks out component i
55 E 57 E
56 58
57 % Elastic2dVariableAnisotropic object for reference domain 59 % Elastic2dVariableAnisotropic object for reference domain
278 obj.n_w = cell(2,1); 280 obj.n_w = cell(2,1);
279 obj.n_e = cell(2,1); 281 obj.n_e = cell(2,1);
280 obj.n_s = cell(2,1); 282 obj.n_s = cell(2,1);
281 obj.n_n = cell(2,1); 283 obj.n_n = cell(2,1);
282 284
285 % Compute normal and rotate (exactly!) 90 degrees counter-clockwise to get tangent
283 n_w_1 = (1./s_w).*e_w'*(J.*(K{1,1}*nu_w(1) + K{1,2}*nu_w(2))); 286 n_w_1 = (1./s_w).*e_w'*(J.*(K{1,1}*nu_w(1) + K{1,2}*nu_w(2)));
284 n_w_2 = (1./s_w).*e_w'*(J.*(K{2,1}*nu_w(1) + K{2,2}*nu_w(2))); 287 n_w_2 = (1./s_w).*e_w'*(J.*(K{2,1}*nu_w(1) + K{2,2}*nu_w(2)));
285 obj.n_w{1} = spdiag(n_w_1); 288 obj.n_w{1} = spdiag(n_w_1);
286 obj.n_w{2} = spdiag(n_w_2); 289 obj.n_w{2} = spdiag(n_w_2);
290 obj.tangent_w = {-obj.n_w{2}, obj.n_w{1}};
287 291
288 n_e_1 = (1./s_e).*e_e'*(J.*(K{1,1}*nu_e(1) + K{1,2}*nu_e(2))); 292 n_e_1 = (1./s_e).*e_e'*(J.*(K{1,1}*nu_e(1) + K{1,2}*nu_e(2)));
289 n_e_2 = (1./s_e).*e_e'*(J.*(K{2,1}*nu_e(1) + K{2,2}*nu_e(2))); 293 n_e_2 = (1./s_e).*e_e'*(J.*(K{2,1}*nu_e(1) + K{2,2}*nu_e(2)));
290 obj.n_e{1} = spdiag(n_e_1); 294 obj.n_e{1} = spdiag(n_e_1);
291 obj.n_e{2} = spdiag(n_e_2); 295 obj.n_e{2} = spdiag(n_e_2);
296 obj.tangent_e = {-obj.n_e{2}, obj.n_e{1}};
292 297
293 n_s_1 = (1./s_s).*e_s'*(J.*(K{1,1}*nu_s(1) + K{1,2}*nu_s(2))); 298 n_s_1 = (1./s_s).*e_s'*(J.*(K{1,1}*nu_s(1) + K{1,2}*nu_s(2)));
294 n_s_2 = (1./s_s).*e_s'*(J.*(K{2,1}*nu_s(1) + K{2,2}*nu_s(2))); 299 n_s_2 = (1./s_s).*e_s'*(J.*(K{2,1}*nu_s(1) + K{2,2}*nu_s(2)));
295 obj.n_s{1} = spdiag(n_s_1); 300 obj.n_s{1} = spdiag(n_s_1);
296 obj.n_s{2} = spdiag(n_s_2); 301 obj.n_s{2} = spdiag(n_s_2);
302 obj.tangent_s = {-obj.n_s{2}, obj.n_s{1}};
297 303
298 n_n_1 = (1./s_n).*e_n'*(J.*(K{1,1}*nu_n(1) + K{1,2}*nu_n(2))); 304 n_n_1 = (1./s_n).*e_n'*(J.*(K{1,1}*nu_n(1) + K{1,2}*nu_n(2)));
299 n_n_2 = (1./s_n).*e_n'*(J.*(K{2,1}*nu_n(1) + K{2,2}*nu_n(2))); 305 n_n_2 = (1./s_n).*e_n'*(J.*(K{2,1}*nu_n(1) + K{2,2}*nu_n(2)));
300 obj.n_n{1} = spdiag(n_n_1); 306 obj.n_n{1} = spdiag(n_n_1);
301 obj.n_n{2} = spdiag(n_n_2); 307 obj.n_n{2} = spdiag(n_n_2);
308 obj.tangent_n = {-obj.n_n{2}, obj.n_n{1}};
302 309
303 % Operators that extract the normal component 310 % Operators that extract the normal component
304 obj.en_w = (obj.n_w{1}*obj.e1_w' + obj.n_w{2}*obj.e2_w')'; 311 obj.en_w = (obj.n_w{1}*obj.e1_w' + obj.n_w{2}*obj.e2_w')';
305 obj.en_e = (obj.n_e{1}*obj.e1_e' + obj.n_e{2}*obj.e2_e')'; 312 obj.en_e = (obj.n_e{1}*obj.e1_e' + obj.n_e{2}*obj.e2_e')';
306 obj.en_s = (obj.n_s{1}*obj.e1_s' + obj.n_s{2}*obj.e2_s')'; 313 obj.en_s = (obj.n_s{1}*obj.e1_s' + obj.n_s{2}*obj.e2_s')';
307 obj.en_n = (obj.n_n{1}*obj.e1_n' + obj.n_n{2}*obj.e2_n')'; 314 obj.en_n = (obj.n_n{1}*obj.e1_n' + obj.n_n{2}*obj.e2_n')';
315
316 % Operators that extract the tangential component
317 obj.et_w = (obj.tangent_w{1}*obj.e1_w' + obj.tangent_w{2}*obj.e2_w')';
318 obj.et_e = (obj.tangent_e{1}*obj.e1_e' + obj.tangent_e{2}*obj.e2_e')';
319 obj.et_s = (obj.tangent_s{1}*obj.e1_s' + obj.tangent_s{2}*obj.e2_s')';
320 obj.et_n = (obj.tangent_n{1}*obj.e1_n' + obj.tangent_n{2}*obj.e2_n')';
308 321
309 % Stress operators 322 % Stress operators
310 sigma = cell(dim, dim); 323 sigma = cell(dim, dim);
311 D1 = {obj.Dx, obj.Dy}; 324 D1 = {obj.Dx, obj.Dy};
312 E = obj.E; 325 E = obj.E;
352 % In this way, we can specify one BC at a time even though the SATs depend on all BC. 365 % In this way, we can specify one BC at a time even though the SATs depend on all BC.
353 function [closure, penalty] = boundary_condition(obj, boundary, bc, tuning) 366 function [closure, penalty] = boundary_condition(obj, boundary, bc, tuning)
354 default_arg('tuning', 1.0); 367 default_arg('tuning', 1.0);
355 assert( iscell(bc), 'The BC type must be a 2x1 or 3x1 cell array' ); 368 assert( iscell(bc), 'The BC type must be a 2x1 or 3x1 cell array' );
356 369
357 [closure, penalty] = obj.refObj.boundary_condition(boundary, bc, tuning); 370 component = bc{1};
358
359 type = bc{2}; 371 type = bc{2};
372
373 switch component
374
375 % If conditions on Cartesian components
376 case {1,2}
377 [closure, penalty] = obj.refObj.boundary_condition(boundary, bc, tuning);
378
379 % If conditions on normal or tangential components
380 case {'n', 't'}
381
382 switch component
383 case 'n'
384 en = obj.getBoundaryOperator('en', boundary);
385 case 't'
386 en = obj.getBoundaryOperator('et', boundary);
387 end
388 e1 = obj.getBoundaryOperator('e1', boundary);
389
390 bc = {1, type};
391 [c1, p1] = obj.refObj.boundary_condition(boundary, bc, tuning);
392 bc = {2, type};
393 c2 = obj.refObj.boundary_condition(boundary, bc, tuning);
394
395 switch type
396 case {'F','f','Free','free','traction','Traction','t','T'}
397 closure = en*en'*(c1+c2);
398 penalty = en*e1'*p1;
399 case {'D','d','dirichlet','Dirichlet','displacement','Displacement'}
400 error('Not implemented');
401 end
402
403 end
360 404
361 switch type 405 switch type
362 case {'F','f','Free','free','traction','Traction','t','T'} 406 case {'F','f','Free','free','traction','Traction','t','T'}
407
363 s = obj.(['s_' boundary]); 408 s = obj.(['s_' boundary]);
364 s = spdiag(s); 409 s = spdiag(s);
365 penalty = penalty*s; 410 penalty = penalty*s;
411
366 end 412 end
367 end 413 end
368 414
369 % type Struct that specifies the interface coupling. 415 % type Struct that specifies the interface coupling.
370 % Fields: 416 % Fields:
402 448
403 % Returns the boundary operator op for the boundary specified by the string boundary. 449 % Returns the boundary operator op for the boundary specified by the string boundary.
404 % op -- string 450 % op -- string
405 function o = getBoundaryOperator(obj, op, boundary) 451 function o = getBoundaryOperator(obj, op, boundary)
406 assertIsMember(boundary, {'w', 'e', 's', 'n'}) 452 assertIsMember(boundary, {'w', 'e', 's', 'n'})
407 assertIsMember(op, {'e', 'e1', 'e2', 'tau', 'tau1', 'tau2', 'en'}) 453 assertIsMember(op, {'e', 'e1', 'e2', 'tau', 'tau1', 'tau2', 'en', 'et'})
408 454
409 o = obj.([op, '_', boundary]); 455 o = obj.([op, '_', boundary]);
410 456
411 end 457 end
412 458