Skip to content

Commit 305da7f

Browse files
Start the Sanz-Serna Problem (#13)
* Start the Sanz-Serna Problem * Fix PR comments * Add linear-forcing splitting of RHS * Use size(,1) instead of length * Add partial derivative wrt time * Make Jacobians matrices instead of function handles Co-authored-by: Steven Roberts <sroberts994@gmail.com>
1 parent 04a84ee commit 305da7f

File tree

10 files changed

+113
-0
lines changed

10 files changed

+113
-0
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
classdef Canonical < otp.sanzserna.SanzSernaProblem
2+
methods
3+
function obj = Canonical(numGridCells)
4+
if nargin < 1
5+
numGridCells = 32;
6+
end
7+
8+
y0 = linspace(1/numGridCells + 1, 2, numGridCells).';
9+
obj = obj@otp.sanzserna.SanzSernaProblem([0, 1], y0, struct);
10+
end
11+
end
12+
end
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
classdef SanzSernaProblem < otp.Problem
2+
% This test problem comes from
3+
% Sanz-Serna, J. M., Verwer, J. G., & Hundsdorfer, W. H. (1986). Convergence and order reduction of Runge-Kutta schemes
4+
% applied to evolutionary problems in partial differential equations. Numerische Mathematik, 50(4), 405–418.
5+
% https://doi.org/10.1007/BF01396661
6+
7+
properties (SetAccess = private)
8+
RhsLinear
9+
RhsForcing
10+
end
11+
12+
methods
13+
function obj = SanzSernaProblem(timeSpan, y0, parameters)
14+
obj@otp.Problem('Sanz-Serna', [], timeSpan, y0, parameters);
15+
end
16+
end
17+
18+
methods (Access=protected)
19+
20+
function onSettingsChanged(obj)
21+
22+
D = spdiags(ones(obj.NumVars, 1) * [obj.NumVars, -obj.NumVars], [-1, 0], obj.NumVars, obj.NumVars);
23+
24+
x = linspace(1/obj.NumVars, 1, obj.NumVars).';
25+
26+
obj.Rhs = otp.Rhs(@(t, y) otp.sanzserna.f(t, y, D, x), ...
27+
otp.Rhs.FieldNames.Jacobian, otp.sanzserna.jac(D, x), ...
28+
otp.Rhs.FieldNames.JacobianVectorProduct, @(t, y, v) otp.sanzserna.jvp(t, y, v, D, x), ...
29+
otp.Rhs.FieldNames.PartialDerivativeTime, @(t, y) otp.sanzserna.pdt(t, y, D, x));
30+
31+
obj.RhsLinear = otp.Rhs(@(t, y) otp.sanzserna.flinear(t, y, D, x), ...
32+
otp.Rhs.FieldNames.Jacobian, otp.sanzserna.jaclinear(D, x));
33+
obj.RhsForcing = otp.Rhs(@(t, y) otp.sanzserna.fforcing(t, y, D, x), ...
34+
otp.Rhs.FieldNames.Jacobian, otp.sanzserna.jacforcing(D, x));
35+
end
36+
37+
function sol = internalSolve(obj, varargin)
38+
sol = internalSolve@otp.Problem(obj, 'Method', @ode45, varargin{:});
39+
end
40+
41+
%true solution
42+
end
43+
end

src/+otp/+sanzserna/f.m

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
function dy = f(t, y, D, x)
2+
3+
hInv = size(y, 1);
4+
5+
forcingTerm = (t - x) / (1 + t)^2;
6+
7+
forcingTerm(1) = forcingTerm(1) + (hInv / (1 + t));
8+
9+
dy = D * y + forcingTerm;
10+
11+
end
12+

src/+otp/+sanzserna/fforcing.m

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
function dy = fforcing(t, y, ~, x)
2+
3+
hInv = size(y, 1);
4+
5+
dy = (t - x) / (1 + t)^2;
6+
7+
dy(1) = dy(1) + (hInv / (1 + t));
8+
9+
end
10+

src/+otp/+sanzserna/flinear.m

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
function dy = flinear(~, y, D, ~)
2+
3+
dy = D * y;
4+
5+
end
6+

src/+otp/+sanzserna/jac.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
function D = jac(D, ~)
2+
3+
end
4+

src/+otp/+sanzserna/jacforcing.m

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
function J = jacforcing(~, x)
2+
3+
numVars = length(x);
4+
J = sparse(numVars, numVars);
5+
6+
end
7+

src/+otp/+sanzserna/jaclinear.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
function D = jaclinear(D, ~)
2+
3+
end
4+

src/+otp/+sanzserna/jvp.m

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
function jx = jvp(~, ~, v, D, ~)
2+
3+
jx = D * v;
4+
5+
end
6+

src/+otp/+sanzserna/pdt.m

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
function jt = pdt(t, y, ~, x)
2+
3+
hInv = size(y, 1);
4+
5+
jt = (1 - t + 2 * x) / (1 + t)^3;
6+
jt(1) = jt(1) - hInv / (1 + t)^2;
7+
8+
end
9+

0 commit comments

Comments
 (0)