Mercurial > repos > public > sbplib
changeset 170:62b5f3c34bcb feature/grids
Implemented Curvilinear and equdistantCurvilinear.
author | Jonatan Werpers <jonatan@werpers.com> |
---|---|
date | Thu, 25 Feb 2016 11:10:25 +0100 |
parents | ba8adcaf4681 |
children | 0e56192f6459 |
files | +grid/Curvilinear.m +grid/CurvilinearTest.m +grid/Mapped.m +grid/equidistantCurvilinear.m +grid/equidistantCurvilinearTest.m |
diffstat | 5 files changed, 213 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
diff -r ba8adcaf4681 -r 62b5f3c34bcb +grid/Curvilinear.m --- a/+grid/Curvilinear.m Wed Feb 24 15:04:22 2016 +0100 +++ b/+grid/Curvilinear.m Thu Feb 25 11:10:25 2016 +0100 @@ -1,10 +1,96 @@ -classdef Curvilinear < grid.Structured - % General grid mapping - methods (Abstract) - % baseGrid returns the domain grid of the mapping. - g = baseGrid(obj); +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 matrix or a cell array with physical coordinates. + % 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') + mapping = grid.evalOn(obj.logic, mapping); + end + + D = obj.logic.D(); + N = obj.logic.N(); + + obj.coords = zeros(N,D); + + if iscell(mapping) + if ~isequal(size(mapping),[1 D]) + error('grid:Curvilinear:Curvilinear','The cell array must be a row array.'); + end + + if isequal(size(mapping{1}),[N 1]) + obj.coords = cell2mat(mapping); + elseif isequal(size(mapping{1}), obj.logic.m) + for i = 1:length(mapping) + obj.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(obj.logic.m)); + end + + elseif isnumeric(mapping) + if isequal(size(mapping), [N, D]) + obj.coords = mapping; + elseif isequal(size(mapping), [N*D, 1]) + obj.coords = reshapeRowMaj(mapping,[N D]); + else + error('grid:Curvilinear:Curvilinear','A matrix mapping must be of size [N D] or [N*D 1].'); + end + else + error('grid:Curvilinear:Curvilinear','mapping must be 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 - m = mapping(obj); + 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.baseGrid()); + end + + % Projects the grid function gf on obj to the grid g. + function gf = projectFunc(obj, gf, g) + gf = obj.logic.projectFunc(gf,g.baseGrid()); + end end end \ No newline at end of file
diff -r ba8adcaf4681 -r 62b5f3c34bcb +grid/CurvilinearTest.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/CurvilinearTest.m Thu Feb 25 11:10:25 2016 +0100 @@ -0,0 +1,71 @@ +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.assumeFail(); +end
diff -r ba8adcaf4681 -r 62b5f3c34bcb +grid/Mapped.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/Mapped.m Thu Feb 25 11:10:25 2016 +0100 @@ -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
diff -r ba8adcaf4681 -r 62b5f3c34bcb +grid/equidistantCurvilinear.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/equidistantCurvilinear.m Thu Feb 25 11:10:25 2016 +0100 @@ -0,0 +1,33 @@ +% 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 = {}; + for i = 1:length(m) + X{i} = util.get_grid(varargin{i}{:},m(i)); + end + + g = grid.Curvilinear(mapping, X{:}); +end \ No newline at end of file
diff -r ba8adcaf4681 -r 62b5f3c34bcb +grid/equidistantCurvilinearTest.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/equidistantCurvilinearTest.m Thu Feb 25 11:10:25 2016 +0100 @@ -0,0 +1,7 @@ +function tests = equdistantCurvilinearTest() + tests = functiontests(localfunctions); +end + +function testNoTests(testCase) + testCase.assumeFail(); +end \ No newline at end of file