Mercurial > repos > public > sbplib
diff +time/SBPInTime.m @ 423:a2cb0d4f4a02 feature/grids
Merge in default.
author | Jonatan Werpers <jonatan@werpers.com> |
---|---|
date | Tue, 07 Feb 2017 15:47:51 +0100 |
parents | e1db62d14835 |
children | 38173ea263ed b5e5b195da1e |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/+time/SBPInTime.m Tue Feb 07 15:47:51 2017 +0100 @@ -0,0 +1,169 @@ +classdef SBPInTime < time.Timestepper + % The SBP in time method. + % Implemented for v_t = A*v + f(t) + % + % Each "step" takes one block step and thus advances + % k = k_local*(blockSize-1) in time. + properties + M % System matrix + L,U,P,Q % LU factorization of M + A + Et_r + penalty + f + k_local % step size within a block + k % Time size of a block k/(blockSize-1) = k_local + t + v + m + n + blockSize % number of points in each block + order + nodes + end + + methods + function obj = SBPInTime(A, f, k, t0, v0, TYPE, order, blockSize) + + default_arg('TYPE','gauss'); + + if(strcmp(TYPE,'gauss')) + default_arg('order',4) + default_arg('blockSize',4) + else + default_arg('order', 8); + default_arg('blockSize',time.SBPInTime.smallestBlockSize(order,TYPE)); + end + + obj.A = A; + obj.f = f; + obj.k_local = k/(blockSize-1); + obj.k = k; + obj.blockSize = blockSize; + obj.t = t0; + obj.m = length(v0); + obj.n = 0; + + %==== Build the time discretization matrix =====% + switch TYPE + case 'equidistant' + ops = sbp.D2Standard(blockSize,{0,obj.k},order); + case 'optimal' + ops = sbp.D1Nonequidistant(blockSize,{0,obj.k},order); + case 'minimal' + ops = sbp.D1Nonequidistant(blockSize,{0,obj.k},order,'minimal'); + case 'gauss' + ops = sbp.D1Gauss(blockSize,{0,obj.k}); + end + + D1 = ops.D1; + HI = ops.HI; + e_l = ops.e_l; + e_r = ops.e_r; + obj.nodes = ops.x; + + Ix = speye(size(A)); + It = speye(blockSize,blockSize); + + obj.Et_r = kron(e_r,Ix); + + % Time derivative + penalty + tau = 1; + Mt = D1 + tau*HI*(e_l*e_l'); + + % penalty to impose "data" + penalty = tau*HI*e_l; + obj.penalty = kron(penalty,Ix); + + Mx = kron(It,A); + Mt = kron(Mt,Ix); + obj.M = Mt - Mx; + %==============================================% + + % LU factorization + [obj.L,obj.U,obj.P,obj.Q] = lu(obj.M); + + % Pretend that the initial condition is the last level + % of a previous step. + obj.v = 1/(e_r'*e_r) * obj.Et_r * v0; + + end + + function [v,t] = getV(obj) + v = obj.Et_r' * obj.v; + t = obj.t; + end + + function obj = step(obj) + obj.v = time.sbp.sbpintime(obj.v, obj.t, obj.nodes,... + obj.penalty, obj.f, obj.blockSize,... + obj.Et_r,... + obj.L, obj.U, obj.P, obj.Q); + obj.t = obj.t + obj.k; + obj.n = obj.n + 1; + end + end + + methods(Static) + function N = smallestBlockSize(order,TYPE) + default_arg('TYPE','gauss') + + switch TYPE + + case 'equidistant' + switch order + case 2 + N = 2; + case 4 + N = 8; + case 6 + N = 12; + case 8 + N = 16; + case 10 + N = 20; + case 12 + N = 24; + otherwise + error('Operator does not exist'); + end + + case 'optimal' + + switch order + case 4 + N = 8; + case 6 + N = 12; + case 8 + N = 16; + case 10 + N = 20; + case 12 + N = 24; + otherwise + error('Operator does not exist'); + end + + case 'minimal' + + switch order + case 4 + N = 6; + case 6 + N = 10; + case 8 + N = 12; + case 10 + N = 16; + case 12 + N = 20; + otherwise + error('Operator does not exist'); + end + case 'gauss' + N = 4; + end + end + end +end