Mercurial > repos > public > sbplib
changeset 535:b52ea450f4c3 feature/grids
Merge feature/boundaryGroup
author | Jonatan Werpers <jonatan@werpers.com> |
---|---|
date | Mon, 07 Aug 2017 09:56:01 +0200 |
parents | 3011f9a28ac8 (current diff) 55a7777dfcd0 (diff) |
children | 6c6a3040a678 |
files | +multiblock/BoundaryGroupTest.m +multiblock/boundaryIdentifier.txt |
diffstat | 7 files changed, 100 insertions(+), 99 deletions(-) [+] |
line wrap: on
line diff
diff -r 3011f9a28ac8 -r b52ea450f4c3 +grid/Grid.m --- a/+grid/Grid.m Wed Aug 02 19:26:39 2017 +0200 +++ b/+grid/Grid.m Mon Aug 07 09:56:01 2017 +0200 @@ -16,7 +16,7 @@ % Projects the grid function gf on obj to the grid g. gf = projectFunc(obj, gf, g) - % Return the names of all boundaries in this grid. + % Return the grid.boundaryIdentifiers of all boundaries in a cell array. bs = getBoundaryNames(obj) % Return coordinates for the given boundary
diff -r 3011f9a28ac8 -r b52ea450f4c3 +grid/boundaryIdentifier.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/boundaryIdentifier.txt Mon Aug 07 09:56:01 2017 +0200 @@ -0,0 +1,5 @@ +A grid.boundaryIdentifier identifies a boundary of a grid. +For a Cartesian grid it is simply 's', 'n', 'w', 'e'. +For a multiblock grid it might be something like {1, 's'}. +For some other grid it will be up to the developer to chose +a good way to identify boundaries.
diff -r 3011f9a28ac8 -r b52ea450f4c3 +multiblock/BoundaryGroup.m --- a/+multiblock/BoundaryGroup.m Wed Aug 02 19:26:39 2017 +0200 +++ b/+multiblock/BoundaryGroup.m Mon Aug 07 09:56:01 2017 +0200 @@ -1,30 +1,10 @@ % BoundaryGroup defines a boundary grouping in a multiblock grid. -classdef BoundaryGroup - properties - blockIDs - names - end - +% It workds like a cell array and collects boundary identifiers +% Within the multiblock package a BoundaryGroup is a valid boundary identifier as well. +classdef BoundaryGroup < Cell methods - function obj = BoundaryGroup(varargin) - % Input arguemnts are arbitrary number or 1x2 cell arrays - % representing each boundary in the group. - % The 1st element of the cell array is an integer defining which grid it belongs to. - % The 2nd element of the cell array is the name of the boundary within the block. - % - % Ex: - % bg = multiblock.BoundaryGroup({1,'n'},{1,'s'},{2,'s'}) - - - obj.blockIDs = []; - obj.names = {}; - for i = 1:length(varargin) - if ~iscell(varargin{i}) || ~all(size(varargin{i}) == [1 2]) - error('multiblock:BoundaryGroup:BoundaryGroup:InvalidInput', 'Inputs must be 1x2 cell arrays'); - end - obj.blockIDs(i) = varargin{i}{1}; - obj.names{i} = varargin{i}{2}; - end + function obj = BoundaryGroup(data) + obj = obj@Cell(data); end function display(obj, name) @@ -33,19 +13,7 @@ disp([name, ' =']) disp(' ') - if length(obj.names) == 1 - fprintf(' {}\n\n') - return - end - - fprintf(' {') - - fprintf('%d:%s', obj.blockIDs(1), obj.names{1}) - for i = 2:length(obj.names) - fprintf(', %d:%s', obj.blockIDs(i), obj.names{i}); - end - - fprintf('}\n\n') + fprintf(' BoundaryGroup%s\n\n', toString(obj.data)); end end -end \ No newline at end of file +end
diff -r 3011f9a28ac8 -r b52ea450f4c3 +multiblock/BoundaryGroupTest.m --- a/+multiblock/BoundaryGroupTest.m Wed Aug 02 19:26:39 2017 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -function tests = BoundaryGroupTest() - tests = functiontests(localfunctions); -end - -function testCreation(testCase) - in = {{3,'n'},{2,'hoho'},{1,'s'}}; - - blockIDs = [3 2 1]; - names = {'n', 'hoho', 's'}; - - bg = multiblock.BoundaryGroup(in{:}); - testCase.verifyEqual(bg.blockIDs, blockIDs); - testCase.verifyEqual(bg.names, names); -end - -function testInputError(testCase) - in = { - {'n', 's'}, - {{3,'n'},{2,2,'hoho'},{1,'s'}}, - }; - - out = { - 'multiblock:BoundaryGroup:BoundaryGroup:InvalidInput', - 'multiblock:BoundaryGroup:BoundaryGroup:InvalidInput', - }; - - for i = 1:length(in) - testCase.verifyError(@()multiblock.BoundaryGroup(in{i}{:}), out{i}); - end -end \ No newline at end of file
diff -r 3011f9a28ac8 -r b52ea450f4c3 +multiblock/DiffOp.m --- a/+multiblock/DiffOp.m Wed Aug 02 19:26:39 2017 +0200 +++ b/+multiblock/DiffOp.m Mon Aug 07 09:56:01 2017 +0200 @@ -120,27 +120,54 @@ ops = sparse2cell(op, obj.NNN); end - function op = getBoundaryOperator(obj, op, boundary) - if iscell(boundary) - localOpName = [op '_' boundary{2}]; - blockId = boundary{1}; - localOp = obj.diffOps{blockId}.(localOpName); + % Get a boundary operator specified by opName for the given boundary/BoundaryGroup + function op = getBoundaryOperator(obj, opName, boundary) + switch class(boundary) + case 'cell' + localOpName = [opName '_' boundary{2}]; + blockId = boundary{1}; + localOp = obj.diffOps{blockId}.(localOpName); - div = {obj.blockmatrixDiv{1}, size(localOp,2)}; - blockOp = blockmatrix.zero(div); - blockOp{blockId,1} = localOp; - op = blockmatrix.toMatrix(blockOp); - return - else - % Boundary är en sträng med en boundary group i. + div = {obj.blockmatrixDiv{1}, size(localOp,2)}; + blockOp = blockmatrix.zero(div); + blockOp{blockId,1} = localOp; + op = blockmatrix.toMatrix(blockOp); + return + case 'multiblock.BoundaryGroup' + op = []; + for i = 1:length(boundary) + op = [op, obj.getBoundaryOperator(opName, boundary{i})]; + end + otherwise + error('Unknown boundary indentifier') end end % Creates the closure and penalty matrix for a given boundary condition, % boundary -- the name of the boundary on the form {id,name} where % id is the number of a block and name is the name of a - % boundary of that block example: {1,'s'} or {3,'w'} + % boundary of that block example: {1,'s'} or {3,'w'}. It + % can also be a boundary group function [closure, penalty] = boundary_condition(obj, boundary, type) + switch class(boundary) + case 'cell' + [closure, penalty] = obj.singleBoundaryCondition(boundary, type); + case 'multiblock.BoundaryGroup' + [n,m] = size(obj.D); + closure = sparse(n,m); + penalty = []; + for i = 1:length(boundary) + [closurePart, penaltyPart] = obj.boundary_condition(boundary{i}, type); + closure = closure + closurePart; + penalty = [penalty, penaltyPart]; + end + otherwise + error('Unknown boundary indentifier') + end + + end + + function [closure, penalty] = singleBoundaryCondition(obj, boundary, type) I = boundary{1}; name = boundary{2};
diff -r 3011f9a28ac8 -r b52ea450f4c3 +multiblock/Grid.m --- a/+multiblock/Grid.m Wed Aug 02 19:26:39 2017 +0200 +++ b/+multiblock/Grid.m Mon Aug 07 09:56:01 2017 +0200 @@ -9,16 +9,19 @@ % General multiblock grid methods - - % grids -- cell array of N grids - % connections -- NxN upper triangular cell matrix. connections{i,j} - % specifies the connection between block i and j. If - % it's empty there is no connection otherwise it's a 2 - % -cell-vector with strings naming the boundaries to be - % connected. (inverted coupling?) - %% Should we have boundary groups at all? maybe it can be handled in a - %% cleaner way outside of the class. Maybe the grid class doesn't need to care at all. All boundaryGroup interaction is in DiffOp? + % grids -- cell array of N grids + % connections -- NxN upper triangular cell matrix. connections{i,j} + % specifies the connection between block i and j. If + % it's empty there is no connection otherwise it's a 2 + % -cell-vector with strings naming the boundaries to be + % connected. (inverted coupling?) + % boundaryGroups -- A struct of BoundaryGroups. The field names of the + % struct are the names of each boundary group. + % The boundary groups can be used to collect block + % boundaries into physical boundaries to simplify + % getting boundary operators and setting boundary conditions function obj = Grid(grids, connections, boundaryGroups) + default_arg('boundaryGroups', struct()); obj.grids = grids; obj.connections = connections; @@ -27,7 +30,7 @@ obj.nPoints = obj.nPoints + grids{i}.N(); end - % if iscell(boundaryGroups) + obj.boundaryGroups = boundaryGroups; end function n = size(obj) @@ -121,13 +124,43 @@ end + % Find all non interface boundaries of all blocks. + % Return their grid.boundaryIdentifiers in a cell array. function bs = getBoundaryNames(obj) - bs = []; + bs = {}; + for i = 1:obj.nBlocks() + candidates = obj.grids{i}.getBoundaryNames(); + for j = 1:obj.nBlocks() + if ~isempty(obj.connections{i,j}) + candidates = setdiff(candidates, obj.connections{i,j}{1}); + end + + if ~isempty(obj.connections{j,i}) + candidates = setdiff(candidates, obj.connections{j,i}{2}); + end + end + + for k = 1:length(candidates) + bs{end+1} = {i, candidates{k}}; + end + end end - % Return coordinates for the given boundary - function b = getBoundary(obj, name) - b = []; + % Return coordinates for the given boundary/boundaryGroup + function b = getBoundary(obj, boundary) + switch class(boundary) + case 'cell' + I = boundary{1}; + name = boundary{2}; + b = obj.grids{I}.getBoundary(name); + case 'multiblock.BoundaryGroup' + b = []; + for i = 1:length(boundary) + b = [b; obj.getBoundary(boundary{i})]; + end + otherwise + error('Unknown boundary indentifier') + end end end end