comparison +time/SBPInTime.m @ 365:f908ce064f35

Added SBP in time timestepper.
author Martin Almquist <martin.almquist@it.uu.se>
date Tue, 24 Jan 2017 14:01:18 +0100
parents
children fccd746d8573 14f2be4fe9c1
comparison
equal deleted inserted replaced
363:8c8fd649bae3 365:f908ce064f35
1 classdef SBPInTime < time.Timestepper
2 % The SBP in time method.
3 % Implemented for v_t = A*v + f(t)
4 % k_local -- time-step
5 % Nblock -- number of points in each block
6 % nodes -- points such that t_n + nodes are the points in block n.
7 % Each "step" takes one block step and thus advances
8 % k = k_local*(Nblock-1) in time.
9 % M -- matrix used in every solve.
10 % [L,U,P,Q] = lu(M);
11 properties
12 M
13 L
14 U
15 P
16 Q
17 A
18 Et_r
19 penalty
20 f
21 k_local
22 k
23 t
24 v
25 m
26 n
27 Nblock
28 order
29 nodes
30 end
31
32 methods
33 function obj = SBPInTime(A, f, k, order, Nblock, t0, v0, TYPE)
34 default_arg('TYPE','equidistant');
35 default_arg('Nblock',time.SBPInTime.smallestBlockSize(order,TYPE));
36
37 obj.A = A;
38 obj.f = f;
39 obj.k_local = k;
40 obj.k = k*(Nblock-1);
41 obj.Nblock = Nblock;
42 obj.t = t0;
43 obj.m = length(v0);
44 obj.n = 0;
45
46 %==== Build the time discretization matrix =====%
47 switch TYPE
48 case 'equidistant'
49 ops = sbp.D2Standard(Nblock,{0,obj.k},order);
50 case 'optimal'
51 ops = sbp.D1Nonequidistant(Nblock,{0,obj.k},order);
52 case 'minimal'
53 ops = sbp.D1Nonequidistant(Nblock,{0,obj.k},order,'minimal');
54 end
55
56 D1 = ops.D1;
57 HI = ops.HI;
58 e_l = ops.e_l;
59 e_r = ops.e_r;
60 obj.nodes = ops.x;
61
62 Ix = speye(size(A));
63 It = speye(Nblock,Nblock);
64
65 obj.Et_r = kron(e_r,Ix);
66
67 % Time derivative + penalty
68 tau = 1;
69 Mt = D1 + tau*HI*(e_l*e_l');
70
71 % penalty to impose "data"
72 penalty = tau*HI*e_l;
73 obj.penalty = kron(penalty,Ix);
74
75 Mx = kron(It,A);
76 Mt = kron(Mt,Ix);
77 obj.M = Mt - Mx;
78 %==============================================%
79
80 % LU factorization
81 [obj.L,obj.U,obj.P,obj.Q] = lu(obj.M);
82
83 % Pretend that the initial condition is the last level
84 % of a previous step.
85 obj.v = obj.Et_r * v0;
86
87 end
88
89 function [v,t] = getV(obj)
90 v = obj.Et_r' * obj.v;
91 t = obj.t;
92 end
93
94 function obj = step(obj)
95 obj.v = time.sbp.sbpintime(obj.v, obj.t, obj.nodes,...
96 obj.penalty, obj.f, obj.Nblock,...
97 obj.Et_r,...
98 obj.L, obj.U, obj.P, obj.Q);
99 obj.t = obj.t + obj.k;
100 obj.n = obj.n + obj.Nblock-1;
101 end
102 end
103
104
105 methods(Static)
106
107 %
108 function [k,numberOfBlocks] = alignedTimeStep(k,Tend,Nblock)
109
110 % input k is the desired time-step
111 % Nblock is the number of points per block.
112
113 % Make sure that we reach the final time by advancing
114 % an integer number of blocks
115 kblock = (Nblock-1)*k;
116 numberOfBlocks = ceil(Tend/kblock);
117 kblock = Tend/(numberOfBlocks);
118
119 % Corrected time step
120 k = kblock/(Nblock-1);
121
122 end
123
124 function N = smallestBlockSize(order,TYPE)
125 default_arg('TYPE','equidistant')
126
127 switch TYPE
128
129 case 'equidistant'
130 switch order
131 case 2
132 N = 2;
133 case 4
134 N = 8;
135 case 6
136 N = 12;
137 case 8
138 N = 16;
139 case 10
140 N = 20;
141 case 12
142 N = 24;
143 otherwise
144 error('Operator does not exist');
145 end
146
147 case 'optimal'
148
149 switch order
150 case 4
151 N = 8;
152 case 6
153 N = 12;
154 case 8
155 N = 16;
156 case 10
157 N = 20;
158 case 12
159 N = 24;
160 otherwise
161 error('Operator does not exist');
162 end
163
164 case 'minimal'
165
166 switch order
167 case 4
168 N = 6;
169 case 6
170 N = 10;
171 case 8
172 N = 12;
173 case 10
174 N = 16;
175 case 12
176 N = 20;
177 otherwise
178 error('Operator does not exist');
179 end
180
181 end
182
183 end
184
185 end
186
187
188
189 end