Extension: Matrix functions
#include "dg/matrix/matrix.h"
tableau.h
Go to the documentation of this file.
1#pragma once
2
3#include <vector>
4#include <string>
5#include <functional>
6#include <unordered_map>
7#include "dg/algorithm.h"
8#include "functors.h"
9
10namespace dg{
11namespace mat{
12
13
30template<class real_type>
32 using value_type = real_type;
33 using function_type = std::function<value_type(value_type)>;
45 FunctionalButcherTableau(unsigned s, unsigned order,
46 const function_type* a , const function_type* b , const real_type* c):
47 m_a(a, a+s*s), m_b(b, b+s), m_c(c, c+s), m_bt(b,b+s), m_q(order), m_p(order), m_s(s){}
58 FunctionalButcherTableau(unsigned s, unsigned embedded_order, unsigned order,
59 const function_type* a, const function_type* b, const function_type* bt, const real_type* c):
60 m_a(a, a+s*s), m_b(b,b+s), m_c(c,c+s), m_bt(bt, bt+s), m_q(order), m_p(embedded_order), m_s(s), m_embedded(true){}
61
69 function_type a( unsigned i, unsigned j) const {
70 return m_a(i,j);
71 }
77 real_type c( unsigned i) const {
78 return m_c[i];
79 }
86 function_type b( unsigned j) const {
87 return m_b[j];
88 }
95 function_type bt( unsigned j) const {
96 return m_bt[j];
97 }
99 unsigned num_stages() const {
100 return m_s;
101 }
103 unsigned order() const {
104 return m_q;
105 }
107 unsigned embedded_order() const{
108 return m_p;
109 }
111 bool isEmbedded()const{
112 return m_embedded;
113 }
115 bool isImplicit()const{
116 for( unsigned i=0; i<m_s; i++)
117 for( unsigned j=i; j<m_s; j++)
118 if( a(i,j) != 0)
119 return true;
120 return false;
121 }
122 // ///True if the method has the "First Same As Last" property:
123 // ///the last stage is evaluated at the same point as the first stage of the next step.
124 // bool isFsal()const{
125 // if( m_c[m_s-1] != 1)
126 // return false;
127 // for (unsigned j=0; j<m_s; j++)
128 // if( a(m_s-1,j) != b(j) )
129 // return false;
130 // return true;
131 // }
132 private:
134 std::vector<function_type> m_b;
135 std::vector<real_type> m_c;
136 std::vector<function_type> m_bt;
137 unsigned m_q, m_p, m_s;
138 bool m_embedded = false;
139};
140
142namespace func_tableau{
143
145//https://en.wikipedia.org/wiki/List_of_Runge%E2%80%93Kutta_methods
146template<class real_type>
147FunctionalButcherTableau<real_type> explicit_euler_1_1( )
148{
149 auto zero = [&](real_type){return 0;};
150 using function_type = std::function<real_type(real_type)>;
151 function_type a[1] = {zero};
152 function_type b[1] = {[&](real_type x){return dg::mat::phi1(x);}};
153 real_type c[1] = {0.};
154 return FunctionalButcherTableau<real_type>( 1,1, a,b,c);
155}
156template<class real_type>
157FunctionalButcherTableau<real_type> midpoint_2_2()
158{
159 auto zero = [&](real_type){return 0;};
160 using function_type = std::function<real_type(real_type)>;
161 function_type a[4] = { zero, zero,
162 [&](real_type x){return 0.5*dg::mat::phi1(x/2.);},
163 zero};
164 function_type b[2] = { zero,
165 [&](real_type x){return dg::mat::phi1(x);}};
166 real_type c[2] = {0, 0.5};
167 return FunctionalButcherTableau<real_type>( 2,2, a,b,c);
168}
169template<class real_type>
170FunctionalButcherTableau<real_type> classic_4_4()
171{
172 auto zero = [&](real_type){return 0;};
173 using function_type = std::function<real_type(real_type)>;
174 function_type a[16] = {
176 [&](real_type x){return 0.5*dg::mat::phi1(x/2.);}, zero,zero,zero,
177 zero, [&](real_type x){return 0.5*dg::mat::phi1(x/2.);}, zero,zero,
178 [&](real_type x){return 0.5*dg::mat::phi1(x/2.)*(exp(x/2.)-1);},zero,[&](real_type x){return dg::mat::phi1(x/2.);},zero
179 };
180 function_type b[4] = {
181 [&](real_type x){return dg::mat::phi1(x)-3.*dg::mat::phi2(x)+4.*dg::mat::phi3(x);},
182 [&](real_type x){return 2.*dg::mat::phi2(x)-4.*dg::mat::phi3(x);},
183 [&](real_type x){return 2.*dg::mat::phi2(x)-4.*dg::mat::phi3(x);},
184 [&](real_type x){return -dg::mat::phi2(x)+4.*dg::mat::phi3(x);}
185 };
186 real_type c[4] = {0, 0.5, 0.5, 1.};
187 return FunctionalButcherTableau<real_type>( 4,4, a,b,c);
188}
189template<class real_type>
190FunctionalButcherTableau<real_type> hochbruck_3_3_4()
191{
192 auto zero = [&](real_type){return 0;};
193 using function_type = std::function<real_type(real_type)>;
194 function_type a[9] = {
195 zero,zero,zero,
196 [&](real_type x){return 0.5*dg::mat::phi1(x/2.);}, zero,zero,
197 zero, [&](real_type x){return dg::mat::phi1(x);}, zero
198 };
199 function_type b[3] = {
200 [&](real_type x){return dg::mat::phi1(x)-14.*dg::mat::phi3(x)+36.*dg::mat::phi4(x);},
201 [&](real_type x){return 16.*dg::mat::phi3(x)-48.*dg::mat::phi4(x);},
202 [&](real_type x){return -2.*dg::mat::phi3(x)+12.*dg::mat::phi4(x);},
203 };
204 function_type bt[3] = {
205 [&](real_type x){return dg::mat::phi1(x)-14.*dg::mat::phi3(x);},
206 [&](real_type x){return 16.*dg::mat::phi3(x);},
207 [&](real_type x){return -2.*dg::mat::phi3(x);}
208 };
209 real_type c[3] = {0, 0.5, 1.};
210 return FunctionalButcherTableau<real_type>( 3,3,4, a,b,bt,c);
211}
212
213
214}//namespace func_tableau
216
229enum func_tableau_identifier{
233 HOCHBRUCK_3_3_4
234};
235
237namespace create{
238
239static std::unordered_map<std::string, enum func_tableau_identifier> str2id{
240 //Explicit methods
241 {"Euler", EXPLICIT_EULER_1_1},
242 {"Midpoint-2-2", MIDPOINT_2_2},
243 {"Runge-Kutta-4-4", CLASSIC_4_4},
244 {"Hochbruck-3-3-4", HOCHBRUCK_3_3_4},
245};
246static inline enum func_tableau_identifier str2func_tableau( std::string name)
247{
248 if( str2id.find(name) == str2id.end())
249 throw dg::Error(dg::Message(_ping_)<<"Tableau "<<name<<" not found!");
250 else
251 return str2id[name];
252}
253static inline std::string func_tableau2str( enum func_tableau_identifier id)
254{
255 for( auto name: str2id)
256 {
257 if( name.second == id)
258 return name.first;
259 }
260 throw dg::Error(dg::Message(_ping_)<<"Tableau conversion failed!");
261}
262
263template<class real_type>
264FunctionalButcherTableau<real_type> func_tableau( enum func_tableau_identifier id)
265{
266 switch(id){
268 return func_tableau::explicit_euler_1_1<real_type>();
269 case MIDPOINT_2_2:
270 return func_tableau::midpoint_2_2<real_type>();
271 case CLASSIC_4_4:
272 return func_tableau::classic_4_4<real_type>();
273 case HOCHBRUCK_3_3_4:
274 return func_tableau::hochbruck_3_3_4<real_type>();
275 }
276 return FunctionalButcherTableau<real_type>(); //avoid compiler warning
277}
278
279
280template<class real_type>
281FunctionalButcherTableau<real_type> func_tableau( std::string name)
282{
283 return func_tableau<real_type>( str2func_tableau(name));
284}
285
286}//namespace create
288
321template<class real_type>
323{
324 using value_type = real_type;
328
334 ConvertsToFunctionalButcherTableau( enum tableau_identifier id):m_t( create::func_tableau<real_type>(id)){}
343 ConvertsToFunctionalButcherTableau( std::string name):m_t( create::func_tableau<real_type>(name)){}
345 ConvertsToFunctionalButcherTableau( const char* name):m_t( create::func_tableau<real_type>(std::string(name))){}
350 return m_t;
351 }
352 private:
354};
355
356}//namespace mat
357}//namespace dg
static DG_DEVICE double zero(double x)
tableau_identifier
MIDPOINT_2_2
EXPLICIT_EULER_1_1
CLASSIC_4_4
T phi1(T x)
Definition: functors.h:56
T phi3(T x)
Definition: functors.h:86
T phi4(T x)
Definition: functors.h:100
T phi2(T x)
Definition: functors.h:71
Classes for Krylov space approximations of a Matrix-Vector product.
Convert identifiers to their corresponding dg::mat::FunctionalButcherTableau.
Definition: tableau.h:323
ConvertsToFunctionalButcherTableau(enum tableau_identifier id)
Create FunctionalButcherTableau from dg::mat::func_tableau_identifier.
Definition: tableau.h:334
ConvertsToFunctionalButcherTableau(FunctionalButcherTableau< real_type > tableau)
Definition: tableau.h:327
real_type value_type
Definition: tableau.h:324
ConvertsToFunctionalButcherTableau(const char *name)
Create FunctionalButcherTableau from its name (very useful)
Definition: tableau.h:345
ConvertsToFunctionalButcherTableau(std::string name)
Create FunctionalButcherTableau from its name (very useful)
Definition: tableau.h:343
Manage coefficients of a functional (extended) Butcher tableau.
Definition: tableau.h:31
unsigned num_stages() const
The number of stages s.
Definition: tableau.h:99
unsigned order() const
global order of accuracy for the method represented by b
Definition: tableau.h:103
FunctionalButcherTableau(unsigned s, unsigned order, const function_type *a, const function_type *b, const real_type *c)
Construct a classic non-embedded tableau.
Definition: tableau.h:45
real_type c(unsigned i) const
Read the c_i coefficients.
Definition: tableau.h:77
bool isImplicit() const
True if an element on or above the diagonal in a is non-zero.
Definition: tableau.h:115
function_type bt(unsigned j) const
Read the embedded bt_j coefficients.
Definition: tableau.h:95
function_type a(unsigned i, unsigned j) const
Read the a_ij coefficients.
Definition: tableau.h:69
FunctionalButcherTableau()=default
No memory allocation.
FunctionalButcherTableau(unsigned s, unsigned embedded_order, unsigned order, const function_type *a, const function_type *b, const function_type *bt, const real_type *c)
Construct an embedded tableau.
Definition: tableau.h:58
real_type value_type
Definition: tableau.h:32
std::function< value_type(value_type)> function_type
Definition: tableau.h:33
bool isEmbedded() const
True if the method has an embedding.
Definition: tableau.h:111
unsigned embedded_order() const
global order of accuracy for the embedded method represented by bt
Definition: tableau.h:107
function_type b(unsigned j) const
Read the b_j coefficients.
Definition: tableau.h:86