Mercurial > repos > public > sbplib
comparison +multiblock/DiffOp.m @ 498:324c927d8b1d feature/quantumTriangles
chnaged sbp interfacein 1d among many things
| author | Ylva Rydin <ylva.rydin@telia.com> |
|---|---|
| date | Fri, 03 Mar 2017 16:19:41 +0100 |
| parents | 30ff8879162e |
| children | 111fcbcff2e9 |
comparison
equal
deleted
inserted
replaced
| 497:4905446f165e | 498:324c927d8b1d |
|---|---|
| 3 grid | 3 grid |
| 4 order | 4 order |
| 5 diffOps | 5 diffOps |
| 6 D | 6 D |
| 7 H | 7 H |
| 8 | 8 |
| 9 blockmatrixDiv | 9 blockmatrixDiv |
| 10 end | 10 end |
| 11 | 11 |
| 12 methods | 12 methods |
| 13 function obj = DiffOp(doHand, grid, order, doParam) | 13 function obj = DiffOp(doHand, grid, order, doParam,timeDep) |
| 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. |
| 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 default_arg('doParam', []) | 27 default_arg('doParam', []) |
| 28 | 28 |
| 29 [getHand, getParam] = parseInput(doHand, grid, doParam); | 29 [getHand, getParam] = parseInput(doHand, grid, doParam); |
| 30 | 30 |
| 31 nBlocks = grid.nBlocks(); | 31 nBlocks = grid.nBlocks(); |
| 32 | 32 |
| 33 obj.order = order; | 33 obj.order = order; |
| 34 | 34 |
| 35 % Create the diffOps for each block | 35 % Create the diffOps for each block |
| 36 obj.diffOps = cell(1, nBlocks); | 36 obj.diffOps = cell(1, nBlocks); |
| 37 for i = 1:nBlocks | 37 for i = 1:nBlocks |
| 38 h = getHand(i); | 38 h = getHand(i); |
| 39 p = getParam(i); | 39 p = getParam(i); |
| 40 if ~iscell(p) | 40 if ~iscell(p) |
| 41 p = {p}; | 41 p = {p}; |
| 42 end | 42 end |
| 43 obj.diffOps{i} = h(grid.grids{i}, order, p{:}); | 43 obj.diffOps{i} = h(grid.grids{i}, order, p{:}); |
| 44 end | 44 end |
| 45 | 45 |
| 46 | 46 |
| 47 % Build the norm matrix | 47 % Build the norm matrix |
| 48 H = cell(nBlocks, nBlocks); | 48 H = cell(nBlocks, nBlocks); |
| 49 for i = 1:nBlocks | 49 for i = 1:nBlocks |
| 50 H{i,i} = obj.diffOps{i}.H; | 50 H{i,i} = obj.diffOps{i}.H; |
| 51 end | 51 end |
| 52 obj.H = blockmatrix.toMatrix(H); | 52 obj.H = blockmatrix.toMatrix(H); |
| 53 | 53 |
| 54 | 54 |
| 55 % Build the differentiation matrix | 55 % Build the differentiation matrix |
| 56 obj.blockmatrixDiv = {grid.Ns, grid.Ns}; | 56 switch timeDep |
| 57 D = blockmatrix.zero(obj.blockmatrixDiv); | 57 case {'n','no','N','No'} |
| 58 for i = 1:nBlocks | 58 obj.blockmatrixDiv = {grid.Ns, grid.Ns}; |
| 59 D{i,i} = obj.diffOps{i}.D; | 59 D = blockmatrix.zero(obj.blockmatrixDiv); |
| 60 end | 60 for i = 1:nBlocks |
| 61 | 61 D{i,i} = obj.diffOps{i}.D; |
| 62 for i = 1:nBlocks | 62 end |
| 63 for j = 1:nBlocks | 63 |
| 64 intf = grid.connections{i,j}; | 64 for i = 1:nBlocks |
| 65 if isempty(intf) | 65 for j = 1:nBlocks |
| 66 continue | 66 intf = grid.connections{i,j}; |
| 67 end | 67 if isempty(intf) |
| 68 | 68 continue |
| 69 | 69 end |
| 70 [ii, ij] = obj.diffOps{i}.interface(intf{1}, obj.diffOps{j}, intf{2}); | 70 |
| 71 D{i,i} = D{i,i} + ii; | 71 |
| 72 D{i,j} = D{i,j} + ij; | 72 [ii, ij] = obj.diffOps{i}.interface(intf{1}, obj.diffOps{j}, intf{2}); |
| 73 | 73 D{i,i} = D{i,i} + ii; |
| 74 [jj, ji] = obj.diffOps{j}.interface(intf{2}, obj.diffOps{i}, intf{1}); | 74 D{i,j} = D{i,j} + ij; |
| 75 D{j,j} = D{j,j} + jj; | 75 |
| 76 D{j,i} = D{j,i} + ji; | 76 [jj, ji] = obj.diffOps{j}.interface(intf{2}, obj.diffOps{i}, intf{1}); |
| 77 end | 77 D{j,j} = D{j,j} + jj; |
| 78 end | 78 D{j,i} = D{j,i} + ji; |
| 79 obj.D = blockmatrix.toMatrix(D); | 79 end |
| 80 | 80 end |
| 81 | 81 obj.D = blockmatrix.toMatrix(D); |
| 82 case {'y','yes','Y','Yes'} | |
| 83 for i = 1:nBlocks | |
| 84 D{i,i} = @(t)obj.diffOps{i}.D(t); | |
| 85 end | |
| 86 | |
| 87 for i = 1:nBlocks | |
| 88 for j = 1:nBlocks | |
| 89 intf = grid.connections{i,j}; | |
| 90 if isempty(intf) | |
| 91 continue | |
| 92 end | |
| 93 | |
| 94 [ii, ij] = obj.diffOps{i}.interface(intf{1}, obj.diffOps{j}, intf{2}); | |
| 95 D{i,i} = @(t)D{i,i}(t) + ii(t); | |
| 96 D{i,j} = ij; | |
| 97 | |
| 98 [jj, ji] = obj.diffOps{j}.interface(intf{2}, obj.diffOps{i}, intf{1}); | |
| 99 D{j,j} = @(t)D{j,j}(t) + jj(t); | |
| 100 D{j,i} = ji; | |
| 101 end | |
| 102 end | |
| 103 obj.D = D; | |
| 104 end | |
| 105 | |
| 106 | |
| 82 function [getHand, getParam] = parseInput(doHand, grid, doParam) | 107 function [getHand, getParam] = parseInput(doHand, grid, doParam) |
| 83 if ~isa(grid, 'multiblock.Grid') | 108 if ~isa(grid, 'multiblock.Grid') |
| 84 error('multiblock:DiffOp:DiffOp:InvalidGrid', 'Requires a multiblock grid.'); | 109 error('multiblock:DiffOp:DiffOp:InvalidGrid', 'Requires a multiblock grid.'); |
| 85 end | 110 end |
| 86 | 111 |
| 87 if iscell(doHand) && length(doHand) == grid.nBlocks() | 112 if iscell(doHand) && length(doHand) == grid.nBlocks() |
| 88 getHand = @(i)doHand{i}; | 113 getHand = @(i)doHand{i}; |
| 89 elseif isa(doHand, 'function_handle') | 114 elseif isa(doHand, 'function_handle') |
| 90 getHand = @(i)doHand; | 115 getHand = @(i)doHand; |
| 91 else | 116 else |
| 92 error('multiblock:DiffOp:DiffOp:InvalidGridDoHand', 'doHand must be a function handle or a cell array of length grid.nBlocks'); | 117 error('multiblock:DiffOp:DiffOp:InvalidGridDoHand', 'doHand must be a function handle or a cell array of length grid.nBlocks'); |
| 93 end | 118 end |
| 94 | 119 |
| 95 if isempty(doParam) | 120 if isempty(doParam) |
| 96 getParam = @(i){}; | 121 getParam = @(i){}; |
| 97 return | 122 return |
| 98 end | 123 end |
| 99 | 124 |
| 100 if ~iscell(doParam) | 125 if ~iscell(doParam) |
| 101 getParam = @(i)doParam; | 126 getParam = @(i)doParam; |
| 102 return | 127 return |
| 103 end | 128 end |
| 104 | 129 |
| 105 % doParam is a non-empty cell-array | 130 % doParam is a non-empty cell-array |
| 106 | 131 |
| 107 if length(doParam) == grid.nBlocks() && all(cellfun(@iscell, doParam)) | 132 if length(doParam) == grid.nBlocks() && all(cellfun(@iscell, doParam)) |
| 108 % doParam is a cell-array of cell-arrays | 133 % doParam is a cell-array of cell-arrays |
| 109 getParam = @(i)doParam{i}; | 134 getParam = @(i)doParam{i}; |
| 110 return | 135 return |
| 111 end | 136 end |
| 112 | 137 |
| 113 getParam = @(i)doParam; | 138 getParam = @(i)doParam; |
| 114 end | 139 end |
| 115 end | 140 end |
| 116 | 141 |
| 117 function ops = splitOp(obj, op) | 142 function ops = splitOp(obj, op) |
| 118 % Splits a matrix operator into a cell-matrix of matrix operators for | 143 % Splits a matrix operator into a cell-matrix of matrix operators for |
| 119 % each grid. | 144 % each grid. |
| 120 ops = sparse2cell(op, obj.NNN); | 145 ops = sparse2cell(op, obj.NNN); |
| 121 end | 146 end |
| 122 | 147 |
| 123 function op = getBoundaryOperator(obj, op, boundary) | 148 function op = getBoundaryOperator(obj, op, boundary) |
| 124 if iscell(boundary) | 149 if iscell(boundary) |
| 125 localOpName = [op '_' boundary{2}]; | 150 localOpName = [op '_' boundary{2}]; |
| 126 blockId = boundary{1}; | 151 blockId = boundary{1}; |
| 127 localOp = obj.diffOps{blockId}.(localOpName); | 152 localOp = obj.diffOps{blockId}.(localOpName); |
| 128 | 153 |
| 129 div = {obj.blockmatrixDiv{1}, size(localOp,2)}; | 154 div = {obj.blockmatrixDiv{1}, size(localOp,2)}; |
| 130 blockOp = blockmatrix.zero(div); | 155 blockOp = blockmatrix.zero(div); |
| 131 blockOp{blockId,1} = localOp; | 156 blockOp{blockId,1} = localOp; |
| 132 op = blockmatrix.toMatrix(blockOp); | 157 op = blockmatrix.toMatrix(blockOp); |
| 133 return | 158 return |
| 134 else | 159 else |
| 135 % Boundary är en sträng med en boundary group i. | 160 % Boundary är en sträng med en boundary group i. |
| 136 end | 161 end |
| 137 end | 162 end |
| 138 | 163 |
| 139 % Creates the closure and penalty matrix for a given boundary condition, | 164 % Creates the closure and penalty matrix for a given boundary condition, |
| 140 % boundary -- the name of the boundary on the form {id,name} where | 165 % boundary -- the name of the boundary on the form {id,name} where |
| 141 % id is the number of a block and name is the name of a | 166 % id is the number of a block and name is the name of a |
| 142 % boundary of that block example: {1,'s'} or {3,'w'} | 167 % boundary of that block example: {1,'s'} or {3,'w'} |
| 143 function [closure, penalty] = boundary_condition(obj, boundary, type) | 168 function [closure, penalty] = boundary_condition(obj, boundary, type) |
| 144 I = boundary{1}; | 169 I = boundary{1}; |
| 145 name = boundary{2}; | 170 name = boundary{2}; |
| 146 | 171 |
| 147 % Get the closure and penaly matrices | 172 % Get the closure and penaly matrices |
| 148 [blockClosure, blockPenalty] = obj.diffOps{I}.boundary_condition(name, type); | 173 [blockClosure, blockPenalty] = obj.diffOps{I}.boundary_condition(name, type); |
| 149 | 174 |
| 150 % Expand to matrix for full domain. | 175 % Expand to matrix for full domain. |
| 151 div = obj.blockmatrixDiv; | 176 div = obj.blockmatrixDiv; |
| 152 if ~iscell(blockClosure) | 177 if ~iscell(blockClosure) |
| 153 temp = blockmatrix.zero(div); | 178 temp = blockmatrix.zero(div); |
| 154 temp{I,I} = blockClosure; | 179 temp{I,I} = blockClosure; |
| 158 temp = blockmatrix.zero(div); | 183 temp = blockmatrix.zero(div); |
| 159 temp{I,I} = blockClosure{i}; | 184 temp{I,I} = blockClosure{i}; |
| 160 closure{i} = blockmatrix.toMatrix(temp); | 185 closure{i} = blockmatrix.toMatrix(temp); |
| 161 end | 186 end |
| 162 end | 187 end |
| 163 | 188 |
| 164 div{2} = size(blockPenalty, 2); % Penalty is a column vector | 189 div{2} = size(blockPenalty, 2); % Penalty is a column vector |
| 165 if ~iscell(blockPenalty) | 190 if ~iscell(blockPenalty) |
| 166 p = blockmatrix.zero(div); | 191 p = blockmatrix.zero(div); |
| 167 p{I} = blockPenalty; | 192 p{I} = blockPenalty; |
| 168 penalty = blockmatrix.toMatrix(p); | 193 penalty = blockmatrix.toMatrix(p); |
| 172 p{I} = blockPenalty{i}; | 197 p{I} = blockPenalty{i}; |
| 173 penalty{i} = blockmatrix.toMatrix(p); | 198 penalty{i} = blockmatrix.toMatrix(p); |
| 174 end | 199 end |
| 175 end | 200 end |
| 176 end | 201 end |
| 177 | 202 |
| 178 function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary) | 203 function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary) |
| 179 | 204 |
| 180 end | 205 end |
| 181 | 206 |
| 182 % Size returns the number of degrees of freedom | 207 % Size returns the number of degrees of freedom |
| 183 function N = size(obj) | 208 function N = size(obj) |
| 184 N = 0; | 209 N = 0; |
| 185 for i = 1:length(obj.diffOps) | 210 for i = 1:length(obj.diffOps) |
| 186 N = N + obj.diffOps{i}.size(); | 211 N = N + obj.diffOps{i}.size(); |
