comparison +multiblock/DiffOp.m @ 1072:6468a5f6ec79 feature/grids/LaplaceSquared

Merge with default
author Jonatan Werpers <jonatan@werpers.com>
date Tue, 12 Feb 2019 17:12:42 +0100
parents 9c8ed00732fd
children 60c875c18de3
comparison
equal deleted inserted replaced
1071:92cb03e64ca4 1072:6468a5f6ec79
8 8
9 blockmatrixDiv 9 blockmatrixDiv
10 end 10 end
11 11
12 methods 12 methods
13 function obj = DiffOp(doHand, g, order, doParam) 13 function obj = DiffOp(doHand, g, order, doParam, intfTypes)
14 % doHand -- may either be a function handle or a cell array of 14 % doHand -- may either be a function handle or a cell array of
15 % function handles for each grid. The function handle(s) 15 % function handles for each grid. The function handle(s)
16 % should be on the form do = doHand(grid, order, ...) 16 % should be on the form do = doHand(grid, order, ...)
17 % Additional parameters for each doHand may be provided in 17 % Additional parameters for each doHand may be provided in
18 % the doParam input. 18 % the doParam input.
22 % for each block. If it is a cell array with length equal 22 % for each block. If it is a cell array with length equal
23 % to the number of blocks then each element is sent to the 23 % to the number of blocks then each element is sent to the
24 % corresponding function handle as extra parameters: 24 % corresponding function handle as extra parameters:
25 % doHand(..., doParam{i}{:}) Otherwise doParam is sent as 25 % doHand(..., doParam{i}{:}) Otherwise doParam is sent as
26 % extra parameters to all doHand: doHand(..., doParam{:}) 26 % extra parameters to all doHand: doHand(..., doParam{:})
27 %
28 % intfTypes (optional) -- nBlocks x nBlocks cell array of types for
29 % every interface.
27 default_arg('doParam', []) 30 default_arg('doParam', [])
31 default_arg('intfTypes', cell(g.nBlocks(), g.nBlocks()) );
28 32
29 [getHand, getParam] = parseInput(doHand, g, doParam); 33 [getHand, getParam] = parseInput(doHand, g, doParam);
30 34
35 obj.order = order;
31 nBlocks = g.nBlocks(); 36 nBlocks = g.nBlocks();
32
33 obj.order = order;
34 37
35 % Create the diffOps for each block 38 % Create the diffOps for each block
36 obj.diffOps = cell(1, nBlocks); 39 obj.diffOps = cell(1, nBlocks);
37 for i = 1:nBlocks 40 for i = 1:nBlocks
38 h = getHand(i); 41 h = getHand(i);
68 intf = g.connections{i,j}; 71 intf = g.connections{i,j};
69 if isempty(intf) 72 if isempty(intf)
70 continue 73 continue
71 end 74 end
72 75
73 76 [ii, ij] = obj.diffOps{i}.interface(intf{1}, obj.diffOps{j}, intf{2}, intfTypes{i,j});
74 [ii, ij] = obj.diffOps{i}.interface(intf{1}, obj.diffOps{j}, intf{2});
75 D{i,i} = D{i,i} + ii; 77 D{i,i} = D{i,i} + ii;
76 D{i,j} = D{i,j} + ij; 78 D{i,j} = D{i,j} + ij;
77 79
78 [jj, ji] = obj.diffOps{j}.interface(intf{2}, obj.diffOps{i}, intf{1}); 80 [jj, ji] = obj.diffOps{j}.interface(intf{2}, obj.diffOps{i}, intf{1}, intfTypes{i,j});
79 D{j,j} = D{j,j} + jj; 81 D{j,j} = D{j,j} + jj;
80 D{j,i} = D{j,i} + ji; 82 D{j,i} = D{j,i} + ji;
81 end 83 end
82 end 84 end
83 obj.D = blockmatrix.toMatrix(D); 85 obj.D = blockmatrix.toMatrix(D);
125 ops = sparse2cell(op, obj.NNN); 127 ops = sparse2cell(op, obj.NNN);
126 end 128 end
127 129
128 % Get a boundary operator specified by opName for the given boundary/BoundaryGroup 130 % Get a boundary operator specified by opName for the given boundary/BoundaryGroup
129 function op = getBoundaryOperator(obj, opName, boundary) 131 function op = getBoundaryOperator(obj, opName, boundary)
132
130 switch class(boundary) 133 switch class(boundary)
131 case 'cell' 134 case 'cell'
132 localOpName = [opName '_' boundary{2}];
133 blockId = boundary{1}; 135 blockId = boundary{1};
134 localOp = obj.diffOps{blockId}.(localOpName); 136 localOp = obj.diffOps{blockId}.getBoundaryOperator(opName, boundary{2});
135 137
136 div = {obj.blockmatrixDiv{1}, size(localOp,2)}; 138 div = {obj.blockmatrixDiv{1}, size(localOp,2)};
137 blockOp = blockmatrix.zero(div); 139 blockOp = blockmatrix.zero(div);
138 blockOp{blockId,1} = localOp; 140 blockOp{blockId,1} = localOp;
139 op = blockmatrix.toMatrix(blockOp); 141 op = blockmatrix.toMatrix(blockOp);
147 error('Unknown boundary indentifier') 149 error('Unknown boundary indentifier')
148 end 150 end
149 end 151 end
150 152
151 function op = getBoundaryQuadrature(obj, boundary) 153 function op = getBoundaryQuadrature(obj, boundary)
152 opName = 'H';
153 switch class(boundary) 154 switch class(boundary)
154 case 'cell' 155 case 'cell'
155 localOpName = [opName '_' boundary{2}];
156 blockId = boundary{1}; 156 blockId = boundary{1};
157 op = obj.diffOps{blockId}.(localOpName); 157 op = obj.diffOps{blockId}.getBoundaryQuadrature(boundary{2});
158
159 return 158 return
160 case 'multiblock.BoundaryGroup' 159 case 'multiblock.BoundaryGroup'
161 N = length(boundary); 160 N = length(boundary);
162 H_bm = cell(N,N); 161 H_bm = cell(N,N);
163 for i = 1:N 162 for i = 1:N
199 198
200 % Get the closure and penaly matrices 199 % Get the closure and penaly matrices
201 [blockClosure, blockPenalty] = obj.diffOps{I}.boundary_condition(name, type); 200 [blockClosure, blockPenalty] = obj.diffOps{I}.boundary_condition(name, type);
202 201
203 % Expand to matrix for full domain. 202 % Expand to matrix for full domain.
204 div = obj.blockmatrixDiv; 203 closure = multiblock.local2globalClosure(blockClosure, obj.blockmatrixDiv, I);
205 if ~iscell(blockClosure) 204 penalty = multiblock.local2globalPenalty(blockPenalty, obj.blockmatrixDiv, I);
206 temp = blockmatrix.zero(div);
207 temp{I,I} = blockClosure;
208 closure = blockmatrix.toMatrix(temp);
209 else
210 for i = 1:length(blockClosure)
211 temp = blockmatrix.zero(div);
212 temp{I,I} = blockClosure{i};
213 closure{i} = blockmatrix.toMatrix(temp);
214 end
215 end
216
217 if ~iscell(blockPenalty)
218 div{2} = size(blockPenalty, 2); % Penalty is a column vector
219 p = blockmatrix.zero(div);
220 p{I} = blockPenalty;
221 penalty = blockmatrix.toMatrix(p);
222 else
223 % TODO: used by beam equation, should be eliminated. SHould only set one BC per call
224 for i = 1:length(blockPenalty)
225 div{2} = size(blockPenalty{i}, 2); % Penalty is a column vector
226 p = blockmatrix.zero(div);
227 p{I} = blockPenalty{i};
228 penalty{i} = blockmatrix.toMatrix(p);
229 end
230 end
231 end 205 end
232 206
233 function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary) 207 function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary)
234 error('not implemented') 208 error('not implemented')
235 end 209 end