changeset 636:476b7e411ce3 feature/d1_staggered

Add staggered operators
author Martin Almquist <malmquist@stanford.edu>
date Tue, 07 Nov 2017 20:44:13 -0800
parents bb1180becc30
children eead18a8964d
files +sbp/+implementations/d1_staggered_2.m +sbp/+implementations/d1_staggered_4.m +sbp/+implementations/d1_staggered_6.m +sbp/D1Staggered.m
diffstat 4 files changed, 315 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/+sbp/+implementations/d1_staggered_2.m	Tue Nov 07 20:44:13 2017 -0800
@@ -0,0 +1,71 @@
+function [xp, xm, Pp, Pm, Qp, Qm] = d1_staggered_2(n, L)
+% [xp, xm, Pp, Pm, Qp, Qm] = sbp_staggered_2(n, L)
+% Input arguments:
+% n : number of grid points: n on xp grid and n+1 on xm grid
+% L : interval length
+
+n = n - 1;
+assert(n >= 3, 'Not enough grid points');  
+
+h = L/(n-1);
+
+qm20 = -1/4;
+qm01 = 1/2;
+qp11 = -1/4;
+qm11 = 1/4;
+qp02 = 1/4;
+pp0 = 1/2;
+pm1 = 1/4;
+qm00 = -1/2;
+qp10 = -1/2;
+qp12 = 3/4;
+qp00 = -1/2;
+qm21 = -3/4;
+pp1 = 1;
+qp01 = 1/4;
+pm0 = 1/2;
+pm2 = 5/4;
+qm10 = -1/4;
+
+% Q+ and Q-, top-left corner
+QpL = [...
+qp00, qp01, qp02;
+ qp10, qp11, qp12
+];
+QmL = [...
+qm00, qm01;
+ qm10, qm11;
+ qm20, qm21
+];
+
+% Q+ and Q-
+b = 2;
+w = b; 
+s = [-1, 1]';  
+Qp = spdiags(repmat(-s(end:-1:1)',[n+2 1]), -(w/2-1):w/2, n+2, n+2); 
+Qm = spdiags(repmat(s(:)',[n+2 1]), -(w/2-1)-1:w/2-1, n+2, n+2);
+Qp(end,:) = [];
+Qm(:,end) = [];
+
+% Add SBP boundary closures
+Qp(1:b,1:b+1) = QpL;
+Qp(end-b+1:end,end-b:end) = -fliplr(flipud(QpL));
+Qm(1:b+1,1:b) = QmL;
+Qm(end-b:end,end-b+1:end) = -fliplr(flipud(QmL));
+
+% P+ and P-
+Pp = ones(n+1,1);
+Pm = ones(n+2,1);
+
+Pp(1:b) = [pp0,  pp1]; 
+Pp(end-b+1:end) = Pp(b:-1:1);
+Pm(1:b+1) = [pm0,  pm1,  pm2];
+Pm(end-b:end) = Pm(b+1:-1:1);
+Pp = spdiags(Pp,0,n+1,n+1);
+Pm = spdiags(Pm,0,n+2,n+2);
+
+Pp = h*Pp;
+Pm = h*Pm;
+
+xp = h*[0:n]';
+xm = h*[0 1/2+0:n n]';  
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/+sbp/+implementations/d1_staggered_4.m	Tue Nov 07 20:44:13 2017 -0800
@@ -0,0 +1,58 @@
+function [xp, xm, Pp, Pm, Qp, Qm] = d1_staggered_4(n, L)
+% [xp, xm, Pp, Pm, Qp, Qm] = sbp_staggered_4(n, L)
+% Input arguments:
+% n : number of grid points: n on xp grid and n+1 on xm grid
+% L : interval length
+
+n = n - 1;
+assert(n >= 7, 'Not enough grid points');  
+
+h = L/(n-1);
+
+% Q+ and Q-, top-left corner
+QpL = [...
+-323/378, 2783/3072, -1085/27648, -17/9216, -667/64512;
+ -5/21, -847/1024, 1085/1024, -37/1024, 899/21504;
+ 5/42, -121/1024, -1085/1024, 3575/3072, -753/7168;
+ -5/189, 121/3072, 1085/27648, -10759/9216, 74635/64512
+];
+QmL = [...
+-55/378, 5/21, -5/42, 5/189;
+ -2783/3072, 847/1024, 121/1024, -121/3072;
+ 1085/27648, -1085/1024, 1085/1024, -1085/27648;
+ 17/9216, 37/1024, -3575/3072, 10759/9216;
+ 667/64512, -899/21504, 753/7168, -74635/64512
+];
+
+% Q+ and Q-
+w = 4; 
+s = [ 1/24,  -9/8,  9/8,  -1/24];  
+Qp = spdiags(repmat(-s(end:-1:1),[n+2 1]), -(w/2-1):w/2, n+2, n+2); 
+Qm = spdiags(repmat(s(:)',[n+2 1]), -(w/2-1)-1:w/2-1, n+2, n+2);
+Qp(end,:) = [];
+Qm(:,end) = [];
+
+% Add SBP boundary closures
+bp = 4; 
+bm = 5;
+Qp(1:bp,1:bm) = double(QpL);
+Qp(end-bp+1:end,end-bm+1:end) = -fliplr(flipud(QpL));
+Qm(1:bm,1:bp) = double(QmL);
+Qm(end-bm+1:end,end-bp+1:end) = -fliplr(flipud(QmL));
+
+% P+ and P-
+Pp = ones(n+1,1);
+Pm = ones(n+2,1);
+
+Pp(1:bp) = [407/1152,  473/384,  343/384,  1177/1152]; 
+Pp(end-bp+1:end) = Pp(bp:-1:1);
+Pm(1:bm) = [5/63,  121/128,  1085/1152,  401/384,  2659/2688];
+Pm(end-bm+1:end) = Pm(bm:-1:1);
+Pp = spdiags(Pp,0,n+1,n+1);
+Pm = spdiags(Pm,0,n+2,n+2);
+
+Pp = h*Pp;
+Pm = h*Pm;
+
+xp = h*[0:n]';
+xm = h*[0 1/2+0:n n]';  
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/+sbp/+implementations/d1_staggered_6.m	Tue Nov 07 20:44:13 2017 -0800
@@ -0,0 +1,103 @@
+function [xp, xm, Pp, Pm, Qp, Qm] = d1_staggered_6(n, L)
+% [xp, xm, Pp, Pm, Qp, Qm] = sbp_staggered_6(n, L)
+% Input arguments:
+% n : number of grid points: n on xp grid and n+1 on xm grid
+% L : interval length
+
+n = n - 1;
+assert(n >= 9, 'Not enough grid points');  
+
+h = L/(n-1);
+
+% Coefficients determined such that the SBP property is satisfied
+qp44 = -144662434693018337/131093333881896960;
+pp3 = 793/720;
+qp22 = -729260819980499/780317463582720;
+pm5 = 1262401/1244160;
+pp4 = 157/160;
+qp03 = -1056618403248889/17835827739033600;
+qp32 = 17518644727427/2340952390748160;
+pm4 = 224201/241920;
+pm2 = 90101/103680;
+qp40 = -572605772036807/27311111225395200;
+qp30 = 3572646778087103/61450000257139200;
+pm3 = 26369/23040;
+qp41 = 935926732952051/29964190601576448;
+qp02 = -67953322736279/2340952390748160;
+pp0 = 95/288;
+qp01 = 143647626126052207/149820953007882240;
+pp1 = 317/240;
+qp12 = 444281115722813/468190478149632;
+qp25 = 312883915256963/24970158834647040;
+qp11 = -36400588465707331/37455238251970560;
+qp20 = -137012145866261/13655555612697600;
+qp10 = -1008199398207353/6827777806348800;
+qp15 = -1088192686015471/37455238251970560;
+qp04 = -239061311631881/131093333881896960;
+qp35 = -2480203967217637/112365714755911680;
+qp21 = 1658590350384343/24970158834647040;
+qp05 = 4843362440877649/449462859023646720;
+qp24 = -372310079307409/4369777796063232;
+qp33 = -4809914536549211/4458956934758400;
+qp23 = 2826535075774271/2972637956505600;
+qp42 = 4202889834071/585238097687040;
+qp14 = 492703999899311/32773333470474240;
+pm1 = 133801/138240;
+qp34 = 36544940032227659/32773333470474240;
+qp00 = -216175739231516543/245800001028556800;
+qp43 = 128340370711031/17835827739033600;
+qp13 = 823082791653949/4458956934758400;
+pm0 = 5251/68040;
+pp2 = 23/30;
+qp45 = 170687698457070187/149820953007882240;
+qp31 = -3169112007572299/37455238251970560;
+
+% Q+ and Q-, top-left corner
+QpL = [...
+-216175739231516543/245800001028556800, 143647626126052207/149820953007882240, -67953322736279/2340952390748160, -1056618403248889/17835827739033600, -239061311631881/131093333881896960, 4843362440877649/449462859023646720;
+ -1008199398207353/6827777806348800, -36400588465707331/37455238251970560, 444281115722813/468190478149632, 823082791653949/4458956934758400, 492703999899311/32773333470474240, -1088192686015471/37455238251970560;
+ -137012145866261/13655555612697600, 1658590350384343/24970158834647040, -729260819980499/780317463582720, 2826535075774271/2972637956505600, -372310079307409/4369777796063232, 312883915256963/24970158834647040;
+ 3572646778087103/61450000257139200, -3169112007572299/37455238251970560, 17518644727427/2340952390748160, -4809914536549211/4458956934758400, 36544940032227659/32773333470474240, -2480203967217637/112365714755911680;
+ -572605772036807/27311111225395200, 935926732952051/29964190601576448, 4202889834071/585238097687040, 128340370711031/17835827739033600, -144662434693018337/131093333881896960, 170687698457070187/149820953007882240
+];
+QmL = [...
+-29624261797040257/245800001028556800, 1008199398207353/6827777806348800, 137012145866261/13655555612697600, -3572646778087103/61450000257139200, 572605772036807/27311111225395200;
+ -143647626126052207/149820953007882240, 36400588465707331/37455238251970560, -1658590350384343/24970158834647040, 3169112007572299/37455238251970560, -935926732952051/29964190601576448;
+ 67953322736279/2340952390748160, -444281115722813/468190478149632, 729260819980499/780317463582720, -17518644727427/2340952390748160, -4202889834071/585238097687040;
+ 1056618403248889/17835827739033600, -823082791653949/4458956934758400, -2826535075774271/2972637956505600, 4809914536549211/4458956934758400, -128340370711031/17835827739033600;
+ 239061311631881/131093333881896960, -492703999899311/32773333470474240, 372310079307409/4369777796063232, -36544940032227659/32773333470474240, 144662434693018337/131093333881896960;
+ -4843362440877649/449462859023646720, 1088192686015471/37455238251970560, -312883915256963/24970158834647040, 2480203967217637/112365714755911680, -170687698457070187/149820953007882240
+];
+
+% Q+ and Q-
+w = 6; 
+s = [ -3/640,  25/384,  -75/64,  75/64,  -25/384,  3/640];  
+Qp = spdiags(repmat(-s(end:-1:1),[n+2 1]), -(w/2-1):w/2, n+2, n+2); 
+Qm = spdiags(repmat(s(:)',[n+2 1]), -(w/2-1)-1:w/2-1, n+2, n+2);
+Qp(end,:) = [];
+Qm(:,end) = [];
+
+% Add SBP boundary closures
+bp = 5;
+bm = 6;
+Qp(1:bp,1:bm) = double(QpL);
+Qp(end-bp+1:end,end-bm+1:end) = -fliplr(flipud(QpL));
+Qm(1:bm,1:bp) = double(QmL);
+Qm(end-bm+1:end,end-bp+1:end) = -fliplr(flipud(QmL));
+
+% P+ and P-
+Pp = ones(n+1,1);
+Pm = ones(n+2,1);
+
+Pp(1:bp) = [95/288,  317/240,  23/30,  793/720,  157/160]; 
+Pp(end-bp+1:end) = Pp(bp:-1:1);
+Pm(1:bm) = [5251/68040,  133801/138240,  90101/103680,  26369/23040,  224201/241920,  1262401/1244160];
+Pm(end-bm+1:end) = Pm(bm:-1:1);
+Pp = spdiags(Pp,0,n+1,n+1);
+Pm = spdiags(Pm,0,n+2,n+2);
+
+Pp = h*Pp;
+Pm = h*Pm;
+
+xp = h*[0:n]';
+xm = h*[0 1/2+0:n n]';
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/+sbp/D1Staggered.m	Tue Nov 07 20:44:13 2017 -0800
@@ -0,0 +1,83 @@
+classdef D1Staggered < sbp.OpSet
+    properties
+        % xp: "plus" grid with m points
+        % xm: "minus" grid with m+1 points
+
+        D1p % SBP operator approximating first derivative
+        D1m % SBP operator approximating first derivative
+        Hp % Norm matrix
+        Hm % Norm matrix
+        HpI % H^-1
+        HmI % H^-1
+        ep_l % Left boundary operator
+        em_l % Left boundary operator
+        ep_r % Right boundary operator
+        em_r % Right boundary operator
+        m % Number of grid points.
+        mp % Number of grid points.
+        mm % Number of grid points.
+        h % Step size
+        xp % grid
+        xm % grid
+        x
+        borrowing % Struct with borrowing limits for different norm matrices
+    end
+
+    methods
+        function obj = D1Staggered(m,lim,order)
+
+          x_l = lim{1};
+          x_r = lim{2};
+          L = x_r-x_l;
+
+          mp = m;
+          mm = m+1;
+
+          switch order
+          case 2
+            [xp, xm, Pp, Pm, Qp, Qm] = sbp.implementations.d1_staggered_2(m, L);
+          case 4
+            [xp, xm, Pp, Pm, Qp, Qm] = sbp.implementations.d1_staggered_4(m, L);
+          case 6
+            [xp, xm, Pp, Pm, Qp, Qm] = sbp.implementations.d1_staggered_6(m, L);
+          otherwise
+           error('Invalid operator order %d.',order);
+          end
+
+          obj.m = m;
+          obj.mp = mp;
+          obj.mm = mm;
+          obj.xp = x_l + xp';
+          obj.xm = x_l + xm';
+
+          D1p = Pp\Qp;
+          D1m = Pm\Qm;
+
+          obj.D1p = D1p;
+          obj.D1m = D1m;
+          pbj.Hp = Pp;
+          obj.Hm = Pm; 
+
+          obj.ep_l = sparse(mp,1);
+          obj.ep_r = sparse(mp,1);
+          obj.ep_l(1) = 1;
+          obj.ep_r(mp) = 1;
+
+          obj.em_l = sparse(mm,1);
+          obj.em_r = sparse(mm,1);
+          obj.em_l(1) = 1;
+          obj.em_r(mm) = 1;
+
+          obj.HpI = inv(obj.Hp);
+          obj.HmI = inv(obj.Hm);
+
+          obj.borrowing = [];
+          obj.x = [];
+
+        end
+
+        function str = string(obj)
+            str = [class(obj) '_' num2str(obj.order)];
+        end
+    end
+end