Mercurial > repos > public > sbplib
diff +grid/Cartesian.m @ 886:8894e9c49e40 feature/timesteppers
Merge with default for latest changes
author | Vidar Stiernström <vidar.stiernstrom@it.uu.se> |
---|---|
date | Thu, 15 Nov 2018 16:36:21 -0800 |
parents | 031d6db97270 |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+grid/Cartesian.m Thu Nov 15 16:36:21 2018 -0800 @@ -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