Mercurial > repos > public > sbplib
changeset 832:5573913a0949 feature/burgers1d
Merged with default, and updated +scheme/Burgers1D accordingly
author | Vidar Stiernström <vidar.stiernstrom@it.uu.se> |
---|---|
date | Tue, 11 Sep 2018 15:58:35 +0200 |
parents | d0934d1143b7 (current diff) 501750fbbfdb (diff) |
children | 9f4c45a2d271 |
files | +grid/Curve.m +grid/Ti.m +grid/Ti3D.m +grid/equal_step_size.m +grid/old/concat_curve.m +grid/old/curve_discretise.m +grid/old/curve_interp.m +grid/old/max_h.m +grid/old/min_h.m +grid/old/plot_shape.m +grid/old/shape.m +grid/old/shape_discretise.m +grid/old/shape_linesegments.m +grid/old/triang_interp.m +grid/old/triang_interp_pts.m +grid/old/triang_map.m +grid/old/triang_plot_interp.m +grid/old/triang_show.m +grid/place_label.m +multiblock/gridVector1d.m +multiblock/gridVector2d.m +multiblock/multiblockgrid.m +multiblock/solutionVector2cell.m +multiblock/stitchSchemes.m +sbp/+implementations/d4_compatible_halfvariable_2.m +sbp/+implementations/d4_compatible_halfvariable_4.m +sbp/+implementations/d4_compatible_halfvariable_6.m +sbp/D4CompatibleVariable.m +scheme/Burgers1D.m cell2sparse.m cell2vector.m vector2cell.m |
diffstat | 235 files changed, 11439 insertions(+), 2696 deletions(-) [+] |
line wrap: on
line diff
--- a/+anim/setup_time_quantity_plot.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+anim/setup_time_quantity_plot.m Tue Sep 11 15:58:35 2018 +0200 @@ -16,7 +16,7 @@ if ishandle(axis_handle) % t = [t t_now]; for j = 1:length(yfun) - addpoints(plot_handles(j),t_now,yfun{j}(varargin{:})); + addpoints(plot_handles(j),t_now,full(yfun{j}(varargin{:}))); end [t,~] = getpoints(plot_handles(1));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+blockmatrix/fromMatrix.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,24 @@ +function bm = fromMatrix(A, div) + d1 = div{1}; + d2 = div{2}; + [n, m] = size(A); + if n ~= sum(d1) || m ~= sum(d2) + error('blockmatrix:fromMatrix:NonMatchingDim','The dimensions in div does not sum to the dimensions in A.'); + end + + bm = 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 + bm{i,j} = sparse(d1(i), d2(j)); + else + bm{i,j} = Asub; + end + J = J + d2(j); + end + I = I + d1(i); + end +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+blockmatrix/fromMatrixTest.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,78 @@ +function tests = fromMatrixTest() + 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(@()blockmatrix.fromMatrix(in{i}{:}),'blockmatrix:fromMatrix:NonMatchingDim'); + end +end + +function testFromMatrix(testCase) + cases = { + { + {[],{[],[]}}, + {} + }, + { + { + magic(3), + {[3],[3]} + }, + {magic(3)} + }, + { + { + magic(3), + {[1 1 1],[1 1 1]} + }, + mat2cell(magic(3),[1 1 1],[1 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], + {[1 4],[2 3]} + }, + { + [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]; + }; + }, + { + { + magic(3), + {[1 0 2],[1 2 0]} + }, + mat2cell(magic(3),[1 0 2],[1 2 0]) + }, + { + { + zeros(0,1), + {0,1}, + }, + {zeros(0,1)} + }, + }; + for i = 1:length(cases) + out = convertToFull(blockmatrix.fromMatrix(cases{i}{1}{:})); + expected = cases{i}{2}; + testCase.verifyEqual(out,expected); + end +end + +function C = convertToFull(C) + [N,M] = size(C); + for i = 1:N + for j = 1:M + C{i,j} = full(C{i,j}); + end + end +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+blockmatrix/getDivision.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,42 @@ +function div = getDivision(bm) + if ~blockmatrix.isBlockmatrix(bm) + error('blockmatrix:getDivision:NotABlockmatrix', 'Input is not a blockmatrix'); + end + + if isempty(bm) + div = {[],[]}; + return + end + + div = {row_height(bm),col_width(bm)}; +end + + +function m = col_width(C) + m = zeros(1,size(C,2)); + for j = 1:size(C,2) + for i = 1:size(C,1) + if isNullMatrix(C{i,j}) + continue + end + m(j) = size(C{i,j},2); + end + end +end + +function n = row_height(C) + n = zeros(1,size(C,1)); + for i = 1:size(C,1) + for j = 1:size(C,2) + if isNullMatrix(C{i,j}) + continue + end + n(i) = size(C{i,j},1); + end + end +end + +function b = isNullMatrix(A) + [n, m] = size(A); + b = n == 0 && m == 0; +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+blockmatrix/getDivisionTest.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,81 @@ +function tests = getDivisionTest() + tests = functiontests(localfunctions); +end + +function testError(testCase) + cases = { + magic(3), + {[2 2 2];{1,2}}, + {[2 2 2];[1 2]}, + {[2; 2; 2], [1; 2]}, + }; + + for i =1:length(cases) + testCase.verifyError(@()blockmatrix.getDivision(cases{i}), 'blockmatrix:getDivision:NotABlockmatrix') + end +end + +function testGetDivision(testCase) + cases = { + { + {}, + {[],[]}; + }, + { + { + [2 2; 2 1], [1; 2]; + [2 2], [1] + }, + {[2 1], [2 1]} + }, + { + { + [2 2; 2 1], []; + [2 2], [1] + }, + {[2 1], [2 1]} + }, + { + { + [2 2; 2 1], []; + [2 2], [] + }, + {[2 1], [2 0]} + }, + { + { + [2 2; 2 1], [1; 2]; + [], [] + }, + {[2 0], [2 1]} + }, + { + { + [2 2; 2 1]; + [2 2] + }, + {[2 1], 2} + }, + { + {zeros(3,0)}, + {3, 0}, + }, + { + {zeros(3,0), zeros(3,0)}, + {3, [0, 0]}, + }, + { + {zeros(3,0); zeros(2,0)}, + {[3 2],0}, + }, + }; + + for i = 1:length(cases) + in = cases{i}{1}; + out = blockmatrix.getDivision(in); + expected = cases{i}{2}; + testCase.verifyEqual(out, expected); + end +end + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+blockmatrix/isBlockmatrix.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,59 @@ +function b = isBlockmatrix(bm) + if ~iscell(bm) + b = false; + return + end + + % Make sure all blocks are numerical matrices + for i = 1:length(bm) + if ~isnumeric(bm{i}) + b = false; + return + end + end + + [N,M] = size(bm); + % Make sure column dimensions agree + for i = 1:N + d = []; + for j = 1:M + d_ij = size(bm{i,j},1); + if d_ij == 0 + continue + end + + if isempty(d) + d = d_ij; + continue + end + + if d ~= d_ij + b = false; + return + end + end + end + + % Make sure row dimensions agree + for j = 1:M + d = []; + for i = 1:N + d_ij = size(bm{i,j},2); + if d_ij == 0 + continue + end + + if isempty(d) + d = d_ij; + continue + end + + if d ~= d_ij + b = false; + return + end + end + end + + b = true; +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+blockmatrix/isBlockmatrixTest.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,67 @@ +function tests = isBlockmatrixTest() + tests = functiontests(localfunctions); +end + +function testIsBlockmatrix(testCase) + cases = { + { + magic(3), + false % Must be a cell array + } + { + {[2 2 2];{1,2}}, + false % All elements of the cell matrix must be regular matrices + }, + { + {[2 2 2];[1 2]}, + false % Row dimensions must match + }, + { + {[2; 2; 2], [1; 2]}, + false % Column dimensions must match + }, + { + {}, + true % An empty matrix is a matrix too + }, + { + { + [2 2; 2 1], [1; 2]; + [2 2], [1] + }, + true % A simple valid one + }, + { + { + [2 2; 2 1], []; + [2 2], [1] + }, + true % Empty blocks assumed to be zero and match dimensions + }, + { + { + [2 2; 2 1], []; + [2 2], [] + }, + true % Empty blocks allowed. + }, + { + { + [2 2; 2 1], [1; 2]; + [], [] + }, + true % Empty blocks allowed. + }, + { + blockmatrix.zero({[1 2 3],[2 3]}), + true % A zero block matrix is a block matrix + }, + }; + + for i = 1:length(cases) + in = cases{i}{1}; + out = blockmatrix.isBlockmatrix(in); + expected = cases{i}{2}; + testCase.verifyEqual(out, expected, sprintf('Should return %d for %s', expected, toString(in))); + end +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+blockmatrix/isDivision.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,34 @@ +function b = isDivision(div) + % Make sure it is a cellarray + if ~iscell(div) + b = false; + return + end + + % Make sure it has the right shape + if numel(div) ~= 2 + b = false; + return + end + + if ~isDivisionVector(div{1}) || ~isDivisionVector(div{2}) + b = false; + return + end + + b = true; +end + +function b = isDivisionVector(v) + if isempty(v) + b = true; + return + end + + if any(v < 0) + b = false; + return + end + + b = true; +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+blockmatrix/isDivisionTest.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,25 @@ +function tests = isDivisionTest() + tests = functiontests(localfunctions); +end + +function testIsDivision(testCase) + cases = { + {[1 2] ,false}, % Must be a cell array + {{[1 2 3]} ,false}, % Must have two vectors + {{[],[]}, true} % No blocks is a valid blockmatrix + {{[1 2],[]} ,true}, + {{[],[1 2]} ,true}, + {{[2 2 2],[1 2]} ,true}, + {{[1 2],[1 0]} ,true}, + {{[0 2],[1 1]} ,true}, + {{[1 2],[1]} ,true}, + {{[1 2],[1], [1 2 3]} ,false}, + }; + + for i = 1:length(cases) + in = cases{i}{1}; + out = blockmatrix.isDivision(in); + expected = cases{i}{2}; + testCase.verifyEqual(out, expected, sprintf('Should return %d for %s', expected, toString(in))); + end +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+blockmatrix/multiply.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,17 @@ +function C = multiply(A, B) + [n_a, m_a] = size(A); + [n_b, m_b] = size(B); + + assert(m_a == n_b, 'Dimensions do not agree.') + + C = cell(n_a, m_b); + + for i = 1:n_a + for j = 1:m_b + C{i,j} = sparse(size(A{i,1},1), size(B{1,j},2)); + for k = 1:n_b + C{i,j} = C{i,j} + A{i,k}*B{k,j}; + end + end + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+blockmatrix/multiplyTest.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,57 @@ +function tests = multiplyTest() + tests = functiontests(localfunctions); +end + + +function testMultiply(testCase) + a11 = [ + 0.8147 0.1270; + 0.9058 0.9134; + ]; + a12 = [ + 0.6324 0.2785 0.9575; + 0.0975 0.5469 0.9649; + ]; + a21 = [ + 0.1576 0.9706; + ]; + a22 = [ + 0.9572 0.4854 0.8003; + ]; + A = { + a11 a12; + a21 a22; + }; + + b11 = [ + 0.1419 0.9157 0.9595; + 0.4218 0.7922 0.6557; + ]; + b12 = [ + 0.0357 0.9340; + 0.8491 0.6787; + ]; + b21 = [ + 0.7577 0.6555 0.0318; + 0.7431 0.1712 0.2769; + 0.3922 0.7060 0.0462; + ]; + b22 = [ + 0.0971 0.3171; + 0.8235 0.9502; + 0.6948 0.0344; + ]; + + B = { + b11 b12; + b21 b22; + }; + + + C = { + a11*b11 + a12*b21, a11*b12 + a12*b22; + a21*b11 + a22*b21, a21*b12 + a22*b22; + }; + + testCase.verifyEqual(blockmatrix.multiply(A,B), C); +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+blockmatrix/toMatrix.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,23 @@ +function A = toMatrix(bm) + if ~blockmatrix.isBlockmatrix(bm) + error('blockmatrix:toMatrix:NotABlockmatrix', 'Input is not a blockmatrix'); + end + + div = blockmatrix.getDivision(bm); + n = div{1}; + m = div{2}; + + N = sum(n); + M = sum(m); + + A = sparse(N,M); + + for i = 1:size(bm,1) + for j = 1:size(bm,2) + if isempty(bm{i,j}) + bm{i,j} = sparse(n(i),m(j)); + end + end + end + A = cell2mat(bm); +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+blockmatrix/toMatrixTest.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,78 @@ +function tests = toMatrixTest() + tests = functiontests(localfunctions); +end + +function testError(testCase) + testCase.verifyError(@()blockmatrix.toMatrix([]), 'blockmatrix:toMatrix:NotABlockmatrix') +end + +function testToMatrix(testCase) + cases = { + { + {}, + [], + }, + { + {1, 2; 3, 4}, + [1,2; 3,4], + } + { + { + [2 2; 2 1], [1; 2]; + [2 2], [1] + }, + [2 2 1; + 2 1 2; + 2 2 1], + }, + { + { + [2 2; 2 1], []; + [2 2], [1] + }, + [2 2 0; + 2 1 0; + 2 2 1], + }, + { + { + [2 2; 2 1], []; + [2 2], [] + }, + [2 2; + 2 1; + 2 2], + }, + { + { + [2 2; 2 1], [1; 2]; + [], [] + }, + [2 2 1; + 2 1 2], + }, + { + {zeros(0,0)}, + [], + }, + { + {zeros(3,0), zeros(3,0)}, + zeros(3,0), + }, + { + {zeros(3,0); zeros(2,0)}, + zeros(5,0), + }, + { + {zeros(0,3), zeros(0,2)}, + zeros(0,5), + }, + }; + + for i = 1:length(cases) + in = cases{i}{1}; + out = full(blockmatrix.toMatrix(in)); + expected = cases{i}{2}; + testCase.verifyEqual(out, expected); + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+blockmatrix/zero.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,20 @@ +% Creates a block matrix according to the division with zeros everywhere. +function bm = zero(div) + if ~blockmatrix.isDivision(div) + error('div is not a valid division'); + end + + n = div{1}; + m = div{2}; + + N = length(n); + M = length(m); + + bm = cell(N,M); + + for i = 1:N + for j = 1:M + bm{i,j} = sparse(n(i),m(j)); + end + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+blockmatrix/zeroTest.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,68 @@ +function tests = zeroTest() + tests = functiontests(localfunctions); +end + +function testZero(testCase) + cases = { + { + {[],[]}, + {}, + }, + { + {0,0}, + {[]}; + }, + { + {1,1}, + {0}; + }, + { + {2,1}, + {[0; 0]}; + }, + { + {1,2}, + {[0 0]}; + }, + { + {[1 2],2}, + {[0 0];[0 0; 0 0]}; + }, + { + {[1 2],[2 1]}, + {[0 0],[0];[0 0; 0 0],[0; 0]}; + }, + { + {[3],[0]}, + {zeros(3,0)}, + }, + + { + {[0],[3]}, + {zeros(0,3)}, + }, + { + {[0 2],[0 3]}, + { + zeros(0,0), zeros(0,3); + zeros(2,0), zeros(2,3); + }, + }, + }; + + for i = 1:length(cases) + out = convertToFull(blockmatrix.zero(cases{i}{1})); + expected = cases{i}{2}; + testCase.verifyEqual(out,expected); + end +end + + +function C = convertToFull(C) + [N,M] = size(C); + for i = 1:N + for j = 1:M + C{i,j} = full(C{i,j}); + end + end +end \ No newline at end of file
--- a/+draw/prompt_bezier.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+draw/prompt_bezier.m Tue Sep 11 15:58:35 2018 +0200 @@ -22,8 +22,8 @@ p.Color = Color.yellow; p.MarkerSize = 16; - C = grid.Curve.bezier(a,c1,c2,b); - fprintf('C = grid.Curve.bezier([%.3g; %.3g],[%.3g; %.3g],[%.3g; %.3g],[%.3g; %.3g]);\n',a,c1,c2,b) + C = parametrization.Curve.bezier(a,c1,c2,b); + fprintf('C = parametrization.Curve.bezier([%.3g; %.3g],[%.3g; %.3g],[%.3g; %.3g],[%.3g; %.3g]);\n',a,c1,c2,b) h = C.plot(); uistack(h,'bottom');
--- a/+draw/prompt_point.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+draw/prompt_point.m Tue Sep 11 15:58:35 2018 +0200 @@ -1,22 +1,23 @@ -function [p, button] = prompt_point(s,varargin) +function [p, button] = prompt_point(s, varargin) default_arg('s',[]) set(gcf,'Pointer','crosshair') if ~isempty(s) - fprintf(s,varargin{:}); + fprintf(s, varargin{:}); end - a = gca; + fh = gcf(); + ah = gca(); - function get_point(src,event) - cp = a.CurrentPoint; + function get_point(src, event) + cp = ah.CurrentPoint; p = cp(1,1:2)'; - a.ButtonDownFcn = []; + fh.WindowButtonUpFcn = []; end - a.ButtonDownFcn = @get_point; - waitfor(a,'ButtonDownFcn', []) + fh.WindowButtonUpFcn = @get_point; + waitfor(fh,'WindowButtonUpFcn', []) set(gcf,'Pointer','arrow')
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/Cartesian.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,197 @@ +classdef Cartesian < grid.Structured + properties + n % Number of points in the grid + d % Number of dimensions + m % Number of points in each direction + x % Cell array of vectors with node placement for each dimension. + h % Spacing/Scaling + lim % Cell array of left and right boundaries for each dimension. + end + + % General d dimensional grid with n points + methods + % Creates a cartesian grid given vectors conatining the coordinates + % in each direction + function obj = Cartesian(varargin) + obj.d = length(varargin); + + for i = 1:obj.d + assert(isnumeric(varargin{i}), 'Coordinate inputs must be vectors.') + + obj.x{i} = varargin{i}; + obj.m(i) = length(varargin{i}); + end + + obj.n = prod(obj.m); + if obj.n == 0 + error('grid:Cartesian:EmptyGrid','Input parameter gives an empty grid.') + end + + obj.h = []; + + obj.lim = cell(1,obj.d); + for i = 1:obj.d + obj.lim{i} = {obj.x{i}(1), obj.x{i}(end)}; + end + end + % n returns the number of points in the grid + function o = N(obj) + o = obj.n; + end + + % d returns the spatial dimension of the grid + function o = D(obj) + o = obj.d; + end + + function m = size(obj) + m = obj.m; + end + + % points returns a n x d matrix containing the coordianets for all points. + % points are ordered according to the kronecker product with X*Y*Z + function X = points(obj) + X = zeros(obj.n, obj.d); + + for i = 1:obj.d + if iscolumn(obj.x{i}) + c = obj.x{i}; + else + c = obj.x{i}'; + end + + m_before = prod(obj.m(1:i-1)); + m_after = prod(obj.m(i+1:end)); + + X(:,i) = kr(ones(m_before,1),c,ones(m_after,1)); + end + end + + % matrices returns a cell array with coordinates in matrix form. + % For 2d case these will have to be transposed to work with plotting routines. + function X = matrices(obj) + + if obj.d == 1 % There is no 1d matrix data type in matlab, handle special case + X{1} = reshape(obj.x{1}, [obj.m 1]); + return + end + + X = cell(1,obj.d); + for i = 1:obj.d + s = ones(1,obj.d); + s(i) = obj.m(i); + + t = reshape(obj.x{i},s); + + s = obj.m; + s(i) = 1; + X{i} = repmat(t,s); + end + end + + function h = scaling(obj) + if isempty(obj.h) + error('grid:Cartesian:NoScalingSet', 'No scaling set') + end + + h = obj.h; + end + + % Restricts the grid function gf on obj to the subgrid g. + % Only works for even multiples + function gf = restrictFunc(obj, gf, g) + m1 = obj.m; + m2 = g.m; + + % Check the input + if prod(m1) ~= numel(gf) + error('grid:Cartesian:restrictFunc:NonMatchingFunctionSize', 'The grid function has to few or too many points.'); + end + + if ~all(mod(m1-1,m2-1) == 0) + error('grid:Cartesian:restrictFunc:NonMatchingGrids', 'Only integer downsamplings are allowed'); + end + + % Calculate stride for each dimension + stride = (m1-1)./(m2-1); + + % Create downsampling indecies + I = {}; + for i = 1:length(m1) + I{i} = 1:stride(i):m1(i); + end + + gf = reshapeRowMaj(gf, m1); + gf = gf(I{:}); + gf = reshapeRowMaj(gf, prod(m2)); + end + + % Projects the grid function gf on obj to the grid g. + 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/CartesianTest.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,318 @@ +function tests = CartesianTest() + tests = functiontests(localfunctions); +end + + +function testWarningEmptyGrid(testCase) + in = { + {[]}, + {[],[1]}, + {[1],[2], []}, + }; + + for i = 1:length(in) + testCase.verifyError(@()grid.Cartesian(in{i}{:}),'grid:Cartesian:EmptyGrid'); + end +end + +function testN(testCase) + in = { + {[1 2 3]}, + {[1 2 3],[1 2]}, + {[1 2 3],[1 2 3]}, + {[1 2 3],[1 2 3], [1]}, + {[1 2 3],[1 2 3], [1 3 4]}, + }; + + out = [3,6,9,9,27]; + + for i = 1:length(in) + g = grid.Cartesian(in{i}{:}); + testCase.verifyEqual(g.N(),out(i)); + end +end + + +function testD(testCase) + in = { + {[1 2 3]}, + {[1 2 3],[1 2]}, + {[1 2 3],[1 2 3]}, + {[1 2 3],[1 2 3], [1]}, + {[1 2 3],[1 2 3], [1 3 4]}, + }; + + out = [1,2,2,3,3]; + + for i = 1:length(in) + g = grid.Cartesian(in{i}{:}); + testCase.verifyEqual(g.D(),out(i)); + end +end + +function testSize(testCase) + in = { + {[1 2 3]}, + {[1 2 3],[1 2]}, + {[1 2 3],[1 2 3]}, + {[1 2 3],[1 2 3], [1]}, + {[1 2 3],[1 2 3], [1 3 4]}, + }; + + out = { + [3], + [3 2], + [3 3], + [3 3 1], + [3 3 3], + }; + + for i = 1:length(in) + g = grid.Cartesian(in{i}{:}); + testCase.verifyEqual(g.size(),out{i}); + end +end + +function testPoints(testCase) + in = { + {[1 2]}, + {[1 2],[3 4]}, + {[1 2],[3 4], [5 6]}, + }; + + out = { + [[1; 2]], + [[1; 1; 2; 2],[3; 4; 3; 4]], + [[1; 1; 1; 1; 2; 2; 2; 2],[3; 3; 4; 4; 3; 3; 4; 4],[ 5; 6; 5; 6; 5; 6; 5; 6]], + }; + + for i = 1:length(in) + g = grid.Cartesian(in{i}{:}); + testCase.verifyEqual(g.points(),out{i}); + end +end + +function testMatrices(testCase) + in = { + {[1 2]}, + {[1 2],[3 4]}, + {[1 2],[3 4], [5 6]}, + }; + + out{1}{1} = [1; 2]; + + out{2}{1} = [1, 1; 2, 2]; + out{2}{2} = [3, 4; 3, 4]; + + out{3}{1}(:,:,1) = [1, 1; 2, 2]; + out{3}{1}(:,:,2) = [1, 1; 2, 2]; + + out{3}{2}(:,:,1) = [3, 4; 3, 4]; + out{3}{2}(:,:,2) = [3, 4; 3, 4]; + + out{3}{3}(:,:,1) = [5, 5; 5, 5]; + out{3}{3}(:,:,2) = [6, 6; 6, 6]; + + for i = 1:length(in) + g = grid.Cartesian(in{i}{:}); + testCase.verifyEqual(g.matrices(),out{i}); + end +end + + +function testRestrictFuncInvalidInput(testCase) + inG1 = { + {[1 2 3 4 5]}, + {[1 2 3],[4 5 6 7 8]}, + {[1 2 3],[4 5 6 7 8]}, + {[1 2 3],[4 5 6 7 8]}, + }; + + inG2 = { + {[1 3 4 5]}, + {[1 3],[4 5 6 8]}, + {[1 3],[4 6 8]}, + {[1 3],[4 6 8]}, + }; + + inGf = { + [1; 2; 3; 4; 5], + [14; 15; 16; 17; 18; 24; 25; 26; 27; 28; 34; 35; 36; 37; 38]; + [14; 15; 16; 17; 18; 24; 25; 26; 27; 28; 34; 35; 36]; + [14; 15; 16; 17; 18; 24; 25; 26; 27; 28; 34; 35; 36; 37; 38; 39; 40]; + }; + + out = { + 'grid:Cartesian:restrictFunc:NonMatchingGrids', + 'grid:Cartesian:restrictFunc:NonMatchingGrids', + 'grid:Cartesian:restrictFunc:NonMatchingFunctionSize', + 'grid:Cartesian:restrictFunc:NonMatchingFunctionSize', + }; + + for i = 1:length(inG1) + g1 = grid.Cartesian(inG1{i}{:}); + g2 = grid.Cartesian(inG2{i}{:}); + testCase.verifyError(@()g1.restrictFunc(inGf{i},g2),out{i}); + end +end + +function testRestrictFunc(testCase) + inG1 = { + {[1 2 3 4 5]}, + {[1 2 3],[4 5 6 7 8]}, + }; + + inG2 = { + {[1 3 5]}, + {[1 3],[4 6 8]}, + }; + + inGf = { + [1; 2; 3; 4; 5], + [14; 15; 16; 17; 18; 24; 25; 26; 27; 28; 34; 35; 36; 37; 38]; + }; + + outGf = { + [1; 3; 5], + [14; 16; 18; 34; 36; 38]; + }; + + for i = 1:length(inG1) + g1 = grid.Cartesian(inG1{i}{:}); + g2 = grid.Cartesian(inG2{i}{:}); + testCase.verifyEqual(g1.restrictFunc(inGf{i}, g2), outGf{i}); + end +end + +function testScaling(testCase) + in = {[1 2 3], [1 2]}; + g = grid.Cartesian(in{:}); + + testCase.verifyError(@()g.scaling(),'grid:Cartesian:NoScalingSet'); + + g.h = [2 1]; + 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
--- a/+grid/Curve.m Tue Sep 11 13:24:08 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,388 +0,0 @@ -classdef Curve - properties - g - gp - transformation - end - - methods - %TODO: - % Concatenation of curves - % Subsections of curves - % Stretching of curve parameter - done for arc length. - % Curve to cell array of linesegments - - % Returns a curve object. - % g -- curve parametrization for parameter between 0 and 1 - % gp -- parametrization of curve derivative - function obj = Curve(g,gp,transformation) - default_arg('gp',[]); - default_arg('transformation',[]); - p_test = g(0); - assert(all(size(p_test) == [2,1]), 'A curve parametrization must return a 2x1 vector.'); - - if ~isempty(transformation) - transformation.base_g = g; - transformation.base_gp = gp; - [g,gp] = grid.Curve.transform_g(g,gp,transformation); - end - - obj.g = g; - obj.gp = gp; - obj.transformation = transformation; - - end - - function n = normal(obj,t) - assert(~isempty(obj.gp),'Curve has no derivative!'); - deriv = obj.gp(t); - normalization = sqrt(sum(deriv.^2,1)); - n = [-deriv(2,:)./normalization; deriv(1,:)./normalization]; - end - - - % Plots a curve g(t) for 0<t<1, using n points. Returns a handle h to the plotted curve. - % h = plot_curve(g,n) - function h = plot(obj,n) - default_arg('n',100); - - t = linspace(0,1,n); - p = obj.g(t); - h = line(p(1,:),p(2,:)); - end - - function h= plot_normals(obj,l,n,m) - default_arg('l',0.1); - default_arg('n',10); - default_arg('m',100); - t_n = linspace(0,1,n); - - normals = obj.normal(t_n)*l; - - n0 = obj.g(t_n); - n1 = n0 + normals; - - h = line([n0(1,:); n1(1,:)],[n0(2,:); n1(2,:)]); - set(h,'Color',Color.red); - obj.plot(m); - end - - function h= show(obj,name) - p = obj.g(1/2); - n = obj.normal(1/2); - p = p + n*0.1; - - % Add arrow - - h = text(p(1),p(2),name); - h.HorizontalAlignment = 'center'; - h.VerticalAlignment = 'middle'; - - obj.plot(); - end - % Shows curve with name and arrow for direction. - - % Length of arc from parameter t0 to t1 (which may be vectors). - % Computed using derivative. - function L = arcLength(obj,t0,t1) - assert(~isempty(obj.gp),'Curve has no derivative!'); - speed = @(t) sqrt(sum(obj.gp(t).^2,1)); - L = integral_vec(speed,t0,t1); - end - - % Creates the arc length parameterization of a curve. - % N -- number of points used to approximate the arclength function - function curve = arcLengthParametrization(obj,N) - default_arg('N',100); - assert(~isempty(obj.gp),'Curve has no derivative!'); - - % Construct arcLength function using splines - tvec = linspace(0,1,N); - arcVec = obj.arcLength(0,tvec); - tFunc = spline(arcVec,tvec); % t as a function of arcLength - L = obj.arcLength(0,1); - arcPar = @(s) tFunc(s*L); - - % New function and derivative - g_new = @(t)obj.g(arcPar(t)); - gp_new = @(t) normalize(obj.gp(arcPar(t))); - curve = grid.Curve(g_new,gp_new); - - end - - % how to make it work for methods without returns - function p = subsref(obj,S) - %Should i add error checking here? - %Maybe if you want performance you fetch obj.g and then use that - switch S(1).type - case '()' - p = obj.g(S.subs{1}); - % case '.' - - % p = obj.(S.subs); - otherwise - p = builtin('subsref',obj,S); - % error() - end - end - - - %% TRANSFORMATION OF A CURVE - function D = reverse(C) - % g = C.g; - % gp = C.gp; - % D = grid.Curve(@(t)g(1-t),@(t)-gp(1-t)); - D = C.transform([],[],-1); - end - - function D = transform(C,A,b,flip) - default_arg('A',[1 0; 0 1]); - default_arg('b',[0; 0]); - default_arg('flip',1); - if isempty(C.transformation) - g = C.g; - gp = C.gp; - transformation.A = A; - transformation.b = b; - transformation.flip = flip; - else - g = C.transformation.base_g; - gp = C.transformation.base_gp; - A_old = C.transformation.A; - b_old = C.transformation.b; - flip_old = C.transformation.flip; - - transformation.A = A*A_old; - transformation.b = A*b_old + b; - transformation.flip = flip*flip_old; - end - - D = grid.Curve(g,gp,transformation); - - end - - function D = translate(C,a) - g = C.g; - gp = C.gp; - - % function v = g_fun(t) - % x = g(t); - % v(1,:) = x(1,:)+a(1); - % v(2,:) = x(2,:)+a(2); - % end - - % D = grid.Curve(@g_fun,gp); - - D = C.transform([],a); - end - - function D = mirror(C, a, b) - assert_size(a,[2,1]); - assert_size(b,[2,1]); - - g = C.g; - gp = C.gp; - - l = b-a; - lx = l(1); - ly = l(2); - - - % fprintf('Singular?\n') - - A = [lx^2-ly^2 2*lx*ly; 2*lx*ly ly^2-lx^2]/(l'*l); - - % function v = g_fun(t) - % % v = a + A*(g(t)-a) - % x = g(t); - - % ax1 = x(1,:)-a(1); - % ax2 = x(2,:)-a(2); - % v(1,:) = a(1)+A(1,:)*[ax1;ax2]; - % v(2,:) = a(2)+A(2,:)*[ax1;ax2]; - % end - - % function v = gp_fun(t) - % v = A*gp(t); - % end - - % D = grid.Curve(@g_fun,@gp_fun); - - % g = A(g-a)+a = Ag - Aa + a; - b = - A*a + a; - D = C.transform(A,b); - - end - - function D = rotate(C,a,rad) - assert_size(a, [2,1]); - assert_size(rad, [1,1]); - g = C.g; - gp = C.gp; - - - A = [cos(rad) -sin(rad); sin(rad) cos(rad)]; - - % function v = g_fun(t) - % % v = a + A*(g(t)-a) - % x = g(t); - - % ax1 = x(1,:)-a(1); - % ax2 = x(2,:)-a(2); - % v(1,:) = a(1)+A(1,:)*[ax1;ax2]; - % v(2,:) = a(2)+A(2,:)*[ax1;ax2]; - % end - - % function v = gp_fun(t) - % v = A*gp(t); - % end - - % D = grid.Curve(@g_fun,@gp_fun); - - - % g = A(g-a)+a = Ag - Aa + a; - b = - A*a + a; - D = C.transform(A,b); - end - end - - methods (Static) - - % Computes the derivative of g: R -> R^2 using an operator D1 - function gp_out = numericalDerivative(g,D1) - m = length(D1); - t = linspace(0,1,m); - gVec = g(t)'; - gpVec = (D1*gVec)'; - - gp1_fun = spline(t,gpVec(1,:)); - gp2_fun = spline(t,gpVec(2,:)); - gp_out = @(t) [gp1_fun(t);gp2_fun(t)]; - end - - function obj = line(p1, p2) - - function v = g_fun(t) - v(1,:) = p1(1) + t.*(p2(1)-p1(1)); - v(2,:) = p1(2) + t.*(p2(2)-p1(2)); - end - g = @g_fun; - - obj = grid.Curve(g); - end - - function obj = circle(c,r,phi) - default_arg('phi',[0; 2*pi]) - default_arg('c',[0; 0]) - default_arg('r',1) - - function v = g_fun(t) - w = phi(1)+t*(phi(2)-phi(1)); - v(1,:) = c(1) + r*cos(w); - v(2,:) = c(2) + r*sin(w); - end - - function v = g_fun_deriv(t) - w = phi(1)+t*(phi(2)-phi(1)); - v(1,:) = -(phi(2)-phi(1))*r*sin(w); - v(2,:) = (phi(2)-phi(1))*r*cos(w); - end - - obj = grid.Curve(@g_fun,@g_fun_deriv); - end - - function obj = bezier(p0, p1, p2, p3) - function v = g_fun(t) - v(1,:) = (1-t).^3*p0(1) + 3*(1-t).^2.*t*p1(1) + 3*(1-t).*t.^2*p2(1) + t.^3*p3(1); - v(2,:) = (1-t).^3*p0(2) + 3*(1-t).^2.*t*p1(2) + 3*(1-t).*t.^2*p2(2) + t.^3*p3(2); - end - - function v = g_fun_deriv(t) - v(1,:) = 3*(1-t).^2*(p1(1)-p0(1)) + 6*(1-t).*t*(p2(1)-p1(1)) + 3*t.^2*(p3(1)-p2(1)); - v(2,:) = 3*(1-t).^2*(p1(2)-p0(2)) + 6*(1-t).*t*(p2(2)-p1(2)) + 3*t.^2*(p3(2)-p2(2)); - end - - obj = grid.Curve(@g_fun,@g_fun_deriv); - end - - - function [g_out,gp_out] = transform_g(g,gp,tr) - A = tr.A; - b = tr.b; - flip = tr.flip; - - function v = g_fun_noflip(t) - % v = A*g + b - x = g(t); - - v(1,:) = A(1,:)*x+b(1); - v(2,:) = A(2,:)*x+b(2); - end - - function v = g_fun_flip(t) - % v = A*g + b - x = g(1-t); - - v(1,:) = A(1,:)*x+b(1); - v(2,:) = A(2,:)*x+b(2); - end - - - switch flip - case 1 - g_out = @g_fun_noflip; - gp_out = @(t)A*gp(t); - case -1 - g_out = @g_fun_flip; - gp_out = @(t)-A*gp(1-t); - end - end - - end -end - - - -function g_norm = normalize(g0) - g1 = g0(1,:); - g2 = g0(2,:); - normalization = sqrt(sum(g0.^2,1)); - g_norm = [g1./normalization; g2./normalization]; -end - -function I = integral_vec(f,a,b) -% Wrapper around the built-in function integral that -% handles multiple limits. - - Na = length(a); - Nb = length(b); - assert(Na == 1 || Nb == 1 || Na==Nb,... - 'a and b must have same length, unless one is a scalar.'); - - if(Na>Nb); - I = zeros(size(a)); - for i = 1:Na - I(i) = integral(f,a(i),b); - end - elseif(Nb>Na) - I = zeros(size(b)); - for i = 1:Nb - I(i) = integral(f,a,b(i)); - end - else - I = zeros(size(b)); - for i = 1:Nb - I(i) = integral(f,a(i),b(i)); - end - end -end - -% Returns a function handle to the spline. -function f = spline(tval,fval,spline_order) - default_arg('spline_order',4); - [m,~] = size(tval); - assert(m==1,'Need row vectors.'); - - f_spline = spapi( optknt(tval,spline_order), tval, fval ); - f = @(t) fnval(f_spline,t); -end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/Curvilinear.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,173 @@ +classdef Curvilinear < grid.Structured & grid.Mapped + properties + logic % Grid of Logical domain + coords % N x D matrix with coordinates of each point in the physical domain + end + + methods + % Creates a curvilinear grid. + % Ex: grid.Curvilinear(mapping, xi, eta, ...) + % mapping -- either a function handle, a matrix or a cell array with physical coordinates. + % A function handle should be a vector valued function of the coordinate mapping. + % A matrix should be a grid function (N*D x 1 vector) or a N x D + % A cell array should be a 1 x D cell array with either N x 1 vectors + % or matrices of the same dimesions as the logical grid. + % xi, eta, ... -- are the coordinate positions of the cartesian logical grid. + function obj = Curvilinear(mapping, varargin) + xi = varargin; + obj.logic = grid.Cartesian(xi{:}); + + % If mapping is a function evaluate it + if isa(mapping, 'function_handle') + if nargin(mapping) ~= length(varargin) + error('The dimension of the mapping does not match the dimension of the logical coordinates') + end + mapping = grid.evalOn(obj.logic, mapping); + end + + D = obj.logic.D(); + N = obj.logic.N(); + + obj.coords = zeros(N,D); + + if iscell(mapping) + obj.coords = cellMappingToCoords(mapping, N, D, obj.logic.m); + elseif isnumeric(mapping) + obj.coords = matrixMappingToCoords(mapping, N, D); + else + error('grid:Curvilinear:Curvilinear','mapping must be a function handle, a matrix or a cell array.'); + end + end + + function m = size(obj) + m = obj.logic.size(); + end + + % logicalGrid returns the domain grid of the mapping. + function g = logicalGrid(obj) + g = obj.logic; + end + + % mapping returns the mapped coordinates as a grid.Function + function m = mapping(obj); + m = obj.coords; + end + + % n returns the number of points in the grid + function o = N(obj) + o = obj.logic.N(); + end + + % d returns the spatial dimension of the grid + function o = D(obj) + o = obj.logic.D(); + end + + % points returns a n x d matrix containing the coordinates for all points. + function X = points(obj) + X = obj.coords; + end + + % Restricts the grid function gf on obj to the subgrid g. + function gf = restrictFunc(obj, gf, g) + gf = obj.logic.restrictFunc(gf, g.logic); + end + + % Projects the grid function gf on obj to the grid g. + function gf = projectFunc(obj, gf, g) + gf = obj.logic.projectFunc(gf,g.logic); + end + + function h = scaling(obj) + if isempty(obj.logic.h) + error('grid:Curvilinear:NoScalingSet','No scaling set'); + 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 + + +function coords = cellMappingToCoords(mapping, N, D, m) + if ~isequal(size(mapping),[1 D]) + error('grid:Curvilinear:Curvilinear','The cell array must be a 1xD array.'); + end + + if isequal(size(mapping{1}),[N 1]) + coords = cell2mat(mapping); + elseif isequal(size(mapping{1}), m) + for i = 1:length(mapping) + coords(:,i) = reshapeRowMaj(mapping{i}, [N 1]); + end + else + error('grid:Curvilinear:Curvilinear','The matrix must have size [N 1] or the same dimension as the grid. Actual: %s', toString(m)); + end +end + +function coords = matrixMappingToCoords(mapping, N, D) + if isequal(size(mapping), [N, D]) + coords = mapping; + elseif isequal(size(mapping), [N*D, 1]) + coords = reshapeRowMaj(mapping,[N D]); + else + error('grid:Curvilinear:Curvilinear','A matrix mapping must be of size [N D] or [N*D 1].'); + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/CurvilinearTest.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,131 @@ +function tests = CurvilinearTest() + tests = functiontests(localfunctions); +end + +function testMappingInputGridFunction(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 = { + [10, 1]; + [10*6, 2]; + [10*5*7, 3]; + }; + + + % How to test this? Just make sure it runs without errors. + + for i = 1:length(in) + g = grid.Curvilinear(in{i}{2},in{i}{1}{:}); + testCase.verifyEqual(size(g.coords),out{i}); + end +end + +function testMappingInputComponentMatrix(testCase) + in = { + {{1:3}, [1 2 3]'}, + {{1:2, 1:3}, [1 2 3 4 5 6; 7 8 9 10 11 12]'}, + }; + + for i = 1:length(in) + g = grid.Curvilinear(in{i}{2},in{i}{1}{:}); + testCase.verifyEqual(g.coords,in{i}{2}); + end +end + +function testMappingInputCellOfMatrix(testCase) + + in = { + {{1:3}, {[1 2 3]'}}, + {{1:2, 1:3}, {[1 2 3; 4 5 6], [7 8 9; 10 11 12]}}, + }; + + out = { + [1 2 3]', + [1 2 3 4 5 6; 7 8 9 10 11 12]', + }; + + for i = 1:length(in) + g = grid.Curvilinear(in{i}{2},in{i}{1}{:}); + testCase.verifyEqual(g.coords,out{i}); + end +end + +function testMappingInputCellOfVectors(testCase) + in = { + {{1:3}, {[1 2 3]'}}, + {{1:2, 1:3}, {[1 2 3 4 5 6]', [7 8 9 10 11 12]'}}, + }; + + out = { + [1 2 3]', + [1 2 3 4 5 6; 7 8 9 10 11 12]', + }; +end + +function testMappingInputError(testCase) + testCase.verifyFail(); +end + +function testScaling(testCase) + in = {{1:2, 1:3}, {[1 2 3 4 5 6]', [7 8 9 10 11 12]'}}; + g = grid.Curvilinear(in{2},in{1}{:}); + + testCase.verifyError(@()g.scaling(),'grid:Curvilinear:NoScalingSet'); + + g.logicalGrid.h = [2 1]; + 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 +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/Empty.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,53 @@ +classdef Empty < grid.Grid & grid.Structured + properties + dim + end + + methods + function obj = Empty(D) + obj.dim = D; + end + % n returns the number of points in the grid + function o = N(obj) + o = 0; + end + + % d returns the spatial dimension of the grid + function o = D(obj) + o = obj.dim; + end + + % points returns a n x d matrix containing the coordinates for all points. + function X = points(obj) + X = sparse(0,obj.dim); + end + + % Restricts the grid function gf on obj to the subgrid g. + function gf = restrictFunc(obj, gf, g) + error('Restrict does not make sense for an empty grid') + end + + % Projects the grid function gf on obj to the grid g. + function gf = projectFunc(obj, gf, g) + error('Project does not make sense for an empty grid') + end + + % Return the grid.boundaryIdentifiers of all boundaries in a cell array. + function bs = getBoundaryNames(obj) + bs = {}; + end + + % Return coordinates for the given boundary + function b = getBoundary(obj, name) + b = sparse(0,obj.dim-1); + end + + function h = scaling(obj) + h = 1; + end + + function s = size(obj) + s = zeros(1, obj.dim); + end + end +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/Grid.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,25 @@ +classdef Grid < handle + % General d dimensional grid with n points + methods (Abstract) + % n returns the number of points in the grid + o = N(obj) + + % d returns the spatial dimension of the grid + o = D(obj) + + % points returns a n x d matrix containing the coordinates for all points. + X = points(obj) + + % Restricts the grid function gf on obj to the subgrid g. + gf = restrictFunc(obj, gf, g) + + % Projects the grid function gf on obj to the grid g. + gf = projectFunc(obj, gf, g) + + % Return the grid.boundaryIdentifiers of all boundaries in a cell array. + bs = getBoundaryNames(obj) + + % Return coordinates for the given boundary + b = getBoundary(obj, name) + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/Mapped.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,10 @@ +classdef Mapped < grid.Grid + % General grid mapping + methods (Abstract) + % logicalGrid returns the domain grid of the mapping. + g = logicalGrid(obj); + + % mapping returns the mapped coordinates as a N x D component matrix + m = mapping(obj); + end +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/Structured.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,7 @@ +classdef Structured < grid.Grid + methods (Abstract) + % Returns the size of the grid in each dimension m = [mx my mz ...] + m = size(obj); % Is this a good idea? Isn't immersed a structured grid? + h = scaling(obj); + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/TODO.txt Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,1 @@ +% TODO: Rename grid package. name conflicts with built in function
--- a/+grid/Ti.m Tue Sep 11 13:24:08 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,201 +0,0 @@ -classdef Ti - properties - gs % {4}Curve - S % FunctionHandle(u,v) - end - - methods - % TODO function to label boundary names. - % function to find largest and smallest delta h in the grid. Maybe shouldnt live here - function obj = Ti(C1,C2,C3,C4) - obj.gs = {C1,C2,C3,C4}; - - g1 = C1.g; - g2 = C2.g; - g3 = C3.g; - g4 = C4.g; - - A = g1(0); - B = g2(0); - C = g3(0); - D = g4(0); - - function o = S_fun(u,v) - x1 = g1(u); - x2 = g2(v); - x3 = g3(1-u); - x4 = g4(1-v); - o1 = (1-v).*x1(1,:) + u.*x2(1,:) + v.*x3(1,:) + (1-u).*x4(1,:) ... - -((1-u)*(1-v).*A(1,:) + u*(1-v).*B(1,:) + u*v.*C(1,:) + (1-u)*v.*D(1,:)); - o2 = (1-v).*x1(2,:) + u.*x2(2,:) + v.*x3(2,:) + (1-u).*x4(2,:) ... - -((1-u)*(1-v).*A(2,:) + u*(1-v).*B(2,:) + u*v.*C(2,:) + (1-u)*v.*D(2,:)); - - o = [o1;o2]; - end - - obj.S = @S_fun; - end - - function [X,Y] = map(obj,u,v) - default_arg('v',u); - - if isscalar(u) - u = linspace(0,1,u); - end - - if isscalar(v) - v = linspace(0,1,v); - end - - S = obj.S; - - nu = length(u); - nv = length(v); - - X = zeros(nv,nu); - Y = zeros(nv,nu); - - u = rowVector(u); - v = rowVector(v); - - for i = 1:nv - p = S(u,v(i)); - X(i,:) = p(1,:); - Y(i,:) = p(2,:); - end - end - - function h = plot(obj,nu,nv) - S = obj.S; - - default_arg('nv',nu) - - u = linspace(0,1,nu); - v = linspace(0,1,nv); - - m = 100; - - X = zeros(nu+nv,m); - Y = zeros(nu+nv,m); - - - t = linspace(0,1,m); - for i = 1:nu - p = S(u(i),t); - X(i,:) = p(1,:); - Y(i,:) = p(2,:); - end - - for i = 1:nv - p = S(t,v(i)); - X(i+nu,:) = p(1,:); - Y(i+nu,:) = p(2,:); - end - - h = line(X',Y'); - end - - - function h = show(obj,nu,nv) - default_arg('nv',nu) - S = obj.S; - - if(nu>2 || nv>2) - h_grid = obj.plot(nu,nv); - set(h_grid,'Color',[0 0.4470 0.7410]); - end - - h_bord = obj.plot(2,2); - set(h_bord,'Color',[0.8500 0.3250 0.0980]); - set(h_bord,'LineWidth',2); - end - - - % TRANSFORMATIONS - function ti = translate(obj,a) - gs = obj.gs; - - for i = 1:length(gs) - new_gs{i} = gs{i}.translate(a); - end - - ti = grid.Ti(new_gs{:}); - end - - % Mirrors the Ti so that the resulting Ti is still left handed. - % (Corrected by reversing curves and switching e and w) - function ti = mirror(obj, a, b) - gs = obj.gs; - - new_gs = cell(1,4); - - new_gs{1} = gs{1}.mirror(a,b).reverse(); - new_gs{3} = gs{3}.mirror(a,b).reverse(); - new_gs{2} = gs{4}.mirror(a,b).reverse(); - new_gs{4} = gs{2}.mirror(a,b).reverse(); - - ti = grid.Ti(new_gs{:}); - end - - function ti = rotate(obj,a,rad) - gs = obj.gs; - - for i = 1:length(gs) - new_gs{i} = gs{i}.rotate(a,rad); - end - - ti = grid.Ti(new_gs{:}); - end - - function ti = rotate_edges(obj,n); - new_gs = cell(1,4); - for i = 0:3 - new_i = mod(i - n,4); - new_gs{new_i+1} = obj.gs{i+1}; - end - ti = grid.Ti(new_gs{:}); - end - end - - methods(Static) - function obj = points(p1, p2, p3, p4) - g1 = grid.Curve.line(p1,p2); - g2 = grid.Curve.line(p2,p3); - g3 = grid.Curve.line(p3,p4); - g4 = grid.Curve.line(p4,p1); - - obj = grid.Ti(g1,g2,g3,g4); - end - - function label(varargin) - if nargin == 2 && ischar(varargin{2}) - label_impl(varargin{:}); - else - for i = 1:length(varargin) - label_impl(varargin{i},inputname(i)); - end - end - - - function label_impl(ti,str) - S = ti.S; - - pc = S(0.5,0.5); - - margin = 0.1; - pw = S( margin, 0.5); - pe = S(1-margin, 0.5); - ps = S( 0.5, margin); - pn = S( 0.5, 1-margin); - - - ti.show(2,2); - grid.place_label(pc,str); - grid.place_label(pw,'w'); - grid.place_label(pe,'e'); - grid.place_label(ps,'s'); - grid.place_label(pn,'n'); - end - end - end -end \ No newline at end of file
--- a/+grid/Ti3D.m Tue Sep 11 13:24:08 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,253 +0,0 @@ -classdef Ti3D - properties - gs % {6}Surfaces - V % FunctionHandle(XI,ETA,ZETA) - end - - methods - % TODO write all fancy features for flipping around with the surfaces - % Each surface is defined with an outward facing outward and choosing - % the "corner" where XI=0 if not possible the corner where ETA=0 is choosen - function obj = Ti3D(CW,CE,CS,CN,CB,CT) - obj.gs = {CE,CW,CS,CN,CB,CT}; - - gw = CW.g; - ge = CE.g; - gs = CS.g; - gn = CN.g; - gb = CB.g; - gt = CT.g; - - function o = V_fun(XI,ETA,ZETA) - XI=XI'; - ETA=ETA'; - ZETA=ZETA'; - - one=0*ETA+1; - zero=0*ETA; - - Sw = gw(ETA,(1-ZETA)); - Se = ge((1-ETA),(1-ZETA)); - Ss = gs(XI,ZETA); - Sn = gn((1-XI),(1-ZETA)); - Sb = gb((1-XI),ETA); - St = gt(XI,ETA); - - Ewt = gw(ETA,zero); - Ewb = gw(ETA,one); - Ews = gw(zero,1-ZETA); - Ewn = gw(one,1-ZETA); - Eet = ge(1-ETA,zero); - Eeb = ge(1-ETA,one); - Ees = ge(one,1-ZETA); - Een = ge(zero,1-ZETA); - Enb = gn(1-XI,one); - Ent = gn(1-XI,zero); - Est = gs(XI,one); - Esb = gs(XI,zero); - - Cwbs = gw(zero,one); - Cwbn = gw(one,one); - Cwts = gw(zero,zero); - Cwtn = gw(one,zero); - Cebs = ge(one,one); - Cebn = ge(zero,one); - Cets = ge(one,zero); - Cetn = ge(zero,zero); - - - X1 = (1-XI).*Sw(1,:,:) + XI.*Se(1,:,:); - X2 = (1-ETA).*Ss(1,:,:) + ETA.*Sn(1,:,:); - X3 = (1-ZETA).*Sb(1,:,:) + ZETA.*St(1,:,:); - - X12 = (1-XI).*(1-ETA).*Ews(1,:,:) + (1-XI).*ETA.*Ewn(1,:,:) + XI.*(1-ETA).*Ees(1,:,:) + XI.*ETA.*Een(1,:,:); - X13 = (1-XI).*(1-ZETA).*Ewb(1,:,:) + (1-XI).*ZETA.*Ewt(1,:,:) + XI.*(1-ZETA).*Eeb(1,:,:) + XI.*ZETA.*Eet(1,:,:); - X23 = (1-ETA).*(1-ZETA).*Esb(1,:,:) + (1-ETA).*ZETA.*Est(1,:,:) + ETA.*(1-ZETA).*Enb(1,:,:) + ETA.*ZETA.*Ent(1,:,:); - - X123 = (1-XI).*(1-ETA).*(1-ZETA).*Cwbs(1,:,:) + (1-XI).*(1-ETA).*ZETA.*Cwts(1,:,:) + (1-XI).*ETA.*(1-ZETA).*Cwbn(1,:,:) + ... - (1-XI).*ETA.*ZETA.*Cwtn(1,:,:) + XI.*(1-ETA).*(1-ZETA).*Cebs(1,:,:) + XI.*(1-ETA).*ZETA.*Cets(1,:,:) + ... - XI.*ETA.*(1-ZETA).*Cebn(1,:,:) + XI.*ETA.*ZETA.*Cetn(1,:,:); - - X = X1 + X2 + X3 - X12 - X13 - X23 + X123; - - - Y1 = (1-XI).*Sw(2,:,:) + XI.*Se(2,:,:); - Y2 = (1-ETA).*Ss(2,:,:) + ETA.*Sn(2,:,:); - Y3 = (1-ZETA).*Sb(2,:,:) + ZETA.*St(2,:,:); - - Y12 = (1-XI).*(1-ETA).*Ews(2,:,:) + (1-XI).*ETA.*Ewn(2,:,:) + XI.*(1-ETA).*Ees(2,:,:) + XI.*ETA.*Een(2,:,:); - Y13 = (1-XI).*(1-ZETA).*Ewb(2,:,:) + (1-XI).*ZETA.*Ewt(2,:,:) + XI.*(1-ZETA).*Eeb(2,:,:) + XI.*ZETA.*Eet(2,:,:); - Y23 = (1-ETA).*(1-ZETA).*Esb(2,:,:) + (1-ETA).*ZETA.*Est(2,:,:) + ETA.*(1-ZETA).*Enb(2,:,:) + ETA.*ZETA.*Ent(2,:,:); - - Y123 = (1-XI).*(1-ETA).*(1-ZETA).*Cwbs(2,:,:) + (1-XI).*(1-ETA).*ZETA.*Cwts(2,:,:) + (1-XI).*ETA.*(1-ZETA).*Cwbn(2,:,:) + ... - (1-XI).*ETA.*ZETA.*Cwtn(2,:,:) + XI.*(1-ETA).*(1-ZETA).*Cebs(2,:,:) + XI.*(1-ETA).*ZETA.*Cets(2,:,:) + ... - XI.*ETA.*(1-ZETA).*Cebn(2,:,:) + XI.*ETA.*ZETA.*Cetn(2,:,:); - - Y = Y1 + Y2 + Y3 - Y12 - Y13 - Y23 + Y123; - - - Z1 = (1-XI).*Sw(3,:,:) + XI.*Se(3,:,:); - Z2 = (1-ETA).*Ss(3,:,:) + ETA.*Sn(3,:,:); - Z3 = (1-ZETA).*Sb(3,:,:) + ZETA.*St(3,:,:); - - Z12 = (1-XI).*(1-ETA).*Ews(3,:,:) + (1-XI).*ETA.*Ewn(3,:,:) + XI.*(1-ETA).*Ees(3,:,:) + XI.*ETA.*Een(3,:,:); - Z13 = (1-XI).*(1-ZETA).*Ewb(3,:,:) + (1-XI).*ZETA.*Ewt(3,:,:) + XI.*(1-ZETA).*Eeb(3,:,:) + XI.*ZETA.*Eet(3,:,:); - Z23 = (1-ETA).*(1-ZETA).*Esb(3,:,:) + (1-ETA).*ZETA.*Est(3,:,:) + ETA.*(1-ZETA).*Enb(3,:,:) + ETA.*ZETA.*Ent(3,:,:); - - Z123 = (1-XI).*(1-ETA).*(1-ZETA).*Cwbs(3,:,:) + (1-XI).*(1-ETA).*ZETA.*Cwts(3,:,:) + (1-XI).*ETA.*(1-ZETA).*Cwbn(3,:,:) + ... - (1-XI).*ETA.*ZETA.*Cwtn(3,:,:) + XI.*(1-ETA).*(1-ZETA).*Cebs(3,:,:) + XI.*(1-ETA).*ZETA.*Cets(3,:,:) + ... - XI.*ETA.*(1-ZETA).*Cebn(3,:,:) + XI.*ETA.*ZETA.*Cetn(3,:,:); - - Z = Z1 + Z2 + Z3 - Z12 - Z13 - Z23 + Z123; - o = [X;Y;Z]; - end - - obj.V = @V_fun; - end - - %Should be rewritten so that the input is xi eta zeta - function [X,Y,Z] = map(obj,XI,ETA,ZETA) - - V = obj.V; - - p = V(XI,ETA,ZETA); - X = p(1,:)'; - Y = p(2,:)'; - Z = p(3,:)'; - - end - - % function h = plot(obj,nu,nv) - % S = obj.S; - % - % default_arg('nv',nu) - % - % u = linspace(0,1,nu); - % v = linspace(0,1,nv); - % - % m = 100; - % - % X = zeros(nu+nv,m); - % Y = zeros(nu+nv,m); - % - % - % t = linspace(0,1,m); - % for i = 1:nu - % p = S(u(i),t); - % X(i,:) = p(1,:); - % Y(i,:) = p(2,:); - % end - % - % for i = 1:nv - % p = S(t,v(i)); - % X(i+nu,:) = p(1,:); - % Y(i+nu,:) = p(2,:); - % end - % - % h = line(X',Y'); - % end - % - % - % function h = show(obj,nu,nv) - % default_arg('nv',nu) - % S = obj.S; - % - % if(nu>2 || nv>2) - % h_grid = obj.plot(nu,nv); - % set(h_grid,'Color',[0 0.4470 0.7410]); - % end - % - % h_bord = obj.plot(2,2); - % set(h_bord,'Color',[0.8500 0.3250 0.0980]); - % set(h_bord,'LineWidth',2); - % end - % - % - % % TRANSFORMATIONS - % function ti = translate(obj,a) - % gs = obj.gs; - % - % for i = 1:length(gs) - % new_gs{i} = gs{i}.translate(a); - % end - % - % ti = grid.Ti(new_gs{:}); - % end - % - % % Mirrors the Ti so that the resulting Ti is still left handed. - % % (Corrected by reversing curves and switching e and w) - % function ti = mirror(obj, a, b) - % gs = obj.gs; - % - % new_gs = cell(1,4); - % - % new_gs{1} = gs{1}.mirror(a,b).reverse(); - % new_gs{3} = gs{3}.mirror(a,b).reverse(); - % new_gs{2} = gs{4}.mirror(a,b).reverse(); - % new_gs{4} = gs{2}.mirror(a,b).reverse(); - % - % ti = grid.Ti(new_gs{:}); - % end - % - % function ti = rotate(obj,a,rad) - % gs = obj.gs; - % - % for i = 1:length(gs) - % new_gs{i} = gs{i}.rotate(a,rad); - % end - % - % ti = grid.Ti(new_gs{:}); - % end - % - % function ti = rotate_edges(obj,n); - % new_gs = cell(1,4); - % for i = 0:3 - % new_i = mod(i - n,4); - % new_gs{new_i+1} = obj.gs{i+1}; - % end - % ti = grid.Ti(new_gs{:}); - % end - % end - % - % methods(Static) - % function obj = points(p1, p2, p3, p4) - % g1 = grid.Curve.line(p1,p2); - % g2 = grid.Curve.line(p2,p3); - % g3 = grid.Curve.line(p3,p4); - % g4 = grid.Curve.line(p4,p1); - % - % obj = grid.Ti(g1,g2,g3,g4); - % end - % - % function label(varargin) - % if nargin == 2 && ischar(varargin{2}) - % label_impl(varargin{:}); - % else - % for i = 1:length(varargin) - % label_impl(varargin{i},inputname(i)); - % end - % end - % - % - % function label_impl(ti,str) - % S = ti.S; - % - % pc = S(0.5,0.5); - % - % margin = 0.1; - % pw = S( margin, 0.5); - % pe = S(1-margin, 0.5); - % ps = S( 0.5, margin); - % pn = S( 0.5, 1-margin); - % - % - % ti.show(2,2); - % grid.place_label(pc,str); - % grid.place_label(pw,'w'); - % grid.place_label(pe,'e'); - % grid.place_label(ps,'s'); - % grid.place_label(pn,'n'); - % end - % end - end -end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/boundaryIdentifier.txt Tue Sep 11 15:58:35 2018 +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.
--- a/+grid/equal_step_size.m Tue Sep 11 13:24:08 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -% Calculates M so that the stepsize m/M is as close to n/M as possible -function M = equal_step_size(n,N,m) - M = round((m*(N-1)+n)/n); -end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/equidistant.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,29 @@ +% Creates a cartesian grid of dimension length(m). +% over the doman xlim, ylim, ... +% Examples: +% g = grid.equidistant([mx, my], xlim, ylim) +% g = grid.equidistant([10, 15], {0,1}, {0,2}) +function g = equidistant(m, varargin) + if length(m) ~= length(varargin) + error('grid:equidistant:NonMatchingParameters','The number of provided dimensions do not match.') + end + + for i = 1:length(m) + if ~iscell(varargin{i}) || numel(varargin{i}) ~= 2 + error('grid:equidistant:InvalidLimits','The limits should be cell arrays with 2 elements.'); + end + + if varargin{i}{1} > varargin{i}{2} + error('grid:equidistant:InvalidLimits','The elements of the limit must be increasing.'); + end + end + + X = {}; + h = []; + for i = 1:length(m) + [X{i}, h(i)] = util.get_grid(varargin{i}{:},m(i)); + end + + g = grid.Cartesian(X{:}); + g.h = h; +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/equidistantCurvilinear.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,35 @@ +% Creates a curvilinear grid of dimension length(m). +% over the logical domain xi_lim, eta_lim, ... +% If all limits are ommited they are set to {0,1}. +% Examples: +% g = grid.equidistantCurvilinear(mapping, [m_xi, m_eta]) +% g = grid.equidistantCurvilinear(mapping, [m_xi, m_eta], xi_lim, eta_lim) +% g = grid.equidistantCurvilinear(mapping, [10, 15], {0,1}, {0,1}) +function g = equidistantCurvilinear(mapping, m, varargin) + if isempty(varargin) + varargin = repmat({{0,1}}, [1 length(m)]); + end + + if length(m) ~= length(varargin) + error('grid:equidistant:NonMatchingParameters','The number of provided dimensions do not match.') + end + + for i = 1:length(m) + if ~iscell(varargin{i}) || numel(varargin{i}) ~= 2 + error('grid:equidistant:InvalidLimits','The limits should be cell arrays with 2 elements.'); + end + + if varargin{i}{1} > varargin{i}{2} + error('grid:equidistant:InvalidLimits','The elements of the limit must be increasing.'); + end + end + + X = {}; + h = []; + for i = 1:length(m) + [X{i}, h(i)] = util.get_grid(varargin{i}{:},m(i)); + end + + g = grid.Curvilinear(mapping, X{:}); + g.logic.h = h; +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/equidistantCurvilinearTest.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,7 @@ +function tests = equdistantCurvilinearTest() + tests = functiontests(localfunctions); +end + +function testNoTests(testCase) + testCase.verifyFail(); +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/equidistantTest.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,50 @@ +function tests = equidistantTest() + tests = functiontests(localfunctions); +end + + +function testErrorInvalidLimits(testCase) + in = { + {10,{1}}, + {10,[0,1]}, + {[10,10],{0,1},{1}}, + {[10,10],{1},{1,0}}, + {10,{1,0}}, + {[10, 5],{1,0}, {0,-1}}, + }; + + for i = 1:length(in) + testCase.verifyError(@()grid.equidistant(in{i}{:}),'grid:equidistant:InvalidLimits',sprintf('in(%d) = %s',i,toString(in{i}))); + end +end + +function testErrorNonMatchingParam(testCase) + in = { + {[],{1}}, + {[],{1},{0,1}}, + {[5,5],{0,1},{0,1},{0,1}}, + {[5,5,4],{0,1},{0,1}}, + }; + + for i = 1:length(in) + testCase.verifyError(@()grid.equidistant(in{i}{:}),'grid:equidistant:NonMatchingParameters',sprintf('in(%d) = %s',i,toString(in{i}))); + end +end + + +function testCompiles(testCase) + in = { + {5, {0,1}}, + {[3 3],{0,1},{0,2}}, + }; + + out = { + [[0; 0.25; 0.5; 0.75; 1]], + [[0; 0; 0; 0.5; 0.5; 0.5; 1; 1; 1;],[0; 1; 2; 0; 1; 2; 0; 1; 2;]], + }; + + for i = 1:length(in) + g = grid.equidistant(in{i}{:}); + testCase.verifyEqual(g.points(),out{i}); + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/evalOn.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,40 @@ +% Takes a function and evaluates it on a grid to return a grid function in the +% form of a (n*k)x1 vector, where n is the number of grid points and k is the +% number of components of the function. +% g -- Grid to evaluate on. +% func -- Function to evaluate. May be a function handle or a constant. If +% it is a vector value it has to be provided as a column vector, +function gf = evalOn(g, func) + if ~isa(func, 'function_handle') + % We should have a constant. + assert(size(func,2) == 1,'grid:evalOn:VectorValuedWrongDim', 'A vector valued function must be given as a column vector'); + + gf = repmat(func,[g.N, 1]); + return + end + % func should now be a function_handle + assert(g.D == nargin(func) || nargin(func) < 0,'grid:evalOn:WrongNumberOfInputs', 'The number of inputs of the function must match the dimension of the domain.') + + x = num2cell(g.points(),1); + k = numberOfComponents(func, g.D); + + gf = func(x{:}); + gf = reorderComponents(gf, k); +end + +% Find the number of vector components of func +function k = numberOfComponents(func, dim) + x0 = num2cell(ones(1, dim)); + f0 = func(x0{:}); + assert(size(f0,2) == 1, 'grid:evalOn:VectorValuedWrongDim', 'A vector valued function must be given as a column vector'); + k = length(f0); +end + +% Reorder the components of the function to sit together +function gf = reorderComponents(a, k) + N = length(a)/k; + gf = zeros(N*k, 1); + for i = 1:k + gf(i:k:end) = a((i-1)*N + 1 : i*N); + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/evalOnScalar.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,41 @@ +% WHAT KIND OF A FUNCTION NAME IS THIS?! +% This functions send matrixa arguments to func unlike grid.evalOn() +% Takes a funciton and evaluates it on a grid to return a grid function in the +% form of a (n*k)x1 vector, where n is the number of grid points and k is the +% number of components of the function. +% g -- Grid to evaluate on. +% func -- Function to evaluate. May be a function handle or a constant. If +% it is a vector value it has to be provided as a column vector, +function gf = evalOn(g, func) + if ~isa(func, 'function_handle') + % We should have a constant. + if size(func,2) ~= 1 + error('grid:evalOnScalar:VectorValuedWrongDim', 'A vector valued function must be given as a column vector') + end + + gf = repmat(func,[g.N, 1]); + return + end + % func should now be a function_handle + + % Get coordinates and convert to cell array for easier use as a parameter + x = g.points(); + X = {}; + for i = 1:size(x, 2) + X{i} = x(:,i); + end + + % Find the number of components + x0 = num2cell(x(1,:)); + f0 = func(x0{:}); + k = length(f0); + + if size(f0,2) ~= 1 + error('grid:evalOnScalar:VectorValuedWrongDim', 'A vector valued function must be given as a column vector') + end + + gf = func(X{:}); + if k > 1 % Reorder so that componets sits together. + gf = reshape(reshape(gf, [g.N, k])', [g.N*k, 1]); + end +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/evalOnScalarTest.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,118 @@ +function tests = evalOnScalarTest() + tests = functiontests(localfunctions); +end + +function testInputConstant(testCase) + in = { + 0, + 47, + 1, + [1; 2], + }; + + out = { + [0; 0; 0], + [47; 47; 47], + [1; 1; 1], + [1; 2; 1; 2; 1; 2], + }; + + g = getTestGrid('1d'); + + for i = 1:length(in) + gf = grid.evalOnScalar(g,in{i}); + testCase.verifyEqual(gf, out{i}); + end +end + +function testInputScalarFunction1d(testCase) + in = { + @(x)1+x*0, + @(x)x, + @(x)x.*x, + }; + + out = { + [1; 1; 1], + [0; 1; 2], + [0; 1; 4], + }; + + g = getTestGrid('1d'); + + for i = 1:length(in) + gf = grid.evalOnScalar(g,in{i}); + testCase.verifyEqual(gf, out{i}); + end +end + +function testInputScalarFunction2d(testCase) + in = { + @(x,y)1+x*0, + @(x,y)x-y, + @(x,y)x./(1+y), + }; + + out = { + [1; 1; 1; 1; 1; 1; 1; 1; 1], + [0; -1; -2; 1; 0; -1; 2; 1; 0], + [0; 0; 0; 1; 1/2; 1/3; 2; 1; 2/3], + }; + + g = getTestGrid('2d'); + + for i = 1:length(in) + gf = grid.evalOnScalar(g, in{i}); + testCase.verifyEqual(gf, out{i}); + end +end + + +function testInputVectorFunction(testCase) + g = getTestGrid('1d'); + in = @(x)[x; -2*x]; + out = [0; 0; 1; -2; 2; -4]; + + gf = grid.evalOnScalar(g,in); + testCase.verifyEqual(gf, out); + + g = getTestGrid('2d'); + in = @(x,y)[x.^2; -2*y]; + out = [ + 0; 0; + 0; -2; + 0; -4; + 1; 0; + 1; -2; + 1; -4; + 4; 0; + 4; -2; + 4; -4; + ]; + + gf = grid.evalOnScalar(g,in); + testCase.verifyEqual(gf, out); +end + + +function testInputErrorVectorValued(testCase) + in = { + [1,2,3], + @(x,y)[x,-y]; + }; + + g = getTestGrid('2d'); + + for i = 1:length(in) + testCase.verifyError(@()grid.evalOnScalar(g, in{i}),'grid:evalOnScalar:VectorValuedWrongDim',sprintf('in(%d) = %s',i,toString(in{i}))); + end +end + +function g = getTestGrid(d) + switch d + case '1d' + g = grid.equidistant(3,{0,2}); + case '2d' + g = grid.equidistant([3,3],{0,2},{0,2}); + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/evalOnTest.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,133 @@ +function tests = evalOnTest() + tests = functiontests(localfunctions); +end + +function testInputConstant(testCase) + in = { + 0, + 47, + 1, + [1; 2], + }; + + out = { + [0; 0; 0], + [47; 47; 47], + [1; 1; 1], + [1; 2; 1; 2; 1; 2], + }; + + g = getTestGrid('1d'); + + for i = 1:length(in) + gf = grid.evalOn(g,in{i}); + testCase.verifyEqual(gf, out{i}); + end +end + +% evalOn should give and error if the number of inputs to func is not the same as +% the number of dimensions of the grid. +function testNumberOfInputs(testCase) + cases = { + {getTestGrid('1d'), @(x,y)x-y}, + {getTestGrid('2d'), @(x)x }, + }; + + for i = 1:length(cases) + g = cases{i}{1}; + f = cases{i}{2}; + testCase.verifyError(@()grid.evalOn(g, f),'grid:evalOn:WrongNumberOfInputs',sprintf('in(%d) = %s',i,toString(f))); + end +end + +function testInputScalarFunction1d(testCase) + in = { + @(x)1+x*0, + @(x)x, + @(x)x.*x, + }; + + out = { + [1; 1; 1], + [0; 1; 2], + [0; 1; 4], + }; + + g = getTestGrid('1d'); + + for i = 1:length(in) + gf = grid.evalOn(g,in{i}); + testCase.verifyEqual(gf, out{i}); + end +end + +function testInputScalarFunction2d(testCase) + in = { + @(x,y)1+x*0, + @(x,y)x-y, + @(x,y)x./(1+y), + }; + + out = { + [1; 1; 1; 1; 1; 1; 1; 1; 1], + [0; -1; -2; 1; 0; -1; 2; 1; 0], + [0; 0; 0; 1; 1/2; 1/3; 2; 1; 2/3], + }; + + g = getTestGrid('2d'); + + for i = 1:length(in) + gf = grid.evalOn(g, in{i}); + testCase.verifyEqual(gf, out{i}); + end +end + + +function testInputVectorFunction(testCase) + g = getTestGrid('1d'); + in = @(x)[x; -2*x]; + out = [0; 0; 1; -2; 2; -4]; + + gf = grid.evalOn(g,in); + testCase.verifyEqual(gf, out); + + g = getTestGrid('2d'); + in = @(x,y)[x.^2; -2*y]; + out = [ + 0; 0; + 0; -2; + 0; -4; + 1; 0; + 1; -2; + 1; -4; + 4; 0; + 4; -2; + 4; -4; + ]; + + gf = grid.evalOn(g,in); + testCase.verifyEqual(gf, out); +end + + +function testInputErrorVectorValued(testCase) + in = { + [1,2,3], + @(x,y)[x,-y], + }; + + g = getTestGrid('2d'); + + for i = 1:length(in) + testCase.verifyError(@()grid.evalOn(g, in{i}),'grid:evalOn:VectorValuedWrongDim',sprintf('in(%d) = %s',i,toString(in{i}))); + end +end + +function g = getTestGrid(d) + switch d + case '1d' + g = grid.equidistant(3,{0,2}); + case '2d' + g = grid.equidistant([3,3],{0,2},{0,2}); + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/funcToComponents.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,8 @@ +% funcToComponents converts a grid function to a N x k matrix, where +% k is the number of vector components of the gridfunction and N is the +% number of points in the grid. +% +% Takes a grid function and and a grid. +function F = funcToComponents(g, gf); + F = reshapeRowMaj(gf, [g.N, length(gf)/g.N]); +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/funcToComponentsTest.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,23 @@ +function tests = funcToComponentsTest() + tests = functiontests(localfunctions); +end + + +function testScalarGf(testCase) + g = getTestGrid(); + gf_in = [1; 2; 3]; + + testCase.verifyEqual(grid.funcToComponents(g, gf_in), gf_in); +end + +function testVectorGf(testCase) + g = getTestGrid(); + gf_in = [1; 2; 3; 4; 5; 6]; + out = [1 2; 3 4; 5 6]; + + testCase.verifyEqual(grid.funcToComponents(g, gf_in), out); +end + +function g = getTestGrid() + g = grid.equidistant(3,{0,2}); +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/funcToMatrix.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,5 @@ +% Converts a gridfunction to a matrix +% Takes a grid function and and a structured grid. +function F = funcToMatrix(g, gf) + F = reshapeRowMaj(gf, g.size()); +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/funcToPlotMatrix.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,5 @@ +% Converts a gridfunction to a plot matrix +% Takes a grid function and and a structured grid. +function F = funcToPlotMatrix(g, gf) + F = reshapeToPlotMatrix(gf, g.size()); +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/gridFunction.txt Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,1 @@ +TODO: Add documentation for gridfunctions here \ No newline at end of file
--- a/+grid/old/concat_curve.m Tue Sep 11 13:24:08 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,12 +0,0 @@ -% Concatenate two curves g1 and g2 intop -% g = concat_curve(g1,g2) -function g = concat_curve(g1,g2) - function v = g_fun(t) - if t < 1/2 - v = g1(2*t); - else - v = g2(2*t-1); - end - end - g = @g_fun; -end \ No newline at end of file
--- a/+grid/old/curve_discretise.m Tue Sep 11 13:24:08 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,97 +0,0 @@ -% Discretises the curve g with the smallest number of points such that all segments -% are shorter than h. If do_plot is true the points of the discretisation and -% the normals of the curve in those points are plotted. -% -% [t,p,d] = curve_discretise(g,h,do_plot) -% -% t is a vector of input values to g. -% p is a cector of points. -% d are the length of the segments. -function [t,p,d] = curve_discretise(g,h,do_plot) - default_arg('do_plot',false) - - n = 10; - - [t,p,d] = curve_discretise_n(g,n); - - % ni = 0; - while any(d>h) - [t,p,d] = curve_discretise_n(g,n); - n = ceil(n*d(1)/h); - % ni = ni+1; - end - - % nj = 0; - while all(d<h) - [t,p,d] = curve_discretise_n(g,n); - n = n-1; - % nj = nj+1; - end - [t,p,d] = curve_discretise_n(g,n+1); - - % fprintf('ni = %d, nj = %d\n',ni,nj); - - if do_plot - fprintf('n:%d max: %f min: %f\n', n, max(d),min(d)); - p = grid.map_curve(g,t); - figure - show(g,t,h); - end - -end - -function [t,p,d] = curve_discretise_n(g,n) - t = linspace(0,1,n); - t = equalize_d(g,t); - d = D(g,t); - p = grid.map_curve(g,t); -end - -function d = D(g,t) - p = grid.map_curve(g,t); - - d = zeros(1,length(t)-1); - for i = 1:length(d) - d(i) = norm(p(:,i) - p(:,i+1)); - end -end - -function t = equalize_d(g,t) - d = D(g,t); - v = d-mean(d); - while any(abs(v)>0.01*mean(d)) - dt = t(2:end)-t(1:end-1); - t(2:end) = t(2:end) - cumsum(dt.*v./d); - - t = t/t(end); - d = D(g,t); - v = d-mean(d); - end -end - - -function show(g,t,hh) - p = grid.map_curve(g,t); - - - - h = grid.plot_curve(g); - h.LineWidth = 2; - axis equal - hold on - h = plot(p(1,:),p(2,:),'.'); - h.Color = [0.8500 0.3250 0.0980]; - h.MarkerSize = 24; - hold off - - n = grid.curve_normals(g,t); - hold on - for i = 1:length(t) - p0 = p(:,i); - p1 = p0 + hh*n(:,i); - l = [p0, p1]; - h = plot(l(1,:),l(2,:)); - h.Color = [0.8500 0.3250 0.0980]; - end - -end \ No newline at end of file
--- a/+grid/old/curve_interp.m Tue Sep 11 13:24:08 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -% Create a cubic spline from the points (x,y) using periodic conditions. -% g = curve_interp(x,y) -function g = curve_interp(x,y) - default_arg('x',[0 2 2 1 1 0]) - default_arg('y',[0 0 2 2 1 1]) - % solve for xp and yp - - % x(t) = at^4 + bt^2+ct+d - - % a = xp1 -2x1 + 2x0 + xp0 - % b = 3x1 -xp1 - 3x0 + 2xp0 - % c = xp0 - % d = x0 - - assert(length(x) == length(y)) - n = length(x); - A = spdiags(ones(n,1)*[2, 8, 2],-1:1,n,n); - A(n,1) = 2; - A(1,n) = 2; - - bx = zeros(n,1); - for i = 2:n-1 - bx(i) = -6*x(i-1)+6*x(i+1); - end - bx(1) = -6*x(n)+6*x(2); - bx(n) = -6*x(n-1)+6*x(1); - - by = zeros(n,1); - for i = 2:n-1 - by(i) = -6*y(i-1)+6*y(i+1); - end - by(1) = -6*y(n)+6*y(2); - by(n) = -6*y(n-1)+6*y(1); - - - xp = A\bx; - yp = A\by; - - x(end+1) = x(1); - y(end+1) = y(1); - - xp(end+1) = xp(1); - yp(end+1) = yp(1); - - function v = g_fun(t) - t = mod(t,1); - i = mod(floor(t*n),n) + 1; - t = t * n -(i-1); - X = (2*x(i)-2*x(i+1)+xp(i)+xp(i+1))*t.^3 + (-3*x(i)+3*x(i+1)-2*xp(i)-xp(i+1))*t.^2 + (xp(i))*t + x(i); - Y = (2*y(i)-2*y(i+1)+yp(i)+yp(i+1))*t.^3 + (-3*y(i)+3*y(i+1)-2*yp(i)-yp(i+1))*t.^2 + (yp(i))*t + y(i); - v = [X;Y]; - end - - g = @g_fun; -end - - -
--- a/+grid/old/max_h.m Tue Sep 11 13:24:08 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -function [d_max, i1_max, j1_max, i2_max, j2_max] = max_h(X,Y) - ni = size(X,1); - nj = size(X,2); - d_max = 0; - - i1_max = 0; - j1_max = 0; - i2_max = 0; - j2_max = 0; - - D = {[0,-1],[1,0],[0,1],[-1,0]}; - - for i = 1:ni - for j = 1:nj - p1 = [X(i,j); Y(i,j)]; - for k = 1:length(D) - i2 = i+D{k}(1); - j2 = j+D{k}(2); - if i2 >= 1 && i2 <= ni && j2 >= 1 && j2 <= nj - p2 = [X(i2,j2); Y(i2,j2)]; - d = norm(p2-p1); - if d > d_max; - d_max = d; - i1_max = i; - j1_max = j; - i2_max = i2; - j2_max = j2; - end - end - end - end - end -end
--- a/+grid/old/min_h.m Tue Sep 11 13:24:08 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -function [d_min, i1_min, j1_min, i2_min, j2_min] = min_h(X,Y) - ni = size(X,1); - nj = size(X,2); - d_min = norm([X(1,1);Y(1,1)] - [X(ni,nj);Y(ni,nj)]); - - i1_min = 0; - j1_min = 0; - i2_min = 0; - j2_min = 0; - - D = {[-1,-1],[0,-1],[1,-1],[1,0],[1,1],[0,1],[-1,1],[-1,0]}; - % D = {[0,-1],[1,0],[0,1],[-1,0]}; - - for i = 1:ni - for j = 1:nj - p1 = [X(i,j); Y(i,j)]; - for k = 1:length(D) - i2 = i+D{k}(1); - j2 = j+D{k}(2); - if i2 >= 1 && i2 <= ni && j2 >= 1 && j2 <= nj - p2 = [X(i2,j2); Y(i2,j2)]; - d = norm(p2-p1); - if d < d_min; - d_min = d; - i1_min = i; - j1_min = j; - i2_min = i2; - j2_min = j2; - end - end - end - end - end -end
--- a/+grid/old/plot_shape.m Tue Sep 11 13:24:08 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,12 +0,0 @@ -% Plot a shape using n points. Returns cell array of plot handles. -% hs = plot_shape(s,n) -function hs = plot_shape(s,n) - default_arg('n',100); - - hs = {}; - hold on - for i = 1:length(s) - hs{end+1} = grid.plot_curve(s{i},n); - end - hold off -end \ No newline at end of file
--- a/+grid/old/shape.m Tue Sep 11 13:24:08 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -% Creates a shape from a number of curves. A shape is a cell array of curves. -function s = shape(varargin); - s = varargin; -end \ No newline at end of file
--- a/+grid/old/shape_discretise.m Tue Sep 11 13:24:08 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -% Discretises a shape such that points on the curves are no further than h appart. -function p = shape_discretise(s,h) - p = []; - for i = 1:length(s) - [~,pt] = grid.curve_discretise(s{i},h); - p = [p, pt]; - end -end \ No newline at end of file
--- a/+grid/old/shape_linesegments.m Tue Sep 11 13:24:08 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -% Converts a shape into a cell array of linesegments shorter than h. -function l = shape_linesegments(s,h) - l = {}; - - for i = 1:length(s) - t = grid.curve_discretise(s{i},h); - l = [l, grid.curve_linesegments(s{i},t)]; - end -end \ No newline at end of file
--- a/+grid/old/triang_interp.m Tue Sep 11 13:24:08 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,132 +0,0 @@ -classdef triang_interp - properties - g1, g2 ,g3 % Curves encirling the tirangle in the positive direction. - A,B,C % The corners of the triangle - Sa, Sb, Sc % Mappings from square with different sides collapsed - end - - methods - function o = triang_interp(g1,g2,g3) - o.g1 = g1; - o.g2 = g2; - o.g3 = g3; - o.A = g1(0); - o.B = g2(0); - o.C = g3(0); - o.Sa = grid.triang_interp.square_to_triangle_interp(g2,g3,g1); - o.Sb = grid.triang_interp.square_to_triangle_interp(g3,g1,g2); - o.Sc = grid.triang_interp.square_to_triangle_interp(g1,g2,g3); - end - - - function show(o,N) - % Show the mapped meridians of the triangle. - % Might be used for the barycentric coordinates. - ma = @(t)o.Sa(1/2,1-t); - mb = @(t)o.Sb(1/2,1-t); - mc = @(t)o.Sc(1/2,1-t); - - na = @(t)o.Sa(t,1/2); - - ka = @(t)(o.g1(1-t)+o.g2(t))/2; - - h = grid.plot_curve(ma); - h.Color = Color.blue; - h = grid.plot_curve(mb); - h.Color = Color.blue; - h = grid.plot_curve(mc); - h.Color = Color.blue; - - h = grid.plot_curve(na); - h.Color = Color.red; - - h = grid.plot_curve(ka); - h.Color = Color.red; - - [a(1),a(2)] = ma(1/3); - [b(1),b(2)] = mb(1/3); - [c(1),c(2)] = mc(1/3); - - d = ka(1-1/3); - - - grid.label_pt(a,b,c,d); - - - % t = linspace(0,1,N); - % for i = 1:N - % sa = @(s)o.Sa(s,t(i)); - % sb = @(s)o.Sb(s,t(i)); - % sc = @(s)o.Sc(s,t(i)); - - % h = grid.plot_curve(sa); - % h.Color = Color.blue; - % h = grid.plot_curve(sb); - % h.Color = Color.blue; - % h = grid.plot_curve(sc); - % h.Color = Color.blue; - % end - - h = grid.plot_curve(o.g1); - h.LineWidth = 2; - h.Color = Color.red; - - h = grid.plot_curve(o.g2); - h.LineWidth = 2; - h.Color = Color.red; - - h = grid.plot_curve(o.g3); - h.LineWidth = 2; - h.Color = Color.red; - - end - - - end - - methods(Static) - % Makes a mapping from the unit square to a triangle by collapsing - % one of the sides of the squares to a corner on the triangle - % The collapsed side is mapped to the corner oposite to g1. - % This is done such that for S(s,t), S(s,1) = g1(s) - function S = square_to_triangle_interp(g1,g2,g3) - corner = grid.line_segment(g3(0),g3(0)); - S = grid.transfinite_interp(corner,g3,f(g1),f(g2)) - - % Function to flip a curve - function h = f(g) - h = @(t)g(1-t); - end - end - end - -end - -% % Return a mapping from u.v to x,y of the domain encircled by g1 g2 g3 in the the positive direction. created be using transfinite interpolation. -% function S = triang_interp(g1,g2,g3) -% A = g1(0) -% B = g2(0) -% C = g3(0) - -% function [x,y] = S_fun(u,v) -% w = sqrt((u-1)^2+v^2)/sqrt(2); % Parameter for g3 -% v = v*(1-u-v)*g1(u) + u*(1-u-v)*g2(v) + u*v*g3(w) ... -% +(1-u)*(1-v)*A+u*(1-v)*B + (1-u)*v*C; -% x = v(1); -% y = v(2); -% end -% S = @S_fun; -% end - - - -% function subsref(obj,S) -% if ~all(isnumeric(S.subs{:})) -% error('Only supports calling object with number') -% end -% if numel(S.subs{:}) > 1 -% disp('You''ve called the object with more than one argument'); -% else -% disp(['You called the object with argument = ',num2str(S.subs{:})]); -% end -% end \ No newline at end of file
--- a/+grid/old/triang_interp_pts.m Tue Sep 11 13:24:08 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,12 +0,0 @@ -% Creates a transfinite interpolation from connecting the four points wiht straight lines. -function [S, g1, g2, g3] = triang_interp_pts(p1,p2,p3) - if size(p1) ~= [2 1] - error('p1 is strange!'); - end - - g1 = @(t)(p1 + t*(p2-p1)); - g2 = @(t)(p2 + t*(p3-p2)); - g3 = @(t)(p3 + t*(p1-p3)); - - S = grid.triang_interp(g1,g2,g3); -end
--- a/+grid/old/triang_map.m Tue Sep 11 13:24:08 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -% Creates a grid [X,Y] from the mapping function S at points in vectors u,v -function [X, Y] = traing_map(S,u,v) - error('not done') - if nargin == 2 - v = u; - end - - if isscalar(u) - u = linspace(0,1,u); - end - - if isscalar(v) - v = linspace(0,1,v); - end - - nu = length(u); - nv = length(v); - - X = zeros(nu,nv); - Y = zeros(nu,nv); - - for i = 1:nu - for j = 1:nv - [x,y] = S(u(i),v(j)); - X(i,j) = x; - Y(i,j) = y; - end - end -end
--- a/+grid/old/triang_plot_interp.m Tue Sep 11 13:24:08 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,114 +0,0 @@ -% Plots a transfinite interpolation in x,y space using nu and nv curves along u and v axes. - - - - - - -% Plots a interp of a triangle where one the interpolation is from a square -% with one side collapsed to -function h = triang_plot_interp_kindaworking(S,n) - u = linspace(0,1,n); - v = linspace(0,1,n); - - m = 100; - m = 20; - - Xl_curves = cell(n,1); - Xr_curves = cell(n,1); - Y_curves = cell(n,1); - - - function u = wierdness(v,d,N) - if N == 0 - u = 0; - else - u = N*d./(1-v); - end - end - - - %Y curves - t = linspace(0,1,m); - for i = 1:n - x = []; y = []; - for j = 1:length(t) - [x(j),y(j)] = S(t(j),v(i)); - end - Y_curves{i} = [x', y']; - end - - - % Right and left X curves - t = linspace(0,1,m); - d = u(2); - for i = 1:n - xl = []; yl = []; - xr = []; yr = []; - N = i-1; - t = linspace(0,1-N*d,m); - for j = 1:length(t) - w = wierdness(t(j),d,N); - [xr(j),yr(j)] = S(w,t(j)); - [xl(j),yl(j)] = S(1-w,t(j)); - end - Xl_curves{i} = [xl', yl']; - Xr_curves{i} = [xr', yr']; - end - - for i = 1:n-1 - line(Xl_curves{i}(:,1),Xl_curves{i}(:,2)) - line(Xr_curves{i}(:,1),Xr_curves{i}(:,2)) - line(Y_curves{i}(:,1),Y_curves{i}(:,2)) - end -end - - - - -function h = triang_plot_interp_nonworking(S,n) - - u = linspace(0,1,n); - v = linspace(0,1,n); - - m = 100; - - X_curves = cell(n-1,1); - Y_curves = cell(n-1,1); - K_curves = cell(n-1,1); - - - t = linspace(0,1,m); - for i = 1:n-1 - x = []; y = []; - for j = find(t+u(i) <= 1) - [x(j),y(j)] = S(u(i),t(j)); - end - X_curves{i} = [x', y']; - end - - for i = 1:n-1 - x = []; y = []; - for j = find(t+v(i) <= 1) - [x(j),y(j)] = S(t(j),v(i)); - end - Y_curves{i} = [x', y']; - end - - for i = 2:n - x = []; y = []; - for j = find(t<u(i)) - [x(j),y(j)] = S(t(j), u(i)-t(j)); - end - K_curves{i-1} = [x', y']; - end - - for i = 1:n-1 - line(X_curves{i}(:,1),X_curves{i}(:,2)) - line(Y_curves{i}(:,1),Y_curves{i}(:,2)) - line(K_curves{i}(:,1),K_curves{i}(:,2)) - end - - h = -1; - % h = plot(X_curves{:},Y_curves{:},K_curves{:}); -end
--- a/+grid/old/triang_show.m Tue Sep 11 13:24:08 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,23 +0,0 @@ -% Show a grid as a matlab figure. -function triang_show(S,n) - - ih = ishold(); - - hold on - h_grid = grid.triang_plot_interp(S,n); - h_bord = grid.triang_plot_interp(S,2); - - set(h_grid,'Color',[0 0.4470 0.7410]); - set(h_bord,'Color',[0.8500 0.3250 0.0980]); - set(h_bord,'LineWidth',2); - - % axis auto - % axis equal - % axis square - - if ih - hold on - else - hold off - end -end
--- a/+grid/place_label.m Tue Sep 11 13:24:08 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,12 +0,0 @@ -% 'left' | 'center' | 'right' -% 'baseline' | 'top' | 'cap' | 'middle' | 'bottom' -function place_label(pt,str,horzAl,vertAl) - default_arg('horzAl','center'); - default_arg('vertAl', 'middle'); - - x = pt(1); - y = pt(2); - h = text(x,y,str); - h.HorizontalAlignment = horzAl; - h.VerticalAlignment = vertAl; -end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+multiblock/+domain/Circle.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,98 @@ +classdef Circle < multiblock.DefCurvilinear + properties + r, c + + hs + r_arc + omega + end + + methods + function obj = Circle(r, c, hs) + default_arg('r', 1); + default_arg('c', [0; 0]); + default_arg('hs', 0.435); + + + % alpha = 0.75; + % hs = alpha*r/sqrt(2); + + % Square should not be a square, it should be an arc. The arc radius + % is chosen so that the three angles of the meshes are all equal. + % This gives that the (half)arc opening angle of should be omega = pi/12 + omega = pi/12; + r_arc = hs*(2*sqrt(2))/(sqrt(3)-1); % = hs* 1/sin(omega) + c_arc = c - [(1/(2-sqrt(3))-1)*hs; 0]; + + cir = parametrization.Curve.circle(c,r,[-pi/4 pi/4]); + + c2 = cir(0); + c3 = cir(1); + + s1 = [-hs; -hs]; + s2 = [ hs; -hs]; + s3 = [ hs; hs]; + s4 = [-hs; hs]; + + sp2 = parametrization.Curve.line(s2,c2); + sp3 = parametrization.Curve.line(s3,c3); + + Se1 = parametrization.Curve.circle(c_arc,r_arc,[-omega, omega]); + Se2 = Se1.rotate(c,pi/2); + Se3 = Se2.rotate(c,pi/2); + Se4 = Se3.rotate(c,pi/2); + + + S = parametrization.Ti(Se1,Se2,Se3,Se4).rotate_edges(-1); + + A = parametrization.Ti(sp2, cir, sp3.reverse, Se1.reverse); + B = A.rotate(c,1*pi/2).rotate_edges(-1); + C = A.rotate(c,2*pi/2).rotate_edges(-1); + D = A.rotate(c,3*pi/2).rotate_edges(0); + + blocks = {S,A,B,C,D}; + blocksNames = {'S','A','B','C','D'}; + + conn = cell(5,5); + conn{1,2} = {'e','w'}; + conn{1,3} = {'n','s'}; + conn{1,4} = {'w','s'}; + conn{1,5} = {'s','w'}; + + conn{2,3} = {'n','e'}; + conn{3,4} = {'w','e'}; + conn{4,5} = {'w','s'}; + conn{5,2} = {'n','s'}; + + boundaryGroups = struct(); + boundaryGroups.E = multiblock.BoundaryGroup({2,'e'}); + boundaryGroups.N = multiblock.BoundaryGroup({3,'n'}); + boundaryGroups.W = multiblock.BoundaryGroup({4,'n'}); + boundaryGroups.S = multiblock.BoundaryGroup({5,'e'}); + boundaryGroups.all = multiblock.BoundaryGroup({{2,'e'},{3,'n'},{4,'n'},{5,'e'}}); + + obj = obj@multiblock.DefCurvilinear(blocks, conn, boundaryGroups, blocksNames); + + obj.r = r; + obj.c = c; + obj.hs = hs; + obj.r_arc = r_arc; + obj.omega = omega; + end + + function ms = getGridSizes(obj, m) + m_S = m; + + % m_Radial + s = 2*obj.hs; + innerArc = obj.r_arc*obj.omega; + outerArc = obj.r*pi/2; + shortSpoke = obj.r-s/sqrt(2); + x = (1/(2-sqrt(3))-1)*obj.hs; + longSpoke = (obj.r+x)-obj.r_arc; + m_R = parametrization.equal_step_size((innerArc+outerArc)/2, m_S, (shortSpoke+longSpoke)/2); + + ms = {[m_S m_S], [m_R m_S], [m_S m_R], [m_S m_R], [m_R m_S]}; + end + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+multiblock/+domain/Rectangle.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,188 @@ +classdef Rectangle < multiblock.Definition + properties + + blockTi % Transfinite interpolation objects used for plotting + xlims + ylims + blockNames % Cell array of block labels + nBlocks + connections % Cell array specifying connections between blocks + boundaryGroups % Structure of boundaryGroups + + end + + + methods + % Creates a divided rectangle + % x and y are vectors of boundary and interface positions. + % blockNames: cell array of labels. The id is default. + function obj = Rectangle(x,y,blockNames) + default_arg('blockNames',[]); + + n = length(y)-1; % number of blocks in the y direction. + m = length(x)-1; % number of blocks in the x direction. + N = n*m; % number of blocks + + if ~issorted(x) + error('The elements of x seem to be in the wrong order'); + end + if ~issorted(flip(y)) + error('The elements of y seem to be in the wrong order'); + end + + % Dimensions of blocks and number of points + blockTi = cell(N,1); + xlims = cell(N,1); + ylims = cell(N,1); + for i = 1:n + for j = 1:m + p1 = [x(j), y(i+1)]; + p2 = [x(j+1), y(i)]; + I = flat_index(m,j,i); + blockTi{I} = parametrization.Ti.rectangle(p1,p2); + xlims{I} = {x(j), x(j+1)}; + ylims{I} = {y(i+1), y(i)}; + end + end + + % Interface couplings + conn = cell(N,N); + for i = 1:n + for j = 1:m + I = flat_index(m,j,i); + if i < n + J = flat_index(m,j,i+1); + conn{I,J} = {'s','n'}; + end + + if j < m + J = flat_index(m,j+1,i); + conn{I,J} = {'e','w'}; + end + end + end + + % Block names (id number as default) + if isempty(blockNames) + obj.blockNames = cell(1, N); + for i = 1:N + obj.blockNames{i} = sprintf('%d', i); + end + else + assert(length(blockNames) == N); + obj.blockNames = blockNames; + end + nBlocks = N; + + % Boundary groups + boundaryGroups = struct(); + nx = m; + ny = n; + E = cell(1,ny); + W = cell(1,ny); + S = cell(1,nx); + N = cell(1,nx); + for i = 1:ny + E_id = flat_index(m,nx,i); + W_id = flat_index(m,1,i); + E{i} = {E_id,'e'}; + W{i} = {W_id,'w'}; + end + for j = 1:nx + S_id = flat_index(m,j,ny); + N_id = flat_index(m,j,1); + S{j} = {S_id,'s'}; + N{j} = {N_id,'n'}; + end + boundaryGroups.E = multiblock.BoundaryGroup(E); + boundaryGroups.W = multiblock.BoundaryGroup(W); + boundaryGroups.S = multiblock.BoundaryGroup(S); + boundaryGroups.N = multiblock.BoundaryGroup(N); + boundaryGroups.all = multiblock.BoundaryGroup([E,W,S,N]); + boundaryGroups.WS = multiblock.BoundaryGroup([W,S]); + boundaryGroups.WN = multiblock.BoundaryGroup([W,N]); + boundaryGroups.ES = multiblock.BoundaryGroup([E,S]); + boundaryGroups.EN = multiblock.BoundaryGroup([E,N]); + + obj.connections = conn; + obj.nBlocks = nBlocks; + obj.boundaryGroups = boundaryGroups; + obj.blockTi = blockTi; + obj.xlims = xlims; + obj.ylims = ylims; + + end + + + % Returns a multiblock.Grid given some parameters + % ms: cell array of [mx, my] vectors + % For same [mx, my] in every block, just input one vector. + function g = getGrid(obj, ms, varargin) + + default_arg('ms',[21,21]) + + % Extend ms if input is a single vector + if (numel(ms) == 2) && ~iscell(ms) + m = ms; + ms = cell(1,obj.nBlocks); + for i = 1:obj.nBlocks + ms{i} = m; + end + end + + grids = cell(1, obj.nBlocks); + for i = 1:obj.nBlocks + grids{i} = grid.equidistant(ms{i}, obj.xlims{i}, obj.ylims{i}); + end + + g = multiblock.Grid(grids, obj.connections, obj.boundaryGroups); + end + + % label is the type of label used for plotting, + % default is block name, 'id' show the index for each block. + function show(obj, label, gridLines, varargin) + default_arg('label', 'name') + default_arg('gridLines', false); + + if isempty('label') && ~gridLines + for i = 1:obj.nBlocks + obj.blockTi{i}.show(2,2); + end + axis equal + return + end + + if gridLines + m = 10; + for i = 1:obj.nBlocks + obj.blockTi{i}.show(m,m); + end + end + + + switch label + case 'name' + labels = obj.blockNames; + case 'id' + labels = {}; + for i = 1:obj.nBlocks + labels{i} = num2str(i); + end + otherwise + axis equal + return + end + + for i = 1:obj.nBlocks + parametrization.Ti.label(obj.blockTi{i}, labels{i}); + end + + axis equal + end + + % Returns the grid size of each block in a cell array + % The input parameters are determined by the subclass + function ms = getGridSizes(obj, varargin) + end + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+multiblock/BoundaryGroup.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,19 @@ +% BoundaryGroup defines a boundary grouping in a multiblock grid. +% 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(data) + obj = obj@Cell(data); + end + + function display(obj, name) + + disp(' ') + disp([name, ' =']) + disp(' ') + + fprintf(' BoundaryGroup%s\n\n', toString(obj.data)); + end + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+multiblock/Contour.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,65 @@ +classdef Contour < handle + properties + grid + contours + nContours + + ZData + CData + + end + + methods + function obj = Contour(g, gf, nContours) + obj.grid = g; + obj.nContours = nContours; + + coords = obj.grid.points(); + X = obj.grid.funcToPlotMatrices(coords(:,1)); + Y = obj.grid.funcToPlotMatrices(coords(:,2)); + + V = obj.grid.funcToPlotMatrices(gf); + + + holdState = ishold(); + hold on + + contours = {1, obj.grid.nBlocks}; + for i = 1:obj.grid.nBlocks + [~, contours{i}] = contour(X{i}, Y{i}, V{i},obj.nContours); + contours{i}.LevelList = contours{1}.LevelList; + end + + if holdState == false + hold off + end + + obj.contours = [contours{:}]; + + obj.ZData = gf; + obj.CData = gf; + end + + function set(obj, propertyName, propertyValue) + set(obj.contours, propertyName, propertyValue); + end + + function obj = set.ZData(obj, gf) + obj.ZData = gf; + + V = obj.grid.funcToPlotMatrices(gf); + for i = 1:obj.grid.nBlocks + obj.contours(i).ZData = V{i}; + end + end + + function obj = set.CData(obj, gf) + obj.CData = gf; + + V = obj.grid.funcToPlotMatrices(gf); + for i = 1:obj.grid.nBlocks + obj.contours(i).CData = V{i}; + end + end + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+multiblock/DefCurvilinear.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,102 @@ +classdef DefCurvilinear < multiblock.Definition + properties + nBlocks + blockMaps % Maps from logical blocks to physical blocks build from transfinite interpolation + blockNames + connections % Cell array specifying connections between blocks + boundaryGroups % Structure of boundaryGroups + end + + methods + % Defines a multiblock setup for transfinite interpolation blocks + % TODO: How to bring in plotting of points? + function obj = DefCurvilinear(blockMaps, connections, boundaryGroups, blockNames) + default_arg('boundaryGroups', struct()); + default_arg('blockNames',{}); + + nBlocks = length(blockMaps); + + obj.nBlocks = nBlocks; + + obj.blockMaps = blockMaps; + + assert(all(size(connections) == [nBlocks, nBlocks])); + obj.connections = connections; + + + if isempty(blockNames) + obj.blockNames = cell(1, nBlocks); + for i = 1:length(blockMaps) + obj.blockNames{i} = sprintf('%d', i); + end + else + assert(length(blockNames) == nBlocks); + obj.blockNames = blockNames; + end + + obj.boundaryGroups = boundaryGroups; + end + + function g = getGrid(obj, varargin) + ms = obj.getGridSizes(varargin{:}); + + grids = cell(1, obj.nBlocks); + for i = 1:obj.nBlocks + grids{i} = grid.equidistantCurvilinear(obj.blockMaps{i}.S, ms{i}); + end + + g = multiblock.Grid(grids, obj.connections, obj.boundaryGroups); + end + + function h = show(obj, label, gridLines, varargin) + default_arg('label', 'name') + default_arg('gridLines', false); + + h = []; + if isempty('label') && ~gridLines + for i = 1:obj.nBlocks + h = [h, obj.blockMaps{i}.show(2,2)]; + end + axis equal + return + end + + if gridLines + ms = obj.getGridSizes(varargin{:}); + for i = 1:obj.nBlocks + h = [h, obj.blockMaps{i}.show(ms{i}(1),ms{i}(2))]; + end + end + + + switch label + case 'name' + labels = obj.blockNames; + case 'id' + labels = {}; + for i = 1:obj.nBlocks + labels{i} = num2str(i); + end + case 'none' + axis equal + return + end + + for i = 1:obj.nBlocks + parametrization.Ti.label(obj.blockMaps{i}, labels{i}); + end + + axis equal + end + end + + methods (Abstract) + % Returns the grid size of each block in a cell array + % The input parameters are determined by the subclass + ms = getGridSizes(obj, varargin) + % end + end + +end + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+multiblock/Definition.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,11 @@ +classdef Definition + methods (Abstract) + + % Returns a multiblock.Grid given some parameters + g = getGrid(obj, varargin) + + % label is the type of label used for plotting, + % default is block name, 'id' show the index for each block. + show(obj, label, gridLines, varargin) + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+multiblock/DiffOp.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,245 @@ +classdef DiffOp < scheme.Scheme + properties + grid + order + diffOps + D + H + + blockmatrixDiv + end + + methods + function obj = DiffOp(doHand, g, 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. + % g -- 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, g, doParam); + + nBlocks = g.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); + if ~iscell(p) + p = {p}; + end + obj.diffOps{i} = h(g.grids{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 = blockmatrix.toMatrix(H); + + + % Build the differentiation matrix + Ns = zeros(nBlocks,1); + for i = 1:nBlocks + Ns(i) = length(obj.diffOps{i}.D); + end + obj.blockmatrixDiv = {Ns, Ns}; + D = blockmatrix.zero(obj.blockmatrixDiv); + for i = 1:nBlocks + D{i,i} = obj.diffOps{i}.D; + end + + for i = 1:nBlocks + for j = 1:nBlocks + intf = g.connections{i,j}; + if isempty(intf) + continue + end + + + [ii, ij] = obj.diffOps{i}.interface(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}.interface(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 = blockmatrix.toMatrix(D); + obj.grid = g; + + + function [getHand, getParam] = parseInput(doHand, g, doParam) + if ~isa(g, 'multiblock.Grid') + error('multiblock:DiffOp:DiffOp:InvalidGrid', 'Requires a multiblock grid.'); + end + + if iscell(doHand) && length(doHand) == g.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){}; + return + end + + if ~iscell(doParam) + getParam = @(i)doParam; + return + end + + % doParam is a non-empty cell-array + + if length(doParam) == g.nBlocks() && all(cellfun(@iscell, doParam)) + % doParam is a cell-array of cell-arrays + getParam = @(i)doParam{i}; + return + end + + getParam = @(i)doParam; + 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 + + % 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 + case 'multiblock.BoundaryGroup' + op = sparse(size(obj.D,1),0); + for i = 1:length(boundary) + op = [op, obj.getBoundaryOperator(opName, boundary{i})]; + end + otherwise + error('Unknown boundary indentifier') + end + end + + function op = getBoundaryQuadrature(obj, boundary) + opName = 'H'; + switch class(boundary) + case 'cell' + localOpName = [opName '_' boundary{2}]; + blockId = boundary{1}; + op = obj.diffOps{blockId}.(localOpName); + + return + case 'multiblock.BoundaryGroup' + N = length(boundary); + H_bm = cell(N,N); + for i = 1:N + H_bm{i,i} = obj.getBoundaryQuadrature(boundary{i}); + end + op = blockmatrix.toMatrix(H_bm); + 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'}. 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 = sparse(n,0); + 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}; + + % Get the closure and penaly matrices + [blockClosure, blockPenalty] = obj.diffOps{I}.boundary_condition(name, type); + + % Expand to matrix for full domain. + div = obj.blockmatrixDiv; + if ~iscell(blockClosure) + temp = blockmatrix.zero(div); + temp{I,I} = blockClosure; + closure = blockmatrix.toMatrix(temp); + else + for i = 1:length(blockClosure) + temp = blockmatrix.zero(div); + temp{I,I} = blockClosure{i}; + closure{i} = blockmatrix.toMatrix(temp); + end + end + + if ~iscell(blockPenalty) + div{2} = size(blockPenalty, 2); % Penalty is a column vector + p = blockmatrix.zero(div); + p{I} = blockPenalty; + penalty = blockmatrix.toMatrix(p); + else + % TODO: used by beam equation, should be eliminated. SHould only set one BC per call + for i = 1:length(blockPenalty) + div{2} = size(blockPenalty{i}, 2); % Penalty is a column vector + p = blockmatrix.zero(div); + p{I} = blockPenalty{i}; + penalty{i} = blockmatrix.toMatrix(p); + end + end + end + + function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary) + error('not implemented') + end + + % Size returns the number of degrees of freedom + function N = size(obj) + N = 0; + for i = 1:length(obj.diffOps) + N = N + obj.diffOps{i}.size(); + end + end + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+multiblock/DiffOpTest.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,59 @@ +function tests = DiffOpTest() + tests = functiontests(localfunctions); +end + +function testCreation(testCase) + do = newMultiblockOp(); +end + +function testSplitOp(testCase) + testCase.verifyFail(); +end + +function testBoundary_condition(testCase) + testCase.verifyFail(); +end + +function testInterface(testCase) + testCase.verifyFail(); +end + +function testSize(testCase) + mbDo = newMultiblockOp(); + testCase.verifyEqual(mbDo.size(), 15) +end + + +function do = mockDiffOp(size, bc, interface) + do.H = 1; + do.D = 1; + + do.size = size; + do.boundary_condition = bc; + do.interface = interface; +end + + +function do = newMultiblockOp() + grids = { + grid.Cartesian([0 1 2], [3 4 5]); + grid.Cartesian([1 2 3], [10 20]); + }; + + conn = cell(2,2); + conn{1, 2} = {'s','n'}; + + mbGrid = multiblock.Grid(grids, conn); + + function [c, p] = boundary_condition(~,~,~,~) + c = 1; p = 1; + end + + function [c, p] = interface(~,~,~,~) + c = 1; p = 1; + end + + doHand = @(grid,~)mockDiffOp(@(~)prod(grid.size()), @boundary_condition, @interface); + + do = multiblock.DiffOp(doHand, mbGrid, 0); +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+multiblock/EmptyGrid.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,47 @@ +classdef EmptyGrid < grid.Empty & multiblock.Grid + methods + function obj = EmptyGrid(D) + obj@multiblock.Grid({},cell(0,0)); + obj@grid.Empty(D); + end + + % n returns the number of points in the grid + function o = N(obj) + o = N@grid.Empty(obj); + end + + % d returns the spatial dimension of the grid + function o = D(obj) + o = D@grid.Empty(obj); + end + + % points returns a n x d matrix containing the coordinates for all points. + function X = points(obj) + X = points@grid.Empty(obj); + end + + % Restricts the grid function gf on obj to the subgrid g. + function gf = restrictFunc(obj, gf, g) + gf = restrictFunc@grid.Empty(obj); + end + + % Projects the grid function gf on obj to the grid g. + function gf = projectFunc(obj, gf, g) + gf = projectFunc@grid.Empty(obj); + end + + % Return the grid.boundaryIdentifiers of all boundaries in a cell array. + function bs = getBoundaryNames(obj) + bs = getBoundaryNames@grid.Empty(obj); + end + + % Return coordinates for the given boundary + function b = getBoundary(obj, name) + b = getBoundary@grid.Empty(name); + end + + function s = size(obj) + s = size@multiblock.Grid(obj); + end + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+multiblock/Grid.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,174 @@ +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?) + % 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()); + assertType(grids, 'cell') + obj.grids = grids; + obj.connections = connections; + + obj.nPoints = 0; + for i = 1:length(grids) + obj.nPoints = obj.nPoints + grids{i}.N(); + end + + obj.boundaryGroups = 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 + + % Ns returns the number of points in each sub grid as a vector + function o = Ns(obj) + ns = zeros(1,obj.nBlocks); + for i = 1:obj.nBlocks + ns(i) = obj.grids{i}.N(); + end + o = ns; + 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 = sparse(0,obj.D()); + 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 = zeros(1,nBlocks); + for i = 1:nBlocks + N(i) = obj.grids{i}.N()*nComponents; + end + + gfs = blockmatrix.fromMatrix(gf, {N,1}); + end + + % TODO: Split op? + % Should the method to split an operator be moved here instead of being in multiblock.DiffOp? + + % Converts a gridfunction to a set of plot matrices + % Takes a grid function and and a structured grid. + function F = funcToPlotMatrices(obj, gf) + % TODO: This method should problably not be here. + % The funcToPlotMatrix uses .size poperty of the grids + % Which doesn't always exist for all types of grids. + % It's only valid for structured grids + gfs = obj.splitFunc(gf); + + F = cell(1, obj.nBlocks()); + + for i = 1:obj.nBlocks() + F{i} = grid.funcToPlotMatrix(obj.grids{i}, gfs{i}); + end + 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 + + % Find all non interface boundaries of all blocks. + % Return their grid.boundaryIdentifiers in a cell array. + function bs = getBoundaryNames(obj) + 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/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 = sparse(0,obj.D()); + for i = 1:length(boundary) + b = [b; obj.getBoundary(boundary{i})]; + end + otherwise + error('Unknown boundary indentifier') + end + end + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+multiblock/GridTest.m Tue Sep 11 15:58:35 2018 +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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+multiblock/Laplace.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,56 @@ +classdef Laplace < scheme.Scheme + properties + grid + order + mbDiffOp + + D + H + J + end + methods + function obj = Laplace(g, order, a, b, opGen) + default_arg('order', 4); + default_arg('a', 1); + default_arg('b', 1); + default_arg('opGen', @sbp.D4Variable); + + obj.grid = g; + obj.order = order; + obj.mbDiffOp = multiblock.DiffOp(@scheme.LaplaceCurvilinear, obj.grid, order, {a,b,opGen}); + + obj.D = obj.mbDiffOp.D; + obj.J = obj.jacobian(); + obj.H = obj.mbDiffOp.H; + end + + function s = size(obj) + s = size(obj.mbDiffOp); + end + + function J = jacobian(obj) + N = obj.grid.nBlocks; + J = cell(N,N); + + for i = 1:N + J{i,i} = obj.mbDiffOp.diffOps{i}.J; + end + J = blockmatrix.toMatrix(J); + end + + function op = getBoundaryOperator(obj, opName, boundary) + op = getBoundaryOperator(obj.mbDiffOp, opName, boundary); + end + + function op = getBoundaryQuadrature(obj, boundary) + op = getBoundaryQuadrature(obj.mbDiffOp, boundary); + end + + function [closure, penalty] = boundary_condition(obj,boundary,type) % TODO: Change name to boundaryCondition + [closure, penalty] = boundary_condition(obj.mbDiffOp, boundary, type); + end + function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary) + error('Not implemented') + end + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+multiblock/Line.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,47 @@ +classdef Line < handle + properties + grid + lines + + YData + end + + methods + function obj = Line(g, gf) + assertType(g, 'multiblock.Grid') + obj.grid = g; + + X = obj.grid.splitFunc(obj.grid.points()); + Y = obj.grid.splitFunc(gf); + + holdState = ishold(); + hold on + + lines = cell(1, obj.grid.nBlocks); + for i = 1:obj.grid.nBlocks + lines{i} = plot(X{i}, Y{i}); + end + + if holdState == false + hold off + end + + obj.lines = [lines{:}]; + + obj.YData = gf; + end + + function set(obj, propertyName, propertyValue) + set(obj.lines, propertyName, propertyValue); + end + + function obj = set.YData(obj, gf) + obj.YData = gf; + + Y = obj.grid.funcToPlotMatrices(gf); + for i = 1:obj.grid.nBlocks + obj.lines(i).YData = Y{i}; + end + end + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+multiblock/Surface.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,62 @@ +classdef Surface < handle + properties + grid + surfs + + ZData + CData + + end + + methods + function obj = Surface(g, gf) + obj.grid = g; + + coords = obj.grid.points(); + X = obj.grid.funcToPlotMatrices(coords(:,1)); + Y = obj.grid.funcToPlotMatrices(coords(:,2)); + + V = obj.grid.funcToPlotMatrices(gf); + + + holdState = ishold(); + hold on + + surfs = cell(1, obj.grid.nBlocks); + for i = 1:obj.grid.nBlocks + surfs{i} = surf(X{i}, Y{i}, V{i}); + end + + if holdState == false + hold off + end + + obj.surfs = [surfs{:}]; + + obj.ZData = gf; + obj.CData = gf; + end + + function set(obj, propertyName, propertyValue) + set(obj.surfs, propertyName, propertyValue); + end + + function obj = set.ZData(obj, gf) + obj.ZData = gf; + + V = obj.grid.funcToPlotMatrices(gf); + for i = 1:obj.grid.nBlocks + obj.surfs(i).ZData = V{i}; + end + end + + function obj = set.CData(obj, gf) + obj.CData = gf; + + V = obj.grid.funcToPlotMatrices(gf); + for i = 1:obj.grid.nBlocks + obj.surfs(i).CData = V{i}; + end + end + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+multiblock/evalOn.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,27 @@ +% Evaluate different function handle for each block in a multiblock.Grid +% Function handles may optionaly take a time argument +% f -- cell array of function handles +% f{i} = f_i(t,x,y,...) +% t -- optional time point. If not specified, it is assumed that the functions take only spatial arguments. +function gf = evalOn(g, f, t) + assertType(g, 'multiblock.Grid'); + assertType(f, 'cell'); + + default_arg('t', []); + + grids = g.grids; + nBlocks = length(grids); + gf = cell(nBlocks, 1); + + if isempty(t) + for i = 1:nBlocks + gf{i} = grid.evalOn(grids{i}, f{i}); + end + else + for i = 1:nBlocks + gf{i} = grid.evalOn(grids{i}, @(varargin)f{i}(t,varargin{:})); + end + end + + gf = blockmatrix.toMatrix(gf); +end
--- a/+multiblock/gridVector1d.m Tue Sep 11 13:24:08 2018 +0200 +++ /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
--- a/+multiblock/gridVector2d.m Tue Sep 11 13:24:08 2018 +0200 +++ /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
--- a/+multiblock/multiblockgrid.m Tue Sep 11 13:24:08 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -% Creates a multi block square grid with defined boundary conditions. -% x,y defines the grid lines. Rember to think of the indexing as a matrix. Order matters! -% bc is a struct defining the boundary conditions on each side of the block. -% bc.w = {'dn',[function or value]} -function [block,conn,bound,ms] = multiblockgrid(x,y,mx,my,bc) - n = length(y)-1; % number of blocks in the y direction. - m = length(x)-1; % number of blocks in the x direction. - N = n*m; % number of blocks - - if ~issorted(x) - error('The elements of x seem to be in the wrong order'); - end - if ~issorted(flip(y)) - error('The elements of y seem to be in the wrong order'); - end - % y = sort(y,'descend'); - - % Dimensions of blocks and number of points - block = cell(n,m); - for i = 1:n - for j = 1:m - block{i,j} = { - {x(j),x(j+1)}, {y(i+1),y(i)}; - }; - - ms{i,j} = [mx(i),my(j)]; - end - end - - % Interface couplings - conn = cell(N,N); - for i = 1:n - for j = 1:m - I = flat_index(n,i,j); - if i < n - J = flat_index(n,i+1,j); - conn{I,J} = {'s','n'}; - end - - if j < m - J = flat_index(n,i,j+1); - conn{I,J} = {'e','w'}; - end - end - end - - - % Boundary conditions - bound = cell(n,m); - for i = 1:n - if isfield(bc,'w') - bound{i,1}.w = bc.w; - end - - if isfield(bc,'e') - bound{i,n}.e = bc.e; - end - end - - for j = 1:m - if isfield(bc,'n') - bound{1,j}.n = bc.n; - end - - if isfield(bc,'s') - bound{m,j}.s = bc.s; - end - end -end -
--- a/+multiblock/solutionVector2cell.m Tue Sep 11 13:24:08 2018 +0200 +++ /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
--- a/+multiblock/stitchSchemes.m Tue Sep 11 13:24:08 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,92 +0,0 @@ -% Stitch schemes together given connection matrix and BC vector. -% schmHand - function_handle to a Scheme constructor -% order - order of accuracy -% schmParam - cell array of extra parameters sent to each Scheme stored as cell arrays -% blocks - block definitions, On whatever form the scheme expects. -% ms - grid points in each direction for each block. Ex {[10,10], [10, 20]} -% conn - connection matrix -% bound - boundary condition vector, array of structs with fields w,e,s,n -% each field with a parameter array that is sent to schm.boundary_condition -% -% Output parameters are cell arrays and cell matrices. -% -% Ex: [schms, D, H] = stitchSchemes(schmHand, order, schmParam, blocks, ms, conn, bound) -function [schms, D, H] = stitchSchemes(schmHand, order, schmParam, blocks, ms, conn, bound) - default_arg('schmParam',[]); - - n_blocks = numel(blocks); - - % Creating Schemes - for i = 1:n_blocks - if isempty(schmParam); - schms{i} = schmHand(ms{i},blocks{i},order,[]); - elseif ~iscell(schmParam) - param = schmParam(i); - schms{i} = schmHand(ms{i},blocks{i},order,param); - else - param = schmParam{i}; - if iscell(param) - schms{i} = schmHand(ms{i},blocks{i},order,param{:}); - else - schms{i} = schmHand(ms{i},blocks{i},order,param); - end - end - - % class(schmParam) - % class(ms) - % class(blocks) - % class(schmParam{i}) - % class(ms) - - - end - - - % Total norm - H = cell(n_blocks,n_blocks); - for i = 1:n_blocks - H{i,i} = schms{i}.H; - end - - %% Total system matrix - - % Differentiation terms - D = cell(n_blocks,n_blocks); - for i = 1:n_blocks - D{i,i} = schms{i}.D; - end - - % Boundary penalty terms - for i = 1:n_blocks - if ~isstruct(bound{i}) - continue - end - - fn = fieldnames(bound{i}); - for j = 1:length(fn); - bc = bound{i}.(fn{j}); - if isempty(bc) - continue - end - - [closure, ~] = schms{i}.boundary_condition(fn{j},bc{:}); - D{i,i} = D{i,i}+closure; - end - end - - % Interface penalty terms - for i = 1:n_blocks - for j = 1:n_blocks - intf = conn{i,j}; - if isempty(intf) - continue - end - - [uu,uv,vv,vu] = schms{i}.interface_coupling(schms{i},intf{1},schms{j},intf{2}); - D{i,i} = D{i,i} + uu; - D{i,j} = uv; - D{j,j} = D{j,j} + vv; - D{j,i} = vu; - end - end -end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+noname/Animation.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,75 @@ +classdef Animation < handle + properties + timeStepper + representationMaker + updaters + end + + % add input validation + + methods + function obj = Animation(timeStepper, representationMaker, updaters); + obj.timeStepper = timeStepper; + obj.updaters = updaters; + obj.representationMaker = representationMaker; + end + + function update(obj, r) + for i = 1:length(obj.updaters) + obj.updaters{i}(r); + end + drawnow + end + + function run(obj, tEnd, timeModifier, do_pause) + default_arg('do_pause', false) + + function next_t = G(next_t) + obj.timeStepper.evolve(next_t); + r = obj.representationMaker(obj.timeStepper); + obj.update(r); + + if do_pause + pause + end + end + + anim.animate(@G, obj.timeStepper.t, tEnd, timeModifier); + end + + function step(obj, tEnd, do_pause) + default_arg('do_pause', false) + + while obj.timeStepper.t < tEnd + obj.timeStepper.step(); + + r = obj.representationMaker(obj.timeStepper); + obj.update(r); + + % TODO: Make it never go faster than a certain fram rate + + if do_pause + pause + end + end + end + + function saveMovie(obj, tEnd, timeModifier, figureHandle, dirname) + save_frame = anim.setup_fig_mov(figureHandle, dirname); + + function next_t = G(next_t) + obj.timeStepper.evolve(next_t); + r = obj.representationMaker(obj.timeStepper); + obj.update(r); + + save_frame(); + end + + fprintf('Generating and saving frames to: ..\n') + anim.animate(@G, obj.timeStepper.t, tEnd, timeModifier); + fprintf('Generating movies...\n') + cmd = sprintf('bash %s/+anim/make_movie.sh %s', sbplibLocation(),dirname); + system(cmd); + end + end +end
--- a/+noname/animate.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+noname/animate.m Tue Sep 11 15:58:35 2018 +0200 @@ -1,14 +1,18 @@ -% hand = noname.animate(discretization, time_modifier, Tend, dirname, opt) +% noname.animate(discretization, time_modifier, Tend, dirname, opt) % % Example: % noname.animate(discr,timemodifier,tend) % noname.animate(discr,1, [tstart tend],'my_mov', opt) -function hand = animate(discretization, time_modifier, Tend, dirname, opt) - default_arg('time_modifier',1); +function animate(discretization, time_modifier, Tend, dirname, opt) + default_arg('time_modifier', 1); default_arg('Tend', Inf); - default_arg('dirname',''); - default_arg('opt', []); + default_arg('dirname', ''); + + optDefault.plotType = 'animation'; + optDefault.time = []; + + default_struct('opt', optDefault); if time_modifier < 0 @@ -34,7 +38,7 @@ fprintf('m : %d\n',size(discretization)); - ts = discretization.getTimestepper(opt); + ts = discretization.getTimestepper(opt.time); if numel(Tend) == 2 Tstart = Tend(1); @@ -50,7 +54,7 @@ Tstart = start_solution.t; end - [update, figure_handle] = discretization.setupPlot('animation'); + [update, figure_handle] = discretization.setupPlot(opt.plotType); if makemovies save_frame = anim.setup_fig_mov(figure_handle,dirname); end @@ -83,7 +87,8 @@ pause anim.animate(@G, Tstart, Tend, time_modifier); else - while true + pause + while ts.t < Tend ts.step(); sol = discretization.getTimeSnapshot(ts); update(sol);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+noname/calcSol.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,10 @@ +% Calculates the solution of a discr at a given time using aligned timesteps. +% Returns the solution as a grid function as defined in +grid +function gf = calculateSolution(discr, T, tsOpt) + k_max = discr.getTimestep(tsOpt); + [k,N] = alignedTimestep(k_max,T); + tsOpt.k = k; + ts = discr.getTimestepper(tsOpt); + + gf = ts.stepN(N-ts.n); +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+noname/calculateErrors.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,53 @@ +% [discr, trueSolution] = schemeFactory(m) +% where trueSolution should be a timeSnapshot of the true solution a time T +% T is the end time +% m are grid size parameters. +% N are number of timesteps to use for each gird size +% timeOpt are options for the timeStepper +% errorFun is a function_handle taking 2 or 3 arguments, errorFun(trueSolution, approxSolution), errorFun(trueSolution, approxSolution, discr) +function e = calculateErrors(schemeFactory, T, m, N, errorFun, timeOpt) + %TODO: Ability to choose paralell or not + assertType(schemeFactory, 'function_handle'); + assertNumberOfArguments(schemeFactory, 1); + assertScalar(T); + assert(length(m) == length(N), 'Vectors m and N must have the same length'); + assertType(errorFun, 'function_handle'); + + if ~ismember(nargin(errorFun), [2,3]) + error('sbplib:noname:calculateErrors:wrongNumberOfArguments', '"%s" must have 2 or 3, found %d', toString(errorFun), nargin(errorFun)); + end + + default_arg('timeOpt', struct()); + + + e = zeros(1,length(m)); + parfor i = 1:length(m) + done = timeTask('m = %3d ', m(i)); + + [discr, trueSolution] = schemeFactory(m(i)); + + timeOptTemp = timeOpt; + timeOptTemp.k = T/N(i); + ts = discr.getTimestepper(timeOptTemp); + ts.stepTo(N(i), true); + approxSolution = discr.getTimeSnapshot(ts); + + switch nargin(errorFun) + case 2 + e(i) = errorFun(trueSolution, approxSolution); + case 3 + e(i) = errorFun(trueSolution, approxSolution, discr); + end + + fprintf('e = %.4e', e(i)) + done() + end + fprintf('\n') +end + + +%% Example error function +% u_true = grid.evalOn(dr.grid, @(x,y)trueSolution(T,x,y)); +% err = u_true-u_false; +% e(i) = norm(err)/norm(u_true); +% % e(i) = sqrt(err'*d.H*d.J*err/(u_true'*d.H*d.J*u_true));
--- a/+noname/calculateSolution.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+noname/calculateSolution.m Tue Sep 11 15:58:35 2018 +0200 @@ -13,7 +13,7 @@ fprintf('File ''%s'' already exist.',filename); do_append = yesnoQuestion('Do you want to append to it?'); if ~do_append - fprintf('Exiting...\n'); + fprintf('Exiting. No Solutions calculated.\n'); return end end
--- a/+noname/convergence.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+noname/convergence.m Tue Sep 11 15:58:35 2018 +0200 @@ -1,5 +1,5 @@ % Reference is either a key or a function handle -function [q, e, h, runtime] = convergence(filename, errorFunc, reference, method, order, m, T) +function [q, e, h, runtime] = convergence(filename, errorFunc, reference, name, order, m, T) default_arg('errorFunc', @scheme.error1d); sf = SolutionFile(filename); @@ -7,7 +7,7 @@ % Generate convergence, error, and efficiency plots for each search key with more than one entry. for i = 1:length(m) - key.method = method; + key.name = name; key.order = order; key.m = m(i); key.T = T; @@ -30,18 +30,11 @@ % Get the reference solution vector if isa(reference,'function_handle'); - x = v_repr.x; + x = v_repr.grid.points(); v_ref = reference(x,T); else % Downsample the reference solution - x = v_repr.x; - x_ref = reference.x; - - [~,I] = ismember(x,x_ref,'rows'); - if any(I == 0) - error('Solution and reference solution seem to be on different grids.'); - end - v_ref = reference.v(I); + v_ref = reference.grid.restrictFunc(reference.v, v_repr.grid); end e = errorFunc(discr,v, v_ref);
--- a/+noname/plotSolutions.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+noname/plotSolutions.m Tue Sep 11 15:58:35 2018 +0200 @@ -10,7 +10,7 @@ key = sf.keys{i}; entry = sf.get(key); - method = key.method; + name = key.name; order = key.order; m = key.m; T = key.T; @@ -23,11 +23,11 @@ update(repr); if save_figures - figname = sprintf('%s_%s_o%d_m%d_T%d',figename_prefix,method,order,m,i); + figname = sprintf('%s_%s_o%d_m%d_T%d',figename_prefix,name,order,m,i); fprintf('Saving figure to ''%s''\n',figname); saveeps(hand,figname); end end -end \ No newline at end of file +end
--- a/+noname/testCfl.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+noname/testCfl.m Tue Sep 11 15:58:35 2018 +0200 @@ -27,29 +27,37 @@ end end + if silentFlag + rsInterval = util.ReplaceableString(''); + end + % Use bisection to find sharp estimate while( (alpha0(2)-alpha0(1))/alpha0(1) > tol) alpha = mean(alpha0); if ~silentFlag fprintf('[%.3e,%.3e]: ', alpha0(1), alpha0(2)); + else + rsInterval.update('[%.3e,%.3e]: ', alpha0(1), alpha0(2)); end [ok, n_step, maxVal] = testAlpha(alpha); if ok alpha0(1) = alpha; + stability = 'STABLE'; else alpha0(2) = alpha; + stability = 'UNSTABLE'; end if ~silentFlag - fprintf('a = %.3e, n_step=%d max = %.2e\n', alpha, n_step, maxVal); + fprintf('a = %.3e, n_step=%d %8s max = %.2e\n', alpha, n_step, stability, maxVal); end end if silentFlag - fprintf('Last calculated: a = %.3e, n_step=%d max = %.2e\n', alpha, n_step, maxVal); + rsInterval = util.ReplaceableString(''); end fprintf('T = %-3d dof = %-4d order = %d: clf = %.4e\n',T, discr.size(), discr.order, alpha0(1));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+parametrization/Curve.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,396 @@ +classdef Curve + properties + g + gp + transformation + end + + methods + %TODO: + % Concatenation of curves + % Subsections of curves + % Stretching of curve parameter - done for arc length. + % Curve to cell array of linesegments + + % Returns a curve object. + % g -- curve parametrization for parameter between 0 and 1 + % gp -- parametrization of curve derivative + function obj = Curve(g,gp,transformation) + default_arg('gp',[]); + default_arg('transformation',[]); + p_test = g(0); + assert(all(size(p_test) == [2,1]), 'A curve parametrization must return a 2x1 vector.'); + + if ~isempty(transformation) + transformation.base_g = g; + transformation.base_gp = gp; + [g,gp] = parametrization.Curve.transform_g(g,gp,transformation); + end + + obj.g = g; + obj.gp = gp; + obj.transformation = transformation; + + end + + function n = normal(obj,t) + assert(~isempty(obj.gp),'Curve has no derivative!'); + deriv = obj.gp(t); + normalization = sqrt(sum(deriv.^2,1)); + n = [-deriv(2,:)./normalization; deriv(1,:)./normalization]; + end + + + % Plots a curve g(t) for 0<t<1, using n points. Returns a handle h to the plotted curve. + % h = plot_curve(g,n) + function h = plot(obj,n) + default_arg('n',100); + + t = linspace(0,1,n); + p = obj.g(t); + h = line(p(1,:),p(2,:)); + end + + function h= plot_normals(obj,l,n,m) + default_arg('l',0.1); + default_arg('n',10); + default_arg('m',100); + t_n = linspace(0,1,n); + + normals = obj.normal(t_n)*l; + + n0 = obj.g(t_n); + n1 = n0 + normals; + + h = line([n0(1,:); n1(1,:)],[n0(2,:); n1(2,:)]); + set(h,'Color',Color.red); + obj.plot(m); + end + + function h= show(obj,name) + default_arg('name', '') + p = obj.g(1/2); + n = obj.normal(1/2); + p = p + n*0.1; + + % Add arrow + + + if ~isempty(name) + h = text(p(1),p(2),name); + h.HorizontalAlignment = 'center'; + h.VerticalAlignment = 'middle'; + end + + h = obj.plot(); + end + % Shows curve with name and arrow for direction. + + % Length of arc from parameter t0 to t1 (which may be vectors). + % Computed using derivative. + function L = arcLength(obj,t0,t1) + assert(~isempty(obj.gp),'Curve has no derivative!'); + speed = @(t) sqrt(sum(obj.gp(t).^2,1)); + L = integral_vec(speed,t0,t1); + end + + % Creates the arc length parameterization of a curve. + % N -- number of points used to approximate the arclength function + function curve = arcLengthParametrization(obj,N) + default_arg('N',100); + assert(~isempty(obj.gp),'Curve has no derivative!'); + + % Construct arcLength function using splines + tvec = linspace(0,1,N); + arcVec = obj.arcLength(0,tvec); + tFunc = spline(arcVec,tvec); % t as a function of arcLength + L = obj.arcLength(0,1); + arcPar = @(s) tFunc(s*L); + + % New function and derivative + g_new = @(t)obj.g(arcPar(t)); + gp_new = @(t) normalize(obj.gp(arcPar(t))); + curve = parametrization.Curve(g_new,gp_new); + + end + + % how to make it work for methods without returns + function p = subsref(obj,S) + %Should i add error checking here? + %Maybe if you want performance you fetch obj.g and then use that + switch S(1).type + case '()' + p = obj.g(S.subs{1}); + % case '.' + + % p = obj.(S.subs); + otherwise + p = builtin('subsref',obj,S); + % error() + end + end + + + %% TRANSFORMATION OF A CURVE + function D = reverse(C) + % g = C.g; + % gp = C.gp; + % D = parametrization.Curve(@(t)g(1-t),@(t)-gp(1-t)); + D = C.transform([],[],-1); + end + + function D = transform(C,A,b,flip) + default_arg('A',[1 0; 0 1]); + default_arg('b',[0; 0]); + default_arg('flip',1); + if isempty(C.transformation) + g = C.g; + gp = C.gp; + transformation.A = A; + transformation.b = b; + transformation.flip = flip; + else + g = C.transformation.base_g; + gp = C.transformation.base_gp; + A_old = C.transformation.A; + b_old = C.transformation.b; + flip_old = C.transformation.flip; + + transformation.A = A*A_old; + transformation.b = A*b_old + b; + transformation.flip = flip*flip_old; + end + + D = parametrization.Curve(g,gp,transformation); + + end + + function D = translate(C,a) + g = C.g; + gp = C.gp; + + % function v = g_fun(t) + % x = g(t); + % v(1,:) = x(1,:)+a(1); + % v(2,:) = x(2,:)+a(2); + % end + + % D = parametrization.Curve(@g_fun,gp); + + D = C.transform([],a); + end + + function D = mirror(C, a, b) + assertSize(a,[2,1]); + assertSize(b,[2,1]); + + g = C.g; + gp = C.gp; + + l = b-a; + lx = l(1); + ly = l(2); + + + % fprintf('Singular?\n') + + A = [lx^2-ly^2 2*lx*ly; 2*lx*ly ly^2-lx^2]/(l'*l); + + % function v = g_fun(t) + % % v = a + A*(g(t)-a) + % x = g(t); + + % ax1 = x(1,:)-a(1); + % ax2 = x(2,:)-a(2); + % v(1,:) = a(1)+A(1,:)*[ax1;ax2]; + % v(2,:) = a(2)+A(2,:)*[ax1;ax2]; + % end + + % function v = gp_fun(t) + % v = A*gp(t); + % end + + % D = parametrization.Curve(@g_fun,@gp_fun); + + % g = A(g-a)+a = Ag - Aa + a; + b = - A*a + a; + D = C.transform(A,b); + + end + + function D = rotate(C,a,rad) + assertSize(a, [2,1]); + assertSize(rad, [1,1]); + g = C.g; + gp = C.gp; + + + A = [cos(rad) -sin(rad); sin(rad) cos(rad)]; + + % function v = g_fun(t) + % % v = a + A*(g(t)-a) + % x = g(t); + + % ax1 = x(1,:)-a(1); + % ax2 = x(2,:)-a(2); + % v(1,:) = a(1)+A(1,:)*[ax1;ax2]; + % v(2,:) = a(2)+A(2,:)*[ax1;ax2]; + % end + + % function v = gp_fun(t) + % v = A*gp(t); + % end + + % D = parametrization.Curve(@g_fun,@gp_fun); + + + % g = A(g-a)+a = Ag - Aa + a; + b = - A*a + a; + D = C.transform(A,b); + end + end + + methods (Static) + + % Computes the derivative of g: R -> R^2 using an operator D1 + function gp_out = numericalDerivative(g,D1) + m = length(D1); + t = linspace(0,1,m); + gVec = g(t)'; + gpVec = (D1*gVec)'; + + gp1_fun = spline(t,gpVec(1,:)); + gp2_fun = spline(t,gpVec(2,:)); + gp_out = @(t) [gp1_fun(t);gp2_fun(t)]; + end + + function obj = line(p1, p2) + + function v = g_fun(t) + v(1,:) = p1(1) + t.*(p2(1)-p1(1)); + v(2,:) = p1(2) + t.*(p2(2)-p1(2)); + end + + function v = g_fun_deriv(t) + v(1,:) = t.*0 + (p2(1)-p1(1)); + v(2,:) = t.*0 + (p2(2)-p1(2)); + end + + obj = parametrization.Curve(@g_fun, @g_fun_deriv); + end + + function obj = circle(c,r,phi) + default_arg('phi',[0; 2*pi]) + default_arg('c',[0; 0]) + default_arg('r',1) + + function v = g_fun(t) + w = phi(1)+t*(phi(2)-phi(1)); + v(1,:) = c(1) + r*cos(w); + v(2,:) = c(2) + r*sin(w); + end + + function v = g_fun_deriv(t) + w = phi(1)+t*(phi(2)-phi(1)); + v(1,:) = -(phi(2)-phi(1))*r*sin(w); + v(2,:) = (phi(2)-phi(1))*r*cos(w); + end + + obj = parametrization.Curve(@g_fun,@g_fun_deriv); + end + + function obj = bezier(p0, p1, p2, p3) + function v = g_fun(t) + v(1,:) = (1-t).^3*p0(1) + 3*(1-t).^2.*t*p1(1) + 3*(1-t).*t.^2*p2(1) + t.^3*p3(1); + v(2,:) = (1-t).^3*p0(2) + 3*(1-t).^2.*t*p1(2) + 3*(1-t).*t.^2*p2(2) + t.^3*p3(2); + end + + function v = g_fun_deriv(t) + v(1,:) = 3*(1-t).^2*(p1(1)-p0(1)) + 6*(1-t).*t*(p2(1)-p1(1)) + 3*t.^2*(p3(1)-p2(1)); + v(2,:) = 3*(1-t).^2*(p1(2)-p0(2)) + 6*(1-t).*t*(p2(2)-p1(2)) + 3*t.^2*(p3(2)-p2(2)); + end + + obj = parametrization.Curve(@g_fun,@g_fun_deriv); + end + + + function [g_out,gp_out] = transform_g(g,gp,tr) + A = tr.A; + b = tr.b; + flip = tr.flip; + + function v = g_fun_noflip(t) + % v = A*g + b + x = g(t); + + v(1,:) = A(1,:)*x+b(1); + v(2,:) = A(2,:)*x+b(2); + end + + function v = g_fun_flip(t) + % v = A*g + b + x = g(1-t); + + v(1,:) = A(1,:)*x+b(1); + v(2,:) = A(2,:)*x+b(2); + end + + + switch flip + case 1 + g_out = @g_fun_noflip; + gp_out = @(t)A*gp(t); + case -1 + g_out = @g_fun_flip; + gp_out = @(t)-A*gp(1-t); + end + end + + end +end + + + +function g_norm = normalize(g0) + g1 = g0(1,:); + g2 = g0(2,:); + normalization = sqrt(sum(g0.^2,1)); + g_norm = [g1./normalization; g2./normalization]; +end + +function I = integral_vec(f,a,b) +% Wrapper around the built-in function integral that +% handles multiple limits. + + Na = length(a); + Nb = length(b); + assert(Na == 1 || Nb == 1 || Na==Nb,... + 'a and b must have same length, unless one is a scalar.'); + + if(Na>Nb); + I = zeros(size(a)); + for i = 1:Na + I(i) = integral(f,a(i),b); + end + elseif(Nb>Na) + I = zeros(size(b)); + for i = 1:Nb + I(i) = integral(f,a,b(i)); + end + else + I = zeros(size(b)); + for i = 1:Nb + I(i) = integral(f,a(i),b(i)); + end + end +end + +% Returns a function handle to the spline. +function f = spline(tval,fval,spline_order) + default_arg('spline_order',4); + [m,~] = size(tval); + assert(m==1,'Need row vectors.'); + + f_spline = spapi( optknt(tval,spline_order), tval, fval ); + f = @(t) fnval(f_spline,t); +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+parametrization/Ti.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,255 @@ +classdef Ti + properties + gs % {4}Curve + S % FunctionHandle(u,v) + end + + methods + % TODO function to label boundary names. + % function to find largest and smallest delta h in the grid. Maybe shouldnt live here + function obj = Ti(C1,C2,C3,C4) + obj.gs = {C1,C2,C3,C4}; + + g1 = C1.g; + g2 = C2.g; + g3 = C3.g; + g4 = C4.g; + + A = g1(0); + B = g2(0); + C = g3(0); + D = g4(0); + + function o = S_fun(u,v) + if isrow(u) && isrow(v) + flipped = false; + else + flipped = true; + u = u'; + v = v'; + end + + x1 = g1(u); + x2 = g2(v); + x3 = g3(1-u); + x4 = g4(1-v); + + o1 = (1-v).*x1(1,:) + u.*x2(1,:) + v.*x3(1,:) + (1-u).*x4(1,:) ... + -((1-u).*(1-v).*A(1,:) + u.*(1-v).*B(1,:) + u.*v.*C(1,:) + (1-u).*v.*D(1,:)); + o2 = (1-v).*x1(2,:) + u.*x2(2,:) + v.*x3(2,:) + (1-u).*x4(2,:) ... + -((1-u).*(1-v).*A(2,:) + u.*(1-v).*B(2,:) + u.*v.*C(2,:) + (1-u).*v.*D(2,:)); + + if ~flipped + o = [o1;o2]; + else + o = [o1'; o2']; + end + end + + obj.S = @S_fun; + end + + % Does this funciton make sense? + % Should it always be eval? + function [X,Y] = map(obj,u,v) + default_arg('v',u); + + if isscalar(u) + u = linspace(0,1,u); + end + + if isscalar(v) + v = linspace(0,1,v); + end + + S = obj.S; + + nu = length(u); + nv = length(v); + + X = zeros(nv,nu); + Y = zeros(nv,nu); + + u = rowVector(u); + v = rowVector(v); + + for i = 1:nv + p = S(u,v(i)); + X(i,:) = p(1,:); + Y(i,:) = p(2,:); + end + end + + % Evaluate S for each pair of u and v, + % Return same shape as u + function [x, y] = eval(obj, u, v) + x = zeros(size(u)); + y = zeros(size(u)); + + for i = 1:numel(u) + p = obj.S(u(i), v(i)); + x(i) = p(1,:); + y(i) = p(2,:); + end + end + + function h = plot(obj,nu,nv) + S = obj.S; + + default_arg('nv',nu) + + u = linspace(0,1,nu); + v = linspace(0,1,nv); + + m = 100; + + X = zeros(nu+nv,m); + Y = zeros(nu+nv,m); + + + t = linspace(0,1,m); + for i = 1:nu + p = S(u(i),t); + X(i,:) = p(1,:); + Y(i,:) = p(2,:); + end + + for i = 1:nv + p = S(t,v(i)); + X(i+nu,:) = p(1,:); + Y(i+nu,:) = p(2,:); + end + + h = line(X',Y'); + end + + + function h = show(obj,nu,nv) + default_arg('nv',nu) + S = obj.S; + + if(nu>2 || nv>2) + h.grid = obj.plot(nu,nv); + set(h.grid,'Color',[0 0.4470 0.7410]); + end + + h.border = obj.plot(2,2); + set(h.border,'Color',[0.8500 0.3250 0.0980]); + set(h.border,'LineWidth',2); + end + + + % TRANSFORMATIONS + function ti = translate(obj,a) + gs = obj.gs; + + for i = 1:length(gs) + new_gs{i} = gs{i}.translate(a); + end + + ti = parametrization.Ti(new_gs{:}); + end + + % Mirrors the Ti so that the resulting Ti is still left handed. + % (Corrected by reversing curves and switching e and w) + function ti = mirror(obj, a, b) + gs = obj.gs; + + new_gs = cell(1,4); + + new_gs{1} = gs{1}.mirror(a,b).reverse(); + new_gs{3} = gs{3}.mirror(a,b).reverse(); + new_gs{2} = gs{4}.mirror(a,b).reverse(); + new_gs{4} = gs{2}.mirror(a,b).reverse(); + + ti = parametrization.Ti(new_gs{:}); + end + + function ti = rotate(obj,a,rad) + gs = obj.gs; + + for i = 1:length(gs) + new_gs{i} = gs{i}.rotate(a,rad); + end + + ti = parametrization.Ti(new_gs{:}); + end + + function ti = rotate_edges(obj,n); + new_gs = cell(1,4); + for i = 0:3 + new_i = mod(i - n,4); + new_gs{new_i+1} = obj.gs{i+1}; + end + ti = parametrization.Ti(new_gs{:}); + end + end + + methods(Static) + function obj = points(p1, p2, p3, p4) + g1 = parametrization.Curve.line(p1,p2); + g2 = parametrization.Curve.line(p2,p3); + g3 = parametrization.Curve.line(p3,p4); + g4 = parametrization.Curve.line(p4,p1); + + obj = parametrization.Ti(g1,g2,g3,g4); + end + + function obj = rectangle(a, b) + p1 = a; + p2 = [b(1), a(2)]; + p3 = b; + p4 = [a(1), b(2)]; + + obj = parametrization.Ti.points(p1,p2,p3,p4); + end + + % Like the constructor but allows inputing line curves as 2-cell arrays: + % example: parametrization.Ti.linesAndCurves(g1, g2, {a, b} g4) + function obj = linesAndCurves(C1, C2, C3, C4) + C = {C1, C2, C3, C4}; + c = cell(1,4); + + for i = 1:4 + if ~iscell(C{i}) + c{i} = C{i}; + else + c{i} = parametrization.Curve.line(C{i}{:}); + end + end + + obj = parametrization.Ti(c{:}); + end + + function label(varargin) + if nargin == 2 && ischar(varargin{2}) + label_impl(varargin{:}); + else + for i = 1:length(varargin) + label_impl(varargin{i},inputname(i)); + end + end + + + function label_impl(ti,str) + S = ti.S; + + pc = S(0.5,0.5); + + margin = 0.1; + pw = S( margin, 0.5); + pe = S(1-margin, 0.5); + ps = S( 0.5, margin); + pn = S( 0.5, 1-margin); + + + ti.show(2,2); + parametrization.place_label(pc,str); + parametrization.place_label(pw,'w'); + parametrization.place_label(pe,'e'); + parametrization.place_label(ps,'s'); + parametrization.place_label(pn,'n'); + end + end + end +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+parametrization/Ti3D.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,253 @@ +classdef Ti3D + properties + gs % {6}Surfaces + V % FunctionHandle(XI,ETA,ZETA) + end + + methods + % TODO write all fancy features for flipping around with the surfaces + % Each surface is defined with an outward facing outward and choosing + % the "corner" where XI=0 if not possible the corner where ETA=0 is choosen + function obj = Ti3D(CW,CE,CS,CN,CB,CT) + obj.gs = {CE,CW,CS,CN,CB,CT}; + + gw = CW.g; + ge = CE.g; + gs = CS.g; + gn = CN.g; + gb = CB.g; + gt = CT.g; + + function o = V_fun(XI,ETA,ZETA) + XI=XI'; + ETA=ETA'; + ZETA=ZETA'; + + one=0*ETA+1; + zero=0*ETA; + + Sw = gw(ETA,(1-ZETA)); + Se = ge((1-ETA),(1-ZETA)); + Ss = gs(XI,ZETA); + Sn = gn((1-XI),(1-ZETA)); + Sb = gb((1-XI),ETA); + St = gt(XI,ETA); + + Ewt = gw(ETA,zero); + Ewb = gw(ETA,one); + Ews = gw(zero,1-ZETA); + Ewn = gw(one,1-ZETA); + Eet = ge(1-ETA,zero); + Eeb = ge(1-ETA,one); + Ees = ge(one,1-ZETA); + Een = ge(zero,1-ZETA); + Enb = gn(1-XI,one); + Ent = gn(1-XI,zero); + Est = gs(XI,one); + Esb = gs(XI,zero); + + Cwbs = gw(zero,one); + Cwbn = gw(one,one); + Cwts = gw(zero,zero); + Cwtn = gw(one,zero); + Cebs = ge(one,one); + Cebn = ge(zero,one); + Cets = ge(one,zero); + Cetn = ge(zero,zero); + + + X1 = (1-XI).*Sw(1,:,:) + XI.*Se(1,:,:); + X2 = (1-ETA).*Ss(1,:,:) + ETA.*Sn(1,:,:); + X3 = (1-ZETA).*Sb(1,:,:) + ZETA.*St(1,:,:); + + X12 = (1-XI).*(1-ETA).*Ews(1,:,:) + (1-XI).*ETA.*Ewn(1,:,:) + XI.*(1-ETA).*Ees(1,:,:) + XI.*ETA.*Een(1,:,:); + X13 = (1-XI).*(1-ZETA).*Ewb(1,:,:) + (1-XI).*ZETA.*Ewt(1,:,:) + XI.*(1-ZETA).*Eeb(1,:,:) + XI.*ZETA.*Eet(1,:,:); + X23 = (1-ETA).*(1-ZETA).*Esb(1,:,:) + (1-ETA).*ZETA.*Est(1,:,:) + ETA.*(1-ZETA).*Enb(1,:,:) + ETA.*ZETA.*Ent(1,:,:); + + X123 = (1-XI).*(1-ETA).*(1-ZETA).*Cwbs(1,:,:) + (1-XI).*(1-ETA).*ZETA.*Cwts(1,:,:) + (1-XI).*ETA.*(1-ZETA).*Cwbn(1,:,:) + ... + (1-XI).*ETA.*ZETA.*Cwtn(1,:,:) + XI.*(1-ETA).*(1-ZETA).*Cebs(1,:,:) + XI.*(1-ETA).*ZETA.*Cets(1,:,:) + ... + XI.*ETA.*(1-ZETA).*Cebn(1,:,:) + XI.*ETA.*ZETA.*Cetn(1,:,:); + + X = X1 + X2 + X3 - X12 - X13 - X23 + X123; + + + Y1 = (1-XI).*Sw(2,:,:) + XI.*Se(2,:,:); + Y2 = (1-ETA).*Ss(2,:,:) + ETA.*Sn(2,:,:); + Y3 = (1-ZETA).*Sb(2,:,:) + ZETA.*St(2,:,:); + + Y12 = (1-XI).*(1-ETA).*Ews(2,:,:) + (1-XI).*ETA.*Ewn(2,:,:) + XI.*(1-ETA).*Ees(2,:,:) + XI.*ETA.*Een(2,:,:); + Y13 = (1-XI).*(1-ZETA).*Ewb(2,:,:) + (1-XI).*ZETA.*Ewt(2,:,:) + XI.*(1-ZETA).*Eeb(2,:,:) + XI.*ZETA.*Eet(2,:,:); + Y23 = (1-ETA).*(1-ZETA).*Esb(2,:,:) + (1-ETA).*ZETA.*Est(2,:,:) + ETA.*(1-ZETA).*Enb(2,:,:) + ETA.*ZETA.*Ent(2,:,:); + + Y123 = (1-XI).*(1-ETA).*(1-ZETA).*Cwbs(2,:,:) + (1-XI).*(1-ETA).*ZETA.*Cwts(2,:,:) + (1-XI).*ETA.*(1-ZETA).*Cwbn(2,:,:) + ... + (1-XI).*ETA.*ZETA.*Cwtn(2,:,:) + XI.*(1-ETA).*(1-ZETA).*Cebs(2,:,:) + XI.*(1-ETA).*ZETA.*Cets(2,:,:) + ... + XI.*ETA.*(1-ZETA).*Cebn(2,:,:) + XI.*ETA.*ZETA.*Cetn(2,:,:); + + Y = Y1 + Y2 + Y3 - Y12 - Y13 - Y23 + Y123; + + + Z1 = (1-XI).*Sw(3,:,:) + XI.*Se(3,:,:); + Z2 = (1-ETA).*Ss(3,:,:) + ETA.*Sn(3,:,:); + Z3 = (1-ZETA).*Sb(3,:,:) + ZETA.*St(3,:,:); + + Z12 = (1-XI).*(1-ETA).*Ews(3,:,:) + (1-XI).*ETA.*Ewn(3,:,:) + XI.*(1-ETA).*Ees(3,:,:) + XI.*ETA.*Een(3,:,:); + Z13 = (1-XI).*(1-ZETA).*Ewb(3,:,:) + (1-XI).*ZETA.*Ewt(3,:,:) + XI.*(1-ZETA).*Eeb(3,:,:) + XI.*ZETA.*Eet(3,:,:); + Z23 = (1-ETA).*(1-ZETA).*Esb(3,:,:) + (1-ETA).*ZETA.*Est(3,:,:) + ETA.*(1-ZETA).*Enb(3,:,:) + ETA.*ZETA.*Ent(3,:,:); + + Z123 = (1-XI).*(1-ETA).*(1-ZETA).*Cwbs(3,:,:) + (1-XI).*(1-ETA).*ZETA.*Cwts(3,:,:) + (1-XI).*ETA.*(1-ZETA).*Cwbn(3,:,:) + ... + (1-XI).*ETA.*ZETA.*Cwtn(3,:,:) + XI.*(1-ETA).*(1-ZETA).*Cebs(3,:,:) + XI.*(1-ETA).*ZETA.*Cets(3,:,:) + ... + XI.*ETA.*(1-ZETA).*Cebn(3,:,:) + XI.*ETA.*ZETA.*Cetn(3,:,:); + + Z = Z1 + Z2 + Z3 - Z12 - Z13 - Z23 + Z123; + o = [X;Y;Z]; + end + + obj.V = @V_fun; + end + + %Should be rewritten so that the input is xi eta zeta + function [X,Y,Z] = map(obj,XI,ETA,ZETA) + + V = obj.V; + + p = V(XI,ETA,ZETA); + X = p(1,:)'; + Y = p(2,:)'; + Z = p(3,:)'; + + end + + % function h = plot(obj,nu,nv) + % S = obj.S; + % + % default_arg('nv',nu) + % + % u = linspace(0,1,nu); + % v = linspace(0,1,nv); + % + % m = 100; + % + % X = zeros(nu+nv,m); + % Y = zeros(nu+nv,m); + % + % + % t = linspace(0,1,m); + % for i = 1:nu + % p = S(u(i),t); + % X(i,:) = p(1,:); + % Y(i,:) = p(2,:); + % end + % + % for i = 1:nv + % p = S(t,v(i)); + % X(i+nu,:) = p(1,:); + % Y(i+nu,:) = p(2,:); + % end + % + % h = line(X',Y'); + % end + % + % + % function h = show(obj,nu,nv) + % default_arg('nv',nu) + % S = obj.S; + % + % if(nu>2 || nv>2) + % h_grid = obj.plot(nu,nv); + % set(h_grid,'Color',[0 0.4470 0.7410]); + % end + % + % h_bord = obj.plot(2,2); + % set(h_bord,'Color',[0.8500 0.3250 0.0980]); + % set(h_bord,'LineWidth',2); + % end + % + % + % % TRANSFORMATIONS + % function ti = translate(obj,a) + % gs = obj.gs; + % + % for i = 1:length(gs) + % new_gs{i} = gs{i}.translate(a); + % end + % + % ti = grid.Ti(new_gs{:}); + % end + % + % % Mirrors the Ti so that the resulting Ti is still left handed. + % % (Corrected by reversing curves and switching e and w) + % function ti = mirror(obj, a, b) + % gs = obj.gs; + % + % new_gs = cell(1,4); + % + % new_gs{1} = gs{1}.mirror(a,b).reverse(); + % new_gs{3} = gs{3}.mirror(a,b).reverse(); + % new_gs{2} = gs{4}.mirror(a,b).reverse(); + % new_gs{4} = gs{2}.mirror(a,b).reverse(); + % + % ti = grid.Ti(new_gs{:}); + % end + % + % function ti = rotate(obj,a,rad) + % gs = obj.gs; + % + % for i = 1:length(gs) + % new_gs{i} = gs{i}.rotate(a,rad); + % end + % + % ti = grid.Ti(new_gs{:}); + % end + % + % function ti = rotate_edges(obj,n); + % new_gs = cell(1,4); + % for i = 0:3 + % new_i = mod(i - n,4); + % new_gs{new_i+1} = obj.gs{i+1}; + % end + % ti = grid.Ti(new_gs{:}); + % end + % end + % + % methods(Static) + % function obj = points(p1, p2, p3, p4) + % g1 = grid.Curve.line(p1,p2); + % g2 = grid.Curve.line(p2,p3); + % g3 = grid.Curve.line(p3,p4); + % g4 = grid.Curve.line(p4,p1); + % + % obj = grid.Ti(g1,g2,g3,g4); + % end + % + % function label(varargin) + % if nargin == 2 && ischar(varargin{2}) + % label_impl(varargin{:}); + % else + % for i = 1:length(varargin) + % label_impl(varargin{i},inputname(i)); + % end + % end + % + % + % function label_impl(ti,str) + % S = ti.S; + % + % pc = S(0.5,0.5); + % + % margin = 0.1; + % pw = S( margin, 0.5); + % pe = S(1-margin, 0.5); + % ps = S( 0.5, margin); + % pn = S( 0.5, 1-margin); + % + % + % ti.show(2,2); + % grid.place_label(pc,str); + % grid.place_label(pw,'w'); + % grid.place_label(pe,'e'); + % grid.place_label(ps,'s'); + % grid.place_label(pn,'n'); + % end + % end + end +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+parametrization/TiTest.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,52 @@ +function tests = TiTest() + tests = functiontests(localfunctions); +end + +function testScalarInput(testCase) + ti = getMinimumTi(); + + cases = { + % {u, v, out}, + {0, 0, [1; 2]}, + {0, 1, [1; 4]}, + {1, 0, [3; 2]}, + {1, 1, [3; 4]}, + {0.5, 0.5, [2; 3]}, + }; + + for i = 1:length(cases) + u = cases{i}{1}; + v = cases{i}{2}; + expected = cases{i}{3}; + + testCase.verifyEqual(ti.S(u,v), expected, sprintf('Case: %d',i)); + end +end + +function testRowVectorInput(testCase) + ti = getMinimumTi(); + + u = [0, 0.5, 1]; + v = [0, 0, 0.5]; + expected = [ + 1, 2, 3; + 2, 2, 3; + ]; + + testCase.verifyEqual(ti.S(u,v), expected); +end + +function testColumnvectorInput(testCase) + ti = getMinimumTi(); + + u = [0; 0.5; 1]; + v = [0; 0; 0.5]; + expected = [1; 2; 3; 2; 2; 3]; + + testCase.verifyEqual(ti.S(u,v), expected); +end + + +function ti = getMinimumTi() + ti = parametrization.Ti.rectangle([1; 2], [3; 4]); +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+parametrization/equal_step_size.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,4 @@ +% Calculates M so that the stepsize m/M is as close to n/M as possible +function M = equal_step_size(n,N,m) + M = round((m*(N-1)+n)/n); +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+parametrization/old/concat_curve.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,12 @@ +% Concatenate two curves g1 and g2 intop +% g = concat_curve(g1,g2) +function g = concat_curve(g1,g2) + function v = g_fun(t) + if t < 1/2 + v = g1(2*t); + else + v = g2(2*t-1); + end + end + g = @g_fun; +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+parametrization/old/curve_discretise.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,97 @@ +% Discretises the curve g with the smallest number of points such that all segments +% are shorter than h. If do_plot is true the points of the discretisation and +% the normals of the curve in those points are plotted. +% +% [t,p,d] = curve_discretise(g,h,do_plot) +% +% t is a vector of input values to g. +% p is a cector of points. +% d are the length of the segments. +function [t,p,d] = curve_discretise(g,h,do_plot) + default_arg('do_plot',false) + + n = 10; + + [t,p,d] = curve_discretise_n(g,n); + + % ni = 0; + while any(d>h) + [t,p,d] = curve_discretise_n(g,n); + n = ceil(n*d(1)/h); + % ni = ni+1; + end + + % nj = 0; + while all(d<h) + [t,p,d] = curve_discretise_n(g,n); + n = n-1; + % nj = nj+1; + end + [t,p,d] = curve_discretise_n(g,n+1); + + % fprintf('ni = %d, nj = %d\n',ni,nj); + + if do_plot + fprintf('n:%d max: %f min: %f\n', n, max(d),min(d)); + p = parametrization.map_curve(g,t); + figure + show(g,t,h); + end + +end + +function [t,p,d] = curve_discretise_n(g,n) + t = linspace(0,1,n); + t = equalize_d(g,t); + d = D(g,t); + p = parametrization.map_curve(g,t); +end + +function d = D(g,t) + p = parametrization.map_curve(g,t); + + d = zeros(1,length(t)-1); + for i = 1:length(d) + d(i) = norm(p(:,i) - p(:,i+1)); + end +end + +function t = equalize_d(g,t) + d = D(g,t); + v = d-mean(d); + while any(abs(v)>0.01*mean(d)) + dt = t(2:end)-t(1:end-1); + t(2:end) = t(2:end) - cumsum(dt.*v./d); + + t = t/t(end); + d = D(g,t); + v = d-mean(d); + end +end + + +function show(g,t,hh) + p = parametrization.map_curve(g,t); + + + + h = parametrization.plot_curve(g); + h.LineWidth = 2; + axis equal + hold on + h = plot(p(1,:),p(2,:),'.'); + h.Color = [0.8500 0.3250 0.0980]; + h.MarkerSize = 24; + hold off + + n = parametrization.curve_normals(g,t); + hold on + for i = 1:length(t) + p0 = p(:,i); + p1 = p0 + hh*n(:,i); + l = [p0, p1]; + h = plot(l(1,:),l(2,:)); + h.Color = [0.8500 0.3250 0.0980]; + end + +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+parametrization/old/curve_interp.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,58 @@ +% Create a cubic spline from the points (x,y) using periodic conditions. +% g = curve_interp(x,y) +function g = curve_interp(x,y) + default_arg('x',[0 2 2 1 1 0]) + default_arg('y',[0 0 2 2 1 1]) + % solve for xp and yp + + % x(t) = at^4 + bt^2+ct+d + + % a = xp1 -2x1 + 2x0 + xp0 + % b = 3x1 -xp1 - 3x0 + 2xp0 + % c = xp0 + % d = x0 + + assert(length(x) == length(y)) + n = length(x); + A = spdiags(ones(n,1)*[2, 8, 2],-1:1,n,n); + A(n,1) = 2; + A(1,n) = 2; + + bx = zeros(n,1); + for i = 2:n-1 + bx(i) = -6*x(i-1)+6*x(i+1); + end + bx(1) = -6*x(n)+6*x(2); + bx(n) = -6*x(n-1)+6*x(1); + + by = zeros(n,1); + for i = 2:n-1 + by(i) = -6*y(i-1)+6*y(i+1); + end + by(1) = -6*y(n)+6*y(2); + by(n) = -6*y(n-1)+6*y(1); + + + xp = A\bx; + yp = A\by; + + x(end+1) = x(1); + y(end+1) = y(1); + + xp(end+1) = xp(1); + yp(end+1) = yp(1); + + function v = g_fun(t) + t = mod(t,1); + i = mod(floor(t*n),n) + 1; + t = t * n -(i-1); + X = (2*x(i)-2*x(i+1)+xp(i)+xp(i+1))*t.^3 + (-3*x(i)+3*x(i+1)-2*xp(i)-xp(i+1))*t.^2 + (xp(i))*t + x(i); + Y = (2*y(i)-2*y(i+1)+yp(i)+yp(i+1))*t.^3 + (-3*y(i)+3*y(i+1)-2*yp(i)-yp(i+1))*t.^2 + (yp(i))*t + y(i); + v = [X;Y]; + end + + g = @g_fun; +end + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+parametrization/old/max_h.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,33 @@ +function [d_max, i1_max, j1_max, i2_max, j2_max] = max_h(X,Y) + ni = size(X,1); + nj = size(X,2); + d_max = 0; + + i1_max = 0; + j1_max = 0; + i2_max = 0; + j2_max = 0; + + D = {[0,-1],[1,0],[0,1],[-1,0]}; + + for i = 1:ni + for j = 1:nj + p1 = [X(i,j); Y(i,j)]; + for k = 1:length(D) + i2 = i+D{k}(1); + j2 = j+D{k}(2); + if i2 >= 1 && i2 <= ni && j2 >= 1 && j2 <= nj + p2 = [X(i2,j2); Y(i2,j2)]; + d = norm(p2-p1); + if d > d_max; + d_max = d; + i1_max = i; + j1_max = j; + i2_max = i2; + j2_max = j2; + end + end + end + end + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+parametrization/old/min_h.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,34 @@ +function [d_min, i1_min, j1_min, i2_min, j2_min] = min_h(X,Y) + ni = size(X,1); + nj = size(X,2); + d_min = norm([X(1,1);Y(1,1)] - [X(ni,nj);Y(ni,nj)]); + + i1_min = 0; + j1_min = 0; + i2_min = 0; + j2_min = 0; + + D = {[-1,-1],[0,-1],[1,-1],[1,0],[1,1],[0,1],[-1,1],[-1,0]}; + % D = {[0,-1],[1,0],[0,1],[-1,0]}; + + for i = 1:ni + for j = 1:nj + p1 = [X(i,j); Y(i,j)]; + for k = 1:length(D) + i2 = i+D{k}(1); + j2 = j+D{k}(2); + if i2 >= 1 && i2 <= ni && j2 >= 1 && j2 <= nj + p2 = [X(i2,j2); Y(i2,j2)]; + d = norm(p2-p1); + if d < d_min; + d_min = d; + i1_min = i; + j1_min = j; + i2_min = i2; + j2_min = j2; + end + end + end + end + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+parametrization/old/plot_shape.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,12 @@ +% Plot a shape using n points. Returns cell array of plot handles. +% hs = plot_shape(s,n) +function hs = plot_shape(s,n) + default_arg('n',100); + + hs = {}; + hold on + for i = 1:length(s) + hs{end+1} = parametrization.plot_curve(s{i},n); + end + hold off +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+parametrization/old/shape.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,4 @@ +% Creates a shape from a number of curves. A shape is a cell array of curves. +function s = shape(varargin); + s = varargin; +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+parametrization/old/shape_discretise.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,8 @@ +% Discretises a shape such that points on the curves are no further than h appart. +function p = shape_discretise(s,h) + p = []; + for i = 1:length(s) + [~,pt] = parametrization.curve_discretise(s{i},h); + p = [p, pt]; + end +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+parametrization/old/shape_linesegments.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,9 @@ +% Converts a shape into a cell array of linesegments shorter than h. +function l = shape_linesegments(s,h) + l = {}; + + for i = 1:length(s) + t = parametrization.curve_discretise(s{i},h); + l = [l, parametrization.curve_linesegments(s{i},t)]; + end +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+parametrization/old/triang_interp.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,132 @@ +classdef triang_interp + properties + g1, g2 ,g3 % Curves encirling the tirangle in the positive direction. + A,B,C % The corners of the triangle + Sa, Sb, Sc % Mappings from square with different sides collapsed + end + + methods + function o = triang_interp(g1,g2,g3) + o.g1 = g1; + o.g2 = g2; + o.g3 = g3; + o.A = g1(0); + o.B = g2(0); + o.C = g3(0); + o.Sa = parametrization.triang_interp.square_to_triangle_interp(g2,g3,g1); + o.Sb = parametrization.triang_interp.square_to_triangle_interp(g3,g1,g2); + o.Sc = parametrization.triang_interp.square_to_triangle_interp(g1,g2,g3); + end + + + function show(o,N) + % Show the mapped meridians of the triangle. + % Might be used for the barycentric coordinates. + ma = @(t)o.Sa(1/2,1-t); + mb = @(t)o.Sb(1/2,1-t); + mc = @(t)o.Sc(1/2,1-t); + + na = @(t)o.Sa(t,1/2); + + ka = @(t)(o.g1(1-t)+o.g2(t))/2; + + h = parametrization.plot_curve(ma); + h.Color = Color.blue; + h = parametrization.plot_curve(mb); + h.Color = Color.blue; + h = parametrization.plot_curve(mc); + h.Color = Color.blue; + + h = parametrization.plot_curve(na); + h.Color = Color.red; + + h = parametrization.plot_curve(ka); + h.Color = Color.red; + + [a(1),a(2)] = ma(1/3); + [b(1),b(2)] = mb(1/3); + [c(1),c(2)] = mc(1/3); + + d = ka(1-1/3); + + + parametrization.label_pt(a,b,c,d); + + + % t = linspace(0,1,N); + % for i = 1:N + % sa = @(s)o.Sa(s,t(i)); + % sb = @(s)o.Sb(s,t(i)); + % sc = @(s)o.Sc(s,t(i)); + + % h = parametrization.plot_curve(sa); + % h.Color = Color.blue; + % h = parametrization.plot_curve(sb); + % h.Color = Color.blue; + % h = parametrization.plot_curve(sc); + % h.Color = Color.blue; + % end + + h = parametrization.plot_curve(o.g1); + h.LineWidth = 2; + h.Color = Color.red; + + h = parametrization.plot_curve(o.g2); + h.LineWidth = 2; + h.Color = Color.red; + + h = parametrization.plot_curve(o.g3); + h.LineWidth = 2; + h.Color = Color.red; + + end + + + end + + methods(Static) + % Makes a mapping from the unit square to a triangle by collapsing + % one of the sides of the squares to a corner on the triangle + % The collapsed side is mapped to the corner oposite to g1. + % This is done such that for S(s,t), S(s,1) = g1(s) + function S = square_to_triangle_interp(g1,g2,g3) + corner = parametrization.line_segment(g3(0),g3(0)); + S = parametrization.transfinite_interp(corner,g3,f(g1),f(g2)) + + % Function to flip a curve + function h = f(g) + h = @(t)g(1-t); + end + end + end + +end + +% % Return a mapping from u.v to x,y of the domain encircled by g1 g2 g3 in the the positive direction. created be using transfinite interpolation. +% function S = triang_interp(g1,g2,g3) +% A = g1(0) +% B = g2(0) +% C = g3(0) + +% function [x,y] = S_fun(u,v) +% w = sqrt((u-1)^2+v^2)/sqrt(2); % Parameter for g3 +% v = v*(1-u-v)*g1(u) + u*(1-u-v)*g2(v) + u*v*g3(w) ... +% +(1-u)*(1-v)*A+u*(1-v)*B + (1-u)*v*C; +% x = v(1); +% y = v(2); +% end +% S = @S_fun; +% end + + + +% function subsref(obj,S) +% if ~all(isnumeric(S.subs{:})) +% error('Only supports calling object with number') +% end +% if numel(S.subs{:}) > 1 +% disp('You''ve called the object with more than one argument'); +% else +% disp(['You called the object with argument = ',num2str(S.subs{:})]); +% end +% end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+parametrization/old/triang_interp_pts.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,12 @@ +% Creates a transfinite interpolation from connecting the four points wiht straight lines. +function [S, g1, g2, g3] = triang_interp_pts(p1,p2,p3) + if size(p1) ~= [2 1] + error('p1 is strange!'); + end + + g1 = @(t)(p1 + t*(p2-p1)); + g2 = @(t)(p2 + t*(p3-p2)); + g3 = @(t)(p3 + t*(p1-p3)); + + S = parametrization.triang_interp(g1,g2,g3); +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+parametrization/old/triang_map.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,29 @@ +% Creates a grid [X,Y] from the mapping function S at points in vectors u,v +function [X, Y] = traing_map(S,u,v) + error('not done') + if nargin == 2 + v = u; + end + + if isscalar(u) + u = linspace(0,1,u); + end + + if isscalar(v) + v = linspace(0,1,v); + end + + nu = length(u); + nv = length(v); + + X = zeros(nu,nv); + Y = zeros(nu,nv); + + for i = 1:nu + for j = 1:nv + [x,y] = S(u(i),v(j)); + X(i,j) = x; + Y(i,j) = y; + end + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+parametrization/old/triang_plot_interp.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,114 @@ +% Plots a transfinite interpolation in x,y space using nu and nv curves along u and v axes. + + + + + + +% Plots a interp of a triangle where one the interpolation is from a square +% with one side collapsed to +function h = triang_plot_interp_kindaworking(S,n) + u = linspace(0,1,n); + v = linspace(0,1,n); + + m = 100; + m = 20; + + Xl_curves = cell(n,1); + Xr_curves = cell(n,1); + Y_curves = cell(n,1); + + + function u = wierdness(v,d,N) + if N == 0 + u = 0; + else + u = N*d./(1-v); + end + end + + + %Y curves + t = linspace(0,1,m); + for i = 1:n + x = []; y = []; + for j = 1:length(t) + [x(j),y(j)] = S(t(j),v(i)); + end + Y_curves{i} = [x', y']; + end + + + % Right and left X curves + t = linspace(0,1,m); + d = u(2); + for i = 1:n + xl = []; yl = []; + xr = []; yr = []; + N = i-1; + t = linspace(0,1-N*d,m); + for j = 1:length(t) + w = wierdness(t(j),d,N); + [xr(j),yr(j)] = S(w,t(j)); + [xl(j),yl(j)] = S(1-w,t(j)); + end + Xl_curves{i} = [xl', yl']; + Xr_curves{i} = [xr', yr']; + end + + for i = 1:n-1 + line(Xl_curves{i}(:,1),Xl_curves{i}(:,2)) + line(Xr_curves{i}(:,1),Xr_curves{i}(:,2)) + line(Y_curves{i}(:,1),Y_curves{i}(:,2)) + end +end + + + + +function h = triang_plot_interp_nonworking(S,n) + + u = linspace(0,1,n); + v = linspace(0,1,n); + + m = 100; + + X_curves = cell(n-1,1); + Y_curves = cell(n-1,1); + K_curves = cell(n-1,1); + + + t = linspace(0,1,m); + for i = 1:n-1 + x = []; y = []; + for j = find(t+u(i) <= 1) + [x(j),y(j)] = S(u(i),t(j)); + end + X_curves{i} = [x', y']; + end + + for i = 1:n-1 + x = []; y = []; + for j = find(t+v(i) <= 1) + [x(j),y(j)] = S(t(j),v(i)); + end + Y_curves{i} = [x', y']; + end + + for i = 2:n + x = []; y = []; + for j = find(t<u(i)) + [x(j),y(j)] = S(t(j), u(i)-t(j)); + end + K_curves{i-1} = [x', y']; + end + + for i = 1:n-1 + line(X_curves{i}(:,1),X_curves{i}(:,2)) + line(Y_curves{i}(:,1),Y_curves{i}(:,2)) + line(K_curves{i}(:,1),K_curves{i}(:,2)) + end + + h = -1; + % h = plot(X_curves{:},Y_curves{:},K_curves{:}); +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+parametrization/old/triang_show.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,23 @@ +% Show a grid as a matlab figure. +function triang_show(S,n) + + ih = ishold(); + + hold on + h_grid = parametrization.triang_plot_interp(S,n); + h_bord = parametrization.triang_plot_interp(S,2); + + set(h_grid,'Color',[0 0.4470 0.7410]); + set(h_bord,'Color',[0.8500 0.3250 0.0980]); + set(h_bord,'LineWidth',2); + + % axis auto + % axis equal + % axis square + + if ih + hold on + else + hold off + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+parametrization/place_label.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,12 @@ +% 'left' | 'center' | 'right' +% 'baseline' | 'top' | 'cap' | 'middle' | 'bottom' +function place_label(pt,str,horzAl,vertAl) + default_arg('horzAl','center'); + default_arg('vertAl', 'middle'); + + x = pt(1); + y = pt(2); + h = text(x,y,str); + h.HorizontalAlignment = horzAl; + h.VerticalAlignment = vertAl; +end \ No newline at end of file
--- a/+sbp/+implementations/d1_upwind_3.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+sbp/+implementations/d1_upwind_3.m Tue Sep 11 15:58:35 2018 +0200 @@ -1,12 +1,12 @@ function [H, HI, Dp, Dm, e_1, e_m] = d1_upwind_3(m,h) - + if(m<6) error('Operator requires at least 6 grid points'); end Hv = ones(m,1); Hv(1:3) = [3/8; 7/6; 23/24]; - Hv(m-2:m) = rot90(Hv(1:3),2); + Hv(m-2:m) = rot90(Hv(1:3), 2); Hv = Hv*h; H = spdiag(Hv,0); HI = spdiag(1./Hv,0);
--- a/+sbp/+implementations/d1_upwind_4.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+sbp/+implementations/d1_upwind_4.m Tue Sep 11 15:58:35 2018 +0200 @@ -23,7 +23,7 @@ ]; Qp(1:4,1:4)=Q_U; - Qp(m-3:m,m-3:m)=rot90(Q_U,2)'; %%% This is different from standard SBP + Qp(m-3:m,m-3:m)=rot90(Q_U, 2)'; %%% This is different from standard SBP Qm=-Qp';
--- a/+sbp/+implementations/d2_2.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+sbp/+implementations/d2_2.m Tue Sep 11 15:58:35 2018 +0200 @@ -1,5 +1,5 @@ function [H, HI, D1, D2, e_1, e_m, M, Q, S_1, S_m] = d2_2(m,h) - + BP = 1; if(m<2*BP) error(['Operator requires at least ' num2str(2*BP) ' grid points']); @@ -11,33 +11,40 @@ H=(speye(m,m));H(1,1)=0.5;H(m,m)=0.5; H=h*H; HI=inv(H); - + diags = -1:1; stencil = [-1/2 0 1/2]; D1 = stripeMatrix(stencil, diags, m); - - D1(1,1)=-1;D1(1,2)=1;D1(m,m-1)=-1;D1(m,m)=1; - D1(m,m-1)=-1;D1(m,m)=1; - D1=D1/h; + + D1(1,1) = -1; + D1(1,2) = 1; - Q=H*D1 + 1/2*(e_1*e_1') - 1/2*(e_m*e_m'); + D1(m,m-1) = -1; + D1(m,m) = 1; + + D1 = D1/h; + + Q = H*D1 + 1/2*(e_1*e_1') - 1/2*(e_m*e_m'); diags = -1:1; stencil = [1 -2 1]; D2 = stripeMatrix(stencil, diags, m); - - D2(1,1)=1;D2(1,2)=-2;D2(1,3)=1; - D2(m,m-2)=1;D2(m,m-1)=-2;D2(m,m)=1; - D2=D2/h^2; - S_U=[-3/2, 2, -1/2]/h; - S_1=sparse(1,m); - S_1(1:3)=S_U; - S_m=sparse(1,m); - S_m(m-2:m)=fliplr(-S_U); + D2(1,1) = 1; + D2(1,2) = -2; + D2(1,3) = 1; + D2(m,m-2) = 1; + D2(m,m-1) = -2; + D2(m,m) = 1; + D2 = D2/h^2; + S_U = [-3/2, 2, -1/2]/h; + S_1 = sparse(1,m); + S_1(1:3) = S_U; + S_m = sparse(1,m); + S_m(m-2:m) = fliplr(-S_U); - M=-H*D2-e_1*S_1+e_m*S_m; + M = -H*D2-e_1*S_1+e_m*S_m; S_1 = S_1'; S_m = S_m'; end \ No newline at end of file
--- a/+sbp/+implementations/d2_4.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+sbp/+implementations/d2_4.m Tue Sep 11 15:58:35 2018 +0200 @@ -1,5 +1,5 @@ function [H, HI, D1, D2, e_1, e_m, M, Q, S_1, S_m] = d2_4(m,h) - + BP = 4; if(m<2*BP) error(['Operator requires at least ' num2str(2*BP) ' grid points']); @@ -20,7 +20,12 @@ Q=spdiags([e -8*e 0*e 8*e -e], -2:2, m, m)/12; %Q=(-1/12*diag(ones(m-2,1),2)+8/12*diag(ones(m-1,1),1)-8/12*diag(ones(m-1,1),-1)+1/12*diag(ones(m-2,1),-2)); - Q_U = [0 0.59e2 / 0.96e2 -0.1e1 / 0.12e2 -0.1e1 / 0.32e2; -0.59e2 / 0.96e2 0 0.59e2 / 0.96e2 0; 0.1e1 / 0.12e2 -0.59e2 / 0.96e2 0 0.59e2 / 0.96e2; 0.1e1 / 0.32e2 0 -0.59e2 / 0.96e2 0;]; + Q_U = [ + 0 0.59e2/0.96e2 -0.1e1/0.12e2 -0.1e1/0.32e2; + -0.59e2/0.96e2 0 0.59e2/0.96e2 0; + 0.1e1/0.12e2 -0.59e2/0.96e2 0 0.59e2/0.96e2; + 0.1e1/0.32e2 0 -0.59e2/0.96e2 0; + ]; Q(1:4,1:4)=Q_U; Q(m-3:m,m-3:m)=rot90( -Q_U(1:4,1:4) ,2 ); @@ -30,13 +35,18 @@ %M=-(-1/12*diag(ones(m-2,1),2)+16/12*diag(ones(m-1,1),1)+16/12*diag(ones(m-1,1),-1)-1/12*diag(ones(m-2,1),-2)-30/12*diag(ones(m,1),0)); - M_U=[0.9e1 / 0.8e1 -0.59e2 / 0.48e2 0.1e1 / 0.12e2 0.1e1 / 0.48e2; -0.59e2 / 0.48e2 0.59e2 / 0.24e2 -0.59e2 / 0.48e2 0; 0.1e1 / 0.12e2 -0.59e2 / 0.48e2 0.55e2 / 0.24e2 -0.59e2 / 0.48e2; 0.1e1 / 0.48e2 0 -0.59e2 / 0.48e2 0.59e2 / 0.24e2;]; + M_U=[ + 0.9e1/0.8e1 -0.59e2/0.48e2 0.1e1/0.12e2 0.1e1/0.48e2; + -0.59e2/0.48e2 0.59e2/0.24e2 -0.59e2/0.48e2 0; + 0.1e1/0.12e2 -0.59e2/0.48e2 0.55e2/0.24e2 -0.59e2/0.48e2; + 0.1e1/0.48e2 0 -0.59e2/0.48e2 0.59e2/0.24e2; + ]; M(1:4,1:4)=M_U; M(m-3:m,m-3:m)=rot90( M_U ,2 ); M=M/h; - S_U=[-0.11e2 / 0.6e1 3 -0.3e1 / 0.2e1 0.1e1 / 0.3e1;]/h; + S_U=[-0.11e2/0.6e1 3 -0.3e1/0.2e1 0.1e1/0.3e1;]/h; S_1=sparse(sparse(1,m)); S_1(1:4)=S_U; S_m=sparse(sparse(1,m));
--- a/+sbp/+implementations/d2_variable_4.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+sbp/+implementations/d2_variable_4.m Tue Sep 11 15:58:35 2018 +0200 @@ -1,6 +1,6 @@ function [H, HI, D1, D2, e_l, e_r, d1_l, d1_r] = d2_variable_4(m,h) - BP = 4; + BP = 6; if(m<2*BP) error(['Operator requires at least ' num2str(2*BP) ' grid points']); end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/+implementations/d2_variable_periodic_2.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,50 @@ +function [H, HI, D1, D2, e_l, e_r, d1_l, d1_r] = d2_variable_periodic_2(m,h) + % m = number of unique grid points, i.e. h = L/m; + + if(m<3) + error(['Operator requires at least ' num2str(3) ' grid points']); + end + + % Norm + Hv = ones(m,1); + Hv = h*Hv; + H = spdiag(Hv, 0); + HI = spdiag(1./Hv, 0); + + + % Dummy boundary operators + e_l = sparse(m,1); + e_r = rot90(e_l, 2); + + d1_l = sparse(m,1); + d1_r = -rot90(d1_l, 2); + + % D1 operator + diags = -1:1; + stencil = [-1/2 0 1/2]; + D1 = stripeMatrixPeriodic(stencil, diags, m); + D1 = D1/h; + + scheme_width = 3; + scheme_radius = (scheme_width-1)/2; + + r = 1:m; + offset = scheme_width; + r = r + offset; + + function D2 = D2_fun(c) + c = [c(end-scheme_width+1:end); c; c(1:scheme_width) ]; + + Mm1 = -c(r-1)/2 - c(r)/2; + M0 = c(r-1)/2 + c(r) + c(r+1)/2; + Mp1 = -c(r)/2 - c(r+1)/2; + + vals = [Mm1,M0,Mp1]; + diags = -scheme_radius : scheme_radius; + M = spdiagsPeriodic(vals,diags); + + M=M/h; + D2=HI*(-M ); + end + D2 = @D2_fun; +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/+implementations/d2_variable_periodic_4.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,57 @@ +function [H, HI, D1, D2, e_l, e_r, d1_l, d1_r] = d2_variable_periodic_4(m,h) + % m = number of unique grid points, i.e. h = L/m; + + if(m<5) + error(['Operator requires at least ' num2str(5) ' grid points']); + end + + % Norm + Hv = ones(m,1); + Hv = h*Hv; + H = spdiag(Hv, 0); + HI = spdiag(1./Hv, 0); + + + % Dummy boundary operators + e_l = sparse(m,1); + e_r = rot90(e_l, 2); + + d1_l = sparse(m,1); + d1_r = -rot90(d1_l, 2); + + S = d1_l*d1_l' + d1_r*d1_r'; + + % D1 operator + stencil = [1/12 -2/3 0 2/3 -1/12]; + diags = -2:2; + Q = stripeMatrixPeriodic(stencil, diags, m); + D1 = HI*(Q - 1/2*e_l*e_l' + 1/2*e_r*e_r'); + + + scheme_width = 5; + scheme_radius = (scheme_width-1)/2; + + r = 1:m; + offset = scheme_width; + r = r + offset; + + function D2 = D2_fun(c) + c = [c(end-scheme_width+1:end); c; c(1:scheme_width) ]; + + % Note: these coefficients are for -M. + Mm2 = -1/8*c(r-2) + 1/6*c(r-1) - 1/8*c(r); + Mm1 = 1/6 *c(r-2) + 1/2*c(r-1) + 1/2*c(r) + 1/6*c(r+1); + M0 = -1/24*c(r-2)- 5/6*c(r-1) - 3/4*c(r) - 5/6*c(r+1) - 1/24*c(r+2); + Mp1 = 0 * c(r-2) + 1/6*c(r-1) + 1/2*c(r) + 1/2*c(r+1) + 1/6 *c(r+2); + Mp2 = 0 * c(r-2) + 0 * c(r-1) - 1/8*c(r) + 1/6*c(r+1) - 1/8 *c(r+2); + + vals = -[Mm2,Mm1,M0,Mp1,Mp2]; + diags = -scheme_radius : scheme_radius; + M = spdiagsPeriodic(vals,diags); + + M=M/h; + D2=HI*(-M ); + + end + D2 = @D2_fun; +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/+implementations/d2_variable_periodic_6.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,58 @@ +function [H, HI, D1, D2, e_l, e_r, d1_l, d1_r] = d2_variable_periodic_6(m,h) + % m = number of unique grid points, i.e. h = L/m; + + if(m<7) + error(['Operator requires at least ' num2str(7) ' grid points']); + end + + % Norm + Hv = ones(m,1); + Hv = h*Hv; + H = spdiag(Hv, 0); + HI = spdiag(1./Hv, 0); + + + % Dummy boundary operators + e_l = sparse(m,1); + e_r = rot90(e_l, 2); + + d1_l = sparse(m,1); + d1_r = -rot90(d1_l, 2); + + + % D1 operator + diags = -3:3; + stencil = [-1/60 9/60 -45/60 0 45/60 -9/60 1/60]; + D1 = stripeMatrixPeriodic(stencil, diags, m); + D1 = D1/h; + + % D2 operator + scheme_width = 7; + scheme_radius = (scheme_width-1)/2; + + r = 1:m; + offset = scheme_width; + r = r + offset; + + function D2 = D2_fun(c) + c = [c(end-scheme_width+1:end); c; c(1:scheme_width) ]; + + Mm3 = c(r-2)/0.40e2 + c(r-1)/0.40e2 - 0.11e2/0.360e3 * c(r-3) - 0.11e2/0.360e3 * c(r); + Mm2 = c(r-3)/0.20e2 - 0.3e1/0.10e2 * c(r-1) + c(r+1)/0.20e2 + 0.7e1/0.40e2 * c(r) + 0.7e1/0.40e2 * c(r-2); + Mm1 = -c(r-3)/0.40e2 - 0.3e1/0.10e2 * c(r-2) - 0.3e1/0.10e2 * c(r+1) - c(r+2)/0.40e2 - 0.17e2/0.40e2 * c(r) - 0.17e2/0.40e2 * c(r-1); + M0 = c(r-3)/0.180e3 + c(r-2)/0.8e1 + 0.19e2/0.20e2 * c(r-1) + 0.19e2/0.20e2 * c(r+1) + c(r+2)/0.8e1 + c(r+3)/0.180e3 + 0.101e3/0.180e3 * c(r); + Mp1 = -c(r-2)/0.40e2 - 0.3e1/0.10e2 * c(r-1) - 0.3e1/0.10e2 * c(r+2) - c(r+3)/0.40e2 - 0.17e2/0.40e2 * c(r) - 0.17e2/0.40e2 * c(r+1); + Mp2 = c(r-1)/0.20e2 - 0.3e1/0.10e2 * c(r+1) + c(r+3)/0.20e2 + 0.7e1/0.40e2 * c(r) + 0.7e1/0.40e2 * c(r+2); + Mp3 = c(r+1)/0.40e2 + c(r+2)/0.40e2 - 0.11e2/0.360e3 * c(r) - 0.11e2/0.360e3 * c(r+3); + + vals = [Mm3,Mm2,Mm1,M0,Mp1,Mp2,Mp3]; + diags = -scheme_radius : scheme_radius; + M = spdiagsPeriodic(vals,diags); + + M=M/h; + D2=HI*(-M ); + end + D2 = @D2_fun; + + +end
--- a/+sbp/+implementations/d4_compatible_6.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+sbp/+implementations/d4_compatible_6.m Tue Sep 11 15:58:35 2018 +0200 @@ -25,7 +25,7 @@ % Vi b?rjar med normen. Notera att alla SBP operatorer delar samma norm, % vilket ?r n?dv?ndigt f?r stabilitet - + BP = 8; if(m<2*BP) error(['Operator requires at least ' num2str(2*BP) ' grid points']);
--- a/+sbp/+implementations/d4_compatible_halfvariable_2.m Tue Sep 11 13:24:08 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,179 +0,0 @@ -% Returns D2 as a function handle -function [H, HI, D1, D2, D3, D4, e_1, e_m, M4, Q, S2_1,... - S2_m, S3_1, S3_m, S_1, S_m] = d4_compatible_halfvariable_2(m,h) - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - %%% 4:de ordn. SBP Finita differens %%% - %%% operatorer framtagna av Ken Mattsson %%% - %%% %%% - %%% 6 randpunkter, diagonal norm %%% - %%% %%% - %%% Datum: 2013-11-11 %%% - %%% %%% - %%% %%% - %%% H (Normen) %%% - %%% D1 (approx f?rsta derivatan) %%% - %%% D2 (approx andra derivatan) %%% - %%% D3 (approx tredje derivatan) %%% - %%% D2 (approx fj?rde derivatan) %%% - %%% %%% - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - % M?ste ange antal punkter (m) och stegl?ngd (h) - % Notera att dessa opetratorer ?r framtagna f?r att anv?ndas n?r - % vi har 3de och 4de derivator i v?r PDE - % I annat fall anv?nd de "traditionella" som har noggrannare - % randsplutningar f?r D1 och D2 - - % Vi b?rjar med normen. Notera att alla SBP operatorer delar samma norm, - % vilket ?r n?dv?ndigt f?r stabilitet - - BP = 4; - if(m<2*BP) - error(['Operator requires at least ' num2str(2*BP) ' grid points']); - end - - H=speye(m,m);H(1,1)=1/2;H(m,m)=1/2; - - - H=H*h; - HI=inv(H); - - - % First derivative SBP operator, 1st order accurate at first 6 boundary points - - q1=1/2; -% Q=q1*(diag(ones(m-1,1),1)-diag(ones(m-1,1),-1)); - stencil = [-q1,0,q1]; - d = (length(stencil)-1)/2; - diags = -d:d; - Q = stripeMatrix(stencil, diags, m); - - %Q=(-1/12*diag(ones(m-2,1),2)+8/12*diag(ones(m-1,1),1)-8/12*diag(ones(m-1,1),-1)+1/12*diag(ones(m-2,1),-2)); - - - e_1=sparse(m,1);e_1(1)=1; - e_m=sparse(m,1);e_m(m)=1; - - - D1=HI*(Q-1/2*(e_1*e_1')+1/2*(e_m*e_m')) ; - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - - - % Second derivative, 1st order accurate at first boundary points - - % below for constant coefficients - % m1=-1;m0=2; - % M=m1*(diag(ones(m-1,1),1)+diag(ones(m-1,1),-1))+m0*diag(ones(m,1),0);M(1,1)=1;M(m,m)=1; - % M=M/h; - %D2=HI*(-M-e_1*S_1+e_m*S_m); - - % Below for variable coefficients - % Require a vector c with the koeffients - - S_U=[-3/2 2 -1/2]/h; - S_1=sparse(1,m); - S_1(1:3)=S_U; - S_m=sparse(1,m); - S_m(m-2:m)=fliplr(-S_U); - - S_1 = S_1'; - S_m = S_m'; - - M=sparse(m,m); - e_1 = sparse(e_1); - e_m = sparse(e_m); - S_1 = sparse(S_1); - S_m = sparse(S_m); - - scheme_width = 3; - scheme_radius = (scheme_width-1)/2; - r = (1+scheme_radius):(m-scheme_radius); - - function D2 = D2_fun(c) - - Mm1 = -c(r-1)/2 - c(r)/2; - M0 = c(r-1)/2 + c(r) + c(r+1)/2; - Mp1 = -c(r)/2 - c(r+1)/2; - - M(r,:) = spdiags([Mm1 M0 Mp1],0:2*scheme_radius,length(r),m); - - - M(1:2,1:2)=[c(1)/2 + c(2)/2 -c(1)/2 - c(2)/2; -c(1)/2 - c(2)/2 c(1)/2 + c(2) + c(3)/2;]; - M(m-1:m,m-1:m)=[c(m-2)/2 + c(m-1) + c(m)/2 -c(m-1)/2 - c(m)/2; -c(m-1)/2 - c(m)/2 c(m-1)/2 + c(m)/2;]; - M=M/h; - - D2=HI*(-M-c(1)*e_1*S_1'+c(m)*e_m*S_m'); - end - D2 = @D2_fun; - - - - - - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - - - % Third derivative, 1st order accurate at first 6 boundary points - - q2=1/2;q1=-1; -% Q3=q2*(diag(ones(m-2,1),2)-diag(ones(m-2,1),-2))+q1*(diag(ones(m-1,1),1)-diag(ones(m-1,1),-1)); - stencil = [-q2,-q1,0,q1,q2]; - d = (length(stencil)-1)/2; - diags = -d:d; - Q3 = stripeMatrix(stencil, diags, m); - - %QQ3=(-1/8*diag(ones(m-3,1),3) + 1*diag(ones(m-2,1),2) - 13/8*diag(ones(m-1,1),1) +13/8*diag(ones(m-1,1),-1) -1*diag(ones(m-2,1),-2) + 1/8*diag(ones(m-3,1),-3)); - - - Q3_U = [0 -0.13e2 / 0.16e2 0.7e1 / 0.8e1 -0.1e1 / 0.16e2; 0.13e2 / 0.16e2 0 -0.23e2 / 0.16e2 0.5e1 / 0.8e1; -0.7e1 / 0.8e1 0.23e2 / 0.16e2 0 -0.17e2 / 0.16e2; 0.1e1 / 0.16e2 -0.5e1 / 0.8e1 0.17e2 / 0.16e2 0;]; - Q3(1:4,1:4)=Q3_U; - Q3(m-3:m,m-3:m)=rot90( -Q3_U ,2 ); - Q3=Q3/h^2; - - - - S2_U=[1 -2 1;]/h^2; - S2_1=sparse(1,m); - S2_1(1:3)=S2_U; - S2_m=sparse(1,m); - S2_m(m-2:m)=fliplr(S2_U); - S2_1 = S2_1'; - S2_m = S2_m'; - - - - D3=HI*(Q3 - e_1*S2_1' + e_m*S2_m' +1/2*(S_1*S_1') -1/2*(S_m*S_m') ) ; - - % Fourth derivative, 0th order accurate at first 6 boundary points (still - % yield 4th order convergence if stable: for example u_tt=-u_xxxx - - m2=1;m1=-4;m0=6; -% M4=m2*(diag(ones(m-2,1),2)+diag(ones(m-2,1),-2))+m1*(diag(ones(m-1,1),1)+diag(ones(m-1,1),-1))+m0*diag(ones(m,1),0); - stencil = [m2,m1,m0,m1,m2]; - d = (length(stencil)-1)/2; - diags = -d:d; - M4 = stripeMatrix(stencil, diags, m); - - %M4=(-1/6*(diag(ones(m-3,1),3)+diag(ones(m-3,1),-3) ) + 2*(diag(ones(m-2,1),2)+diag(ones(m-2,1),-2)) -13/2*(diag(ones(m-1,1),1)+diag(ones(m-1,1),-1)) + 28/3*diag(ones(m,1),0)); - - M4_U=[0.13e2 / 0.10e2 -0.12e2 / 0.5e1 0.9e1 / 0.10e2 0.1e1 / 0.5e1; -0.12e2 / 0.5e1 0.26e2 / 0.5e1 -0.16e2 / 0.5e1 0.2e1 / 0.5e1; 0.9e1 / 0.10e2 -0.16e2 / 0.5e1 0.47e2 / 0.10e2 -0.17e2 / 0.5e1; 0.1e1 / 0.5e1 0.2e1 / 0.5e1 -0.17e2 / 0.5e1 0.29e2 / 0.5e1;]; - - - M4(1:4,1:4)=M4_U; - - M4(m-3:m,m-3:m)=rot90( M4_U ,2 ); - M4=M4/h^3; - - S3_U=[-1 3 -3 1;]/h^3; - S3_1=sparse(1,m); - S3_1(1:4)=S3_U; - S3_m=sparse(1,m); - S3_m(m-3:m)=fliplr(-S3_U); - S3_1 = S3_1'; - S3_m = S3_m'; - - D4=HI*(M4-e_1*S3_1'+e_m*S3_m' + S_1*S2_1'-S_m*S2_m'); -end
--- a/+sbp/+implementations/d4_compatible_halfvariable_4.m Tue Sep 11 13:24:08 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,167 +0,0 @@ -function [H, HI, D2, D4, e_1, e_m, M4, S2_1, S2_m, S3_1,... - S3_m, S_1, S_m] = d4_compatible_halfvariable_4(m,h) - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - %%% 4:de ordn. SBP Finita differens %%% - %%% %%% - %%% H (Normen) %%% - %%% D1=H^(-1)Q (approx f?rsta derivatan) %%% - %%% D2 (approx andra derivatan) %%% - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - - %m=20; %problemstorlek - %h=1/(m-1); - %h=1; - - BP = 6; - if(m<2*BP) - error(['Operator requires at least ' num2str(2*BP) ' grid points']); - end - -% c=ones(m,1); - - - H=speye(m,m); - H(1:4,1:4)=diag([17/48 59/48 43/48 49/48]); - H(m-3:m,m-3:m)=rot90(diag([17/48 59/48 43/48 49/48]),2); - H=H*h; - HI=inv(H); - HI = sparse(HI); - - - -% Q=(-1/12*diag(ones(m-2,1),2)+8/12*diag(ones(m-1,1),1)-8/12*diag(ones(m-1,1),-1)+1/12*diag(ones(m-2,1),-2)); - e=ones(m,1); -% Q=spdiags([e -8*e 0*e 8*e -e], -2:2, m, m)/12; -% Q_U = [0 0.59e2 / 0.96e2 -0.1e1 / 0.12e2 -0.1e1 / 0.32e2; -0.59e2 / 0.96e2 0 0.59e2 / 0.96e2 0; 0.1e1 / 0.12e2 -0.59e2 / 0.96e2 0 0.59e2 / 0.96e2; 0.1e1 / 0.32e2 0 -0.59e2 / 0.96e2 0;]; -% Q(1:4,1:4)=Q_U; -% Q(m-3:m,m-3:m)=rot90( -Q_U(1:4,1:4) ,2 ); - - e_1=sparse(m,1);e_1(1)=1; - e_m=sparse(m,1);e_m(m)=1; - -% D1=HI*(Q-1/2*(e_1*e_1')+1/2*(e_m*e_m')) ; - - M_U=[0.9e1 / 0.8e1 -0.59e2 / 0.48e2 0.1e1 / 0.12e2 0.1e1 / 0.48e2; -0.59e2 / 0.48e2 0.59e2 / 0.24e2 -0.59e2 / 0.48e2 0; 0.1e1 / 0.12e2 -0.59e2 / 0.48e2 0.55e2 / 0.24e2 -0.59e2 / 0.48e2; 0.1e1 / 0.48e2 0 -0.59e2 / 0.48e2 0.59e2 / 0.24e2;]; -% M=-(-1/12*diag(ones(m-2,1),2)+16/12*diag(ones(m-1,1),1)+16/12*diag(ones(m-1,1),-1)-1/12*diag(ones(m-2,1),-2)-30/12*diag(ones(m,1),0)); - M=-spdiags([-e 16*e -30*e 16*e -e], -2:2, m, m)/12; - - M(1:4,1:4)=M_U; - - M(m-3:m,m-3:m)=rot90( M_U ,2 ); - M=M/h; - - S_U=[-0.11e2 / 0.6e1 3 -0.3e1 / 0.2e1 0.1e1 / 0.3e1;]/h; - S_1=sparse(1,m); - S_1(1:4)=S_U; - S_m=sparse(1,m); - S_m(m-3:m)=fliplr(-S_U); - S_1 = S_1'; - S_m = S_m'; - - - M=sparse(m,m); - e_1 = sparse(e_1); - e_m = sparse(e_m); - S_1 = sparse(S_1); - S_m = sparse(S_m); - - - scheme_width = 5; - scheme_radius = (scheme_width-1)/2; - r = (1+scheme_radius):(m-scheme_radius); - - function D2 = D2_fun(c) - - % ALTERNATIVES %%%%%%%%%%%%% - % for i=4:m-3 - % M(i,i-2:i+2)=[-c(i-1) / 0.6e1 + c(i-2) / 0.8e1 + c(i) / 0.8e1 -c(i-2) / 0.6e1 - c(i+1) / 0.6e1 - c(i-1) / 0.2e1 - c(i) / 0.2e1 c(i-2) / 0.24e2 + 0.5e1 / 0.6e1 * c(i-1) + 0.5e1 / 0.6e1 * c(i+1) + c(i+2) / 0.24e2 + 0.3e1 / 0.4e1 * c(i) -c(i-1) / 0.6e1 - c(i+2) / 0.6e1 - c(i) / 0.2e1 - c(i+1) / 0.2e1 -c(i+1) / 0.6e1 + c(i) / 0.8e1 + c(i+2) / 0.8e1;]; - % end - %%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % for i=4:m-3 - % M(i,i-2:i+2)= [ - % c(i-2) / 0.8e1 - c(i-1) / 0.6e1 + c(i) / 0.8e1 , - % -c(i-2) / 0.6e1 - c(i-1) / 0.2e1 - c(i) / 0.2e1 - c(i+1) / 0.6e1 , - % c(i-2) / 2.4e1 + c(i-1) / 1.2e0 + c(i) * 0.3/0.4 + c(i+1) / 1.2e0 + c(i+2) / 2.4e1 , - % -c(i-1) / 0.6e1 - c(i) / 0.2e1 - c(i+1) / 0.2e1 - c(i+2) / 0.6e1 , - % c(i) / 0.8e1 - c(i+1) / 0.6e1 + c(i+2) / 0.8e1 , - % ]; - % end - %%%%%%%%%%%%%%%%%%%%%%%%%%%%% - Mm2 = c(r-2) / 0.8e1 - c(r-1) / 0.6e1 + c(r) / 0.8e1 ; - Mm1 = -c(r-2) / 0.6e1 - c(r-1) / 0.2e1 - c(r) / 0.2e1 - c(r+1) / 0.6e1 ; - M0 = c(r-2) / 2.4e1 + c(r-1) / 1.2e0 + c(r) * 0.3/0.4 + c(r+1) / 1.2e0 + c(r+2) / 2.4e1; - Mp1 = -c(r-1) / 0.6e1 - c(r) / 0.2e1 - c(r+1) / 0.2e1 - c(r+2) / 0.6e1; - Mp2 = c(r) / 0.8e1 - c(r+1) / 0.6e1 + c(r+2) / 0.8e1; - % printSize(Mm2); - % scheme_radius - % m - M(r,:) = spdiags([Mm2 Mm1 M0 Mp1 Mp2],0:2*scheme_radius,length(r),m); - % M(r,:) = spdiags([Mm2 Mm1 M0 Mp1 Mp2],(-2:2)+scheme_radius,M(r,:)); % This is slower - %%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % %% Somthing is wrong here!! - % Mm2 = c(r-2) / 0.8e1 - c(r-1) / 0.6e1 + c(r) / 0.8e1 ; - % Mm1 = -c(r-2) / 0.6e1 - c(r-1) / 0.2e1 - c(r) / 0.2e1 - c(r+1) / 0.6e1 ; - % M0 = c(r-2) / 2.4e1 + c(r-1) / 1.2e0 + c(r) * 0.3/0.4 + c(r+1) / 1.2e0 + c(r+2) / 2.4e1; - % Mp1 = -c(r-1) / 0.6e1 - c(r) / 0.2e1 - c(r+1) / 0.2e1 - c(r+2) / 0.6e1; - % Mp2 = c(r) / 0.8e1 - c(r+1) / 0.6e1 + c(r+2) / 0.8e1; - % % printSize(M_diag_ind); - % % Mdiags = [Mm2 Mm1 M0 Mp1 Mp2]; - % % printSize(Mdiags); - % M(M_diag_ind) = [Mm2 Mm1 M0 Mp1 Mp2]; % This is slightly faster - %%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % Kan man skriva det som en multiplikation av en 3-dim matris? - %%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - - - - M(1:6,1:6)=[0.12e2 / 0.17e2 * c(1) + 0.59e2 / 0.192e3 * c(2) + 0.27010400129e11 / 0.345067064608e12 * c(3) + 0.69462376031e11 / 0.2070402387648e13 * c(4) -0.59e2 / 0.68e2 * c(1) - 0.6025413881e10 / 0.21126554976e11 * c(3) - 0.537416663e9 / 0.7042184992e10 * c(4) 0.2e1 / 0.17e2 * c(1) - 0.59e2 / 0.192e3 * c(2) + 0.213318005e9 / 0.16049630912e11 * c(4) + 0.2083938599e10 / 0.8024815456e10 * c(3) 0.3e1 / 0.68e2 * c(1) - 0.1244724001e10 / 0.21126554976e11 * c(3) + 0.752806667e9 / 0.21126554976e11 * c(4) 0.49579087e8 / 0.10149031312e11 * c(3) - 0.49579087e8 / 0.10149031312e11 * c(4) -c(4) / 0.784e3 + c(3) / 0.784e3; -0.59e2 / 0.68e2 * c(1) - 0.6025413881e10 / 0.21126554976e11 * c(3) - 0.537416663e9 / 0.7042184992e10 * c(4) 0.3481e4 / 0.3264e4 * c(1) + 0.9258282831623875e16 / 0.7669235228057664e16 * c(3) + 0.236024329996203e15 / 0.1278205871342944e16 * c(4) -0.59e2 / 0.408e3 * c(1) - 0.29294615794607e14 / 0.29725717938208e14 * c(3) - 0.2944673881023e13 / 0.29725717938208e14 * c(4) -0.59e2 / 0.1088e4 * c(1) + 0.260297319232891e15 / 0.2556411742685888e16 * c(3) - 0.60834186813841e14 / 0.1278205871342944e16 * c(4) -0.1328188692663e13 / 0.37594290333616e14 * c(3) + 0.1328188692663e13 / 0.37594290333616e14 * c(4) -0.8673e4 / 0.2904112e7 * c(3) + 0.8673e4 / 0.2904112e7 * c(4); 0.2e1 / 0.17e2 * c(1) - 0.59e2 / 0.192e3 * c(2) + 0.213318005e9 / 0.16049630912e11 * c(4) + 0.2083938599e10 / 0.8024815456e10 * c(3) -0.59e2 / 0.408e3 * c(1) - 0.29294615794607e14 / 0.29725717938208e14 * c(3) - 0.2944673881023e13 / 0.29725717938208e14 * c(4) c(1) / 0.51e2 + 0.59e2 / 0.192e3 * c(2) + 0.13777050223300597e17 / 0.26218083221499456e17 * c(4) + 0.564461e6 / 0.13384296e8 * c(5) + 0.378288882302546512209e21 / 0.270764341349677687456e21 * c(3) c(1) / 0.136e3 - 0.125059e6 / 0.743572e6 * c(5) - 0.4836340090442187227e19 / 0.5525802884687299744e19 * c(3) - 0.17220493277981e14 / 0.89177153814624e14 * c(4) -0.10532412077335e14 / 0.42840005263888e14 * c(4) + 0.1613976761032884305e19 / 0.7963657098519931984e19 * c(3) + 0.564461e6 / 0.4461432e7 * c(5) -0.960119e6 / 0.1280713392e10 * c(4) - 0.3391e4 / 0.6692148e7 * c(5) + 0.33235054191e11 / 0.26452850508784e14 * c(3); 0.3e1 / 0.68e2 * c(1) - 0.1244724001e10 / 0.21126554976e11 * c(3) + 0.752806667e9 / 0.21126554976e11 * c(4) -0.59e2 / 0.1088e4 * c(1) + 0.260297319232891e15 / 0.2556411742685888e16 * c(3) - 0.60834186813841e14 / 0.1278205871342944e16 * c(4) c(1) / 0.136e3 - 0.125059e6 / 0.743572e6 * c(5) - 0.4836340090442187227e19 / 0.5525802884687299744e19 * c(3) - 0.17220493277981e14 / 0.89177153814624e14 * c(4) 0.3e1 / 0.1088e4 * c(1) + 0.507284006600757858213e21 / 0.475219048083107777984e21 * c(3) + 0.1869103e7 / 0.2230716e7 * c(5) + c(6) / 0.24e2 + 0.1950062198436997e16 / 0.3834617614028832e16 * c(4) -0.4959271814984644613e19 / 0.20965546238960637264e20 * c(3) - c(6) / 0.6e1 - 0.15998714909649e14 / 0.37594290333616e14 * c(4) - 0.375177e6 / 0.743572e6 * c(5) -0.368395e6 / 0.2230716e7 * c(5) + 0.752806667e9 / 0.539854092016e12 * c(3) + 0.1063649e7 / 0.8712336e7 * c(4) + c(6) / 0.8e1; 0.49579087e8 / 0.10149031312e11 * c(3) - 0.49579087e8 / 0.10149031312e11 * c(4) -0.1328188692663e13 / 0.37594290333616e14 * c(3) + 0.1328188692663e13 / 0.37594290333616e14 * c(4) -0.10532412077335e14 / 0.42840005263888e14 * c(4) + 0.1613976761032884305e19 / 0.7963657098519931984e19 * c(3) + 0.564461e6 / 0.4461432e7 * c(5) -0.4959271814984644613e19 / 0.20965546238960637264e20 * c(3) - c(6) / 0.6e1 - 0.15998714909649e14 / 0.37594290333616e14 * c(4) - 0.375177e6 / 0.743572e6 * c(5) 0.8386761355510099813e19 / 0.128413970713633903242e21 * c(3) + 0.2224717261773437e16 / 0.2763180339520776e16 * c(4) + 0.5e1 / 0.6e1 * c(6) + c(7) / 0.24e2 + 0.280535e6 / 0.371786e6 * c(5) -0.35039615e8 / 0.213452232e9 * c(4) - c(7) / 0.6e1 - 0.13091810925e11 / 0.13226425254392e14 * c(3) - 0.1118749e7 / 0.2230716e7 * c(5) - c(6) / 0.2e1; -c(4) / 0.784e3 + c(3) / 0.784e3 -0.8673e4 / 0.2904112e7 * c(3) + 0.8673e4 / 0.2904112e7 * c(4) -0.960119e6 / 0.1280713392e10 * c(4) - 0.3391e4 / 0.6692148e7 * c(5) + 0.33235054191e11 / 0.26452850508784e14 * c(3) -0.368395e6 / 0.2230716e7 * c(5) + 0.752806667e9 / 0.539854092016e12 * c(3) + 0.1063649e7 / 0.8712336e7 * c(4) + c(6) / 0.8e1 -0.35039615e8 / 0.213452232e9 * c(4) - c(7) / 0.6e1 - 0.13091810925e11 / 0.13226425254392e14 * c(3) - 0.1118749e7 / 0.2230716e7 * c(5) - c(6) / 0.2e1 0.3290636e7 / 0.80044587e8 * c(4) + 0.5580181e7 / 0.6692148e7 * c(5) + 0.5e1 / 0.6e1 * c(7) + c(8) / 0.24e2 + 0.660204843e9 / 0.13226425254392e14 * c(3) + 0.3e1 / 0.4e1 * c(6);]; - - M(m-5:m,m-5:m)=[c(m-7) / 0.24e2 + 0.5e1 / 0.6e1 * c(m-6) + 0.5580181e7 / 0.6692148e7 * c(m-4) + 0.4887707739997e13 / 0.119037827289528e15 * c(m-3) + 0.3e1 / 0.4e1 * c(m-5) + 0.660204843e9 / 0.13226425254392e14 * c(m-2) + 0.660204843e9 / 0.13226425254392e14 * c(m-1) -c(m-6) / 0.6e1 - 0.1618585929605e13 / 0.9919818940794e13 * c(m-3) - c(m-5) / 0.2e1 - 0.1118749e7 / 0.2230716e7 * c(m-4) - 0.13091810925e11 / 0.13226425254392e14 * c(m-2) - 0.13091810925e11 / 0.13226425254392e14 * c(m-1) -0.368395e6 / 0.2230716e7 * c(m-4) + c(m-5) / 0.8e1 + 0.48866620889e11 / 0.404890569012e12 * c(m-3) + 0.752806667e9 / 0.539854092016e12 * c(m-2) + 0.752806667e9 / 0.539854092016e12 * c(m-1) -0.3391e4 / 0.6692148e7 * c(m-4) - 0.238797444493e12 / 0.119037827289528e15 * c(m-3) + 0.33235054191e11 / 0.26452850508784e14 * c(m-2) + 0.33235054191e11 / 0.26452850508784e14 * c(m-1) -0.8673e4 / 0.2904112e7 * c(m-2) - 0.8673e4 / 0.2904112e7 * c(m-1) + 0.8673e4 / 0.1452056e7 * c(m-3) -c(m-3) / 0.392e3 + c(m-2) / 0.784e3 + c(m-1) / 0.784e3; -c(m-6) / 0.6e1 - 0.1618585929605e13 / 0.9919818940794e13 * c(m-3) - c(m-5) / 0.2e1 - 0.1118749e7 / 0.2230716e7 * c(m-4) - 0.13091810925e11 / 0.13226425254392e14 * c(m-2) - 0.13091810925e11 / 0.13226425254392e14 * c(m-1) c(m-6) / 0.24e2 + 0.5e1 / 0.6e1 * c(m-5) + 0.3896014498639e13 / 0.4959909470397e13 * c(m-3) + 0.8386761355510099813e19 / 0.128413970713633903242e21 * c(m-2) + 0.280535e6 / 0.371786e6 * c(m-4) + 0.3360696339136261875e19 / 0.171218627618178537656e21 * c(m-1) -c(m-5) / 0.6e1 - 0.4959271814984644613e19 / 0.20965546238960637264e20 * c(m-2) - 0.375177e6 / 0.743572e6 * c(m-4) - 0.13425842714e11 / 0.33740880751e11 * c(m-3) - 0.193247108773400725e18 / 0.6988515412986879088e19 * c(m-1) -0.365281640980e12 / 0.1653303156799e13 * c(m-3) + 0.564461e6 / 0.4461432e7 * c(m-4) + 0.1613976761032884305e19 / 0.7963657098519931984e19 * c(m-2) - 0.198407225513315475e18 / 0.7963657098519931984e19 * c(m-1) -0.1328188692663e13 / 0.37594290333616e14 * c(m-2) + 0.2226377963775e13 / 0.37594290333616e14 * c(m-1) - 0.8673e4 / 0.363014e6 * c(m-3) c(m-3) / 0.49e2 + 0.49579087e8 / 0.10149031312e11 * c(m-2) - 0.256702175e9 / 0.10149031312e11 * c(m-1); -0.368395e6 / 0.2230716e7 * c(m-4) + c(m-5) / 0.8e1 + 0.48866620889e11 / 0.404890569012e12 * c(m-3) + 0.752806667e9 / 0.539854092016e12 * c(m-2) + 0.752806667e9 / 0.539854092016e12 * c(m-1) -c(m-5) / 0.6e1 - 0.4959271814984644613e19 / 0.20965546238960637264e20 * c(m-2) - 0.375177e6 / 0.743572e6 * c(m-4) - 0.13425842714e11 / 0.33740880751e11 * c(m-3) - 0.193247108773400725e18 / 0.6988515412986879088e19 * c(m-1) c(m-5) / 0.24e2 + 0.1869103e7 / 0.2230716e7 * c(m-4) + 0.507284006600757858213e21 / 0.475219048083107777984e21 * c(m-2) + 0.3e1 / 0.1088e4 * c(m) + 0.31688435395e11 / 0.67481761502e11 * c(m-3) + 0.27769176016102795561e20 / 0.712828572124661666976e21 * c(m-1) -0.125059e6 / 0.743572e6 * c(m-4) + c(m) / 0.136e3 - 0.23099342648e11 / 0.101222642253e12 * c(m-3) - 0.4836340090442187227e19 / 0.5525802884687299744e19 * c(m-2) + 0.193950157930938693e18 / 0.5525802884687299744e19 * c(m-1) 0.260297319232891e15 / 0.2556411742685888e16 * c(m-2) - 0.59e2 / 0.1088e4 * c(m) - 0.106641839640553e15 / 0.1278205871342944e16 * c(m-1) + 0.26019e5 / 0.726028e6 * c(m-3) -0.1244724001e10 / 0.21126554976e11 * c(m-2) + 0.3e1 / 0.68e2 * c(m) + 0.752806667e9 / 0.21126554976e11 * c(m-1); -0.3391e4 / 0.6692148e7 * c(m-4) - 0.238797444493e12 / 0.119037827289528e15 * c(m-3) + 0.33235054191e11 / 0.26452850508784e14 * c(m-2) + 0.33235054191e11 / 0.26452850508784e14 * c(m-1) -0.365281640980e12 / 0.1653303156799e13 * c(m-3) + 0.564461e6 / 0.4461432e7 * c(m-4) + 0.1613976761032884305e19 / 0.7963657098519931984e19 * c(m-2) - 0.198407225513315475e18 / 0.7963657098519931984e19 * c(m-1) -0.125059e6 / 0.743572e6 * c(m-4) + c(m) / 0.136e3 - 0.23099342648e11 / 0.101222642253e12 * c(m-3) - 0.4836340090442187227e19 / 0.5525802884687299744e19 * c(m-2) + 0.193950157930938693e18 / 0.5525802884687299744e19 * c(m-1) 0.564461e6 / 0.13384296e8 * c(m-4) + 0.470299699916357e15 / 0.952302618316224e15 * c(m-3) + 0.550597048646198778781e21 / 0.1624586048098066124736e22 * c(m-1) + c(m) / 0.51e2 + 0.378288882302546512209e21 / 0.270764341349677687456e21 * c(m-2) -0.59e2 / 0.408e3 * c(m) - 0.29294615794607e14 / 0.29725717938208e14 * c(m-2) - 0.2234477713167e13 / 0.29725717938208e14 * c(m-1) - 0.8673e4 / 0.363014e6 * c(m-3) -0.59e2 / 0.3136e4 * c(m-3) - 0.13249937023e11 / 0.48148892736e11 * c(m-1) + 0.2e1 / 0.17e2 * c(m) + 0.2083938599e10 / 0.8024815456e10 * c(m-2); -0.8673e4 / 0.2904112e7 * c(m-2) - 0.8673e4 / 0.2904112e7 * c(m-1) + 0.8673e4 / 0.1452056e7 * c(m-3) -0.1328188692663e13 / 0.37594290333616e14 * c(m-2) + 0.2226377963775e13 / 0.37594290333616e14 * c(m-1) - 0.8673e4 / 0.363014e6 * c(m-3) 0.260297319232891e15 / 0.2556411742685888e16 * c(m-2) - 0.59e2 / 0.1088e4 * c(m) - 0.106641839640553e15 / 0.1278205871342944e16 * c(m-1) + 0.26019e5 / 0.726028e6 * c(m-3) -0.59e2 / 0.408e3 * c(m) - 0.29294615794607e14 / 0.29725717938208e14 * c(m-2) - 0.2234477713167e13 / 0.29725717938208e14 * c(m-1) - 0.8673e4 / 0.363014e6 * c(m-3) 0.9258282831623875e16 / 0.7669235228057664e16 * c(m-2) + 0.3481e4 / 0.3264e4 * c(m) + 0.228389721191751e15 / 0.1278205871342944e16 * c(m-1) + 0.8673e4 / 0.1452056e7 * c(m-3) -0.6025413881e10 / 0.21126554976e11 * c(m-2) - 0.59e2 / 0.68e2 * c(m) - 0.537416663e9 / 0.7042184992e10 * c(m-1); -c(m-3) / 0.392e3 + c(m-2) / 0.784e3 + c(m-1) / 0.784e3 c(m-3) / 0.49e2 + 0.49579087e8 / 0.10149031312e11 * c(m-2) - 0.256702175e9 / 0.10149031312e11 * c(m-1) -0.1244724001e10 / 0.21126554976e11 * c(m-2) + 0.3e1 / 0.68e2 * c(m) + 0.752806667e9 / 0.21126554976e11 * c(m-1) -0.59e2 / 0.3136e4 * c(m-3) - 0.13249937023e11 / 0.48148892736e11 * c(m-1) + 0.2e1 / 0.17e2 * c(m) + 0.2083938599e10 / 0.8024815456e10 * c(m-2) -0.6025413881e10 / 0.21126554976e11 * c(m-2) - 0.59e2 / 0.68e2 * c(m) - 0.537416663e9 / 0.7042184992e10 * c(m-1) 0.3e1 / 0.3136e4 * c(m-3) + 0.27010400129e11 / 0.345067064608e12 * c(m-2) + 0.234566387291e12 / 0.690134129216e12 * c(m-1) + 0.12e2 / 0.17e2 * c(m);]; - - M=M/h; - D2=HI*(-M-c(1)*e_1*S_1'+c(m)*e_m*S_m'); - end - D2 = @D2_fun; - - - S2_U=[2 -5 4 -1;]/h^2; - S2_1=sparse(1,m); - S2_1(1:4)=S2_U; - S2_m=sparse(1,m); - S2_m(m-3:m)=fliplr(S2_U); - S2_1 = S2_1'; - S2_m = S2_m'; - - m3=-1/6;m2=2;m1=-13/2;m0=28/3; -% M4=m3*(diag(ones(m-3,1),3)+diag(ones(m-3,1),-3))+m2*(diag(ones(m-2,1),2)+diag(ones(m-2,1),-2))+m1*(diag(ones(m-1,1),1)+diag(ones(m-1,1),-1))+m0*diag(ones(m,1),0); - stencil = [m3,m2,m1,m0,m1,m2,m3]; - d = (length(stencil)-1)/2; - diags = -d:d; - M4 = stripeMatrix(stencil, diags, m); - - %M4=(-1/6*(diag(ones(m-3,1),3)+diag(ones(m-3,1),-3) ) + 2*(diag(ones(m-2,1),2)+diag(ones(m-2,1),-2)) -13/2*(diag(ones(m-1,1),1)+diag(ones(m-1,1),-1)) + 28/3*diag(ones(m,1),0)); - - M4_U=[0.5762947e7 / 0.2316384e7 -0.6374287e7 / 0.1158192e7 0.573947e6 / 0.165456e6 -0.124637e6 / 0.289548e6 0.67979e5 / 0.2316384e7 -0.60257e5 / 0.1158192e7; -0.6374287e7 / 0.1158192e7 0.30392389e8 / 0.2316384e7 -0.2735053e7 / 0.289548e6 0.273109e6 / 0.165456e6 0.83767e5 / 0.1158192e7 0.245549e6 / 0.2316384e7; 0.573947e6 / 0.165456e6 -0.2735053e7 / 0.289548e6 0.5266855e7 / 0.579096e6 -0.1099715e7 / 0.289548e6 0.869293e6 / 0.1158192e7 -0.10195e5 / 0.144774e6; -0.124637e6 / 0.289548e6 0.273109e6 / 0.165456e6 -0.1099715e7 / 0.289548e6 0.3259225e7 / 0.579096e6 -0.324229e6 / 0.72387e5 0.1847891e7 / 0.1158192e7; 0.67979e5 / 0.2316384e7 0.83767e5 / 0.1158192e7 0.869293e6 / 0.1158192e7 -0.324229e6 / 0.72387e5 0.2626501e7 / 0.330912e6 -0.7115491e7 / 0.1158192e7; -0.60257e5 / 0.1158192e7 0.245549e6 / 0.2316384e7 -0.10195e5 / 0.144774e6 0.1847891e7 / 0.1158192e7 -0.7115491e7 / 0.1158192e7 0.21383077e8 / 0.2316384e7;]; - - M4(1:6,1:6)=M4_U; - - M4(m-5:m,m-5:m)=rot90( M4_U ,2 ); - M4=M4/h^3; - - S3_U=[-1 3 -3 1;]/h^3; - S3_1=sparse(1,m); - S3_1(1:4)=S3_U; - S3_m=sparse(1,m); - S3_m(m-3:m)=fliplr(-S3_U); - S3_1 = S3_1'; - S3_m = S3_m'; - - D4=HI*(M4-e_1*S3_1'+e_m*S3_m' + S_1*S2_1'-S_m*S2_m'); - - - - - -end
--- a/+sbp/+implementations/d4_compatible_halfvariable_6.m Tue Sep 11 13:24:08 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,170 +0,0 @@ -function [H, HI, D2, D4, e_1, e_m, M4, S2_1, S2_m, S3_1,... - S3_m, S_1, S_m] = d4_compatible_halfvariable_6(m,h) - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - %%% 6:te ordn. SBP Finita differens %%% - %%% operatorer med diagonal norm %%% - %%% Extension to variable koeff %%% - %%% %%% - %%% H (Normen) %%% - %%% D1=H^(-1)Q (approx f?rsta derivatan) %%% - %%% D2 (approx andra derivatan) %%% - %%% D2=HI*(R+C*D*S %%% - %%% %%% - %%% R=-D1'*H*C*D1-RR %%% - %%% %%% - %%% RR ?r dissipation) %%% - %%% Dissipationen uppbyggd av D4: %%% - %%% DI=D4*B*H*D4 %%% - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - - %m=10; %problemstorlek - %h=1/(m-1); - - % Variable koefficicients are stored in vector: c, size m, - % with the unknown stored as c(1), c(2), ..., c_m - % x=1:h:m*h;x=x'; - % c=x.^0; - - BP = 8; - if(m<2*BP) - error(['Operator requires at least ' num2str(2*BP) ' grid points']); - end - - - H=speye(m,m); - H(1:6,1:6)=diag([13649/43200,12013/8640,2711/4320,5359/4320,7877/8640, ... - 43801/43200]); - H(m-5:m,m-5:m)=rot90(diag([13649/43200,12013/8640, ... - 2711/4320,5359/4320,7877/8640,43801/43200]),2); - - -% x1=0.70127127127127; - - -% D1=(1/60*diag(ones(m-3,1),3)-9/60*diag(ones(m-2,1),2)+45/60*diag(ones(m-1,1),1)-45/60*diag(ones(m-1,1),-1)+9/60*diag(ones(m-2,1),-2)-1/60*diag(ones(m-3,1),-3)); -% -% -% -% D1(1:6,1:9)=[-21600/13649, 43200/13649*x1-7624/40947, -172800/13649*x1+ ... -% 715489/81894, 259200/13649*x1-187917/13649, -172800/13649* ... -% x1+735635/81894, 43200/13649*x1-89387/40947, 0, 0, 0; ... -% -8640/12013*x1+7624/180195, 0, 86400/12013*x1-57139/12013, ... -% -172800/12013*x1+745733/72078, 129600/12013*x1-91715/12013, ... -% -34560/12013*x1+240569/120130, 0, 0, 0; ... -% 17280/2711*x1-715489/162660, -43200/2711*x1+57139/5422, 0, ... -% 86400/2711*x1-176839/8133, -86400/2711*x1+242111/10844, ... -% 25920/2711*x1-182261/27110, 0, 0, 0; ... -% -25920/5359*x1+187917/53590, 86400/5359*x1-745733/64308, ... -% -86400/5359*x1+176839/16077, 0, 43200/5359*x1-165041/32154, ... -% -17280/5359*x1+710473/321540, 72/5359, 0, 0; ... -% 34560/7877*x1-147127/47262, -129600/7877*x1+91715/7877, ... -% 172800/7877*x1-242111/15754, -86400/7877*x1+165041/23631, ... -% 0, 8640/7877*x1, -1296/7877, 144/7877, 0; ... -% -43200/43801*x1+89387/131403, 172800/43801*x1-240569/87602,... -% -259200/43801*x1+182261/43801, 172800/43801*x1-710473/262806, ... -% -43200/43801*x1, 0, 32400/43801, -6480/43801, 720/43801]; -% D1(m-5:m,m-8:m)=rot90( -D1(1:6,1:9),2); -% D1=D1/h; - - e_1=sparse(m,1);e_1(1)=1; - e_m=sparse(m,1);e_m(m)=1; - - S_U=[-25/12, 4, -3, 4/3, -1/4]/h; - S_1=sparse(1,m); - S_1(1:5)=S_U; - S_m=sparse(1,m); - S_m(m-4:m)=fliplr(-S_U); - S_1 = S_1'; - S_m = S_m'; - - - - %DS=sparse(m,m); - %DS(1,1:5)=-[-25/12, 4, -3, 4/3, -1/4]; - %DS(m,m-4:m)=fliplr(-[-25/12, 4, -3, 4/3, -1/4]); - %DS=diag(c)*DS/h; - - - H=h*H; - HI=inv(H); - - - M=sparse(m,m); - e_1 = sparse(e_1); - e_m = sparse(e_m); - S_1 = sparse(S_1); - S_m = sparse(S_m); - - scheme_width = 7; - scheme_radius = (scheme_width-1)/2; - r = (1+scheme_radius):(m-scheme_radius); - - function D2 = D2_fun(c) - - Mm3 = c(r-2) / 0.40e2 + c(r-1) / 0.40e2 - 0.11e2 / 0.360e3 * c(r-3) - 0.11e2 / 0.360e3 * c(r); - Mm2 = c(r-3) / 0.20e2 - 0.3e1 / 0.10e2 * c(r-1) + c(r+1) / 0.20e2 + 0.7e1 / 0.40e2 * c(r) + 0.7e1 / 0.40e2 * c(r-2); - Mm1 = -c(r-3) / 0.40e2 - 0.3e1 / 0.10e2 * c(r-2) - 0.3e1 / 0.10e2 * c(r+1) - c(r+2) / 0.40e2 - 0.17e2 / 0.40e2 * c(r) - 0.17e2 / 0.40e2 * c(r-1); - M0 = c(r-3) / 0.180e3 + c(r-2) / 0.8e1 + 0.19e2 / 0.20e2 * c(r-1) + 0.19e2 / 0.20e2 * c(r+1) + c(r+2) / 0.8e1 + c(r+3) / 0.180e3 + 0.101e3 / 0.180e3 * c(r); - Mp1 = -c(r-2) / 0.40e2 - 0.3e1 / 0.10e2 * c(r-1) - 0.3e1 / 0.10e2 * c(r+2) - c(r+3) / 0.40e2 - 0.17e2 / 0.40e2 * c(r) - 0.17e2 / 0.40e2 * c(r+1); - Mp2 = c(r-1) / 0.20e2 - 0.3e1 / 0.10e2 * c(r+1) + c(r+3) / 0.20e2 + 0.7e1 / 0.40e2 * c(r) + 0.7e1 / 0.40e2 * c(r+2); - Mp3 = c(r+1) / 0.40e2 + c(r+2) / 0.40e2 - 0.11e2 / 0.360e3 * c(r) - 0.11e2 / 0.360e3 * c(r+3); - - M(r,:) = spdiags([Mm3 Mm2 Mm1 M0 Mp1 Mp2 Mp3],0:2*scheme_radius,length(r),m); - - - M(1:9,1:9)=[0.7912667594695582093926295e0 * c(1) + 0.2968472090638000742888467e0 * c(2) + 0.3185519088796429015220016e-2 * c(3) + 0.1632404042590951953384672e-1 * c(4) + 0.3160302244094415087693968e-1 * c(5) + 0.3167964748016105299646518e-1 * c(6) + 0.3148577733947253920469418e-1 * c(7) -0.1016689339350338144430605e1 * c(1) - 0.2845627370491611369031341e-1 * c(3) - 0.4128029838349298819825156e-1 * c(4) - 0.1392281451620140507549866e0 * c(5) - 0.1195777325611201766551392e0 * c(6) - 0.1194267756529333410855186e0 * c(7) 0.7075642937243715046279337e-1 * c(1) - 0.1845476106024151050283847e0 * c(2) - 0.4364163147111892346990101e-1 * c(4) + 0.2432367907207732460874765e0 * c(5) + 0.1582127073537215443965653e0 * c(6) + 0.1602348578364786307613271e0 * c(7) 0.2251991532891353212689574e0 * c(1) - 0.1662748711097054895317080e0 * c(2) + 0.2710530961648671297733465e-1 * c(3) - 0.1916646185968439909125616e0 * c(5) - 0.7684117160199014594442072e-1 * c(6) - 0.8219586949831697575883635e-1 * c(7) -0.5224403464202056316702078e-1 * c(1) + 0.4440063948509876221050939e-1 * c(2) - 0.1023976547309387874453988e-2 * c(3) + 0.7403484645316174090533193e-1 * c(4) + 0.1241625568998496895352046e-1 * c(6) + 0.7188652847892601282652228e-1 * c(5) + 0.1379362997104735503447960e-1 * c(7) -0.1828896813877197352675410e-1 * c(1) + 0.9574633163221758060736592e-2 * c(2) - 0.8105784530576404277872603e-3 * c(3) - 0.7348845587775519698437916e-2 * c(4) + 0.1063601949723906997026904e-1 * c(5) - 0.1315967038382618382356495e-1 * c(6) - 0.2117936478838753524581943e-1 * c(7) 0.1911888563316170927411831e-2 * c(4) - 0.4068130355529149936100229e-1 * c(5) + 0.1319674981073749167009902e-1 * c(6) + 0.2557266518123783676349144e-1 * c(7) 0.1559652871136785763960685e-1 * c(5) - 0.6486184157331537899459796e-2 * c(6) - 0.9110344554036319740147054e-2 * c(7) 0.5593983696629863059347067e-3 * c(6) - 0.1384822535100796372263822e-2 * c(5) + 0.8254241654378100663291154e-3 * c(7); -0.1016689339350338144430605e1 * c(1) - 0.2845627370491611369031341e-1 * c(3) - 0.4128029838349298819825156e-1 * c(4) - 0.1392281451620140507549866e0 * c(5) - 0.1195777325611201766551392e0 * c(6) - 0.1194267756529333410855186e0 * c(7) 0.1306332157111667628555907e1 * c(1) + 0.2542001760457345743492403e0 * c(3) + 0.1043897828092562609502636e0 * c(4) + 0.6672328021032112950919876e0 * c(5) + 0.4681819359722749441073885e0 * c(6) + 0.4676415410195836920069412e0 * c(7) -0.9091410269992464604926176e-1 * c(1) + 0.1103611313171476425250639e0 * c(4) - 0.1290397544997518887000350e1 * c(5) - 0.6639605248735044787146222e0 * c(6) - 0.6615974464005206184151509e0 * c(7) -0.2893557395653431666593814e0 * c(1) - 0.2421320004064592721552708e0 * c(3) + 0.1187670255028031027693374e1 * c(5) + 0.3956598149904136332753521e0 * c(6) + 0.3860048921755800000681479e0 * c(7) 0.6712774475803763988977355e-1 * c(1) + 0.9147192682075630179962131e-2 * c(3) - 0.1872196143003808021730728e0 * c(4) - 0.1319358558853174530078498e0 * c(6) - 0.4871575736811911887376923e0 * c(5) - 0.1047516312275448138054418e0 * c(7) 0.2349927974590068869356781e-1 * c(1) + 0.7240905383565181316381731e-2 * c(3) + 0.1858378996391679448655070e-1 * c(4) - 0.9289616133938676174345208e-1 * c(5) + 0.1223513270418807666970488e0 * c(6) + 0.1113520320436295033894092e0 * c(7) -0.4834791406446907590553793e-2 * c(4) + 0.2310683832687820403062715e0 * c(5) - 0.1080774142196007991746827e0 * c(6) - 0.1181561776427343335410349e0 * c(7) -0.8368141434403455353724691e-1 * c(5) + 0.4093499466767054661591066e-1 * c(6) + 0.4274641967636400692133626e-1 * c(7) -0.3576545132696983143406173e-2 * c(6) + 0.7389399124121078682094445e-2 * c(5) - 0.3812853991424095538688273e-2 * c(7); 0.7075642937243715046279337e-1 * c(1) - 0.1845476106024151050283847e0 * c(2) - 0.4364163147111892346990101e-1 * c(4) + 0.2432367907207732460874765e0 * c(5) + 0.1582127073537215443965653e0 * c(6) + 0.1602348578364786307613271e0 * c(7) -0.9091410269992464604926176e-1 * c(1) + 0.1103611313171476425250639e0 * c(4) - 0.1290397544997518887000350e1 * c(5) - 0.6639605248735044787146222e0 * c(6) - 0.6615974464005206184151509e0 * c(7) 0.6327161147136873807796515e-2 * c(1) + 0.1147318200715868527529827e0 * c(2) + 0.1166740554279680007487795e0 * c(4) + 0.2766610808285444037240703e1 * c(5) + 0.1070920689960817104203947e1 * c(6) + 0.1013161391032973057171717e1 * c(7) 0.2013769413884797246646959e-1 * c(1) + 0.1033717994630886401730470e0 * c(2) - 0.2913221621151742724258117e1 * c(5) - 0.8755807343482262259774782e0 * c(6) - 0.6909957183488812426508351e0 * c(7) -0.4671751091575462868310238e-2 * c(1) - 0.2760353365637712827793337e-1 * c(2) - 0.1979290298620869974478871e0 * c(4) + 0.5402985338373433052255418e0 * c(6) + 0.1239177593031911077924537e1 * c(5) + 0.2628038050247358227280031e0 * c(7) -0.1635430866921887819487473e-2 * c(1) - 0.5952475275883259619711594e-2 * c(2) + 0.1964682777744275219350831e-1 * c(4) + 0.3236640012639046600590714e0 * c(5) - 0.4659516693228870973898560e0 * c(6) - 0.2217272720941736859420432e0 * c(7) -0.5111353189352474549563559e-2 * c(4) - 0.5355878163774754346032096e0 * c(5) + 0.3328335104489738933610597e0 * c(6) + 0.2078656591178540157917135e0 * c(7) 0.1824328174134289562208038e0 * c(5) - 0.1059816030196818445908057e0 * c(6) - 0.7645121439374711162999809e-1 * c(7) 0.9209089963443799485648361e-2 * c(6) - 0.1591502818872493167091475e-1 * c(5) + 0.6705938225281132185266388e-2 * c(7); 0.2251991532891353212689574e0 * c(1) - 0.1662748711097054895317080e0 * c(2) + 0.2710530961648671297733465e-1 * c(3) - 0.1916646185968439909125616e0 * c(5) - 0.7684117160199014594442072e-1 * c(6) - 0.8219586949831697575883635e-1 * c(7) -0.2893557395653431666593814e0 * c(1) - 0.2421320004064592721552708e0 * c(3) + 0.1187670255028031027693374e1 * c(5) + 0.3956598149904136332753521e0 * c(6) + 0.3860048921755800000681479e0 * c(7) 0.2013769413884797246646959e-1 * c(1) + 0.1033717994630886401730470e0 * c(2) - 0.2913221621151742724258117e1 * c(5) - 0.8755807343482262259774782e0 * c(6) - 0.6909957183488812426508351e0 * c(7) 0.6409299775987186986730499e-1 * c(1) + 0.9313657638804699948929701e-1 * c(2) + 0.2306367624634749229113646e0 * c(3) + 0.3689440308283716620260816e1 * c(5) + 0.1190550338687608873798462e1 * c(6) + 0.5912479546888856519443605e0 * c(7) -0.1486895819265604128572498e-1 * c(1) - 0.2487040599390160764166412e-1 * c(2) - 0.8712928907711754187084757e-2 * c(3) - 0.1263507837371824205693950e1 * c(6) - 0.3058317397843997326920898e0 * c(7) - 0.1470691926045802954795783e1 * c(5) -0.5205147429855955657625694e-2 * c(1) - 0.5363098747528542488971874e-2 * c(2) - 0.6897142765790609546343709e-2 * c(3) - 0.7857524521667450101721993e0 * c(5) + 0.2291148005423734600066709e0 * c(7) + 0.9977064356292750529201981e0 * c(6) 0.6697297488067662265210608e0 * c(5) - 0.5013247356072127938999311e0 * c(6) - 0.1795161243106645437322408e0 * c(7) -0.2022909060111751565150958e0 * c(5) + 0.1453421858063658498587377e0 * c(6) + 0.5694872020480930665635812e-1 * c(7) -0.1200429618441003833696998e-1 * c(6) - 0.4776915669385923841535432e-2 * c(7) + 0.1678121185379596217850541e-1 * c(5); -0.5224403464202056316702078e-1 * c(1) + 0.4440063948509876221050939e-1 * c(2) - 0.1023976547309387874453988e-2 * c(3) + 0.7403484645316174090533193e-1 * c(4) + 0.1241625568998496895352046e-1 * c(6) + 0.7188652847892601282652228e-1 * c(5) + 0.1379362997104735503447960e-1 * c(7) 0.6712774475803763988977355e-1 * c(1) + 0.9147192682075630179962131e-2 * c(3) - 0.1872196143003808021730728e0 * c(4) - 0.1319358558853174530078498e0 * c(6) - 0.4871575736811911887376923e0 * c(5) - 0.1047516312275448138054418e0 * c(7) -0.4671751091575462868310238e-2 * c(1) - 0.2760353365637712827793337e-1 * c(2) - 0.1979290298620869974478871e0 * c(4) + 0.5402985338373433052255418e0 * c(6) + 0.1239177593031911077924537e1 * c(5) + 0.2628038050247358227280031e0 * c(7) -0.1486895819265604128572498e-1 * c(1) - 0.2487040599390160764166412e-1 * c(2) - 0.8712928907711754187084757e-2 * c(3) - 0.1263507837371824205693950e1 * c(6) - 0.3058317397843997326920898e0 * c(7) - 0.1470691926045802954795783e1 * c(5) 0.3449455095910233625229891e-2 * c(1) + 0.6641183499427826101618457e-2 * c(2) + 0.3291545083271862858501887e-3 * c(3) + 0.3357721707576477199985656e0 * c(4) + 0.2096413329579026439044119e1 * c(6) + 0.2317323204183126854954203e0 * c(7) + 0.6107825764368264576481962e-2 * c(8) + 0.7109125850683376695640722e0 * c(5) 0.1207544072304193806052558e-2 * c(1) + 0.1432116665752147607469646e-2 * c(2) + 0.2605582646183255957264249e-3 * c(3) - 0.3332941113251635390801278e-1 * c(4) - 0.2808241697385532683612407e0 * c(7) - 0.2720908083525083608370563e-1 * c(8) + 0.1045865435682921987447929e0 * c(5) - 0.1348436986667115543203552e1 * c(6) 0.8671038084174692625075159e-2 * c(4) + 0.1736073411355428563685818e0 * c(6) + 0.5331362125287625412555844e-1 * c(8) - 0.2424935262404526301801157e0 * c(5) + 0.1569015257678588270609004e0 * c(7) -0.8631683980217122275970376e-1 * c(6) + 0.2698842360470999243492629e-1 * c(7) + 0.8098194147715651085292754e-1 * c(5) - 0.3276463639080639163926118e-1 * c(8) 0.7462059484530855073291365e-2 * c(6) - 0.8121640361668678949573496e-3 * c(7) + 0.5522702088127090209264064e-3 * c(8) - 0.7202165657176696199260422e-2 * c(5); -0.1828896813877197352675410e-1 * c(1) + 0.9574633163221758060736592e-2 * c(2) - 0.8105784530576404277872603e-3 * c(3) - 0.7348845587775519698437916e-2 * c(4) + 0.1063601949723906997026904e-1 * c(5) - 0.1315967038382618382356495e-1 * c(6) - 0.2117936478838753524581943e-1 * c(7) 0.2349927974590068869356781e-1 * c(1) + 0.7240905383565181316381731e-2 * c(3) + 0.1858378996391679448655070e-1 * c(4) - 0.9289616133938676174345208e-1 * c(5) + 0.1223513270418807666970488e0 * c(6) + 0.1113520320436295033894092e0 * c(7) -0.1635430866921887819487473e-2 * c(1) - 0.5952475275883259619711594e-2 * c(2) + 0.1964682777744275219350831e-1 * c(4) + 0.3236640012639046600590714e0 * c(5) - 0.4659516693228870973898560e0 * c(6) - 0.2217272720941736859420432e0 * c(7) -0.5205147429855955657625694e-2 * c(1) - 0.5363098747528542488971874e-2 * c(2) - 0.6897142765790609546343709e-2 * c(3) - 0.7857524521667450101721993e0 * c(5) + 0.2291148005423734600066709e0 * c(7) + 0.9977064356292750529201981e0 * c(6) 0.1207544072304193806052558e-2 * c(1) + 0.1432116665752147607469646e-2 * c(2) + 0.2605582646183255957264249e-3 * c(3) - 0.3332941113251635390801278e-1 * c(4) - 0.2808241697385532683612407e0 * c(7) - 0.2720908083525083608370563e-1 * c(8) + 0.1045865435682921987447929e0 * c(5) - 0.1348436986667115543203552e1 * c(6) 0.4227226173449345042468960e-3 * c(1) + 0.3088241944378964404772302e-3 * c(2) + 0.2062575706647430620228133e-3 * c(3) + 0.3308343404200968256656458e-2 * c(4) + 0.5828047016405001815804837e0 * c(5) + 0.8054174220366215473556835e0 * c(7) + 0.1338363233410033443348225e0 * c(8) + 0.5555555555555555555555556e-2 * c(9) + 0.1190362071861893051132274e1 * c(6) -0.8607044252686413302647675e-3 * c(4) - 0.1748074708673904989293256e0 * c(5) - 0.3132544850115050165022338e0 * c(8) - 0.2500000000000000000000000e-1 * c(9) - 0.3169166305310429271303167e0 * c(7) - 0.6691607091647929161078591e0 * c(6) 0.3354661791693352108660900e-1 * c(5) - 0.3343620022386971405018586e0 * c(7) + 0.5000000000000000000000000e-1 * c(9) + 0.2169790609807602750804271e0 * c(6) + 0.1838363233410033443348225e0 * c(8) 0.2912518476823004642951502e-1 * c(7) + 0.2279091916474916391629437e-1 * c(8) - 0.3068985997518740530511593e-1 * c(6) - 0.1781799513347360596249022e-2 * c(5) - 0.3055555555555555555555556e-1 * c(9); 0.1911888563316170927411831e-2 * c(4) - 0.4068130355529149936100229e-1 * c(5) + 0.1319674981073749167009902e-1 * c(6) + 0.2557266518123783676349144e-1 * c(7) -0.4834791406446907590553793e-2 * c(4) + 0.2310683832687820403062715e0 * c(5) - 0.1080774142196007991746827e0 * c(6) - 0.1181561776427343335410349e0 * c(7) -0.5111353189352474549563559e-2 * c(4) - 0.5355878163774754346032096e0 * c(5) + 0.3328335104489738933610597e0 * c(6) + 0.2078656591178540157917135e0 * c(7) 0.6697297488067662265210608e0 * c(5) - 0.5013247356072127938999311e0 * c(6) - 0.1795161243106645437322408e0 * c(7) 0.8671038084174692625075159e-2 * c(4) + 0.1736073411355428563685818e0 * c(6) + 0.5331362125287625412555844e-1 * c(8) - 0.2424935262404526301801157e0 * c(5) + 0.1569015257678588270609004e0 * c(7) -0.8607044252686413302647675e-3 * c(4) - 0.1748074708673904989293256e0 * c(5) - 0.3132544850115050165022338e0 * c(8) - 0.2500000000000000000000000e-1 * c(9) - 0.3169166305310429271303167e0 * c(7) - 0.6691607091647929161078591e0 * c(6) 0.2239223735771599178951297e-3 * c(4) + 0.1275437785430956673825710e0 * c(5) + 0.1011699483929608164601067e1 * c(6) + 0.9698817275172575247533506e0 * c(8) + 0.1250000000000000000000000e0 * c(9) + 0.5555555555555555555555556e-2 * c(10) + 0.4823177543031281500117826e0 * c(7) -0.3784113973033012949863031e-1 * c(5) - 0.2997556885134827361576001e0 * c(6) - 0.3000000000000000000000000e0 * c(9) - 0.2500000000000000000000000e-1 * c(10) - 0.3991486867446821178415359e0 * c(7) - 0.4382544850115050165022338e0 * c(8) 0.4698146218022683933926520e-1 * c(6) - 0.2966863787471237458744416e0 * c(8) + 0.5000000000000000000000000e-1 * c(10) + 0.1716355704146006481727960e0 * c(7) + 0.3069346152296258362380356e-2 * c(5) + 0.1750000000000000000000000e0 * c(9); 0.1559652871136785763960685e-1 * c(5) - 0.6486184157331537899459796e-2 * c(6) - 0.9110344554036319740147054e-2 * c(7) -0.8368141434403455353724691e-1 * c(5) + 0.4093499466767054661591066e-1 * c(6) + 0.4274641967636400692133626e-1 * c(7) 0.1824328174134289562208038e0 * c(5) - 0.1059816030196818445908057e0 * c(6) - 0.7645121439374711162999809e-1 * c(7) -0.2022909060111751565150958e0 * c(5) + 0.1453421858063658498587377e0 * c(6) + 0.5694872020480930665635812e-1 * c(7) -0.8631683980217122275970376e-1 * c(6) + 0.2698842360470999243492629e-1 * c(7) + 0.8098194147715651085292754e-1 * c(5) - 0.3276463639080639163926118e-1 * c(8) 0.3354661791693352108660900e-1 * c(5) - 0.3343620022386971405018586e0 * c(7) + 0.5000000000000000000000000e-1 * c(9) + 0.2169790609807602750804271e0 * c(6) + 0.1838363233410033443348225e0 * c(8) -0.3784113973033012949863031e-1 * c(5) - 0.2997556885134827361576001e0 * c(6) - 0.3000000000000000000000000e0 * c(9) - 0.2500000000000000000000000e-1 * c(10) - 0.3991486867446821178415359e0 * c(7) - 0.4382544850115050165022338e0 * c(8) 0.1230328942716804455358698e-1 * c(5) + 0.1183647529645898332481833e0 * c(6) + 0.9410511898227943334189628e0 * c(7) + 0.9500000000000000000000000e0 * c(9) + 0.1250000000000000000000000e0 * c(10) + 0.5555555555555555555555556e-2 * c(11) + 0.5699474344521144554459336e0 * c(8) -0.2308067892671916339568942e-1 * c(6) - 0.2986625053775149497180439e0 * c(7) - 0.3000000000000000000000000e0 * c(10) - 0.2500000000000000000000000e-1 * c(11) - 0.1047734860515050802561078e-2 * c(5) - 0.4272090808352508360837056e0 * c(8) - 0.4250000000000000000000000e0 * c(9); 0.5593983696629863059347067e-3 * c(6) - 0.1384822535100796372263822e-2 * c(5) + 0.8254241654378100663291154e-3 * c(7) -0.3576545132696983143406173e-2 * c(6) + 0.7389399124121078682094445e-2 * c(5) - 0.3812853991424095538688273e-2 * c(7) 0.9209089963443799485648361e-2 * c(6) - 0.1591502818872493167091475e-1 * c(5) + 0.6705938225281132185266388e-2 * c(7) -0.1200429618441003833696998e-1 * c(6) - 0.4776915669385923841535432e-2 * c(7) + 0.1678121185379596217850541e-1 * c(5) 0.7462059484530855073291365e-2 * c(6) - 0.8121640361668678949573496e-3 * c(7) + 0.5522702088127090209264064e-3 * c(8) - 0.7202165657176696199260422e-2 * c(5) 0.2912518476823004642951502e-1 * c(7) + 0.2279091916474916391629437e-1 * c(8) - 0.3068985997518740530511593e-1 * c(6) - 0.1781799513347360596249022e-2 * c(5) - 0.3055555555555555555555556e-1 * c(9) 0.4698146218022683933926520e-1 * c(6) - 0.2966863787471237458744416e0 * c(8) + 0.5000000000000000000000000e-1 * c(10) + 0.1716355704146006481727960e0 * c(7) + 0.3069346152296258362380356e-2 * c(5) + 0.1750000000000000000000000e0 * c(9) -0.2308067892671916339568942e-1 * c(6) - 0.2986625053775149497180439e0 * c(7) - 0.3000000000000000000000000e0 * c(10) - 0.2500000000000000000000000e-1 * c(11) - 0.1047734860515050802561078e-2 * c(5) - 0.4272090808352508360837056e0 * c(8) - 0.4250000000000000000000000e0 * c(9) 0.5139370221149109977041877e-2 * c(6) + 0.1247723215009422001393184e0 * c(7) + 0.9505522702088127090209264e0 * c(8) + 0.9500000000000000000000000e0 * c(10) + 0.1250000000000000000000000e0 * c(11) + 0.5555555555555555555555556e-2 * c(12) + 0.9159362465153641826887659e-4 * c(5) + 0.5611111111111111111111111e0 * c(9);]; - - M(m-8:m,m-8:m)=[0.5555555555555555555555556e-2 * c(m-11) + 0.1250000000000000000000000e0 * c(m-10) + 0.9500000000000000000000000e0 * c(m-9) + 0.9505522702088127090209264e0 * c(m-7) + 0.1247205076844361998744053e0 * c(m-6) + 0.5139370221149109977041877e-2 * c(m-5) + 0.5611111111111111111111111e0 * c(m-8) + 0.1434074411575366831819799e-3 * c(m-4) -0.2500000000000000000000000e-1 * c(m-10) - 0.3000000000000000000000000e0 * c(m-9) - 0.2980649679116425253322056e0 * c(m-6) - 0.2308067892671916339568942e-1 * c(m-5) - 0.4250000000000000000000000e0 * c(m-8) - 0.4272090808352508360837056e0 * c(m-7) - 0.1645272326387475188399322e-2 * c(m-4) 0.5000000000000000000000000e-1 * c(m-9) - 0.2966863787471237458744416e0 * c(m-7) + 0.4698146218022683933926520e-1 * c(m-5) + 0.1750000000000000000000000e0 * c(m-8) + 0.1700291833903489463825077e0 * c(m-6) + 0.4675733176547960152668626e-2 * c(m-4) 0.2279091916474916391629437e-1 * c(m-7) + 0.3097763128598982561225538e-1 * c(m-6) - 0.3055555555555555555555556e-1 * c(m-8) - 0.3068985997518740530511593e-1 * c(m-5) - 0.3634246031107139778989373e-2 * c(m-4) 0.5522702088127090209264064e-3 * c(m-7) - 0.3265435411305071914756373e-2 * c(m-6) + 0.7462059484530855073291365e-2 * c(m-5) - 0.4748894282038492179461399e-2 * c(m-4) 0.6272075574042975468177820e-3 * c(m-6) - 0.1200429618441003833696998e-1 * c(m-5) + 0.1137708862700574079015220e-1 * c(m-4) 0.9209089963443799485648361e-2 * c(m-5) - 0.3129629392354775191148163e-3 * c(m-6) - 0.8896127024208321966533544e-2 * c(m-4) -0.3576545132696983143406173e-2 * c(m-5) + 0.4335019854436220306755673e-3 * c(m-6) + 0.3143043147253361112730605e-2 * c(m-4) 0.5593983696629863059347067e-3 * c(m-5) - 0.1446656414398166805849327e-3 * c(m-6) - 0.4147327282231696253497740e-3 * c(m-4); -0.2500000000000000000000000e-1 * c(m-10) - 0.3000000000000000000000000e0 * c(m-9) - 0.2980649679116425253322056e0 * c(m-6) - 0.2308067892671916339568942e-1 * c(m-5) - 0.4250000000000000000000000e0 * c(m-8) - 0.4272090808352508360837056e0 * c(m-7) - 0.1645272326387475188399322e-2 * c(m-4) 0.5555555555555555555555556e-2 * c(m-10) + 0.1250000000000000000000000e0 * c(m-9) + 0.9500000000000000000000000e0 * c(m-8) + 0.9341601509609901526962449e0 * c(m-6) + 0.1183647529645898332481833e0 * c(m-5) + 0.1919432828897222527630486e-1 * c(m-4) + 0.5699474344521144554459336e0 * c(m-7) -0.2500000000000000000000000e-1 * c(m-9) - 0.3000000000000000000000000e0 * c(m-8) - 0.2997556885134827361576001e0 * c(m-5) - 0.5636663150858098975790317e-1 * c(m-4) - 0.4382544850115050165022338e0 * c(m-7) - 0.3806231949664312575822630e0 * c(m-6) 0.5000000000000000000000000e-1 * c(m-8) - 0.3557251496099816106154206e0 * c(m-6) + 0.5490976528821799120017102e-1 * c(m-4) + 0.1838363233410033443348225e0 * c(m-7) + 0.2169790609807602750804271e0 * c(m-5) 0.5528052133944605740009217e-1 * c(m-6) - 0.8631683980217122275970376e-1 * c(m-5) - 0.3276463639080639163926118e-1 * c(m-7) + 0.5268984374242044588776166e-1 * c(m-4) -0.5373770512016897565958305e-2 * c(m-6) + 0.1453421858063658498587377e0 * c(m-5) - 0.1399684152943489522927794e0 * c(m-4) -0.1059816030196818445908057e0 * c(m-5) + 0.1014880675788250237247178e0 * c(m-4) + 0.4493535440856820866087846e-2 * c(m-6) 0.4093499466767054661591066e-1 * c(m-5) - 0.3471075437892810033585296e-1 * c(m-4) - 0.6224240288742446280057699e-2 * c(m-6) -0.6486184157331537899459796e-2 * c(m-5) + 0.4409068609809831485979484e-2 * c(m-4) + 0.2077115547521706413480312e-2 * c(m-6); 0.5000000000000000000000000e-1 * c(m-9) - 0.2966863787471237458744416e0 * c(m-7) + 0.4698146218022683933926520e-1 * c(m-5) + 0.1750000000000000000000000e0 * c(m-8) + 0.1700291833903489463825077e0 * c(m-6) + 0.4675733176547960152668626e-2 * c(m-4) -0.2500000000000000000000000e-1 * c(m-9) - 0.3000000000000000000000000e0 * c(m-8) - 0.2997556885134827361576001e0 * c(m-5) - 0.5636663150858098975790317e-1 * c(m-4) - 0.4382544850115050165022338e0 * c(m-7) - 0.3806231949664312575822630e0 * c(m-6) 0.5555555555555555555555556e-2 * c(m-9) + 0.1250000000000000000000000e0 * c(m-8) + 0.9698817275172575247533506e0 * c(m-7) + 0.1011699483929608164601067e1 * c(m-5) + 0.1773466968705924819112984e0 * c(m-4) + 0.2239223735771599178951297e-3 * c(m-3) + 0.4325148359756313354830552e0 * c(m-6) -0.2500000000000000000000000e-1 * c(m-8) - 0.3132544850115050165022338e0 * c(m-7) - 0.2322389872063761557916742e0 * c(m-4) - 0.8607044252686413302647675e-3 * c(m-3) - 0.2594851141920572702679681e0 * c(m-6) - 0.6691607091647929161078591e0 * c(m-5) 0.5331362125287625412555844e-1 * c(m-7) + 0.1736073411355428563685818e0 * c(m-5) + 0.8671038084174692625075159e-2 * c(m-3) + 0.8084259844422177692569663e-1 * c(m-6) - 0.1664345989168155800449120e0 * c(m-4) -0.5013247356072127938999311e0 * c(m-5) + 0.5021853752328231128475915e0 * c(m-4) - 0.1197175073672143005877150e-1 * c(m-6) 0.3328335104489738933610597e0 * c(m-5) - 0.3179803804558436283847901e0 * c(m-4) - 0.5111353189352474549563559e-2 * c(m-3) - 0.9741776803777790426705996e-2 * c(m-6) -0.1080774142196007991746827e0 * c(m-5) + 0.9941834083648937298100811e-1 * c(m-4) - 0.4834791406446907590553793e-2 * c(m-3) + 0.1349386478955833378422842e-1 * c(m-6) 0.1319674981073749167009902e-1 * c(m-5) - 0.1060554802883657391328704e-1 * c(m-4) + 0.1911888563316170927411831e-2 * c(m-3) - 0.4503090345217088684223814e-2 * c(m-6); 0.2279091916474916391629437e-1 * c(m-7) + 0.3097763128598982561225538e-1 * c(m-6) - 0.3055555555555555555555556e-1 * c(m-8) - 0.3068985997518740530511593e-1 * c(m-5) - 0.3634246031107139778989373e-2 * c(m-4) 0.5000000000000000000000000e-1 * c(m-8) - 0.3557251496099816106154206e0 * c(m-6) + 0.5490976528821799120017102e-1 * c(m-4) + 0.1838363233410033443348225e0 * c(m-7) + 0.2169790609807602750804271e0 * c(m-5) -0.2500000000000000000000000e-1 * c(m-8) - 0.3132544850115050165022338e0 * c(m-7) - 0.2322389872063761557916742e0 * c(m-4) - 0.8607044252686413302647675e-3 * c(m-3) - 0.2594851141920572702679681e0 * c(m-6) - 0.6691607091647929161078591e0 * c(m-5) 0.5555555555555555555555556e-2 * c(m-8) + 0.1338363233410033443348225e0 * c(m-7) + 0.7391887916719206077121040e0 * c(m-6) + 0.6490333320052011212240632e0 * c(m-4) + 0.3308343404200968256656458e-2 * c(m-3) + 0.2062575706647430620228133e-3 * c(m-2) + 0.3088241944378964404772302e-3 * c(m-1) + 0.4227226173449345042468960e-3 * c(m) + 0.1190362071861893051132274e1 * c(m-5) -0.2720908083525083608370563e-1 * c(m-7) - 0.1931148612480615118957263e0 * c(m-6) - 0.3332941113251635390801278e-1 * c(m-3) + 0.2605582646183255957264249e-3 * c(m-2) + 0.1432116665752147607469646e-2 * c(m-1) + 0.1207544072304193806052558e-2 * c(m) - 0.1348436986667115543203552e1 * c(m-5) + 0.1687723507780044227927853e-1 * c(m-4) 0.3590669644811151307464697e-1 * c(m-6) - 0.5925443480724830632401754e0 * c(m-4) - 0.6897142765790609546343709e-2 * c(m-2) - 0.5363098747528542488971874e-2 * c(m-1) - 0.5205147429855955657625694e-2 * c(m) + 0.9977064356292750529201981e0 * c(m-5) 0.7272438906214475928744770e-1 * c(m-4) + 0.1964682777744275219350831e-1 * c(m-3) - 0.5952475275883259619711594e-2 * c(m-1) - 0.1635430866921887819487473e-2 * c(m) + 0.2921234010758621482958052e-1 * c(m-6) - 0.4659516693228870973898560e0 * c(m-5) 0.5891947149681041048896399e-1 * c(m-4) + 0.1858378996391679448655070e-1 * c(m-3) + 0.7240905383565181316381731e-2 * c(m-2) + 0.2349927974590068869356781e-1 * c(m) - 0.4046360079256766884300687e-1 * c(m-6) + 0.1223513270418807666970488e0 * c(m-5) -0.2404661162020836566908542e-1 * c(m-4) - 0.7348845587775519698437916e-2 * c(m-3) - 0.8105784530576404277872603e-3 * c(m-2) + 0.9574633163221758060736592e-2 * c(m-1) - 0.1828896813877197352675410e-1 * c(m) + 0.1350326632905990039353503e-1 * c(m-6) - 0.1315967038382618382356495e-1 * c(m-5); 0.5522702088127090209264064e-3 * c(m-7) - 0.3265435411305071914756373e-2 * c(m-6) + 0.7462059484530855073291365e-2 * c(m-5) - 0.4748894282038492179461399e-2 * c(m-4) 0.5528052133944605740009217e-1 * c(m-6) - 0.8631683980217122275970376e-1 * c(m-5) - 0.3276463639080639163926118e-1 * c(m-7) + 0.5268984374242044588776166e-1 * c(m-4) 0.5331362125287625412555844e-1 * c(m-7) + 0.1736073411355428563685818e0 * c(m-5) + 0.8671038084174692625075159e-2 * c(m-3) + 0.8084259844422177692569663e-1 * c(m-6) - 0.1664345989168155800449120e0 * c(m-4) -0.2720908083525083608370563e-1 * c(m-7) - 0.1931148612480615118957263e0 * c(m-6) - 0.3332941113251635390801278e-1 * c(m-3) + 0.2605582646183255957264249e-3 * c(m-2) + 0.1432116665752147607469646e-2 * c(m-1) + 0.1207544072304193806052558e-2 * c(m) - 0.1348436986667115543203552e1 * c(m-5) + 0.1687723507780044227927853e-1 * c(m-4) 0.6107825764368264576481962e-2 * c(m-7) + 0.1155752633643216628010304e0 * c(m-6) + 0.2096413329579026439044119e1 * c(m-5) + 0.3357721707576477199985656e0 * c(m-3) + 0.3291545083271862858501887e-3 * c(m-2) + 0.6641183499427826101618457e-2 * c(m-1) + 0.3449455095910233625229891e-2 * c(m) + 0.8270696421223286922584620e0 * c(m-4) -0.4995827370863505253765970e-1 * c(m-6) - 0.1263507837371824205693950e1 * c(m-5) - 0.8712928907711754187084757e-2 * c(m-2) - 0.2487040599390160764166412e-1 * c(m-1) - 0.1486895819265604128572498e-1 * c(m) - 0.1726565392121567634950213e1 * c(m-4) 0.5402985338373433052255418e0 * c(m-5) - 0.1979290298620869974478871e0 * c(m-3) - 0.2760353365637712827793337e-1 * c(m-1) - 0.4671751091575462868310238e-2 * c(m) - 0.6952587985456154591014641e-1 * c(m-6) + 0.1571507277911208446562686e1 * c(m-4) -0.1319358558853174530078498e0 * c(m-5) - 0.1872196143003808021730728e0 * c(m-3) + 0.9147192682075630179962131e-2 * c(m-2) + 0.6712774475803763988977355e-1 * c(m) + 0.9630407686703666967100804e-1 * c(m-6) - 0.6882132817757726722141421e0 * c(m-4) 0.1241625568998496895352046e-1 * c(m-5) + 0.7403484645316174090533193e-1 * c(m-3) - 0.1023976547309387874453988e-2 * c(m-2) + 0.4440063948509876221050939e-1 * c(m-1) - 0.5224403464202056316702078e-1 * c(m) - 0.3213800979246298453953842e-1 * c(m-6) + 0.1178181682424363524005403e0 * c(m-4); 0.6272075574042975468177820e-3 * c(m-6) - 0.1200429618441003833696998e-1 * c(m-5) + 0.1137708862700574079015220e-1 * c(m-4) -0.5373770512016897565958305e-2 * c(m-6) + 0.1453421858063658498587377e0 * c(m-5) - 0.1399684152943489522927794e0 * c(m-4) -0.5013247356072127938999311e0 * c(m-5) + 0.5021853752328231128475915e0 * c(m-4) - 0.1197175073672143005877150e-1 * c(m-6) 0.3590669644811151307464697e-1 * c(m-6) - 0.5925443480724830632401754e0 * c(m-4) - 0.6897142765790609546343709e-2 * c(m-2) - 0.5363098747528542488971874e-2 * c(m-1) - 0.5205147429855955657625694e-2 * c(m) + 0.9977064356292750529201981e0 * c(m-5) -0.4995827370863505253765970e-1 * c(m-6) - 0.1263507837371824205693950e1 * c(m-5) - 0.8712928907711754187084757e-2 * c(m-2) - 0.2487040599390160764166412e-1 * c(m-1) - 0.1486895819265604128572498e-1 * c(m) - 0.1726565392121567634950213e1 * c(m-4) 0.2760393423824887721078848e-1 * c(m-6) + 0.1190550338687608873798462e1 * c(m-5) + 0.4253084328734353394994388e1 * c(m-4) + 0.2306367624634749229113646e0 * c(m-2) + 0.9313657638804699948929701e-1 * c(m-1) + 0.6409299775987186986730499e-1 * c(m) -0.8755807343482262259774782e0 * c(m-5) - 0.3645285178085761821545207e1 * c(m-4) + 0.1033717994630886401730470e0 * c(m-1) + 0.2013769413884797246646959e-1 * c(m) + 0.4106783858513785463625543e-1 * c(m-6) 0.3956598149904136332753521e0 * c(m-5) + 0.1630560443616104907615866e1 * c(m-4) - 0.2421320004064592721552708e0 * c(m-2) - 0.2893557395653431666593814e0 * c(m) - 0.5688529641249387985434413e-1 * c(m-6) -0.7684117160199014594442072e-1 * c(m-5) - 0.2928439026361256842196229e0 * c(m-4) + 0.2710530961648671297733465e-1 * c(m-2) - 0.1662748711097054895317080e0 * c(m-1) + 0.2251991532891353212689574e0 * c(m) + 0.1898341454096471754822498e-1 * c(m-6); 0.9209089963443799485648361e-2 * c(m-5) - 0.3129629392354775191148163e-3 * c(m-6) - 0.8896127024208321966533544e-2 * c(m-4) -0.1059816030196818445908057e0 * c(m-5) + 0.1014880675788250237247178e0 * c(m-4) + 0.4493535440856820866087846e-2 * c(m-6) 0.3328335104489738933610597e0 * c(m-5) - 0.3179803804558436283847901e0 * c(m-4) - 0.5111353189352474549563559e-2 * c(m-3) - 0.9741776803777790426705996e-2 * c(m-6) 0.7272438906214475928744770e-1 * c(m-4) + 0.1964682777744275219350831e-1 * c(m-3) - 0.5952475275883259619711594e-2 * c(m-1) - 0.1635430866921887819487473e-2 * c(m) + 0.2921234010758621482958052e-1 * c(m-6) - 0.4659516693228870973898560e0 * c(m-5) 0.5402985338373433052255418e0 * c(m-5) - 0.1979290298620869974478871e0 * c(m-3) - 0.2760353365637712827793337e-1 * c(m-1) - 0.4671751091575462868310238e-2 * c(m) - 0.6952587985456154591014641e-1 * c(m-6) + 0.1571507277911208446562686e1 * c(m-4) -0.8755807343482262259774782e0 * c(m-5) - 0.3645285178085761821545207e1 * c(m-4) + 0.1033717994630886401730470e0 * c(m-1) + 0.2013769413884797246646959e-1 * c(m) + 0.4106783858513785463625543e-1 * c(m-6) 0.1070920689960817104203947e1 * c(m-5) + 0.3717418466925056542408153e1 * c(m-4) + 0.1166740554279680007487795e0 * c(m-3) + 0.1147318200715868527529827e0 * c(m-1) + 0.6327161147136873807796515e-2 * c(m) + 0.6235373239336055200426697e-1 * c(m-6) -0.6639605248735044787146222e0 * c(m-5) - 0.1865625445986772763641423e1 * c(m-4) + 0.1103611313171476425250639e0 * c(m-3) - 0.9091410269992464604926176e-1 * c(m) - 0.8636954541126674177407762e-1 * c(m-6) 0.1582127073537215443965653e0 * c(m-5) + 0.3746489300753517635549495e0 * c(m-4) - 0.4364163147111892346990101e-1 * c(m-3) - 0.1845476106024151050283847e0 * c(m-1) + 0.7075642937243715046279337e-1 * c(m) + 0.2882271848190011329385407e-1 * c(m-6); -0.3576545132696983143406173e-2 * c(m-5) + 0.4335019854436220306755673e-3 * c(m-6) + 0.3143043147253361112730605e-2 * c(m-4) 0.4093499466767054661591066e-1 * c(m-5) - 0.3471075437892810033585296e-1 * c(m-4) - 0.6224240288742446280057699e-2 * c(m-6) -0.1080774142196007991746827e0 * c(m-5) + 0.9941834083648937298100811e-1 * c(m-4) - 0.4834791406446907590553793e-2 * c(m-3) + 0.1349386478955833378422842e-1 * c(m-6) 0.5891947149681041048896399e-1 * c(m-4) + 0.1858378996391679448655070e-1 * c(m-3) + 0.7240905383565181316381731e-2 * c(m-2) + 0.2349927974590068869356781e-1 * c(m) - 0.4046360079256766884300687e-1 * c(m-6) + 0.1223513270418807666970488e0 * c(m-5) -0.1319358558853174530078498e0 * c(m-5) - 0.1872196143003808021730728e0 * c(m-3) + 0.9147192682075630179962131e-2 * c(m-2) + 0.6712774475803763988977355e-1 * c(m) + 0.9630407686703666967100804e-1 * c(m-6) - 0.6882132817757726722141421e0 * c(m-4) 0.3956598149904136332753521e0 * c(m-5) + 0.1630560443616104907615866e1 * c(m-4) - 0.2421320004064592721552708e0 * c(m-2) - 0.2893557395653431666593814e0 * c(m) - 0.5688529641249387985434413e-1 * c(m-6) -0.6639605248735044787146222e0 * c(m-5) - 0.1865625445986772763641423e1 * c(m-4) + 0.1103611313171476425250639e0 * c(m-3) - 0.9091410269992464604926176e-1 * c(m) - 0.8636954541126674177407762e-1 * c(m-6) 0.4681819359722749441073885e0 * c(m-5) + 0.1015239189167790053447110e1 * c(m-4) + 0.1043897828092562609502636e0 * c(m-3) + 0.2542001760457345743492403e0 * c(m-2) + 0.1306332157111667628555907e1 * c(m) + 0.1196351539550049336518187e0 * c(m-6) -0.1195777325611201766551392e0 * c(m-5) - 0.2187310061229745694542609e0 * c(m-4) - 0.4128029838349298819825156e-1 * c(m-3) - 0.2845627370491611369031341e-1 * c(m-2) - 0.1016689339350338144430605e1 * c(m) - 0.3992391469197282238624438e-1 * c(m-6); 0.5593983696629863059347067e-3 * c(m-5) - 0.1446656414398166805849327e-3 * c(m-6) - 0.4147327282231696253497740e-3 * c(m-4) -0.6486184157331537899459796e-2 * c(m-5) + 0.4409068609809831485979484e-2 * c(m-4) + 0.2077115547521706413480312e-2 * c(m-6) 0.1319674981073749167009902e-1 * c(m-5) - 0.1060554802883657391328704e-1 * c(m-4) + 0.1911888563316170927411831e-2 * c(m-3) - 0.4503090345217088684223814e-2 * c(m-6) -0.2404661162020836566908542e-1 * c(m-4) - 0.7348845587775519698437916e-2 * c(m-3) - 0.8105784530576404277872603e-3 * c(m-2) + 0.9574633163221758060736592e-2 * c(m-1) - 0.1828896813877197352675410e-1 * c(m) + 0.1350326632905990039353503e-1 * c(m-6) - 0.1315967038382618382356495e-1 * c(m-5) 0.1241625568998496895352046e-1 * c(m-5) + 0.7403484645316174090533193e-1 * c(m-3) - 0.1023976547309387874453988e-2 * c(m-2) + 0.4440063948509876221050939e-1 * c(m-1) - 0.5224403464202056316702078e-1 * c(m) - 0.3213800979246298453953842e-1 * c(m-6) + 0.1178181682424363524005403e0 * c(m-4) -0.7684117160199014594442072e-1 * c(m-5) - 0.2928439026361256842196229e0 * c(m-4) + 0.2710530961648671297733465e-1 * c(m-2) - 0.1662748711097054895317080e0 * c(m-1) + 0.2251991532891353212689574e0 * c(m) + 0.1898341454096471754822498e-1 * c(m-6) 0.1582127073537215443965653e0 * c(m-5) + 0.3746489300753517635549495e0 * c(m-4) - 0.4364163147111892346990101e-1 * c(m-3) - 0.1845476106024151050283847e0 * c(m-1) + 0.7075642937243715046279337e-1 * c(m) + 0.2882271848190011329385407e-1 * c(m-6) -0.1195777325611201766551392e0 * c(m-5) - 0.2187310061229745694542609e0 * c(m-4) - 0.4128029838349298819825156e-1 * c(m-3) - 0.2845627370491611369031341e-1 * c(m-2) - 0.1016689339350338144430605e1 * c(m) - 0.3992391469197282238624438e-1 * c(m-6) 0.3167964748016105299646518e-1 * c(m-5) + 0.4976563420877041544013670e-1 * c(m-4) + 0.1632404042590951953384672e-1 * c(m-3) + 0.3185519088796429015220016e-2 * c(m-2) + 0.2968472090638000742888467e0 * c(m-1) + 0.7912667594695582093926295e0 * c(m) + 0.1332316557164627464149716e-1 * c(m-6);]; - - M(5,10)=M(10,5); - M(m-4,m-9)=M(m-9,m-4); - - M=M/h; - - D2=HI*(-M-diag(c)*e_1*S_1'+diag(c)*e_m*S_m'); - end - D2 = @D2_fun; - - S2_U=[0.35e2 / 0.12e2 -0.26e2 / 0.3e1 0.19e2 / 0.2e1 -0.14e2 / 0.3e1 0.11e2 / 0.12e2;]/h^2; - S2_1=sparse(1,m); - S2_1(1:5)=S2_U; - S2_m=sparse(1,m); - S2_m(m-4:m)=fliplr(S2_U); - S2_1 = S2_1'; - S2_m = S2_m'; - - - - - - % Fourth derivative, 1th order accurate at first 8 boundary points (still - % yield 5th order convergence if stable: for example u_tt=-u_xxxx - - m4=7/240;m3=-2/5;m2=169/60;m1=-122/15;m0=91/8; -% M4=m4*(diag(ones(m-4,1),4)+diag(ones(m-4,1),-4))+m3*(diag(ones(m-3,1),3)+diag(ones(m-3,1),-3))+m2*(diag(ones(m-2,1),2)+diag(ones(m-2,1),-2))+m1*(diag(ones(m-1,1),1)+diag(ones(m-1,1),-1))+m0*diag(ones(m,1),0); - stencil = [m4,m3,m2,m1,m0,m1,m2,m3,m4]; - d = (length(stencil)-1)/2; - diags = -d:d; - M4 = stripeMatrix(stencil, diags, m); - - %M4=(-1/6*(diag(ones(m-3,1),3)+diag(ones(m-3,1),-3) ) + 2*(diag(ones(m-2,1),2)+diag(ones(m-2,1),-2)) -13/2*(diag(ones(m-1,1),1)+diag(ones(m-1,1),-1)) + 28/3*diag(ones(m,1),0)); - - M4_U=[0.1394226315049e13 / 0.367201486080e12 -0.1137054563243e13 / 0.114750464400e12 0.16614189027367e14 / 0.1836007430400e13 -0.1104821700277e13 / 0.306001238400e12 0.1355771086763e13 / 0.1836007430400e13 -0.27818686453e11 / 0.459001857600e12 -0.40671054239e11 / 0.1836007430400e13 0.5442887371e10 / 0.306001238400e12; -0.1137054563243e13 / 0.114750464400e12 0.70616795535409e14 / 0.2570410402560e13 -0.173266854731041e15 / 0.6426026006400e13 0.28938615291031e14 / 0.2570410402560e13 -0.146167361863e12 / 0.71400288960e11 0.2793470836571e13 / 0.12852052012800e14 0.6219558097e10 / 0.428401733760e12 -0.7313844559e10 / 0.166909766400e12; 0.16614189027367e14 / 0.1836007430400e13 -0.173266854731041e15 / 0.6426026006400e13 0.378613061504779e15 / 0.12852052012800e14 -0.9117069604217e13 / 0.642602600640e12 0.632177582849e12 / 0.233673672960e12 -0.1057776382577e13 / 0.6426026006400e13 0.443019868399e12 / 0.4284017337600e13 -0.3707981e7 / 0.2318191200e10; -0.1104821700277e13 / 0.306001238400e12 0.28938615291031e14 / 0.2570410402560e13 -0.9117069604217e13 / 0.642602600640e12 0.5029150721885e13 / 0.514082080512e12 -0.5209119714341e13 / 0.1285205201280e13 0.12235427457469e14 / 0.12852052012800e14 -0.13731270505e11 / 0.64260260064e11 0.2933596129e10 / 0.40800165120e11; 0.1355771086763e13 / 0.1836007430400e13 -0.146167361863e12 / 0.71400288960e11 0.632177582849e12 / 0.233673672960e12 -0.5209119714341e13 / 0.1285205201280e13 0.14871726798559e14 / 0.2570410402560e13 -0.7504337615347e13 / 0.1606506501600e13 0.310830296467e12 / 0.171360693504e12 -0.55284274391e11 / 0.183600743040e12; -0.27818686453e11 / 0.459001857600e12 0.2793470836571e13 / 0.12852052012800e14 -0.1057776382577e13 / 0.6426026006400e13 0.12235427457469e14 / 0.12852052012800e14 -0.7504337615347e13 / 0.1606506501600e13 0.106318657014853e15 / 0.12852052012800e14 -0.14432772918527e14 / 0.2142008668800e13 0.58102695589e11 / 0.22666758400e11; -0.40671054239e11 / 0.1836007430400e13 0.6219558097e10 / 0.428401733760e12 0.443019868399e12 / 0.4284017337600e13 -0.13731270505e11 / 0.64260260064e11 0.310830296467e12 / 0.171360693504e12 -0.14432772918527e14 / 0.2142008668800e13 0.27102479467823e14 / 0.2570410402560e13 -0.1216032192203e13 / 0.153000619200e12; 0.5442887371e10 / 0.306001238400e12 -0.7313844559e10 / 0.166909766400e12 -0.3707981e7 / 0.2318191200e10 0.2933596129e10 / 0.40800165120e11 -0.55284274391e11 / 0.183600743040e12 0.58102695589e11 / 0.22666758400e11 -0.1216032192203e13 / 0.153000619200e12 0.20799922829107e14 / 0.1836007430400e13;]; - - M4(1:8,1:8)=M4_U; - - M4(m-7:m,m-7:m)=rot90( M4_U ,2 ); - M4=M4/h^3; - - S3_U=[-0.5e1 / 0.2e1 9 -12 7 -0.3e1 / 0.2e1;]/h^3; - S3_1=sparse(1,m); - S3_1(1:5)=S3_U; - S3_m=sparse(1,m); - S3_m(m-4:m)=fliplr(-S3_U); - S3_1 = S3_1'; - S3_m = S3_m'; - - D4=HI*(M4-e_1*S3_1'+e_m*S3_m' + S_1*S2_1'-S_m*S2_m'); - -end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/+implementations/d4_lonely_4_min_boundary_points.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,81 @@ +function [H, HI, D4, e_l, e_r, M4, d2_l, d2_r, d3_l, d3_r, d1_l, d1_r] = d4_variable_4_min_boundary_points(m,h) + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%% 4:de ordn. SBP Finita differens %%% + %%% operatorer framtagna av Mark Carpenter %%% + %%% %%% + %%% H (Normen) %%% + %%% D1=H^(-1)Q (approx f?rsta derivatan) %%% + %%% D2 (approx andra derivatan) %%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %H?r med endast 4 randpunkter + + + BP = 4; + if(m<2*BP) + error(['Operator requires at least ' num2str(2*BP) ' grid points']); + end + + + % Norm + Hv = ones(m,1); + Hv(1:4) = [17/48 59/48 43/48 49/48]; + Hv(m-3:m) = rot90(Hv(1:4),2); + Hv = h*Hv; + H = spdiag(Hv, 0); + HI = spdiag(1./Hv, 0); + + + % Boundary operators + e_l = sparse(m,1); + e_l(1) = 1; + e_r = rot90(e_l, 2); + + d1_l = sparse(m,1); + d1_l(1:4) = 1/h*[-11/6 3 -3/2 1/3]; + d1_r = -rot90(d1_l, 2); + + d2_l = sparse(m,1); + d2_l(1:4) = 1/h^2*[2 -5 4 -1]; + d2_r = rot90(d2_l, 2); + + d3_l = sparse(m,1); + d3_l(1:4) = 1/h^3*[-1 3 -3 1]; + d3_r = -rot90(d3_l, 2); + + + % First derivative + stencil = [1/12 -2/3 0 2/3 -1/12]; + diags = [-1 0 1]; + + Q_U = [ + 0 0.59e2/0.96e2 -0.1e1/0.12e2 -0.1e1/0.32e2; + -0.59e2/0.96e2 0 0.59e2/0.96e2 0; + 0.1e1/0.12e2 -0.59e2/0.96e2 0 0.59e2/0.96e2; + 0.1e1/0.32e2 0 -0.59e2/0.96e2 0; + ]; + + Q = stripeMatrix(stencil, diags, m); + Q(1:4,1:4)=Q_U; + Q(m-3:m,m-3:m) = -rot90(Q_U, 2); + + D1 = HI*(Q - 1/2*e_l*e_l' + 1/2*e_r*e_r'); + + % Fourth derivative + stencil = [-1/6, 2, -13/2, 28/3, -13/2, 2, -1/6]; + diags = -3:3; + M4 = stripeMatrix(stencil, diags, m); + + M4_U=[ + 0.8e1/0.3e1 -0.37e2/0.6e1 0.13e2/0.3e1 -0.5e1/0.6e1; + -0.37e2/0.6e1 0.47e2/0.3e1 -13 0.11e2/0.3e1; + 0.13e2/0.3e1 -13 0.44e2/0.3e1 -0.47e2/0.6e1; + -0.5e1/0.6e1 0.11e2/0.3e1 -0.47e2/0.6e1 0.29e2/0.3e1; + ]; + + + M4(1:4,1:4) = M4_U; + M4(m-3:m,m-3:m) = rot90(M4_U, 2); + M4 = 1/h^3*M4; + + D4=HI*(M4 - e_l*d3_l'+e_r*d3_r' + d1_l*d2_l'-d1_r*d2_r'); +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/+implementations/d4_lonely_6_2.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,76 @@ +function [H, HI, D4, e_l, e_r, M4, d2_l, d2_r, d3_l, d3_r, d1_l, d1_r] = d4_variable_6_2(m,h) + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%% 6:te ordn. SBP Finita differens %%% + %%% operatorer med diagonal norm %%% + %%% Extension to variable koeff %%% + %%% %%% + %%% H (Normen) %%% + %%% D1=H^(-1)Q (approx f?rsta derivatan) %%% + %%% D2 (approx andra derivatan) %%% + %%% D2=HI*(R+C*D*S %%% + %%% %%% + %%% R=-D1'*H*C*D1-RR %%% + %%% %%% + %%% RR ?r dissipation) %%% + %%% Dissipationen uppbyggd av D4: %%% + %%% DI=D4*B*H*D4 %%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % H?r med 6 RP ist?llet f?r 8 f?r D4 operatorn, dock samma randderivator + % Denna ?r noggrannare, och har 2a ordningens randdslutning och b?r ge 6te + % ordningens konvergens. Hade dock ingen fri parameter att optimera + + BP = 6; + if(m<2*BP) + error(['Operator requires at least ' num2str(2*BP) ' grid points']); + end + + % Norm + Hv = ones(m,1); + Hv(1:6) = [0.181e3/0.576e3, 0.1343e4/0.960e3, 0.293e3/0.480e3, 0.1811e4/0.1440e4, 0.289e3/0.320e3, 0.65e2/0.64e2]; + Hv(m-5:m) = rot90(Hv(1:6),2); + Hv = h*Hv; + H = spdiag(Hv, 0); + HI = spdiag(1./Hv, 0); + + + % Boundary operators + e_l = sparse(m,1); + e_l(1) = 1; + e_r = rot90(e_l, 2); + + d1_l = sparse(m,1); + d1_l(1:6) = [-0.137e3/0.60e2 5 -5 0.10e2/0.3e1 -0.5e1/0.4e1 0.1e1/0.5e1;]/h; + d1_r = -rot90(d1_l, 2); + + d2_l = sparse(m,1); + d2_l(1:6) = [0.15e2/0.4e1 -0.77e2/0.6e1 0.107e3/0.6e1 -13 0.61e2/0.12e2 -0.5e1/0.6e1;]/h^2; + d2_r = rot90(d2_l, 2); + + d3_l = sparse(m,1); + d3_l(1:6) = [-0.17e2/0.4e1 0.71e2/0.4e1 -0.59e2/0.2e1 0.49e2/0.2e1 -0.41e2/0.4e1 0.7e1/0.4e1;]/h^3; + d3_r = -rot90(d3_l, 2); + + + % Fourth derivative, 1th order accurate at first 8 boundary points (still + % yield 5th order convergence if stable: for example u_tt = -u_xxxx + stencil = [7/240, -2/5, 169/60, -122/15, 91/8, -122/15, 169/60, -2/5, 7/240]; + diags = -4:4; + M4 = stripeMatrix(stencil, diags, m); + + M4_U = [ + 0.1009e4/0.192e3 -0.7657e4/0.480e3 0.9307e4/0.480e3 -0.509e3/0.40e2 0.4621e4/0.960e3 -0.25e2/0.32e2; + -0.7657e4/0.480e3 0.49513e5/0.960e3 -0.4007e4/0.60e2 0.21799e5/0.480e3 -0.8171e4/0.480e3 0.2657e4/0.960e3; + 0.9307e4/0.480e3 -0.4007e4/0.60e2 0.1399e4/0.15e2 -0.2721e4/0.40e2 0.12703e5/0.480e3 -0.521e3/0.120e3; + -0.509e3/0.40e2 0.21799e5/0.480e3 -0.2721e4/0.40e2 0.3349e4/0.60e2 -0.389e3/0.15e2 0.559e3/0.96e2; + 0.4621e4/0.960e3 -0.8171e4/0.480e3 0.12703e5/0.480e3 -0.389e3/0.15e2 0.17857e5/0.960e3 -0.1499e4/0.160e3; + -0.25e2/0.32e2 0.2657e4/0.960e3 -0.521e3/0.120e3 0.559e3/0.96e2 -0.1499e4/0.160e3 0.2225e4/0.192e3; + ]; + + + M4(1:6,1:6) = M4_U; + M4(m-5:m,m-5:m) = rot90(M4_U, 2); + M4 = 1/h^3*M4; + + D4=HI*(M4 - e_l*d3_l'+e_r*d3_r' + d1_l*d2_l'-d1_r*d2_r'); +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/+implementations/d4_lonely_6_3.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,70 @@ +function [H, HI, D4, e_l, e_r, M4, d2_l, d2_r, d3_l, d3_r, d1_l, d1_r] = d4_variable_6_3(m,h) + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%% 6:te ordn. SBP Finita differens %%% + %%% operatorer med diagonal norm %%% + %%% Extension to variable koeff %%% + %%% %%% + %%% H (Normen) %%% + %%% D1=H^(-1)Q (approx f?rsta derivatan) %%% + %%% D2 (approx andra derivatan) %%% + %%% D2=HI*(R+C*D*S %%% + %%% %%% + %%% R=-D1'*H*C*D1-RR %%% + %%% %%% + %%% RR ?r dissipation) %%% + %%% Dissipationen uppbyggd av D4: %%% + %%% DI=D4*B*H*D4 %%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % H?r med 7 RP ist?llet f?r 8 f?r D4 operatorn, dock samma randderivator + % Denna ?r noggrannare, och har 2a ordningens randdslutning och b?r ge 6te + % ordningens konvergens. Hade 2 fria parametrar att optimera + + % Norm + Hv = ones(m,1); + Hv(1:7) = [0.414837907e9/0.1191965760e10, 0.475278367e9/0.397321920e9, 0.13872751e8/0.12416310e8, 0.346739027e9/0.595982880e9, 0.560227469e9/0.397321920e9, 0.322971631e9/0.397321920e9, 0.616122491e9/0.595982880e9]; + Hv(m-6:m) = rot90(Hv(1:7),2); + Hv = h*Hv; + H = spdiag(Hv, 0); + HI = spdiag(1./Hv, 0); + + + % Boundary operators + e_l = sparse(m,1); + e_l(1) = 1; + e_r = rot90(e_l, 2); + + d1_l = sparse(m,1); + d1_l(1:6) = [-0.137e3/0.60e2 5 -5 0.10e2/0.3e1 -0.5e1/0.4e1 0.1e1/0.5e1;]/h; + d1_r = -rot90(d1_l, 2); + + d2_l = sparse(m,1); + d2_l(1:6) = [0.15e2/0.4e1 -0.77e2/0.6e1 0.107e3/0.6e1 -13 0.61e2/0.12e2 -0.5e1/0.6e1;]/h^2; + d2_r = rot90(d2_l, 2); + + d3_l = sparse(m,1); + d3_l(1:6) = [-0.17e2/0.4e1 0.71e2/0.4e1 -0.59e2/0.2e1 0.49e2/0.2e1 -0.41e2/0.4e1 0.7e1/0.4e1;]/h^3; + d3_r = -rot90(d3_l, 2); + + + % Fourth derivative, 1th order accurate at first 8 boundary points + stencil = [7/240, -2/5, 169/60, -122/15, 91/8, -122/15, 169/60, -2/5, 7/240]; + diags = -4:4; + M4 = stripeMatrix(stencil, diags, m); + + M4_U = [ + 0.1399708478939e13/0.263487168000e12 -0.13482796013041e14/0.834376032000e12 0.344344095859e12/0.17565811200e11 -0.3166261424681e13/0.250312809600e12 0.1508605165681e13/0.333750412800e12 -0.486270829441e12/0.834376032000e12 -0.221976356359e12/0.5006256192000e13; + -0.13482796013041e14/0.834376032000e12 0.7260475818391e13/0.139062672000e12 -0.27224036353e11/0.406022400e9 0.1847477458951e13/0.41718801600e11 -0.848984558161e12/0.55625068800e11 0.247494925991e12/0.139062672000e12 0.165585445559e12/0.834376032000e12; + 0.344344095859e12/0.17565811200e11 -0.27224036353e11/0.406022400e9 0.2044938640393e13/0.22250027520e11 -0.1071086785417e13/0.16687520640e11 0.502199537033e12/0.22250027520e11 -0.143589154441e12/0.55625068800e11 -0.88181965559e11/0.333750412800e12; + -0.3166261424681e13/0.250312809600e12 0.1847477458951e13/0.41718801600e11 -0.1071086785417e13/0.16687520640e11 0.628860435593e12/0.12515640480e11 -0.73736245829e11/0.3337504128e10 0.195760572271e12/0.41718801600e11 -0.81156046361e11/0.250312809600e12; + 0.1508605165681e13/0.333750412800e12 -0.848984558161e12/0.55625068800e11 0.502199537033e12/0.22250027520e11 -0.73736245829e11/0.3337504128e10 0.76725285869e11/0.4450005504e10 -0.3912429433e10/0.406022400e9 0.53227370659e11/0.17565811200e11; + -0.486270829441e12/0.834376032000e12 0.247494925991e12/0.139062672000e12 -0.143589154441e12/0.55625068800e11 0.195760572271e12/0.41718801600e11 -0.3912429433e10/0.406022400e9 0.1699707221791e13/0.139062672000e12 -0.6959018412841e13/0.834376032000e12; + -0.221976356359e12/0.5006256192000e13 0.165585445559e12/0.834376032000e12 -0.88181965559e11/0.333750412800e12 -0.81156046361e11/0.250312809600e12 0.53227370659e11/0.17565811200e11 -0.6959018412841e13/0.834376032000e12 0.3012195053939e13/0.263487168000e12; + ]; + + M4(1:7,1:7) = M4_U; + M4(m-6:m,m-6:m) = rot90(M4_U, 2); + M4 = 1/h^3*M4; + + D4=HI*(M4 - e_l*d3_l'+e_r*d3_r' + d1_l*d2_l'-d1_r*d2_r'); +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/+implementations/d4_lonely_6_min_boundary_points.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,74 @@ +function [H, HI, D4, e_l, e_r, M4, d2_l, d2_r, d3_l, d3_r, d1_l, d1_r] = d4_variable_6_min_boundary_points(m,h) + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%% 6:te ordn. SBP Finita differens %%% + %%% operatorer med diagonal norm %%% + %%% Extension to variable koeff %%% + %%% %%% + %%% H (Normen) %%% + %%% D1=H^(-1)Q (approx f?rsta derivatan) %%% + %%% D2 (approx andra derivatan) %%% + %%% D2=HI*(R+C*D*S %%% + %%% %%% + %%% R=-D1'*H*C*D1-RR %%% + %%% %%% + %%% RR ?r dissipation) %%% + %%% Dissipationen uppbyggd av D4: %%% + %%% DI=D4*B*H*D4 %%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % H?r med 6 RP ist?llet f?r 8 f?r D4 operatorn, dock samma randderivator + + BP = 6; + if(m<2*BP) + error(['Operator requires at least ' num2str(2*BP) ' grid points']); + end + + % Norm + Hv = ones(m,1); + Hv(1:6) = [13649/43200,12013/8640,2711/4320,5359/4320,7877/8640, 43801/43200]; + Hv(m-5:m) = rot90(Hv(1:6),2); + Hv = h*Hv; + H = spdiag(Hv, 0); + HI = spdiag(1./Hv, 0); + + + % Boundary operators + e_l = sparse(m,1); + e_l(1) = 1; + e_r = rot90(e_l, 2); + + d1_l = sparse(m,1); + d1_l(1:5) = [-25/12, 4, -3, 4/3, -1/4]/h; + d1_r = -rot90(d1_l, 2); + + d2_l = sparse(m,1); + d2_l(1:5) = [0.35e2/0.12e2 -0.26e2/0.3e1 0.19e2/0.2e1 -0.14e2/0.3e1 0.11e2/0.12e2;]/h^2; + d2_r = rot90(d2_l, 2); + + d3_l = sparse(m,1); + d3_l(1:5) = [-0.5e1/0.2e1 9 -12 7 -0.3e1/0.2e1;]/h^3; + d3_r = -rot90(d3_l, 2); + + + % Fourth derivative, 1th order accurate at first 8 boundary points (still + % yield 5th order convergence if stable: for example u_tt=-u_xxxx + + stencil = [7/240, -2/5, 169/60, -122/15, 91/8, -122/15, 169/60, -2/5, 7/240]; + diags = -4:4; + M4 = stripeMatrix(stencil, diags, m); + + M4_U=[ + 0.3504379e7/0.907200e6 -0.4613983e7/0.453600e6 0.4260437e7/0.453600e6 -0.418577e6/0.113400e6 0.524579e6/0.907200e6 0.535e3/0.18144e5; + -0.4613983e7/0.453600e6 0.5186159e7/0.181440e6 -0.81121e5/0.2835e4 0.218845e6/0.18144e5 -0.159169e6/0.90720e5 -0.94669e5/0.907200e6; + 0.4260437e7/0.453600e6 -0.81121e5/0.2835e4 0.147695e6/0.4536e4 -0.384457e6/0.22680e5 0.339653e6/0.90720e5 -0.18233e5/0.113400e6; + -0.418577e6/0.113400e6 0.218845e6/0.18144e5 -0.384457e6/0.22680e5 0.65207e5/0.4536e4 -0.22762e5/0.2835e4 0.1181753e7/0.453600e6; + 0.524579e6/0.907200e6 -0.159169e6/0.90720e5 0.339653e6/0.90720e5 -0.22762e5/0.2835e4 0.2006171e7/0.181440e6 -0.3647647e7/0.453600e6; + 0.535e3/0.18144e5 -0.94669e5/0.907200e6 -0.18233e5/0.113400e6 0.1181753e7/0.453600e6 -0.3647647e7/0.453600e6 0.10305271e8/0.907200e6; + ]; + + M4(1:6,1:6) = M4_U; + M4(m-5:m,m-5:m) = rot90(M4_U, 2); + M4 = 1/h^3*M4; + + D4=HI*(M4 - e_l*d3_l'+e_r*d3_r' + d1_l*d2_l'-d1_r*d2_r'); +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/+implementations/d4_lonely_8_higher_boundary_order.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,76 @@ +function [H, HI, D4, e_l, e_r, M4, d2_l, d2_r, d3_l, d3_r, d1_l, d1_r] = d4_variable_8_higher_boundary_order(m,h) + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%% 8:te ordn. SBP Finita differens %%% + %%% operatorer med diagonal norm %%% + %%% %%% + %%% %%% + %%% H (Normen) %%% + %%% D1=H^(-1)Q (approx f?rsta derivatan) %%% + %%% D2 (approx andra derivatan) %%% + %%% D2=HI*(R+C*D*S %%% + %%% %%% + %%% R=-D1'*H*C*D1-RR %%% + %%% %%% + %%% RR ?r dissipation) %%% + %%% Dissipationen uppbyggd av D4: %%% + %%% DI=D4*B*H*D4 %%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %This is 3rd order accurate at the boundary. Not same norm as D1 operator + + BP = 8; + if(m<2*BP) + error(['Operator requires at least ' num2str(2*BP) ' grid points']); + end + + % Norm + Hv = ones(m,1); + Hv(1:8) = [0.7488203e7/0.25401600e8, 0.5539027e7/0.3628800e7, 0.308923e6/0.1209600e7, 0.1307491e7/0.725760e6, 0.59407e5/0.145152e6, 0.1548947e7/0.1209600e7, 0.3347963e7/0.3628800e7, 0.25641187e8/0.25401600e8]; + Hv(m-7:m) = rot90(Hv(1:8),2); + Hv = h*Hv; + H = spdiag(Hv, 0); + HI = spdiag(1./Hv, 0); + + + % Boundary operators + e_l = sparse(m,1); + e_l(1) = 1; + e_r = rot90(e_l, 2); + + d1_l = sparse(m,1); + d1_l(1:7) = [-0.49e2/0.20e2 6 -0.15e2/0.2e1 0.20e2/0.3e1 -0.15e2/0.4e1 0.6e1/0.5e1 -0.1e1/0.6e1]/h; + d1_r = -rot90(d1_l, 2); + + d2_l = sparse(m,1); + d2_l(1:7) = [0.203e3/0.45e2 -0.87e2/0.5e1 0.117e3/0.4e1 -0.254e3/0.9e1 0.33e2/0.2e1 -0.27e2/0.5e1 0.137e3/0.180e3]/h^2; + d2_r = rot90(d2_l, 2); + + d3_l = sparse(m,1); + d3_l(1:7) = [-0.49e2/0.8e1 29 -0.461e3/0.8e1 62 -0.307e3/0.8e1 13 -0.15e2/0.8e1]/h^3; + d3_r = -rot90(d3_l, 2); + + + + % Fourth derivative, 1th order accurate at first 8 boundary points (still + % yield 5th order convergence if stable: for example u_tt = -u_xxxx + + stencil = [-0.41e2/0.7560e4, 0.1261e4/0.15120e5, -0.541e3/0.840e3, 0.4369e4/0.1260e4, -0.1669e4/0.180e3, 0.1529e4/0.120e3, -0.1669e4/0.180e3, 0.4369e4/0.1260e4, -0.541e3/0.840e3, 0.1261e4/0.15120e5,-0.41e2/0.7560e4]; + diags = -5:5; + M4 = stripeMatrix(stencil, diags, m); + + M4_U = [ + 0.1031569831e10/0.155675520e9 -0.32874237931e11/0.1452971520e10 0.3069551773e10/0.90810720e8 -0.658395212131e12/0.21794572800e11 0.31068454007e11/0.1816214400e10 -0.39244130657e11/0.7264857600e10 0.1857767503e10/0.2724321600e10 0.1009939e7/0.49420800e8; + -0.32874237931e11/0.1452971520e10 0.12799022387e11/0.155675520e9 -0.134456503627e12/0.1037836800e10 0.15366749479e11/0.129729600e9 -0.207640325549e12/0.3113510400e10 0.5396424073e10/0.259459200e9 -0.858079351e9/0.345945600e9 -0.19806607e8/0.170270100e9; + 0.3069551773e10/0.90810720e8 -0.134456503627e12/0.1037836800e10 0.6202056779e10/0.28828800e8 -0.210970327081e12/0.1037836800e10 0.2127730129e10/0.18532800e8 -0.4048692749e10/0.115315200e9 0.1025943959e10/0.259459200e9 0.71054663e8/0.290594304e9; + -0.658395212131e12/0.21794572800e11 0.15366749479e11/0.129729600e9 -0.210970327081e12/0.1037836800e10 0.31025293213e11/0.155675520e9 -0.1147729001e10/0.9884160e7 0.1178067773e10/0.32432400e8 -0.13487255581e11/0.3113510400e10 -0.231082547e9/0.1816214400e10; + 0.31068454007e11/0.1816214400e10 -0.207640325549e12/0.3113510400e10 0.2127730129e10/0.18532800e8 -0.1147729001e10/0.9884160e7 0.11524865123e11/0.155675520e9 -0.29754506009e11/0.1037836800e10 0.14231221e8/0.2316600e7 -0.15030629699e11/0.21794572800e11; + -0.39244130657e11/0.7264857600e10 0.5396424073e10/0.259459200e9 -0.4048692749e10/0.115315200e9 0.1178067773e10/0.32432400e8 -0.29754506009e11/0.1037836800e10 0.572247737e9/0.28828800e8 -0.11322059051e11/0.1037836800e10 0.3345834083e10/0.908107200e9; + 0.1857767503e10/0.2724321600e10 -0.858079351e9/0.345945600e9 0.1025943959e10/0.259459200e9 -0.13487255581e11/0.3113510400e10 0.14231221e8/0.2316600e7 -0.11322059051e11/0.1037836800e10 0.10478882597e11/0.778377600e9 -0.68446325191e11/0.7264857600e10; + 0.1009939e7/0.49420800e8 -0.19806607e8/0.170270100e9 0.71054663e8/0.290594304e9 -0.231082547e9/0.1816214400e10 -0.15030629699e11/0.21794572800e11 0.3345834083e10/0.908107200e9 -0.68446325191e11/0.7264857600e10 0.9944747557e10/0.778377600e9; + ]; + + M4(1:8,1:8) = M4_U; + M4(m-7:m,m-7:m) = rot90(M4_U, 2); + M4 = 1/h^3*M4; + + D4=HI*(M4 - e_l*d3_l'+e_r*d3_r' + d1_l*d2_l'-d1_r*d2_r'); +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/+implementations/d4_lonely_8_min_boundary_points.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,73 @@ +function [H, HI, D4, e_l, e_r, M4, d2_l, d2_r, d3_l, d3_r, d1_l, d1_r] = d4_variable_8_min_boundary_points(m,h) + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%% 8:te ordn. SBP Finita differens %%% + %%% operatorer med diagonal norm %%% + %%% %%% + %%% %%% + %%% H (Normen) %%% + %%% D1=H^(-1)Q (approx f?rsta derivatan) %%% + %%% D2 (approx andra derivatan) %%% + %%% D2=HI*(R+C*D*S %%% + %%% %%% + %%% R=-D1'*H*C*D1-RR %%% + %%% %%% + %%% RR ?r dissipation) %%% + %%% Dissipationen uppbyggd av D4: %%% + %%% DI=D4*B*H*D4 %%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + BP = 8; + if(m<2*BP) + error(['Operator requires at least ' num2str(2*BP) ' grid points']); + end + + % Norm + Hv = ones(m,1); + Hv(1:8) = [1498139/5080320, 1107307/725760, 20761/80640, 1304999/725760, 299527/725760, 103097/80640, 670091/725760, 5127739/5080320]; + Hv(m-7:m) = rot90(Hv(1:8),2); + Hv = h*Hv; + H = spdiag(Hv, 0); + HI = spdiag(1./Hv, 0); + + + % Boundary operators + e_l = sparse(m,1); + e_l(1) = 1; + e_r = rot90(e_l, 2); + + d1_l = sparse(m,1); + d1_l(1:6) = [-0.137e3/0.60e2 5 -5 0.10e2/0.3e1 -0.5e1/0.4e1 0.1e1/0.5e1;]/h; + d1_r = -rot90(d1_l, 2); + + d2_l = sparse(m,1); + d2_l(1:6) = [0.15e2/0.4e1 -0.77e2/0.6e1 0.107e3/0.6e1 -13 0.61e2/0.12e2 -0.5e1/0.6e1;]/h^2; + d2_r = rot90(d2_l, 2); + + d3_l = sparse(m,1); + d3_l(1:6) = [-0.17e2/0.4e1 0.71e2/0.4e1 -0.59e2/0.2e1 0.49e2/0.2e1 -0.41e2/0.4e1 0.7e1/0.4e1;]/h^3; + d3_r = -rot90(d3_l, 2); + + + % Fourth derivative, 1th order accurate at first 8 boundary points + + stencil = [-0.41e2/0.7560e4, 0.1261e4/0.15120e5,-0.541e3/0.840e3,0.4369e4/0.1260e4,-0.1669e4/0.180e3,0.1529e4/0.120e3,-0.1669e4/0.180e3,0.4369e4/0.1260e4,-0.541e3/0.840e3, 0.1261e4/0.15120e5,-0.41e2/0.7560e4]; + diags = -5:5; + M4 = stripeMatrix(stencil, diags, m); + + M4_U = [ + 0.151705142321e12/0.29189160000e11 -0.25643455801727e14/0.1634592960000e13 0.286417898677e12/0.15135120000e11 -0.4038072020317e13/0.326918592000e12 0.96455968907e11/0.20432412000e11 -0.151076916769e12/0.181621440000e12 0.14511526363e11/0.408648240000e12 -0.196663079e9/0.33359040000e11; + -0.25643455801727e14/0.1634592960000e13 0.735383382473e12/0.14594580000e11 -0.5035391734409e13/0.77837760000e11 0.20392440917e11/0.467026560e9 -0.109540902413e12/0.6671808000e10 0.2488686539e10/0.884520000e9 -0.2798067539e10/0.33359040000e11 0.6433463591e10/0.408648240000e12; + 0.286417898677e12/0.15135120000e11 -0.5035391734409e13/0.77837760000e11 0.145019791981e12/0.1621620000e10 -0.333577111061e12/0.5189184000e10 0.18928722391e11/0.778377600e9 -0.93081704557e11/0.25945920000e11 -0.372660319e9/0.3243240000e10 0.2861399869e10/0.544864320000e12; + -0.4038072020317e13/0.326918592000e12 0.20392440917e11/0.467026560e9 -0.333577111061e12/0.5189184000e10 0.59368471277e11/0.1167566400e10 -0.201168708569e12/0.9340531200e10 0.1492314487e10/0.432432000e9 0.1911896257e10/0.9340531200e10 0.24383341e8/0.2554051500e10; + 0.96455968907e11/0.20432412000e11 -0.109540902413e12/0.6671808000e10 0.18928722391e11/0.778377600e9 -0.201168708569e12/0.9340531200e10 0.1451230301e10/0.106142400e9 -0.103548247007e12/0.15567552000e11 0.27808437809e11/0.11675664000e11 -0.36870830713e11/0.65383718400e11; + -0.151076916769e12/0.181621440000e12 0.2488686539e10/0.884520000e9 -0.93081704557e11/0.25945920000e11 0.1492314487e10/0.432432000e9 -0.103548247007e12/0.15567552000e11 0.1229498243e10/0.115830000e9 -0.32222519717e11/0.3706560000e10 0.470092704233e12/0.136216080000e12; + 0.14511526363e11/0.408648240000e12 -0.2798067539e10/0.33359040000e11 -0.372660319e9/0.3243240000e10 0.1911896257e10/0.9340531200e10 0.27808437809e11/0.11675664000e11 -0.32222519717e11/0.3706560000e10 0.11547819313e11/0.912161250e9 -0.15187033999199e14/0.1634592960000e13; + -0.196663079e9/0.33359040000e11 0.6433463591e10/0.408648240000e12 0.2861399869e10/0.544864320000e12 0.24383341e8/0.2554051500e10 -0.36870830713e11/0.65383718400e11 0.470092704233e12/0.136216080000e12 -0.15187033999199e14/0.1634592960000e13 0.33832994693e11/0.2653560000e10; + ]; + + M4(1:8,1:8) = M4_U; + M4(m-7:m,m-7:m) = rot90(M4_U, 2); + M4 = 1/h^3*M4; + + D4=HI*(M4 - e_l*d3_l'+e_r*d3_r' + d1_l*d2_l'-d1_r*d2_r'); +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/+implementations/d4_variable_2.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,89 @@ +% Returns D2 as a function handle +function [H, HI, D1, D2, D4, e_l, e_r, M4, d2_l, d2_r, d3_l, d3_r, d1_l, d1_r] = d4_variable_2(m,h) + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%% 4:de ordn. SBP Finita differens %%% + %%% operatorer framtagna av Ken Mattsson %%% + %%% %%% + %%% 6 randpunkter, diagonal norm %%% + %%% %%% + %%% Datum: 2013-11-11 %%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + BP = 2; + if(m < 2*BP) + error('Operator requires at least %d grid points', 2*BP); + end + + % Norm + Hv = ones(m,1); + Hv(1) = 1/2; + Hv(m) = 1/2; + Hv = h*Hv; + H = spdiag(Hv, 0); + HI = spdiag(1./Hv, 0); + + % Boundary operators + e_l = sparse(m,1); + e_l(1) = 1; + e_r = rot90(e_l, 2); + + d1_l = sparse(m,1); + d1_l(1:3) = 1/h*[-3/2 2 -1/2]; + d1_r = -rot90(d1_l, 2); + + d2_l = sparse(m,1); + d2_l(1:3) = 1/h^2*[1 -2 1]; + d2_r = rot90(d2_l, 2); + + d3_l = sparse(m,1); + d3_l(1:4) = 1/h^3*[-1 3 -3 1]; + d3_r = -rot90(d3_l, 2); + + + % First derivative SBP operator, 1st order accurate at first 6 boundary points + stencil = [-1/2, 0, 1/2]; + diags = [-1 0 1]; + Q = stripeMatrix(stencil, diags, m); + + D1 = HI*(Q - 1/2*e_l*e_l' + 1/2*e_r*e_r'); + + % Second derivative, 1st order accurate at first boundary points + M = sparse(m,m); + + scheme_width = 3; + scheme_radius = (scheme_width-1)/2; + r = (1+scheme_radius):(m-scheme_radius); + + function D2 = D2_fun(c) + Mm1 = -c(r-1)/2 - c(r)/2; + M0 = c(r-1)/2 + c(r) + c(r+1)/2; + Mp1 = -c(r)/2 - c(r+1)/2; + + M(r,:) = spdiags([Mm1 M0 Mp1],0:2*scheme_radius,length(r),m); + + M(1:2,1:2) = [c(1)/2 + c(2)/2 -c(1)/2 - c(2)/2; -c(1)/2 - c(2)/2 c(1)/2 + c(2) + c(3)/2;]; + M(m-1:m,m-1:m) = [c(m-2)/2 + c(m-1) + c(m)/2 -c(m-1)/2 - c(m)/2; -c(m-1)/2 - c(m)/2 c(m-1)/2 + c(m)/2;]; + M = 1/h*M; + + D2 = HI*(-M - c(1)*e_l*d1_l' + c(m)*e_r*d1_r'); + end + D2 = @D2_fun; + + % Fourth derivative, 0th order accurate at first 6 boundary points + stencil = [1, -4, 6, -4, 1]; + diags = -2:2; + M4 = stripeMatrix(stencil, diags, m); + + M4_U = [ + 0.13e2/0.10e2 -0.12e2/0.5e1 0.9e1/0.10e2 0.1e1/0.5e1; + -0.12e2/0.5e1 0.26e2/0.5e1 -0.16e2/0.5e1 0.2e1/0.5e1; + 0.9e1/0.10e2 -0.16e2/0.5e1 0.47e2/0.10e2 -0.17e2/0.5e1; + 0.1e1/0.5e1 0.2e1/0.5e1 -0.17e2/0.5e1 0.29e2/0.5e1; + ]; + + M4(1:4,1:4) = M4_U; + M4(m-3:m,m-3:m) = rot90(M4_U, 2); + M4 = 1/h^3*M4; + + D4=HI*(M4 - e_l*d3_l'+e_r*d3_r' + d1_l*d2_l'-d1_r*d2_r'); +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/+implementations/d4_variable_4.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,171 @@ +function [H, HI, D1, D2, D4, e_l, e_r, M4, d2_l, d2_r, d3_l, d3_r, d1_l, d1_r] = d4_variable_4(m,h) + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%% 4:de ordn. SBP Finita differens %%% + %%% %%% + %%% H (Normen) %%% + %%% D1=H^(-1)Q (approx f?rsta derivatan) %%% + %%% D2 (approx andra derivatan) %%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + BP = 6; + if(m<2*BP) + error(['Operator requires at least ' num2str(2*BP) ' grid points']); + end + + % Norm + Hv = ones(m,1); + Hv(1:4) = [17/48 59/48 43/48 49/48]; + Hv(m-3:m) = rot90(Hv(1:4),2); + Hv = h*Hv; + H = spdiag(Hv, 0); + HI = spdiag(1./Hv, 0); + + + % Boundary operators + e_l = sparse(m,1); + e_l(1) = 1; + e_r = rot90(e_l, 2); + + d1_l = sparse(m,1); + d1_l(1:4) = 1/h*[-11/6 3 -3/2 1/3]; + d1_r = -rot90(d1_l, 2); + + d2_l = sparse(m,1); + d2_l(1:4) = 1/h^2*[2 -5 4 -1]; + d2_r = rot90(d2_l, 2); + + d3_l = sparse(m,1); + d3_l(1:4) = 1/h^3*[-1 3 -3 1]; + d3_r = -rot90(d3_l, 2); + + + % First derivative SBP operator, + stencil = [1/12 -2/3 0 2/3 -1/12]; + diags = -2:2; + + Q_U = [ + 0 0.59e2/0.96e2 -0.1e1/0.12e2 -0.1e1/0.32e2; + -0.59e2/0.96e2 0 0.59e2/0.96e2 0; + 0.1e1/0.12e2 -0.59e2/0.96e2 0 0.59e2/0.96e2; + 0.1e1/0.32e2 0 -0.59e2/0.96e2 0; + ]; + + Q = stripeMatrix(stencil, diags, m); + Q(1:4,1:4)=Q_U; + Q(m-3:m,m-3:m) = -rot90(Q_U, 2); + + D1 = HI*(Q - 1/2*e_l*e_l' + 1/2*e_r*e_r'); + + + % Second derivative + M = sparse(m,m); + + scheme_width = 5; + scheme_radius = (scheme_width-1)/2; + r = (1+scheme_radius):(m-scheme_radius); + + function D2 = D2_fun(c) + Mm2 = c(r-2)/0.8e1 - c(r-1)/0.6e1 + c(r) /0.8e1 ; + Mm1 = -c(r-2)/0.6e1 - c(r-1)/0.2e1 - c(r) /0.2e1 - c(r+1)/0.6e1 ; + M0 = c(r-2)/2.4e1 + c(r-1)/1.2e0 + c(r)*0.3/0.4 + c(r+1)/1.2e0 + c(r+2)/2.4e1; + Mp1 = -c(r-1)/0.6e1 - c(r) /0.2e1 - c(r+1)/0.2e1 - c(r+2)/0.6e1; + Mp2 = c(r) /0.8e1 - c(r+1)/0.6e1 + c(r+2)/0.8e1; + + M(r,:) = spdiags([Mm2 Mm1 M0 Mp1 Mp2],0:2*scheme_radius,length(r),m); + + M(1:6,1:6) = [ + 0.12e2/0.17e2 * c(1) + 0.59e2/0.192e3 * c(2) + 0.27010400129e11/0.345067064608e12 * c(3) + 0.69462376031e11/0.2070402387648e13 * c(4) -0.59e2/0.68e2 * c(1) - 0.6025413881e10/0.21126554976e11 * c(3) - 0.537416663e9/0.7042184992e10 * c(4) 0.2e1/0.17e2 * c(1) - 0.59e2/0.192e3 * c(2) + 0.213318005e9/0.16049630912e11 * c(4) + 0.2083938599e10/0.8024815456e10 * c(3) 0.3e1/0.68e2 * c(1) - 0.1244724001e10/0.21126554976e11 * c(3) + 0.752806667e9/0.21126554976e11 * c(4) 0.49579087e8/0.10149031312e11 * c(3) - 0.49579087e8/0.10149031312e11 * c(4) -c(4)/0.784e3 + c(3)/0.784e3; + -0.59e2/0.68e2 * c(1) - 0.6025413881e10/0.21126554976e11 * c(3) - 0.537416663e9/0.7042184992e10 * c(4) 0.3481e4/0.3264e4 * c(1) + 0.9258282831623875e16/0.7669235228057664e16 * c(3) + 0.236024329996203e15/0.1278205871342944e16 * c(4) -0.59e2/0.408e3 * c(1) - 0.29294615794607e14/0.29725717938208e14 * c(3) - 0.2944673881023e13/0.29725717938208e14 * c(4) -0.59e2/0.1088e4 * c(1) + 0.260297319232891e15/0.2556411742685888e16 * c(3) - 0.60834186813841e14/0.1278205871342944e16 * c(4) -0.1328188692663e13/0.37594290333616e14 * c(3) + 0.1328188692663e13/0.37594290333616e14 * c(4) -0.8673e4/0.2904112e7 * c(3) + 0.8673e4/0.2904112e7 * c(4); + 0.2e1/0.17e2 * c(1) - 0.59e2/0.192e3 * c(2) + 0.213318005e9/0.16049630912e11 * c(4) + 0.2083938599e10/0.8024815456e10 * c(3) -0.59e2/0.408e3 * c(1) - 0.29294615794607e14/0.29725717938208e14 * c(3) - 0.2944673881023e13/0.29725717938208e14 * c(4) c(1)/0.51e2 + 0.59e2/0.192e3 * c(2) + 0.13777050223300597e17/0.26218083221499456e17 * c(4) + 0.564461e6/0.13384296e8 * c(5) + 0.378288882302546512209e21/0.270764341349677687456e21 * c(3) c(1)/0.136e3 - 0.125059e6/0.743572e6 * c(5) - 0.4836340090442187227e19/0.5525802884687299744e19 * c(3) - 0.17220493277981e14/0.89177153814624e14 * c(4) -0.10532412077335e14/0.42840005263888e14 * c(4) + 0.1613976761032884305e19/0.7963657098519931984e19 * c(3) + 0.564461e6/0.4461432e7 * c(5) -0.960119e6/0.1280713392e10 * c(4) - 0.3391e4/0.6692148e7 * c(5) + 0.33235054191e11/0.26452850508784e14 * c(3); + 0.3e1/0.68e2 * c(1) - 0.1244724001e10/0.21126554976e11 * c(3) + 0.752806667e9/0.21126554976e11 * c(4) -0.59e2/0.1088e4 * c(1) + 0.260297319232891e15/0.2556411742685888e16 * c(3) - 0.60834186813841e14/0.1278205871342944e16 * c(4) c(1)/0.136e3 - 0.125059e6/0.743572e6 * c(5) - 0.4836340090442187227e19/0.5525802884687299744e19 * c(3) - 0.17220493277981e14/0.89177153814624e14 * c(4) 0.3e1/0.1088e4 * c(1) + 0.507284006600757858213e21/0.475219048083107777984e21 * c(3) + 0.1869103e7/0.2230716e7 * c(5) + c(6)/0.24e2 + 0.1950062198436997e16/0.3834617614028832e16 * c(4) -0.4959271814984644613e19/0.20965546238960637264e20 * c(3) - c(6)/0.6e1 - 0.15998714909649e14/0.37594290333616e14 * c(4) - 0.375177e6/0.743572e6 * c(5) -0.368395e6/0.2230716e7 * c(5) + 0.752806667e9/0.539854092016e12 * c(3) + 0.1063649e7/0.8712336e7 * c(4) + c(6)/0.8e1; + 0.49579087e8/0.10149031312e11 * c(3) - 0.49579087e8/0.10149031312e11 * c(4) -0.1328188692663e13/0.37594290333616e14 * c(3) + 0.1328188692663e13/0.37594290333616e14 * c(4) -0.10532412077335e14/0.42840005263888e14 * c(4) + 0.1613976761032884305e19/0.7963657098519931984e19 * c(3) + 0.564461e6/0.4461432e7 * c(5) -0.4959271814984644613e19/0.20965546238960637264e20 * c(3) - c(6)/0.6e1 - 0.15998714909649e14/0.37594290333616e14 * c(4) - 0.375177e6/0.743572e6 * c(5) 0.8386761355510099813e19/0.128413970713633903242e21 * c(3) + 0.2224717261773437e16/0.2763180339520776e16 * c(4) + 0.5e1/0.6e1 * c(6) + c(7)/0.24e2 + 0.280535e6/0.371786e6 * c(5) -0.35039615e8/0.213452232e9 * c(4) - c(7)/0.6e1 - 0.13091810925e11/0.13226425254392e14 * c(3) - 0.1118749e7/0.2230716e7 * c(5) - c(6)/0.2e1; + -c(4)/0.784e3 + c(3)/0.784e3 -0.8673e4/0.2904112e7 * c(3) + 0.8673e4/0.2904112e7 * c(4) -0.960119e6/0.1280713392e10 * c(4) - 0.3391e4/0.6692148e7 * c(5) + 0.33235054191e11/0.26452850508784e14 * c(3) -0.368395e6/0.2230716e7 * c(5) + 0.752806667e9/0.539854092016e12 * c(3) + 0.1063649e7/0.8712336e7 * c(4) + c(6)/0.8e1 -0.35039615e8/0.213452232e9 * c(4) - c(7)/0.6e1 - 0.13091810925e11/0.13226425254392e14 * c(3) - 0.1118749e7/0.2230716e7 * c(5) - c(6)/0.2e1 0.3290636e7/0.80044587e8 * c(4) + 0.5580181e7/0.6692148e7 * c(5) + 0.5e1/0.6e1 * c(7) + c(8)/0.24e2 + 0.660204843e9/0.13226425254392e14 * c(3) + 0.3e1/0.4e1 * c(6); + ]; + + M(m-5:m,m-5:m) = [ + c(m-7)/0.24e2 + 0.5e1/0.6e1 * c(m-6) + 0.5580181e7/0.6692148e7 * c(m-4) + 0.4887707739997e13/0.119037827289528e15 * c(m-3) + 0.3e1/0.4e1 * c(m-5) + 0.660204843e9/0.13226425254392e14 * c(m-2) + 0.660204843e9/0.13226425254392e14 * c(m-1) -c(m-6)/0.6e1 - 0.1618585929605e13/0.9919818940794e13 * c(m-3) - c(m-5)/0.2e1 - 0.1118749e7/0.2230716e7 * c(m-4) - 0.13091810925e11/0.13226425254392e14 * c(m-2) - 0.13091810925e11/0.13226425254392e14 * c(m-1) -0.368395e6/0.2230716e7 * c(m-4) + c(m-5)/0.8e1 + 0.48866620889e11/0.404890569012e12 * c(m-3) + 0.752806667e9/0.539854092016e12 * c(m-2) + 0.752806667e9/0.539854092016e12 * c(m-1) -0.3391e4/0.6692148e7 * c(m-4) - 0.238797444493e12/0.119037827289528e15 * c(m-3) + 0.33235054191e11/0.26452850508784e14 * c(m-2) + 0.33235054191e11/0.26452850508784e14 * c(m-1) -0.8673e4/0.2904112e7 * c(m-2) - 0.8673e4/0.2904112e7 * c(m-1) + 0.8673e4/0.1452056e7 * c(m-3) -c(m-3)/0.392e3 + c(m-2)/0.784e3 + c(m-1)/0.784e3; + -c(m-6)/0.6e1 - 0.1618585929605e13/0.9919818940794e13 * c(m-3) - c(m-5)/0.2e1 - 0.1118749e7/0.2230716e7 * c(m-4) - 0.13091810925e11/0.13226425254392e14 * c(m-2) - 0.13091810925e11/0.13226425254392e14 * c(m-1) c(m-6)/0.24e2 + 0.5e1/0.6e1 * c(m-5) + 0.3896014498639e13/0.4959909470397e13 * c(m-3) + 0.8386761355510099813e19/0.128413970713633903242e21 * c(m-2) + 0.280535e6/0.371786e6 * c(m-4) + 0.3360696339136261875e19/0.171218627618178537656e21 * c(m-1) -c(m-5)/0.6e1 - 0.4959271814984644613e19/0.20965546238960637264e20 * c(m-2) - 0.375177e6/0.743572e6 * c(m-4) - 0.13425842714e11/0.33740880751e11 * c(m-3) - 0.193247108773400725e18/0.6988515412986879088e19 * c(m-1) -0.365281640980e12/0.1653303156799e13 * c(m-3) + 0.564461e6/0.4461432e7 * c(m-4) + 0.1613976761032884305e19/0.7963657098519931984e19 * c(m-2) - 0.198407225513315475e18/0.7963657098519931984e19 * c(m-1) -0.1328188692663e13/0.37594290333616e14 * c(m-2) + 0.2226377963775e13/0.37594290333616e14 * c(m-1) - 0.8673e4/0.363014e6 * c(m-3) c(m-3)/0.49e2 + 0.49579087e8/0.10149031312e11 * c(m-2) - 0.256702175e9/0.10149031312e11 * c(m-1); + -0.368395e6/0.2230716e7 * c(m-4) + c(m-5)/0.8e1 + 0.48866620889e11/0.404890569012e12 * c(m-3) + 0.752806667e9/0.539854092016e12 * c(m-2) + 0.752806667e9/0.539854092016e12 * c(m-1) -c(m-5)/0.6e1 - 0.4959271814984644613e19/0.20965546238960637264e20 * c(m-2) - 0.375177e6/0.743572e6 * c(m-4) - 0.13425842714e11/0.33740880751e11 * c(m-3) - 0.193247108773400725e18/0.6988515412986879088e19 * c(m-1) c(m-5)/0.24e2 + 0.1869103e7/0.2230716e7 * c(m-4) + 0.507284006600757858213e21/0.475219048083107777984e21 * c(m-2) + 0.3e1/0.1088e4 * c(m) + 0.31688435395e11/0.67481761502e11 * c(m-3) + 0.27769176016102795561e20/0.712828572124661666976e21 * c(m-1) -0.125059e6/0.743572e6 * c(m-4) + c(m)/0.136e3 - 0.23099342648e11/0.101222642253e12 * c(m-3) - 0.4836340090442187227e19/0.5525802884687299744e19 * c(m-2) + 0.193950157930938693e18/0.5525802884687299744e19 * c(m-1) 0.260297319232891e15/0.2556411742685888e16 * c(m-2) - 0.59e2/0.1088e4 * c(m) - 0.106641839640553e15/0.1278205871342944e16 * c(m-1) + 0.26019e5/0.726028e6 * c(m-3) -0.1244724001e10/0.21126554976e11 * c(m-2) + 0.3e1/0.68e2 * c(m) + 0.752806667e9/0.21126554976e11 * c(m-1); + -0.3391e4/0.6692148e7 * c(m-4) - 0.238797444493e12/0.119037827289528e15 * c(m-3) + 0.33235054191e11/0.26452850508784e14 * c(m-2) + 0.33235054191e11/0.26452850508784e14 * c(m-1) -0.365281640980e12/0.1653303156799e13 * c(m-3) + 0.564461e6/0.4461432e7 * c(m-4) + 0.1613976761032884305e19/0.7963657098519931984e19 * c(m-2) - 0.198407225513315475e18/0.7963657098519931984e19 * c(m-1) -0.125059e6/0.743572e6 * c(m-4) + c(m)/0.136e3 - 0.23099342648e11/0.101222642253e12 * c(m-3) - 0.4836340090442187227e19/0.5525802884687299744e19 * c(m-2) + 0.193950157930938693e18/0.5525802884687299744e19 * c(m-1) 0.564461e6/0.13384296e8 * c(m-4) + 0.470299699916357e15/0.952302618316224e15 * c(m-3) + 0.550597048646198778781e21/0.1624586048098066124736e22 * c(m-1) + c(m)/0.51e2 + 0.378288882302546512209e21/0.270764341349677687456e21 * c(m-2) -0.59e2/0.408e3 * c(m) - 0.29294615794607e14/0.29725717938208e14 * c(m-2) - 0.2234477713167e13/0.29725717938208e14 * c(m-1) - 0.8673e4/0.363014e6 * c(m-3) -0.59e2/0.3136e4 * c(m-3) - 0.13249937023e11/0.48148892736e11 * c(m-1) + 0.2e1/0.17e2 * c(m) + 0.2083938599e10/0.8024815456e10 * c(m-2); + -0.8673e4/0.2904112e7 * c(m-2) - 0.8673e4/0.2904112e7 * c(m-1) + 0.8673e4/0.1452056e7 * c(m-3) -0.1328188692663e13/0.37594290333616e14 * c(m-2) + 0.2226377963775e13/0.37594290333616e14 * c(m-1) - 0.8673e4/0.363014e6 * c(m-3) 0.260297319232891e15/0.2556411742685888e16 * c(m-2) - 0.59e2/0.1088e4 * c(m) - 0.106641839640553e15/0.1278205871342944e16 * c(m-1) + 0.26019e5/0.726028e6 * c(m-3) -0.59e2/0.408e3 * c(m) - 0.29294615794607e14/0.29725717938208e14 * c(m-2) - 0.2234477713167e13/0.29725717938208e14 * c(m-1) - 0.8673e4/0.363014e6 * c(m-3) 0.9258282831623875e16/0.7669235228057664e16 * c(m-2) + 0.3481e4/0.3264e4 * c(m) + 0.228389721191751e15/0.1278205871342944e16 * c(m-1) + 0.8673e4/0.1452056e7 * c(m-3) -0.6025413881e10/0.21126554976e11 * c(m-2) - 0.59e2/0.68e2 * c(m) - 0.537416663e9/0.7042184992e10 * c(m-1); + -c(m-3)/0.392e3 + c(m-2)/0.784e3 + c(m-1)/0.784e3 c(m-3)/0.49e2 + 0.49579087e8/0.10149031312e11 * c(m-2) - 0.256702175e9/0.10149031312e11 * c(m-1) -0.1244724001e10/0.21126554976e11 * c(m-2) + 0.3e1/0.68e2 * c(m) + 0.752806667e9/0.21126554976e11 * c(m-1) -0.59e2/0.3136e4 * c(m-3) - 0.13249937023e11/0.48148892736e11 * c(m-1) + 0.2e1/0.17e2 * c(m) + 0.2083938599e10/0.8024815456e10 * c(m-2) -0.6025413881e10/0.21126554976e11 * c(m-2) - 0.59e2/0.68e2 * c(m) - 0.537416663e9/0.7042184992e10 * c(m-1) 0.3e1/0.3136e4 * c(m-3) + 0.27010400129e11/0.345067064608e12 * c(m-2) + 0.234566387291e12/0.690134129216e12 * c(m-1) + 0.12e2/0.17e2 * c(m); + ]; + + M = M/h; + D2 = HI*(-M - c(1)*e_l*d1_l' + c(m)*e_r*d1_r'); + end + D2 = @D2_fun; + + + % Fourth derivative + stencil = [-1/6,2,-13/2, 28/3,-13/2,2,-1/6]; + diags = -3:3; + M4 = stripeMatrix(stencil, diags, m); + + M4_U = [ + 0.5762947e7/0.2316384e7 -0.6374287e7/0.1158192e7 0.573947e6/0.165456e6 -0.124637e6/0.289548e6 0.67979e5/0.2316384e7 -0.60257e5/0.1158192e7; + -0.6374287e7/0.1158192e7 0.30392389e8/0.2316384e7 -0.2735053e7/0.289548e6 0.273109e6/0.165456e6 0.83767e5/0.1158192e7 0.245549e6/0.2316384e7; + 0.573947e6/0.165456e6 -0.2735053e7/0.289548e6 0.5266855e7/0.579096e6 -0.1099715e7/0.289548e6 0.869293e6/0.1158192e7 -0.10195e5/0.144774e6; + -0.124637e6/0.289548e6 0.273109e6/0.165456e6 -0.1099715e7/0.289548e6 0.3259225e7/0.579096e6 -0.324229e6/0.72387e5 0.1847891e7/0.1158192e7; + 0.67979e5/0.2316384e7 0.83767e5/0.1158192e7 0.869293e6/0.1158192e7 -0.324229e6/0.72387e5 0.2626501e7/0.330912e6 -0.7115491e7/0.1158192e7; + -0.60257e5/0.1158192e7 0.245549e6/0.2316384e7 -0.10195e5/0.144774e6 0.1847891e7/0.1158192e7 -0.7115491e7/0.1158192e7 0.21383077e8/0.2316384e7; + ]; + + M4(1:6,1:6) = M4_U; + M4(m-5:m,m-5:m) = rot90(M4_U, 2); + M4 = 1/h^3*M4; + + D4=HI*(M4 - e_l*d3_l'+e_r*d3_r' + d1_l*d2_l'-d1_r*d2_r'); +end + + +% Alternatives for variable 2nd derivative + % % ALTERNATIVES %%%%%%%%%%%%% + % % for i=4:m-3 + % % M(i,i-2:i+2)=[-c(i-1)/0.6e1 + c(i-2)/0.8e1 + c(i)/0.8e1 -c(i-2)/0.6e1 - c(i+1)/0.6e1 - c(i-1)/0.2e1 - c(i)/0.2e1 c(i-2)/0.24e2 + 0.5e1/0.6e1 * c(i-1) + 0.5e1/0.6e1 * c(i+1) + c(i+2)/0.24e2 + 0.3e1/0.4e1 * c(i) -c(i-1)/0.6e1 - c(i+2)/0.6e1 - c(i)/0.2e1 - c(i+1)/0.2e1 -c(i+1)/0.6e1 + c(i)/0.8e1 + c(i+2)/0.8e1;]; + % % end + % %%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % % for i=4:m-3 + % % M(i,i-2:i+2)= [ + % % c(i-2)/0.8e1 - c(i-1)/0.6e1 + c(i) /0.8e1 , + % % -c(i-2)/0.6e1 - c(i-1)/0.2e1 - c(i) /0.2e1 - c(i+1)/0.6e1 , + % % c(i-2)/2.4e1 + c(i-1)/1.2e0 + c(i) * 0.3/0.4 + c(i+1)/1.2e0 + c(i+2)/2.4e1 , + % % -c(i-1)/0.6e1 - c(i) /0.2e1 - c(i+1)/0.2e1 - c(i+2)/0.6e1 , + % % c(i) /0.8e1 - c(i+1)/0.6e1 + c(i+2)/0.8e1 , + % % ]; + % % end + % %%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Mm2 = c(r-2)/0.8e1 - c(r-1)/0.6e1 + c(r) /0.8e1 ; + % Mm1 = -c(r-2)/0.6e1 - c(r-1)/0.2e1 - c(r) /0.2e1 - c(r+1)/0.6e1 ; + % M0 = c(r-2)/2.4e1 + c(r-1)/1.2e0 + c(r) * 0.3/0.4 + c(r+1)/1.2e0 + c(r+2)/2.4e1; + % Mp1 = -c(r-1)/0.6e1 - c(r) /0.2e1 - c(r+1)/0.2e1 - c(r+2)/0.6e1; + % Mp2 = c(r) /0.8e1 - c(r+1)/0.6e1 + c(r+2)/0.8e1; + + % M(r,:) = spdiags([Mm2 Mm1 M0 Mp1 Mp2],0:2*scheme_radius,length(r),m); + % % M(r,:) = spdiags([Mm2 Mm1 M0 Mp1 Mp2],(-2:2)+scheme_radius,M(r,:)); % This is slower + % %%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % % %% Somthing is wrong here!! + % % Mm2 = c(r-2)/0.8e1 - c(r-1)/0.6e1 + c(r) /0.8e1 ; + % % Mm1 = -c(r-2)/0.6e1 - c(r-1)/0.2e1 - c(r) /0.2e1 - c(r+1)/0.6e1 ; + % % M0 = c(r-2)/2.4e1 + c(r-1)/1.2e0 + c(r) * 0.3/0.4 + c(r+1)/1.2e0 + c(r+2)/2.4e1; + % % Mp1 = -c(r-1)/0.6e1 - c(r) /0.2e1 - c(r+1)/0.2e1 - c(r+2)/0.6e1; + % % Mp2 = c(r) /0.8e1 - c(r+1)/0.6e1 + c(r+2)/0.8e1; + % % % printSize(M_diag_ind); + % % % Mdiags = [Mm2 Mm1 M0 Mp1 Mp2]; + % % % printSize(Mdiags); + % % M(M_diag_ind) = [Mm2 Mm1 M0 Mp1 Mp2]; % This is slightly faster + % %%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % % Kan man skriva det som en multiplikation av en 3-dim matris? + % %%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + + + + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/+implementations/d4_variable_6.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,158 @@ +function [H, HI, D1, D2, D4, e_l, e_r, M4, d2_l, d2_r, d3_l, d3_r, d1_l, d1_r] = d4_variable_6(m,h) + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %%% 6:te ordn. SBP Finita differens %%% + %%% operatorer med diagonal norm %%% + %%% Extension to variable koeff %%% + %%% %%% + %%% H (Normen) %%% + %%% D1=H^(-1)Q (approx f?rsta derivatan) %%% + %%% D2 (approx andra derivatan) %%% + %%% D2=HI*(R+C*D*S %%% + %%% %%% + %%% R=-D1'*H*C*D1-RR %%% + %%% %%% + %%% RR ?r dissipation) %%% + %%% Dissipationen uppbyggd av D4: %%% + %%% DI=D4*B*H*D4 %%% + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + BP = 9; + if(m<2*BP) + error(['Operator requires at least ' num2str(2*BP) ' grid points']); + end + + % Norm + Hv = ones(m,1); + Hv(1:6) = [13649/43200,12013/8640,2711/4320,5359/4320,7877/8640, 43801/43200]; + Hv(m-5:m) = rot90(Hv(1:6),2); + Hv = h*Hv; + H = spdiag(Hv, 0); + HI = spdiag(1./Hv, 0); + + + % Boundary operators + e_l = sparse(m,1); + e_l(1) = 1; + e_r = rot90(e_l, 2); + + d1_l = sparse(m,1); + d1_l(1:5) = [-25/12, 4, -3, 4/3, -1/4]/h; + d1_r = -rot90(d1_l, 2); + + d2_l = sparse(m,1); + d2_l(1:5) = [0.35e2/0.12e2 -0.26e2/0.3e1 0.19e2/0.2e1 -0.14e2/0.3e1 0.11e2/0.12e2;]/h^2; + d2_r = rot90(d2_l, 2); + + d3_l = sparse(m,1); + d3_l(1:5) = [-5/2 9 -12 7 -3/2]/h^3; + d3_r = -rot90(d3_l, 2); + + + % First derivtive + x1=0.70127127127127; + + + D1=(1/60*diag(ones(m-3,1),3)-9/60*diag(ones(m-2,1),2)+45/60*diag(ones(m-1,1),1)-45/60*diag(ones(m-1,1),-1)+9/60*diag(ones(m-2,1),-2)-1/60*diag(ones(m-3,1),-3)); + + + + D1(1:6,1:9)=[-21600/13649, 43200/13649*x1-7624/40947, -172800/13649*x1+ ... + 715489/81894, 259200/13649*x1-187917/13649, -172800/13649* ... + x1+735635/81894, 43200/13649*x1-89387/40947, 0, 0, 0; ... + -8640/12013*x1+7624/180195, 0, 86400/12013*x1-57139/12013, ... + -172800/12013*x1+745733/72078, 129600/12013*x1-91715/12013, ... + -34560/12013*x1+240569/120130, 0, 0, 0; ... + 17280/2711*x1-715489/162660, -43200/2711*x1+57139/5422, 0, ... + 86400/2711*x1-176839/8133, -86400/2711*x1+242111/10844, ... + 25920/2711*x1-182261/27110, 0, 0, 0; ... + -25920/5359*x1+187917/53590, 86400/5359*x1-745733/64308, ... + -86400/5359*x1+176839/16077, 0, 43200/5359*x1-165041/32154, ... + -17280/5359*x1+710473/321540, 72/5359, 0, 0; ... + 34560/7877*x1-147127/47262, -129600/7877*x1+91715/7877, ... + 172800/7877*x1-242111/15754, -86400/7877*x1+165041/23631, ... + 0, 8640/7877*x1, -1296/7877, 144/7877, 0; ... + -43200/43801*x1+89387/131403, 172800/43801*x1-240569/87602,... + -259200/43801*x1+182261/43801, 172800/43801*x1-710473/262806, ... + -43200/43801*x1, 0, 32400/43801, -6480/43801, 720/43801]; + D1(m-5:m,m-8:m)=rot90( -D1(1:6,1:9),2); + D1=D1/h; + + + % Second derivative + M=sparse(m,m); + + scheme_width = 7; + scheme_radius = (scheme_width-1)/2; + r = (1+scheme_radius):(m-scheme_radius); + + function D2 = D2_fun(c) + + Mm3 = c(r-2)/0.40e2 + c(r-1)/0.40e2 - 0.11e2/0.360e3 * c(r-3) - 0.11e2/0.360e3 * c(r); + Mm2 = c(r-3)/0.20e2 - 0.3e1/0.10e2 * c(r-1) + c(r+1)/0.20e2 + 0.7e1/0.40e2 * c(r) + 0.7e1/0.40e2 * c(r-2); + Mm1 = -c(r-3)/0.40e2 - 0.3e1/0.10e2 * c(r-2) - 0.3e1/0.10e2 * c(r+1) - c(r+2)/0.40e2 - 0.17e2/0.40e2 * c(r) - 0.17e2/0.40e2 * c(r-1); + M0 = c(r-3)/0.180e3 + c(r-2)/0.8e1 + 0.19e2/0.20e2 * c(r-1) + 0.19e2/0.20e2 * c(r+1) + c(r+2)/0.8e1 + c(r+3)/0.180e3 + 0.101e3/0.180e3 * c(r); + Mp1 = -c(r-2)/0.40e2 - 0.3e1/0.10e2 * c(r-1) - 0.3e1/0.10e2 * c(r+2) - c(r+3)/0.40e2 - 0.17e2/0.40e2 * c(r) - 0.17e2/0.40e2 * c(r+1); + Mp2 = c(r-1)/0.20e2 - 0.3e1/0.10e2 * c(r+1) + c(r+3)/0.20e2 + 0.7e1/0.40e2 * c(r) + 0.7e1/0.40e2 * c(r+2); + Mp3 = c(r+1)/0.40e2 + c(r+2)/0.40e2 - 0.11e2/0.360e3 * c(r) - 0.11e2/0.360e3 * c(r+3); + + M(r,:) = spdiags([Mm3 Mm2 Mm1 M0 Mp1 Mp2 Mp3],0:2*scheme_radius,length(r),m); + + + M(1:9,1:9)=[ + 0.7912667594695582093926295e0 * c(1) + 0.2968472090638000742888467e0 * c(2) + 0.3185519088796429015220016e-2 * c(3) + 0.1632404042590951953384672e-1 * c(4) + 0.3160302244094415087693968e-1 * c(5) + 0.3167964748016105299646518e-1 * c(6) + 0.3148577733947253920469418e-1 * c(7) -0.1016689339350338144430605e1 * c(1) - 0.2845627370491611369031341e-1 * c(3) - 0.4128029838349298819825156e-1 * c(4) - 0.1392281451620140507549866e0 * c(5) - 0.1195777325611201766551392e0 * c(6) - 0.1194267756529333410855186e0 * c(7) 0.7075642937243715046279337e-1 * c(1) - 0.1845476106024151050283847e0 * c(2) - 0.4364163147111892346990101e-1 * c(4) + 0.2432367907207732460874765e0 * c(5) + 0.1582127073537215443965653e0 * c(6) + 0.1602348578364786307613271e0 * c(7) 0.2251991532891353212689574e0 * c(1) - 0.1662748711097054895317080e0 * c(2) + 0.2710530961648671297733465e-1 * c(3) - 0.1916646185968439909125616e0 * c(5) - 0.7684117160199014594442072e-1 * c(6) - 0.8219586949831697575883635e-1 * c(7) -0.5224403464202056316702078e-1 * c(1) + 0.4440063948509876221050939e-1 * c(2) - 0.1023976547309387874453988e-2 * c(3) + 0.7403484645316174090533193e-1 * c(4) + 0.1241625568998496895352046e-1 * c(6) + 0.7188652847892601282652228e-1 * c(5) + 0.1379362997104735503447960e-1 * c(7) -0.1828896813877197352675410e-1 * c(1) + 0.9574633163221758060736592e-2 * c(2) - 0.8105784530576404277872603e-3 * c(3) - 0.7348845587775519698437916e-2 * c(4) + 0.1063601949723906997026904e-1 * c(5) - 0.1315967038382618382356495e-1 * c(6) - 0.2117936478838753524581943e-1 * c(7) 0.1911888563316170927411831e-2 * c(4) - 0.4068130355529149936100229e-1 * c(5) + 0.1319674981073749167009902e-1 * c(6) + 0.2557266518123783676349144e-1 * c(7) 0.1559652871136785763960685e-1 * c(5) - 0.6486184157331537899459796e-2 * c(6) - 0.9110344554036319740147054e-2 * c(7) 0.5593983696629863059347067e-3 * c(6) - 0.1384822535100796372263822e-2 * c(5) + 0.8254241654378100663291154e-3 * c(7); + -0.1016689339350338144430605e1 * c(1) - 0.2845627370491611369031341e-1 * c(3) - 0.4128029838349298819825156e-1 * c(4) - 0.1392281451620140507549866e0 * c(5) - 0.1195777325611201766551392e0 * c(6) - 0.1194267756529333410855186e0 * c(7) 0.1306332157111667628555907e1 * c(1) + 0.2542001760457345743492403e0 * c(3) + 0.1043897828092562609502636e0 * c(4) + 0.6672328021032112950919876e0 * c(5) + 0.4681819359722749441073885e0 * c(6) + 0.4676415410195836920069412e0 * c(7) -0.9091410269992464604926176e-1 * c(1) + 0.1103611313171476425250639e0 * c(4) - 0.1290397544997518887000350e1 * c(5) - 0.6639605248735044787146222e0 * c(6) - 0.6615974464005206184151509e0 * c(7) -0.2893557395653431666593814e0 * c(1) - 0.2421320004064592721552708e0 * c(3) + 0.1187670255028031027693374e1 * c(5) + 0.3956598149904136332753521e0 * c(6) + 0.3860048921755800000681479e0 * c(7) 0.6712774475803763988977355e-1 * c(1) + 0.9147192682075630179962131e-2 * c(3) - 0.1872196143003808021730728e0 * c(4) - 0.1319358558853174530078498e0 * c(6) - 0.4871575736811911887376923e0 * c(5) - 0.1047516312275448138054418e0 * c(7) 0.2349927974590068869356781e-1 * c(1) + 0.7240905383565181316381731e-2 * c(3) + 0.1858378996391679448655070e-1 * c(4) - 0.9289616133938676174345208e-1 * c(5) + 0.1223513270418807666970488e0 * c(6) + 0.1113520320436295033894092e0 * c(7) -0.4834791406446907590553793e-2 * c(4) + 0.2310683832687820403062715e0 * c(5) - 0.1080774142196007991746827e0 * c(6) - 0.1181561776427343335410349e0 * c(7) -0.8368141434403455353724691e-1 * c(5) + 0.4093499466767054661591066e-1 * c(6) + 0.4274641967636400692133626e-1 * c(7) -0.3576545132696983143406173e-2 * c(6) + 0.7389399124121078682094445e-2 * c(5) - 0.3812853991424095538688273e-2 * c(7); + 0.7075642937243715046279337e-1 * c(1) - 0.1845476106024151050283847e0 * c(2) - 0.4364163147111892346990101e-1 * c(4) + 0.2432367907207732460874765e0 * c(5) + 0.1582127073537215443965653e0 * c(6) + 0.1602348578364786307613271e0 * c(7) -0.9091410269992464604926176e-1 * c(1) + 0.1103611313171476425250639e0 * c(4) - 0.1290397544997518887000350e1 * c(5) - 0.6639605248735044787146222e0 * c(6) - 0.6615974464005206184151509e0 * c(7) 0.6327161147136873807796515e-2 * c(1) + 0.1147318200715868527529827e0 * c(2) + 0.1166740554279680007487795e0 * c(4) + 0.2766610808285444037240703e1 * c(5) + 0.1070920689960817104203947e1 * c(6) + 0.1013161391032973057171717e1 * c(7) 0.2013769413884797246646959e-1 * c(1) + 0.1033717994630886401730470e0 * c(2) - 0.2913221621151742724258117e1 * c(5) - 0.8755807343482262259774782e0 * c(6) - 0.6909957183488812426508351e0 * c(7) -0.4671751091575462868310238e-2 * c(1) - 0.2760353365637712827793337e-1 * c(2) - 0.1979290298620869974478871e0 * c(4) + 0.5402985338373433052255418e0 * c(6) + 0.1239177593031911077924537e1 * c(5) + 0.2628038050247358227280031e0 * c(7) -0.1635430866921887819487473e-2 * c(1) - 0.5952475275883259619711594e-2 * c(2) + 0.1964682777744275219350831e-1 * c(4) + 0.3236640012639046600590714e0 * c(5) - 0.4659516693228870973898560e0 * c(6) - 0.2217272720941736859420432e0 * c(7) -0.5111353189352474549563559e-2 * c(4) - 0.5355878163774754346032096e0 * c(5) + 0.3328335104489738933610597e0 * c(6) + 0.2078656591178540157917135e0 * c(7) 0.1824328174134289562208038e0 * c(5) - 0.1059816030196818445908057e0 * c(6) - 0.7645121439374711162999809e-1 * c(7) 0.9209089963443799485648361e-2 * c(6) - 0.1591502818872493167091475e-1 * c(5) + 0.6705938225281132185266388e-2 * c(7); + 0.2251991532891353212689574e0 * c(1) - 0.1662748711097054895317080e0 * c(2) + 0.2710530961648671297733465e-1 * c(3) - 0.1916646185968439909125616e0 * c(5) - 0.7684117160199014594442072e-1 * c(6) - 0.8219586949831697575883635e-1 * c(7) -0.2893557395653431666593814e0 * c(1) - 0.2421320004064592721552708e0 * c(3) + 0.1187670255028031027693374e1 * c(5) + 0.3956598149904136332753521e0 * c(6) + 0.3860048921755800000681479e0 * c(7) 0.2013769413884797246646959e-1 * c(1) + 0.1033717994630886401730470e0 * c(2) - 0.2913221621151742724258117e1 * c(5) - 0.8755807343482262259774782e0 * c(6) - 0.6909957183488812426508351e0 * c(7) 0.6409299775987186986730499e-1 * c(1) + 0.9313657638804699948929701e-1 * c(2) + 0.2306367624634749229113646e0 * c(3) + 0.3689440308283716620260816e1 * c(5) + 0.1190550338687608873798462e1 * c(6) + 0.5912479546888856519443605e0 * c(7) -0.1486895819265604128572498e-1 * c(1) - 0.2487040599390160764166412e-1 * c(2) - 0.8712928907711754187084757e-2 * c(3) - 0.1263507837371824205693950e1 * c(6) - 0.3058317397843997326920898e0 * c(7) - 0.1470691926045802954795783e1 * c(5) -0.5205147429855955657625694e-2 * c(1) - 0.5363098747528542488971874e-2 * c(2) - 0.6897142765790609546343709e-2 * c(3) - 0.7857524521667450101721993e0 * c(5) + 0.2291148005423734600066709e0 * c(7) + 0.9977064356292750529201981e0 * c(6) 0.6697297488067662265210608e0 * c(5) - 0.5013247356072127938999311e0 * c(6) - 0.1795161243106645437322408e0 * c(7) -0.2022909060111751565150958e0 * c(5) + 0.1453421858063658498587377e0 * c(6) + 0.5694872020480930665635812e-1 * c(7) -0.1200429618441003833696998e-1 * c(6) - 0.4776915669385923841535432e-2 * c(7) + 0.1678121185379596217850541e-1 * c(5); + -0.5224403464202056316702078e-1 * c(1) + 0.4440063948509876221050939e-1 * c(2) - 0.1023976547309387874453988e-2 * c(3) + 0.7403484645316174090533193e-1 * c(4) + 0.1241625568998496895352046e-1 * c(6) + 0.7188652847892601282652228e-1 * c(5) + 0.1379362997104735503447960e-1 * c(7) 0.6712774475803763988977355e-1 * c(1) + 0.9147192682075630179962131e-2 * c(3) - 0.1872196143003808021730728e0 * c(4) - 0.1319358558853174530078498e0 * c(6) - 0.4871575736811911887376923e0 * c(5) - 0.1047516312275448138054418e0 * c(7) -0.4671751091575462868310238e-2 * c(1) - 0.2760353365637712827793337e-1 * c(2) - 0.1979290298620869974478871e0 * c(4) + 0.5402985338373433052255418e0 * c(6) + 0.1239177593031911077924537e1 * c(5) + 0.2628038050247358227280031e0 * c(7) -0.1486895819265604128572498e-1 * c(1) - 0.2487040599390160764166412e-1 * c(2) - 0.8712928907711754187084757e-2 * c(3) - 0.1263507837371824205693950e1 * c(6) - 0.3058317397843997326920898e0 * c(7) - 0.1470691926045802954795783e1 * c(5) 0.3449455095910233625229891e-2 * c(1) + 0.6641183499427826101618457e-2 * c(2) + 0.3291545083271862858501887e-3 * c(3) + 0.3357721707576477199985656e0 * c(4) + 0.2096413329579026439044119e1 * c(6) + 0.2317323204183126854954203e0 * c(7) + 0.6107825764368264576481962e-2 * c(8) + 0.7109125850683376695640722e0 * c(5) 0.1207544072304193806052558e-2 * c(1) + 0.1432116665752147607469646e-2 * c(2) + 0.2605582646183255957264249e-3 * c(3) - 0.3332941113251635390801278e-1 * c(4) - 0.2808241697385532683612407e0 * c(7) - 0.2720908083525083608370563e-1 * c(8) + 0.1045865435682921987447929e0 * c(5) - 0.1348436986667115543203552e1 * c(6) 0.8671038084174692625075159e-2 * c(4) + 0.1736073411355428563685818e0 * c(6) + 0.5331362125287625412555844e-1 * c(8) - 0.2424935262404526301801157e0 * c(5) + 0.1569015257678588270609004e0 * c(7) -0.8631683980217122275970376e-1 * c(6) + 0.2698842360470999243492629e-1 * c(7) + 0.8098194147715651085292754e-1 * c(5) - 0.3276463639080639163926118e-1 * c(8) 0.7462059484530855073291365e-2 * c(6) - 0.8121640361668678949573496e-3 * c(7) + 0.5522702088127090209264064e-3 * c(8) - 0.7202165657176696199260422e-2 * c(5); + -0.1828896813877197352675410e-1 * c(1) + 0.9574633163221758060736592e-2 * c(2) - 0.8105784530576404277872603e-3 * c(3) - 0.7348845587775519698437916e-2 * c(4) + 0.1063601949723906997026904e-1 * c(5) - 0.1315967038382618382356495e-1 * c(6) - 0.2117936478838753524581943e-1 * c(7) 0.2349927974590068869356781e-1 * c(1) + 0.7240905383565181316381731e-2 * c(3) + 0.1858378996391679448655070e-1 * c(4) - 0.9289616133938676174345208e-1 * c(5) + 0.1223513270418807666970488e0 * c(6) + 0.1113520320436295033894092e0 * c(7) -0.1635430866921887819487473e-2 * c(1) - 0.5952475275883259619711594e-2 * c(2) + 0.1964682777744275219350831e-1 * c(4) + 0.3236640012639046600590714e0 * c(5) - 0.4659516693228870973898560e0 * c(6) - 0.2217272720941736859420432e0 * c(7) -0.5205147429855955657625694e-2 * c(1) - 0.5363098747528542488971874e-2 * c(2) - 0.6897142765790609546343709e-2 * c(3) - 0.7857524521667450101721993e0 * c(5) + 0.2291148005423734600066709e0 * c(7) + 0.9977064356292750529201981e0 * c(6) 0.1207544072304193806052558e-2 * c(1) + 0.1432116665752147607469646e-2 * c(2) + 0.2605582646183255957264249e-3 * c(3) - 0.3332941113251635390801278e-1 * c(4) - 0.2808241697385532683612407e0 * c(7) - 0.2720908083525083608370563e-1 * c(8) + 0.1045865435682921987447929e0 * c(5) - 0.1348436986667115543203552e1 * c(6) 0.4227226173449345042468960e-3 * c(1) + 0.3088241944378964404772302e-3 * c(2) + 0.2062575706647430620228133e-3 * c(3) + 0.3308343404200968256656458e-2 * c(4) + 0.5828047016405001815804837e0 * c(5) + 0.8054174220366215473556835e0 * c(7) + 0.1338363233410033443348225e0 * c(8) + 0.5555555555555555555555556e-2 * c(9) + 0.1190362071861893051132274e1 * c(6) -0.8607044252686413302647675e-3 * c(4) - 0.1748074708673904989293256e0 * c(5) - 0.3132544850115050165022338e0 * c(8) - 0.2500000000000000000000000e-1 * c(9) - 0.3169166305310429271303167e0 * c(7) - 0.6691607091647929161078591e0 * c(6) 0.3354661791693352108660900e-1 * c(5) - 0.3343620022386971405018586e0 * c(7) + 0.5000000000000000000000000e-1 * c(9) + 0.2169790609807602750804271e0 * c(6) + 0.1838363233410033443348225e0 * c(8) 0.2912518476823004642951502e-1 * c(7) + 0.2279091916474916391629437e-1 * c(8) - 0.3068985997518740530511593e-1 * c(6) - 0.1781799513347360596249022e-2 * c(5) - 0.3055555555555555555555556e-1 * c(9); + 0.1911888563316170927411831e-2 * c(4) - 0.4068130355529149936100229e-1 * c(5) + 0.1319674981073749167009902e-1 * c(6) + 0.2557266518123783676349144e-1 * c(7) -0.4834791406446907590553793e-2 * c(4) + 0.2310683832687820403062715e0 * c(5) - 0.1080774142196007991746827e0 * c(6) - 0.1181561776427343335410349e0 * c(7) -0.5111353189352474549563559e-2 * c(4) - 0.5355878163774754346032096e0 * c(5) + 0.3328335104489738933610597e0 * c(6) + 0.2078656591178540157917135e0 * c(7) 0.6697297488067662265210608e0 * c(5) - 0.5013247356072127938999311e0 * c(6) - 0.1795161243106645437322408e0 * c(7) 0.8671038084174692625075159e-2 * c(4) + 0.1736073411355428563685818e0 * c(6) + 0.5331362125287625412555844e-1 * c(8) - 0.2424935262404526301801157e0 * c(5) + 0.1569015257678588270609004e0 * c(7) -0.8607044252686413302647675e-3 * c(4) - 0.1748074708673904989293256e0 * c(5) - 0.3132544850115050165022338e0 * c(8) - 0.2500000000000000000000000e-1 * c(9) - 0.3169166305310429271303167e0 * c(7) - 0.6691607091647929161078591e0 * c(6) 0.2239223735771599178951297e-3 * c(4) + 0.1275437785430956673825710e0 * c(5) + 0.1011699483929608164601067e1 * c(6) + 0.9698817275172575247533506e0 * c(8) + 0.1250000000000000000000000e0 * c(9) + 0.5555555555555555555555556e-2 * c(10) + 0.4823177543031281500117826e0 * c(7) -0.3784113973033012949863031e-1 * c(5) - 0.2997556885134827361576001e0 * c(6) - 0.3000000000000000000000000e0 * c(9) - 0.2500000000000000000000000e-1 * c(10) - 0.3991486867446821178415359e0 * c(7) - 0.4382544850115050165022338e0 * c(8) 0.4698146218022683933926520e-1 * c(6) - 0.2966863787471237458744416e0 * c(8) + 0.5000000000000000000000000e-1 * c(10) + 0.1716355704146006481727960e0 * c(7) + 0.3069346152296258362380356e-2 * c(5) + 0.1750000000000000000000000e0 * c(9); + 0.1559652871136785763960685e-1 * c(5) - 0.6486184157331537899459796e-2 * c(6) - 0.9110344554036319740147054e-2 * c(7) -0.8368141434403455353724691e-1 * c(5) + 0.4093499466767054661591066e-1 * c(6) + 0.4274641967636400692133626e-1 * c(7) 0.1824328174134289562208038e0 * c(5) - 0.1059816030196818445908057e0 * c(6) - 0.7645121439374711162999809e-1 * c(7) -0.2022909060111751565150958e0 * c(5) + 0.1453421858063658498587377e0 * c(6) + 0.5694872020480930665635812e-1 * c(7) -0.8631683980217122275970376e-1 * c(6) + 0.2698842360470999243492629e-1 * c(7) + 0.8098194147715651085292754e-1 * c(5) - 0.3276463639080639163926118e-1 * c(8) 0.3354661791693352108660900e-1 * c(5) - 0.3343620022386971405018586e0 * c(7) + 0.5000000000000000000000000e-1 * c(9) + 0.2169790609807602750804271e0 * c(6) + 0.1838363233410033443348225e0 * c(8) -0.3784113973033012949863031e-1 * c(5) - 0.2997556885134827361576001e0 * c(6) - 0.3000000000000000000000000e0 * c(9) - 0.2500000000000000000000000e-1 * c(10) - 0.3991486867446821178415359e0 * c(7) - 0.4382544850115050165022338e0 * c(8) 0.1230328942716804455358698e-1 * c(5) + 0.1183647529645898332481833e0 * c(6) + 0.9410511898227943334189628e0 * c(7) + 0.9500000000000000000000000e0 * c(9) + 0.1250000000000000000000000e0 * c(10) + 0.5555555555555555555555556e-2 * c(11) + 0.5699474344521144554459336e0 * c(8) -0.2308067892671916339568942e-1 * c(6) - 0.2986625053775149497180439e0 * c(7) - 0.3000000000000000000000000e0 * c(10) - 0.2500000000000000000000000e-1 * c(11) - 0.1047734860515050802561078e-2 * c(5) - 0.4272090808352508360837056e0 * c(8) - 0.4250000000000000000000000e0 * c(9); + 0.5593983696629863059347067e-3 * c(6) - 0.1384822535100796372263822e-2 * c(5) + 0.8254241654378100663291154e-3 * c(7) -0.3576545132696983143406173e-2 * c(6) + 0.7389399124121078682094445e-2 * c(5) - 0.3812853991424095538688273e-2 * c(7) 0.9209089963443799485648361e-2 * c(6) - 0.1591502818872493167091475e-1 * c(5) + 0.6705938225281132185266388e-2 * c(7) -0.1200429618441003833696998e-1 * c(6) - 0.4776915669385923841535432e-2 * c(7) + 0.1678121185379596217850541e-1 * c(5) 0.7462059484530855073291365e-2 * c(6) - 0.8121640361668678949573496e-3 * c(7) + 0.5522702088127090209264064e-3 * c(8) - 0.7202165657176696199260422e-2 * c(5) 0.2912518476823004642951502e-1 * c(7) + 0.2279091916474916391629437e-1 * c(8) - 0.3068985997518740530511593e-1 * c(6) - 0.1781799513347360596249022e-2 * c(5) - 0.3055555555555555555555556e-1 * c(9) 0.4698146218022683933926520e-1 * c(6) - 0.2966863787471237458744416e0 * c(8) + 0.5000000000000000000000000e-1 * c(10) + 0.1716355704146006481727960e0 * c(7) + 0.3069346152296258362380356e-2 * c(5) + 0.1750000000000000000000000e0 * c(9) -0.2308067892671916339568942e-1 * c(6) - 0.2986625053775149497180439e0 * c(7) - 0.3000000000000000000000000e0 * c(10) - 0.2500000000000000000000000e-1 * c(11) - 0.1047734860515050802561078e-2 * c(5) - 0.4272090808352508360837056e0 * c(8) - 0.4250000000000000000000000e0 * c(9) 0.5139370221149109977041877e-2 * c(6) + 0.1247723215009422001393184e0 * c(7) + 0.9505522702088127090209264e0 * c(8) + 0.9500000000000000000000000e0 * c(10) + 0.1250000000000000000000000e0 * c(11) + 0.5555555555555555555555556e-2 * c(12) + 0.9159362465153641826887659e-4 * c(5) + 0.5611111111111111111111111e0 * c(9); + ]; + + M(m-8:m,m-8:m)=[ + 0.5555555555555555555555556e-2 * c(m-11) + 0.1250000000000000000000000e0 * c(m-10) + 0.9500000000000000000000000e0 * c(m-9) + 0.9505522702088127090209264e0 * c(m-7) + 0.1247205076844361998744053e0 * c(m-6) + 0.5139370221149109977041877e-2 * c(m-5) + 0.5611111111111111111111111e0 * c(m-8) + 0.1434074411575366831819799e-3 * c(m-4) -0.2500000000000000000000000e-1 * c(m-10) - 0.3000000000000000000000000e0 * c(m-9) - 0.2980649679116425253322056e0 * c(m-6) - 0.2308067892671916339568942e-1 * c(m-5) - 0.4250000000000000000000000e0 * c(m-8) - 0.4272090808352508360837056e0 * c(m-7) - 0.1645272326387475188399322e-2 * c(m-4) 0.5000000000000000000000000e-1 * c(m-9) - 0.2966863787471237458744416e0 * c(m-7) + 0.4698146218022683933926520e-1 * c(m-5) + 0.1750000000000000000000000e0 * c(m-8) + 0.1700291833903489463825077e0 * c(m-6) + 0.4675733176547960152668626e-2 * c(m-4) 0.2279091916474916391629437e-1 * c(m-7) + 0.3097763128598982561225538e-1 * c(m-6) - 0.3055555555555555555555556e-1 * c(m-8) - 0.3068985997518740530511593e-1 * c(m-5) - 0.3634246031107139778989373e-2 * c(m-4) 0.5522702088127090209264064e-3 * c(m-7) - 0.3265435411305071914756373e-2 * c(m-6) + 0.7462059484530855073291365e-2 * c(m-5) - 0.4748894282038492179461399e-2 * c(m-4) 0.6272075574042975468177820e-3 * c(m-6) - 0.1200429618441003833696998e-1 * c(m-5) + 0.1137708862700574079015220e-1 * c(m-4) 0.9209089963443799485648361e-2 * c(m-5) - 0.3129629392354775191148163e-3 * c(m-6) - 0.8896127024208321966533544e-2 * c(m-4) -0.3576545132696983143406173e-2 * c(m-5) + 0.4335019854436220306755673e-3 * c(m-6) + 0.3143043147253361112730605e-2 * c(m-4) 0.5593983696629863059347067e-3 * c(m-5) - 0.1446656414398166805849327e-3 * c(m-6) - 0.4147327282231696253497740e-3 * c(m-4); + -0.2500000000000000000000000e-1 * c(m-10) - 0.3000000000000000000000000e0 * c(m-9) - 0.2980649679116425253322056e0 * c(m-6) - 0.2308067892671916339568942e-1 * c(m-5) - 0.4250000000000000000000000e0 * c(m-8) - 0.4272090808352508360837056e0 * c(m-7) - 0.1645272326387475188399322e-2 * c(m-4) 0.5555555555555555555555556e-2 * c(m-10) + 0.1250000000000000000000000e0 * c(m-9) + 0.9500000000000000000000000e0 * c(m-8) + 0.9341601509609901526962449e0 * c(m-6) + 0.1183647529645898332481833e0 * c(m-5) + 0.1919432828897222527630486e-1 * c(m-4) + 0.5699474344521144554459336e0 * c(m-7) -0.2500000000000000000000000e-1 * c(m-9) - 0.3000000000000000000000000e0 * c(m-8) - 0.2997556885134827361576001e0 * c(m-5) - 0.5636663150858098975790317e-1 * c(m-4) - 0.4382544850115050165022338e0 * c(m-7) - 0.3806231949664312575822630e0 * c(m-6) 0.5000000000000000000000000e-1 * c(m-8) - 0.3557251496099816106154206e0 * c(m-6) + 0.5490976528821799120017102e-1 * c(m-4) + 0.1838363233410033443348225e0 * c(m-7) + 0.2169790609807602750804271e0 * c(m-5) 0.5528052133944605740009217e-1 * c(m-6) - 0.8631683980217122275970376e-1 * c(m-5) - 0.3276463639080639163926118e-1 * c(m-7) + 0.5268984374242044588776166e-1 * c(m-4) -0.5373770512016897565958305e-2 * c(m-6) + 0.1453421858063658498587377e0 * c(m-5) - 0.1399684152943489522927794e0 * c(m-4) -0.1059816030196818445908057e0 * c(m-5) + 0.1014880675788250237247178e0 * c(m-4) + 0.4493535440856820866087846e-2 * c(m-6) 0.4093499466767054661591066e-1 * c(m-5) - 0.3471075437892810033585296e-1 * c(m-4) - 0.6224240288742446280057699e-2 * c(m-6) -0.6486184157331537899459796e-2 * c(m-5) + 0.4409068609809831485979484e-2 * c(m-4) + 0.2077115547521706413480312e-2 * c(m-6); + 0.5000000000000000000000000e-1 * c(m-9) - 0.2966863787471237458744416e0 * c(m-7) + 0.4698146218022683933926520e-1 * c(m-5) + 0.1750000000000000000000000e0 * c(m-8) + 0.1700291833903489463825077e0 * c(m-6) + 0.4675733176547960152668626e-2 * c(m-4) -0.2500000000000000000000000e-1 * c(m-9) - 0.3000000000000000000000000e0 * c(m-8) - 0.2997556885134827361576001e0 * c(m-5) - 0.5636663150858098975790317e-1 * c(m-4) - 0.4382544850115050165022338e0 * c(m-7) - 0.3806231949664312575822630e0 * c(m-6) 0.5555555555555555555555556e-2 * c(m-9) + 0.1250000000000000000000000e0 * c(m-8) + 0.9698817275172575247533506e0 * c(m-7) + 0.1011699483929608164601067e1 * c(m-5) + 0.1773466968705924819112984e0 * c(m-4) + 0.2239223735771599178951297e-3 * c(m-3) + 0.4325148359756313354830552e0 * c(m-6) -0.2500000000000000000000000e-1 * c(m-8) - 0.3132544850115050165022338e0 * c(m-7) - 0.2322389872063761557916742e0 * c(m-4) - 0.8607044252686413302647675e-3 * c(m-3) - 0.2594851141920572702679681e0 * c(m-6) - 0.6691607091647929161078591e0 * c(m-5) 0.5331362125287625412555844e-1 * c(m-7) + 0.1736073411355428563685818e0 * c(m-5) + 0.8671038084174692625075159e-2 * c(m-3) + 0.8084259844422177692569663e-1 * c(m-6) - 0.1664345989168155800449120e0 * c(m-4) -0.5013247356072127938999311e0 * c(m-5) + 0.5021853752328231128475915e0 * c(m-4) - 0.1197175073672143005877150e-1 * c(m-6) 0.3328335104489738933610597e0 * c(m-5) - 0.3179803804558436283847901e0 * c(m-4) - 0.5111353189352474549563559e-2 * c(m-3) - 0.9741776803777790426705996e-2 * c(m-6) -0.1080774142196007991746827e0 * c(m-5) + 0.9941834083648937298100811e-1 * c(m-4) - 0.4834791406446907590553793e-2 * c(m-3) + 0.1349386478955833378422842e-1 * c(m-6) 0.1319674981073749167009902e-1 * c(m-5) - 0.1060554802883657391328704e-1 * c(m-4) + 0.1911888563316170927411831e-2 * c(m-3) - 0.4503090345217088684223814e-2 * c(m-6); + 0.2279091916474916391629437e-1 * c(m-7) + 0.3097763128598982561225538e-1 * c(m-6) - 0.3055555555555555555555556e-1 * c(m-8) - 0.3068985997518740530511593e-1 * c(m-5) - 0.3634246031107139778989373e-2 * c(m-4) 0.5000000000000000000000000e-1 * c(m-8) - 0.3557251496099816106154206e0 * c(m-6) + 0.5490976528821799120017102e-1 * c(m-4) + 0.1838363233410033443348225e0 * c(m-7) + 0.2169790609807602750804271e0 * c(m-5) -0.2500000000000000000000000e-1 * c(m-8) - 0.3132544850115050165022338e0 * c(m-7) - 0.2322389872063761557916742e0 * c(m-4) - 0.8607044252686413302647675e-3 * c(m-3) - 0.2594851141920572702679681e0 * c(m-6) - 0.6691607091647929161078591e0 * c(m-5) 0.5555555555555555555555556e-2 * c(m-8) + 0.1338363233410033443348225e0 * c(m-7) + 0.7391887916719206077121040e0 * c(m-6) + 0.6490333320052011212240632e0 * c(m-4) + 0.3308343404200968256656458e-2 * c(m-3) + 0.2062575706647430620228133e-3 * c(m-2) + 0.3088241944378964404772302e-3 * c(m-1) + 0.4227226173449345042468960e-3 * c(m) + 0.1190362071861893051132274e1 * c(m-5) -0.2720908083525083608370563e-1 * c(m-7) - 0.1931148612480615118957263e0 * c(m-6) - 0.3332941113251635390801278e-1 * c(m-3) + 0.2605582646183255957264249e-3 * c(m-2) + 0.1432116665752147607469646e-2 * c(m-1) + 0.1207544072304193806052558e-2 * c(m) - 0.1348436986667115543203552e1 * c(m-5) + 0.1687723507780044227927853e-1 * c(m-4) 0.3590669644811151307464697e-1 * c(m-6) - 0.5925443480724830632401754e0 * c(m-4) - 0.6897142765790609546343709e-2 * c(m-2) - 0.5363098747528542488971874e-2 * c(m-1) - 0.5205147429855955657625694e-2 * c(m) + 0.9977064356292750529201981e0 * c(m-5) 0.7272438906214475928744770e-1 * c(m-4) + 0.1964682777744275219350831e-1 * c(m-3) - 0.5952475275883259619711594e-2 * c(m-1) - 0.1635430866921887819487473e-2 * c(m) + 0.2921234010758621482958052e-1 * c(m-6) - 0.4659516693228870973898560e0 * c(m-5) 0.5891947149681041048896399e-1 * c(m-4) + 0.1858378996391679448655070e-1 * c(m-3) + 0.7240905383565181316381731e-2 * c(m-2) + 0.2349927974590068869356781e-1 * c(m) - 0.4046360079256766884300687e-1 * c(m-6) + 0.1223513270418807666970488e0 * c(m-5) -0.2404661162020836566908542e-1 * c(m-4) - 0.7348845587775519698437916e-2 * c(m-3) - 0.8105784530576404277872603e-3 * c(m-2) + 0.9574633163221758060736592e-2 * c(m-1) - 0.1828896813877197352675410e-1 * c(m) + 0.1350326632905990039353503e-1 * c(m-6) - 0.1315967038382618382356495e-1 * c(m-5); + 0.5522702088127090209264064e-3 * c(m-7) - 0.3265435411305071914756373e-2 * c(m-6) + 0.7462059484530855073291365e-2 * c(m-5) - 0.4748894282038492179461399e-2 * c(m-4) 0.5528052133944605740009217e-1 * c(m-6) - 0.8631683980217122275970376e-1 * c(m-5) - 0.3276463639080639163926118e-1 * c(m-7) + 0.5268984374242044588776166e-1 * c(m-4) 0.5331362125287625412555844e-1 * c(m-7) + 0.1736073411355428563685818e0 * c(m-5) + 0.8671038084174692625075159e-2 * c(m-3) + 0.8084259844422177692569663e-1 * c(m-6) - 0.1664345989168155800449120e0 * c(m-4) -0.2720908083525083608370563e-1 * c(m-7) - 0.1931148612480615118957263e0 * c(m-6) - 0.3332941113251635390801278e-1 * c(m-3) + 0.2605582646183255957264249e-3 * c(m-2) + 0.1432116665752147607469646e-2 * c(m-1) + 0.1207544072304193806052558e-2 * c(m) - 0.1348436986667115543203552e1 * c(m-5) + 0.1687723507780044227927853e-1 * c(m-4) 0.6107825764368264576481962e-2 * c(m-7) + 0.1155752633643216628010304e0 * c(m-6) + 0.2096413329579026439044119e1 * c(m-5) + 0.3357721707576477199985656e0 * c(m-3) + 0.3291545083271862858501887e-3 * c(m-2) + 0.6641183499427826101618457e-2 * c(m-1) + 0.3449455095910233625229891e-2 * c(m) + 0.8270696421223286922584620e0 * c(m-4) -0.4995827370863505253765970e-1 * c(m-6) - 0.1263507837371824205693950e1 * c(m-5) - 0.8712928907711754187084757e-2 * c(m-2) - 0.2487040599390160764166412e-1 * c(m-1) - 0.1486895819265604128572498e-1 * c(m) - 0.1726565392121567634950213e1 * c(m-4) 0.5402985338373433052255418e0 * c(m-5) - 0.1979290298620869974478871e0 * c(m-3) - 0.2760353365637712827793337e-1 * c(m-1) - 0.4671751091575462868310238e-2 * c(m) - 0.6952587985456154591014641e-1 * c(m-6) + 0.1571507277911208446562686e1 * c(m-4) -0.1319358558853174530078498e0 * c(m-5) - 0.1872196143003808021730728e0 * c(m-3) + 0.9147192682075630179962131e-2 * c(m-2) + 0.6712774475803763988977355e-1 * c(m) + 0.9630407686703666967100804e-1 * c(m-6) - 0.6882132817757726722141421e0 * c(m-4) 0.1241625568998496895352046e-1 * c(m-5) + 0.7403484645316174090533193e-1 * c(m-3) - 0.1023976547309387874453988e-2 * c(m-2) + 0.4440063948509876221050939e-1 * c(m-1) - 0.5224403464202056316702078e-1 * c(m) - 0.3213800979246298453953842e-1 * c(m-6) + 0.1178181682424363524005403e0 * c(m-4); + 0.6272075574042975468177820e-3 * c(m-6) - 0.1200429618441003833696998e-1 * c(m-5) + 0.1137708862700574079015220e-1 * c(m-4) -0.5373770512016897565958305e-2 * c(m-6) + 0.1453421858063658498587377e0 * c(m-5) - 0.1399684152943489522927794e0 * c(m-4) -0.5013247356072127938999311e0 * c(m-5) + 0.5021853752328231128475915e0 * c(m-4) - 0.1197175073672143005877150e-1 * c(m-6) 0.3590669644811151307464697e-1 * c(m-6) - 0.5925443480724830632401754e0 * c(m-4) - 0.6897142765790609546343709e-2 * c(m-2) - 0.5363098747528542488971874e-2 * c(m-1) - 0.5205147429855955657625694e-2 * c(m) + 0.9977064356292750529201981e0 * c(m-5) -0.4995827370863505253765970e-1 * c(m-6) - 0.1263507837371824205693950e1 * c(m-5) - 0.8712928907711754187084757e-2 * c(m-2) - 0.2487040599390160764166412e-1 * c(m-1) - 0.1486895819265604128572498e-1 * c(m) - 0.1726565392121567634950213e1 * c(m-4) 0.2760393423824887721078848e-1 * c(m-6) + 0.1190550338687608873798462e1 * c(m-5) + 0.4253084328734353394994388e1 * c(m-4) + 0.2306367624634749229113646e0 * c(m-2) + 0.9313657638804699948929701e-1 * c(m-1) + 0.6409299775987186986730499e-1 * c(m) -0.8755807343482262259774782e0 * c(m-5) - 0.3645285178085761821545207e1 * c(m-4) + 0.1033717994630886401730470e0 * c(m-1) + 0.2013769413884797246646959e-1 * c(m) + 0.4106783858513785463625543e-1 * c(m-6) 0.3956598149904136332753521e0 * c(m-5) + 0.1630560443616104907615866e1 * c(m-4) - 0.2421320004064592721552708e0 * c(m-2) - 0.2893557395653431666593814e0 * c(m) - 0.5688529641249387985434413e-1 * c(m-6) -0.7684117160199014594442072e-1 * c(m-5) - 0.2928439026361256842196229e0 * c(m-4) + 0.2710530961648671297733465e-1 * c(m-2) - 0.1662748711097054895317080e0 * c(m-1) + 0.2251991532891353212689574e0 * c(m) + 0.1898341454096471754822498e-1 * c(m-6); + 0.9209089963443799485648361e-2 * c(m-5) - 0.3129629392354775191148163e-3 * c(m-6) - 0.8896127024208321966533544e-2 * c(m-4) -0.1059816030196818445908057e0 * c(m-5) + 0.1014880675788250237247178e0 * c(m-4) + 0.4493535440856820866087846e-2 * c(m-6) 0.3328335104489738933610597e0 * c(m-5) - 0.3179803804558436283847901e0 * c(m-4) - 0.5111353189352474549563559e-2 * c(m-3) - 0.9741776803777790426705996e-2 * c(m-6) 0.7272438906214475928744770e-1 * c(m-4) + 0.1964682777744275219350831e-1 * c(m-3) - 0.5952475275883259619711594e-2 * c(m-1) - 0.1635430866921887819487473e-2 * c(m) + 0.2921234010758621482958052e-1 * c(m-6) - 0.4659516693228870973898560e0 * c(m-5) 0.5402985338373433052255418e0 * c(m-5) - 0.1979290298620869974478871e0 * c(m-3) - 0.2760353365637712827793337e-1 * c(m-1) - 0.4671751091575462868310238e-2 * c(m) - 0.6952587985456154591014641e-1 * c(m-6) + 0.1571507277911208446562686e1 * c(m-4) -0.8755807343482262259774782e0 * c(m-5) - 0.3645285178085761821545207e1 * c(m-4) + 0.1033717994630886401730470e0 * c(m-1) + 0.2013769413884797246646959e-1 * c(m) + 0.4106783858513785463625543e-1 * c(m-6) 0.1070920689960817104203947e1 * c(m-5) + 0.3717418466925056542408153e1 * c(m-4) + 0.1166740554279680007487795e0 * c(m-3) + 0.1147318200715868527529827e0 * c(m-1) + 0.6327161147136873807796515e-2 * c(m) + 0.6235373239336055200426697e-1 * c(m-6) -0.6639605248735044787146222e0 * c(m-5) - 0.1865625445986772763641423e1 * c(m-4) + 0.1103611313171476425250639e0 * c(m-3) - 0.9091410269992464604926176e-1 * c(m) - 0.8636954541126674177407762e-1 * c(m-6) 0.1582127073537215443965653e0 * c(m-5) + 0.3746489300753517635549495e0 * c(m-4) - 0.4364163147111892346990101e-1 * c(m-3) - 0.1845476106024151050283847e0 * c(m-1) + 0.7075642937243715046279337e-1 * c(m) + 0.2882271848190011329385407e-1 * c(m-6); + -0.3576545132696983143406173e-2 * c(m-5) + 0.4335019854436220306755673e-3 * c(m-6) + 0.3143043147253361112730605e-2 * c(m-4) 0.4093499466767054661591066e-1 * c(m-5) - 0.3471075437892810033585296e-1 * c(m-4) - 0.6224240288742446280057699e-2 * c(m-6) -0.1080774142196007991746827e0 * c(m-5) + 0.9941834083648937298100811e-1 * c(m-4) - 0.4834791406446907590553793e-2 * c(m-3) + 0.1349386478955833378422842e-1 * c(m-6) 0.5891947149681041048896399e-1 * c(m-4) + 0.1858378996391679448655070e-1 * c(m-3) + 0.7240905383565181316381731e-2 * c(m-2) + 0.2349927974590068869356781e-1 * c(m) - 0.4046360079256766884300687e-1 * c(m-6) + 0.1223513270418807666970488e0 * c(m-5) -0.1319358558853174530078498e0 * c(m-5) - 0.1872196143003808021730728e0 * c(m-3) + 0.9147192682075630179962131e-2 * c(m-2) + 0.6712774475803763988977355e-1 * c(m) + 0.9630407686703666967100804e-1 * c(m-6) - 0.6882132817757726722141421e0 * c(m-4) 0.3956598149904136332753521e0 * c(m-5) + 0.1630560443616104907615866e1 * c(m-4) - 0.2421320004064592721552708e0 * c(m-2) - 0.2893557395653431666593814e0 * c(m) - 0.5688529641249387985434413e-1 * c(m-6) -0.6639605248735044787146222e0 * c(m-5) - 0.1865625445986772763641423e1 * c(m-4) + 0.1103611313171476425250639e0 * c(m-3) - 0.9091410269992464604926176e-1 * c(m) - 0.8636954541126674177407762e-1 * c(m-6) 0.4681819359722749441073885e0 * c(m-5) + 0.1015239189167790053447110e1 * c(m-4) + 0.1043897828092562609502636e0 * c(m-3) + 0.2542001760457345743492403e0 * c(m-2) + 0.1306332157111667628555907e1 * c(m) + 0.1196351539550049336518187e0 * c(m-6) -0.1195777325611201766551392e0 * c(m-5) - 0.2187310061229745694542609e0 * c(m-4) - 0.4128029838349298819825156e-1 * c(m-3) - 0.2845627370491611369031341e-1 * c(m-2) - 0.1016689339350338144430605e1 * c(m) - 0.3992391469197282238624438e-1 * c(m-6); + 0.5593983696629863059347067e-3 * c(m-5) - 0.1446656414398166805849327e-3 * c(m-6) - 0.4147327282231696253497740e-3 * c(m-4) -0.6486184157331537899459796e-2 * c(m-5) + 0.4409068609809831485979484e-2 * c(m-4) + 0.2077115547521706413480312e-2 * c(m-6) 0.1319674981073749167009902e-1 * c(m-5) - 0.1060554802883657391328704e-1 * c(m-4) + 0.1911888563316170927411831e-2 * c(m-3) - 0.4503090345217088684223814e-2 * c(m-6) -0.2404661162020836566908542e-1 * c(m-4) - 0.7348845587775519698437916e-2 * c(m-3) - 0.8105784530576404277872603e-3 * c(m-2) + 0.9574633163221758060736592e-2 * c(m-1) - 0.1828896813877197352675410e-1 * c(m) + 0.1350326632905990039353503e-1 * c(m-6) - 0.1315967038382618382356495e-1 * c(m-5) 0.1241625568998496895352046e-1 * c(m-5) + 0.7403484645316174090533193e-1 * c(m-3) - 0.1023976547309387874453988e-2 * c(m-2) + 0.4440063948509876221050939e-1 * c(m-1) - 0.5224403464202056316702078e-1 * c(m) - 0.3213800979246298453953842e-1 * c(m-6) + 0.1178181682424363524005403e0 * c(m-4) -0.7684117160199014594442072e-1 * c(m-5) - 0.2928439026361256842196229e0 * c(m-4) + 0.2710530961648671297733465e-1 * c(m-2) - 0.1662748711097054895317080e0 * c(m-1) + 0.2251991532891353212689574e0 * c(m) + 0.1898341454096471754822498e-1 * c(m-6) 0.1582127073537215443965653e0 * c(m-5) + 0.3746489300753517635549495e0 * c(m-4) - 0.4364163147111892346990101e-1 * c(m-3) - 0.1845476106024151050283847e0 * c(m-1) + 0.7075642937243715046279337e-1 * c(m) + 0.2882271848190011329385407e-1 * c(m-6) -0.1195777325611201766551392e0 * c(m-5) - 0.2187310061229745694542609e0 * c(m-4) - 0.4128029838349298819825156e-1 * c(m-3) - 0.2845627370491611369031341e-1 * c(m-2) - 0.1016689339350338144430605e1 * c(m) - 0.3992391469197282238624438e-1 * c(m-6) 0.3167964748016105299646518e-1 * c(m-5) + 0.4976563420877041544013670e-1 * c(m-4) + 0.1632404042590951953384672e-1 * c(m-3) + 0.3185519088796429015220016e-2 * c(m-2) + 0.2968472090638000742888467e0 * c(m-1) + 0.7912667594695582093926295e0 * c(m) + 0.1332316557164627464149716e-1 * c(m-6); + ]; + + M(5,10)=M(10,5); + M(m-4,m-9)=M(m-9,m-4); + + M=M/h; + + D2 = HI*(-M - c(1)*e_l*d1_l' + c(m)*e_r*d1_r'); + end + D2 = @D2_fun; + + % Fourth derivative, 1th order accurate at first 8 boundary points (still + % yield 5th order convergence if stable: for example u_tt=-u_xxxx + stencil = [7/240, -2/5, 169/60, -122/15, 91/8, -122/15, 169/60, -2/5, 7/240]; + diags = -4:4; + M4 = stripeMatrix(stencil, diags, m); + + M4_U = [ + 0.1394226315049e13/0.367201486080e12 -0.1137054563243e13/0.114750464400e12 0.16614189027367e14/0.1836007430400e13 -0.1104821700277e13/0.306001238400e12 0.1355771086763e13/0.1836007430400e13 -0.27818686453e11/0.459001857600e12 -0.40671054239e11/0.1836007430400e13 0.5442887371e10/0.306001238400e12; + -0.1137054563243e13/0.114750464400e12 0.70616795535409e14/0.2570410402560e13 -0.173266854731041e15/0.6426026006400e13 0.28938615291031e14/0.2570410402560e13 -0.146167361863e12/0.71400288960e11 0.2793470836571e13/0.12852052012800e14 0.6219558097e10/0.428401733760e12 -0.7313844559e10/0.166909766400e12; + 0.16614189027367e14/0.1836007430400e13 -0.173266854731041e15/0.6426026006400e13 0.378613061504779e15/0.12852052012800e14 -0.9117069604217e13/0.642602600640e12 0.632177582849e12/0.233673672960e12 -0.1057776382577e13/0.6426026006400e13 0.443019868399e12/0.4284017337600e13 -0.3707981e7/0.2318191200e10; + -0.1104821700277e13/0.306001238400e12 0.28938615291031e14/0.2570410402560e13 -0.9117069604217e13/0.642602600640e12 0.5029150721885e13/0.514082080512e12 -0.5209119714341e13/0.1285205201280e13 0.12235427457469e14/0.12852052012800e14 -0.13731270505e11/0.64260260064e11 0.2933596129e10/0.40800165120e11; + 0.1355771086763e13/0.1836007430400e13 -0.146167361863e12/0.71400288960e11 0.632177582849e12/0.233673672960e12 -0.5209119714341e13/0.1285205201280e13 0.14871726798559e14/0.2570410402560e13 -0.7504337615347e13/0.1606506501600e13 0.310830296467e12/0.171360693504e12 -0.55284274391e11/0.183600743040e12; + -0.27818686453e11/0.459001857600e12 0.2793470836571e13/0.12852052012800e14 -0.1057776382577e13/0.6426026006400e13 0.12235427457469e14/0.12852052012800e14 -0.7504337615347e13/0.1606506501600e13 0.106318657014853e15/0.12852052012800e14 -0.14432772918527e14/0.2142008668800e13 0.58102695589e11/0.22666758400e11; + -0.40671054239e11/0.1836007430400e13 0.6219558097e10/0.428401733760e12 0.443019868399e12/0.4284017337600e13 -0.13731270505e11/0.64260260064e11 0.310830296467e12/0.171360693504e12 -0.14432772918527e14/0.2142008668800e13 0.27102479467823e14/0.2570410402560e13 -0.1216032192203e13/0.153000619200e12; + 0.5442887371e10/0.306001238400e12 -0.7313844559e10/0.166909766400e12 -0.3707981e7/0.2318191200e10 0.2933596129e10/0.40800165120e11 -0.55284274391e11/0.183600743040e12 0.58102695589e11/0.22666758400e11 -0.1216032192203e13/0.153000619200e12 0.20799922829107e14/0.1836007430400e13; + ]; + + M4(1:8,1:8) = M4_U; + M4(m-7:m,m-7:m) = rot90( M4_U ,2 ); + M4 = M4/h^3; + + + + D4=HI*(M4 - e_l*d3_l'+e_r*d3_r' + d1_l*d2_l'-d1_r*d2_r'); +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/+implementations/intOpAWW_orders_2to2_ratio2to1.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,47 @@ +function [IC2F,IF2C,Hc,Hf] = IntOp_orders_2to2_ratio2to1(mc,hc,ACC) + +% ACC is a string. +% ACC = 'C2F' creates IC2F with one order of accuracy higher than IF2C. +% ACC = 'F2C' creates IF2C with one order of accuracy higher than IC2F. +ratio = 2; +mf = ratio*mc-1; +hf = hc/ratio; + +switch ACC + case 'F2C' + [stencil_F2C,BC_F2C,HcU,HfU] = ... + sbp.implementations.intOpAWW_orders_2to2_ratio_2to1_accC2F1_accF2C2; + case 'C2F' + [stencil_F2C,BC_F2C,HcU,HfU] = ... + sbp.implementations.intOpAWW_orders_2to2_ratio_2to1_accC2F2_accF2C1; +end + +stencil_width = length(stencil_F2C); +stencil_hw = (stencil_width-1)/2; +[BC_rows,BC_cols] = size(BC_F2C); + +%%% Norm matrices %%% +Hc = speye(mc,mc); +HcUm = length(HcU); +Hc(1:HcUm,1:HcUm) = spdiags(HcU',0,HcUm,HcUm); +Hc(mc-HcUm+1:mc,mc-HcUm+1:mc) = spdiags(rot90(HcU',2),0,HcUm,HcUm); +Hc = Hc*hc; + +Hf = speye(mf,mf); +HfUm = length(HfU); +Hf(1:HfUm,1:HfUm) = spdiags(HfU',0,HfUm,HfUm); +Hf(mf-length(HfU)+1:mf,mf-length(HfU)+1:mf) = spdiags(rot90(HfU',2),0,HfUm,HfUm); +Hf = Hf*hf; +%%%%%%%%%%%%%%%%%%%%%% + +%%% Create IF2C from stencil and BC +IF2C = sparse(mc,mf); +for i = BC_rows+1 : mc-BC_rows + IF2C(i,ratio*i-1+(-stencil_hw:stencil_hw)) = stencil_F2C; %#ok<SPRIX> +end +IF2C(1:BC_rows,1:BC_cols) = BC_F2C; +IF2C(end-BC_rows+1:end,end-BC_cols+1:end) = rot90(BC_F2C,2); +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%% Create IC2F using symmetry condition %%%% +IC2F = Hf\IF2C.'*Hc; \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/+implementations/intOpAWW_orders_2to2_ratio_2to1_accC2F1_accF2C2.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,17 @@ +function [stencil_F2C,BC_F2C,HcU,HfU] = intOpAWW_orders_2to2_ratio_2to1_accC2F1_accF2C2 +%INT_ORDERS_2TO2_RATIO_2TO1_ACCC2F1_ACCF2C2_STENCIL_5_BC_2_5 +% [STENCIL_F2C,BC_F2C,HCU,HFU] = INT_ORDERS_2TO2_RATIO_2TO1_ACCC2F1_ACCF2C2_STENCIL_5_BC_2_5 + +% This function was generated by the Symbolic Math Toolbox version 8.0. +% 21-May-2018 15:36:07 + +stencil_F2C = [-1.0./8.0,1.0./4.0,3.0./4.0,1.0./4.0,-1.0./8.0]; +if nargout > 1 + BC_F2C = reshape([6.288191560529559e-1,-6.440957802647795e-2,6.855471317807184e-1,1.572264341096408e-1,-2.438028498638558e-1,7.469014249319279e-1,-8.431231982626708e-2,2.921561599131335e-1,1.374888185644862e-2,-1.318744409282243e-1],[2,5]); +end +if nargout > 2 + HcU = 1.0./2.0; +end +if nargout > 3 + HfU = 1.0./2.0; +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/+implementations/intOpAWW_orders_2to2_ratio_2to1_accC2F2_accF2C1.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,17 @@ +function [stencil_F2C,BC_F2C,HcU,HfU] = intOpAWW_orders_2to2_ratio_2to1_accC2F2_accF2C1 +%INT_ORDERS_2TO2_RATIO_2TO1_ACCC2F2_ACCF2C1_STENCIL_5_BC_1_3 +% [STENCIL_F2C,BC_F2C,HCU,HFU] = INT_ORDERS_2TO2_RATIO_2TO1_ACCC2F2_ACCF2C1_STENCIL_5_BC_1_3 + +% This function was generated by the Symbolic Math Toolbox version 8.0. +% 21-May-2018 15:36:08 + +stencil_F2C = [1.0./4.0,1.0./2.0,1.0./4.0]; +if nargout > 1 + BC_F2C = [1.0./2.0,1.0./2.0]; +end +if nargout > 2 + HcU = 1.0./2.0; +end +if nargout > 3 + HfU = 1.0./2.0; +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/+implementations/intOpAWW_orders_4to4_ratio2to1.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,47 @@ +function [IC2F,IF2C,Hc,Hf] = IntOp_orders_4to4_ratio2to1(mc,hc,ACC) + +% ACC is a string. +% ACC = 'C2F' creates IC2F with one order of accuracy higher than IF2C. +% ACC = 'F2C' creates IF2C with one order of accuracy higher than IC2F. +ratio = 2; +mf = ratio*mc-1; +hf = hc/ratio; + +switch ACC + case 'F2C' + [stencil_F2C,BC_F2C,HcU,HfU] = ... + sbp.implementations.intOpAWW_orders_4to4_ratio_2to1_accC2F2_accF2C3; + case 'C2F' + [stencil_F2C,BC_F2C,HcU,HfU] = ... + sbp.implementations.intOpAWW_orders_4to4_ratio_2to1_accC2F3_accF2C2; +end + +stencil_width = length(stencil_F2C); +stencil_hw = (stencil_width-1)/2; +[BC_rows,BC_cols] = size(BC_F2C); + +%%% Norm matrices %%% +Hc = speye(mc,mc); +HcUm = length(HcU); +Hc(1:HcUm,1:HcUm) = spdiags(HcU',0,HcUm,HcUm); +Hc(mc-HcUm+1:mc,mc-HcUm+1:mc) = spdiags(rot90(HcU',2),0,HcUm,HcUm); +Hc = Hc*hc; + +Hf = speye(mf,mf); +HfUm = length(HfU); +Hf(1:HfUm,1:HfUm) = spdiags(HfU',0,HfUm,HfUm); +Hf(mf-length(HfU)+1:mf,mf-length(HfU)+1:mf) = spdiags(rot90(HfU',2),0,HfUm,HfUm); +Hf = Hf*hf; +%%%%%%%%%%%%%%%%%%%%%% + +%%% Create IF2C from stencil and BC +IF2C = sparse(mc,mf); +for i = BC_rows+1 : mc-BC_rows + IF2C(i,ratio*i-1+(-stencil_hw:stencil_hw)) = stencil_F2C; %#ok<SPRIX> +end +IF2C(1:BC_rows,1:BC_cols) = BC_F2C; +IF2C(end-BC_rows+1:end,end-BC_cols+1:end) = rot90(BC_F2C,2); +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%% Create IC2F using symmetry condition %%%% +IC2F = Hf\IF2C.'*Hc; \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/+implementations/intOpAWW_orders_4to4_ratio_2to1_accC2F2_accF2C3.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,18 @@ +function [stencil_F2C,BC_F2C,HcU,HfU] = intOpAWW_orders_4to4_ratio_2to1_accC2F2_accF2C3 +%INT_ORDERS_4TO4_RATIO_2TO1_ACCC2F2_ACCF2C3_STENCIL_9_BC_3_11 +% [STENCIL_F2C,BC_F2C,HCU,HFU] = INT_ORDERS_4TO4_RATIO_2TO1_ACCC2F2_ACCF2C3_STENCIL_9_BC_3_11 + +% This function was generated by the Symbolic Math Toolbox version 8.0. +% 21-May-2018 15:36:01 + +stencil_F2C = [7.0./2.56e2,-1.0./3.2e1,-7.0./6.4e1,9.0./3.2e1,8.5e1./1.28e2,9.0./3.2e1,-7.0./6.4e1,-1.0./3.2e1,7.0./2.56e2]; +if nargout > 1 + BC_F2C = reshape([7.523257802630956e-2,2.447812262221267e-1,-1.679313063616916e-1,1.290510950666589,6.315723344677289e-3,1.67178747937954e-1,1.982667903557025,-7.554383893379468e-1,7.215271362899867e-1,-2.820478831383137,1.807034411305536,-7.589683751979843e-1,-7.685973268458095e-1,3.965751544535173e-1,4.119789638051451e-1,1.574000556785898e-1,-1.113618964927466e-1,3.631000220124657e-1,1.639694219982991,-9.114074742274862e-1,4.952715520862987e-1,-4.524162151353456e-1,2.65481378213589e-1,-2.268273408674622e-1,3.455365956773523e-1,-2.009765975089827e-1,1.722179564305811e-1,-5.52933488235368e-1,3.18109976271229e-1,-2.171481232558432e-1,1.033835580108027e-1,-5.911351224351343e-2,3.960076712054991e-2],[3,11]); +end +if nargout > 2 + t2 = [1.7e1./4.8e1,5.9e1./4.8e1,4.3e1./4.8e1,4.9e1./4.8e1]; + HcU = t2; +end +if nargout > 3 + HfU = t2; +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/+implementations/intOpAWW_orders_4to4_ratio_2to1_accC2F3_accF2C2.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,18 @@ +function [stencil_F2C,BC_F2C,HcU,HfU] = intOpAWW_orders_4to4_ratio_2to1_accC2F3_accF2C2 +%INT_ORDERS_4TO4_RATIO_2TO1_ACCC2F3_ACCF2C2_STENCIL_9_BC_3_11 +% [STENCIL_F2C,BC_F2C,HCU,HFU] = INT_ORDERS_4TO4_RATIO_2TO1_ACCC2F3_ACCF2C2_STENCIL_9_BC_3_11 + +% This function was generated by the Symbolic Math Toolbox version 8.0. +% 21-May-2018 15:36:05 + +stencil_F2C = [-1.0./2.56e2,-1.0./3.2e1,1.0./6.4e1,9.0./3.2e1,6.1e1./1.28e2,9.0./3.2e1,1.0./6.4e1,-1.0./3.2e1,-1.0./2.56e2]; +if nargout > 1 + BC_F2C = reshape([1.0./2.0,0.0,0.0,1.77e2./2.72e2,3.0./8.0,-5.9e1./6.88e2,1.125919117647059e-2,3.546742584745763e-1,1.335392441860465e-2,-4.9e1./5.44e2,2.335805084745763e-1,3.204941860465116e-1,-1.194852941176471e-2,1.350635593220339e-2,5.308866279069767e-1,-9.0./5.44e2,-1.11228813559322e-2,2.943313953488372e-1,-2.803308823529412e-2,2.105402542372881e-2,-1.580668604651163e-2,-9.0./5.44e2,1.430084745762712e-2,-5.450581395348837e-2,-9.191176470588235e-4,7.944915254237288e-4,-5.450581395348837e-3,1.0./5.44e2,-1.588983050847458e-3,2.180232558139535e-3,2.297794117647059e-4,-1.986228813559322e-4,2.725290697674419e-4],[3,11]); +end +if nargout > 2 + t2 = [1.7e1./4.8e1,5.9e1./4.8e1,4.3e1./4.8e1,4.9e1./4.8e1]; + HcU = t2; +end +if nargout > 3 + HfU = t2; +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/+implementations/intOpAWW_orders_6to6_ratio2to1.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,47 @@ +function [IC2F,IF2C,Hc,Hf] = IntOp_orders_6to6_ratio2to1(mc,hc,ACC) + +% ACC is a string. +% ACC = 'C2F' creates IC2F with one order of accuracy higher than IF2C. +% ACC = 'F2C' creates IF2C with one order of accuracy higher than IC2F. +ratio = 2; +mf = ratio*mc-1; +hf = hc/ratio; + +switch ACC + case 'F2C' + [stencil_F2C,BC_F2C,HcU,HfU] = ... + sbp.implementations.intOpAWW_orders_6to6_ratio_2to1_accC2F3_accF2C4; + case 'C2F' + [stencil_F2C,BC_F2C,HcU,HfU] = ... + sbp.implementations.intOpAWW_orders_6to6_ratio_2to1_accC2F4_accF2C3; +end + +stencil_width = length(stencil_F2C); +stencil_hw = (stencil_width-1)/2; +[BC_rows,BC_cols] = size(BC_F2C); + +%%% Norm matrices %%% +Hc = speye(mc,mc); +HcUm = length(HcU); +Hc(1:HcUm,1:HcUm) = spdiags(HcU',0,HcUm,HcUm); +Hc(mc-HcUm+1:mc,mc-HcUm+1:mc) = spdiags(rot90(HcU',2),0,HcUm,HcUm); +Hc = Hc*hc; + +Hf = speye(mf,mf); +HfUm = length(HfU); +Hf(1:HfUm,1:HfUm) = spdiags(HfU',0,HfUm,HfUm); +Hf(mf-length(HfU)+1:mf,mf-length(HfU)+1:mf) = spdiags(rot90(HfU',2),0,HfUm,HfUm); +Hf = Hf*hf; +%%%%%%%%%%%%%%%%%%%%%% + +%%% Create IF2C from stencil and BC +IF2C = sparse(mc,mf); +for i = BC_rows+1 : mc-BC_rows + IF2C(i,ratio*i-1+(-stencil_hw:stencil_hw)) = stencil_F2C; %#ok<SPRIX> +end +IF2C(1:BC_rows,1:BC_cols) = BC_F2C; +IF2C(end-BC_rows+1:end,end-BC_cols+1:end) = rot90(BC_F2C,2); +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%% Create IC2F using symmetry condition %%%% +IC2F = Hf\IF2C.'*Hc; \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/+implementations/intOpAWW_orders_6to6_ratio_2to1_accC2F3_accF2C4.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,18 @@ +function [stencil_F2C,BC_F2C,HcU,HfU] = intOpAWW_orders_6to6_ratio_2to1_accC2F3_accF2C4 +%INT_ORDERS_6TO6_RATIO_2TO1_ACCC2F3_ACCF2C4_STENCIL_13_BC_3_17 +% [STENCIL_F2C,BC_F2C,HCU,HFU] = INT_ORDERS_6TO6_RATIO_2TO1_ACCC2F3_ACCF2C4_STENCIL_13_BC_3_17 + +% This function was generated by the Symbolic Math Toolbox version 8.0. +% 21-May-2018 15:35:47 + +stencil_F2C = [-5.95703125e-3,3.0./5.12e2,3.57421875e-2,-2.5e1./5.12e2,-8.935546875e-2,7.5e1./2.56e2,3.17e2./5.12e2,7.5e1./2.56e2,-8.935546875e-2,-2.5e1./5.12e2,3.57421875e-2,3.0./5.12e2,-5.95703125e-3]; +if nargout > 1 + BC_F2C = reshape([5.233890618131365e-1,-1.594459192645467e-2,3.532688727637403e-2,8.021234957689208e-1,3.90683205173562e-1,-1.73222951632239e-1,-8.87662686483442e-2,2.90091235796637e-1,-1.600356115709148e-1,-1.044025375027475e-1,2.346179009198368e-1,6.091329306528956e-1,1.561275522703128e-1,-1.168382445709856e-1,1.040987887887311,-2.387061036980731e-1,1.363504965974361e-1,1.082611928255256e-1,-5.745310654054326e-1,3.977694249198785e-1,-9.376217911402619e-1,3.554518646054656e-2,5.609157787396987e-5,-1.564625311232018e-1,6.107907974027401e-1,-3.786608696698368e-1,7.02265869951125e-1,2.054294270642538e-1,-1.302300112378257e-1,2.478941407690889e-1,-2.657085326191479e-1,1.568761445933572e-1,-2.632906518005349e-1,-1.228047556139644e-1,7.182193248980271e-2,-1.1291238242346e-1,5.811258780405158e-2,-3.466364400805378e-2,5.683680203338252e-2,1.781337575097077e-2,-1.030572999042704e-2,1.577197067502767e-2,-1.443802115768554e-2,8.391316308374261e-3,-1.29534117369052e-2,-1.548018627738296e-3,8.794183904936319e-4,-1.298961407229805e-3,1.573818938200601e-3,-8.940753636685258e-4,1.320610764016968e-3],[3,17]); +end +if nargout > 2 + t2 = [3.159490740740741e-1,1.390393518518519,6.275462962962963e-1,1.240509259259259,9.116898148148148e-1,1.013912037037037]; + HcU = t2; +end +if nargout > 3 + HfU = t2; +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/+implementations/intOpAWW_orders_6to6_ratio_2to1_accC2F4_accF2C3.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,18 @@ +function [stencil_F2C,BC_F2C,HcU,HfU] = intOpAWW_orders_6to6_ratio_2to1_accC2F4_accF2C3 +%INT_ORDERS_6TO6_RATIO_2TO1_ACCC2F4_ACCF2C3_STENCIL_13_BC_4_17 +% [STENCIL_F2C,BC_F2C,HCU,HFU] = INT_ORDERS_6TO6_RATIO_2TO1_ACCC2F4_ACCF2C3_STENCIL_13_BC_4_17 + +% This function was generated by the Symbolic Math Toolbox version 8.0. +% 21-May-2018 15:35:56 + +stencil_F2C = [1.07421875e-3,3.0./5.12e2,-6.4453125e-3,-2.5e1./5.12e2,1.611328125e-2,7.5e1./2.56e2,2.45e2./5.12e2,7.5e1./2.56e2,1.611328125e-2,-2.5e1./5.12e2,-6.4453125e-3,3.0./5.12e2,1.07421875e-3]; +if nargout > 1 + BC_F2C = reshape([1.0./2.0,0.0,0.0,0.0,6.876076086160158e-1,1.5e1./3.2e1,-3.461879841386942e-1,3.502577439820862e-2,3.099721991995751e-3,2.228547003766753e-1,9.363652999354482e-3,-3.15791046603844e-3,-1.05789143206462e-1,2.35563165945226e-1,6.070385985337514e-1,-4.847496617839149e-2,-4.809232246867902e-3,5.154694068405061e-3,7.049223649022501e-1,1.016749349808733e-2,3.460117842882262e-2,-4.996621498584866e-2,5.210650763094799e-1,2.233592875303228e-1,-2.239024779745769e-3,4.254668119953384e-4,9.213872590833641e-3,3.910524351558127e-1,-9.048711215107334e-2,8.597375629526346e-2,-3.468219752858724e-1,3.250682992395969e-1,-1.309107466664224e-1,1.199249722306043e-1,-4.071552384959425e-1,1.474417123938701e-1,-3.02863877390285e-2,3.046016554982103e-2,-1.081315128181483e-1,1.120705238850532e-2,7.977722870036266e-2,-6.772545887788229e-2,2.00270418837606e-1,-5.427183680490763e-2,6.524845570188292e-2,-5.637610037043203e-2,1.711235764016968e-1,-4.203646902407166e-2,4.639548341453586e-3,-4.055884445496545e-3,1.258630924935448e-2,-2.776451559292779e-3,-1.023784366070774e-2,8.817108288936985e-3,-2.659664906860937e-2,7.14445034054861e-3,-1.435466025441424e-3,1.240274208149505e-3,-3.764718680837329e-3,1.028716295017727e-3,1.032012418492197e-3,-8.794183904936319e-4,2.597922814459609e-3,-6.571159498040679e-4,1.892022767235695e-4,-1.612267049238325e-4,4.76285849317595e-4,-1.204712574640791e-4],[4,17]); +end +if nargout > 2 + t2 = [3.159490740740741e-1,1.390393518518519,6.275462962962963e-1,1.240509259259259,9.116898148148148e-1,1.013912037037037]; + HcU = t2; +end +if nargout > 3 + HfU = t2; +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/+implementations/intOpAWW_orders_8to8_ratio2to1.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,47 @@ +function [IC2F,IF2C,Hc,Hf] = IntOp_orders_8to8_ratio2to1(mc,hc,ACC) + +% ACC is a string. +% ACC = 'C2F' creates IC2F with one order of accuracy higher than IF2C. +% ACC = 'F2C' creates IF2C with one order of accuracy higher than IC2F. +ratio = 2; +mf = ratio*mc-1; +hf = hc/ratio; + +switch ACC + case 'F2C' + [stencil_F2C,BC_F2C,HcU,HfU] = ... + sbp.implementations.intOpAWW_orders_8to8_ratio_2to1_accC2F4_accF2C5; + case 'C2F' + [stencil_F2C,BC_F2C,HcU,HfU] = ... + sbp.implementations.intOpAWW_orders_8to8_ratio_2to1_accC2F5_accF2C4; +end + +stencil_width = length(stencil_F2C); +stencil_hw = (stencil_width-1)/2; +[BC_rows,BC_cols] = size(BC_F2C); + +%%% Norm matrices %%% +Hc = speye(mc,mc); +HcUm = length(HcU); +Hc(1:HcUm,1:HcUm) = spdiags(HcU',0,HcUm,HcUm); +Hc(mc-HcUm+1:mc,mc-HcUm+1:mc) = spdiags(rot90(HcU',2),0,HcUm,HcUm); +Hc = Hc*hc; + +Hf = speye(mf,mf); +HfUm = length(HfU); +Hf(1:HfUm,1:HfUm) = spdiags(HfU',0,HfUm,HfUm); +Hf(mf-length(HfU)+1:mf,mf-length(HfU)+1:mf) = spdiags(rot90(HfU',2),0,HfUm,HfUm); +Hf = Hf*hf; +%%%%%%%%%%%%%%%%%%%%%% + +%%% Create IF2C from stencil and BC +IF2C = sparse(mc,mf); +for i = BC_rows+1 : mc-BC_rows + IF2C(i,ratio*i-1+(-stencil_hw:stencil_hw)) = stencil_F2C; %#ok<SPRIX> +end +IF2C(1:BC_rows,1:BC_cols) = BC_F2C; +IF2C(end-BC_rows+1:end,end-BC_cols+1:end) = rot90(BC_F2C,2); +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%% Create IC2F using symmetry condition %%%% +IC2F = Hf\IF2C.'*Hc; \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/+implementations/intOpAWW_orders_8to8_ratio_2to1_accC2F4_accF2C5.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,18 @@ +function [stencil_F2C,BC_F2C,HcU,HfU] = intOpAWW_orders_8to8_ratio_2to1_accC2F4_accF2C5 +%INT_ORDERS_8TO8_RATIO_2TO1_ACCC2F4_ACCF2C5_STENCIL_17_BC_5_24 +% [STENCIL_F2C,BC_F2C,HCU,HFU] = INT_ORDERS_8TO8_RATIO_2TO1_ACCC2F4_ACCF2C5_STENCIL_17_BC_5_24 + +% This function was generated by the Symbolic Math Toolbox version 8.0. +% 21-May-2018 15:35:02 + +stencil_F2C = [1.324608212425595e-3,-1.220703125e-3,-1.059686569940476e-2,1.1962890625e-2,3.708902994791667e-2,-5.9814453125e-2,-7.417805989583333e-2,2.99072265625e-1,5.927225748697917e-1,2.99072265625e-1,-7.417805989583333e-2,-5.9814453125e-2,3.708902994791667e-2,1.1962890625e-2,-1.059686569940476e-2,-1.220703125e-3,1.324608212425595e-3]; +if nargout > 1 + BC_F2C = reshape([2.087365925359584,-1.227221822236823,1.090916714284468e1,-1.041312149906314,1.134214373258162,-1.269686811479259,2.075368250436277,-1.520771409696474e1,1.389750473974189,-1.48485748783569,-1.040579640776707,8.899721508624742e-1,-7.177691661032869,6.882712043721976e-1,-7.599347599660409e-1,-1.26440526850463,1.160658043364166,-5.391509178445742,6.679923135342851e-1,-7.521725463922262e-1,3.752349810676949,-2.906684049793639,2.672876913566556e1,-2.493145660873,2.782825829667436,1.443588084644871e-1,-1.307230271348211e-1,2.216804748506809,1.437719804483573e-1,-1.145830952112369e-1,3.2149320801083e-1,-2.34361439272989e-1,1.855837403850803,1.286992417665136e-1,-5.758238484341108e-2,-1.301103772185027,9.973408313121463e-1,-8.837520107531879,9.534930382604288e-1,-1.429199518808459e-2,-2.384453600787036,1.818345997558567,-1.577342441239303e1,1.422846302346762,3.154159322410927e-3,3.589377915408905e-1,-2.109524979864723e-1,9.363227187483732e-1,6.301238593470628e-2,5.732390257964316e-2,2.793582225299658,-2.033528056927806,1.621324028555783e1,-1.189222718426265,6.189671387692164e-2,5.342131492864642e-1,-4.222231296997605e-1,3.787253511209165,-3.350064226195165e-1,1.245325350855226e-2,-2.184146687275183,1.551331905163865,-1.19387312118926e1,8.349589004472998e-1,-1.35383591594438e-1,-8.014367493869704e-1,5.668415377001197e-1,-4.302842643863972,2.84183319528176e-1,3.83514596570461e-2,9.45794880458861e-1,-6.732638898386457e-1,5.234390273661413,-3.83498639699941e-1,1.440453495443018e-1,5.645065377027613e-1,-4.039220855868618e-1,3.170156487564899,-2.383074337879712e-1,1.216617375214008e-1,-1.937863224145611e-1,1.358891032584724e-1,-1.023378722711107,6.830621267493578e-2,-4.169135139842575e-3,2.270306426219975e-2,-2.38399209865252e-2,2.928388757260058e-1,-4.02060181933195e-2,6.880595419697505e-2,9.638828970166005e-2,-6.98778025332229e-2,5.609317796857676e-1,-4.429526993510467e-2,2.882554468024363e-2,3.582431391759518e-2,-2.671910644265286e-2,2.251335440088556e-1,-1.966486325944329e-2,1.791756577091828e-2,-3.350790201878844e-1,2.581411034605136e-1,-2.283079071439122,2.162064132948073e-1,-2.321676317817421e-1,6.356644993195555e-2,-4.921907141164279e-2,4.384534411523264e-1,-4.198474091936761e-2,4.597203884996652e-2,2.261662512481835e-2,-1.740429407604355e-2,1.537038474929879e-1,-1.452709057733876e-2,1.556101844926456e-2,3.097679325854209e-2,-2.394872918869654e-2,2.128879105995857e-1,-2.032077838507769e-2,2.213372706946953e-2],[5,24]); +end +if nargout > 2 + t2 = [2.948906761778786e-1,1.525720623897707,2.57452876984127e-1,1.798113701499118,4.127080577601411e-1,1.278484623015873,9.232955798059965e-1,1.009333860859158]; + HcU = t2; +end +if nargout > 3 + HfU = t2; +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/+implementations/intOpAWW_orders_8to8_ratio_2to1_accC2F5_accF2C4.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,18 @@ +function [stencil_F2C,BC_F2C,HcU,HfU] = intOpAWW_orders_8to8_ratio_2to1_accC2F5_accF2C4 +%INT_ORDERS_8TO8_RATIO_2TO1_ACCC2F5_ACCF2C4_STENCIL_17_BC_6_24 +% [STENCIL_F2C,BC_F2C,HCU,HFU] = INT_ORDERS_8TO8_RATIO_2TO1_ACCC2F5_ACCF2C4_STENCIL_17_BC_6_24 + +% This function was generated by the Symbolic Math Toolbox version 8.0. +% 21-May-2018 15:35:39 + +stencil_F2C = [-2.564929780505952e-4,-1.220703125e-3,2.051943824404762e-3,1.1962890625e-2,-7.181803385416667e-3,-5.9814453125e-2,1.436360677083333e-2,2.99072265625e-1,4.820454915364583e-1,2.99072265625e-1,1.436360677083333e-2,-5.9814453125e-2,-7.181803385416667e-3,1.1962890625e-2,2.051943824404762e-3,-1.220703125e-3,-2.564929780505952e-4]; +if nargout > 1 + BC_F2C = reshape([-1.673327822994457e1,1.665420585653232e1,-1.973927473454954e2,2.826257908914756e1,-6.156813484052936e1,3.974966126696054,2.880639373222355e1,-2.660797294399895e1,3.202303847857831e2,-4.598960974033412e1,1.003152507870138e2,-6.481221721577338,8.061874893005659,-7.706608975219419,9.234201483040626e1,-1.322147613066874e1,2.880209985918895e1,-1.859523138300886,-2.19528557898034e1,2.13763239391502e1,-2.476320412310993e2,3.572924955195535e1,-7.795290920161567e1,5.036097395109802,-1.287197329845376,1.244100160910233,-1.394684346537857e1,2.112320869857597,-4.60441856527933,2.978264879234002e-1,1.935199269380359,-1.88580031845933,2.330807783420723e1,-2.91749306966336,6.644427567385864,-4.302395355488564e-1,-1.148984264037686,1.109982778464842,-1.314799057941425e1,2.137017065505111,-4.084082382904703,2.606486561845403e-1,1.565462612018858,-1.508309105065004,1.772442871757061e1,-2.40060893717649,6.31422909250156,-4.052444871368164e-1,3.179380137695096e-1,-3.071741522636364e-1,3.636264382483117,-5.183996466001354e-1,2.322192602480252,-6.467931586900172e-2,6.277081831671831e-1,-6.107890751034906e-1,7.335850436798604,-1.091016872160133,3.089218691662174,6.988892111841499e-2,1.639756762532723,-1.583883992641009,1.876236237708381e1,-2.685390559486947,5.859855615166555,3.919312696253764e-3,1.611803934956753,-1.540778869185931,1.795955382224485e1,-2.495154500270907,5.003492494640851,-4.157919873785453e-2,-6.213413520816026e-1,6.242581523412814e-1,-7.823535324240331,1.222418137438074,-3.120142966701915,2.975831327541895e-1,2.12230710100161,-2.0451058741188,2.412395225004063e1,-3.423544496956294,7.325914828631551,-4.793445914188063e-1,-4.31809447483846,4.158975059021769,-4.906211424150023e1,6.975058620124194,-1.501259943091044e1,9.418983630154896e-1,-6.138797742037704e-1,5.810969368378602e-1,-6.6821474226667,9.113864351863538e-1,-1.814400062103318,1.002574935832871e-1,-9.860044240994036e-2,9.448685284232805e-2,-1.106188847377502,1.552858946803229e-1,-3.265426230113952e-1,2.062042480203908e-2,-2.745034502159738,2.655226942873441,-3.151193386341271e1,4.520932327069998,-9.883338555855938,6.423439846307804e-1,2.139968493382333,-2.067738462547628,2.450223844197562e1,-3.50699574523559,7.635005983192545,-4.923960464980415e-1,1.036406872394752,-1.002008838408551,1.188339891704641e1,-1.70302259679446,3.715789696036691,-2.407301455417931e-1,1.606428513214277,-1.552524985439685,1.840245870449254e1,-2.635131753653705,5.741508438443495,-3.708346905830083e-1,5.659562678739624e-2,-5.465656201303744e-2,6.471932864664631e-1,-9.253169145609999e-2,2.010909570941804e-1,-1.292046400706276e-2,5.435391241988039e-1,-5.252672844681129e-1,6.225561585258754,-8.91344337215917e-1,1.941632399616401,-1.253426955105431e-1,-1.552116972709218,1.499962759958308,-1.777819805127299e1,2.545472086708348,-5.545140384142844,3.580057322157566e-1],[6,24]); +end +if nargout > 2 + t2 = [2.948906761778786e-1,1.525720623897707,2.57452876984127e-1,1.798113701499118,4.127080577601411e-1,1.278484623015873,9.232955798059965e-1,1.009333860859158]; + HcU = t2; +end +if nargout > 3 + HfU = t2; +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/+implementations/intOpMC_orders_2to2_ratio2to1.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,35 @@ +function [IC2F,IF2C] = intOpMC_orders_2to2_ratio2to1(mc) + +mf = 2*(mc-1) + 1; + +stencil_F2C = [1.0./4.0,1.0./2.0,1.0./4.0]; +stencil_width = length(stencil_F2C); +stencil_halfwidth = (stencil_width-1)/2; + +BC_F2C = [1.0./2.0,1.0./2.0]; + +Hc = speye(mc,mc); +Hc(1,1) = 1/2; +Hc(end,end) = 1/2; + +Hf = 1/2*speye(mf,mf); +Hf(1,1) = 1/4; +Hf(end,end) = 1/4; + +IF2C = sparse(mc,mf); +[BCrows, BCcols] = size(BC_F2C); +IF2C(1:BCrows, 1:BCcols) = BC_F2C; +IF2C(mc-BCrows+1:mc, mf-BCcols+1:mf) = rot90(BC_F2C,2); + +for i = BCrows+1 : mc-BCrows + IF2C(i,(2*i-stencil_halfwidth-1) :(2*i+stencil_halfwidth-1))... + = stencil_F2C; +end + +IC2F = Hf\(IF2C'*Hc); + + + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/+implementations/intOpMC_orders_4to4_ratio2to1.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,66 @@ +% Marks New interpolation operators +% 4th order to 2nd order accurate (diagonal norm) +% M=9 is the minimum amount of points on the coarse mesh + +function [IC2F,IF2C] = intOpMC_orders_4to4_ratio2to1(M_C) + +M_F=M_C*2-1; + +% Coarse to fine +I1=zeros(M_F,M_C); +t1=[ 2047/2176 , 129/1088 , -129/2176 , 0 , 0 , 0 , 0 ,... + 0 ;... + 429/944 , 279/472 , -43/944 , 0 , 0 , 0 , 0 , 0 ;... + 111/2752 , 4913/5504 , 3/32 , -147/5504 ,... + 0 , 0 , 0 , 0 ;... + -103/784 , 549/784 , 387/784 , -1/16 , 0 ,... + 0 , 0 , 0 ;... + -335/3072 , 205/768 , 2365/3072 , 49/512 ,... + -3/128 , 0 , 0 , 0 ;... + -9/256 , 5/256 , 129/256 , 147/256 ,... + -1/16 , 0 , 0 , 0 ;... + 5/192 , -59/1024 , 43/512 , 2695/3072 ,... + 3/32 , -3/128 , 0 , 0 ;... + 23/768 , -37/768 , -43/768 , 147/256 ,... + 9/16 , -1/16 , 0 , 0 ;... + 13/2048 , -11/1024 , -43/2048 , 49/512 ,... + 55/64 , 3/32 , -3/128 , 0 ;... + -1/384 , 1/256 , 0 , -49/768 , 9/16 ,... + 9/16 , -1/16 , 0 ;... + -1/1024 , 3/2048 , 0 , -49/2048 , 3/32 ,... + 55/64 , 3/32 , -3/128]; + + +t2=[-3/128 3/32 55/64 3/32 -3/128]; +t3=[-1/16 9/16 9/16 -1/16]; +I1(1:11,1:8)=t1; +I1(M_F-10:M_F,M_C-7:M_C)=fliplr(flipud(t1)); +I1(12,5:8)=t3; +for i=13:2:M_F-12 + j=(i-1)/2; + I1(i,j-1:j+3)=t2; + I1(i+1,j:j+3)=t3; +end + +% Fine to coarse +I2=zeros(M_C,M_F); + +t1=[ 2047/4352 , 429/544 , 111/2176 , -103/544 ... + , -335/2176 , -27/544 , 5/136 , 23/544 ,... + 39/4352 , -1/272 , -3/2176 ;... + 129/7552 , 279/944 , 4913/15104 , 549/1888 ... + , 205/1888 , 15/1888 , -3/128 , -37/1888 ... + , -33/7552 , 3/1888 , 9/15104 ]; +t2=[-3/256 -1/32 3/64 9/32 55/128 9/32 3/64 -1/32 -3/256]; + +I2(1:2,1:11)=t1; + +I2(M_C-1:M_C,M_F-10:M_F)=fliplr(flipud(t1)); + +for i=3:M_C-2 + j=2*(i-3)+1; + I2(i,j:j+8)=t2; +end + +IC2F = sparse(I1); +IF2C = sparse(I2);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/+implementations/intOpMC_orders_6to6_ratio2to1.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,115 @@ +% Marks New interpolation operators +% 6th order accurate (diagonal norm) +% M=19 is the minimum amount of points on the coarse mesh + +function [IC2F,IF2C] = intOpMC_orders_6to6_ratio2to1(M_C) + +M_F=M_C*2-1; + +% Coarse to fine +I1=zeros(M_F,M_C); + +t1= [6854313/6988288 , 401925/6988288 , -401925/6988288 ... + , 133975/6988288 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ; ... + 560547/1537664 , 1201479/1537664 , -240439/1537664 ... + , 16077/1537664 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ; ... + 203385/5552128 , 1225647/1388032 , 364155/2776064 ... + , -80385/1388032 , 39385/5552128 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ; ... + -145919/2743808 , 721527/1371904 , 105687/171488 , ... + -25/256 , 23631/2743808 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ; ... + -178863/4033024 , 1178085/8066048 , ... + 1658587/2016512 , 401925/4033024 , -15/512 , ... + 43801/8066048 , 0 , 0 , 0 , 0 , 0 , 0 ; ... + -1668147/11213056 , 4193225/11213056 , ... + 375675/2803264 , 2009625/2803264 , ... + -984625/11213056 , 3/256 , 0 , 0 , 0 , 0 , 0 , 0 ; ... + -561187/2949120 , 831521/1474560 , -788801/1474560 ... + , 412643/368640 , 39385/589824 , -43801/1474560 ... + , 5/1024 , 0 , 0 , 0 , 0 , 0 ; ... + 23/1024 , 23/147456 , -43435/221184 , ... + 26795/36864 , 39385/73728 , -43801/442368 , ... + 3/256 , 0 , 0 , 0 , 0 , 0 ; ... + 79379/368640 , -1664707/2949120 , 284431/737280 , ... + 26795/294912 , 606529/737280 , 43801/589824 , ... + -15/512 , 5/1024 , 0 , 0 , 0 , 0 ; ... + 3589/27648 , -2225/6144 , 22939/73728 , ... + -26795/221184 , 39385/73728 , 43801/73728 , ... + -25/256 , 3/256 , 0 , 0 , 0 , 0 ; ... + -720623/14745600 , 10637/92160 , -89513/1474560 , ... + -5359/147456 , 39385/589824 , 3372677/3686400 , ... + 75/1024 , -15/512 , 5/1024 , 0 , 0 , 0 ; ... + -6357/81920 , 55219/276480 , -8707/61440 , ... + 5359/368640 , -39385/442368 , 43801/73728 , ... + 75/128 , -25/256 , 3/256 , 0 , 0 , 0 ; ... + -13315/884736 , 2589/65536 , -479/16384 , ... + 5359/884736 , -7877/294912 , 43801/589824 , ... + 231/256 , 75/1024 , -15/512 , 5/1024 , 0 , 0 ; ... + 8299/737280 , -7043/245760 , 5473/276480 , 0 , ... + 7877/737280 , -43801/442368 , 75/128 , ... + 75/128 , -25/256 , 3/256 , 0 , 0 ; ... + 11027/2949120 , -8461/884736 , 655/98304 , 0 , ... + 7877/1769472 , -43801/1474560 , 75/1024 , ... + 231/256 , 75/1024 , -15/512 , 5/1024 , 0 ; ... + -601/614400 , 601/245760 , -601/368640 , 0 , 0 , ... + 43801/3686400 , -25/256 , 75/128 , ... + 75/128 , -25/256 , 3/256 , 0 ; ... + -601/1474560 , 601/589824 , -601/884736 , 0 , 0 , ... + 43801/8847360 , -15/512 , 75/1024 , ... + 231/256 , 75/1024 , -15/512 , 5/1024 ] ; + + t2= [5/1024 , -15/512 , 75/1024, 231/256 , 75/1024 , -15/512 , 5/1024]; + + t3= [3/256 , -25/256 , 75/128 , 75/128 , -25/256 , 3/256]; + +I1(1:17,1:12)=t1; +I1(M_F-16:M_F,M_C-11:M_C)=fliplr(flipud(t1)); +I1(18,7:12)=t3; +for i=19:2:M_F-18 + j=(i-3)/2; + I1(i,j-1:j+5)=t2; + I1(i+1,j:j+5)=t3; +end + +% Fine to coarse +I2=zeros(M_C,M_F); + +t1=[6854313/13976576 , 2802735/3494144 , ... + 1016925/27953152 , -729595/6988288 , ... + -894315/13976576 , -1668147/6988288 , ... + -8417805/27953152 , 15525/436768 , ... + 1190685/3494144 , 89725/436768 , ... + -2161869/27953152 , -858195/6988288 , ... + -332875/13976576 , 124485/6988288 , ... + 165405/27953152 , -5409/3494144 , -9015/13976576; ... + 80385/12301312 , 1201479/3075328 , 1225647/6150656 ... + , 721527/3075328 , 1178085/24602624 , ... + 838645/6150656 , 60843/300032 , 345/6150656 , ... + -4994121/24602624 , -100125/768832 , ... + 31911/768832 , 55219/768832 , 349515/24602624 , ... + -63387/6150656 , -42305/12301312 , 5409/6150656 ... + , 9015/24602624 ; ... + -80385/5552128 , -240439/1388032 , 364155/5552128 ... + , 105687/173504 , 1658587/2776064 , 75135/694016 ... + , -2366403/5552128 , -217175/1388032 , ... + 853293/2776064 , 344085/1388032 , ... + -268539/5552128 , -78363/694016 , -64665/2776064 ... + , 5473/347008 , 29475/5552128 , -1803/1388032 , ... + -3005/5552128]; + + + + t2=[ 5/2048 , 3/512 , -15/1024 , -25/512 , ... + 75/2048 , 75/256 , 231/512 , 75/256 , ... + 75/2048 , -25/512 , -15/1024 , 3/512 , 5/2048]; + +I2(1:3,1:17)=t1; + +I2(M_C-2:M_C,M_F-16:M_F)=fliplr(flipud(t1)); + +for i=4:M_C-3 + j=2*(i-4)+1; + I2(i,j:j+12)=t2; +end +IC2F = sparse(I1); +IF2C = sparse(I2); +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/+implementations/intOpMC_orders_8to8_ratio2to1.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,53 @@ +% Marks New interpolation operators +% 8th order accurate (diagonal norm) +% M=19 is the minimum amount of points on the coarse mesh + +function [IC2F,IF2C] = intOpMC_orders_8to8_ratio2to1(M_C) + +M_F=M_C*2-1; + +% Coarse to fine +I1=zeros(M_F,M_C); + +t1= [0.99340647972821530406e0 0.26374081087138783775e-1 -0.39561121630708175663e-1 0.26374081087138783775e-1 -0.65935202717846959438e-2 0 0 0 0 0 0 0 0 0 0 0; 0.31183959860287729600e0 0.94014160558849081601e0 -0.31646240838273622401e0 0.65141605588490816007e-1 -0.66040139712270400169e-3 0 0 0 0 0 0 0 0 0 0 0; -0.33163591467432411328e-1 0.11092588191512759415e1 -0.10539936193077965253e0 -0.77189144409925778387e-2 0.60418595406382404105e-1 -0.23395546718453703858e-1 0 0 0 0 0 0 0 0 0 0; -0.63951987538041216890e-1 0.56657207530367360435e0 0.56073157416571775151e0 -0.67107298938782711711e-1 0.54915118559238359570e-2 -0.17358748484912632117e-2 0 0 0 0 0 0 0 0 0 0; 0.22970968995770386894e0 -0.84424237330911973043e0 0.20693327723706358111e1 -0.42910115554542331920e0 -0.13191478386190563918e0 0.11675567167691342983e0 -0.10539821288804421121e-1 0 0 0 0 0 0 0 0 0; 0.10195433776615307267e0 -0.45344410547614678949e0 0.11049699103276728065e1 0.26297465812771521534e0 -0.38617448080010680341e-1 0.23925781250000000000e-1 -0.17631339153836246986e-2 0 0 0 0 0 0 0 0 0; -0.33882356049961665258e0 0.12718893449497745294e1 -0.16822328941798626751e1 0.17813590728082409984e1 0.11793036905675500906e0 -0.18266200597575250398e0 0.37689938246258754051e-1 -0.51502644057974593120e-2 0 0 0 0 0 0 0 0; -0.50400650482311136546e0 0.19901277318227816880e1 -0.29708252195230746436e1 0.23722122500767090037e1 0.24457622727717445252e0 -0.15152936311741758892e0 0.21886284536938453771e-1 -0.24414062500000000000e-2 0 0 0 0 0 0 0 0; 0.37882732714731866331e-2 0.12115606818363056270e0 -0.53924884156527999826e0 0.88886598075786086512e0 0.27660232216640139169e0 0.33730204543181760125e0 -0.12179633685076087365e0 0.38041730885639608773e-1 -0.47112422807823442564e-2 0 0 0 0 0 0 0; 0.41123781086486062886e0 -0.14418811327145423418e1 0.16793759240044487847e1 -0.57156511000645013503e0 0.24685906775203751929e0 0.76471858554416232639e0 -0.11045284035765094522e0 0.24149101163134162809e-1 -0.24414062500000000000e-2 0 0 0 0 0 0 0; 0.36463669929508579110e0 -0.13698743320477484358e1 0.18268133133896437122e1 -0.93074264690533336964e0 0.10888458847499176143e0 0.85685706622610101431e0 0.24359267370152174731e0 -0.13314605809973863070e0 0.37689938246258754051e-1 -0.47112422807823442564e-2 0 0 0 0 0 0; 0.25541802394537278164e0 -0.10497853549910180363e1 0.15921730465359157986e1 -0.96615555845660927855e0 -0.49371813550407503858e-1 0.76471858554416232639e0 0.55226420178825472608e0 -0.12074550581567081404e0 0.23925781250000000000e-1 -0.24414062500000000000e-2 0 0 0 0 0 0; -0.93469656691661424206e-1 0.26634337856674539612e0 -0.17694629839462736800e0 -0.64947940656920645005e-1 -0.54442294237495880713e-1 0.33730204543181760125e0 0.61880473767909428853e0 0.26629211619947726141e0 -0.13191478386190563918e0 0.37689938246258754051e-1 -0.47112422807823442564e-2 0 0 0 0 0; -0.49445400002561969522e0 0.18168098496802059221e1 -0.23462477366129557292e1 0.11091140417405116705e1 0.98743627100815007716e-2 -0.15294371710883246528e0 0.55226420178825472608e0 0.60372752907835407022e0 -0.11962890625000000000e0 0.23925781250000000000e-1 -0.24414062500000000000e-2 0 0 0 0 0; -0.24633538738293361369e0 0.93021448723433316305e0 -0.12527182680719820488e1 0.63698038058706249354e0 0.15554941210713108775e-1 -0.16865102271590880063e0 0.24359267370152174731e0 0.67646871560981190145e0 0.26382956772381127836e0 -0.13191478386190563918e0 0.37689938246258754051e-1 -0.47112422807823442564e-2 0 0 0 0; 0.23150628239599695492e0 -0.82682792555928440531e0 0.10237569354829334077e1 -0.45129113643047460593e0 -0.10075880316409694665e-2 0.30588743421766493056e-1 -0.11045284035765094522e0 0.60372752907835407022e0 0.59814453125000000000e0 -0.11962890625000000000e0 0.23925781250000000000e-1 -0.24414062500000000000e-2 0 0 0 0; 0.19518658723021413499e0 -0.70515100787561674409e0 0.88870680011413432419e0 -0.40458631782898657259e0 -0.19443676513391385969e-2 0.48186006490259657322e-1 -0.12179633685076087365e0 0.26629211619947726141e0 0.67021304034523590205e0 0.26382956772381127836e0 -0.13191478386190563918e0 0.37689938246258754051e-1 -0.47112422807823442564e-2 0 0 0; -0.43403699494753775353e-1 0.15442805550926787092e0 -0.18997683853068679729e0 0.82584189359473172950e-1 0 -0.31213003491598462302e-2 0.22090568071530189043e-1 -0.12074550581567081404e0 0.59814453125000000000e0 0.59814453125000000000e0 -0.11962890625000000000e0 0.23925781250000000000e-1 -0.24414062500000000000e-2 0 0 0; -0.58783367481931040778e-1 0.20994477957758583150e0 -0.25976152530269196017e0 0.11403438083569734975e0 0 -0.60232508112824571652e-2 0.34798953385931678187e-1 -0.13314605809973863070e0 0.26382956772381127836e0 0.67021304034523590205e0 0.26382956772381127836e0 -0.13191478386190563918e0 0.37689938246258754051e-1 -0.47112422807823442564e-2 0 0; 0.63390647713259204145e-2 -0.22373993350504987875e-1 0.27185871992161665013e-1 -0.11561529976981026786e-1 0 0 -0.22541395991357335758e-2 0.24149101163134162809e-1 -0.11962890625000000000e0 0.59814453125000000000e0 0.59814453125000000000e0 -0.11962890625000000000e0 0.23925781250000000000e-1 -0.24414062500000000000e-2 0 0; 0.10649583863025939259e-1 -0.37634916628131671889e-1 0.45812371547331598336e-1 -0.19540204529147604911e-1 0 0 -0.43498691732414597734e-2 0.38041730885639608773e-1 -0.13191478386190563918e0 0.26382956772381127836e0 0.67021304034523590205e0 0.26382956772381127836e0 -0.13191478386190563918e0 0.37689938246258754051e-1 -0.47112422807823442564e-2 0; -0.45575492476359756866e-3 0.15951422366725914903e-2 -0.19141706840071097884e-2 0.79757111833629574515e-3 0 0 0 -0.24641939962381798784e-2 0.23925781250000000000e-1 -0.11962890625000000000e0 0.59814453125000000000e0 0.59814453125000000000e0 -0.11962890625000000000e0 0.23925781250000000000e-1 -0.24414062500000000000e-2 0; -0.87948159845213680356e-3 0.30781855945824788125e-2 -0.36938227134989745750e-2 0.15390927972912394062e-2 0 0 0 -0.47552163607049510966e-2 0.37689938246258754051e-1 -0.13191478386190563918e0 0.26382956772381127836e0 0.67021304034523590205e0 0.26382956772381127836e0 -0.13191478386190563918e0 0.37689938246258754051e-1 -0.47112422807823442564e-2;]; + + + t2= [-0.456778318652801649905139026187255979136056340856723240855601037075101451671715366e81 / 0.96954962498118328965695036971472316719781487805298788537830810438965808195608854955e83 0.3654226549222413199241112209498047833088450726853785926844808296600811613373722928e82 / 0.96954962498118328965695036971472316719781487805298788537830810438965808195608854955e83 -0.1827113274611206599620556104749023916544225363426892963422404148300405806686861464e82 / 0.13850708928302618423670719567353188102825926829328398362547258634137972599372693565e83 0.3654226549222413199241112209498047833088450726853785926844808296600811613373722928e82 / 0.13850708928302618423670719567353188102825926829328398362547258634137972599372693565e83 0.1856585148354920384923865861096125662293072684152233190798249652677391616531107981e82 / 0.2770141785660523684734143913470637620565185365865679672509451726827594519874538713e82 0.3654226549222413199241112209498047833088450726853785926844808296600811613373722928e82 / 0.13850708928302618423670719567353188102825926829328398362547258634137972599372693565e83 -0.1827113274611206599620556104749023916544225363426892963422404148300405806686861464e82 / 0.13850708928302618423670719567353188102825926829328398362547258634137972599372693565e83 0.3654226549222413199241112209498047833088450726853785926844808296600811613373722928e82 / 0.96954962498118328965695036971472316719781487805298788537830810438965808195608854955e83 -0.456778318652801649905139026187255979136056340856723240855601037075101451671715366e81 / 0.96954962498118328965695036971472316719781487805298788537830810438965808195608854955e83;]; + + t3= [-0.5e1 / 0.2048e4 0.49e2 / 0.2048e4 -0.245e3 / 0.2048e4 0.1225e4 / 0.2048e4 0.1225e4 / 0.2048e4 -0.245e3 / 0.2048e4 0.49e2 / 0.2048e4 -0.5e1 / 0.2048e4;]; +I1(1:23,1:16)=t1; +I1(M_F-22:M_F,M_C-15:M_C)=fliplr(flipud(t1)); +I1(24,9:16)=t3; +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%DEBUGGING + +for i=25:2:M_F-24 + j=(i-3)/2; + I1(i,j-2:j+6)=t2; + I1(i+1,j-1:j+6)=t3; +end + +% Fine to coarse: A +I2=zeros(M_C,M_F); + +t1=[0.49670323986410765203e0 0.80670591743192512511e0 -0.14476656476698073533e-1 -0.19497555250083395132e0 0.16074268813765884450e0 0.22100911221277072755e0 -0.53042418939472250452e0 -0.86254139670456354517e0 0.64231825172866668299e-2 0.69727164011248914487e0 0.61825742343094006838e0 0.43307239695721032895e0 -0.15848187861199173328e0 -0.83836831742920925562e0 -0.41767239062238727391e0 0.39252899650233765024e0 0.33094736964907844809e0 -0.73592865087013788440e-1 -0.99669762780958210515e-1 0.10748160731101219580e-1 0.18056833808814782786e-1 -0.77275234787125894193e-3 -0.14911993994710636483e-2; 0.25487859584304862664e-2 0.47007080279424540800e0 0.93589176759289320118e-1 0.33386224041716468423e0 -0.11418395501435496457e0 -0.18998278818813064037e0 0.38484431284491986603e0 0.65828018436035862232e0 0.39704539050575728856e-1 -0.47252462545568042557e0 -0.44892698918501097924e0 -0.34402935194949605213e0 0.87284452472801643396e-1 0.59539401290875351190e0 0.30484430526276345964e0 -0.27096308216867871783e0 -0.23108785344796321535e0 0.50608234918774219796e-1 0.68801842319351676214e-1 -0.73322707316320135247e-2 -0.12333488857215226757e-1 0.52275043402033040521e-3 0.10087644967132781708e-2; -0.22656973277393401539e-1 -0.93771184228725468159e0 -0.52699680965389826267e-1 0.19581430555012001670e1 0.16586148101136731602e1 0.27435837109255836264e1 -0.30164708462284474624e1 -0.58235016129647971089e1 -0.10472767830023645070e1 0.32615209891555982371e1 0.35478595826728208891e1 0.30921640208240511054e1 -0.34364793368678654581e0 -0.45566547247355317663e1 -0.24329078834671892590e1 0.19882413967858906122e1 0.17259601262271516763e1 -0.36895458453625989435e0 -0.50448363278283993228e0 0.52797763052066775846e-1 0.88972343374038343284e-1 -0.37175165926095403240e-2 -0.71737841052106668688e-2; 0.21626748627943672418e-2 0.27636709246281031633e-1 -0.55259484658035070394e-3 -0.33553649469391355855e-1 -0.49244245327794891233e-1 0.93489376222103426899e-1 0.45734620580442859300e0 0.66579609152388478842e0 0.24716623315221892947e0 -0.15893464065423852815e0 -0.25881084331023040874e0 -0.26865808253702445366e0 -0.18060020510041282529e-1 0.30841043055726240020e0 0.17712461121229459766e0 -0.12549015561536110372e0 -0.11250298507032009025e0 0.22964117700293735857e-1 0.31709446610808019222e-1 -0.32149051440245356510e-2 -0.54335286230388551025e-2 0.22177994574852164638e-3 0.42797426992744435493e-3;]; + + + + t2=[-0.23556211403911721282e-2 -0.12207031250000000000e-2 0.18844969123129377026e-1 0.11962890625000000000e-1 -0.65957391930952819589e-1 -0.59814453125000000000e-1 0.13191478386190563918e0 0.29907226562500000000e0 0.33510652017261795103e0 0.29907226562500000000e0 0.13191478386190563918e0 -0.59814453125000000000e-1 -0.65957391930952819589e-1 0.11962890625000000000e-1 0.18844969123129377026e-1 -0.12207031250000000000e-2 -0.23556211403911721282e-2;]; + + +I2(1:4,1:23)=t1; + +I2(M_C-3:M_C,M_F-22:M_F)=fliplr(flipud(t1)); + +for i=5:M_C-4 + j=2*(i-5)+1; + I2(i,j:j+16)=t2; +end + +IC2F = sparse(I1); +IF2C = sparse(I2); + +
--- a/+sbp/D1Gauss.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+sbp/D1Gauss.m Tue Sep 11 15:58:35 2018 +0200 @@ -37,5 +37,9 @@ obj.borrowing = []; end + + function str = string(obj) + str = [class(obj) '_' num2str(obj.order)]; + end end end
--- a/+sbp/D1Nonequidistant.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+sbp/D1Nonequidistant.m Tue Sep 11 15:58:35 2018 +0200 @@ -81,6 +81,11 @@ obj.Q = obj.H*obj.D1 - obj.e_r*obj.e_r' + obj.e_l*obj.e_l'; obj.borrowing = []; + + end + + function str = string(obj) + str = [class(obj) '_' num2str(obj.order)]; end end end
--- a/+sbp/D1Upwind.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+sbp/D1Upwind.m Tue Sep 11 15:58:35 2018 +0200 @@ -53,6 +53,10 @@ obj.borrowing = []; end + + function str = string(obj) + str = [class(obj) '_' num2str(obj.order)]; + end end
--- a/+sbp/D2BlockNorm.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+sbp/D2BlockNorm.m Tue Sep 11 15:58:35 2018 +0200 @@ -50,6 +50,10 @@ obj.m = m; end + + function str = string(obj) + str = [class(obj) '_' num2str(obj.order)]; + end end
--- a/+sbp/D2Standard.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+sbp/D2Standard.m Tue Sep 11 15:58:35 2018 +0200 @@ -64,10 +64,10 @@ obj.m = m; end + + function str = string(obj) + str = [class(obj) '_' num2str(obj.order)]; + end + end end - - - - -
--- a/+sbp/D2Variable.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+sbp/D2Variable.m Tue Sep 11 15:58:35 2018 +0200 @@ -18,7 +18,7 @@ methods function obj = D2Variable(m,lim,order) - + x_l = lim{1}; x_r = lim{2}; L = x_r-x_l; @@ -26,28 +26,48 @@ obj.x = linspace(x_l,x_r,m)'; switch order + + case 6 + + [obj.H, obj.HI, obj.D1, obj.D2, ... + ~, obj.e_l, obj.e_r, ~, ~, ~, ~, ~,... + obj.d1_l, obj.d1_r] = ... + sbp.implementations.d4_variable_6(m, obj.h); + obj.borrowing.M.d1 = 0.1878; + obj.borrowing.R.delta_D = 0.3696; + % Borrowing e^T*D1 - d1 from R + case 4 [obj.H, obj.HI, obj.D1, obj.D2, obj.e_l,... obj.e_r, obj.d1_l, obj.d1_r] = ... sbp.implementations.d2_variable_4(m,obj.h); - obj.borrowing.M.S = 0.2505765857; + obj.borrowing.M.d1 = 0.2505765857; + + obj.borrowing.R.delta_D = 0.577587500088313; + % Borrowing e^T*D1 - d1 from R case 2 [obj.H, obj.HI, obj.D1, obj.D2, obj.e_l,... obj.e_r, obj.d1_l, obj.d1_r] = ... sbp.implementations.d2_variable_2(m,obj.h); - obj.borrowing.M.S = 0.3636363636; + obj.borrowing.M.d1 = 0.3636363636; % Borrowing const taken from Virta 2014 + + obj.borrowing.R.delta_D = 1.000000538455350; + % Borrowing e^T*D1 - d1 from R otherwise error('Invalid operator order %d.',order); end - + obj.borrowing.H11 = obj.H(1,1)/obj.h; % First element in H/h, obj.m = m; obj.M = []; - + end + function str = string(obj) + str = [class(obj) '_' num2str(obj.order)]; end end + end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/D2VariablePeriodic.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,71 @@ +classdef D2VariablePeriodic < sbp.OpSet + properties + D1 % SBP operator approximating first derivative + H % Norm matrix + HI % H^-1 + Q % Skew-symmetric matrix + e_l % Left boundary operator + e_r % Right boundary operator + D2 % SBP operator for second derivative + M % Norm matrix, second derivative + d1_l % Left boundary first derivative + d1_r % Right boundary first derivative + m % Number of grid points. + h % Step size + x % grid + borrowing % Struct with borrowing limits for different norm matrices + end + + methods + function obj = D2VariablePeriodic(m,lim,order) + + x_l = lim{1}; + x_r = lim{2}; + L = x_r-x_l; + obj.h = L/m; + x = linspace(x_l,x_r,m+1)'; + obj.x = x(1:end-1); + + switch order + + case 6 + [obj.H, obj.HI, obj.D1, obj.D2, obj.e_l,... + obj.e_r, obj.d1_l, obj.d1_r] = ... + sbp.implementations.d2_variable_periodic_6(m,obj.h); + obj.borrowing.M.d1 = 0.1878; + obj.borrowing.R.delta_D = 0.3696; + % Borrowing e^T*D1 - d1 from R + + case 4 + [obj.H, obj.HI, obj.D1, obj.D2, obj.e_l,... + obj.e_r, obj.d1_l, obj.d1_r] = ... + sbp.implementations.d2_variable_periodic_4(m,obj.h); + obj.borrowing.M.d1 = 0.2505765857; + + obj.borrowing.R.delta_D = 0.577587500088313; + % Borrowing e^T*D1 - d1 from R + case 2 + [obj.H, obj.HI, obj.D1, obj.D2, obj.e_l,... + obj.e_r, obj.d1_l, obj.d1_r] = ... + sbp.implementations.d2_variable_periodic_2(m,obj.h); + obj.borrowing.M.d1 = 0.3636363636; + % Borrowing const taken from Virta 2014 + + obj.borrowing.R.delta_D = 1.000000538455350; + % Borrowing e^T*D1 - d1 from R + + otherwise + error('Invalid operator order %d.',order); + end + obj.borrowing.H11 = obj.H(1,1)/obj.h; % First element in H/h, + + obj.m = m; + obj.M = []; + end + function str = string(obj) + str = [class(obj) '_' num2str(obj.order)]; + end + end + + +end
--- a/+sbp/D4Compatible.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+sbp/D4Compatible.m Tue Sep 11 15:58:35 2018 +0200 @@ -28,8 +28,8 @@ methods function obj = D4Compatible(m,lim,order) - - + + x_l = lim{1}; x_r = lim{2}; L = x_r-x_l; @@ -68,6 +68,10 @@ end + + function str = string(obj) + str = [class(obj) '_' num2str(obj.order)]; + end end
--- a/+sbp/D4CompatibleVariable.m Tue Sep 11 13:24:08 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +0,0 @@ -classdef D4CompatibleVariable < sbp.OpSet - properties - D1 % SBP operator approximating first derivative - H % Norm matrix - HI % H^-1 - Q % Skew-symmetric matrix - e_l % Left boundary operator - e_r % Right boundary operator - D2 % SBP operator for second derivative - M % Norm matrix, second derivative - d1_l % Left boundary first derivative - d1_r % Right boundary first derivative - D3 % SBP operator for third derivative - Q3 % Skew-symmetric matrix in third derivative - d2_l % Left boundary second derivative - d2_r % Right boundary second derivative - D4 % SBP operator for fourth derivative - M4 % Norm matrix, fourth derivative - d3_l % Left boundary third derivative - d3_r % Right boundary third derivative - m % Number of grid points. - h % Step size - x % grid - borrowing % Struct with borrowing limits for different norm matrices - end - - - - methods - function obj = D4CompatibleVariable(m,lim,order) - - x_l = lim{1}; - x_r = lim{2}; - L = x_r-x_l; - obj.h = L/(m-1); - obj.x = linspace(x_l,x_r,m)'; - - if order == 2 - [obj.H, obj.HI, ~, obj.D2, ~, obj.D4, obj.e_l, obj.e_r,... - obj.M4, ~, obj.d2_l, obj.d2_r, obj.d3_l,... - obj.d3_r, obj.d1_l, obj.d1_r] =... - sbp.implementations.d4_compatible_halfvariable_2(m,obj.h); - obj.borrowing.N.S2 = 1.2500; - obj.borrowing.N.S3 = 0.4000; - elseif order == 4 - [obj.H, obj.HI, obj.D2, obj.D4, obj.e_l, obj.e_r, obj.M4,... - obj.d2_l, obj.d2_r, obj.d3_l, obj.d3_r, obj.d1_l,... - obj.d1_r] =... - sbp.implementations.d4_compatible_halfvariable_4(m,obj.h); - obj.borrowing.N.S2 = 0.5055; - obj.borrowing.N.S3 = 0.9290; - elseif order == 6 - [obj.H, obj.HI, obj.D2, obj.D4, obj.e_l, obj.e_r, obj.M4,... - obj.d2_l, obj.d2_r, obj.d3_l, obj.d3_r, obj.d1_l,... - obj.d1_r] =... - sbp.implementations.d4_compatible_halfvariable_6(m,obj.h); - obj.borrowing.N.S2 = 0.3259; - obj.borrowing.N.S3 = 0.1580; - else - error('Invalid operator order.'); - end - - obj.m = m; - - obj.D1 = []; - obj.D3 = []; - - - end - end - - - -end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/D4Lonely.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,124 @@ +classdef D4Lonely < sbp.OpSet + properties + m % Number of grid points. + h % Step size + x % grid + H % Norm matrix + HI % H^-1 + D4 % SBP operator for fourth derivative + M4 % Norm matrix, fourth derivative + e_l, e_r % Left and right boundary operator + d1_l, d1_r % Left and right boundary first derivative + d2_l, d2_r % Left and right boundary second derivative + d3_l, d3_r % Left and right boundary third derivative + borrowing % Struct with borrowing limits for different norm matrices + opt + order + end + + methods + function obj = D4Lonely(m, lim, order, opt) + default_arg('opt', '') + + obj.opt = opt; + obj.order = order; + + x_l = lim{1}; + x_r = lim{2}; + L = x_r-x_l; + obj.h = L/(m-1); + obj.x = linspace(x_l, x_r,m)'; + + if order == 2 + switch opt + case '' + [H, HI, D1, D2, D4, e_l, e_r, M4, d2_l, d2_r, d3_l, d3_r, d1_l, d1_r] = ... + sbp.implementations.d4_variable_2(m, obj.h); + obj.borrowing.N.S2 = 1.2500; + obj.borrowing.N.S3 = 0.4000; + otherwise + error('Invalid operator option.'); + end + + elseif order == 4 + switch opt + case 'min_boundary_points' + [H, HI, D4, e_l, e_r, M4, d2_l, d2_r, d3_l, d3_r, d1_l, d1_r] = ... + sbp.implementations.d4_lonely_4_min_boundary_points(m, obj.h); + obj.borrowing.N.S2 = 0.6244; + obj.borrowing.N.S3 = 1.3961; + case '' + [H, HI, D1, D2, D4, e_l, e_r, M4, d2_l, d2_r, d3_l, d3_r, d1_l, d1_r] = ... + sbp.implementations.d4_variable_4(m, obj.h); + obj.borrowing.N.S2 = 0.5055; + obj.borrowing.N.S3 = 0.9290; + otherwise + error('Invalid operator option.'); + end + + elseif order == 6 + switch opt + case '2' + [H, HI, D4, e_l, e_r, M4, d2_l, d2_r, d3_l, d3_r, d1_l, d1_r] = ... + sbp.implementations.d4_lonely_6_2(m, obj.h); + obj.borrowing.N.S2 = 0.2931; + obj.borrowing.N.S3 = 0.0807; + case '3' + [H, HI, D4, e_l, e_r, M4, d2_l, d2_r, d3_l, d3_r, d1_l, d1_r] = ... + sbp.implementations.d4_lonely_6_3(m, obj.h); + obj.borrowing.N.S2 = 0.2842; + obj.borrowing.N.S3 = 0.0709; + case 'min_boundary_points' + [H, HI, D4, e_l, e_r, M4, d2_l, d2_r, d3_l, d3_r, d1_l, d1_r] = ... + sbp.implementations.d4_lonely_6_min_boundary_points(m, obj.h); + obj.borrowing.N.S2 = 0.3569; + obj.borrowing.N.S3 = 0.1908; + case '' + [H, HI, D1, D2, D4, e_l, e_r, M4, d2_l, d2_r, d3_l, d3_r, d1_l, d1_r] = ... + sbp.implementations.d4_variable_6(m, obj.h); + obj.borrowing.N.S2 = 0.3259; + obj.borrowing.N.S3 = 0.1580; + otherwise + error('Invalid operator option.'); + end + + elseif order == 8 + switch opt + case 'min_boundary_points' + [H, HI, D4, e_l, e_r, M4, d2_l, d2_r, d3_l, d3_r, d1_l, d1_r] = ... + sbp.implementations.d4_lonely_8_min_boundary_points(m, obj.h); + obj.borrowing.N.S2 = 0.2804; + obj.borrowing.N.S3 = 0.0740; + case '' + [H, HI, D4, e_l, e_r, M4, d2_l, d2_r, d3_l, d3_r, d1_l, d1_r] = ... + sbp.implementations.d4_lonely_8_higher_boundary_order(m, obj.h); + obj.borrowing.N.S2 = 0.2475; + obj.borrowing.N.S3 = 0.0401; + otherwise + error('Invalid operator option.'); + end + else + error('Invalid operator order.'); + end + + obj.m = m; + + obj.H = H; + obj.HI = HI; + obj.D4 = D4; + obj.M4 = M4; + obj.e_l = e_l; + obj.e_r = e_r; + obj.d1_l = d1_l; + obj.d1_r = d1_r; + obj.d2_l = d2_l; + obj.d2_r = d2_r; + obj.d3_l = d3_l; + obj.d3_r = d3_r; + end + + function str = string(obj) + str = [class(obj) '_' num2str(obj.order) '_' obj.opt]; + end + end +end \ No newline at end of file
--- a/+sbp/D4Standard.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+sbp/D4Standard.m Tue Sep 11 15:58:35 2018 +0200 @@ -28,7 +28,7 @@ methods function obj = D4Standard(m,lim,order) - + x_l = lim{1}; x_r = lim{2}; L = x_r-x_l; @@ -56,6 +56,10 @@ obj.m = m; end + + function str = string(obj) + str = [class(obj) '_' num2str(obj.order)]; + end end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/D4Variable.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,75 @@ +classdef D4Variable < sbp.OpSet + properties + m % Number of grid points. + h % Step size + x % grid + H % Norm matrix + HI % H^-1 + D1 % SBP operator approximating first derivative + D2 % SBP operator for second derivative + D4 % SBP operator for fourth derivative + Q % Skew-symmetric matrix + M % Norm matrix, second derivative + M4 % Norm matrix, fourth derivative + e_l, e_r % Left and right boundary operator + d1_l, d1_r % Left and right boundary first derivative + d2_l, d2_r % Left and right boundary second derivative + d3_l, d3_r % Left and right boundary third derivative + borrowing % Struct with borrowing limits for different norm matrices + order + end + + methods + function obj = D4Variable(m, lim, order) + x_l = lim{1}; + x_r = lim{2}; + L = x_r-x_l; + obj.h = L/(m-1); + obj.x = linspace(x_l, x_r,m)'; + + if order == 2 + [H, HI, D1, D2, D4, e_l, e_r, M4, d2_l, d2_r, d3_l, d3_r, d1_l, d1_r] = ... + sbp.implementations.d4_variable_2(m, obj.h); + obj.borrowing.M.d1 = 0.4000; + obj.borrowing.N.S2 = 1.2500; + obj.borrowing.N.S3 = 0.4000; + elseif order == 4 + [H, HI, D1, D2, D4, e_l, e_r, M4, d2_l, d2_r, d3_l, d3_r, d1_l, d1_r] = ... + sbp.implementations.d4_variable_4(m, obj.h); + obj.borrowing.M.d1 = 0.2508; + obj.borrowing.N.S2 = 0.5055; + obj.borrowing.N.S3 = 0.9290; + elseif order == 6 + [H, HI, D1, D2, D4, e_l, e_r, M4, d2_l, d2_r, d3_l, d3_r, d1_l, d1_r] = ... + sbp.implementations.d4_variable_6(m, obj.h); + obj.borrowing.M.d1 = 0.1878; + obj.borrowing.N.S2 = 0.3259; + obj.borrowing.N.S3 = 0.1580; + else + error('Invalid operator order.'); + end + + obj.m = m; + obj.order = order; + + obj.H = H; + obj.HI = HI; + obj.D1 = D1; + obj.D2 = D2; + obj.D4 = D4; + obj.M4 = M4; + obj.e_l = e_l; + obj.e_r = e_r; + obj.d1_l = d1_l; + obj.d1_r = d1_r; + obj.d2_l = d2_l; + obj.d2_r = d2_r; + obj.d3_l = d3_l; + obj.d3_r = d3_r; + end + + function str = string(obj) + str = [class(obj) '_' num2str(obj.order)]; + end + end +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/InterpAWW.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,68 @@ +classdef InterpAWW < sbp.InterpOps + properties + + % Interpolation operators + IC2F + IF2C + + % Orders used on coarse and fine sides + order_C + order_F + + % Grid points, refinement ratio. + ratio + m_C + m_F + + % Boundary accuracy of IC2F and IF2C. + acc_C2F + acc_F2C + end + + methods + % accOp : String, 'C2F' or 'F2C'. Specifies which of the operators + % should have higher accuracy. + function obj = InterpAWW(m_C,m_F,order_C,order_F,accOp) + assertIsMember(accOp, {'C2F','F2C'}); + + ratio = (m_F-1)/(m_C-1); + h_C = 1; + + assert(order_C == order_F,... + 'Error: Different orders of accuracy not available'); + + switch ratio + case 2 + switch order_C + case 2 + [IC2F,IF2C] = sbp.implementations.intOpAWW_orders_2to2_ratio2to1(m_C, h_C, accOp); + case 4 + [IC2F,IF2C] = sbp.implementations.intOpAWW_orders_4to4_ratio2to1(m_C, h_C, accOp); + case 6 + [IC2F,IF2C] = sbp.implementations.intOpAWW_orders_6to6_ratio2to1(m_C, h_C, accOp); + case 8 + [IC2F,IF2C] = sbp.implementations.intOpAWW_orders_8to8_ratio2to1(m_C, h_C, accOp); + otherwise + error(['Order ' num2str(order_C) ' not available.']); + end + otherwise + error(['Grid ratio ' num2str(ratio) ' not available']); + end + + obj.IC2F = IC2F; + obj.IF2C = IF2C; + obj.order_C = order_C; + obj.order_F = order_F; + obj.ratio = ratio; + obj.m_C = m_C; + obj.m_F = m_F; + + end + + function str = string(obj) + str = [class(obj) '_orders' num2str(obj.order_F) 'to'... + num2str(obj.order_C) '_ratio' num2str(obj.ratio) 'to1']; + end + + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/InterpMC.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,61 @@ +classdef InterpMC < sbp.InterpOps + properties + + % Interpolation operators + IC2F + IF2C + + % Orders used on coarse and fine sides + order_C + order_F + + % Grid points, refinement ratio. + ratio + m_C + m_F + end + + methods + function obj = InterpMC(m_C,m_F,order_C,order_F) + + ratio = (m_F-1)/(m_C-1); + + assert(order_C == order_F,... + 'Error: Different orders of accuracy not available'); + + switch ratio + case 2 + switch order_C + case 2 + [IC2F,IF2C] = sbp.implementations.intOpMC_orders_2to2_ratio2to1(m_C); + case 4 + [IC2F,IF2C] = sbp.implementations.intOpMC_orders_4to4_ratio2to1(m_C); + case 6 + [IC2F,IF2C] = sbp.implementations.intOpMC_orders_6to6_ratio2to1(m_C); + case 8 + [IC2F,IF2C] = sbp.implementations.intOpMC_orders_8to8_ratio2to1(m_C); + otherwise + error(['Order ' num2str(order_C) ' not available.']); + end + otherwise + error(['Grid ratio ' num2str(ratio) ' not available']); + end + + obj.IC2F = IC2F; + obj.IF2C = IF2C; + obj.order_C = order_C; + obj.order_F = order_F; + obj.ratio = ratio; + obj.m_C = m_C; + obj.m_F = m_F; + + + end + + function str = string(obj) + str = [class(obj) '_orders' num2str(obj.order_F) 'to'... + num2str(obj.order_C) '_ratio' num2str(obj.ratio) 'to1']; + end + + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+sbp/InterpOps.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,14 @@ +classdef (Abstract) InterpOps + properties (Abstract) + % C and F may refer to coarse and fine, but it's not a must. + IC2F % Interpolation operator from "C" to "F" + IF2C % Interpolation operator from "F" to "C" + + end + + methods (Abstract) + % Returns a string representation of the type of operator. + str = string(obj) + end + +end \ No newline at end of file
--- a/+sbp/OpSet.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+sbp/OpSet.m Tue Sep 11 15:58:35 2018 +0200 @@ -6,4 +6,9 @@ x % Grid end + methods (Abstract) + % Returns a string representation of the type of operator. + str = string(obj) + end + end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+scheme/Beam.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,263 @@ +classdef Beam < scheme.Scheme + properties + order % Order accuracy for the approximation + grid + + D % non-stabalized scheme operator + alpha + + h + H % Discrete norm + Hi + + e_l, e_r + d1_l, d1_r + d2_l, d2_r + d3_l, d3_r + gamm + delt + alphaII + alphaIII + + opt + end + + methods + function obj = Beam(grid, order, alpha, opsGen, opt) + default_arg('alpha', -1); + + % default_arg('opsGen', @sbp.D4); + default_arg('opsGen', @sbp.D4Variable); % Supposed to be better + + opt_default.interface_l.tuning = 1.1; + opt_default.interface_l.tau = []; + opt_default.interface_l.sig = []; + opt_default.interface_r.tuning = 1.1; + opt_default.interface_r.tau = []; + opt_default.interface_r.sig = []; + default_struct('opt', opt_default); + + if ~isa(grid, 'grid.Cartesian') || grid.D() ~= 1 + error('Grid must be 1d cartesian'); + end + + obj.grid = grid; + obj.order = order; + obj.alpha = alpha; + + m = grid.m; + h = grid.scaling(); + + x_lim = {grid.x{1}(1), grid.x{1}(end)}; + ops = opsGen(m, x_lim, order); + + D4 = ops.D4; + obj.H = ops.H; + obj.Hi = ops.HI; + obj.e_l = ops.e_l; + obj.e_r = ops.e_r; + obj.d1_l = ops.d1_l; + obj.d1_r = ops.d1_r; + obj.d2_l = ops.d2_l; + obj.d2_r = ops.d2_r; + obj.d3_l = ops.d3_l; + obj.d3_r = ops.d3_r; + + obj.D = alpha*D4; + + alphaII = ops.borrowing.N.S2/2; + alphaIII = ops.borrowing.N.S3/2; + + obj.gamm = h*alphaII; + obj.delt = h^3*alphaIII; + obj.alphaII = alphaII; + obj.alphaIII = alphaIII; + obj.h = h; + obj.opt = opt; + end + + + % 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. + function [closure, penalty] = boundary_condition(obj,boundary,type) + default_arg('type','dn'); + + [e, d1, d2, d3, s] = obj.get_boundary_ops(boundary); + gamm = obj.gamm; + delt = obj.delt; + + + % TODO: Can this be simplifed? Can I handle conditions on u on its own, u_x on its own ... + + switch type + case {'dn', 'clamped'} % Dirichlet-neumann boundary condition + alpha = obj.alpha; + + % tau1 < -alpha^2/gamma + % tuning = 2; + tuning = 1.1; + + tau1 = tuning * alpha/delt; + tau4 = s*alpha; + + sig2 = tuning * alpha/gamm; + sig3 = -s*alpha; + + tau = tau1*e+tau4*d3; + sig = sig2*d1+sig3*d2; + + closure = obj.Hi*(tau*e' + sig*d1'); + + penalty{1} = -obj.Hi*tau; + penalty{2} = -obj.Hi*sig; + + + case {'free'} + a = obj.alpha; + + tau = s*a*d1; + sig = -s*a*e; + + closure = obj.Hi*(tau*d2' + sig*d3'); + penalty{1} = -obj.Hi*tau; + penalty{1} = -obj.Hi*sig; + + case 'e' + alpha = obj.alpha; + tuning = 1.1; + + tau1 = tuning * alpha/delt; + tau4 = s*alpha; + + tau = tau1*e+tau4*d3; + + closure = obj.Hi*tau*e'; + penalty = -obj.Hi*tau; + case 'd1' + alpha = obj.alpha; + + tuning = 1.1; + + sig2 = tuning * alpha/gamm; + sig3 = -s*alpha; + + sig = sig2*d1+sig3*d2; + + closure = obj.Hi*sig*d1'; + penalty = -obj.Hi*sig; + + case 'd2' + a = obj.alpha; + + tau = s*a*d1; + + closure = obj.Hi*tau*d2'; + penalty = -obj.Hi*tau; + case 'd3' + a = obj.alpha; + + sig = -s*a*e; + + closure = obj.Hi*sig*d3'; + penalty = -obj.Hi*sig; + + otherwise % Unknown, boundary condition + error('No such boundary condition: type = %s',type); + end + end + + function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary) + % u denotes the solution in the own domain + % v denotes the solution in the neighbour domain + [e_u,d1_u,d2_u,d3_u,s_u] = obj.get_boundary_ops(boundary); + [e_v,d1_v,d2_v,d3_v,s_v] = neighbour_scheme.get_boundary_ops(neighbour_boundary); + + + alpha_u = obj.alpha; + alpha_v = neighbour_scheme.alpha; + + + switch boundary + case 'l' + interface_opt = obj.opt.interface_l; + case 'r' + interface_opt = obj.opt.interface_r; + end + + + if isempty(interface_opt.tau) && isempty(interface_opt.sig) + gamm_u = obj.gamm; + delt_u = obj.delt; + + gamm_v = neighbour_scheme.gamm; + delt_v = neighbour_scheme.delt; + + tuning = interface_opt.tuning; + + tau1 = ((alpha_u/2)/delt_u + (alpha_v/2)/delt_v)/2*tuning; + sig2 = ((alpha_u/2)/gamm_u + (alpha_v/2)/gamm_v)/2*tuning; + else + h_u = obj.h; + h_v = neighbour_scheme.h; + + switch neighbour_boundary + case 'l' + neighbour_interface_opt = neighbour_scheme.opt.interface_l; + case 'r' + neighbour_interface_opt = neighbour_scheme.opt.interface_r; + end + + tau_u = interface_opt.tau; + sig_u = interface_opt.sig; + tau_v = neighbour_interface_opt.tau; + sig_v = neighbour_interface_opt.sig; + + tau1 = tau_u/h_u^3 + tau_v/h_v^3; + sig2 = sig_u/h_u + sig_v/h_v; + end + + tau4 = s_u*alpha_u/2; + sig3 = -s_u*alpha_u/2; + phi2 = s_u*1/2; + psi1 = -s_u*1/2; + + tau = tau1*e_u + tau4*d3_u; + sig = sig2*d1_u + sig3*d2_u ; + phi = phi2*d1_u ; + psi = psi1*e_u ; + + closure = obj.Hi*(tau*e_u' + sig*d1_u' + phi*alpha_u*d2_u' + psi*alpha_u*d3_u'); + penalty = -obj.Hi*(tau*e_v' + sig*d1_v' + phi*alpha_v*d2_v' + psi*alpha_v*d3_v'); + end + + % Returns the boundary ops and sign for the boundary specified by the string boundary. + % The right boundary is considered the positive boundary + function [e, d1, d2, d3, s] = get_boundary_ops(obj,boundary) + switch boundary + case 'l' + e = obj.e_l; + d1 = obj.d1_l; + d2 = obj.d2_l; + d3 = obj.d3_l; + s = -1; + case 'r' + e = obj.e_r; + d1 = obj.d1_r; + d2 = obj.d2_r; + d3 = obj.d3_r; + s = 1; + otherwise + error('No such boundary: boundary = %s',boundary); + end + end + + function N = size(obj) + N = obj.grid.N; + end + + end +end
--- a/+scheme/Beam2d.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+scheme/Beam2d.m Tue Sep 11 15:58:35 2018 +0200 @@ -1,10 +1,6 @@ classdef Beam2d < scheme.Scheme properties - m % Number of points in each direction, possibly a vector - N % Number of points total - h % Grid spacing - u,v % Grid - x,y % Values of x and y for each grid point + grid order % Order accuracy for the approximation D % non-stabalized scheme operator @@ -27,21 +23,23 @@ methods function obj = Beam2d(m,lim,order,alpha,opsGen) + default_arg('alpha',1); default_arg('opsGen',@sbp.Higher); - default_arg('a',1); - if length(m) == 1 - m = [m m]; + if ~isa(grid, 'grid.Cartesian') || grid.D() ~= 2 + error('Grid must be 2d cartesian'); end - m_x = m(1); - m_y = m(2); + obj.grid = grid; + obj.alpha = alpha; + obj.order = order; - xlim = lim{1}; - ylim = lim{2}; + m_x = grid.m(1); + m_y = grid.m(2); - [x, h_x] = util.get_grid(xlim{:},m_x); - [y, h_y] = util.get_grid(ylim{:},m_y); + h = grid.scaling(); + h_x = h(1); + h_y = h(2); ops_x = opsGen(m_x,h_x,order); ops_y = opsGen(m_y,h_y,order); @@ -49,9 +47,6 @@ I_x = speye(m_x); I_y = speye(m_y); - - - D4_x = sparse(ops_x.derivatives.D4); H_x = sparse(ops_x.norms.H); Hi_x = sparse(ops_x.norms.HI); @@ -105,16 +100,7 @@ obj.d3_s = kr(I_x,d3_l_y); obj.d3_n = kr(I_x,d3_r_y); - obj.m = m; - obj.h = [h_x h_y]; - obj.order = order; - - obj.alpha = alpha; obj.D = alpha*D4; - obj.u = x; - obj.v = y; - obj.x = kr(x,ones(m_y,1)); - obj.y = kr(ones(m_x,1),y); obj.gamm_x = h_x*ops_x.borrowing.N.S2/2; obj.delt_x = h_x^3*ops_x.borrowing.N.S3/2;
--- a/+scheme/Burgers1D.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+scheme/Burgers1D.m Tue Sep 11 15:58:35 2018 +0200 @@ -1,9 +1,8 @@ classdef Burgers1D < scheme.Scheme properties - m % Number of points in each direction, possibly a vector - h % Grid spacing - x % Grid + grid % Physical grid order % Order accuracy for the approximation + params D % Non-stabalized scheme operator @@ -17,8 +16,12 @@ end methods - function obj = Burgers1D(pde_form, operator_type, order, m, lim, params) - [x, h] = util.get_grid(lim{:},m); + function obj = Burgers1D(grid, pde_form, operator_type, order, params) + assert(grid.D == 1); + assert(grid.size() == length(params.eps)); + m = grid.size(); + h = grid.scaling(); + lim = grid.lim{1}; % Ugly, and only applicable for cartesian grids. default_arg('pde_form','skew-symmetric'); default_arg('operator_type','narrow'); @@ -38,10 +41,8 @@ D = @(v, viscosity) -1/2*D1*v.^2 + D2(params.eps + viscosity)*v; end - obj.m = m; - obj.h = h; + obj.grid = grid; obj.order = order; - obj.x = x; obj.params = params; %% TODO: Figure out how to evaluate viscosity as viscosity(v,t) here instead of parametrizing D on the viscosity. @@ -107,8 +108,7 @@ end function N = size(obj) - N = obj.m; + N = obj.grid.m; end - end end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+scheme/Elastic2dCurvilinear.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,621 @@ +classdef Elastic2dCurvilinear < scheme.Scheme + +% Discretizes the elastic wave equation in curvilinear coordinates. +% +% Untransformed equation: +% rho u_{i,tt} = di lambda dj u_j + dj mu di u_j + dj mu dj u_i +% +% Transformed equation: +% J*rho u_{i,tt} = dk J b_ik lambda b_jl dl u_j +% + dk J b_jk mu b_il dl u_j +% + dk J b_jk mu b_jl dl u_i +% opSet should be cell array of opSets, one per dimension. This +% is useful if we have periodic BC in one direction. + + properties + m % Number of points in each direction, possibly a vector + h % Grid spacing + + grid + dim + + order % Order of accuracy for the approximation + + % Diagonal matrices for varible coefficients + LAMBDA % Variable coefficient, related to dilation + MU % Shear modulus, variable coefficient + RHO, RHOi % Density, variable + + % Metric coefficients + b % Cell matrix of size dim x dim + J, Ji + beta % Cell array of scale factors + + D % Total operator + D1 % First derivatives + + % Second derivatives + D2_lambda + D2_mu + + % Traction operators used for BC + T_l, T_r + tau_l, tau_r + + H, Hi % Inner products + phi % Borrowing constant for (d1 - e^T*D1) from R + gamma % Borrowing constant for d1 from M + H11 % First element of H + e_l, e_r + d1_l, d1_r % Normal derivatives at the boundary + E % E{i}^T picks out component i + + H_boundary_l, H_boundary_r % Boundary inner products + + % Kroneckered norms and coefficients + RHOi_kron + Ji_kron, J_kron + Hi_kron, H_kron + end + + methods + + function obj = Elastic2dCurvilinear(g ,order, lambda_fun, mu_fun, rho_fun, opSet) + default_arg('opSet',{@sbp.D2Variable, @sbp.D2Variable}); + default_arg('lambda_fun', @(x,y) 0*x+1); + default_arg('mu_fun', @(x,y) 0*x+1); + default_arg('rho_fun', @(x,y) 0*x+1); + dim = 2; + + lambda = grid.evalOn(g, lambda_fun); + mu = grid.evalOn(g, mu_fun); + rho = grid.evalOn(g, rho_fun); + m = g.size(); + obj.m = m; + m_tot = g.N(); + + % 1D operators + ops = cell(dim,1); + for i = 1:dim + ops{i} = opSet{i}(m(i), {0, 1}, order); + end + + % Borrowing constants + for i = 1:dim + beta = ops{i}.borrowing.R.delta_D; + obj.H11{i} = ops{i}.borrowing.H11; + obj.phi{i} = beta/obj.H11{i}; + obj.gamma{i} = ops{i}.borrowing.M.d1; + end + + I = cell(dim,1); + D1 = cell(dim,1); + D2 = cell(dim,1); + H = cell(dim,1); + Hi = cell(dim,1); + e_l = cell(dim,1); + e_r = cell(dim,1); + d1_l = cell(dim,1); + d1_r = cell(dim,1); + + for i = 1:dim + I{i} = speye(m(i)); + D1{i} = ops{i}.D1; + D2{i} = ops{i}.D2; + H{i} = ops{i}.H; + Hi{i} = ops{i}.HI; + e_l{i} = ops{i}.e_l; + e_r{i} = ops{i}.e_r; + d1_l{i} = ops{i}.d1_l; + d1_r{i} = ops{i}.d1_r; + end + + %====== Assemble full operators ======== + + % Variable coefficients + LAMBDA = spdiag(lambda); + obj.LAMBDA = LAMBDA; + MU = spdiag(mu); + obj.MU = MU; + RHO = spdiag(rho); + obj.RHO = RHO; + obj.RHOi = inv(RHO); + + % Allocate + obj.D1 = cell(dim,1); + obj.D2_lambda = cell(dim,dim,dim); + obj.D2_mu = cell(dim,dim,dim); + obj.e_l = cell(dim,1); + obj.e_r = cell(dim,1); + obj.d1_l = cell(dim,1); + obj.d1_r = cell(dim,1); + + % D1 + obj.D1{1} = kron(D1{1},I{2}); + obj.D1{2} = kron(I{1},D1{2}); + + % -- Metric coefficients ---- + coords = g.points(); + x = coords(:,1); + y = coords(:,2); + + % Use non-periodic difference operators for metric even if opSet is periodic. + xmax = max(ops{1}.x); + ymax = max(ops{2}.x); + opSetMetric{1} = sbp.D2Variable(m(1), {0, xmax}, order); + opSetMetric{2} = sbp.D2Variable(m(2), {0, ymax}, order); + D1Metric{1} = kron(opSetMetric{1}.D1, I{2}); + D1Metric{2} = kron(I{1}, opSetMetric{2}.D1); + + x_xi = D1Metric{1}*x; + x_eta = D1Metric{2}*x; + y_xi = D1Metric{1}*y; + y_eta = D1Metric{2}*y; + + J = x_xi.*y_eta - x_eta.*y_xi; + + b = cell(dim,dim); + b{1,1} = y_eta./J; + b{1,2} = -x_eta./J; + b{2,1} = -y_xi./J; + b{2,2} = x_xi./J; + + % Scale factors for boundary integrals + beta = cell(dim,1); + beta{1} = sqrt(x_eta.^2 + y_eta.^2); + beta{2} = sqrt(x_xi.^2 + y_xi.^2); + + J = spdiag(J); + Ji = inv(J); + for i = 1:dim + beta{i} = spdiag(beta{i}); + for j = 1:dim + b{i,j} = spdiag(b{i,j}); + end + end + obj.J = J; + obj.Ji = Ji; + obj.b = b; + obj.beta = beta; + %---------------------------- + + % Boundary operators + obj.e_l{1} = kron(e_l{1},I{2}); + obj.e_l{2} = kron(I{1},e_l{2}); + obj.e_r{1} = kron(e_r{1},I{2}); + obj.e_r{2} = kron(I{1},e_r{2}); + + obj.d1_l{1} = kron(d1_l{1},I{2}); + obj.d1_l{2} = kron(I{1},d1_l{2}); + obj.d1_r{1} = kron(d1_r{1},I{2}); + obj.d1_r{2} = kron(I{1},d1_r{2}); + + % D2 + for i = 1:dim + for j = 1:dim + for k = 1:dim + obj.D2_lambda{i,j,k} = sparse(m_tot); + obj.D2_mu{i,j,k} = sparse(m_tot); + end + end + end + ind = grid.funcToMatrix(g, 1:m_tot); + + % x-dir + for i = 1:dim + for j = 1:dim + for k = 1 + + coeff_lambda = J*b{i,k}*b{j,k}*lambda; + coeff_mu = J*b{j,k}*b{i,k}*mu; + + for col = 1:m(2) + D_lambda = D2{1}(coeff_lambda(ind(:,col))); + D_mu = D2{1}(coeff_mu(ind(:,col))); + + p = ind(:,col); + obj.D2_lambda{i,j,k}(p,p) = D_lambda; + obj.D2_mu{i,j,k}(p,p) = D_mu; + end + + end + end + end + + % y-dir + for i = 1:dim + for j = 1:dim + for k = 2 + + coeff_lambda = J*b{i,k}*b{j,k}*lambda; + coeff_mu = J*b{j,k}*b{i,k}*mu; + + for row = 1:m(1) + D_lambda = D2{2}(coeff_lambda(ind(row,:))); + D_mu = D2{2}(coeff_mu(ind(row,:))); + + p = ind(row,:); + obj.D2_lambda{i,j,k}(p,p) = D_lambda; + obj.D2_mu{i,j,k}(p,p) = D_mu; + end + + end + end + end + + % Quadratures + obj.H = kron(H{1},H{2}); + obj.Hi = inv(obj.H); + obj.H_boundary_l = cell(dim,1); + obj.H_boundary_l{1} = obj.e_l{1}'*beta{1}*obj.e_l{1}*H{2}; + obj.H_boundary_l{2} = obj.e_l{2}'*beta{2}*obj.e_l{2}*H{1}; + obj.H_boundary_r = cell(dim,1); + obj.H_boundary_r{1} = obj.e_r{1}'*beta{1}*obj.e_r{1}*H{2}; + obj.H_boundary_r{2} = obj.e_r{2}'*beta{2}*obj.e_r{2}*H{1}; + + % E{i}^T picks out component i. + E = cell(dim,1); + I = speye(m_tot,m_tot); + for i = 1:dim + e = sparse(dim,1); + e(i) = 1; + E{i} = kron(I,e); + end + obj.E = E; + + % Differentiation matrix D (without SAT) + D2_lambda = obj.D2_lambda; + D2_mu = obj.D2_mu; + D1 = obj.D1; + D = sparse(dim*m_tot,dim*m_tot); + d = @kroneckerDelta; % Kronecker delta + db = @(i,j) 1-d(i,j); % Logical not of Kronecker delta + for i = 1:dim + for j = 1:dim + for k = 1:dim + for l = 1:dim + D = D + E{i}*Ji*inv(RHO)*( d(k,l)*D2_lambda{i,j,k}*E{j}' + ... + db(k,l)*D1{k}*J*b{i,k}*b{j,l}*LAMBDA*D1{l}*E{j}' ... + ); + + D = D + E{i}*Ji*inv(RHO)*( d(k,l)*D2_mu{i,j,k}*E{j}' + ... + db(k,l)*D1{k}*J*b{j,k}*b{i,l}*MU*D1{l}*E{j}' ... + ); + + D = D + E{i}*Ji*inv(RHO)*( d(k,l)*D2_mu{j,j,k}*E{i}' + ... + db(k,l)*D1{k}*J*b{j,k}*b{j,l}*MU*D1{l}*E{i}' ... + ); + + end + end + end + end + obj.D = D; + %=========================================% + + % Numerical traction operators for BC. + % Because d1 =/= e0^T*D1, the numerical tractions are different + % at every boundary. + T_l = cell(dim,1); + T_r = cell(dim,1); + tau_l = cell(dim,1); + tau_r = cell(dim,1); + % tau^{j}_i = sum_k T^{j}_{ik} u_k + + d1_l = obj.d1_l; + d1_r = obj.d1_r; + e_l = obj.e_l; + e_r = obj.e_r; + + % Loop over boundaries + for j = 1:dim + T_l{j} = cell(dim,dim); + T_r{j} = cell(dim,dim); + tau_l{j} = cell(dim,1); + tau_r{j} = cell(dim,1); + + % Loop over components + for i = 1:dim + tau_l{j}{i} = sparse(m_tot,dim*m_tot); + tau_r{j}{i} = sparse(m_tot,dim*m_tot); + + % Loop over components that T_{ik}^{(j)} acts on + for k = 1:dim + + T_l{j}{i,k} = sparse(m_tot,m_tot); + T_r{j}{i,k} = sparse(m_tot,m_tot); + + for m = 1:dim + for l = 1:dim + T_l{j}{i,k} = T_l{j}{i,k} + ... + -d(k,l)* J*b{i,j}*b{k,m}*LAMBDA*(d(m,j)*e_l{m}*d1_l{m}' + db(m,j)*D1{m}) ... + -d(k,l)* J*b{k,j}*b{i,m}*MU*(d(m,j)*e_l{m}*d1_l{m}' + db(m,j)*D1{m}) ... + -d(i,k)* J*b{l,j}*b{l,m}*MU*(d(m,j)*e_l{m}*d1_l{m}' + db(m,j)*D1{m}); + + T_r{j}{i,k} = T_r{j}{i,k} + ... + d(k,l)* J*b{i,j}*b{k,m}*LAMBDA*(d(m,j)*e_r{m}*d1_r{m}' + db(m,j)*D1{m}) + ... + d(k,l)* J*b{k,j}*b{i,m}*MU*(d(m,j)*e_r{m}*d1_r{m}' + db(m,j)*D1{m}) + ... + d(i,k)* J*b{l,j}*b{l,m}*MU*(d(m,j)*e_r{m}*d1_r{m}' + db(m,j)*D1{m}); + end + end + + T_l{j}{i,k} = inv(beta{j})*T_l{j}{i,k}; + T_r{j}{i,k} = inv(beta{j})*T_r{j}{i,k}; + + tau_l{j}{i} = tau_l{j}{i} + T_l{j}{i,k}*E{k}'; + tau_r{j}{i} = tau_r{j}{i} + T_r{j}{i,k}*E{k}'; + end + + end + end + obj.T_l = T_l; + obj.T_r = T_r; + obj.tau_l = tau_l; + obj.tau_r = tau_r; + + % Kroneckered norms and coefficients + I_dim = speye(dim); + obj.RHOi_kron = kron(obj.RHOi, I_dim); + obj.Ji_kron = kron(obj.Ji, I_dim); + obj.Hi_kron = kron(obj.Hi, I_dim); + obj.H_kron = kron(obj.H, I_dim); + obj.J_kron = kron(obj.J, I_dim); + + % Misc. + obj.h = g.scaling(); + obj.order = order; + obj.grid = g; + obj.dim = dim; + + end + + + % Closure functions return the operators applied to the own domain to close the boundary + % Penalty functions return the operators 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'. + % bc is a cell array of component and bc type, e.g. {1, 'd'} for Dirichlet condition + % on the first component. + % 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. + function [closure, penalty] = boundary_condition(obj, boundary, bc, tuning) + default_arg('tuning', 1.2); + + assert( iscell(bc), 'The BC type must be a 2x1 cell array' ); + comp = bc{1}; + type = bc{2}; + + % j is the coordinate direction of the boundary + j = obj.get_boundary_number(boundary); + [e, T, tau, H_gamma] = obj.get_boundary_operator({'e','T','tau','H'}, boundary); + + E = obj.E; + Hi = obj.Hi; + LAMBDA = obj.LAMBDA; + MU = obj.MU; + RHOi = obj.RHOi; + Ji = obj.Ji; + + dim = obj.dim; + m_tot = obj.grid.N(); + + % Preallocate + closure = sparse(dim*m_tot, dim*m_tot); + penalty = sparse(dim*m_tot, m_tot/obj.m(j)); + + % Loop over components that we (potentially) have different BC on + k = comp; + switch type + + % Dirichlet boundary condition + case {'D','d','dirichlet','Dirichlet'} + + phi = obj.phi{j}; + h = obj.h(j); + h11 = obj.H11{j}*h; + gamma = obj.gamma{j}; + + a_lambda = dim/h11 + 1/(h11*phi); + a_mu_i = 2/(gamma*h); + a_mu_ij = 2/h11 + 1/(h11*phi); + + d = @kroneckerDelta; % Kronecker delta + db = @(i,j) 1-d(i,j); % Logical not of Kronecker delta + alpha = @(i,j) tuning*( d(i,j)* a_lambda*LAMBDA ... + + d(i,j)* a_mu_i*MU ... + + db(i,j)*a_mu_ij*MU ); + + % Loop over components that Dirichlet penalties end up on + for i = 1:dim + C = T{k,i}; + A = -d(i,k)*alpha(i,j); + B = A + C; + closure = closure + E{i}*RHOi*Hi*Ji*B'*e*H_gamma*(e'*E{k}' ); + penalty = penalty - E{i}*RHOi*Hi*Ji*B'*e*H_gamma; + end + + % Free boundary condition + case {'F','f','Free','free','traction','Traction','t','T'} + closure = closure - E{k}*RHOi*Ji*Hi*e*H_gamma* (e'*tau{k} ); + penalty = penalty + E{k}*RHOi*Ji*Hi*e*H_gamma; + + % Unknown boundary condition + otherwise + error('No such boundary condition: type = %s',type); + end + end + + function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary) + % u denotes the solution in the own domain + % v denotes the solution in the neighbour domain + % Operators without subscripts are from the own domain. + error('Not implemented'); + tuning = 1.2; + + % j is the coordinate direction of the boundary + j = obj.get_boundary_number(boundary); + j_v = neighbour_scheme.get_boundary_number(neighbour_boundary); + + % Get boundary operators + [e, T, tau, H_gamma] = obj.get_boundary_operator({'e','T','tau','H'}, boundary); + [e_v, tau_v] = neighbour_scheme.get_boundary_operator({'e','tau'}, neighbour_boundary); + + % Operators and quantities that correspond to the own domain only + Hi = obj.Hi; + RHOi = obj.RHOi; + dim = obj.dim; + + %--- Other operators ---- + m_tot_u = obj.grid.N(); + E = obj.E; + LAMBDA_u = obj.LAMBDA; + MU_u = obj.MU; + lambda_u = e'*LAMBDA_u*e; + mu_u = e'*MU_u*e; + + m_tot_v = neighbour_scheme.grid.N(); + E_v = neighbour_scheme.E; + LAMBDA_v = neighbour_scheme.LAMBDA; + MU_v = neighbour_scheme.MU; + lambda_v = e_v'*LAMBDA_v*e_v; + mu_v = e_v'*MU_v*e_v; + %------------------------- + + % Borrowing constants + phi_u = obj.phi{j}; + h_u = obj.h(j); + h11_u = obj.H11{j}*h_u; + gamma_u = obj.gamma{j}; + + phi_v = neighbour_scheme.phi{j_v}; + h_v = neighbour_scheme.h(j_v); + h11_v = neighbour_scheme.H11{j_v}*h_v; + gamma_v = neighbour_scheme.gamma{j_v}; + + % E > sum_i 1/(2*alpha_ij)*(tau_i)^2 + function [alpha_ii, alpha_ij] = computeAlpha(phi,h,h11,gamma,lambda,mu) + th1 = h11/(2*dim); + th2 = h11*phi/2; + th3 = h*gamma; + a1 = ( (th1 + th2)*th3*lambda + 4*th1*th2*mu ) / (2*th1*th2*th3); + a2 = ( 16*(th1 + th2)*lambda*mu ) / (th1*th2*th3); + alpha_ii = a1 + sqrt(a2 + a1^2); + + alpha_ij = mu*(2/h11 + 1/(phi*h11)); + end + + [alpha_ii_u, alpha_ij_u] = computeAlpha(phi_u,h_u,h11_u,gamma_u,lambda_u,mu_u); + [alpha_ii_v, alpha_ij_v] = computeAlpha(phi_v,h_v,h11_v,gamma_v,lambda_v,mu_v); + sigma_ii = tuning*(alpha_ii_u + alpha_ii_v)/4; + sigma_ij = tuning*(alpha_ij_u + alpha_ij_v)/4; + + d = @kroneckerDelta; % Kronecker delta + db = @(i,j) 1-d(i,j); % Logical not of Kronecker delta + sigma = @(i,j) tuning*(d(i,j)*sigma_ii + db(i,j)*sigma_ij); + + % Preallocate + closure = sparse(dim*m_tot_u, dim*m_tot_u); + penalty = sparse(dim*m_tot_u, dim*m_tot_v); + + % Loop over components that penalties end up on + for i = 1:dim + closure = closure - E{i}*RHOi*Hi*e*sigma(i,j)*H_gamma*e'*E{i}'; + penalty = penalty + E{i}*RHOi*Hi*e*sigma(i,j)*H_gamma*e_v'*E_v{i}'; + + closure = closure - 1/2*E{i}*RHOi*Hi*e*H_gamma*e'*tau{i}; + penalty = penalty - 1/2*E{i}*RHOi*Hi*e*H_gamma*e_v'*tau_v{i}; + + % Loop over components that we have interface conditions on + for k = 1:dim + closure = closure + 1/2*E{i}*RHOi*Hi*T{k,i}'*e*H_gamma*e'*E{k}'; + penalty = penalty - 1/2*E{i}*RHOi*Hi*T{k,i}'*e*H_gamma*e_v'*E_v{k}'; + end + end + end + + % Returns the coordinate number and outward normal component for the boundary specified by the string boundary. + function [j, nj] = get_boundary_number(obj, boundary) + + switch boundary + case {'w','W','west','West', 'e', 'E', 'east', 'East'} + j = 1; + case {'s','S','south','South', 'n', 'N', 'north', 'North'} + j = 2; + otherwise + error('No such boundary: boundary = %s',boundary); + end + + switch boundary + case {'w','W','west','West','s','S','south','South'} + nj = -1; + case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'} + nj = 1; + end + end + + % Returns the boundary operator op for the boundary specified by the string boundary. + % op: may be a cell array of strings + function [varargout] = get_boundary_operator(obj, op, boundary) + + switch boundary + case {'w','W','west','West', 'e', 'E', 'east', 'East'} + j = 1; + case {'s','S','south','South', 'n', 'N', 'north', 'North'} + j = 2; + otherwise + error('No such boundary: boundary = %s',boundary); + end + + if ~iscell(op) + op = {op}; + end + + for i = 1:length(op) + switch op{i} + case 'e' + switch boundary + case {'w','W','west','West','s','S','south','South'} + varargout{i} = obj.e_l{j}; + case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'} + varargout{i} = obj.e_r{j}; + end + case 'd' + switch boundary + case {'w','W','west','West','s','S','south','South'} + varargout{i} = obj.d1_l{j}; + case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'} + varargout{i} = obj.d1_r{j}; + end + case 'H' + switch boundary + case {'w','W','west','West','s','S','south','South'} + varargout{i} = obj.H_boundary_l{j}; + case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'} + varargout{i} = obj.H_boundary_r{j}; + end + case 'T' + switch boundary + case {'w','W','west','West','s','S','south','South'} + varargout{i} = obj.T_l{j}; + case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'} + varargout{i} = obj.T_r{j}; + end + case 'tau' + switch boundary + case {'w','W','west','West','s','S','south','South'} + varargout{i} = obj.tau_l{j}; + case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'} + varargout{i} = obj.tau_r{j}; + end + otherwise + error(['No such operator: operator = ' op{i}]); + end + end + + end + + function N = size(obj) + N = obj.dim*prod(obj.m); + end + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+scheme/Elastic2dVariable.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,512 @@ +classdef Elastic2dVariable < scheme.Scheme + +% Discretizes the elastic wave equation: +% rho u_{i,tt} = di lambda dj u_j + dj mu di u_j + dj mu dj u_i +% opSet should be cell array of opSets, one per dimension. This +% is useful if we have periodic BC in one direction. + + properties + m % Number of points in each direction, possibly a vector + h % Grid spacing + + grid + dim + + order % Order of accuracy for the approximation + + % Diagonal matrices for varible coefficients + LAMBDA % Variable coefficient, related to dilation + MU % Shear modulus, variable coefficient + RHO, RHOi % Density, variable + + D % Total operator + D1 % First derivatives + + % Second derivatives + D2_lambda + D2_mu + + % Traction operators used for BC + T_l, T_r + tau_l, tau_r + + H, Hi % Inner products + + phi % Borrowing constant for (d1 - e^T*D1) from R + gamma % Borrowing constant for d1 from M + H11 % First element of H + + % Borrowing from H, M, and R + thH + thM + thR + + e_l, e_r + d1_l, d1_r % Normal derivatives at the boundary + E % E{i}^T picks out component i + + H_boundary % Boundary inner products + + % Kroneckered norms and coefficients + RHOi_kron + Hi_kron + end + + methods + + function obj = Elastic2dVariable(g ,order, lambda_fun, mu_fun, rho_fun, opSet) + default_arg('opSet',{@sbp.D2Variable, @sbp.D2Variable}); + default_arg('lambda_fun', @(x,y) 0*x+1); + default_arg('mu_fun', @(x,y) 0*x+1); + default_arg('rho_fun', @(x,y) 0*x+1); + dim = 2; + + assert(isa(g, 'grid.Cartesian')) + + lambda = grid.evalOn(g, lambda_fun); + mu = grid.evalOn(g, mu_fun); + rho = grid.evalOn(g, rho_fun); + m = g.size(); + m_tot = g.N(); + + h = g.scaling(); + lim = g.lim; + if isempty(lim) + x = g.x; + lim = cell(length(x),1); + for i = 1:length(x) + lim{i} = {min(x{i}), max(x{i})}; + end + end + + % 1D operators + ops = cell(dim,1); + for i = 1:dim + ops{i} = opSet{i}(m(i), lim{i}, order); + end + + % Borrowing constants + for i = 1:dim + beta = ops{i}.borrowing.R.delta_D; + obj.H11{i} = ops{i}.borrowing.H11; + obj.phi{i} = beta/obj.H11{i}; + obj.gamma{i} = ops{i}.borrowing.M.d1; + + % Better names + obj.thR{i} = ops{i}.borrowing.R.delta_D; + obj.thM{i} = ops{i}.borrowing.M.d1; + obj.thH{i} = ops{i}.borrowing.H11; + end + + I = cell(dim,1); + D1 = cell(dim,1); + D2 = cell(dim,1); + H = cell(dim,1); + Hi = cell(dim,1); + e_l = cell(dim,1); + e_r = cell(dim,1); + d1_l = cell(dim,1); + d1_r = cell(dim,1); + + for i = 1:dim + I{i} = speye(m(i)); + D1{i} = ops{i}.D1; + D2{i} = ops{i}.D2; + H{i} = ops{i}.H; + Hi{i} = ops{i}.HI; + e_l{i} = ops{i}.e_l; + e_r{i} = ops{i}.e_r; + d1_l{i} = ops{i}.d1_l; + d1_r{i} = ops{i}.d1_r; + end + + %====== Assemble full operators ======== + LAMBDA = spdiag(lambda); + obj.LAMBDA = LAMBDA; + MU = spdiag(mu); + obj.MU = MU; + RHO = spdiag(rho); + obj.RHO = RHO; + obj.RHOi = inv(RHO); + + obj.D1 = cell(dim,1); + obj.D2_lambda = cell(dim,1); + obj.D2_mu = cell(dim,1); + obj.e_l = cell(dim,1); + obj.e_r = cell(dim,1); + obj.d1_l = cell(dim,1); + obj.d1_r = cell(dim,1); + + % D1 + obj.D1{1} = kron(D1{1},I{2}); + obj.D1{2} = kron(I{1},D1{2}); + + % Boundary operators + obj.e_l{1} = kron(e_l{1},I{2}); + obj.e_l{2} = kron(I{1},e_l{2}); + obj.e_r{1} = kron(e_r{1},I{2}); + obj.e_r{2} = kron(I{1},e_r{2}); + + obj.d1_l{1} = kron(d1_l{1},I{2}); + obj.d1_l{2} = kron(I{1},d1_l{2}); + obj.d1_r{1} = kron(d1_r{1},I{2}); + obj.d1_r{2} = kron(I{1},d1_r{2}); + + % D2 + for i = 1:dim + obj.D2_lambda{i} = sparse(m_tot); + obj.D2_mu{i} = sparse(m_tot); + end + ind = grid.funcToMatrix(g, 1:m_tot); + + for i = 1:m(2) + D_lambda = D2{1}(lambda(ind(:,i))); + D_mu = D2{1}(mu(ind(:,i))); + + p = ind(:,i); + obj.D2_lambda{1}(p,p) = D_lambda; + obj.D2_mu{1}(p,p) = D_mu; + end + + for i = 1:m(1) + D_lambda = D2{2}(lambda(ind(i,:))); + D_mu = D2{2}(mu(ind(i,:))); + + p = ind(i,:); + obj.D2_lambda{2}(p,p) = D_lambda; + obj.D2_mu{2}(p,p) = D_mu; + end + + % Quadratures + obj.H = kron(H{1},H{2}); + obj.Hi = inv(obj.H); + obj.H_boundary = cell(dim,1); + obj.H_boundary{1} = H{2}; + obj.H_boundary{2} = H{1}; + + % E{i}^T picks out component i. + E = cell(dim,1); + I = speye(m_tot,m_tot); + for i = 1:dim + e = sparse(dim,1); + e(i) = 1; + E{i} = kron(I,e); + end + obj.E = E; + + % Differentiation matrix D (without SAT) + D2_lambda = obj.D2_lambda; + D2_mu = obj.D2_mu; + D1 = obj.D1; + D = sparse(dim*m_tot,dim*m_tot); + d = @kroneckerDelta; % Kronecker delta + db = @(i,j) 1-d(i,j); % Logical not of Kronecker delta + for i = 1:dim + for j = 1:dim + D = D + E{i}*inv(RHO)*( d(i,j)*D2_lambda{i}*E{j}' +... + db(i,j)*D1{i}*LAMBDA*D1{j}*E{j}' ... + ); + D = D + E{i}*inv(RHO)*( d(i,j)*D2_mu{i}*E{j}' +... + db(i,j)*D1{j}*MU*D1{i}*E{j}' + ... + D2_mu{j}*E{i}' ... + ); + end + end + obj.D = D; + %=========================================% + + % Numerical traction operators for BC. + % Because d1 =/= e0^T*D1, the numerical tractions are different + % at every boundary. + T_l = cell(dim,1); + T_r = cell(dim,1); + tau_l = cell(dim,1); + tau_r = cell(dim,1); + % tau^{j}_i = sum_k T^{j}_{ik} u_k + + d1_l = obj.d1_l; + d1_r = obj.d1_r; + e_l = obj.e_l; + e_r = obj.e_r; + D1 = obj.D1; + + % Loop over boundaries + for j = 1:dim + T_l{j} = cell(dim,dim); + T_r{j} = cell(dim,dim); + tau_l{j} = cell(dim,1); + tau_r{j} = cell(dim,1); + + % Loop over components + for i = 1:dim + tau_l{j}{i} = sparse(m_tot,dim*m_tot); + tau_r{j}{i} = sparse(m_tot,dim*m_tot); + for k = 1:dim + T_l{j}{i,k} = ... + -d(i,j)*LAMBDA*(d(i,k)*e_l{k}*d1_l{k}' + db(i,k)*D1{k})... + -d(j,k)*MU*(d(i,j)*e_l{i}*d1_l{i}' + db(i,j)*D1{i})... + -d(i,k)*MU*e_l{j}*d1_l{j}'; + + T_r{j}{i,k} = ... + d(i,j)*LAMBDA*(d(i,k)*e_r{k}*d1_r{k}' + db(i,k)*D1{k})... + +d(j,k)*MU*(d(i,j)*e_r{i}*d1_r{i}' + db(i,j)*D1{i})... + +d(i,k)*MU*e_r{j}*d1_r{j}'; + + tau_l{j}{i} = tau_l{j}{i} + T_l{j}{i,k}*E{k}'; + tau_r{j}{i} = tau_r{j}{i} + T_r{j}{i,k}*E{k}'; + end + + end + end + obj.T_l = T_l; + obj.T_r = T_r; + obj.tau_l = tau_l; + obj.tau_r = tau_r; + + % Kroneckered norms and coefficients + I_dim = speye(dim); + obj.RHOi_kron = kron(obj.RHOi, I_dim); + obj.Hi_kron = kron(obj.Hi, I_dim); + + % Misc. + obj.m = m; + obj.h = h; + obj.order = order; + obj.grid = g; + obj.dim = dim; + + end + + + % Closure functions return the operators applied to the own domain to close the boundary + % Penalty functions return the operators 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'. + % bc is a cell array of component and bc type, e.g. {1, 'd'} for Dirichlet condition + % on the first component. + % 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. + function [closure, penalty] = boundary_condition(obj, boundary, bc, tuning) + default_arg('tuning', 1.2); + + assert( iscell(bc), 'The BC type must be a 2x1 cell array' ); + comp = bc{1}; + type = bc{2}; + + % j is the coordinate direction of the boundary + j = obj.get_boundary_number(boundary); + [e, T, tau, H_gamma] = obj.get_boundary_operator({'e','T','tau','H'}, boundary); + + E = obj.E; + Hi = obj.Hi; + LAMBDA = obj.LAMBDA; + MU = obj.MU; + RHOi = obj.RHOi; + + dim = obj.dim; + m_tot = obj.grid.N(); + + % Preallocate + closure = sparse(dim*m_tot, dim*m_tot); + penalty = sparse(dim*m_tot, m_tot/obj.m(j)); + + k = comp; + switch type + + % Dirichlet boundary condition + case {'D','d','dirichlet','Dirichlet'} + + phi = obj.phi{j}; + h = obj.h(j); + h11 = obj.H11{j}*h; + gamma = obj.gamma{j}; + + a_lambda = dim/h11 + 1/(h11*phi); + a_mu_i = 2/(gamma*h); + a_mu_ij = 2/h11 + 1/(h11*phi); + + d = @kroneckerDelta; % Kronecker delta + db = @(i,j) 1-d(i,j); % Logical not of Kronecker delta + alpha = @(i,j) tuning*( d(i,j)* a_lambda*LAMBDA ... + + d(i,j)* a_mu_i*MU ... + + db(i,j)*a_mu_ij*MU ); + + % Loop over components that Dirichlet penalties end up on + for i = 1:dim + C = T{k,i}; + A = -d(i,k)*alpha(i,j); + B = A + C; + closure = closure + E{i}*RHOi*Hi*B'*e*H_gamma*(e'*E{k}' ); + penalty = penalty - E{i}*RHOi*Hi*B'*e*H_gamma; + end + + % Free boundary condition + case {'F','f','Free','free','traction','Traction','t','T'} + closure = closure - E{k}*RHOi*Hi*e*H_gamma* (e'*tau{k} ); + penalty = penalty + E{k}*RHOi*Hi*e*H_gamma; + + % Unknown boundary condition + otherwise + error('No such boundary condition: type = %s',type); + end + end + + function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary) + % u denotes the solution in the own domain + % v denotes the solution in the neighbour domain + % Operators without subscripts are from the own domain. + tuning = 1.2; + + % j is the coordinate direction of the boundary + j = obj.get_boundary_number(boundary); + j_v = neighbour_scheme.get_boundary_number(neighbour_boundary); + + % Get boundary operators + [e, T, tau, H_gamma] = obj.get_boundary_operator({'e','T','tau','H'}, boundary); + [e_v, tau_v] = neighbour_scheme.get_boundary_operator({'e','tau'}, neighbour_boundary); + + % Operators and quantities that correspond to the own domain only + Hi = obj.Hi; + RHOi = obj.RHOi; + dim = obj.dim; + + %--- Other operators ---- + m_tot_u = obj.grid.N(); + E = obj.E; + LAMBDA_u = obj.LAMBDA; + MU_u = obj.MU; + lambda_u = e'*LAMBDA_u*e; + mu_u = e'*MU_u*e; + + m_tot_v = neighbour_scheme.grid.N(); + E_v = neighbour_scheme.E; + LAMBDA_v = neighbour_scheme.LAMBDA; + MU_v = neighbour_scheme.MU; + lambda_v = e_v'*LAMBDA_v*e_v; + mu_v = e_v'*MU_v*e_v; + %------------------------- + + % Borrowing constants + h_u = obj.h(j); + thR_u = obj.thR{j}*h_u; + thM_u = obj.thM{j}*h_u; + thH_u = obj.thH{j}*h_u; + + h_v = neighbour_scheme.h(j_v); + thR_v = neighbour_scheme.thR{j_v}*h_v; + thH_v = neighbour_scheme.thH{j_v}*h_v; + thM_v = neighbour_scheme.thM{j_v}*h_v; + + % alpha = penalty strength for normal component, beta for tangential + alpha_u = dim*lambda_u/(4*thH_u) + lambda_u/(4*thR_u) + mu_u/(2*thM_u); + alpha_v = dim*lambda_v/(4*thH_v) + lambda_v/(4*thR_v) + mu_v/(2*thM_v); + beta_u = mu_u/(2*thH_u) + mu_u/(4*thR_u); + beta_v = mu_v/(2*thH_v) + mu_v/(4*thR_v); + alpha = alpha_u + alpha_v; + beta = beta_u + beta_v; + + d = @kroneckerDelta; % Kronecker delta + db = @(i,j) 1-d(i,j); % Logical not of Kronecker delta + strength = @(i,j) tuning*(d(i,j)*alpha + db(i,j)*beta); + + % Preallocate + closure = sparse(dim*m_tot_u, dim*m_tot_u); + penalty = sparse(dim*m_tot_u, dim*m_tot_v); + + % Loop over components that penalties end up on + for i = 1:dim + closure = closure - E{i}*RHOi*Hi*e*strength(i,j)*H_gamma*e'*E{i}'; + penalty = penalty + E{i}*RHOi*Hi*e*strength(i,j)*H_gamma*e_v'*E_v{i}'; + + closure = closure - 1/2*E{i}*RHOi*Hi*e*H_gamma*e'*tau{i}; + penalty = penalty - 1/2*E{i}*RHOi*Hi*e*H_gamma*e_v'*tau_v{i}; + + % Loop over components that we have interface conditions on + for k = 1:dim + closure = closure + 1/2*E{i}*RHOi*Hi*T{k,i}'*e*H_gamma*e'*E{k}'; + penalty = penalty - 1/2*E{i}*RHOi*Hi*T{k,i}'*e*H_gamma*e_v'*E_v{k}'; + end + end + end + + % Returns the coordinate number and outward normal component for the boundary specified by the string boundary. + function [j, nj] = get_boundary_number(obj, boundary) + + switch boundary + case {'w','W','west','West', 'e', 'E', 'east', 'East'} + j = 1; + case {'s','S','south','South', 'n', 'N', 'north', 'North'} + j = 2; + otherwise + error('No such boundary: boundary = %s',boundary); + end + + switch boundary + case {'w','W','west','West','s','S','south','South'} + nj = -1; + case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'} + nj = 1; + end + end + + % Returns the boundary operator op for the boundary specified by the string boundary. + % op: may be a cell array of strings + function [varargout] = get_boundary_operator(obj, op, boundary) + + switch boundary + case {'w','W','west','West', 'e', 'E', 'east', 'East'} + j = 1; + case {'s','S','south','South', 'n', 'N', 'north', 'North'} + j = 2; + otherwise + error('No such boundary: boundary = %s',boundary); + end + + if ~iscell(op) + op = {op}; + end + + for i = 1:length(op) + switch op{i} + case 'e' + switch boundary + case {'w','W','west','West','s','S','south','South'} + varargout{i} = obj.e_l{j}; + case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'} + varargout{i} = obj.e_r{j}; + end + case 'd' + switch boundary + case {'w','W','west','West','s','S','south','South'} + varargout{i} = obj.d1_l{j}; + case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'} + varargout{i} = obj.d1_r{j}; + end + case 'H' + varargout{i} = obj.H_boundary{j}; + case 'T' + switch boundary + case {'w','W','west','West','s','S','south','South'} + varargout{i} = obj.T_l{j}; + case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'} + varargout{i} = obj.T_r{j}; + end + case 'tau' + switch boundary + case {'w','W','west','West','s','S','south','South'} + varargout{i} = obj.tau_l{j}; + case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'} + varargout{i} = obj.tau_r{j}; + end + otherwise + error(['No such operator: operator = ' op{i}]); + end + end + + end + + function N = size(obj) + N = obj.dim*prod(obj.m); + end + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+scheme/Heat2dCurvilinear.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,385 @@ +classdef Heat2dCurvilinear < scheme.Scheme + +% Discretizes the Laplacian with variable coefficent, curvilinear, +% in the Heat equation way (i.e., the discretization matrix is not necessarily +% symmetric) +% u_t = div * (kappa * grad u ) +% opSet should be cell array of opSets, one per dimension. This +% is useful if we have periodic BC in one direction. + + properties + m % Number of points in each direction, possibly a vector + h % Grid spacing + + grid + dim + + order % Order of accuracy for the approximation + + % Diagonal matrix for variable coefficients + KAPPA % Variable coefficient + + D % Total operator + D1 % First derivatives + + % Second derivatives + D2_kappa + + H, Hi % Inner products + e_l, e_r + d1_l, d1_r % Normal derivatives at the boundary + alpha % Vector of borrowing constants + + % Boundary inner products + H_boundary_l, H_boundary_r + + % Metric coefficients + b % Cell matrix of size dim x dim + J, Ji + beta % Cell array of scale factors + + % Numerical boundary flux operators + flux_l, flux_r + + end + + methods + + function obj = Heat2dCurvilinear(g ,order, kappa_fun, opSet) + default_arg('opSet',{@sbp.D2Variable, @sbp.D2Variable}); + default_arg('kappa_fun', @(x,y) 0*x+1); + dim = 2; + + kappa = grid.evalOn(g, kappa_fun); + m = g.size(); + m_tot = g.N(); + + % 1D operators + ops = cell(dim,1); + for i = 1:dim + ops{i} = opSet{i}(m(i), {0, 1}, order); + end + + I = cell(dim,1); + D1 = cell(dim,1); + D2 = cell(dim,1); + H = cell(dim,1); + Hi = cell(dim,1); + e_l = cell(dim,1); + e_r = cell(dim,1); + d1_l = cell(dim,1); + d1_r = cell(dim,1); + + for i = 1:dim + I{i} = speye(m(i)); + D1{i} = ops{i}.D1; + D2{i} = ops{i}.D2; + H{i} = ops{i}.H; + Hi{i} = ops{i}.HI; + e_l{i} = ops{i}.e_l; + e_r{i} = ops{i}.e_r; + d1_l{i} = ops{i}.d1_l; + d1_r{i} = ops{i}.d1_r; + end + + %====== Assemble full operators ======== + KAPPA = spdiag(kappa); + obj.KAPPA = KAPPA; + + % Allocate + obj.D1 = cell(dim,1); + obj.D2_kappa = cell(dim,1); + obj.e_l = cell(dim,1); + obj.e_r = cell(dim,1); + obj.d1_l = cell(dim,1); + obj.d1_r = cell(dim,1); + + % D1 + obj.D1{1} = kron(D1{1},I{2}); + obj.D1{2} = kron(I{1},D1{2}); + + % -- Metric coefficients ---- + coords = g.points(); + x = coords(:,1); + y = coords(:,2); + + % Use non-periodic difference operators for metric even if opSet is periodic. + xmax = max(ops{1}.x); + ymax = max(ops{2}.x); + opSetMetric{1} = sbp.D2Variable(m(1), {0, xmax}, order); + opSetMetric{2} = sbp.D2Variable(m(2), {0, ymax}, order); + D1Metric{1} = kron(opSetMetric{1}.D1, I{2}); + D1Metric{2} = kron(I{1}, opSetMetric{2}.D1); + + x_xi = D1Metric{1}*x; + x_eta = D1Metric{2}*x; + y_xi = D1Metric{1}*y; + y_eta = D1Metric{2}*y; + + J = x_xi.*y_eta - x_eta.*y_xi; + + b = cell(dim,dim); + b{1,1} = y_eta./J; + b{1,2} = -x_eta./J; + b{2,1} = -y_xi./J; + b{2,2} = x_xi./J; + + % Scale factors for boundary integrals + beta = cell(dim,1); + beta{1} = sqrt(x_eta.^2 + y_eta.^2); + beta{2} = sqrt(x_xi.^2 + y_xi.^2); + + J = spdiag(J); + Ji = inv(J); + for i = 1:dim + beta{i} = spdiag(beta{i}); + for j = 1:dim + b{i,j} = spdiag(b{i,j}); + end + end + obj.J = J; + obj.Ji = Ji; + obj.b = b; + obj.beta = beta; + %---------------------------- + + % Boundary operators + obj.e_l{1} = kron(e_l{1},I{2}); + obj.e_l{2} = kron(I{1},e_l{2}); + obj.e_r{1} = kron(e_r{1},I{2}); + obj.e_r{2} = kron(I{1},e_r{2}); + + obj.d1_l{1} = kron(d1_l{1},I{2}); + obj.d1_l{2} = kron(I{1},d1_l{2}); + obj.d1_r{1} = kron(d1_r{1},I{2}); + obj.d1_r{2} = kron(I{1},d1_r{2}); + + % D2 coefficients + kappa_coeff = cell(dim,dim); + for j = 1:dim + obj.D2_kappa{j} = sparse(m_tot,m_tot); + kappa_coeff{j} = sparse(m_tot,1); + for i = 1:dim + kappa_coeff{j} = kappa_coeff{j} + b{i,j}*J*b{i,j}*kappa; + end + end + ind = grid.funcToMatrix(g, 1:m_tot); + + % x-dir + j = 1; + for col = 1:m(2) + D_kappa = D2{1}(kappa_coeff{j}(ind(:,col))); + + p = ind(:,col); + obj.D2_kappa{j}(p,p) = D_kappa; + end + + % y-dir + j = 2; + for row = 1:m(1) + D_kappa = D2{2}(kappa_coeff{j}(ind(row,:))); + + p = ind(row,:); + obj.D2_kappa{j}(p,p) = D_kappa; + end + + % Quadratures + obj.H = kron(H{1},H{2}); + obj.Hi = inv(obj.H); + obj.H_boundary_l = cell(dim,1); + obj.H_boundary_l{1} = obj.e_l{1}'*beta{1}*obj.e_l{1}*H{2}; + obj.H_boundary_l{2} = obj.e_l{2}'*beta{2}*obj.e_l{2}*H{1}; + obj.H_boundary_r = cell(dim,1); + obj.H_boundary_r{1} = obj.e_r{1}'*beta{1}*obj.e_r{1}*H{2}; + obj.H_boundary_r{2} = obj.e_r{2}'*beta{2}*obj.e_r{2}*H{1}; + + %=== Differentiation matrix D (without SAT) === + D2_kappa = obj.D2_kappa; + D1 = obj.D1; + D = sparse(m_tot,m_tot); + + d = @kroneckerDelta; % Kronecker delta + db = @(i,j) 1-d(i,j); % Logical not of Kronecker delta + + % 2nd derivatives + for j = 1:dim + D = D + Ji*D2_kappa{j}; + end + + % Mixed terms + for i = 1:dim + for j = 1:dim + for k = 1:dim + D = D + db(i,j)*Ji*D1{j}*b{i,j}*J*KAPPA*b{i,k}*D1{k}; + end + end + end + obj.D = D; + %=========================================% + + % Normal flux operators for BC. + flux_l = cell(dim,1); + flux_r = cell(dim,1); + + d1_l = obj.d1_l; + d1_r = obj.d1_r; + e_l = obj.e_l; + e_r = obj.e_r; + + % Loop over boundaries + for j = 1:dim + flux_l{j} = sparse(m_tot,m_tot); + flux_r{j} = sparse(m_tot,m_tot); + + % Loop over dummy index + for i = 1:dim + % Loop over dummy index + for k = 1:dim + flux_l{j} = flux_l{j} ... + - beta{j}\b{i,j}*J*KAPPA*b{i,k}*( d(j,k)*e_l{k}*d1_l{k}' + db(j,k)*D1{k} ); + + flux_r{j} = flux_r{j} ... + + beta{j}\b{i,j}*J*KAPPA*b{i,k}*( d(j,k)*e_r{k}*d1_r{k}' + db(j,k)*D1{k} ); + end + + end + end + obj.flux_l = flux_l; + obj.flux_r = flux_r; + + % Misc. + obj.m = m; + obj.h = g.scaling(); + obj.order = order; + obj.grid = g; + obj.dim = dim; + obj.alpha = [ops{1}.borrowing.M.d1, ops{2}.borrowing.M.d1]; + + end + + + % Closure functions return the operators applied to the own domain to close the boundary + % Penalty functions return the operators 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. + % 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. + function [closure, penalty] = boundary_condition(obj, boundary, type, symmetric, tuning) + default_arg('type','Neumann'); + default_arg('symmetric', false); + default_arg('tuning',1.2); + + % j is the coordinate direction of the boundary + % nj: outward unit normal component. + % nj = -1 for west, south, bottom boundaries + % nj = 1 for east, north, top boundaries + [j, nj] = obj.get_boundary_number(boundary); + switch nj + case 1 + e = obj.e_r{j}; + flux = obj.flux_r{j}; + H_gamma = obj.H_boundary_r{j}; + case -1 + e = obj.e_l{j}; + flux = obj.flux_l{j}; + H_gamma = obj.H_boundary_l{j}; + end + + Hi = obj.Hi; + Ji = obj.Ji; + KAPPA = obj.KAPPA; + kappa_gamma = e'*KAPPA*e; + h = obj.h(j); + alpha = h*obj.alpha(j); + + switch type + + % Dirichlet boundary condition + case {'D','d','dirichlet','Dirichlet'} + + if ~symmetric + closure = -Ji*Hi*flux'*e*H_gamma*(e' ); + penalty = Ji*Hi*flux'*e*H_gamma; + else + closure = Ji*Hi*flux'*e*H_gamma*(e' )... + -tuning*2/alpha*Ji*Hi*e*kappa_gamma*H_gamma*(e' ) ; + penalty = -Ji*Hi*flux'*e*H_gamma ... + +tuning*2/alpha*Ji*Hi*e*kappa_gamma*H_gamma; + end + + % Normal flux boundary condition + case {'N','n','neumann','Neumann'} + closure = -Ji*Hi*e*H_gamma*(e'*flux ); + penalty = Ji*Hi*e*H_gamma; + + % Unknown boundary condition + otherwise + error('No such boundary condition: type = %s',type); + end + end + + function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary) + % u denotes the solution in the own domain + % v denotes the solution in the neighbour domain + error('Interface not implemented'); + end + + % Returns the coordinate number and outward normal component for the boundary specified by the string boundary. + function [j, nj] = get_boundary_number(obj, boundary) + + switch boundary + case {'w','W','west','West', 'e', 'E', 'east', 'East'} + j = 1; + case {'s','S','south','South', 'n', 'N', 'north', 'North'} + j = 2; + otherwise + error('No such boundary: boundary = %s',boundary); + end + + switch boundary + case {'w','W','west','West','s','S','south','South'} + nj = -1; + case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'} + nj = 1; + end + end + + % Returns the coordinate number and outward normal component for the boundary specified by the string boundary. + function [return_op] = get_boundary_operator(obj, op, boundary) + + switch boundary + case {'w','W','west','West', 'e', 'E', 'east', 'East'} + j = 1; + case {'s','S','south','South', 'n', 'N', 'north', 'North'} + j = 2; + otherwise + error('No such boundary: boundary = %s',boundary); + end + + switch op + case 'e' + switch boundary + case {'w','W','west','West','s','S','south','South'} + return_op = obj.e_l{j}; + case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'} + return_op = obj.e_r{j}; + end + case 'd' + switch boundary + case {'w','W','west','West','s','S','south','South'} + return_op = obj.d1_l{j}; + case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'} + return_op = obj.d1_r{j}; + end + otherwise + error(['No such operator: operatr = ' op]); + end + + end + + function N = size(obj) + N = prod(obj.m); + end + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+scheme/Heat2dVariable.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,276 @@ +classdef Heat2dVariable < scheme.Scheme + +% Discretizes the Laplacian with variable coefficent, +% In the Heat equation way (i.e., the discretization matrix is not necessarily +% symmetric) +% u_t = div * (kappa * grad u ) +% opSet should be cell array of opSets, one per dimension. This +% is useful if we have periodic BC in one direction. + + properties + m % Number of points in each direction, possibly a vector + h % Grid spacing + + grid + dim + + order % Order of accuracy for the approximation + + % Diagonal matrix for variable coefficients + KAPPA % Variable coefficient + + D % Total operator + D1 % First derivatives + + % Second derivatives + D2_kappa + + H, Hi % Inner products + e_l, e_r + d1_l, d1_r % Normal derivatives at the boundary + alpha % Vector of borrowing constants + + H_boundary % Boundary inner products + + end + + methods + + function obj = Heat2dVariable(g ,order, kappa_fun, opSet) + default_arg('opSet',{@sbp.D2Variable, @sbp.D2Variable}); + default_arg('kappa_fun', @(x,y) 0*x+1); + dim = 2; + + assert(isa(g, 'grid.Cartesian')) + + kappa = grid.evalOn(g, kappa_fun); + m = g.size(); + m_tot = g.N(); + + h = g.scaling(); + lim = g.lim; + + % 1D operators + ops = cell(dim,1); + for i = 1:dim + ops{i} = opSet{i}(m(i), lim{i}, order); + end + + I = cell(dim,1); + D1 = cell(dim,1); + D2 = cell(dim,1); + H = cell(dim,1); + Hi = cell(dim,1); + e_l = cell(dim,1); + e_r = cell(dim,1); + d1_l = cell(dim,1); + d1_r = cell(dim,1); + + for i = 1:dim + I{i} = speye(m(i)); + D1{i} = ops{i}.D1; + D2{i} = ops{i}.D2; + H{i} = ops{i}.H; + Hi{i} = ops{i}.HI; + e_l{i} = ops{i}.e_l; + e_r{i} = ops{i}.e_r; + d1_l{i} = ops{i}.d1_l; + d1_r{i} = ops{i}.d1_r; + end + + %====== Assemble full operators ======== + KAPPA = spdiag(kappa); + obj.KAPPA = KAPPA; + + obj.D1 = cell(dim,1); + obj.D2_kappa = cell(dim,1); + obj.e_l = cell(dim,1); + obj.e_r = cell(dim,1); + obj.d1_l = cell(dim,1); + obj.d1_r = cell(dim,1); + + % D1 + obj.D1{1} = kron(D1{1},I{2}); + obj.D1{2} = kron(I{1},D1{2}); + + % Boundary operators + obj.e_l{1} = kron(e_l{1},I{2}); + obj.e_l{2} = kron(I{1},e_l{2}); + obj.e_r{1} = kron(e_r{1},I{2}); + obj.e_r{2} = kron(I{1},e_r{2}); + + obj.d1_l{1} = kron(d1_l{1},I{2}); + obj.d1_l{2} = kron(I{1},d1_l{2}); + obj.d1_r{1} = kron(d1_r{1},I{2}); + obj.d1_r{2} = kron(I{1},d1_r{2}); + + % D2 + for i = 1:dim + obj.D2_kappa{i} = sparse(m_tot); + end + ind = grid.funcToMatrix(g, 1:m_tot); + + for i = 1:m(2) + D_kappa = D2{1}(kappa(ind(:,i))); + p = ind(:,i); + obj.D2_kappa{1}(p,p) = D_kappa; + end + + for i = 1:m(1) + D_kappa = D2{2}(kappa(ind(i,:))); + p = ind(i,:); + obj.D2_kappa{2}(p,p) = D_kappa; + end + + % Quadratures + obj.H = kron(H{1},H{2}); + obj.Hi = inv(obj.H); + obj.H_boundary = cell(dim,1); + obj.H_boundary{1} = H{2}; + obj.H_boundary{2} = H{1}; + + % Differentiation matrix D (without SAT) + D2_kappa = obj.D2_kappa; + D1 = obj.D1; + D = sparse(m_tot,m_tot); + for i = 1:dim + D = D + D2_kappa{i}; + end + obj.D = D; + %=========================================% + + % Misc. + obj.m = m; + obj.h = h; + obj.order = order; + obj.grid = g; + obj.dim = dim; + obj.alpha = [ops{1}.borrowing.M.d1, ops{2}.borrowing.M.d1]; + + end + + + % Closure functions return the operators applied to the own domain to close the boundary + % Penalty functions return the operators 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. + % 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. + function [closure, penalty] = boundary_condition(obj, boundary, type, symmetric, tuning) + default_arg('type','Neumann'); + default_arg('symmetric', false); + default_arg('tuning',1.2); + + % j is the coordinate direction of the boundary + % nj: outward unit normal component. + % nj = -1 for west, south, bottom boundaries + % nj = 1 for east, north, top boundaries + [j, nj] = obj.get_boundary_number(boundary); + switch nj + case 1 + e = obj.e_r; + d = obj.d1_r; + case -1 + e = obj.e_l; + d = obj.d1_l; + end + + Hi = obj.Hi; + H_gamma = obj.H_boundary{j}; + KAPPA = obj.KAPPA; + kappa_gamma = e{j}'*KAPPA*e{j}; + h = obj.h(j); + alpha = h*obj.alpha(j); + + switch type + + % Dirichlet boundary condition + case {'D','d','dirichlet','Dirichlet'} + + if ~symmetric + closure = -nj*Hi*d{j}*kappa_gamma*H_gamma*(e{j}' ); + penalty = nj*Hi*d{j}*kappa_gamma*H_gamma; + else + closure = nj*Hi*d{j}*kappa_gamma*H_gamma*(e{j}' )... + -tuning*2/alpha*Hi*e{j}*kappa_gamma*H_gamma*(e{j}' ) ; + penalty = -nj*Hi*d{j}*kappa_gamma*H_gamma ... + +tuning*2/alpha*Hi*e{j}*kappa_gamma*H_gamma; + end + + % Free boundary condition + case {'N','n','neumann','Neumann'} + closure = -nj*Hi*e{j}*kappa_gamma*H_gamma*(d{j}' ); + penalty = Hi*e{j}*kappa_gamma*H_gamma; + % penalty is for normal derivative and not for derivative, hence the sign. + + % Unknown boundary condition + otherwise + error('No such boundary condition: type = %s',type); + end + end + + function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary) + % u denotes the solution in the own domain + % v denotes the solution in the neighbour domain + error('Interface not implemented'); + end + + % Returns the coordinate number and outward normal component for the boundary specified by the string boundary. + function [j, nj] = get_boundary_number(obj, boundary) + + switch boundary + case {'w','W','west','West', 'e', 'E', 'east', 'East'} + j = 1; + case {'s','S','south','South', 'n', 'N', 'north', 'North'} + j = 2; + otherwise + error('No such boundary: boundary = %s',boundary); + end + + switch boundary + case {'w','W','west','West','s','S','south','South'} + nj = -1; + case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'} + nj = 1; + end + end + + % Returns the coordinate number and outward normal component for the boundary specified by the string boundary. + function [return_op] = get_boundary_operator(obj, op, boundary) + + switch boundary + case {'w','W','west','West', 'e', 'E', 'east', 'East'} + j = 1; + case {'s','S','south','South', 'n', 'N', 'north', 'North'} + j = 2; + otherwise + error('No such boundary: boundary = %s',boundary); + end + + switch op + case 'e' + switch boundary + case {'w','W','west','West','s','S','south','South'} + return_op = obj.e_l{j}; + case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'} + return_op = obj.e_r{j}; + end + case 'd' + switch boundary + case {'w','W','west','West','s','S','south','South'} + return_op = obj.d1_l{j}; + case {'e', 'E', 'east', 'East','n', 'N', 'north', 'North'} + return_op = obj.d1_r{j}; + end + otherwise + error(['No such operator: operatr = ' op]); + end + + end + + function N = size(obj) + N = prod(obj.m); + end + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+scheme/LaplaceCurvilinear.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,349 @@ +classdef LaplaceCurvilinear < scheme.Scheme + properties + m % Number of points in each direction, possibly a vector + h % Grid spacing + + grid + + order % Order accuracy for the approximation + + a,b % Parameters of the operator + + + % Inner products and operators for physical coordinates + D % Laplace operator + H, Hi % Inner product + e_w, e_e, e_s, e_n + d_w, d_e, d_s, d_n % Normal derivatives at the boundary + H_w, H_e, H_s, H_n % Boundary inner products + Dx, Dy % Physical derivatives + M % Gradient inner product + + % Metric coefficients + J, Ji + a11, a12, a22 + x_u + x_v + y_u + y_v + + % Inner product and operators for logical coordinates + H_u, H_v % Norms in the x and y directions + Hi_u, Hi_v + Hu,Hv % Kroneckerd norms. 1'*Hx*v corresponds to integration in the x dir. + Hiu, Hiv + du_w, dv_w + du_e, dv_e + du_s, dv_s + du_n, dv_n + gamm_u, gamm_v + lambda + end + + methods + % Implements a*div(b*grad(u)) as a SBP scheme + % TODO: Implement proper H, it should be the real physical quadrature, the logic quadrature may be but in a separate variable (H_logic?) + + function obj = LaplaceCurvilinear(g ,order, a, b, opSet) + default_arg('opSet',@sbp.D2Variable); + default_arg('a', 1); + default_arg('b', 1); + + if b ~=1 + error('Not implemented yet') + end + + assert(isa(g, 'grid.Curvilinear')) + + m = g.size(); + m_u = m(1); + m_v = m(2); + m_tot = g.N(); + + h = g.scaling(); + h_u = h(1); + h_v = h(2); + + + % 1D operators + ops_u = opSet(m_u, {0, 1}, order); + ops_v = opSet(m_v, {0, 1}, order); + + I_u = speye(m_u); + I_v = speye(m_v); + + D1_u = ops_u.D1; + D2_u = ops_u.D2; + H_u = ops_u.H; + Hi_u = ops_u.HI; + e_l_u = ops_u.e_l; + e_r_u = ops_u.e_r; + d1_l_u = ops_u.d1_l; + d1_r_u = ops_u.d1_r; + + D1_v = ops_v.D1; + D2_v = ops_v.D2; + H_v = ops_v.H; + Hi_v = ops_v.HI; + e_l_v = ops_v.e_l; + e_r_v = ops_v.e_r; + d1_l_v = ops_v.d1_l; + d1_r_v = ops_v.d1_r; + + + % Logical operators + Du = kr(D1_u,I_v); + Dv = kr(I_u,D1_v); + obj.Hu = kr(H_u,I_v); + obj.Hv = kr(I_u,H_v); + obj.Hiu = kr(Hi_u,I_v); + obj.Hiv = kr(I_u,Hi_v); + + e_w = kr(e_l_u,I_v); + e_e = kr(e_r_u,I_v); + e_s = kr(I_u,e_l_v); + e_n = kr(I_u,e_r_v); + obj.du_w = kr(d1_l_u,I_v); + obj.dv_w = (e_w'*Dv)'; + obj.du_e = kr(d1_r_u,I_v); + obj.dv_e = (e_e'*Dv)'; + obj.du_s = (e_s'*Du)'; + obj.dv_s = kr(I_u,d1_l_v); + obj.du_n = (e_n'*Du)'; + obj.dv_n = kr(I_u,d1_r_v); + + + % Metric coefficients + coords = g.points(); + x = coords(:,1); + y = coords(:,2); + + x_u = Du*x; + x_v = Dv*x; + y_u = Du*y; + y_v = Dv*y; + + J = x_u.*y_v - x_v.*y_u; + a11 = 1./J .* (x_v.^2 + y_v.^2); + a12 = -1./J .* (x_u.*x_v + y_u.*y_v); + a22 = 1./J .* (x_u.^2 + y_u.^2); + lambda = 1/2 * (a11 + a22 - sqrt((a11-a22).^2 + 4*a12.^2)); + + obj.x_u = x_u; + obj.x_v = x_v; + obj.y_u = y_u; + obj.y_v = y_v; + + + % Assemble full operators + L_12 = spdiag(a12); + Duv = Du*L_12*Dv; + Dvu = Dv*L_12*Du; + + Duu = sparse(m_tot); + Dvv = sparse(m_tot); + ind = grid.funcToMatrix(g, 1:m_tot); + + for i = 1:m_v + D = D2_u(a11(ind(:,i))); + p = ind(:,i); + Duu(p,p) = D; + end + + for i = 1:m_u + D = D2_v(a22(ind(i,:))); + p = ind(i,:); + Dvv(p,p) = D; + end + + + % Physical operators + obj.J = spdiag(J); + obj.Ji = spdiag(1./J); + + obj.D = obj.Ji*a*(Duu + Duv + Dvu + Dvv); + obj.H = obj.J*kr(H_u,H_v); + obj.Hi = obj.Ji*kr(Hi_u,Hi_v); + + obj.e_w = e_w; + obj.e_e = e_e; + obj.e_s = e_s; + obj.e_n = e_n; + + %% normal derivatives + I_w = ind(1,:); + I_e = ind(end,:); + I_s = ind(:,1); + I_n = ind(:,end); + + a11_w = spdiag(a11(I_w)); + a12_w = spdiag(a12(I_w)); + a11_e = spdiag(a11(I_e)); + a12_e = spdiag(a12(I_e)); + a22_s = spdiag(a22(I_s)); + a12_s = spdiag(a12(I_s)); + a22_n = spdiag(a22(I_n)); + a12_n = spdiag(a12(I_n)); + + s_w = sqrt((e_w'*x_v).^2 + (e_w'*y_v).^2); + s_e = sqrt((e_e'*x_v).^2 + (e_e'*y_v).^2); + s_s = sqrt((e_s'*x_u).^2 + (e_s'*y_u).^2); + s_n = sqrt((e_n'*x_u).^2 + (e_n'*y_u).^2); + + obj.d_w = -1*(spdiag(1./s_w)*(a11_w*obj.du_w' + a12_w*obj.dv_w'))'; + obj.d_e = (spdiag(1./s_e)*(a11_e*obj.du_e' + a12_e*obj.dv_e'))'; + obj.d_s = -1*(spdiag(1./s_s)*(a22_s*obj.dv_s' + a12_s*obj.du_s'))'; + obj.d_n = (spdiag(1./s_n)*(a22_n*obj.dv_n' + a12_n*obj.du_n'))'; + + obj.Dx = spdiag( y_v./J)*Du + spdiag(-y_u./J)*Dv; + obj.Dy = spdiag(-x_v./J)*Du + spdiag( x_u./J)*Dv; + + %% Boundary inner products + obj.H_w = H_v*spdiag(s_w); + obj.H_e = H_v*spdiag(s_e); + obj.H_s = H_u*spdiag(s_s); + obj.H_n = H_u*spdiag(s_n); + + % Misc. + obj.m = m; + obj.h = [h_u h_v]; + obj.order = order; + obj.grid = g; + + obj.a = a; + obj.b = b; + obj.a11 = a11; + obj.a12 = a12; + obj.a22 = a22; + obj.lambda = lambda; + + obj.gamm_u = h_u*ops_u.borrowing.M.d1; + obj.gamm_v = h_v*ops_v.borrowing.M.d1; + end + + + % 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. + % 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. + function [closure, penalty] = boundary_condition(obj, boundary, type, parameter) + default_arg('type','neumann'); + default_arg('parameter', []); + + [e, d, gamm, H_b, ~] = obj.get_boundary_ops(boundary); + switch type + % Dirichlet boundary condition + case {'D','d','dirichlet'} + tuning = 1.2; + % tuning = 20.2; + + b1 = gamm*obj.lambda./obj.a11.^2; + b2 = gamm*obj.lambda./obj.a22.^2; + + tau1 = tuning * spdiag(-1./b1 - 1./b2); + tau2 = 1; + + tau = (tau1*e + tau2*d)*H_b; + + closure = obj.a*obj.Hi*tau*e'; + penalty = -obj.a*obj.Hi*tau; + + + % Neumann boundary condition + case {'N','n','neumann'} + tau1 = -1; + tau2 = 0; + tau = (tau1*e + tau2*d)*H_b; + + closure = obj.a*obj.Hi*tau*d'; + penalty = -obj.a*obj.Hi*tau; + + + % Unknown, boundary condition + otherwise + error('No such boundary condition: type = %s',type); + end + end + + function [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary) + % u denotes the solution in the own domain + % v denotes the solution in the neighbour domain + tuning = 1.2; + % tuning = 20.2; + [e_u, d_u, gamm_u, H_b_u, I_u] = obj.get_boundary_ops(boundary); + [e_v, d_v, gamm_v, H_b_v, I_v] = neighbour_scheme.get_boundary_ops(neighbour_boundary); + + u = obj; + v = neighbour_scheme; + + b1_u = gamm_u*u.lambda(I_u)./u.a11(I_u).^2; + b2_u = gamm_u*u.lambda(I_u)./u.a22(I_u).^2; + b1_v = gamm_v*v.lambda(I_v)./v.a11(I_v).^2; + b2_v = gamm_v*v.lambda(I_v)./v.a22(I_v).^2; + + tau1 = -1./(4*b1_u) -1./(4*b1_v) -1./(4*b2_u) -1./(4*b2_v); + tau1 = tuning * spdiag(tau1); + tau2 = 1/2; + + sig1 = -1/2; + sig2 = 0; + + tau = (e_u*tau1 + tau2*d_u)*H_b_u; + sig = (sig1*e_u + sig2*d_u)*H_b_u; + + closure = obj.a*obj.Hi*( tau*e_u' + sig*d_u'); + penalty = obj.a*obj.Hi*(-tau*e_v' + sig*d_v'); + end + + % Ruturns the boundary ops and sign for the boundary specified by the string boundary. + % The right boundary is considered the positive boundary + % + % I -- the indecies of the boundary points in the grid matrix + function [e, d, gamm, H_b, I] = get_boundary_ops(obj, boundary) + + % gridMatrix = zeros(obj.m(2),obj.m(1)); + % gridMatrix(:) = 1:numel(gridMatrix); + + ind = grid.funcToMatrix(obj.grid, 1:prod(obj.m)); + + switch boundary + case 'w' + e = obj.e_w; + d = obj.d_w; + H_b = obj.H_w; + I = ind(1,:); + case 'e' + e = obj.e_e; + d = obj.d_e; + H_b = obj.H_e; + I = ind(end,:); + case 's' + e = obj.e_s; + d = obj.d_s; + H_b = obj.H_s; + I = ind(:,1)'; + case 'n' + e = obj.e_n; + d = obj.d_n; + H_b = obj.H_n; + I = ind(:,end)'; + otherwise + error('No such boundary: boundary = %s',boundary); + end + + switch boundary + case {'w','e'} + gamm = obj.gamm_u; + case {'s','n'} + gamm = obj.gamm_v; + end + end + + function N = size(obj) + N = prod(obj.m); + end + end +end
--- a/+scheme/Scheme.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+scheme/Scheme.m Tue Sep 11 15:58:35 2018 +0200 @@ -1,42 +1,47 @@ -% 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) - m % Number of points in each direction, possibly a vector 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. - % 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. - m = boundary_condition(obj,boundary,type,data) - m = interface(obj,boundary,neighbour_scheme,neighbour_boundary) - N = size(obj) % Returns the number of degrees of freedom. + % 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. + % neighbour_scheme is an instance of Scheme that should be + % interfaced to. + % neighbour_boundary is a string specifying which boundary to + % interface to. + % penalty may be a cell array if there are several penalties with different weights + [closure, penalty] = boundary_condition(obj,boundary,type) % TODO: Change name to boundaryCondition + [closure, penalty] = interface(obj,boundary,neighbour_scheme,neighbour_boundary) + % TODO: op = getBoundaryOperator()?? + % makes sense to have it available through a method instead of random properties + + % 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+scheme/TODO.txt Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,1 @@ +% TODO: Rename package and abstract class to diffOp
--- a/+scheme/Wave2dCurve.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+scheme/Wave2dCurve.m Tue Sep 11 15:58:35 2018 +0200 @@ -2,9 +2,9 @@ properties m % Number of points in each direction, possibly a vector h % Grid spacing - u,v % Grid - x,y % Values of x and y for each grid point - X,Y % Grid point locations as matrices + + grid + order % Order accuracy for the approximation D % non-stabalized scheme operator @@ -26,24 +26,32 @@ du_n, dv_n gamm_u, gamm_v lambda + + Dx, Dy % Physical derivatives + + x_u + x_v + y_u + y_v end methods - function obj = Wave2dCurve(m,ti,order,c,opSet) + function obj = Wave2dCurve(g ,order, c, opSet) default_arg('opSet',@sbp.D2Variable); default_arg('c', 1); - if length(m) == 1 - m = [m m]; - end + warning('Use LaplaceCruveilinear instead') + assert(isa(g, 'grid.Curvilinear')) + + m = g.size(); m_u = m(1); m_v = m(2); - m_tot = m_u*m_v; + m_tot = g.N(); - [u, h_u] = util.get_grid(0, 1, m_u); - [v, h_v] = util.get_grid(0, 1, m_v); - + h = g.scaling(); + h_u = h(1); + h_v = h(2); % Operators ops_u = opSet(m_u, {0, 1}, order); @@ -52,66 +60,64 @@ I_u = speye(m_u); I_v = speye(m_v); - D1_u = sparse(ops_u.D1); + D1_u = ops_u.D1; D2_u = ops_u.D2; - H_u = sparse(ops_u.H); - Hi_u = sparse(ops_u.HI); - % M_u = sparse(ops_u.M); - e_l_u = sparse(ops_u.e_l); - e_r_u = sparse(ops_u.e_r); - d1_l_u = sparse(ops_u.d1_l); - d1_r_u = sparse(ops_u.d1_r); + H_u = ops_u.H; + Hi_u = ops_u.HI; + e_l_u = ops_u.e_l; + e_r_u = ops_u.e_r; + d1_l_u = ops_u.d1_l; + d1_r_u = ops_u.d1_r; - D1_v = sparse(ops_v.D1); + D1_v = ops_v.D1; D2_v = ops_v.D2; - H_v = sparse(ops_v.H); - Hi_v = sparse(ops_v.HI); - % M_v = sparse(ops_v.M); - e_l_v = sparse(ops_v.e_l); - e_r_v = sparse(ops_v.e_r); - d1_l_v = sparse(ops_v.d1_l); - d1_r_v = sparse(ops_v.d1_r); + H_v = ops_v.H; + Hi_v = ops_v.HI; + e_l_v = ops_v.e_l; + e_r_v = ops_v.e_r; + d1_l_v = ops_v.d1_l; + d1_r_v = ops_v.d1_r; + + Du = kr(D1_u,I_v); + Dv = kr(I_u,D1_v); % Metric derivatives - [X,Y] = ti.map(u,v); + coords = g.points(); + x = coords(:,1); + y = coords(:,2); - [x_u,x_v] = gridDerivatives(X,D1_u,D1_v); - [y_u,y_v] = gridDerivatives(Y,D1_u,D1_v); - - + x_u = Du*x; + x_v = Dv*x; + y_u = Du*y; + y_v = Dv*y; J = x_u.*y_v - x_v.*y_u; - a11 = 1./J .* (x_v.^2 + y_v.^2); %% GÖR SOM MATRISER + a11 = 1./J .* (x_v.^2 + y_v.^2); a12 = -1./J .* (x_u.*x_v + y_u.*y_v); a22 = 1./J .* (x_u.^2 + y_u.^2); lambda = 1/2 * (a11 + a22 - sqrt((a11-a22).^2 + 4*a12.^2)); - dof_order = reshape(1:m_u*m_v,m_v,m_u); + % Assemble full operators + L_12 = spdiags(a12, 0, m_tot, m_tot); + Duv = Du*L_12*Dv; + Dvu = Dv*L_12*Du; Duu = sparse(m_tot); Dvv = sparse(m_tot); + ind = grid.funcToMatrix(g, 1:m_tot); for i = 1:m_v - D = D2_u(a11(i,:)); - p = dof_order(i,:); + D = D2_u(a11(ind(:,i))); + p = ind(:,i); Duu(p,p) = D; end for i = 1:m_u - D = D2_v(a22(:,i)); - p = dof_order(:,i); + D = D2_v(a22(ind(i,:))); + p = ind(i,:); Dvv(p,p) = D; end - L_12 = spdiags(a12(:),0,m_tot,m_tot); - Du = kr(D1_u,I_v); - Dv = kr(I_u,D1_v); - - Duv = Du*L_12*Dv; - Dvu = Dv*L_12*Du; - - - obj.H = kr(H_u,H_v); obj.Hi = kr(Hi_u,Hi_v); obj.Hu = kr(H_u,I_v); @@ -119,7 +125,6 @@ obj.Hiu = kr(Hi_u,I_v); obj.Hiv = kr(I_u,Hi_v); - % obj.M = kr(M_u,H_v)+kr(H_u,M_v); obj.e_w = kr(e_l_u,I_v); obj.e_e = kr(e_r_u,I_v); obj.e_s = kr(I_u,e_l_v); @@ -133,28 +138,30 @@ obj.du_n = (obj.e_n'*Du)'; obj.dv_n = kr(I_u,d1_r_v); + obj.x_u = x_u; + obj.x_v = x_v; + obj.y_u = y_u; + obj.y_v = y_v; + obj.m = m; obj.h = [h_u h_v]; obj.order = order; - + obj.grid = g; obj.c = c; - obj.J = spdiags(J(:),0,m_tot,m_tot); - obj.Ji = spdiags(1./J(:),0,m_tot,m_tot); + obj.J = spdiags(J, 0, m_tot, m_tot); + obj.Ji = spdiags(1./J, 0, m_tot, m_tot); obj.a11 = a11; obj.a12 = a12; obj.a22 = a22; obj.D = obj.Ji*c^2*(Duu + Duv + Dvu + Dvv); - obj.u = u; - obj.v = v; - obj.X = X; - obj.Y = Y; - obj.x = X(:); - obj.y = Y(:); obj.lambda = lambda; - obj.gamm_u = h_u*ops_u.borrowing.M.S; - obj.gamm_v = h_v*ops_v.borrowing.M.S; + obj.Dx = spdiag( y_v./J)*Du + spdiag(-y_u./J)*Dv; + obj.Dy = spdiag(-x_v./J)*Du + spdiag( x_u./J)*Dv; + + obj.gamm_u = h_u*ops_u.borrowing.M.d1; + obj.gamm_v = h_v*ops_v.borrowing.M.d1; end @@ -165,12 +172,11 @@ % 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. - function [closure, penalty] = boundary_condition(obj,boundary,type,data) + function [closure, penalty] = boundary_condition(obj, boundary, type, parameter) default_arg('type','neumann'); - default_arg('data',0); + default_arg('parameter', []); - [e, d_n, d_t, coeff_n, coeff_t, s, gamm, halfnorm_inv] = obj.get_boundary_ops(boundary); - + [e, d_n, d_t, coeff_n, coeff_t, s, gamm, halfnorm_inv , ~, ~, ~, scale_factor] = obj.get_boundary_ops(boundary); switch type % Dirichlet boundary condition case {'D','d','dirichlet'} @@ -190,28 +196,19 @@ b2 = gamm*u.lambda./u.a22.^2; tau = -1./b1 - 1./b2; - tau = tuning * spdiag(tau(:)); - sig1 = 1/2; + tau = tuning * spdiag(tau); + sig1 = 1; penalty_parameter_1 = halfnorm_inv_n*(tau + sig1*halfnorm_inv_t*F*e'*halfnorm_t)*e; closure = obj.Ji*obj.c^2 * penalty_parameter_1*e'; - pp = -obj.Ji*obj.c^2 * penalty_parameter_1; - switch class(data) - case 'double' - penalty = pp*data; - case 'function_handle' - penalty = @(t)pp*data(t); - otherwise - error('Weird data argument!') - end + penalty = -obj.Ji*obj.c^2 * penalty_parameter_1; % Neumann boundary condition case {'N','n','neumann'} c = obj.c; - a_n = spdiags(coeff_n,0,length(coeff_n),length(coeff_n)); a_t = spdiags(coeff_t,0,length(coeff_t),length(coeff_t)); d = (a_n * d_n' + a_t*d_t')'; @@ -221,16 +218,24 @@ tau = c.^2 * obj.Ji*(tau1*e + tau2*d); closure = halfnorm_inv*tau*d'; + penalty = -halfnorm_inv*tau; - pp = halfnorm_inv*tau; - switch class(data) - case 'double' - penalty = pp*data; - case 'function_handle' - penalty = @(t)pp*data(t); - otherwise - error('Weird data argument!') - end + % Characteristic boundary condition + case {'characteristic', 'char', 'c'} + default_arg('parameter', 1); + beta = parameter; + c = obj.c; + + a_n = spdiags(coeff_n,0,length(coeff_n),length(coeff_n)); + a_t = spdiags(coeff_t,0,length(coeff_t),length(coeff_t)); + d = s*(a_n * d_n' + a_t*d_t')'; % outward facing normal derivative + + tau = -c.^2 * 1/beta*obj.Ji*e; + + warning('is this right?! /c?') + closure{1} = halfnorm_inv*tau/c*spdiag(scale_factor)*e'; + closure{2} = halfnorm_inv*tau*beta*d'; + penalty = -halfnorm_inv*tau; % Unknown, boundary condition otherwise @@ -263,7 +268,7 @@ b2_v = gamm_v*v.lambda(I_v)./v.a22(I_v).^2; tau = -1./(4*b1_u) -1./(4*b1_v) -1./(4*b2_u) -1./(4*b2_v); - tau = tuning * spdiag(tau(:)); + tau = tuning * spdiag(tau); sig1 = 1/2; sig2 = -1/2; @@ -279,10 +284,12 @@ % The right boundary is considered the positive boundary % % I -- the indecies of the boundary points in the grid matrix - function [e, d_n, d_t, coeff_n, coeff_t, s, gamm, halfnorm_inv_n, halfnorm_inv_t, halfnorm_t, I] = get_boundary_ops(obj,boundary) + function [e, d_n, d_t, coeff_n, coeff_t, s, gamm, halfnorm_inv_n, halfnorm_inv_t, halfnorm_t, I, scale_factor] = get_boundary_ops(obj, boundary) - gridMatrix = zeros(obj.m(2),obj.m(1)); - gridMatrix(:) = 1:numel(gridMatrix); + % gridMatrix = zeros(obj.m(2),obj.m(1)); + % gridMatrix(:) = 1:numel(gridMatrix); + + ind = grid.funcToMatrix(obj.grid, 1:prod(obj.m)); switch boundary case 'w' @@ -291,36 +298,40 @@ d_t = obj.dv_w; s = -1; - I = gridMatrix(:,1); + I = ind(1,:); coeff_n = obj.a11(I); coeff_t = obj.a12(I); + scale_factor = sqrt(obj.x_v(I).^2 + obj.y_v(I).^2); case 'e' e = obj.e_e; d_n = obj.du_e; d_t = obj.dv_e; s = 1; - I = gridMatrix(:,end); + I = ind(end,:); coeff_n = obj.a11(I); coeff_t = obj.a12(I); + scale_factor = sqrt(obj.x_v(I).^2 + obj.y_v(I).^2); case 's' e = obj.e_s; d_n = obj.dv_s; d_t = obj.du_s; s = -1; - I = gridMatrix(1,:)'; + I = ind(:,1)'; coeff_n = obj.a22(I); coeff_t = obj.a12(I); + scale_factor = sqrt(obj.x_u(I).^2 + obj.y_u(I).^2); case 'n' e = obj.e_n; d_n = obj.dv_n; d_t = obj.du_n; s = 1; - I = gridMatrix(end,:)'; + I = ind(:,end)'; coeff_n = obj.a22(I); coeff_t = obj.a12(I); + scale_factor = sqrt(obj.x_u(I).^2 + obj.y_u(I).^2); otherwise error('No such boundary: boundary = %s',boundary); end @@ -343,15 +354,6 @@ N = prod(obj.m); end - 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') - 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+scheme/bcSetup.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,110 @@ +% function [closure, S] = bcSetup(diffOp, bc) +% Takes a diffOp and a cell array of boundary condition definitions. +% Each bc is a struct with the fields +% * type -- Type of boundary condition +% * boundary -- Boundary identifier +% * data -- A function_handle for a function which provides boundary data.(see below) +% Also takes S_sign which modifies the sign of S, [-1,1] +% Returns a closure matrix and a forcing function S. +% +% The boundary data function can either be a function of time or a function of time and space coordinates. +% In the case where it only depends on time it should return the data as grid function for the boundary. +% In the case where it also takes space coordinates the number of space coordinates should match the number of dimensions of the problem domain. +% For example in the 2D case: f(t,x,y). +function [closure, S] = bcSetup(diffOp, bcs, S_sign) + default_arg('S_sign', 1); + assertType(bcs, 'cell'); + assert(S_sign == 1 || S_sign == -1, 'S_sign must be either 1 or -1'); + + verifyBcFormat(bcs, diffOp); + + % Setup storage arrays + closure = spzeros(size(diffOp)); + gridData = {}; + symbolicData = {}; + + % Collect closures, penalties and data + for i = 1:length(bcs) + [localClosure, penalty] = diffOp.boundary_condition(bcs{i}.boundary, bcs{i}.type); + closure = closure + localClosure; + + [ok, isSym, data] = parseData(bcs{i}, penalty, diffOp.grid); + + if ~ok + % There was no data + continue + end + + if isSym + symbolicData{end+1} = data; + else + gridData{end+1} = data; + end + end + + % Setup penalty function + O = spzeros(size(diffOp),1); + function v = S_fun(t) + v = O; + for i = 1:length(gridData) + v = v + gridData{i}.penalty*gridData{i}.func(t); + end + + for i = 1:length(symbolicData) + v = v + symbolicData{i}.penalty*symbolicData{i}.func(t, symbolicData{i}.coords{:}); + end + + v = S_sign * v; + end + S = @S_fun; +end + +function verifyBcFormat(bcs, diffOp) + for i = 1:length(bcs) + assertType(bcs{i}, 'struct'); + assertStructFields(bcs{i}, {'type', 'boundary'}); + + if ~isfield(bcs{i}, 'data') || isempty(bcs{i}.data) + continue + end + + if ~isa(bcs{i}.data, 'function_handle') + error('bcs{%d}.data should be a function of time or a function of time and space',i); + end + + b = diffOp.grid.getBoundary(bcs{i}.boundary); + + dim = size(b,2); + + if nargin(bcs{i}.data) == 1 + % Grid data (only function of time) + assertSize(bcs{i}.data(0), 1, size(b)); + elseif nargin(bcs{i}.data) ~= 1+dim + error('sbplib:scheme:bcSetup:DataWrongNumberOfArguments', 'bcs{%d}.data has the wrong number of input arguments. Must be either only time or time and space.', i); + end + end +end + +function [ok, isSym, dataStruct] = parseData(bc, penalty, grid) + if ~isfield(bc,'data') || isempty(bc.data) + ok = false; + return + end + ok = true; + + nArg = nargin(bc.data); + + if nArg > 1 + % Symbolic data + isSym = true; + coord = grid.getBoundary(bc.boundary); + dataStruct.penalty = penalty; + dataStruct.func = bc.data; + dataStruct.coords = num2cell(coord, 1); + else + % Grid data + isSym = false; + dataStruct.penalty = penalty; + dataStruct.func = bcs{i}.data; + end +end
--- a/+time/Cdiff.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+time/Cdiff.m Tue Sep 11 15:58:35 2018 +0200 @@ -12,22 +12,20 @@ methods + % Solves u_tt = Du + Eu_t + S + % D, E, S can either all be constants or all be function handles, + % They can also be omitted by setting them equal to the empty matrix. + % Cdiff(D, E, S, k, t0, n0, v, v_prev) function obj = Cdiff(D, E, S, k, t0, n0, v, v_prev) - % Cdiff(D, E, S, k, t0, n0, v, v_prev) - m = size(D,1); + m = length(v); default_arg('E',sparse(m,m)); default_arg('S',sparse(m,1)); - if ~(issparse(D) && issparse(E) && issparse(S)) - warning('One of the matrices D, E, S is not sparse!') - print_issparse(D) - print_issparse(E) - print_issparse(S) - end - obj.D = D; obj.E = E; obj.S = S; + + obj.k = k; obj.t = t0; obj.n = n0;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+time/CdiffImplicit.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,152 @@ +classdef CdiffImplicit < time.Timestepper + properties + A, B, C, G + AA, BB, CC + k + t + v, v_prev + n + + % LU factorization + L,U,p,q + end + + methods + % Solves + % A*u_tt + B*u + C*v_t = G(t) + % u(t0) = f1 + % u_t(t0) = f2 + % starting at time t0 with timestep k + function obj = CdiffImplicit(A, B, C, G, f1, f2, k, t0) + default_arg('A', []); + default_arg('C', []); + default_arg('G', []); + default_arg('f1', 0); + default_arg('f2', 0); + default_arg('t0', 0); + + m = size(B,1); + + if isempty(A) + A = speye(m); + end + + if isempty(C) + C = sparse(m,m); + end + + if isempty(G) + G = @(t) sparse(m,1); + end + + if isempty(f1) + f1 = sparse(m,1); + end + + if isempty(f2) + f2 = sparse(m,1); + end + + obj.A = A; + obj.B = B; + obj.C = C; + obj.G = G; + + AA = 1/k^2*A + 1/2*B + 1/(2*k)*C; + BB = -2/k^2*A; + CC = 1/k^2*A + 1/2*B - 1/(2*k)*C; + % AA*v_next + BB*v + CC*v_prev == G(t_n) + + obj.AA = AA; + obj.BB = BB; + obj.CC = CC; + + v_prev = f1; + I = speye(m); + % v = (1/k^2*A)\((1/k^2*A - 1/2*B)*f1 + (1/k*I - 1/2*C)*f2 + 1/2*G(0)); + v = f1 + k*f2; + + + if ~issparse(A) || ~issparse(B) || ~issparse(C) + error('LU factorization with full pivoting only works for sparse matrices.') + end + + [L,U,p,q] = lu(AA,'vector'); + + obj.L = L; + obj.U = U; + obj.p = p; + obj.q = q; + + + obj.k = k; + obj.t = t0+k; + obj.n = 1; + obj.v = v; + obj.v_prev = v_prev; + end + + function [v,t] = getV(obj) + v = obj.v; + t = obj.t; + end + + function [vt,t] = getVt(obj) + % Calculate next time step to be able to do centered diff. + v_next = zeros(size(obj.v)); + b = obj.G(obj.t) - obj.BB*obj.v - obj.CC*obj.v_prev; + + y = obj.L\b(obj.p); + z = obj.U\y; + v_next(obj.q) = z; + + + vt = (v_next-obj.v_prev)/(2*obj.k); + t = obj.t; + end + + function obj = step(obj) + b = obj.G(obj.t) - obj.BB*obj.v - obj.CC*obj.v_prev; + obj.v_prev = obj.v; + + % % Backslash + % obj.v = obj.AA\b; + + % LU with column pivot + y = obj.L\b(obj.p); + z = obj.U\y; + obj.v(obj.q) = z; + + % Update time + obj.t = obj.t + obj.k; + obj.n = obj.n + 1; + end + end +end + + + + + +%%% Derivation +% syms A B C G +% syms n k +% syms f1 f2 + +% v = symfun(sym('v(n)'),n); + + +% d = A/k^2 * (v(n+1) - 2*v(n) +v(n-1)) + B/2*(v(n+1)+v(n-1)) + C/(2*k)*(v(n+1) - v(n-1)) == G +% ic1 = v(0) == f1 +% ic2 = A/k*(v(1)-f1) + k/2*(B*f1 + C*f2 - G) - f2 == 0 + +% c = collect(d, [v(n) v(n-1) v(n+1)]) % (-(2*A)/k^2)*v(n) + (B/2 + A/k^2 - C/(2*k))*v(n - 1) + (B/2 + A/k^2 + C/(2*k))*v(n + 1) == G +% syms AA BB CC +% % AA = B/2 + A/k^2 + C/(2*k) +% % BB = -(2*A)/k^2 +% % CC = B/2 + A/k^2 - C/(2*k) +% s = subs(c, [B/2 + A/k^2 + C/(2*k), -(2*A)/k^2, B/2 + A/k^2 - C/(2*k)], [AA, BB, CC]) + + +% ic2_a = collect(ic2, [v(1) f1 f2]) % (A/k)*v(1) + ((B*k)/2 - A/k)*f1 + ((C*k)/2 - 1)*f2 - (G*k)/2 == 0 +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+time/CdiffTimeDep.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,51 @@ +classdef CdiffTimeDep < time.Timestepper + properties + D + E + S + k + t + v + v_prev + n + end + + + methods + % Solves u_tt = Du + E(t)u_t + S(t) + % D, E, S can either all be constants or all be function handles, + % They can also be omitted by setting them equal to the empty matrix. + % CdiffTimeDep(D, E, S, k, t0, n0, v, v_prev) + function obj = CdiffTimeDep(D, E, S, k, t0, n0, v, v_prev) + m = length(v); + default_arg('E', @(t)sparse(m,m)); + default_arg('S', @(t)sparse(m,1)); + + obj.D = D; + obj.E = E; + obj.S = S; + + obj.k = k; + obj.t = t0; + obj.n = n0; + obj.v = v; + obj.v_prev = v_prev; + end + + function [v,t] = getV(obj) + v = obj.v; + t = obj.t; + end + + function [vt,t] = getVt(obj) + vt = (obj.v-obj.v_prev)/obj.k; % Could be improved using u_tt = f(u)) + t = obj.t; + end + + function obj = step(obj) + [obj.v, obj.v_prev] = time.cdiff.cdiff(obj.v, obj.v_prev, obj.k, obj.D, obj.E(obj.t), obj.S(obj.t)); + obj.t = obj.t + obj.k; + obj.n = obj.n + 1; + end + end +end \ No newline at end of file
--- a/+time/Rungekutta4SecondOrder.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+time/Rungekutta4SecondOrder.m Tue Sep 11 15:58:35 2018 +0200 @@ -15,6 +15,21 @@ methods + % Solves u_tt = Du + Eu_t + S by + % Rewriting on first order form: + % w_t = M*w + C(t) + % where + % M = [ + % 0, I; + % D, E; + % ] + % and + % C(t) = [ + % 0; + % S(t) + % ] + % D, E, S can either all be constants or all be function handles, + % They can also be omitted by setting them equal to the empty matrix. function obj = Rungekutta4SecondOrder(D, E, S, k, t0, v0, v0t) obj.D = D; obj.E = E; @@ -22,21 +37,55 @@ obj.m = length(v0); obj.n = 0; - I = speye(obj.m); - O = sparse(obj.m,obj.m); - obj.M = [O, I; D, E*I]; % Multiply with I to allow 0 as input. + + if isa(D, 'function_handle') || isa(E, 'function_handle') || isa(S, 'function_handle') + default_arg('D', @(t)sparse(obj.m, obj.m)); + default_arg('E', @(t)sparse(obj.m, obj.m)); + default_arg('S', @(t)sparse(obj.m, 1) ); - if S == 0 - obj.C = zeros(2*obj.m,1); + if ~isa(D, 'function_handle') + D = @(t)D; + end + if ~isa(E, 'function_handle') + E = @(t)E; + end + if ~isa(S, 'function_handle') + S = @(t)S; + end + + obj.k = k; + obj.t = t0; + obj.w = [v0; v0t]; + + % Avoid matrix formulation because it is VERY slow + obj.F = @(w,t)[ + w(obj.m+1:end); + D(t)*w(1:obj.m) + E(t)*w(obj.m+1:end) + S(t); + ]; else - obj.C = [zeros(obj.m,1), S]; - end + + default_arg('D', sparse(obj.m, obj.m)); + default_arg('E', sparse(obj.m, obj.m)); + default_arg('S', sparse(obj.m, 1) ); + + I = speye(obj.m); + O = sparse(obj.m,obj.m); - obj.k = k; - obj.t = t0; - obj.w = [v0; v0t]; + obj.M = [ + O, I; + D, E; + ]; + obj.C = [ + zeros(obj.m,1); + S; + ]; - obj.F = @(w,t)(obj.M*w + obj.C); + obj.k = k; + obj.t = t0; + obj.w = [v0; v0t]; + + obj.F = @(w,t)(obj.M*w + obj.C); + end end function [v,t] = getV(obj)
--- a/+time/Rungekutta4proper.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+time/Rungekutta4proper.m Tue Sep 11 15:58:35 2018 +0200 @@ -10,6 +10,7 @@ methods + % Timesteps v_t = F(v,t), using RK4 fromt t = t0 with timestep k and initial conditions v = v0 function obj = Rungekutta4proper(F, k, t0, v0) obj.F = F; obj.k = k;
--- a/+time/SBPInTime.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+time/SBPInTime.m Tue Sep 11 15:58:35 2018 +0200 @@ -104,6 +104,7 @@ end end + methods(Static) function N = smallestBlockSize(order,TYPE) default_arg('TYPE','gauss')
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+time/SBPInTimeImplicitFormulation.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,130 @@ +classdef SBPInTimeImplicitFormulation < time.Timestepper + % The SBP in time method. + % Implemented for A*v_t = B*v + f(t), v(0) = v0 + properties + A,B + f + + k % total time step. + + blockSize % number of points in each block + N % Number of components + + order + nodes + + M,K % System matrices + L,U,p,q % LU factorization of M + e_T + + % Time state + t + v + n + end + + methods + function obj = SBPInTimeImplicitFormulation(A, B, f, k, t0, v0, TYPE, order, blockSize) + + default_arg('TYPE','gauss'); + default_arg('f',[]); + + if(strcmp(TYPE,'gauss')) + default_arg('order',4) + default_arg('blockSize',4) + else + default_arg('order', 8); + default_arg('blockSize',time.SBPInTimeImplicitFormulation.smallestBlockSize(order,TYPE)); + end + + obj.A = A; + obj.B = B; + + if ~isempty(f) + obj.f = f; + else + obj.f = @(t)sparse(length(v0),1); + end + + obj.k = k; + obj.blockSize = blockSize; + obj.N = length(v0); + + obj.n = 0; + obj.t = t0; + + %==== Build the time discretization matrix =====% + switch TYPE + case 'equidistant' + ops = sbp.D2Standard(blockSize,{0,obj.k},order); + case 'optimal' + ops = sbp.D1Nonequidistant(blockSize,{0,obj.k},order); + case 'minimal' + ops = sbp.D1Nonequidistant(blockSize,{0,obj.k},order,'minimal'); + case 'gauss' + ops = sbp.D1Gauss(blockSize,{0,obj.k}); + end + + I = speye(size(A)); + I_t = speye(blockSize,blockSize); + + D1 = kron(ops.D1, I); + HI = kron(ops.HI, I); + e_0 = kron(ops.e_l, I); + e_T = kron(ops.e_r, I); + obj.nodes = ops.x; + + % Convert to form M*w = K*v0 + f(t) + tau = kron(I_t, A) * e_0; + M = kron(I_t, A)*D1 + HI*tau*e_0' - kron(I_t, B); + + K = HI*tau; + + obj.M = M; + obj.K = K; + obj.e_T = e_T; + + % LU factorization + [obj.L,obj.U,obj.p,obj.q] = lu(obj.M, 'vector'); + + obj.v = v0; + end + + function [v,t] = getV(obj) + v = obj.v; + t = obj.t; + end + + function obj = step(obj) + RHS = zeros(obj.blockSize*obj.N,1); + + for i = 1:obj.blockSize + RHS((1 + (i-1)*obj.N):(i*obj.N)) = obj.f(obj.t + obj.nodes(i)); + end + + RHS = RHS + obj.K*obj.v; + + y = obj.L\RHS(obj.p); + z = obj.U\y; + + w = zeros(size(z)); + w(obj.q) = z; + + obj.v = obj.e_T'*w; + + obj.t = obj.t + obj.k; + obj.n = obj.n + 1; + end + end + + methods(Static) + function N = smallestBlockSize(order,TYPE) + default_arg('TYPE','gauss') + + switch TYPE + case 'gauss' + N = 4; + end + end + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+time/SBPInTimeScaled.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,139 @@ +classdef SBPInTimeScaled < time.Timestepper + % The SBP in time method. + % Implemented for A*v_t = B*v + f(t), v(0) = v0 + % The resulting system of equations is + % M*u_next= K*u_prev_end + f + properties + A,B + f + + k % total time step. + + blockSize % number of points in each block + N % Number of components + + order + nodes + + Mtilde,Ktilde % System matrices + L,U,p,q % LU factorization of M + e_T + + scaling + S, Sinv % Scaling matrices + + % Time state + t + vtilde + n + end + + methods + function obj = SBPInTimeScaled(A, B, f, k, t0, v0, scaling, TYPE, order, blockSize) + default_arg('TYPE','gauss'); + default_arg('f',[]); + + if(strcmp(TYPE,'gauss')) + default_arg('order',4) + default_arg('blockSize',4) + else + default_arg('order', 8); + default_arg('blockSize',time.SBPInTimeImplicitFormulation.smallestBlockSize(order,TYPE)); + end + + obj.A = A; + obj.B = B; + obj.scaling = scaling; + + if ~isempty(f) + obj.f = f; + else + obj.f = @(t)sparse(length(v0),1); + end + + obj.k = k; + obj.blockSize = blockSize; + obj.N = length(v0); + + obj.n = 0; + obj.t = t0; + + %==== Build the time discretization matrix =====% + switch TYPE + case 'equidistant' + ops = sbp.D2Standard(blockSize,{0,obj.k},order); + case 'optimal' + ops = sbp.D1Nonequidistant(blockSize,{0,obj.k},order); + case 'minimal' + ops = sbp.D1Nonequidistant(blockSize,{0,obj.k},order,'minimal'); + case 'gauss' + ops = sbp.D1Gauss(blockSize,{0,obj.k}); + end + + I = speye(size(A)); + I_t = speye(blockSize,blockSize); + + D1 = kron(ops.D1, I); + HI = kron(ops.HI, I); + e_0 = kron(ops.e_l, I); + e_T = kron(ops.e_r, I); + obj.nodes = ops.x; + + % Convert to form M*w = K*v0 + f(t) + tau = kron(I_t, A) * e_0; + M = kron(I_t, A)*D1 + HI*tau*e_0' - kron(I_t, B); + + K = HI*tau; + + obj.S = kron(I_t, spdiag(scaling)); + obj.Sinv = kron(I_t, spdiag(1./scaling)); + + obj.Mtilde = obj.Sinv*M*obj.S; + obj.Ktilde = obj.Sinv*K*spdiag(scaling); + obj.e_T = e_T; + + + % LU factorization + [obj.L,obj.U,obj.p,obj.q] = lu(obj.Mtilde, 'vector'); + + obj.vtilde = (1./obj.scaling).*v0; + end + + function [v,t] = getV(obj) + v = obj.scaling.*obj.vtilde; + t = obj.t; + end + + function obj = step(obj) + forcing = zeros(obj.blockSize*obj.N,1); + + for i = 1:obj.blockSize + forcing((1 + (i-1)*obj.N):(i*obj.N)) = obj.f(obj.t + obj.nodes(i)); + end + + RHS = obj.Sinv*forcing + obj.Ktilde*obj.vtilde; + + y = obj.L\RHS(obj.p); + z = obj.U\y; + + w = zeros(size(z)); + w(obj.q) = z; + + obj.vtilde = obj.e_T'*w; + + obj.t = obj.t + obj.k; + obj.n = obj.n + 1; + end + end + + methods(Static) + function N = smallestBlockSize(order,TYPE) + default_arg('TYPE','gauss') + + switch TYPE + case 'gauss' + N = 4; + end + end + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+time/SBPInTimeSecondOrderFormImplicit.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,86 @@ +classdef SBPInTimeSecondOrderFormImplicit < time.Timestepper + properties + A, B, C, f + AA, BB, ff + + n + t + k + + firstOrderTimeStepper + end + + methods + % Solves A*u_tt + B*u_t + C*u = f(t) + % A, B can either both be constants or both be function handles, + % They can also be omitted by setting them equal to the empty matrix. + function obj = SBPInTimeSecondOrderFormImplicit(A, B, C, f, k, t0, v0, v0t, do_scaling, TYPE, order, blockSize) + default_arg('f', []); + default_arg('TYPE', []); + default_arg('order', []); + default_arg('blockSize',[]); + default_arg('do_scaling', false); + + m = length(v0); + + default_arg('A', speye(m, m)); + default_arg('B', sparse(m, m)); + default_arg('C', sparse(m, m)); + + I = speye(m); + O = sparse(m,m); + + % Rewrite to + % AA*w_t = BB*w + ff(t); + + obj.AA = [ + I, O; + O, A; + ]; + obj.BB = [ + O, I; + -C, -B; + ]; + + if ~isempty(f) + obj.ff = @(t)[ + sparse(m,1); + f(t); + ]; + else + obj.ff = @(t) sparse(2*m,1); + end + + w0 = [v0; v0t]; + + obj.k = k; + obj.t = t0; + obj.n = 0; + + if do_scaling + scaling = [ones(m,1); sqrt(diag(C))]; + obj.firstOrderTimeStepper = time.SBPInTimeScaled(obj.AA, obj.BB, obj.ff, obj.k, obj.t, w0, scaling, TYPE, order, blockSize); + else + obj.firstOrderTimeStepper = time.SBPInTimeImplicitFormulation(obj.AA, obj.BB, obj.ff, obj.k, obj.t, w0, TYPE, order, blockSize); + end + end + + function [v,t] = getV(obj) + w = obj.firstOrderTimeStepper.getV(); + v = w(1:end/2); + t = obj.t; + end + + function [vt,t] = getVt(obj) + w = obj.firstOrderTimeStepper.getV(); + vt = w(end/2+1:end); + t = obj.t; + end + + function obj = step(obj) + obj.firstOrderTimeStepper.step(); + obj.t = obj.firstOrderTimeStepper.t; + obj.n = obj.firstOrderTimeStepper.n; + end + end +end
--- a/+time/Timestepper.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+time/Timestepper.m Tue Sep 11 15:58:35 2018 +0200 @@ -60,6 +60,14 @@ s = util.replace_string(s,''); end + + function [v, t] = stepTo(obj, n, progress_bar) + assertScalar(n); + default_arg('progress_bar',false); + + [v, t] = obj.stepN(n-obj.n, progress_bar); + end + function [v,t] = evolve(obj, tend, progress_bar) default_arg('progress_bar',false) if ~progress_bar
--- a/+util/ReplaceableString.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+util/ReplaceableString.m Tue Sep 11 15:58:35 2018 +0200 @@ -34,10 +34,20 @@ obj.display(); end + function show(obj, varargin) + obj.param = varargin; + obj.display(); + end + + function remove(obj) + obj.update(''); + end + function display(obj) reverseStr = repmat(sprintf('\b'), 1, obj.n); - newStr = padStr(sprintf(obj.fmt, obj.param{:}),obj.n); - fprintf([reverseStr, newStr]); + cleareStr = repmat(sprintf(' '), 1, obj.n); + newStr = sprintf(obj.fmt, obj.param{:}); + fprintf([reverseStr, cleareStr, reverseStr, newStr]); obj.n = length(newStr); end
--- a/+util/calc_borrowing.m Tue Sep 11 13:24:08 2018 +0200 +++ b/+util/calc_borrowing.m Tue Sep 11 15:58:35 2018 +0200 @@ -1,97 +1,241 @@ +function calc_borrowing(m, h) + default_arg('m',100); + default_arg('h',1); -m = 100; -h = 1; + operators = { + { + 'd4_lonely', getM4_lonely, { + {4, 'min_boundary_points'}, + {6, 'min_boundary_points'}, + {6, '2'}, + {6, '3'}, + {8, 'min_boundary_points'}, + {8, 'higher_boundary_order'}, + } + }, { + 'd4_variable', { + {2}, + {4}, + {6}, + } + } + % BORKEN BAD IDEA + } + + + for i = 1:operators + baseName = operators{i}{1}; + postFixes = operators{i}{2}; + for pf = postFixes + [a2, a3] = borrowFromD4(m, h, l{:}); + end + end -%% 4th order non-compatible -[H, HI, D1, D2, D3, D4, e_1, e_m, M, M4,Q, Q3, S2_1, S2_m, S3_1, S3_m, S_1, S_m] = sbp.higher4(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'; + + lonely = { + {4, 'min_boundary_points'}, + {6, 'min_boundary_points'}, + {6, '2'}, + {6, '3'}, + {8, 'min_boundary_points'}, + {8, 'higher_boundary_order'}, + }; -alpha_I = util.matrixborrow(M4, h^-1*S1 ); -alpha_II = util.matrixborrow(M4, h*S2 ); -alpha_III = util.matrixborrow(M4, h^3*S3); -fprintf('4th order non-compatible\n') -fprintf('alpha_I1: %.10f\n',alpha_I) -fprintf('alpha_II: %.10f\n',alpha_II) -fprintf('alpha_III: %.10f\n',alpha_III) -fprintf('\n') - + for i = 1:length(lonely) + l = lonely{i}; + [a2, a3] = d4_lonely(m, h, l{:}); + fprintf('d4_lonely %d %s\n', l{:}) + fprintf('\t alpha_II = %f\n', a2) + fprintf('\t alpha_III = %f\n', a3) + fprintf('\n') + end -%% 6th order non-compatible -[H, HI, D1, D2, D3, D4, e_1, e_m, M, M4,Q, Q3, S2_1, S2_m, S3_1, S3_m, S_1, S_m] = sbp.higher6(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'; + variable = { + {2}, + {4}, + {6}, + }; -alpha_II = util.matrixborrow(M4, h*S2 ); -alpha_III = util.matrixborrow(M4, h^3*S3); -fprintf('6th order non-compatible\n') -fprintf('alpha_II: %.10f\n',alpha_II) -fprintf('alpha_III: %.10f\n',alpha_III) -fprintf('\n') + for i = 1:length(variable) + l = variable{i}; + [a2, a3] = d4_variable(m, h, l{:}); + fprintf('d4_variable %d\n', l{:}) + fprintf('\t alpha_II = %f\n', a2) + fprintf('\t alpha_III = %f\n', a3) + fprintf('\n') + end -%% 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.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'; + %% 4th order non-compatible + [H, HI, D1, D2, D3, D4, e_1, e_m, M, M4,Q, Q3, S2_1, S2_m, S3_1, S3_m, S_1, S_m] = sbp.higher4(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'; -alpha_II = util.matrixborrow(M4, h*S2 ); -alpha_III = util.matrixborrow(M4, h^3*S3); -fprintf('2nd order compatible\n') -fprintf('alpha_II: %.10f\n',alpha_II) -fprintf('alpha_III: %.10f\n',alpha_III) -fprintf('\n') + alpha_I = util.matrixborrow(M4, h^-1*S1 ); + alpha_II = util.matrixborrow(M4, h*S2 ); + alpha_III = util.matrixborrow(M4, h^3*S3); + fprintf('4th order non-compatible\n') + fprintf('alpha_I1: %.10f\n',alpha_I) + fprintf('alpha_II: %.10f\n',alpha_II) + fprintf('alpha_III: %.10f\n',alpha_III) + fprintf('\n') + + + %% 6th order non-compatible + [H, HI, D1, D2, D3, D4, e_1, e_m, M, M4,Q, Q3, S2_1, S2_m, S3_1, S3_m, S_1, S_m] = sbp.higher6(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'; + + alpha_II = util.matrixborrow(M4, h*S2 ); + alpha_III = util.matrixborrow(M4, h^3*S3); + fprintf('6th order non-compatible\n') + fprintf('alpha_II: %.10f\n',alpha_II) + fprintf('alpha_III: %.10f\n',alpha_III) + fprintf('\n') -%% 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.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'; + %% 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.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'; -alpha_II = util.matrixborrow(M4, h*S2 ); -alpha_III = util.matrixborrow(M4, h^3*S3); -fprintf('4th order compatible\n') -fprintf('alpha_II: %.10f\n',alpha_II) -fprintf('alpha_III: %.10f\n',alpha_III) -fprintf('\n') + alpha_II = util.matrixborrow(M4, h*S2 ); + alpha_III = util.matrixborrow(M4, h^3*S3); + fprintf('2nd order compatible\n') + fprintf('alpha_II: %.10f\n',alpha_II) + fprintf('alpha_III: %.10f\n',alpha_III) + fprintf('\n') + + + %% 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.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'; -%% 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.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'; + alpha_II = util.matrixborrow(M4, h*S2 ); + alpha_III = util.matrixborrow(M4, h^3*S3); + fprintf('4th order compatible\n') + fprintf('alpha_II: %.10f\n',alpha_II) + fprintf('alpha_III: %.10f\n',alpha_III) + fprintf('\n') -alpha_II = util.matrixborrow(M4, h*S2 ); -alpha_III = util.matrixborrow(M4, h^3*S3); -fprintf('6th order compatible\n') -fprintf('alpha_II: %.10f\n',alpha_II) -fprintf('alpha_III: %.10f\n',alpha_III) -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.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'; + + alpha_II = util.matrixborrow(M4, h*S2 ); + alpha_III = util.matrixborrow(M4, h^3*S3); + fprintf('6th order compatible\n') + fprintf('alpha_II: %.10f\n',alpha_II) + fprintf('alpha_III: %.10f\n',alpha_III) + fprintf('\n') -% Ordinary + % 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; -for order = [2 4 6 8 10] - op = sbp.Ordinary(m,h, order); + 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 - S_1 = op.boundary.S_1; - S_m = op.boundary.S_m; + + + +end - M = op.norms.M; +function [alpha_II, alpha_III] = d4_lonely(m, h, order, modifier) + default_arg('modifier', []) + func = sprintf('sbp.implementations.d4_lonely_%d', order); + if ~isempty(modifier) + func = sprintf('%s_%s', func, modifier); + end + funcCall = sprintf('%s(%s,%s)', func, toString(m), toString(h)); + [H, HI, D4, e_l, e_r, M4, d2_l, d2_r, d3_l, d3_r, d1_l, d1_r] = eval(funcCall); + + d2d2 = d2_l*d2_l' + d2_r*d2_r'; + alpha_II = util.matrixborrow(M4, h*d2d2); + + d3d3 = d3_l*d3_l' + d3_r*d3_r'; + alpha_III = util.matrixborrow(M4, h^3*d3d3); +end - 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') +function [alpha_II, alpha_III] = d4_variable(m, h, order) + default_arg('modifier', []) + func = sprintf('sbp.implementations.d4_variable_%d', order); + + funcCall = sprintf('%s(%s,%s)', func, toString(m), toString(h)); + [H, HI, D1, D2, D4, e_l, e_r, M4, d2_l, d2_r, d3_l, d3_r, d1_l, d1_r] = eval(funcCall); + + d2d2 = d2_l*d2_l' + d2_r*d2_r'; + alpha_II = util.matrixborrow(M4, h*d2d2); + + d3d3 = d3_l*d3_l' + d3_r*d3_r'; + alpha_III = util.matrixborrow(M4, h^3*d3d3); +end + +function [d2_l, d2_r, d3_l, d3_r, M4] = getM4_lonely(m, h, order, modifier) + fStr = getFunctionCallStr('d4_lonely', {order, modifier}, {m ,h}); + [H, HI, D4, e_l, e_r, M4, d2_l, d2_r, d3_l, d3_r, d1_l, d1_r] = eval(funcCall); end +% Calculates the borrowing constants for a D4 operator. +% getM4 is a function handle on the form +% [d2_l, d2_r, d3_l, d3_r, M4] = getM4(m,h) +function [a2, a3] = borrowFromD4(m, h, getM4) + [d2_l, d2_r, d3_l, d3_r, M4] = getM4(m, h); + + d2d2 = d2_l*d2_l' + d2_r*d2_r'; + a2 = util.matrixborrow(M4, h*d2d2); + + d3d3 = d3_l*d3_l' + d3_r*d3_r'; + a3 = util.matrixborrow(M4, h^3*d3d3); +end + + +function funcCallStr = getFunctionCallStr(baseName, postFix, parameters) + default_arg('postFix', []) + default_arg('parameters', []) + + funcCallStr = sprintf('sbp.implementations.%s', baseName); + + for i = 1:length(postFix) + if ischar(postFix{i}) + funcCallStr = [funcCallStr '_' postFix{i}]; + else + funcCallStr = [funcCallStr '_' toString(postFix{i})]; + end + end + + if isempty(parameters) + return + end + + funcCallStr = [funcCallStr '(' toString(parameters{1})]; + + for i = 2:length(parameters) + funcCallStr = [funcCallStr ', ' toString(parameters{i})]; + end + + funcCallStr = [funcCallStr ')'; +end
--- a/.hgtags Tue Sep 11 13:24:08 2018 +0200 +++ b/.hgtags Tue Sep 11 15:58:35 2018 +0200 @@ -1,1 +1,4 @@ 18c023aaf3f79cbe2b9b1cf547d80babdaa1637d v0.1 +0776fa4754ff0c1918f6e1278c66f48c62d05736 grids0.1 +b723495cdb2f96314d7b3f0aa79723a7dc088c7d v0.2 +08f3ffe63f484d02abce8df4df61e826f568193f elastic1.0
--- a/Color.m Tue Sep 11 13:24:08 2018 +0200 +++ b/Color.m Tue Sep 11 15:58:35 2018 +0200 @@ -10,6 +10,10 @@ black = [0.000 0.000 0.000]; white = [1.000 1.000 1.000]; colors = { Color.blue, Color.red, Color.yellow, Color.green, Color.purple, Color.lightblue, Color.darkred, Color.black, Color.white}; + markers = {'+', 'o', '*', '.', 'x', 'square', 'diamond', 'v', '^', '>', '<', 'pentagram', 'hexagram'}; + lineStyles = {'-', '--', ':', '-.'}; + + solidMarkers = {'o', 'square', 'diamond', 'v', 'pentagram', '^', '>', '<', 'hexagram'}; notabilityYellow = [100.0 99.0 22.0 ]/100; notabilityOrange = [97.0 61.0 15.0 ]/100; @@ -34,13 +38,11 @@ methods(Static) function sample() - markers ={'+', 'o', '*', '.', 'x', 'square', 'diamond', 'v', '^', '>', '<', 'pentagram', 'hexagram'}; % Filled and non-filled markers? - lineStyles = {'-', '--', ':', '-.'}; function showMarkers(x0, y0, lx, ly, color, filled) - n = length(markers); + n = length(Color.markers); s = ceil(sqrt(n)); x = linspace(x0, x0 + lx, s); @@ -50,7 +52,7 @@ for i = 1:n lh = line(X(i),Y(i)); - lh.Marker = markers{i}; + lh.Marker = Color.markers{i}; lh.MarkerSize = 12; lh.Color = color; @@ -79,13 +81,13 @@ end function showLines(y0, ly, A, w) - n = length(lineStyles); + n = length(Color.lineStyles); x = linspace(0,1,100); y = linspace(y0, y0+ ly, n); for i = 1:n lh = line(x, y(i) + A*sin(pi*x*w)); lh.LineWidth = 2; - lh.LineStyle = lineStyles{i}; + lh.LineStyle = Color.lineStyles{i}; end end
--- a/Dictionary.m Tue Sep 11 13:24:08 2018 +0200 +++ b/Dictionary.m Tue Sep 11 15:58:35 2018 +0200 @@ -98,14 +98,11 @@ % Should probably use mat2str with some kind of normalization to make all variables valied fieldname % and make it possible to recover the value function fName = getFieldname(obj, val) - if isnumeric(val) - valStr = num2str(val); - elseif ischar(val) - valStr = val; - else - error('Dont know what to do with val!'); + if ~ischar(val) + val = toString(val); end - fName = sprintf('f%s',valStr); + + fName = matlab.lang.makeValidName(val); end end end \ No newline at end of file
--- a/TextTable.m Tue Sep 11 13:24:08 2018 +0200 +++ b/TextTable.m Tue Sep 11 15:58:35 2018 +0200 @@ -4,28 +4,36 @@ fmtArray vertDiv horzDiv - - nCols - nRows end methods - function obj = TextTable(data, vertDiv, horzDiv); + function obj = TextTable(data, vertDiv, horzDiv) default_arg('vertDiv', []); default_arg('horzDiv', []); - obj.data = data; obj.vertDiv = vertDiv; obj.horzDiv = horzDiv; - [obj.nRows, obj.nCols] = size(data); obj.fmtArray = cell(size(data)); obj.formatAll('%s'); end + function n = nRows(obj) + n = size(obj.data, 1); + end + + function n = nCols(obj) + n = size(obj.data, 2); + end + + function print(obj) + disp(obj.toString()); + end + function formatAll(obj, fmt) + obj.fmtArray = cell(size(obj.data)); obj.fmtArray(:,:) = {fmt}; end @@ -58,28 +66,31 @@ str = ''; + N = size(strArray, 2); + % First horzDiv - if ismember(0, obj.horzDiv) + if isDiv(0, obj.horzDiv, N); str = [str, obj.getHorzDiv(widths)]; end for i = 1:obj.nRows - str = [str, TextTable.rowToString(strArray(i,:), widths, obj.vertDiv, obj.horzDiv)]; + str = [str, TextTable.rowToString(strArray(i,:), widths, obj.vertDiv)]; % Interior horzDiv - if ismember(i, obj.horzDiv) + if isDiv(i, obj.horzDiv, N) str = [str, obj.getHorzDiv(widths)]; end end end function str = getHorzDiv(obj, widths) - str = TextTable.rowToString(cell(1,obj.nCols), widths, obj.vertDiv, obj.horzDiv); + str = TextTable.rowToString(cell(1,obj.nCols), widths, obj.vertDiv); str(find(' ' == str)) = '-'; str(find('|' == str)) = '+'; end function strArray = getStringArray(obj) + assert(all(size(obj.data) == size(obj.fmtArray)), 'Sizes of format matrix and data matrix do not match.') strArray = cell(size(obj.data)); for i = 1:obj.nRows @@ -91,32 +102,42 @@ end methods (Static) - function str = rowToString(strs, widths, vertDiv, horzDiv) + function str = rowToString(strs, widths, vertDiv) + N = length(strs); + % First vertDiv - if ismember(0, vertDiv) - str = '| '; + if isDiv(0, vertDiv, N) + prefix = '| '; else - str = ' '; + prefix = ' '; end - % Interior cols - for j = 1:length(strs) - 1 - str = [str, sprintf('%*s ', widths(j), strs{j})]; + % Pad strings + for i = 1:N + strs{i} = sprintf('%*s', widths(i), strs{i}); + end - % Interior vertDiv - if ismember(j, vertDiv) - str = [str, '| ']; + % Column delimiters + delims = cell(1,N-1); + for i = 1:length(delims) + if isDiv(i, vertDiv, N); + delims{i} = '| '; + else + delims{i} = ' '; end end - % Last col - str = [str, sprintf('%*s ', widths(end), strs{end})]; - - if ismember(length(strs), vertDiv) - str = [str, '|']; + if isDiv(N, vertDiv, N); + suffix = '|'; + else + suffix = ''; end - str = [str, sprintf('\n')]; + str = [prefix, strjoin(strs, delims), suffix, sprintf('\n')]; end end +end + +function b = isDiv(i, div, N) + b = ismember(i, div) || ismember(i, N+div+1); end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/assertIsMember.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,3 @@ +function assertIsMember(v, allowed) + assert(ismember(v, allowed), 'Expected ''%s'' to be in the set %s', inputname(1), toString(allowed)); +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/assertNumberOfArguments.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,5 @@ +function assertNumberOfArguments(fun, N) + if nargin(fun) ~= N + error('sbplib:assertNumberOfArguments:wrongNumberOfArguments', '"%s" must have %d, found %d', inputname(1), N, nargin(fun)); + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/assertScalar.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,5 @@ +function assertScalar(obj) + if ~isscalar(obj) + error('sbplib:assertScalar:notScalar', '"%s" must be scalar, found size "%s"', inputname(1), toString(size(obj))); + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/assertSize.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,16 @@ +% Assert that array A has the size s. +function assertSize(A,varargin) + if length(varargin) == 1 + s = varargin{1}; + errmsg = sprintf('Expected %s to have size %s, got: %s',inputname(1), toString(s), toString(size(A))); + assert(all(size(A) == s), errmsg); + elseif length(varargin) == 2 + dim = varargin{1}; + s = varargin{2}; + + errmsg = sprintf('Expected %s to have size %d along dimension %d, got: %d',inputname(1), s, dim, size(A,dim)); + assert(size(A,dim) == s, errmsg); + else + error('Expected 2 or 3 arguments to assertSize()'); + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/assertStructFields.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,12 @@ +% Assert that the struct s has the all the field names in the cell array fns. +function assertStructFields(s, fns) + assertType(s, 'struct'); + assertType(fns, 'cell'); + + ok = ismember(fns, fieldnames(s)); + if ~all(ok) + str1 = sprintf("'%s' must have the fields %s\n", inputname(1), toString(fns)); + str2 = sprintf("The following fields are missing: %s", toString(fns(~ok))); + error(str1 + str2); + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/assertSymbolic.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,3 @@ +function assertSymbolic(s) + assert(logical(simplify(s))); +end
--- a/assertType.m Tue Sep 11 13:24:08 2018 +0200 +++ b/assertType.m Tue Sep 11 15:58:35 2018 +0200 @@ -1,5 +1,11 @@ function assertType(obj, type) - if ~isa(obj, type) - error('sbplib:assertType:wrongType', '"%s" must have type "%s", found "%s"', inputname(1), type, class(obj)); + if ~iscell(type) + if ~isa(obj, type) + error('sbplib:assertType:wrongType', '"%s" must have type "%s", found "%s"', inputname(1), type, class(obj)); + end + else + if ~isAnyOf(obj, type) + error('sbplib:assertType:wrongType', '"%s" must be one of the types %s, found "%s"', inputname(1), toString(type), class(obj)); + end end end
--- a/assert_size.m Tue Sep 11 13:24:08 2018 +0200 +++ b/assert_size.m Tue Sep 11 15:58:35 2018 +0200 @@ -1,16 +1,5 @@ % Assert that array A has the size s. function assert_size(A,s) - errmsg = sprintf('Expected %s to have size %s, got: %s',inputname(1), format_vector(s), format_vector(size(A))); - assert(all(size(A) == s),errmsg); -end - -function str = format_vector(a) - l = length(a); - str = sprintf('[%d',a(1)); - - for i = 2:l - str = [str sprintf(', %d',a(i))]; - end - - str = [str ']']; + warning('Use assertSize() instead!') + assertSize(A,s); end \ No newline at end of file
--- a/cell2sparse.m Tue Sep 11 13:24:08 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -function A = cell2sparse(C) - - if isempty(C) - A = sparse([]); - return - end - - n = row_height(C); - m = col_width(C); - - N = sum(n); - M = sum(m); - - A = sparse(N,M); - - n_ind = [0 cumsum(n)]; - m_ind = [0 cumsum(m)]; - - for i = 1:size(C,1) - for j = 1:size(C,2) - if ~has_matrix(C{i,j}) - continue - end - A(n_ind(i)+1:n_ind(i+1),m_ind(j)+1:m_ind(j+1)) = C{i,j}; - end - end - -end - -function m = col_width(C) - for j = 1:size(C,2) - for i = 1:size(C,1) - if ~has_matrix(C{i,j}) - continue - end - m(j) = size(C{i,j},2); - end - end -end - -function n = row_height(C) - for i = 1:size(C,1) - for j = 1:size(C,2) - if ~has_matrix(C{i,j}) - continue - end - n(i) = size(C{i,j},1); - end - end -end - -function b = has_matrix(c) - b = ~(isempty(c) || (numel(c)==1 && c == 0)); -end \ No newline at end of file
--- a/cell2vector.m Tue Sep 11 13:24:08 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -% cell2vector accepts a column cell array of column vectors and returns a columnvector -% with the input concatenated. It also returns the number of elements in each vector. -% cv -- column cell array with column vectors -% v -- vector of the concatenated vectors -% n -- number of elements in each vector before concatenation. Can be used with vector2cell(). -function [v, n] = cell2vector(cv) - v = []; - n = zeros(length(cv),1); - - for i = 1:length(cv) - n(i) = length(cv{i}); - v = [v; cv{i}]; - end -end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/centerColorbar.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,6 @@ +function centerColorbar(ah) + old = ah.CLim; + + l = max(abs(old)); + ah.CLim = [-l l]; +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/convergencePlot.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,55 @@ +function hand = convergencePlot(orders, h, e) + N = length(orders); + + fh = figure(); + ah = axes(); + ah.XScale = 'log'; + ah.YScale = 'log'; + hold on + ph = {}; + phc = {}; + legends = {}; + for i = 1:N + ph{i} = loglog(h{i}, e{i}); + phc{i} = plotConvergenceFit(orders{i}, h{i}, e{i}); + + ph{i}.LineStyle = 'none'; + ph{i}.Marker = Color.solidMarkers{i}; + ph{i}.MarkerSize = 12; + ph{i}.Color = Color.colors{i}; + ph{i}.MarkerFaceColor = Color.colors{i}; + + legends{i} = sprintf('$o = %d$', orders{i}); + end + hold off + + lh = legend([ph{:}], legends); + lh.Interpreter = 'latex'; + lh.Location = 'SouthEast'; + + for i = 1:N + uistack(phc{i}, 'bottom'); + end + + xlabel('$h$', 'interpreter', 'latex') + ylabel('Error', 'interpreter', 'latex') + + % xlim([0.7e-2, 1e-1]) + % ylim([3e-5, 4]) + + grid on + + ah = gca(); + ah.TickLabelInterpreter = 'latex'; + setFontSize(fh); + + % if savePngs + % savepng(fh, 'fig/conv/conv',600) + % end + + hand = struct(); + hand.fig = fh; + hand.data = ph; + hand.fits = phc; + hand.legend = lh; +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/copyWithDefault.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,31 @@ +% Copy the struct src to dest with default values from default +% dest = copyWithDefault(src, default) +function dest = copyWithDefault(src, default) + % src does not have a value => use default + if isempty(src) + dest = default; + return + end + + % src has a value and is not a struct => use src + % src has a value and default is not a struct => use src + if ~isstruct(src) || ~isstruct(default) + dest = src; + return + end + + + % src has a value and is a struct => add all default fields + dest = src; + + fn = fieldnames(default); + for i = 1:length(fn) + if isfield(src, fn{i}) + srcField = src.(fn{i}); + else + srcField = []; + end + + dest.(fn{i}) = copyWithDefault(srcField, default.(fn{i})); + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/default_struct.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,10 @@ +function default_struct(s, val) + if evalin('caller',sprintf('~exist(''%s'',''var'')',s)) + given = []; + else + given = evalin('caller', s); + end + + final = copyWithDefault(given, val); + assignin('caller', s, final); +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/findZeros.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,30 @@ +% findZeros looks for solutions to the equation f(x)==0 within +% the limits lim with a granularity of h. +% Returns a sorted list of unique solutions. +function z = findZeros(f, lim, h) + n = ceil((lim(2)-lim(1))/h); + z0 = linspace(lim(1), lim(2), n); + + z = zeros(1,n); + + for i = 1:n + zt(i) = fzero(f, z0(i)); + end + + zt = sort(zt); + + z = []; + for i = 1:n + if zt(i) < lim(1) || zt(i) > lim(2) + continue + end + + if ~isempty(z) && abs(z(end) - zt(i)) < 1e-6 + continue + end + + z = [z zt(i)]; + end + + % z = unique(z); +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/four.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,19 @@ +% four returns the fourier transform u_hat of the function u and the frequencies w +function [w, u_hat] = four(x, u) + u_hat = fft(u); + + N = length(x); + L = x(end) - x(1); + + k = shift_k(0:N-1); + + u_hat = fftshift(u_hat); + + dw = 2*pi/L; + w = dw*k; +end + +function k_shifted = shift_k(k) + N = length(k); + k_shifted = [-floor(N/2):-1, 0, 1:ceil(N/2)-1]; +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fourInv.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,4 @@ +function u = ifour(u_hat) + u_hat = ifftshift(u_hat); + u = ifft(u_hat); +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gaussian.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,3 @@ +function z = gaussian(x,x0,d) + z = exp(-sum((x-x0).^2,2)/d^2); +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/isAnyOf.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,11 @@ +% Returns true of obj is any of he types in the cell array types +% b = isAnyOf(obj, types) +function b = isAnyOf(obj, types) + for i = 1:length(types) + if isa(obj, types{i}); + b = true; + return + end + end + b = false; +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kroneckerDelta.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,6 @@ +function d = kroneckerDelta(i,j) + +d = 0; +if i==j + d = 1; +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/matlabFunctionSizePreserving.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,12 @@ +% Takes a symfun and makes a better anonymous function +function fun = matlabFunctionSizePreserving(f) + mf = matlabFunction(f); + args = argnames(f); + + funStr = func2str(mf); + for i = 1:length(args) + funStr = [funStr sprintf(' + 0*%s', toString(args(i)))]; + end + + fun = str2func(funStr); +end
--- a/minors.m Tue Sep 11 13:24:08 2018 +0200 +++ b/minors.m Tue Sep 11 15:58:35 2018 +0200 @@ -1,4 +1,5 @@ -function [minor, sub] = minors(A) +function [minor, sub] = minors(A, verbose) + default_arg('verbose', true); [n, m] = size(A); if n ~= m @@ -18,8 +19,10 @@ end for i = 1:length(sub) - fprintf('%d:\n', ks{i}); - disp(sub{i}) + if verbose + fprintf('%d:\n', ks{i}); + disp(sub{i}) + end minor(i) = det(sub{i}); end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mononomial.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,17 @@ +% calculate a N-D mononomial with powers k in points x: +% z = x(:,1).^k(1) * x(:,2).^k(2) * ... +function z = mononomial(x, k) + assert(size(x,2) == length(k), 'k must have the same length as the width of x'); + + if any(k < 0) + z = x(:,1)*0; + return + end + + denom = prod(factorial(k)); + + for i = 1:length(k) + x(:,i) = x(:,i).^k(i); + end + z = prod(x,2)/denom; +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nextColor.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,5 @@ +function c = nextColor(ah) + default_arg('ah', gca); + + c = ah.ColorOrder(ah.ColorOrderIndex, :); +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pointIndex.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,4 @@ +% Get the index of the points p within the tall array of points ps +function [I, ok] = pointIndex(p, ps) + [ok, I] = ismember(p, ps, 'rows'); +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/reshapeRowMaj.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,12 @@ +% Reshapes a matrix as if it was stored in row major order. +function B = reshapeRowMaj(A, m) + D = length(m); + + if D == 1 + m = [m 1]; + D = 2; + end + + % Reshape and reverse order of indecies + B = permute(reshape(permute(A, ndims(A):-1:1), rot90(m,2)), D:-1:1); +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/reshapeRowMajTest.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,113 @@ +function tests = reshapeRowMajTest() + tests = functiontests(localfunctions); +end + +function test1D(testCase) + in = { + {5,[1; 2; 3; 4; 5]}, + {5,[1 2 3 4 5]}, + }; + out = { + [1; 2; 3; 4; 5], + [1; 2; 3; 4; 5], + }; + for i = 1:length(in) + testCase.verifyEqual(reshapeRowMaj(in{i}{2}, in{i}{1}),out{i}); + end +end + + +function testIdentity(testCase) + in = { + {[2,2], magic(2)}, + {[3,3], magic(3)}, + {[2,3], [1 2 3; 4 5 6]}, + }; + + for i = 1:length(in) + testCase.verifyEqual(reshapeRowMaj(in{i}{2}, in{i}{1}),in{i}{2}); + end +end + +function test2D(testCase) + in = { + {[2,2],[11; 12; 21; 22]}, + {[3,2],[1 2 3; 4 5 6]}, + {[6 1],[1 2 3; 4 5 6]}, + {[1 6],[1 2 3; 4 5 6]}, + }; + + out{1}(1,1) = 11; + out{1}(1,2) = 12; + out{1}(2,1) = 21; + out{1}(2,2) = 22; + + out{2} = [1 2; 3 4; 5 6]; + out{3} = [1; 2; 3; 4; 5; 6]; + out{4} = [1 2 3 4 5 6]; + + for i = 1:length(in) + testCase.verifyEqual(reshapeRowMaj(in{i}{2}, in{i}{1}),out{i}); + end +end + +function test3D(testCase) + in = { + {[2, 2, 2], [111; 112; 121; 122; 211; 212; 221; 222]}, + {[8 1], cat(3,[1 2; 3 4],[5 6; 7 8])}, + {[1 8], cat(3,[1 2; 3 4],[5 6; 7 8])}, + {[2 4], cat(3,[1 2; 3 4],[5 6; 7 8])}, + {[4 2], cat(3,[1 2; 3 4],[5 6; 7 8])}, + }; + + out{1}(1,1,1) = 111; + out{1}(1,1,2) = 112; + out{1}(1,2,1) = 121; + out{1}(1,2,2) = 122; + out{1}(2,1,1) = 211; + out{1}(2,1,2) = 212; + out{1}(2,2,1) = 221; + out{1}(2,2,2) = 222; + + out{2} = [1; 5; 2; 6; 3; 7; 4; 8]; + out{3} = [1 5 2 6 3 7 4 8]; + out{4} = [1 5 2 6; 3 7 4 8]; + out{5} = [1 5; 2 6; 3 7; 4 8]; + + for i = 1:length(in) + testCase.verifyEqual(reshapeRowMaj(in{i}{2}, in{i}{1}),out{i}); + end +end + +function testNonSquare(testCase) + in = { + {[2, 3, 4],[111; 112; 113; 114; 121; 122; 123; 124; 131; 132; 133; 134; 211; 212; 213; 214; 221; 222; 223; 224; 231; 232; 233; 234]}, + }; + out{1}(1,1,1) = 111; + out{1}(1,1,2) = 112; + out{1}(1,1,3) = 113; + out{1}(1,1,4) = 114; + out{1}(1,2,1) = 121; + out{1}(1,2,2) = 122; + out{1}(1,2,3) = 123; + out{1}(1,2,4) = 124; + out{1}(1,3,1) = 131; + out{1}(1,3,2) = 132; + out{1}(1,3,3) = 133; + out{1}(1,3,4) = 134; + out{1}(2,1,1) = 211; + out{1}(2,1,2) = 212; + out{1}(2,1,3) = 213; + out{1}(2,1,4) = 214; + out{1}(2,2,1) = 221; + out{1}(2,2,2) = 222; + out{1}(2,2,3) = 223; + out{1}(2,2,4) = 224; + out{1}(2,3,1) = 231; + out{1}(2,3,2) = 232; + out{1}(2,3,3) = 233; + out{1}(2,3,4) = 234; + for i = 1:length(in) + testCase.verifyEqual(reshapeRowMaj(in{i}{2}, in{i}{1}),out{i}); + end +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/reshapeToPlotMatrix.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,17 @@ +% Takes a grid function and reshapes it into a matrix of shape m for plotting. +function F = reshapeToPlotMatrix(gf, m) + D = length(m); + + switch D + case 1 + F = gf; + case 2 + F = reshape(gf, rot90(m,2)); + case 3 + % After the reshape the indecies will be M(z,y,x). Plot need them to be M(y,x,z) + p = [2 3 1]; % Permuation + F = permute(reshape(gf,rot90(m,2)), p); + otherwise + error('reshapeToPlotMatrix:NotImplemented','Grid function to matrix is not implemented for dimension = %d', length(m)); + end +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/reshapeToPlotMatrixTest.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,48 @@ +function tests = reshapeToPlotMatrixTest() + tests = functiontests(localfunctions); +end + +function test1D(testCase) + inGf = [1 2 3 4 5]'; + inM = 5; + out = [1 2 3 4 5]'; + testCase.verifyEqual(reshapeToPlotMatrix(inGf, inM),out); +end + +function test2D(testCase) + x = 1:2; + y = 1:3; + + f = @(x,y) x + y*10; + + xx = [1; 1; 1; 2; 2; 2]; + yy = [1; 2; 3; 1; 2; 3]; + inGf = f(xx,yy); + + [X,Y] = meshgrid(x,y); + out = f(X,Y); + + inM = [2, 3]; + + testCase.verifyEqual(reshapeToPlotMatrix(inGf, inM),out); +end + +function test3D(testCase) + x = 1:2; + y = 1:3; + z = 1:4; + + f = @(x,y,z) x + y*10 + z*100; + + xx = [repmat(1, [12, 1]); repmat(2, [12, 1])]; + yy = repmat([1; 1; 1; 1; 2; 2; 2; 2; 3; 3; 3; 3], [2, 1]); + zz = repmat([1; 2; 3; 4], [6, 1]); + inGf = f(xx,yy,zz); + + [X,Y,Z] = meshgrid(x,y,z); + out = f(X,Y,Z); + + inM = [2, 3, 4]; + + testCase.verifyEqual(reshapeToPlotMatrix(inGf, inM),out); +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rickerWavelet.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,3 @@ +function y = rickerWavelet(x, x0, A) + y = (1-2*pi^2*A^2*(x-x0).^2).*exp(-pi^2*A^2*(x-x0).^2); +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/runtestsPackage.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,4 @@ +function res = runtestsPackage(pkgName) + ts = matlab.unittest.TestSuite.fromPackage(pkgName); + res = ts.run(); +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/saveFigureSize.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,6 @@ +function saveFigurePosition() + defaultPosition = get(0,'defaultfigureposition'); + f = gcf; + defaultPosition(3:4) = f.Position(3:4); + set(0,'defaultfigureposition',defaultPosition); +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sbplibLocation.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,4 @@ +function location = sbplibLocation() + scriptname = mfilename('fullpath'); + [location, ~, ~] = fileparts(scriptname); +end
--- a/sbplibVersion.m Tue Sep 11 13:24:08 2018 +0200 +++ b/sbplibVersion.m Tue Sep 11 15:58:35 2018 +0200 @@ -1,11 +1,10 @@ % Prints the version and location of the sbplib currently in use. function sbplibVersion() - scriptname = mfilename('fullpath'); - [folder,~,~] = fileparts(scriptname); + location = sbplibLocation(); - name = 'sbplib'; + name = 'sbplib (feature/grids)'; ver = '0.0.x'; fprintf('%s %s\n', name, ver); - fprintf('Running in:\n%s\n',folder); + fprintf('Running in:\n%s\n', location); end \ No newline at end of file
--- a/semiDefIneq.m Tue Sep 11 13:24:08 2018 +0200 +++ b/semiDefIneq.m Tue Sep 11 15:58:35 2018 +0200 @@ -1,5 +1,6 @@ -function ineq = semiDefIneq(A) - [m, sub] = minors(A); +function ineq = semiDefIneq(A, verbose) + default_arg('verbose', true); + [m, sub] = minors(A, verbose); ineqsys = true; for i = 1:length(m)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/skewPart.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,4 @@ +% Returns the skew of A +function S = skewPart(A, tol) + S = 1/2*(A - A'); +end
--- a/spdiag.m Tue Sep 11 13:24:08 2018 +0200 +++ b/spdiag.m Tue Sep 11 15:58:35 2018 +0200 @@ -5,6 +5,6 @@ a = a'; end - n = length(a)-abs(i); + n = length(a)+abs(i); A = spdiags(a,i,n,n); end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/spdiagsPeriodic.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,60 @@ +function A = spdiagsPeriodic(vals,diags) + % Creates an m x m periodic discretization matrix. + % vals - m x ndiags matrix of values + % diags - 1 x ndiags vector of the 'center diagonals' that vals end up on + % vals that are not on main diagonal are going to spill over to + % off-diagonal corners. + + default_arg('diags',0); + + [m, ~] = size(vals); + + A = sparse(m,m); + + for i = 1:length(diags) + + d = diags(i); + a = vals(:,i); + + % Sub-diagonals + if d < 0 + a_bulk = a(1+abs(d):end); + a_corner = a(1:1+abs(d)-1); + corner_diag = m-abs(d); + A = A + spdiagVariable(a_bulk, d); + A = A + spdiagVariable(a_corner, corner_diag); + + % Super-diagonals + elseif d > 0 + a_bulk = a(1:end-d); + a_corner = a(end-d+1:end); + corner_diag = -m + d; + A = A + spdiagVariable(a_bulk, d); + A = A + spdiagVariable(a_corner, corner_diag); + + % Main diagonal + else + A = A + spdiagVariable(a, 0); + end + + end + +end + +function A = spdiagVariable(a,i) + default_arg('i',0); + + if isrow(a) + a = a'; + end + + n = length(a)+abs(i); + + if i > 0 + a = [sparse(i,1); a]; + elseif i < 0 + a = [a; sparse(abs(i),1)]; + end + + A = spdiags(a,i,n,n); +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stencilEquation.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,13 @@ +% Find the equation for the stencil for d^k/dx^k +function [A,b] = stencilEquation(k, offsets, order) + q = sym('q', [1, length(offsets)]); + + p = 0:(order-1+k); + + v = vandermonde(offsets, p); + vdiff = vandermonde( 0, p-k); + + eq = q*v == vdiff; + + [A,b] = equationsToMatrix(eq, q); +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stripeMatrixPeriodic.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,8 @@ +% Creates a periodic discretization matrix of size n x n +% with the values of val on the diagonals diag. +% A = stripeMatrix(val,diags,n) +function A = stripeMatrixPeriodic(val,diags,n) + + D = ones(n,1)*val; + A = spdiagsPeriodic(D,diags); +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/structArray.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,16 @@ +% % Usage example: +% c = structArray({'a','b'}, { +% 1, 2; +% 3, 4; +% }); + +function c = structArray(fields, values) + assert(length(fields) == size(values, 2), 'Number of fields and number of colums of ''values'' must be equal'); + c = struct(); + + for i = 1:size(values, 1) + for j = 1:length(fields) + c(i).(fields{j}) = values{i,j}; + end + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/structCellArray.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,16 @@ +% % Usage example: +% c = structCellArray({'a','b'}, { +% 1, 2; +% 3, 4; +% }); + +function c = structCellArray(fields, values) + assert(length(fields) == size(values, 2), 'Number of fields and number of colums of ''values'' must be equal'); + c = cell(1, size(values, 1)); + + for i = 1:size(values, 1) + for j = 1:length(fields) + c{i}.(fields{j}) = values{i,j}; + end + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/subsSymfun.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,14 @@ +% Subs for a symfun +% f remains a symbolic function. If any of it's arguments is eliminated +% it is removed from the argument list while preserving the order of the +% other arguments +function f = subsSymfun(f, old, new) + args = argnames(f); + + newExpr = subs(f, old, new); + vars = symvar(subs(args, old, new)); + + newArgs = args(ismember(args,vars)); + + f = symfun(newExpr, newArgs); +end \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/symmetricPart.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,4 @@ +% Returns the symmetric of A +function S = symmetricPart(A, tol) + S = 1/2*(A + A'); +end
--- a/timeTask.m Tue Sep 11 13:24:08 2018 +0200 +++ b/timeTask.m Tue Sep 11 15:58:35 2018 +0200 @@ -1,5 +1,5 @@ -function done = timeTask(taskName) - fprintf('%s', taskName); +function done = timeTask(fmt, varargin) + fprintf(fmt, varargin{:}); tStart = tic; function done_fun()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vandermonde.m Tue Sep 11 15:58:35 2018 +0200 @@ -0,0 +1,15 @@ +% Create vandermonde matrix for points x and polynomials of order p +% x is a list of N points of size [N,dim], +% p is a list of polynomial orders of size [M, dim]. +% the given mononomials are evaluated and the NxM matrix V is returned. +function V = vandermonde(x, p) + assert(size(x,2) == size(p,2), 'x and p must have the same number of columns') + n = size(x,1); + m = size(p,1); + + for i = 1:m + V(:,i) = mononomial(x, p(i,:)); + end + + assertSize(V,[n,m]); +end
--- a/vector2cell.m Tue Sep 11 13:24:08 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -% Splits column vector v into segments of length n and returns the result as a column cell array. -% v -- column vector to be split -% n -- number of elements in each part -% -% cv -- cell array of vectors with lenght n(i) -function cv = vector2cell(v,n) - cv = cell(length(n),1); - - ind = [0; cumsum(n)]; - for i = 1:length(n) - ind_i = (ind(i)+1):ind(i+1); - cv{i} = v(ind_i); - end -end \ No newline at end of file