Mercurial > repos > public > sbplib
changeset 200:ef41fde95ac4 feature/beams
Merged feature/grids into feature/beams.
author | Jonatan Werpers <jonatan@werpers.com> |
---|---|
date | Mon, 13 Jun 2016 16:59:02 +0200 |
parents | 419ec303e97d (current diff) d18096820ed4 (diff) |
children | 3c4ffbfbfb84 |
files | +grid/Multiblock.m +multiblock/gridVector1d.m +multiblock/gridVector2d.m +multiblock/solutionVector2cell.m +scheme/Scheme.m |
diffstat | 31 files changed, 938 insertions(+), 96 deletions(-) [+] |
line wrap: on
line diff
diff -r 419ec303e97d -r ef41fde95ac4 +anim/animate.m --- a/+anim/animate.m Mon Feb 29 15:40:34 2016 +0100 +++ b/+anim/animate.m Mon Jun 13 16:59:02 2016 +0200 @@ -19,6 +19,7 @@ dTau_target = 1/target_frame_rate; % Real time between frames rs = util.ReplaceableString(); + rs.appendFormat(' t: %d\n'); rs.appendFormat(' tau: %d\n'); rs.appendFormat(' target tau: %d\n'); rs.appendFormat(' Target fps: %.2f\n'); @@ -59,7 +60,7 @@ % Update information about this frame tau = toc(animation_start); - rs.updateParam(tau, targetTau, 1/dTau_target, 1/dTau, time_modifier_bound, time_modifier); + rs.updateParam(t, tau, targetTau, 1/dTau_target, 1/dTau, time_modifier_bound, time_modifier); end
diff -r 419ec303e97d -r ef41fde95ac4 +anim/setup_1d_plot.m --- a/+anim/setup_1d_plot.m Mon Feb 29 15:40:34 2016 +0100 +++ b/+anim/setup_1d_plot.m Mon Jun 13 16:59:02 2016 +0200 @@ -9,8 +9,9 @@ % be passed to functions in yfun. % plot_handles - Array of plot_handles. One for each yfun. % axis_handle - Handle to the axis plotted to. -function [update_data, plot_handles, axis_handle] = setup_1d_plot(x,yfun) +function [update_data, plot_handles, axis_handle] = setup_1d_plot(x,yfun,show_title) default_arg('yfun',{@(y)y}); + default_arg('show_title', true) if isa(yfun,'function_handle') yfun = {yfun}; @@ -24,8 +25,6 @@ axis_handle = gca; - xlabel('x') - ylabel('y') xlim([x(1) x(end)]); function update(t,varargin) @@ -33,7 +32,10 @@ for i = 1:length(yfun) set(plot_handles(i),'YData',yfun{i}(varargin{:})); end - title(axis_handle,sprintf('T=%.3f',t)); + + if show_title + title(axis_handle,sprintf('T=%.3f',t)); + end end end update_data = @update;
diff -r 419ec303e97d -r ef41fde95ac4 +grid/Cartesian.m --- a/+grid/Cartesian.m Mon Feb 29 15:40:34 2016 +0100 +++ b/+grid/Cartesian.m Mon Jun 13 16:59:02 2016 +0200 @@ -122,5 +122,68 @@ function gf = projectFunc(obj, gf, g) error('grid:Cartesian:NotImplemented') end + + % Return the names of all boundaries in this grid. + function bs = getBoundaryNames(obj) + switch obj.D() + case 1 + bs = {'l', 'r'}; + case 2 + bs = {'w', 'e', 's', 'n'}; + case 3 + bs = {'w', 'e', 's', 'n', 'd', 'u'}; + otherwise + error('not implemented'); + end + end + + % Return coordinates for the given boundary + function X = getBoundary(obj, name) + % In what dimension is the boundary? + switch name + case {'l', 'r', 'w', 'e'} + D = 1; + case {'s', 'n'} + D = 2; + case {'d', 'u'} + D = 3; + otherwise + error('not implemented'); + end + + % At what index is the boundary? + switch name + case {'l', 'w', 's', 'd'} + index = 1; + case {'r', 'e', 'n', 'u'} + index = obj.m(D); + otherwise + error('not implemented'); + end + + + + I = cell(1, obj.d); + for i = 1:obj.d + if i == D + I{i} = index; + else + I{i} = ':'; + end + end + + % Calculate size of result: + m = obj.m; + m(D) = []; + N = prod(m); + + X = zeros(N, obj.d); + + coordMat = obj.matrices(); + for i = 1:length(coordMat) + Xtemp = coordMat{i}(I{:}); + X(:,i) = reshapeRowMaj(Xtemp, [N,1]); + end + end end end \ No newline at end of file
diff -r 419ec303e97d -r ef41fde95ac4 +grid/CartesianTest.m --- a/+grid/CartesianTest.m Mon Feb 29 15:40:34 2016 +0100 +++ b/+grid/CartesianTest.m Mon Jun 13 16:59:02 2016 +0200 @@ -194,3 +194,125 @@ testCase.verifyEqual(g.scaling(),[2 1]); end + + +function testGetBoundaryNames(testCase) + in = { + {[1 2 3]}, + {[1 2 3], [4 5]}, + {[1 2 3], [4 5], [6 7 8]}, + }; + + out = { + {'l', 'r'}, + {'w', 'e', 's', 'n'}, + {'w', 'e', 's', 'n', 'd', 'u'}, + }; + + for i = 1:length(in) + g = grid.Cartesian(in{i}{:}); + testCase.verifyEqual(g.getBoundaryNames(), out{i}); + end +end + +function testGetBoundary(testCase) + grids = { + {[1 2 3]}, + {[1 2 3], [4 5]}, + {[1 2 3], [4 5], [6 7 8]}, + }; + + boundaries = { + {'l', 'r'}, + {'w', 'e', 's', 'n'}, + {'w', 'e', 's', 'n', 'd', 'u'}, + }; + + + % 1d + out{1,1} = 1; + out{1,2} = 3; + + % 2d + out{2,1} = [ + 1,4; + 1,5; + ]; + out{2,2} = [ + 3,4; + 3,5; + ]; + out{2,3} = [ + 1,4; + 2,4; + 3,4; + ]; + out{2,4} = [ + 1,5; + 2,5; + 3,5; + ]; + + % 3d + out{3,1} = [ + 1,4,6; + 1,4,7; + 1,4,8; + 1,5,6; + 1,5,7; + 1,5,8; + ]; + out{3,2} = [ + 3,4,6; + 3,4,7; + 3,4,8; + 3,5,6; + 3,5,7; + 3,5,8; + ]; + out{3,3} = [ + 1,4,6; + 1,4,7; + 1,4,8; + 2,4,6; + 2,4,7; + 2,4,8; + 3,4,6; + 3,4,7; + 3,4,8; + ]; + out{3,4} = [ + 1,5,6; + 1,5,7; + 1,5,8; + 2,5,6; + 2,5,7; + 2,5,8; + 3,5,6; + 3,5,7; + 3,5,8; + ]; + out{3,5} = [ + 1,4,6; + 1,5,6; + 2,4,6; + 2,5,6; + 3,4,6; + 3,5,6; + ]; + out{3,6} = [ + 1,4,8; + 1,5,8; + 2,4,8; + 2,5,8; + 3,4,8; + 3,5,8; + ]; + + for ig = 1:length(grids) + g = grid.Cartesian(grids{ig}{:}); + for ib = 1:length(boundaries{ig}) + testCase.verifyEqual(g.getBoundary(boundaries{ig}{ib}), out{ig,ib}); + end + end +end
diff -r 419ec303e97d -r ef41fde95ac4 +grid/Curvilinear.m --- a/+grid/Curvilinear.m Mon Feb 29 15:40:34 2016 +0100 +++ b/+grid/Curvilinear.m Mon Jun 13 16:59:02 2016 +0200 @@ -80,6 +80,64 @@ end h = obj.logic.h; end + + % Return the names of all boundaries in this grid. + function bs = getBoundaryNames(obj) + bs = obj.logic.getBoundaryNames(); + end + + % Return coordinates for the given boundary + function X = getBoundary(obj, name) + % In what dimension is the boundary? + switch name + case {'l', 'r', 'w', 'e'} + D = 1; + case {'s', 'n'} + D = 2; + case {'d', 'u'} + D = 3; + otherwise + error('not implemented'); + end + + % At what index is the boundary? + switch name + case {'l', 'w', 's', 'd'} + index = 1; + case {'r', 'e', 'n', 'u'} + index = obj.logic.m(D); + otherwise + error('not implemented'); + end + + + + I = cell(1, obj.D); + for i = 1:obj.D + if i == D + I{i} = index; + else + I{i} = ':'; + end + end + + % Calculate size of result: + m = obj.logic.m; + m(D) = []; + N = prod(m); + + X = zeros(N, obj.D); + + p = obj.points; + for i = 1:obj.D() + coordMat{i} = reshapeRowMaj(p(:,i), obj.logic.m); + end + + for i = 1:length(coordMat) + Xtemp = coordMat{i}(I{:}); + X(:,i) = reshapeRowMaj(Xtemp, [N,1]); + end + end end end
diff -r 419ec303e97d -r ef41fde95ac4 +grid/CurvilinearTest.m --- a/+grid/CurvilinearTest.m Mon Feb 29 15:40:34 2016 +0100 +++ b/+grid/CurvilinearTest.m Mon Jun 13 16:59:02 2016 +0200 @@ -67,7 +67,7 @@ end function testMappingInputError(testCase) - testCase.assumeFail(); + testCase.verifyFail(); end function testScaling(testCase) @@ -80,3 +80,52 @@ testCase.verifyEqual(g.scaling(),[2 1]); end +function testGetBoundaryNames(testCase) + in = { + {{1:10}, @(x) exp(x)}, + {{1:10,1:6}, @(x,y) [exp(x+y); exp(x-y)]}, + {{1:10,1:5,1:7}, @(x,y,z)[exp(x+y+z); exp(x-y-z); 2+x+y-z]}, + }; + + out = { + {'l', 'r'}, + {'w', 'e', 's', 'n'}, + {'w', 'e', 's', 'n', 'd', 'u'}, + }; + + for i = 1:length(in) + g = grid.Curvilinear(in{i}{2},in{i}{1}{:}); + testCase.verifyEqual(g.getBoundaryNames(), out{i}); + end +end + +function testGetBoundary(testCase) + grids = { + {{1:10}, @(x) exp(x)}, + {{1:10,1:6}, @(x,y) [exp(x+y); exp(x-y)]}, + {{1:10,1:5,1:7}, @(x,y,z)[exp(x+y+z); exp(x-y-z); 2+x+y-z]}, + }; + + boundaries = { + {'l', 'r'}, + {'w', 'e', 's', 'n'}, + {'w', 'e', 's', 'n', 'd', 'u'}, + }; + + + for ig = 1:length(grids) + g = grid.Curvilinear(grids{ig}{2},grids{ig}{1}{:}); + + logicalGrid = grid.Cartesian(grids{ig}{1}{:}); + + for ib = 1:length(boundaries{ig}) + + logicalBoundary = logicalGrid.getBoundary(boundaries{ig}{ib}); + + x = num2cell(logicalBoundary',2); + expectedBoundary = grids{ig}{2}(x{:})'; + testCase.verifyEqual(g.getBoundary(boundaries{ig}{ib}), expectedBoundary); + end + end +end +
diff -r 419ec303e97d -r ef41fde95ac4 +grid/Grid.m --- a/+grid/Grid.m Mon Feb 29 15:40:34 2016 +0100 +++ b/+grid/Grid.m Mon Jun 13 16:59:02 2016 +0200 @@ -15,13 +15,11 @@ % 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. + bs = getBoundaryNames(obj) + + % Return coordinates for the given boundary + b = getBoundary(obj, name) end end - - -%% Should it be able to return a cell size aswell? For an equidistant grid this would be know -%% for other grids the constructor would have to make something up. -%% For example the grid.Cartesian constructor would take a h (1 x d) vector as an in parameter. - - -%Should define boundaries somehow, look in stitchSchemes. \ No newline at end of file
diff -r 419ec303e97d -r ef41fde95ac4 +grid/Multiblock.m --- a/+grid/Multiblock.m Mon Feb 29 15:40:34 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,19 +0,0 @@ -classdef Multiblock < grid.Grid - % General multiblock grid - methods (Abstract) - % NBlocks returns the number of blocks in the grid. - o = NBlocks(obj); - - % Grid returns the ith grid in the multiblockgrid - gs = grid(obj,i); - - % Grids returns a cell array of all the grids in the multiblock grid. - gs = grids(obj); - - % Split a grid function on obj to a cell array of grid function on each block - gf = splitFunc(gf) - end -end - - -% Should define boundaries and connections between grids. \ No newline at end of file
diff -r 419ec303e97d -r ef41fde95ac4 +grid/bspline.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/bspline.m Mon Jun 13 16:59:02 2016 +0200 @@ -0,0 +1,47 @@ +% Calculates a D dimensional p-order bspline at t with knots T and control points P. +% T = [t0 t1 t2 ... tm] is a 1 x (m+1) vector with non-decresing elements and t0 = 0 tm = 1. +% P = [P0 P1 P2 ... Pn] is a D x (n+1) matrix. + +% knots p+1 to m-p-1 are the internal knots + +% Implemented from: http://mathworld.wolfram.com/B-Spline.html +function C = bspline(t,p,P,T) + m = length(T) - 1; + n = size(P,2) - 1; + D = size(P,1); + + assert(p == m - n - 1); + + C = zeros(D,length(t)); + + for i = 0:n + for k = 1:D + C(k,:) = C(k,:) + P(k,1+i)*B(i,p,t,T); + end + end + + % Curve not defined for t = 1 ? Ugly fix: + I = find(t == 1); + C(:,I) = repmat(P(:,end),[1,length(I)]); +end + +function o = B(i, j, t, T) + if j == 0 + o = T(1+i) <= t & t < T(1+i+1); + return + end + + if T(1+i+j)-T(1+i) ~= 0 + a = (t-T(1+i))/(T(1+i+j)-T(1+i)); + else + a = t*0; + end + + if T(1+i+j+1)-T(1+i+1) ~= 0 + b = (T(1+i+j+1)-t)/(T(1+i+j+1)-T(1+i+1)); + else + b = t*0; + end + + o = a.*B(i, j-1, t, T) + b.*B(i+1, j-1, t, T); +end \ No newline at end of file
diff -r 419ec303e97d -r ef41fde95ac4 +grid/equidistantCurvilinearTest.m --- a/+grid/equidistantCurvilinearTest.m Mon Feb 29 15:40:34 2016 +0100 +++ b/+grid/equidistantCurvilinearTest.m Mon Jun 13 16:59:02 2016 +0200 @@ -3,5 +3,5 @@ end function testNoTests(testCase) - testCase.assumeFail(); + testCase.verifyFail(); end \ No newline at end of file
diff -r 419ec303e97d -r ef41fde95ac4 +multiblock/BoundaryGroup.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+multiblock/BoundaryGroup.m Mon Jun 13 16:59:02 2016 +0200 @@ -0,0 +1,51 @@ +% BoundaryGroup defines a boundary grouping in a multiblock grid. +classdef BoundaryGroup + properties + blockIDs + names + end + + 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 + end + + function display(obj, name) + + disp(' ') + 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') + end + end +end \ No newline at end of file
diff -r 419ec303e97d -r ef41fde95ac4 +multiblock/BoundaryGroupTest.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+multiblock/BoundaryGroupTest.m Mon Jun 13 16:59:02 2016 +0200 @@ -0,0 +1,30 @@ +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 419ec303e97d -r ef41fde95ac4 +multiblock/DiffOp.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+multiblock/DiffOp.m Mon Jun 13 16:59:02 2016 +0200 @@ -0,0 +1,121 @@ +classdef DiffOp < scheme.Scheme + properties + grid + order + diffOps + D + H + end + + methods + function obj = DiffOp(doHand, grid, order, doParam) + % doHand -- may either be a function handle or a cell array of + % function handles for each grid. The function handle(s) + % should be on the form do = doHand(grid, order, ...) + % Additional parameters for each doHand may be provided in + % the doParam input. + % grid -- a multiblock grid + % order -- integer specifying the order of accuracy + % doParam -- may either be a cell array or a cell array of cell arrays + % for each block. If it is a cell array with length equal + % to the number of blocks then each element is sent to the + % corresponding function handle as extra parameters: + % doHand(..., doParam{i}{:}) Otherwise doParam is sent as + % extra parameters to all doHand: doHand(..., doParam{:}) + default_arg('doParam', []) + + [getHand, getParam] = parseInput(doHand, grid, doParam); + + nBlocks = grid.nBlocks(); + + obj.order = order; + + % Create the diffOps for each block + obj.diffOps = cell(1, nBlocks); + for i = 1:nBlocks + h = getHand(i); + p = getParam(i); + obj.diffOps{i} = h(grid.grid{i}, order, p{:}); + end + + + % Build the norm matrix + H = cell(nBlocks, nBlocks); + for i = 1:nBlocks + H{i,i} = obj.diffOps{i}.H; + end + obj.H = cell2sparse(H); + + + % Build the differentiation matrix + D = cell(nBlocks, nBlocks); + for i = 1:nBlocks + D{i,i} = obj.diffOps{i}.D; + end + + for i = 1:nBlocks + for j = i:nBlocks + intf = grid.connections{i,j}; + if isempty(intf) + continue + end + + [ii, ij] = obj.diffOps{i}.inteface_coupling(intf{1}, obj.diffOps{j}, intf{2}); + D{i,i} = D{i,i} + ii; + D{i,j} = D{i,j} + ij; + + [jj, ji] = obj.diffOps{j}.inteface_coupling(intf{2}, obj.diffOps{i}, intf{1}); + D{j,j} = D{j,j} + jj; + D{j,i} = D{j,i} + ji; + end + end + obj.D = cell2sparse(D); + + % end + + function [getHand, getParam] = parseInput(doHand, grid, doParam) + if ~isa(grid, 'multiblock.Grid') + error('multiblock:DiffOp:DiffOp:InvalidGrid', 'Requires a multiblock grid.'); + end + + if iscell(doHand) && length(doHand) == grid.nBlocks() + getHand = @(i)doHand{i}; + elseif isa(doHand, 'function_handle') + getHand = @(i)doHand; + else + error('multiblock:DiffOp:DiffOp:InvalidGridDoHand', 'doHand must be a function handle or a cell array of length grid.nBlocks'); + end + + if isempty(doParam) + getParam = @(i){}; + elseif iscell(doParam) && length(doParam) == grid.nBlocks() + getParam = @(i)doParam{i}; + else + getParam = @(i)doParam; + end + end + end + + function ops = splitOp(obj, op) + % Splits a matrix operator into a cell-matrix of matrix operators for + % each grid. + ops = sparse2cell(op, obj.NNN); + end + + function m = boundary_condition(obj,boundary,type,data) + + end + + function m = interface(obj,boundary,neighbour_scheme,neighbour_boundary) + + end + + + function N = size(obj) + N = 0; + for i = 1:length(diffOps) + N = N + diffOps.size(); + end + end + end +end
diff -r 419ec303e97d -r ef41fde95ac4 +multiblock/DiffOpTest.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+multiblock/DiffOpTest.m Mon Jun 13 16:59:02 2016 +0200 @@ -0,0 +1,20 @@ +function tests = DiffOpTest() + tests = functiontests(localfunctions); +end + +function testCreation(testCase) + g = multiblock.Grid({},{}); + doHand = @(grid,order)[]; + order = 0; + do = multiblock.DiffOp(doHand, g, order); +end + +function testMissing(testCase) + testCase.verifyFail(); +end + + +% function do = mockDiffOp() +% do.H = 1; +% do.D = 1; +% end \ No newline at end of file
diff -r 419ec303e97d -r ef41fde95ac4 +multiblock/Grid.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+multiblock/Grid.m Mon Jun 13 16:59:02 2016 +0200 @@ -0,0 +1,111 @@ +classdef Grid < grid.Grid + properties + grids + connections + boundaryGroups + + nPoints + end + + % 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. + function obj = Grid(grids, connections, boundaryGroups) + obj.grids = grids; + obj.connections = connections; + + obj.nPoints = 0; + for i = 1:length(grids) + obj.nPoints = obj.nPoints + grids{i}.N(); + end + + % if iscell(boundaryGroups) + end + + function n = size(obj) + n = length(obj.grids); + end + + % n returns the number of points in the grid + function o = N(obj) + o = obj.nPoints; + end + + function n = nBlocks(obj) + n = length(obj.grids); + end + + % d returns the spatial dimension of the grid + function o = D(obj) + o = obj.grids{1}.D(); + end + + % points returns a n x d matrix containing the coordinates for all points. + function X = points(obj) + X = []; + for i = 1:length(obj.grids) + X = [X; obj.grids{i}.points]; + end + end + + % Split a grid function on obj to a cell array of grid function on each block + function gfs = splitFunc(obj, gf) + nComponents = length(gf)/obj.nPoints; + nBlocks = length(obj.grids); + + % Collect number of points in each block + N = cell(1,nBlocks); + for i = 1:nBlocks + N{i} = obj.grids{i}.N(); + end + + gfs = mat2cell(gf, N, 1); + end + + % Restricts the grid function gf on obj to the subgrid g. + function gf = restrictFunc(obj, gf, g) + gfs = obj.splitFunc(gf); + + for i = 1:length(obj.grids) + gfs{i} = obj.grids{i}.restrictFunc(gfs{i}, g.grids{i}); + end + + gf = cell2mat(gfs); + end + + % Projects the grid function gf on obj to the grid g. + function o = projectFunc(obj, gf, g) + error('not implemented') + + p = g.points(); + o = zeros(length(p),1); + for i = 1:length(p) + I = whatGrid(p(i)); + o(i) = obj.grids{I}.projectFunc(gf, p(i)); + end + + + function I = whatGrid(p) + % Find what grid a point lies on + end + + end + + function bs = getBoundaryNames(obj) + bs = []; + end + + % Return coordinates for the given boundary + function b = getBoundary(obj, name) + b = []; + end + end +end
diff -r 419ec303e97d -r ef41fde95ac4 +multiblock/GridTest.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+multiblock/GridTest.m Mon Jun 13 16:59:02 2016 +0200 @@ -0,0 +1,37 @@ +function tests = GridTest() + tests = functiontests(localfunctions); +end + +function testCreation(testCase) + g = multiblock.Grid({},{}); +end + +function testMissing(testCase) + testCase.verifyFail(); +end + +function testGetBoundaryNames(testCase) + [grids, conn] = prepareAdjecentBlocks(); + + mbg = multiblock.Grid(grids, conn, multiblock.BoundaryGroup({1,'w'},{2,'w'}) ); + + testCase.verifyFail(); +end + +function testGetBoundary(testCase) + [grids, conn] = prepareAdjecentBlocks(); + + mbg = multiblock.Grid(grids, conn, multiblock.BoundaryGroup({1,'w'},{2,'w'}) ); + testCase.verifyFail(); +end + + +function [grids, conn] = prepareAdjecentBlocks() + grids = { + grid.Cartesian([0 1 2], [3 4 5]); + grid.Cartesian([1 2], [10 20]); + }; + + conn = cell(2,2); + conn{1, 2} = {'s','n'}; +end \ No newline at end of file
diff -r 419ec303e97d -r ef41fde95ac4 +multiblock/gridVector1d.m --- a/+multiblock/gridVector1d.m Mon Feb 29 15:40:34 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -function x = gridVector1d(schms) - n = length(schms); - x = cell(n,1); - - for i = 1:n - x{i} = schms{i}.x; - end -end \ No newline at end of file
diff -r 419ec303e97d -r ef41fde95ac4 +multiblock/gridVector2d.m --- a/+multiblock/gridVector2d.m Mon Feb 29 15:40:34 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -function [x,y] = gridVector2d(schms) - n = length(schms); - x = cell(n,1); - y = cell(n,1); - - for i = 1:n - x{i} = schms{i}.x; - y{i} = schms{i}.y; - end -end \ No newline at end of file
diff -r 419ec303e97d -r ef41fde95ac4 +multiblock/solutionVector2cell.m --- a/+multiblock/solutionVector2cell.m Mon Feb 29 15:40:34 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -function v_cell = solutionVector2cell(schms,v,components) - if nargin == 2 - components = 1; - end - - N = length(schms); - v_cell = cell(N,1); - - i_start = 1; - for i =1:N - i_end = i_start + schms{i}.size()*components - 1; - v_cell{i} = v(i_start:i_end); - i_start = i_end+1; - end -end \ No newline at end of file
diff -r 419ec303e97d -r ef41fde95ac4 +scheme/Scheme.m --- a/+scheme/Scheme.m Mon Feb 29 15:40:34 2016 +0100 +++ b/+scheme/Scheme.m Mon Jun 13 16:59:02 2016 +0200 @@ -1,40 +1,45 @@ -% Start with all matrix returns. When that works see how we should generalize to non-matrix stuff/nonlinear +% Start with all matrix returns. When that works see how we should generalize +% to non-matrix stuff/nonlinear classdef Scheme < handle properties (Abstract) order % Order accuracy for the approximation - % vectors u,v,w depending on dim that gives were gridpoints are in each dimension - % vectors x,y,z containing the x,y,z values corresponding to each grid point - % matrices X,Y,Z with point coordinates as multi dimensional vectors + grid D % non-stabalized scheme operator H % Discrete norm - - % Should also containg: - % the grid points used - % the grid spacing end methods (Abstract) - % Closure functions return the opertors applied to the own doamin to close the boundary - % Penalty functions return the opertors to force the solution. In the case of an interface it returns the operator applied to the other doamin. - % boundary is a string specifying the boundary e.g. 'l','r' or 'e','w','n','s'. - % type is a string specifying the type of boundary condition if there are several. - % neighbour_scheme is an instance of Scheme that should be interfaced to. - % neighbour_boundary is a string specifying which boundary to interface to. - [closure, penalty] = boundary_condition(obj,boundary,type) + % Closure functions return the opertors applied to the own doamin to + % close the boundary Penalty functions return the opertors to force + % the solution. In the case of an interface it returns the operator + % applied to the other doamin. In some cases the penalty return value + % can be ommited and the closure function take care of both parts. + % boundary is a string specifying the boundary e.g. + % 'l','r' or 'e','w','n','s'. + % type is a string specifying the type of + % boundary condition if there are several. + % data is a function returning the data that + % should be applied at the boundary. + % neighbour_scheme is an instance of Scheme that should be + % interfaced to. + % neighbour_boundary is a string specifying which boundary to + % interface to. + [closure, penalty] = boundary_condition(obj,boundary,type,data) [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary) - N = size(obj) % Returns the number of degrees of freedom. + % Returns the number of degrees of freedom. + N = size(obj) end methods(Static) - % Calculates the matrcis need for the inteface coupling between boundary bound_u of scheme schm_u - % and bound_v of scheme schm_v. - % [uu, uv, vv, vu] = inteface_couplong(A,'r',B,'l') + % Calculates the matrcis need for the inteface coupling between + % boundary bound_u of scheme schm_u and bound_v of scheme schm_v. + % [uu, uv, vv, vu] = inteface_coupling(A,'r',B,'l') function [uu, uv, vv, vu] = interface_coupling(schm_u,bound_u,schm_v,bound_v) [uu,uv] = schm_u.interface(bound_u,schm_v,bound_v); [vv,vu] = schm_v.interface(bound_v,schm_u,bound_u); end end -end \ No newline at end of file +end
diff -r 419ec303e97d -r ef41fde95ac4 +util/calc_borrowing.m --- a/+util/calc_borrowing.m Mon Feb 29 15:40:34 2016 +0100 +++ b/+util/calc_borrowing.m Mon Jun 13 16:59:02 2016 +0200 @@ -32,7 +32,7 @@ %% 2nd order compatible -[H, HI, D1, D4, e_1, e_m, M4, Q, S2_1, S2_m, S3_1, S3_m, S_1, S_m] = sbp.higher2_compatible(m,h); +[H, HI, D1, D4, e_1, e_m, M4, Q, S2_1, S2_m, S3_1, S3_m, S_1, S_m] = sbp.higher_compatible2(m,h); S1 = S_1*S_1' + S_m*S_m'; S2 = S2_1*S2_1' + S2_m*S2_m'; S3 = S3_1*S3_1' + S3_m*S3_m'; @@ -46,7 +46,7 @@ %% 4th order compatible -[H, HI, D1, D4, e_1, e_m, M4, Q, S2_1, S2_m, S3_1, S3_m, S_1, S_m] = sbp.higher4_compatible(m,h); +[H, HI, D1, D4, e_1, e_m, M4, Q, S2_1, S2_m, S3_1, S3_m, S_1, S_m] = sbp.higher_compatible4(m,h); S1 = S_1*S_1' + S_m*S_m'; S2 = S2_1*S2_1' + S2_m*S2_m'; S3 = S3_1*S3_1' + S3_m*S3_m'; @@ -59,7 +59,7 @@ fprintf('\n') %% 6th order compatible -[H, HI, D1, D4, e_1, e_m, M4, Q, S2_1, S2_m, S3_1, S3_m, S_1, S_m] = sbp.higher6_compatible(m,h); +[H, HI, D1, D4, e_1, e_m, M4, Q, S2_1, S2_m, S3_1, S3_m, S_1, S_m] = sbp.higher_compatible6(m,h); S1 = S_1*S_1' + S_m*S_m'; S2 = S2_1*S2_1' + S2_m*S2_m'; S3 = S3_1*S3_1' + S3_m*S3_m'; @@ -69,3 +69,27 @@ fprintf('6th order compatible\n') fprintf('alpha_II: %.10f\n',alpha_II) fprintf('alpha_III: %.10f\n',alpha_III) +fprintf('\n')3 + + + + + +% Ordinary + +for order = [2 4 6 8 10] + op = sbp.Ordinary(m,h, order); + + S_1 = op.boundary.S_1; + S_m = op.boundary.S_m; + + M = op.norms.M; + + S1 = S_1*S_1' + S_m*S_m'; + alpha = util.matrixborrow(M, h*S1); + fprintf('%dth order Ordinary\n', order) + fprintf('alpha: %.10f\n', alpha) + fprintf('\n') +end + +
diff -r 419ec303e97d -r ef41fde95ac4 getVarname.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/getVarname.m Mon Jun 13 16:59:02 2016 +0200 @@ -0,0 +1,7 @@ +function names = getVarname(varargin) + names = cell(size(varargin)); + + for i = 1:numel(varargin) + names{i} = inputname(i); + end +end \ No newline at end of file
diff -r 419ec303e97d -r ef41fde95ac4 labelTask.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/labelTask.m Mon Jun 13 16:59:02 2016 +0200 @@ -0,0 +1,12 @@ +function o = labelTask(in) + + switch class(in) + case 'char' + fprintf(in); + o = tic(); + case 'uint64' + o = toc(in); + fprintf(' - done %fs\n', o); + otherwise + error('Unknow input type: %s', class(in)) + end
diff -r 419ec303e97d -r ef41fde95ac4 prof.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/prof.m Mon Jun 13 16:59:02 2016 +0200 @@ -0,0 +1,10 @@ +function prof(f) + profile on + try + f(); + profile viewer + catch e + fprintf(2, '\n%s', getReport(e)); + profile clear + end +end \ No newline at end of file
diff -r 419ec303e97d -r ef41fde95ac4 saveFigurePosition.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/saveFigurePosition.m Mon Jun 13 16:59:02 2016 +0200 @@ -0,0 +1,6 @@ +function saveFigurePosition() + defaultPosition = get(0,'defaultfigureposition'); + f = gcf; + defaultPosition(1:2) = f.Position(1:2); + set(0,'defaultfigureposition',defaultPosition); +end \ No newline at end of file
diff -r 419ec303e97d -r ef41fde95ac4 savepng.m --- a/savepng.m Mon Feb 29 15:40:34 2016 +0100 +++ b/savepng.m Mon Jun 13 16:59:02 2016 +0200 @@ -1,4 +1,5 @@ function savepng(h, filename, dpi) + default_arg('dpi', 300) print(h,filename,'-dpng',sprintf('-r%d',dpi)); % Let print size in inches as input parameter % Smaller boundingbox
diff -r 419ec303e97d -r ef41fde95ac4 setFontSize.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/setFontSize.m Mon Jun 13 16:59:02 2016 +0200 @@ -0,0 +1,7 @@ +% setFontSize(fig, pts) +% Sets all fontsizes within a figure to size pts +% The default value for pts is 16. +function setFontSize(fig, pts) + default_arg('pts', 16); + set(findall(fig,'-property','FontSize'),'FontSize',pts); +end \ No newline at end of file
diff -r 419ec303e97d -r ef41fde95ac4 sparse2cell.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sparse2cell.m Mon Jun 13 16:59:02 2016 +0200 @@ -0,0 +1,28 @@ +% sparse2cell breaks a sparse matrix up into a cell matrix of sparse matrices. +% any zero submatrix creates a empty cell in the cell matrix. +% A -- NxM sparse matrix +% d1, d2 -- vectors of sub matrix sizes for each dimensions. Must have sum(di) == Ni. +% Example: +% C = sparse2cell(A,[5 10], [10 5]) +function C = sparse2cell(A, d1, d2) + [n, m] = size(A); + if n ~= sum(d1) || m ~= sum(d2) + error('sparse2cell:NonMatchingDim','The elements of d1 and d2 must sum to N and M.'); + end + + C = cell(length(d1), length(d2)); + I = 1; + for i = 1:length(d1) + J = 1; + for j = 1:length(d2) + Asub = A(I:(I + d1(i)-1), J:(J + d2(j)-1)); + if nnz(Asub) == 0 + C{i,j} = []; + else + C{i,j} = Asub; + end + J = J + d2(j); + end + I = I + d1(i); + end +end
diff -r 419ec303e97d -r ef41fde95ac4 sparse2cellTest.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sparse2cellTest.m Mon Jun 13 16:59:02 2016 +0200 @@ -0,0 +1,43 @@ +function tests = sparse2cellTest() + tests = functiontests(localfunctions); +end + +function testErrorNonMatchingDim(testCase) + in = { + {magic(5), [1 2 3], [4]}, + {magic(5), [1 1 1 1 1 1], [5]}, + {magic(5), [5], [1 1 1 1 1 1]}, + {ones(4,2),[2 3],[2]}, + {ones(4,2),[2 2],[3]}, + }; + + for i = 1:length(in) + testCase.verifyError(@()sparse2cell(in{i}{:}),'sparse2cell:NonMatchingDim'); + end +end + +function testOutput(testCase) + in = {}; + out = {}; + in{1}{1} =[17 24 1 8 15; 23 5 7 14 16; 4 6 13 20 22; 10 12 19 21 3; 11 18 25 2 9]; + in{1}{2} = [1 4]; + in{1}{3} = [2 3]; + + out{1} = { + [17 24], [1 8 15]; + [23 5; 4 6; 10 12; 11 18], [7 14 16; 13 20 22; 19 21 3; 25 2 9]; + }; + + in{1}{1} = [17 24 1 8 15; 23 5 0 0 0; 4 6 0 0 0; 10 12 0 0 0; 11 18 0 0 0]; + in{1}{2} = [1 4]; + in{1}{3} = [2 3]; + + out{1} = { + [17 24], [1 8 15]; + [23 5; 4 6; 10 12; 11 18], []; + }; + + for i = 1:length(in) + testCase.verifyEqual(sparse2cell(in{i}{:}), out{i}); + end +end \ No newline at end of file
diff -r 419ec303e97d -r ef41fde95ac4 time.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/time.m Mon Jun 13 16:59:02 2016 +0200 @@ -0,0 +1,34 @@ +function t_out = time(f, n) + default_arg('n',1); + + if n == 1 + t = timeOnce(f); + else + t = timeAvg(f, n); + end + + if nargout == 1 + t_out = t; + else + fprintf('Elapsed time is %.6f seconds.\n', t) + end +end + +function t = timeOnce(f) + s = tic(); + + f(); + + t = toc(s); +end + + +function t = timeAvg(f, n) + s = tic(); + + for i = 1:n + f(); + end + + t = toc(s)/n; +end
diff -r 419ec303e97d -r ef41fde95ac4 toString.m --- a/toString.m Mon Feb 29 15:40:34 2016 +0100 +++ b/toString.m Mon Jun 13 16:59:02 2016 +0200 @@ -28,19 +28,26 @@ end function str = cell2string(c) - len = length(c); - - if len == 0 + if isempty(c) str = '{}'; return end + [n, m] = size(c); + str = '{'; - for i =1:len-1 - str = [str sprintf('%s, ', value2string(c{i}))]; + for i = 1:n-1 + for j = 1:m-1 + str = [str sprintf('%s, ', value2string(c{i,j}))]; + end + str = [str sprintf('%s; ', value2string(c{i,end}))]; end - str = [str sprintf('%s}', value2string(c{end}))]; + + for j = 1:m-1 + str = [str sprintf('%s, ', value2string(c{end,j}))]; + end + str = [str sprintf('%s}', value2string(c{end,end}))]; end function str = struct2string(s)