Peano
Loading...
Searching...
No Matches
ButcherTableau.py
Go to the documentation of this file.
1# This file is part of the ExaHyPE2 project. For conditions of distribution and
2# use, please see the copyright notice at www.peano-framework.org
3from typing import List
4
5
7 """!
8
9 Butcher tableau of an explicit Runge-Kutta scheme
10
11 An explicit Runge-Kutta scheme with s stages advances
12
13 @f$ \\partial _t Q = F(t,Q) @f$
14
15 from @f$ Q^n @f$ to @f$ Q^{n+1} @f$ through
16
17 @f$ K_k = F \\left( t^n + c_k \\Delta t, Q^n + \\Delta t \\sum _{j<k} a_{kj} K_j \\right) @f$
18
19 @f$ Q^{n+1} = Q^n + \\Delta t \\sum _k b_k K_k @f$
20
21 The tableau holds the coefficients:
22
23 - relative_time_step_sizes(): the @f$ c_k @f$, i.e. the left column of
24 the classic tableau.
25 - weight_matrix(): the @f$ a_{kj} @f$, i.e. the strictly lower
26 triangular matrix in the middle of the classic tableau. Row k holds the
27 weights of the estimates which make up the input of stage k.
28 - final_estimate_weights(): the @f$ b_k @f$, i.e. the bottom row of the
29 classic tableau.
30
31 We support the orders one to four with one stage per order:
32
33 | Order | Scheme |
34 |-------|------------------------------|
35 | 1 | explicit Euler |
36 | 2 | explicit midpoint rule |
37 | 3 | Kutta's third-order scheme |
38 | 4 | Kutta's 3/8 rule |
39
40 The tableau does not know anything about the discretisation in space,
41 so Finite Differences (@ref exahype2.api.rkfd4) and Discontinuous
42 Galerkin schemes alike can build on it.
43
44 Ported from the legacy python/exahype2/solvers/ButcherTableau.py, which
45 remains in place, as the legacy Runge-Kutta solvers import it.
46
47 """
48
49 def __init__(self, order: int):
50 """!
51
52 @param order: int
53 Order of the Runge-Kutta scheme. Has to be between one and four.
54 It equals the number of stages.
55
56 """
57 if order < 1 or order > 4:
58 raise ValueError(
59 f"Runge-Kutta order has to be between 1 and 4, but got {order}"
60 )
61 self._order = order
62
63 @property
64 def order(self) -> int:
65 return self._order
66
67 @property
68 def number_of_stages(self) -> int:
69 return self._order
70
71 def relative_time_step_sizes(self) -> List[float]:
72 """!
73
74 The @f$ c_k @f$, i.e. the time stamp of stage k relative to the
75 time step size: Stage k evaluates the right-hand side at
76 @f$ t^n + c_k \\Delta t @f$.
77
78 """
79 return {
80 1: [0.0],
81 2: [0.0, 1 / 2],
82 3: [0.0, 1 / 2, 1.0],
83 4: [0.0, 1 / 3, 2 / 3, 1.0],
84 }[self._order]
85
86 def weight_matrix(self) -> List[List[float]]:
87 """!
88
89 The @f$ a_{kj} @f$ as number_of_stages x number_of_stages matrix.
90 The matrix is strictly lower triangular, as the scheme is explicit.
91
92 """
93 return {
94 1: [
95 [0.0],
96 ],
97 2: [
98 [0.0, 0.0],
99 [1 / 2, 0.0],
100 ],
101 3: [
102 [0.0, 0.0, 0.0],
103 [1 / 2, 0.0, 0.0],
104 [-1.0, 2.0, 0.0],
105 ],
106 4: [
107 [0.0, 0.0, 0.0, 0.0],
108 [1 / 3, 0.0, 0.0, 0.0],
109 [-1 / 3, 1.0, 0.0, 0.0],
110 [1.0, -1.0, 1.0, 0.0],
111 ],
112 }[self._order]
113
114 def final_estimate_weights(self) -> List[float]:
115 """!
116
117 The @f$ b_k @f$, i.e. the weights of the stages' estimates within
118 the final linear combination which yields @f$ Q^{n+1} @f$.
119
120 """
121 return {
122 1: [1.0],
123 2: [0.0, 1.0],
124 3: [1 / 6, 2 / 3, 1 / 6],
125 4: [1 / 8, 3 / 8, 3 / 8, 1 / 8],
126 }[self._order]
Butcher tableau of an explicit Runge-Kutta scheme.
List[List[float]] weight_matrix(self)
The as number_of_stages x number_of_stages matrix.