changeset 1346:464e6f65c2c6 feature/poroelastic

Refactor computation of borrowing from C. Update to correct number of boundary points for borrowing from R.
author Martin Almquist <martin.almquist@it.uu.se>
date Tue, 30 Apr 2024 14:18:47 +0200
parents 14f44e81e1e3
children ac54767ae1fb
files +scheme/Elastic2dVariableAnisotropicIncompatible.m
diffstat 1 files changed, 67 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- a/+scheme/Elastic2dVariableAnisotropicIncompatible.m	Tue Apr 30 13:33:39 2024 +0200
+++ b/+scheme/Elastic2dVariableAnisotropicIncompatible.m	Tue Apr 30 14:18:47 2024 +0200
@@ -50,7 +50,7 @@
         h11 % First entry in norm matrix
         theta_R % Borrowing from R
 
-        nBP % Number of boundary points, related to borrowing.
+        nBP_R % Number of boundary points in R, related to borrowing from R.
         e_shifted_scalar_w, e_shifted_scalar_e, e_shifted_scalar_s, e_shifted_scalar_n; % Act on scalar field, return scalar field
 
     end
@@ -124,12 +124,15 @@
             case 2
                 width = 3;
                 nBP = 2;
+                nBP_R = 2;
             case 4
                 width = 5;
                 nBP = 6;
+                nBP_R = 4;
             case 6
                 width = 7;
                 nBP = 9;
+                nBP_R = 7;
             end
 
             I = cell(dim,1);
@@ -187,11 +190,11 @@
             e_n = kron(e_scalar_n, I_dim);
 
             % Boundary restriction, shifted up to nBP-1 points
-            e_shifted_scalar_w = cell(nBP, 1);
-            e_shifted_scalar_e = cell(nBP, 1);
-            e_shifted_scalar_s = cell(nBP, 1);
-            e_shifted_scalar_n = cell(nBP, 1);
-            for i = 1:nBP-1
+            e_shifted_scalar_w = cell(nBP_R, 1);
+            e_shifted_scalar_e = cell(nBP_R, 1);
+            e_shifted_scalar_s = cell(nBP_R, 1);
+            e_shifted_scalar_n = cell(nBP_R, 1);
+            for i = 1:nBP_R-1
                 e_0_nBP = {0*e_0{1}, 0*e_0{2}};
                 e_m_nBP = {0*e_m{1}, 0*e_m{2}};
                 e_0_nBP{1}(i) = 1;
@@ -407,7 +410,7 @@
             obj.order = order;
             obj.grid = g;
             obj.dim = dim;
-            obj.nBP = nBP;
+            obj.nBP_R = nBP_R;
 
         end
 
@@ -429,7 +432,7 @@
         % dComps = vector of components with displacement BC. Default: 1:dim.
         % In this way, we can specify one BC at a time even though the SATs depend on all BC.
         function [closure, penalty] = boundary_condition(obj, boundary, bc, tuning)
-            default_arg('tuning', 1.0);
+            default_arg('tuning', 1.2);
 
             assert( iscell(bc), 'The BC type must be a 2x1 or 3x1 cell array' );
             comp = bc{1};
@@ -439,7 +442,6 @@
             end
 
             e           = obj.getBoundaryOperatorForScalarField('e', boundary);
-            e_sh        = obj.getBoundaryOperatorForScalarField('e_shifted', boundary);
             tau         = obj.getBoundaryOperator(['tau' num2str(comp)], boundary);
             T           = obj.getBoundaryTractionOperator(boundary);
             [h11, th_R] = obj.getBorrowing(boundary);
