Mercurial > repos > public > sbplib
comparison +time/+rk/ExplicitSecondOrder.m @ 1102:d4c895d4b524 feature/timesteppers
Add skeleton for time.rk.ExplicitSecondOrder
author | Jonatan Werpers <jonatan@werpers.com> |
---|---|
date | Tue, 09 Apr 2019 22:17:07 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
1101:b895037bb701 | 1102:d4c895d4b524 |
---|---|
1 classdef ExplicitSecondOrder < time.Timestepper | |
2 properties | |
3 F % RHS of the ODE | |
4 dt % Time step | |
5 t % Time point | |
6 v, vt % Solution state | |
7 n % Time level | |
8 bt | |
9 end | |
10 | |
11 | |
12 methods | |
13 % Timesteps v_tt = F(t,v,vt), using the specified ButcherTableau | |
14 % from t = t0 with timestep dt and initial conditions v(0) = v0 | |
15 function obj = ExplicitSecondOrder(F, dt, t0, v0, v0t, bt) | |
16 assertType(bt, 'time.rk.ButcherTableau') | |
17 obj.F = F; | |
18 obj.dt = dt; | |
19 obj.t = t0; | |
20 obj.v = v0; | |
21 obj.vt = v0t; | |
22 obj.n = 0; | |
23 | |
24 assert(bt.isExplicit()) | |
25 obj.bt = bt; | |
26 end | |
27 | |
28 function [v,t] = getV(obj) | |
29 v = obj.v; | |
30 t = obj.t; | |
31 end | |
32 | |
33 function [vt,t] = getVt(obj) | |
34 vt = obj.vt; | |
35 t = obj.t; | |
36 end | |
37 | |
38 function obj = step(obj) | |
39 s = obj.bt.nStages(); | |
40 a = obj.bt.a; | |
41 b = obj.bt.b; | |
42 c = obj.bt.c; | |
43 | |
44 t = obj.t; | |
45 v = obj.v; | |
46 vt = obj.vt; | |
47 dt = obj.dt; | |
48 | |
49 k1 = obj.F(t, v, v_t); | |
50 k2 = obj.F(t + 1/2*dt, v + 1/2*dt*v_t, v_t + 1/2*dt*k1); | |
51 k3 = obj.F(t + 1/2*dt, v + 1/2*dt*v_t + 1/4*dt^2*k1, v_t + 1/2*dt*k2); | |
52 k4 = obj.F(t + dt, v + dt*v_t + 1/2*dt^2*k2, v_t + dt*k3); | |
53 | |
54 % Compute rates K | |
55 K = zeros(length(v), s); | |
56 for i = 1:s | |
57 U_i = obj.v; | |
58 V_i = obj.vt; | |
59 for j = 1:i-1 | |
60 U_i = U_i % + dt*a(i,j)*K(:,j); | |
61 V_i = V_i % + dt*a(i,j)*K(:,j); | |
62 end | |
63 K(:,i) = F(t+dt*c(i), U_i, V_i); | |
64 end | |
65 | |
66 % Compute updated solution | |
67 v_next = v; | |
68 vt_next = vt; | |
69 for i = 1:s | |
70 v_next = v_next % + dt*b(i)*K(:,i); | |
71 vt_next = vt_next % + dt*b(i)*K(:,i); | |
72 end | |
73 | |
74 obj.v = v_next; | |
75 obj.vt = vt_next; | |
76 obj.t = obj.t + obj.dt; | |
77 obj.n = obj.n + 1; | |
78 end | |
79 | |
80 | |
81 % Returns a vector of time points, including substage points, | |
82 % in the time interval [t0, tEnd]. | |
83 % The time-step obj.dt is assumed to be aligned with [t0, tEnd] already. | |
84 function tvec = timePoints(obj, t0, tEnd) | |
85 % TBD: Should this be implemented here or somewhere else? | |
86 N = round( (tEnd-t0)/obj.dt ); | |
87 tvec = zeros(N*obj.s, 1); | |
88 s = obj.coeffs.s; | |
89 c = obj.coeffs.c; | |
90 for i = 1:N | |
91 ind = (i-1)*s+1 : i*s; | |
92 tvec(ind) = ((i-1) + c')*obj.dt; | |
93 end | |
94 end | |
95 | |
96 % Returns a vector of quadrature weights corresponding to grid points | |
97 % in time interval [t0, tEnd], substage points included. | |
98 % The time-step obj.dt is assumed to be aligned with [t0, tEnd] already. | |
99 function weights = quadWeights(obj, t0, tEnd) | |
100 % TBD: Should this be implemented here or somewhere else? | |
101 N = round( (tEnd-t0)/obj.dt ); | |
102 b = obj.coeffs.b; | |
103 weights = repmat(b', N, 1); | |
104 end | |
105 end | |
106 | |
107 methods(Static) | |
108 % TBD: Function name | |
109 function ts = methodFromStr(F, dt, t0, v0, methodStr) | |
110 try | |
111 bt = time.rk.ButcherTableau.(method); | |
112 catch | |
113 error('Runge-Kutta method ''%s'' is not implemented', methodStr) | |
114 end | |
115 | |
116 ts = time.rk.Explicit(F, dt, t0, v0, bt); | |
117 end | |
118 end | |
119 end |