Mercurial > repos > public > sbplib
changeset 971:e54c2f54dbfe feature/getBoundaryOperator
Merge with feature/poroelastic. Use only the changes made to multiblock.DiffOp and scheme.Elastic2dVariable. DiffOp.getBoundaryOperator/Quadrature now use scheme methods instead of propeties.
author | Martin Almquist <malmquist@stanford.edu> |
---|---|
date | Tue, 25 Dec 2018 07:50:07 +0100 |
parents | 2412f407749a (diff) 23d9ca6755be (current diff) |
children | 47b48a97c675 |
files | +multiblock/DiffOp.m +multiblock/Grid.m +sbp/+implementations/d2_variable_2.m +sbp/+implementations/d2_variable_4.m +sbp/+implementations/d4_variable_6.m +time/+rkparameters/rk4.m +time/ExplicitRungeKuttaDiscreteData.m +time/ExplicitRungeKuttaSecondOrderDiscreteData.m .hgtags diracDiscr.m diracDiscrTest.m |
diffstat | 11 files changed, 5 insertions(+), 1018 deletions(-) [+] |
line wrap: on
line diff
--- a/+multiblock/DiffOp.m Tue Dec 25 07:23:38 2018 +0100 +++ b/+multiblock/DiffOp.m Tue Dec 25 07:50:07 2018 +0100 @@ -151,6 +151,7 @@ end end + % Get square matrix that integrates the solution restricted to a boundary function op = getBoundaryQuadrature(obj, boundary) switch class(boundary) case 'cell'
--- a/+multiblock/Grid.m Tue Dec 25 07:23:38 2018 +0100 +++ b/+multiblock/Grid.m Tue Dec 25 07:50:07 2018 +0100 @@ -132,27 +132,6 @@ end - % Pads a grid function that lives on a subgrid with - % zeros and gives it the size that mathces obj. - function gf = expandFunc(obj, gfSub, subGridId) - nComponents = length(gfSub)/obj.grids{subGridId}.N(); - nBlocks = numel(obj.grids); - - % Create sparse block matrix - gfs = cell(nBlocks,1); - for i = 1:nBlocks - N = obj.grids{i}.N()*nComponents; - gfs{i} = sparse(N, 1); - end - - % Insert local gf - gfs{subGridId} = gfSub; - - % Convert cell to vector - gf = blockmatrix.toMatrix(gfs); - - end - % Find all non interface boundaries of all blocks. % Return their grid.boundaryIdentifiers in a cell array. function bs = getBoundaryNames(obj)
--- a/+sbp/+implementations/d2_variable_2.m Tue Dec 25 07:23:38 2018 +0100 +++ b/+sbp/+implementations/d2_variable_2.m Tue Dec 25 07:50:07 2018 +0100 @@ -27,7 +27,7 @@ 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; @@ -40,7 +40,7 @@ scheme_radius = (scheme_width-1)/2; r = (1+scheme_radius):(m-scheme_radius); - function [D2, B] = D2_fun(c) + function D2 = D2_fun(c) Mm1 = -c(r-1)/2 - c(r)/2; M0 = c(r-1)/2 + c(r) + c(r+1)/2; @@ -54,8 +54,6 @@ M=M/h; D2=HI*(-M-c(1)*e_l*d1_l'+c(m)*e_r*d1_r'); - B = HI*M; end D2 = @D2_fun; - end \ No newline at end of file
--- a/+sbp/+implementations/d2_variable_4.m Tue Dec 25 07:23:38 2018 +0100 +++ b/+sbp/+implementations/d2_variable_4.m Tue Dec 25 07:50:07 2018 +0100 @@ -49,7 +49,7 @@ N = m; - function [D2, B] = D2_fun(c) + function D2 = D2_fun(c) M = 78+(N-12)*5; %h = 1/(N-1); @@ -131,8 +131,6 @@ cols(40+(i-7)*5:44+(i-7)*5) = [i-2;i-1;i;i+1;i+2]; end D2 = sparse(rows,cols,D2); - - B = HI*( c(end)*e_r*d1_r' - c(1)*e_l*d1_l') - D2; end D2 = @D2_fun; end \ No newline at end of file
--- a/+sbp/+implementations/d4_variable_6.m Tue Dec 25 07:23:38 2018 +0100 +++ b/+sbp/+implementations/d4_variable_6.m Tue Dec 25 07:50:07 2018 +0100 @@ -85,7 +85,7 @@ scheme_radius = (scheme_width-1)/2; r = (1+scheme_radius):(m-scheme_radius); - function [D2, B] = D2_fun(c) + 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); @@ -128,7 +128,6 @@ M=M/h; D2 = HI*(-M - c(1)*e_l*d1_l' + c(m)*e_r*d1_r'); - B = HI*M; end D2 = @D2_fun;
--- a/+time/+rkparameters/rk4.m Tue Dec 25 07:23:38 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,12 +0,0 @@ -function [a,b,c,s] = rk4() - -% Butcher tableau for classical RK$ -s = 4; -a = sparse(s,s); -a(2,1) = 1/2; -a(3,2) = 1/2; -a(4,3) = 1; -b = 1/6*[1; 2; 2; 1]; -c = [0; 1/2; 1/2; 1]; - -end \ No newline at end of file
--- a/+time/ExplicitRungeKuttaDiscreteData.m Tue Dec 25 07:23:38 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,121 +0,0 @@ -classdef ExplicitRungeKuttaDiscreteData < time.Timestepper - properties - D - S % Function handle for time-dependent data - data % Matrix of data vectors, one column per stage - k - t - v - m - n - order - a, b, c, s % Butcher tableau - K % Stage rates - U % Stage approximations - T % Stage times - end - - - methods - function obj = ExplicitRungeKuttaDiscreteData(D, S, data, k, t0, v0, order) - default_arg('order', 4); - default_arg('S', []); - default_arg('data', []); - - obj.D = D; - obj.S = S; - obj.k = k; - obj.t = t0; - obj.v = v0; - obj.m = length(v0); - obj.n = 0; - obj.order = order; - obj.data = data; - - switch order - case 4 - [obj.a, obj.b, obj.c, obj.s] = time.rkparameters.rk4(); - otherwise - error('That RK method is not available'); - end - - obj.K = sparse(obj.m, obj.s); - obj.U = sparse(obj.m, obj.s); - - end - - function [v,t,U,T,K] = getV(obj) - v = obj.v; - t = obj.t; - U = obj.U; % Stage approximations in previous time step. - T = obj.T; % Stage times in previous time step. - K = obj.K; % Stage rates in previous time step. - end - - function [a,b,c,s] = getTableau(obj) - a = obj.a; - b = obj.b; - c = obj.c; - s = obj.s; - end - - % Returns quadrature weights for stages in one time step - function quadWeights = getTimeStepQuadrature(obj) - [~, b] = obj.getTableau(); - quadWeights = obj.k*b; - end - - function obj = step(obj) - v = obj.v; - a = obj.a; - b = obj.b; - c = obj.c; - s = obj.s; - S = obj.S; - dt = obj.k; - K = obj.K; - U = obj.U; - D = obj.D; - data = obj.data; - - for i = 1:s - U(:,i) = v; - for j = 1:i-1 - U(:,i) = U(:,i) + dt*a(i,j)*K(:,j); - end - - K(:,i) = D*U(:,i); - obj.T(i) = obj.t + c(i)*dt; - - % Data from continuous function and discrete time-points. - if ~isempty(S) - K(:,i) = K(:,i) + S(obj.T(i)); - end - if ~isempty(data) - K(:,i) = K(:,i) + data(:,obj.n*s + i); - end - - end - - obj.v = v + dt*K*b; - obj.t = obj.t + dt; - obj.n = obj.n + 1; - obj.U = U; - obj.K = K; - end - end - - - methods (Static) - function k = getTimeStep(lambda, order) - default_arg('order', 4); - switch order - case 4 - k = time.rk4.get_rk4_time_step(lambda); - otherwise - error('Time-step function not available for this order'); - end - end - end - -end \ No newline at end of file
--- a/+time/ExplicitRungeKuttaSecondOrderDiscreteData.m Tue Dec 25 07:23:38 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,129 +0,0 @@ -classdef ExplicitRungeKuttaSecondOrderDiscreteData < time.Timestepper - properties - k - t - w - m - D - E - M - C_cont % Continuous part (function handle) of forcing on first order form. - C_discr% Discrete part (matrix) of forcing on first order form. - n - order - tsImplementation % Time stepper object, RK first order form, - % which this wraps around. - end - - - 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, should be matrices (or empty for zero) - % They can also be omitted by setting them equal to the empty matrix. - % S = S_cont + S_discr, where S_cont is a function handle - % S_discr a matrix of data vectors, one column per stage. - function obj = ExplicitRungeKuttaSecondOrderDiscreteData(D, E, S_cont, S_discr, k, t0, v0, v0t, order) - default_arg('order', 4); - default_arg('S_cont', []); - default_arg('S_discr', []); - obj.D = D; - obj.E = E; - obj.m = length(v0); - obj.n = 0; - - default_arg('D', sparse(obj.m, obj.m) ); - default_arg('E', sparse(obj.m, obj.m) ); - - obj.k = k; - obj.t = t0; - obj.w = [v0; v0t]; - - I = speye(obj.m); - O = sparse(obj.m,obj.m); - - obj.M = [ - O, I; - D, E; - ]; - - % Build C_cont - if ~isempty(S_cont) - obj.C_cont = @(t)[ - sparse(obj.m,1); - S_cont(t) - ]; - else - obj.C_cont = []; - end - - % Build C_discr - if ~isempty(S_discr) - [~, nt] = size(S_discr); - obj.C_discr = [sparse(obj.m, nt); - S_discr - ]; - else - obj.C_discr = []; - end - obj.tsImplementation = time.ExplicitRungeKuttaDiscreteData(obj.M, obj.C_cont, obj.C_discr,... - k, obj.t, obj.w, order); - end - - function [v,t,U,T,K] = getV(obj) - [w,t,U,T,K] = obj.tsImplementation.getV(); - - v = w(1:end/2); - U = U(1:end/2, :); % Stage approximations in previous time step. - K = K(1:end/2, :); % Stage rates in previous time step. - % T: Stage times in previous time step. - end - - function [vt,t,U,T,K] = getVt(obj) - [w,t,U,T,K] = obj.tsImplementation.getV(); - - vt = w(end/2+1:end); - U = U(end/2+1:end, :); % Stage approximations in previous time step. - K = K(end/2+1:end, :); % Stage rates in previous time step. - % T: Stage times in previous time step. - end - - function [a,b,c,s] = getTableau(obj) - [a,b,c,s] = obj.tsImplementation.getTableau(); - end - - % Returns quadrature weights for stages in one time step - function quadWeights = getTimeStepQuadrature(obj) - [~, b] = obj.getTableau(); - quadWeights = obj.k*b; - end - - % Use RK for first order form to step - function obj = step(obj) - obj.tsImplementation.step(); - [v, t] = obj.tsImplementation.getV(); - obj.w = v; - obj.t = t; - obj.n = obj.n + 1; - end - end - - methods (Static) - function k = getTimeStep(lambda, order) - default_arg('order', 4); - k = obj.tsImplementation.getTimeStep(lambda, order); - end - end - -end \ No newline at end of file
--- a/.hgtags Tue Dec 25 07:23:38 2018 +0100 +++ b/.hgtags Tue Dec 25 07:50:07 2018 +0100 @@ -2,4 +2,3 @@ 0776fa4754ff0c1918f6e1278c66f48c62d05736 grids0.1 b723495cdb2f96314d7b3f0aa79723a7dc088c7d v0.2 08f3ffe63f484d02abce8df4df61e826f568193f elastic1.0 -08f3ffe63f484d02abce8df4df61e826f568193f Heimisson2018
--- a/diracDiscr.m Tue Dec 25 07:23:38 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,130 +0,0 @@ - -function d = diracDiscr(x_s, x, m_order, s_order, H) - % n-dimensional delta function - % x_s: source point coordinate vector, e.g. [x, y] or [x, y, z]. - % x: cell array of grid point column vectors for each dimension. - % m_order: Number of moment conditions - % s_order: Number of smoothness conditions - % H: cell array of 1D norm matrices - - dim = length(x_s); - d_1D = cell(dim,1); - - % If 1D, non-cell input is accepted - if dim == 1 && ~iscell(x) - d = diracDiscr1D(x_s, x, m_order, s_order, H); - - else - for i = 1:dim - d_1D{i} = diracDiscr1D(x_s(i), x{i}, m_order, s_order, H{i}); - end - - d = d_1D{dim}; - for i = dim-1: -1: 1 - % Perform outer product, transpose, and then turn into column vector - d = (d_1D{i}*d')'; - d = d(:); - end - end - -end - - -% Helper function for 1D delta functions -function ret = diracDiscr1D(x_0in , x , m_order, s_order, H) - -m = length(x); - -% Return zeros if x0 is outside grid -if(x_0in < x(1) || x_0in > x(end) ) - - ret = zeros(size(x)); - -else - - fnorm = diag(H); - eta = abs(x-x_0in); - tot = m_order+s_order; - S = []; - M = []; - - % Get interior grid spacing - middle = floor(m/2); - h = x(middle+1) - x(middle); - - poss = find(tot*h/2 >= eta); - - % Ensure that poss is not too long - if length(poss) == (tot + 2) - poss = poss(2:end-1); - elseif length(poss) == (tot + 1) - poss = poss(1:end-1); - end - - % Use first tot grid points - if length(poss)<tot && x_0in < x(1) + ceil(tot/2)*h; - index=1:tot; - pol=(x(1:tot)-x(1))/(x(tot)-x(1)); - x_0=(x_0in-x(1))/(x(tot)-x(1)); - norm=fnorm(1:tot)/h; - - % Use last tot grid points - elseif length(poss)<tot && x_0in > x(end) - ceil(tot/2)*h; - index = length(x)-tot+1:length(x); - pol = (x(end-tot+1:end)-x(end-tot+1))/(x(end)-x(end-tot+1)); - norm = fnorm(end-tot+1:end)/h; - x_0 = (x_0in-x(end-tot+1))/(x(end)-x(end-tot+1)); - - % Interior, compensate for round-off errors. - elseif length(poss) < tot - if poss(end)<m - poss = [poss; poss(end)+1]; - else - poss = [poss(1)-1; poss]; - end - pol = (x(poss)-x(poss(1)))/(x(poss(end))-x(poss(1))); - x_0 = (x_0in-x(poss(1)))/(x(poss(end))-x(poss(1))); - norm = fnorm(poss)/h; - index = poss; - - % Interior - else - pol = (x(poss)-x(poss(1)))/(x(poss(end))-x(poss(1))); - x_0 = (x_0in-x(poss(1)))/(x(poss(end))-x(poss(1))); - norm = fnorm(poss)/h; - index = poss; - end - - h_pol = pol(2)-pol(1); - b = zeros(m_order+s_order,1); - - for i = 1:m_order - b(i,1) = x_0^(i-1); - end - - for i = 1:(m_order+s_order) - for j = 1:m_order - M(j,i) = pol(i)^(j-1)*h_pol*norm(i); - end - end - - for i = 1:(m_order+s_order) - for j = 1:s_order - S(j,i) = (-1)^(i-1)*pol(i)^(j-1); - end - end - - A = [M;S]; - - d = A\b; - ret = x*0; - ret(index) = d/h*h_pol; -end - -end - - - - - -
--- a/diracDiscrTest.m Tue Dec 25 07:23:38 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,595 +0,0 @@ -function tests = diracDiscrTest() - tests = functiontests(localfunctions); -end - -function testLeftGP(testCase) - - orders = [2, 4, 6]; - mom_conds = orders; - - for o = 1:length(orders) - order = orders(o); - mom_cond = mom_conds(o); - [xl, xr, m, h, x, H, fs] = setup1D(order, mom_cond); - - % Test left boundary grid points - x0s = xl + [0, h, 2*h]; - - for j = 1:length(fs) - f = fs{j}; - fx = f(x); - for i = 1:length(x0s) - x0 = x0s(i); - delta = diracDiscr(x0, x, mom_cond, 0, H); - integral = delta'*H*fx; - err = abs(integral - f(x0)); - testCase.verifyLessThan(err, 1e-12); - end - end - end -end - -function testLeftRandom(testCase) - - orders = [2, 4, 6]; - mom_conds = orders; - - for o = 1:length(orders) - order = orders(o); - mom_cond = mom_conds(o); - [xl, xr, m, h, x, H, fs] = setup1D(order, mom_cond); - - % Test random points near left boundary - x0s = xl + 2*h*rand(1,10); - - for j = 1:length(fs) - f = fs{j}; - fx = f(x); - for i = 1:length(x0s) - x0 = x0s(i); - delta = diracDiscr(x0, x, mom_cond, 0, H); - integral = delta'*H*fx; - err = abs(integral - f(x0)); - testCase.verifyLessThan(err, 1e-12); - end - end - end -end - -function testRightGP(testCase) - - orders = [2, 4, 6]; - mom_conds = orders; - - for o = 1:length(orders) - order = orders(o); - mom_cond = mom_conds(o); - [xl, xr, m, h, x, H, fs] = setup1D(order, mom_cond); - - % Test right boundary grid points - x0s = xr-[0, h, 2*h]; - - for j = 1:length(fs) - f = fs{j}; - fx = f(x); - for i = 1:length(x0s) - x0 = x0s(i); - delta = diracDiscr(x0, x, mom_cond, 0, H); - integral = delta'*H*fx; - err = abs(integral - f(x0)); - testCase.verifyLessThan(err, 1e-12); - end - end - end -end - -function testRightRandom(testCase) - - orders = [2, 4, 6]; - mom_conds = orders; - - for o = 1:length(orders) - order = orders(o); - mom_cond = mom_conds(o); - [xl, xr, m, h, x, H, fs] = setup1D(order, mom_cond); - - % Test random points near right boundary - x0s = xr - 2*h*rand(1,10); - - for j = 1:length(fs) - f = fs{j}; - fx = f(x); - for i = 1:length(x0s) - x0 = x0s(i); - delta = diracDiscr(x0, x, mom_cond, 0, H); - integral = delta'*H*fx; - err = abs(integral - f(x0)); - testCase.verifyLessThan(err, 1e-12); - end - end - end -end - -function testInteriorGP(testCase) - - orders = [2, 4, 6]; - mom_conds = orders; - - for o = 1:length(orders) - order = orders(o); - mom_cond = mom_conds(o); - [xl, xr, m, h, x, H, fs] = setup1D(order, mom_cond); - - % Test interior grid points - m_half = round(m/2); - x0s = xl + (m_half-1:m_half+1)*h; - - for j = 1:length(fs) - f = fs{j}; - fx = f(x); - for i = 1:length(x0s) - x0 = x0s(i); - delta = diracDiscr(x0, x, mom_cond, 0, H); - integral = delta'*H*fx; - err = abs(integral - f(x0)); - testCase.verifyLessThan(err, 1e-12); - end - end - end -end - -function testInteriorRandom(testCase) - - orders = [2, 4, 6]; - mom_conds = orders; - - for o = 1:length(orders) - order = orders(o); - mom_cond = mom_conds(o); - [xl, xr, m, h, x, H, fs] = setup1D(order, mom_cond); - - % Test random points in interior - x0s = (xl+2*h) + (xr-xl-4*h)*rand(1,20); - - for j = 1:length(fs) - f = fs{j}; - fx = f(x); - for i = 1:length(x0s) - x0 = x0s(i); - delta = diracDiscr(x0, x, mom_cond, 0, H); - integral = delta'*H*fx; - err = abs(integral - f(x0)); - testCase.verifyLessThan(err, 1e-12); - end - end - end -end - -% x0 outside grid should yield 0 integral! -function testX0OutsideGrid(testCase) - - orders = [2, 4, 6]; - mom_conds = orders; - - for o = 1:length(orders) - order = orders(o); - mom_cond = mom_conds(o); - [xl, xr, m, h, x, H, fs] = setup1D(order, mom_cond); - - % Test points outisde grid - x0s = [xl-1.1*h, xr+1.1*h]; - - for j = 1:length(fs) - f = fs{j}; - fx = f(x); - for i = 1:length(x0s) - x0 = x0s(i); - delta = diracDiscr(x0, x, mom_cond, 0, H); - integral = delta'*H*fx; - err = abs(integral - 0); - testCase.verifyLessThan(err, 1e-12); - end - end - end -end - -function testAllGP(testCase) - - orders = [2, 4, 6]; - mom_conds = orders; - - for o = 1:length(orders) - order = orders(o); - mom_cond = mom_conds(o); - [xl, xr, m, h, x, H, fs] = setup1D(order, mom_cond); - - % Test all grid points - x0s = x; - - for j = 1:length(fs) - f = fs{j}; - fx = f(x); - for i = 1:length(x0s) - x0 = x0s(i); - delta = diracDiscr(x0, x, mom_cond, 0, H); - integral = delta'*H*fx; - err = abs(integral - f(x0)); - testCase.verifyLessThan(err, 1e-12); - end - end - end -end - -function testHalfGP(testCase) - - orders = [2, 4, 6]; - mom_conds = orders; - - for o = 1:length(orders) - order = orders(o); - mom_cond = mom_conds(o); - [xl, xr, m, h, x, H, fs] = setup1D(order, mom_cond); - - % Test halfway between all grid points - x0s = 1/2*( x(2:end)+x(1:end-1) ); - - for j = 1:length(fs) - f = fs{j}; - fx = f(x); - for i = 1:length(x0s) - x0 = x0s(i); - delta = diracDiscr(x0, x, mom_cond, 0, H); - integral = delta'*H*fx; - err = abs(integral - f(x0)); - testCase.verifyLessThan(err, 1e-12); - end - end - end -end - -% function testAllGPStaggered(testCase) - -% orders = [2, 4, 6]; -% mom_conds = orders; - -% for o = 1:length(orders) -% order = orders(o); -% mom_cond = mom_conds(o); -% [xl, xr, m, h, x, H, fs] = setupStaggered(order, mom_cond); - -% % Test all grid points -% x0s = x; - -% for j = 1:length(fs) -% f = fs{j}; -% fx = f(x); -% for i = 1:length(x0s) -% x0 = x0s(i); -% delta = diracDiscr(x0, x, mom_cond, 0, H); -% integral = delta'*H*fx; -% err = abs(integral - f(x0)); -% testCase.verifyLessThan(err, 1e-12); -% end -% end -% end -% end - -% function testHalfGPStaggered(testCase) - -% orders = [2, 4, 6]; -% mom_conds = orders; - -% for o = 1:length(orders) -% order = orders(o); -% mom_cond = mom_conds(o); -% [xl, xr, m, h, x, H, fs] = setupStaggered(order, mom_cond); - -% % Test halfway between all grid points -% x0s = 1/2*( x(2:end)+x(1:end-1) ); - -% for j = 1:length(fs) -% f = fs{j}; -% fx = f(x); -% for i = 1:length(x0s) -% x0 = x0s(i); -% delta = diracDiscr(x0, x, mom_cond, 0, H); -% integral = delta'*H*fx; -% err = abs(integral - f(x0)); -% testCase.verifyLessThan(err, 1e-12); -% end -% end -% end -% end - -% function testRandomStaggered(testCase) - -% orders = [2, 4, 6]; -% mom_conds = orders; - -% for o = 1:length(orders) -% order = orders(o); -% mom_cond = mom_conds(o); -% [xl, xr, m, h, x, H, fs] = setupStaggered(order, mom_cond); - -% % Test random points within grid boundaries -% x0s = xl + (xr-xl)*rand(1,300); - -% for j = 1:length(fs) -% f = fs{j}; -% fx = f(x); -% for i = 1:length(x0s) -% x0 = x0s(i); -% delta = diracDiscr(x0, x, mom_cond, 0, H); -% integral = delta'*H*fx; -% err = abs(integral - f(x0)); -% testCase.verifyLessThan(err, 1e-12); -% end -% end -% end -% end - -%=============== 2D tests ============================== -function testAllGP2D(testCase) - - orders = [2, 4, 6]; - mom_conds = orders; - - for o = 1:length(orders) - order = orders(o); - mom_cond = mom_conds(o); - [xlims, ylims, m, x, X, ~, H, fs] = setup2D(order, mom_cond); - H_global = kron(H{1}, H{2}); - - % Test all grid points - x0s = X; - - for j = 1:length(fs) - f = fs{j}; - fx = f(X(:,1), X(:,2)); - for i = 1:length(x0s) - x0 = x0s(i,:); - delta = diracDiscr(x0, x, mom_cond, 0, H); - integral = delta'*H_global*fx; - err = abs(integral - f(x0(1), x0(2))); - testCase.verifyLessThan(err, 1e-12); - end - end - end -end - -function testAllRandom2D(testCase) - - orders = [2, 4, 6]; - mom_conds = orders; - - for o = 1:length(orders) - order = orders(o); - mom_cond = mom_conds(o); - [xlims, ylims, m, x, X, h, H, fs] = setup2D(order, mom_cond); - H_global = kron(H{1}, H{2}); - - xl = xlims{1}; - xr = xlims{2}; - yl = ylims{1}; - yr = ylims{2}; - - % Test random points, even outside grid - Npoints = 100; - x0s = [(xl-3*h{1}) + (xr-xl+6*h{1})*rand(Npoints,1), ... - (yl-3*h{2}) + (yr-yl+6*h{2})*rand(Npoints,1) ]; - - for j = 1:length(fs) - f = fs{j}; - fx = f(X(:,1), X(:,2)); - for i = 1:length(x0s) - x0 = x0s(i,:); - delta = diracDiscr(x0, x, mom_cond, 0, H); - integral = delta'*H_global*fx; - - % Integral should be 0 if point is outside grid - if x0(1) < xl || x0(1) > xr || x0(2) < yl || x0(2) > yr - err = abs(integral - 0); - else - err = abs(integral - f(x0(1), x0(2))); - end - testCase.verifyLessThan(err, 1e-12); - end - end - end -end - -%=============== 3D tests ============================== -function testAllGP3D(testCase) - - orders = [2, 4, 6]; - mom_conds = orders; - - for o = 1:length(orders) - order = orders(o); - mom_cond = mom_conds(o); - [xlims, ylims, zlims, m, x, X, h, H, fs] = setup3D(order, mom_cond); - H_global = kron(kron(H{1}, H{2}), H{3}); - - % Test all grid points - x0s = X; - - for j = 1:length(fs) - f = fs{j}; - fx = f(X(:,1), X(:,2), X(:,3)); - for i = 1:length(x0s) - x0 = x0s(i,:); - delta = diracDiscr(x0, x, mom_cond, 0, H); - integral = delta'*H_global*fx; - err = abs(integral - f(x0(1), x0(2), x0(3))); - testCase.verifyLessThan(err, 1e-12); - end - end - end -end - -function testAllRandom3D(testCase) - - orders = [2, 4, 6]; - mom_conds = orders; - - for o = 1:length(orders) - order = orders(o); - mom_cond = mom_conds(o); - [xlims, ylims, zlims, m, x, X, h, H, fs] = setup3D(order, mom_cond); - H_global = kron(kron(H{1}, H{2}), H{3}); - - xl = xlims{1}; - xr = xlims{2}; - yl = ylims{1}; - yr = ylims{2}; - zl = zlims{1}; - zr = zlims{2}; - - % Test random points, even outside grid - Npoints = 200; - x0s = [(xl-3*h{1}) + (xr-xl+6*h{1})*rand(Npoints,1), ... - (yl-3*h{2}) + (yr-yl+6*h{2})*rand(Npoints,1), ... - (zl-3*h{3}) + (zr-zl+6*h{3})*rand(Npoints,1) ]; - - for j = 1:length(fs) - f = fs{j}; - fx = f(X(:,1), X(:,2), X(:,3)); - for i = 1:length(x0s) - x0 = x0s(i,:); - delta = diracDiscr(x0, x, mom_cond, 0, H); - integral = delta'*H_global*fx; - - % Integral should be 0 if point is outside grid - if x0(1) < xl || x0(1) > xr || x0(2) < yl || x0(2) > yr || x0(3) < zl || x0(3) > zr - err = abs(integral - 0); - else - err = abs(integral - f(x0(1), x0(2), x0(3))); - end - testCase.verifyLessThan(err, 1e-12); - end - end - end -end - - -% ====================================================== -% ============== Setup functions ======================= -% ====================================================== -function [xl, xr, m, h, x, H, fs] = setup1D(order, mom_cond) - - % Grid - xl = -3; - xr = 900; - L = xr-xl; - m = 101; - h = (xr-xl)/(m-1); - g = grid.equidistant(m, {xl, xr}); - x = g.points(); - - % Quadrature - ops = sbp.D2Standard(m, {xl, xr}, order); - H = ops.H; - - % Moment conditions - fs = cell(mom_cond,1); - for p = 0:mom_cond-1 - fs{p+1} = @(x) (x/L).^p; - end - -end - -function [xlims, ylims, m, x, X, h, H, fs] = setup2D(order, mom_cond) - - % Grid - xlims = {-3, 20}; - ylims = {-11,5}; - Lx = xlims{2} - xlims{1}; - Ly = ylims{2} - ylims{1}; - - m = [15, 16]; - g = grid.equidistant(m, xlims, ylims); - X = g.points(); - x = g.x; - - % Quadrature - opsx = sbp.D2Standard(m(1), xlims, order); - opsy = sbp.D2Standard(m(2), ylims, order); - Hx = opsx.H; - Hy = opsy.H; - H = {Hx, Hy}; - - % Moment conditions - fs = cell(mom_cond,1); - for p = 0:mom_cond-1 - fs{p+1} = @(x,y) (x/Lx + y/Ly).^p; - end - - % Grid spacing in interior - mm = round(m/2); - hx = x{1}(mm(1)+1) - x{1}(mm(1)); - hy = x{2}(mm(2)+1) - x{2}(mm(2)); - h = {hx, hy}; - -end - -function [xlims, ylims, zlims, m, x, X, h, H, fs] = setup3D(order, mom_cond) - - % Grid - xlims = {-3, 20}; - ylims = {-11,5}; - zlims = {2,4}; - Lx = xlims{2} - xlims{1}; - Ly = ylims{2} - ylims{1}; - Lz = zlims{2} - zlims{1}; - - m = [13, 14, 15]; - g = grid.equidistant(m, xlims, ylims, zlims); - X = g.points(); - x = g.x; - - % Quadrature - opsx = sbp.D2Standard(m(1), xlims, order); - opsy = sbp.D2Standard(m(2), ylims, order); - opsz = sbp.D2Standard(m(3), zlims, order); - Hx = opsx.H; - Hy = opsy.H; - Hz = opsz.H; - H = {Hx, Hy, Hz}; - - % Moment conditions - fs = cell(mom_cond,1); - for p = 0:mom_cond-1 - fs{p+1} = @(x,y,z) (x/Lx + y/Ly + z/Lz).^p; - end - - % Grid spacing in interior - mm = round(m/2); - hx = x{1}(mm(1)+1) - x{1}(mm(1)); - hy = x{2}(mm(2)+1) - x{2}(mm(2)); - hz = x{3}(mm(3)+1) - x{3}(mm(3)); - h = {hx, hy, hz}; - -end - -function [xl, xr, m, h, x, H, fs] = setupStaggered(order, mom_cond) - - % Grid - xl = -3; - xr = 900; - L = xr-xl; - m = 101; - [~, g_dual] = grid.primalDual1D(m, {xl, xr}); - x = g_dual.points(); - h = g_dual.h; - - % Quadrature - ops = sbp.D1Staggered(m, {xl, xr}, order); - H = ops.H_dual; - - % Moment conditions - fs = cell(mom_cond,1); - for p = 0:mom_cond-1 - fs{p+1} = @(x) (x/L).^p; - end - -end