Mercurial > repos > public > sbplib
comparison +multiblock/DiffOp.m @ 943:21394c78c72e feature/utux2D
Merge with default
author | Martin Almquist <malmquist@stanford.edu> |
---|---|
date | Tue, 04 Dec 2018 15:24:36 -0800 |
parents | 1c61d8fa9903 57760d7088ad |
children | a4ad90b37998 a3accd2f1283 |
comparison
equal
deleted
inserted
replaced
942:35701c85e356 | 943:21394c78c72e |
---|---|
8 | 8 |
9 blockmatrixDiv | 9 blockmatrixDiv |
10 end | 10 end |
11 | 11 |
12 methods | 12 methods |
13 function obj = DiffOp(doHand, grid, order, doParam, intfTypes) | 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. |
19 % grid -- a multiblock grid | 19 % g -- a multiblock grid |
20 % order -- integer specifying the order of accuracy | 20 % order -- integer specifying the order of accuracy |
21 % doParam -- may either be a cell array or a cell array of cell arrays | 21 % doParam -- may either be a cell array or a cell array of cell arrays |
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: |
26 % extra parameters to all doHand: doHand(..., doParam{:}) | 26 % extra parameters to all doHand: doHand(..., doParam{:}) |
27 % | 27 % |
28 % intfTypes (optional) -- nBlocks x nBlocks cell array of types for | 28 % intfTypes (optional) -- nBlocks x nBlocks cell array of types for |
29 % every interface. | 29 % every interface. |
30 default_arg('doParam', []) | 30 default_arg('doParam', []) |
31 default_arg('intfTypes', cell(grid.nBlocks(), grid.nBlocks()) ); | 31 default_arg('intfTypes', cell(g.nBlocks(), g.nBlocks()) ); |
32 | 32 |
33 [getHand, getParam] = parseInput(doHand, grid, doParam); | 33 [getHand, getParam] = parseInput(doHand, g, doParam); |
34 | 34 |
35 obj.order = order; | 35 obj.order = order; |
36 nBlocks = grid.nBlocks(); | 36 nBlocks = g.nBlocks(); |
37 | 37 |
38 % Create the diffOps for each block | 38 % Create the diffOps for each block |
39 obj.diffOps = cell(1, nBlocks); | 39 obj.diffOps = cell(1, nBlocks); |
40 for i = 1:nBlocks | 40 for i = 1:nBlocks |
41 h = getHand(i); | 41 h = getHand(i); |
42 p = getParam(i); | 42 p = getParam(i); |
43 if ~iscell(p) | 43 if ~iscell(p) |
44 p = {p}; | 44 p = {p}; |
45 end | 45 end |
46 obj.diffOps{i} = h(grid.grids{i}, order, p{:}); | 46 obj.diffOps{i} = h(g.grids{i}, order, p{:}); |
47 end | 47 end |
48 | 48 |
49 | 49 |
50 % Build the norm matrix | 50 % Build the norm matrix |
51 H = cell(nBlocks, nBlocks); | 51 H = cell(nBlocks, nBlocks); |
54 end | 54 end |
55 obj.H = blockmatrix.toMatrix(H); | 55 obj.H = blockmatrix.toMatrix(H); |
56 | 56 |
57 | 57 |
58 % Build the differentiation matrix | 58 % Build the differentiation matrix |
59 obj.blockmatrixDiv = {grid.Ns, grid.Ns}; | 59 Ns = zeros(nBlocks,1); |
60 for i = 1:nBlocks | |
61 Ns(i) = length(obj.diffOps{i}.D); | |
62 end | |
63 obj.blockmatrixDiv = {Ns, Ns}; | |
60 D = blockmatrix.zero(obj.blockmatrixDiv); | 64 D = blockmatrix.zero(obj.blockmatrixDiv); |
61 for i = 1:nBlocks | 65 for i = 1:nBlocks |
62 D{i,i} = obj.diffOps{i}.D; | 66 D{i,i} = obj.diffOps{i}.D; |
63 end | 67 end |
64 | 68 |
65 for i = 1:nBlocks | 69 for i = 1:nBlocks |
66 for j = 1:nBlocks | 70 for j = 1:nBlocks |
67 intf = grid.connections{i,j}; | 71 intf = g.connections{i,j}; |
68 if isempty(intf) | 72 if isempty(intf) |
69 continue | 73 continue |
70 end | 74 end |
71 | 75 |
72 [ii, ij] = obj.diffOps{i}.interface(intf{1}, obj.diffOps{j}, intf{2}, intfTypes{i,j}); | 76 [ii, ij] = obj.diffOps{i}.interface(intf{1}, obj.diffOps{j}, intf{2}, intfTypes{i,j}); |
77 D{j,j} = D{j,j} + jj; | 81 D{j,j} = D{j,j} + jj; |
78 D{j,i} = D{j,i} + ji; | 82 D{j,i} = D{j,i} + ji; |
79 end | 83 end |
80 end | 84 end |
81 obj.D = blockmatrix.toMatrix(D); | 85 obj.D = blockmatrix.toMatrix(D); |
82 | 86 obj.grid = g; |
83 | 87 |
84 function [getHand, getParam] = parseInput(doHand, grid, doParam) | 88 |
85 if ~isa(grid, 'multiblock.Grid') | 89 function [getHand, getParam] = parseInput(doHand, g, doParam) |
90 if ~isa(g, 'multiblock.Grid') | |
86 error('multiblock:DiffOp:DiffOp:InvalidGrid', 'Requires a multiblock grid.'); | 91 error('multiblock:DiffOp:DiffOp:InvalidGrid', 'Requires a multiblock grid.'); |
87 end | 92 end |
88 | 93 |
89 if iscell(doHand) && length(doHand) == grid.nBlocks() | 94 if iscell(doHand) && length(doHand) == g.nBlocks() |
90 getHand = @(i)doHand{i}; | 95 getHand = @(i)doHand{i}; |
91 elseif isa(doHand, 'function_handle') | 96 elseif isa(doHand, 'function_handle') |
92 getHand = @(i)doHand; | 97 getHand = @(i)doHand; |
93 else | 98 else |
94 error('multiblock:DiffOp:DiffOp:InvalidGridDoHand', 'doHand must be a function handle or a cell array of length grid.nBlocks'); | 99 error('multiblock:DiffOp:DiffOp:InvalidGridDoHand', 'doHand must be a function handle or a cell array of length grid.nBlocks'); |
104 return | 109 return |
105 end | 110 end |
106 | 111 |
107 % doParam is a non-empty cell-array | 112 % doParam is a non-empty cell-array |
108 | 113 |
109 if length(doParam) == grid.nBlocks() && all(cellfun(@iscell, doParam)) | 114 if length(doParam) == g.nBlocks() && all(cellfun(@iscell, doParam)) |
110 % doParam is a cell-array of cell-arrays | 115 % doParam is a cell-array of cell-arrays |
111 getParam = @(i)doParam{i}; | 116 getParam = @(i)doParam{i}; |
112 return | 117 return |
113 end | 118 end |
114 | 119 |
138 case 'multiblock.BoundaryGroup' | 143 case 'multiblock.BoundaryGroup' |
139 op = sparse(size(obj.D,1),0); | 144 op = sparse(size(obj.D,1),0); |
140 for i = 1:length(boundary) | 145 for i = 1:length(boundary) |
141 op = [op, obj.getBoundaryOperator(opName, boundary{i})]; | 146 op = [op, obj.getBoundaryOperator(opName, boundary{i})]; |
142 end | 147 end |
148 otherwise | |
149 error('Unknown boundary indentifier') | |
150 end | |
151 end | |
152 | |
153 function op = getBoundaryQuadrature(obj, boundary) | |
154 opName = 'H'; | |
155 switch class(boundary) | |
156 case 'cell' | |
157 localOpName = [opName '_' boundary{2}]; | |
158 blockId = boundary{1}; | |
159 op = obj.diffOps{blockId}.(localOpName); | |
160 | |
161 return | |
162 case 'multiblock.BoundaryGroup' | |
163 N = length(boundary); | |
164 H_bm = cell(N,N); | |
165 for i = 1:N | |
166 H_bm{i,i} = obj.getBoundaryQuadrature(boundary{i}); | |
167 end | |
168 op = blockmatrix.toMatrix(H_bm); | |
143 otherwise | 169 otherwise |
144 error('Unknown boundary indentifier') | 170 error('Unknown boundary indentifier') |
145 end | 171 end |
146 end | 172 end |
147 | 173 |
175 | 201 |
176 % Get the closure and penaly matrices | 202 % Get the closure and penaly matrices |
177 [blockClosure, blockPenalty] = obj.diffOps{I}.boundary_condition(name, type); | 203 [blockClosure, blockPenalty] = obj.diffOps{I}.boundary_condition(name, type); |
178 | 204 |
179 % Expand to matrix for full domain. | 205 % Expand to matrix for full domain. |
180 div = obj.blockmatrixDiv; | 206 closure = multiblock.local2globalClosure(blockClosure, obj.blockmatrixDiv, I); |
181 if ~iscell(blockClosure) | 207 penalty = multiblock.local2globalPenalty(blockPenalty, obj.blockmatrixDiv, I); |
182 temp = blockmatrix.zero(div); | |
183 temp{I,I} = blockClosure; | |
184 closure = blockmatrix.toMatrix(temp); | |
185 else | |
186 for i = 1:length(blockClosure) | |
187 temp = blockmatrix.zero(div); | |
188 temp{I,I} = blockClosure{i}; | |
189 closure{i} = blockmatrix.toMatrix(temp); | |
190 end | |
191 end | |
192 | |
193 if ~iscell(blockPenalty) | |
194 div{2} = size(blockPenalty, 2); % Penalty is a column vector | |
195 p = blockmatrix.zero(div); | |
196 p{I} = blockPenalty; | |
197 penalty = blockmatrix.toMatrix(p); | |
198 else | |
199 % TODO: used by beam equation, should be eliminated. SHould only set one BC per call | |
200 for i = 1:length(blockPenalty) | |
201 div{2} = size(blockPenalty{i}, 2); % Penalty is a column vector | |
202 p = blockmatrix.zero(div); | |
203 p{I} = blockPenalty{i}; | |
204 penalty{i} = blockmatrix.toMatrix(p); | |
205 end | |
206 end | |
207 end | 208 end |
208 | 209 |
209 function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary) | 210 function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary) |
210 error('not implemented') | 211 error('not implemented') |
211 end | 212 end |