changeset 754:5264ce57b573 feature/d1_staggered

Bugfix diracDiscr to make it work for grids that are non-equidistant near boundaries.
author Martin Almquist <malmquist@stanford.edu>
date Fri, 15 Jun 2018 14:01:13 -0700
parents 44c46bd6913a
children 14f0058356f2
files diracDiscr.m diracDiscrTest.m
diffstat 2 files changed, 143 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/diracDiscr.m	Fri Jun 15 13:02:29 2018 -0700
+++ b/diracDiscr.m	Fri Jun 15 14:01:13 2018 -0700
@@ -1,4 +1,4 @@
-function ret = diracDiscr(x_0in , x , m_order, s_order, H)
+function ret = diracDiscr(x_0in , x , m_order, s_order, H, h)
 
 m = length(x);
 
@@ -11,12 +11,16 @@
 
     fnorm = diag(H);
     eta = abs(x-x_0in);
-    h = x(2)-x(1);
     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);
--- a/diracDiscrTest.m	Fri Jun 15 13:02:29 2018 -0700
+++ b/diracDiscrTest.m	Fri Jun 15 14:01:13 2018 -0700
@@ -220,11 +220,122 @@
     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] = setupStuff(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
+
+
+% ============== Setup functions =======================
 function [xl, xr, m, h, x, H, fs] = setupStuff(order, mom_cond)
 
     % Grid
     xl = -3;
-    xr = 2;
+    xr = 900;
+    L = xr-xl;
     m = 101;
     h = (xr-xl)/(m-1);
     g = grid.equidistant(m, {xl, xr});
@@ -237,7 +348,30 @@
     % Moment conditions
     fs = cell(mom_cond,1);
     for p = 0:mom_cond-1
-        fs{p+1} = @(x) x.^p;
+        fs{p+1} = @(x) (x/L).^p;
+    end
+
+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