@@ -487,54 +489,11 @@
 
                 % Symmetric part only required on components with displacement BC.
                 % (Otherwise it's not symmetric.)
-
-                % 1. Compute beta such that C_bJbL_boundary - \beta*C_bJbL_i >= 0, i = 0, 1, ..., nBP.
-                [~, N] = size(e);
-                beta_vec = ones(N, 1);
-                b = obj.getComponent('normal', boundary);
-                C_boundary = cell(dim, dim, dim, dim);
-                for i = 1:dim
-                    for j = 1:dim
-                        for k = 1:dim
-                            for l = 1:dim
-                                C_boundary{i,j,k,l} = e'*C{i,j,k,l}*e ;
-                            end
-                        end
-                    end
-                end
-
-                % Loop over shift inward from boundary
-                for m = 1:obj.nBP-1
-                    C_shifted = cell(dim, dim, dim, dim);
-                    for i = 1:dim
-                        for j = 1:dim
-                            for k = 1:dim
-                                for l = 1:dim
-                                    C_shifted{i,j,k,l} = e_sh{m}'*C{i,j,k,l}*e_sh{m};
-                                end
-                            end
-                        end
-                    end
-
-                    % Loop along boundary
-                    for i = 1:N
-                        C_boundary_mat = [C_boundary{b,1,b,1}(i,i), C_boundary{b,1,b,2}(i,i); ...
-                                          C_boundary{b,2,b,1}(i,i), C_boundary{b,2,b,2}(i,i)];
-                                          
-                        C_shifted_mat = [C_shifted{b,1,b,1}(i,i), C_shifted{b,1,b,2}(i,i); ...
-                                          C_shifted{b,2,b,1}(i,i), C_shifted{b,2,b,2}(i,i)];
-
-                        beta = obj.computeBorrowingFromC(C_boundary_mat, C_shifted_mat);
-                        beta_vec(i) = min(beta_vec(i), beta);
-                    end
-                end
-                if min(beta_vec) < 1e-10
-                    disp('WARNING! No borrowing from C seems to be possible.')
-                    disp(['min(beta) = ' num2str(min(beta_vec))])
-                end
+                beta_vec = obj.computeBorrowingFromC(boundary);
                 beta_inv = e*spdiag(1./beta_vec)*e'; 
                 
                 % Compensate at corners
+                [~, N] = size(e);
                 corner_weight = ones(N, 1);
                 corner_weight(1) = 2;
                 corner_weight(end) = 2;
@@ -550,7 +509,7 @@
                             Z = Z + nu(l)*C{l,i,k,j}*nu(k);
                         end
                     end
-                    Z = -1.2*tuning*(corner_weight/h11 + beta_inv/th_R)*Z;
+                    Z = -tuning*(corner_weight/h11 + beta_inv/th_R)*Z;
                     X = Z;
                     closure = closure + E{i}*RHOi*Hi*X'*e*H_gamma*(e'*E{j}' );
                     penalty = penalty - E{i}*RHOi*Hi*X'*e*H_gamma;
@@ -705,7 +664,7 @@
         end
 
         % Computes the largest beta such that C_b - beta*C_s >= 0, using bisection.
-        function beta = computeBorrowingFromC(obj, C_b, C_s)
+        function beta = borrowingBisection(obj, C_b, C_s)
             tol = 1e-8;
             beta_min = 0;
             beta_max = 1;
@@ -725,6 +684,58 @@
             end
         end
 
+        % Computes largest beta such that C_bJbL_boundary - \beta*C_bJbL_i >= 0, i = 0, 1, ..., nBP.
+        function beta = computeBorrowingFromC(obj, boundary)
+            
+            e       = obj.getBoundaryOperatorForScalarField('e', boundary);
+            e_sh    = obj.getBoundaryOperatorForScalarField('e_shifted', boundary);
+            dim     = obj.dim;
+
+            [~, N] = size(e);
+            beta = ones(N, 1);
+            b = obj.getComponent('normal', boundary);
+            C_boundary = cell(dim, dim, dim, dim);
+            for i = 1:dim
+                for j = 1:dim
+                    for k = 1:dim
+                        for l = 1:dim
+                            C_boundary{i,j,k,l} = e'*obj.C{i,j,k,l}*e ;
+                        end
+                    end
+                end
+            end
+
+            % Loop over shift inward from boundary
+            for m = 1:obj.nBP_R-1
+                C_shifted = cell(dim, dim, dim, dim);
+                for i = 1:dim
+                    for j = 1:dim
+                        for k = 1:dim
+                            for l = 1:dim
+                                C_shifted{i,j,k,l} = e_sh{m}'*obj.C{i,j,k,l}*e_sh{m};
+                            end
+                        end
+                    end
+                end
+
+                % Loop along boundary
+                for i = 1:N
+                    C_boundary_mat = [C_boundary{b,1,b,1}(i,i), C_boundary{b,1,b,2}(i,i); ...
+                                        C_boundary{b,2,b,1}(i,i), C_boundary{b,2,b,2}(i,i)];
+                                        
+                    C_shifted_mat = [C_shifted{b,1,b,1}(i,i), C_shifted{b,1,b,2}(i,i); ...
+                                        C_shifted{b,2,b,1}(i,i), C_shifted{b,2,b,2}(i,i)];
+
+                    beta_i = obj.borrowingBisection(C_boundary_mat, C_shifted_mat);
+                    beta(i) = min(beta(i), beta_i);
+                end
+            end
+            if min(beta) < 1e-10
+                disp('WARNING! No borrowing from C seems to be possible.')
+                disp(['min(beta) = ' num2str(min(beta))])
+            end
+        end
+
         % Returns the component number that is the tangential/normal component
         % at the specified boundary
         function comp = getComponent(obj, comp_str, boundary)