TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
TRUSTSchema_RK.h
1/****************************************************************************
2* Copyright (c) 2024, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15
16#ifndef TRUSTSchema_RK_included
17#define TRUSTSchema_RK_included
18
19#include <Domaine_Cl_dis_base.h>
20#include <Schema_Temps_base.h>
21#include <Equation_base.h>
22#include <type_traits>
23
24using ARR1 = std::array<double, 1>; // OK je sais mais bon ... ne demande pas alors :-)
25using ARR2 = std::array<double, 2>;
26using ARR3 = std::array<double, 3>;
27using ARR4 = std::array<double, 4>;
28
29enum class Ordre_RK { UN , RATIO_DEUX , DEUX_CLASSIQUE , DEUX_WILLIAMSON , TROIS_CLASSIQUE , TROIS_WILLIAMSON , QUATRE_CLASSIQUE , QUATRE_CLASSIQUE_3_8 , QUATRE_WILLIAMSON };
30
31template <Ordre_RK _ORDRE_ >
33{
34 // Renvoie le nombre de valeurs temporelles a conserver. Ici : n et n+1, donc 2.
35 int nb_valeurs_temporelles() const override { return 2 ; }
36
37 // Renvoie le nombre de valeurs temporelles futures. Ici : n+1, donc 1.
38 int nb_valeurs_futures() const override { return 1 ; }
39
40 // Renvoie le le temps a la i-eme valeur future. Ici : t(n+1)
41 double temps_futur(int i) const override
42 {
43 assert(i == 1);
44 return temps_courant() + pas_de_temps();
45 }
46
47 // Renvoie le le temps le temps que doivent rendre les champs a l'appel de valeurs(). Ici : t(n+1)
48 double temps_defaut() const override { return temps_courant() + pas_de_temps(); }
49
50 // a surcharger si utile
51 void completer() override { /* Do nothing */ }
52
53 friend class RK3_FT; // pour trio
54 int faire_un_pas_de_temps_eqn_base(Equation_base& eq) override { return faire_un_pas_de_temps_eqn_base_generique<_ORDRE_>(eq); } // SFINAE :-)
55
56protected:
57 static constexpr int NW = 100;
58
59 inline void print_warning(const int nw)
60 {
61 Cerr << finl << "**** Advice (printed only on the first " << nw << " time steps) ****" << finl;
62 Cerr << "You are using Runge Kutta schema ! If you wish to increase the time step, try facsec between 1 and 2/3/4 (depends on the order of the scheme)." << finl;
63 }
64
65private:
66 static constexpr double SQRT2 = 1.4142135623730950488016887242096980785696718753769480731766797, SQRT2_2 = SQRT2 / 2.;
67
68 // RK low storage : See Williamson RK series https://www.sciencedirect.com/science/article/pii/0021999180900339
69 static constexpr ARR2 A2 = { 0.0, SQRT2 - 2. };
70 static constexpr ARR2 B2 = { SQRT2_2, SQRT2_2 };
71
72 static constexpr ARR3 A3 = { 0.0, -5. / 9., -153. / 128. };
73 static constexpr ARR3 B3 = { 1. / 3., 15. / 16., 8. / 15. };
74
75 static constexpr ARR3 A4 = { 0.0, -1. /2. , -2. };
76 static constexpr ARR3 B4 = { 1. / 2., 1. , 1. / 6. };
77
78 // RK CLASSIQUE : see https://en.wikipedia.org/wiki/List_of_Runge%E2%80%93Kutta_methods
79 static constexpr std::array<ARR1, 1> BUTCHER_2 = { { { 1. / 2. } } }; /* RK2 */
80 static constexpr std::array<ARR2, 2> BUTCHER_3 = { { { 1. / 2., 0. }, { -1., 2. } } }; /* RK3 */
81 static constexpr std::array<ARR3, 3> BUTCHER_4 = { { { 1. / 2., 0. , 0.}, { 0., 1. / 2., 0.}, { 0. , 0., 1. } } }; /* RK4 */
82 static constexpr std::array<ARR3, 3> BUTCHER_4_3_8 = { { { 1. / 3., 0. , 0.}, { -1. / 3., 1., 0.}, { 1. , -1., 1. } } }; /* RK4 3/8 rule */
83
84 static constexpr std::array<ARR4, 4> BUTCHER_TAB = { {
85 { 0., 1., 0., 0. }, /* RK2 classique*/
86 { 1. / 6., 2. / 3., 1. / 6., 0. }, /* RK3 classique*/
87 { 1. / 6., 1. / 3., 1. / 3., 1. / 6. }, /* RK4 classique*/
88 { 1. / 8., 3. / 8., 3. / 8., 1. / 8. } /* RK4 3/8 rule */
89 }
90 };
91
92 // SFINAE template functions
93 template<Ordre_RK _O_ = _ORDRE_, int NB>
94 std::enable_if_t<_O_ == Ordre_RK::DEUX_WILLIAMSON, std::array<double, NB>>
95 inline const get_a() { return A2; }
96
97 template<Ordre_RK _O_ = _ORDRE_, int NB>
98 std::enable_if_t<_O_ != Ordre_RK::DEUX_WILLIAMSON, std::array<double, NB>>
99 inline const get_a() { return _ORDRE_ == Ordre_RK::TROIS_WILLIAMSON ? A3 : A4; }
100
101 template<Ordre_RK _O_ = _ORDRE_, int NB>
102 std::enable_if_t<_O_ == Ordre_RK::DEUX_WILLIAMSON, std::array<double, NB>>
103 inline const get_b() { return B2; }
104
105 template<Ordre_RK _O_ = _ORDRE_, int NB>
106 std::enable_if_t<_O_ != Ordre_RK::DEUX_WILLIAMSON, std::array<double, NB>>
107 inline const get_b() { return _ORDRE_ == Ordre_RK::TROIS_WILLIAMSON ? B3 : B4; }
108
109 template<Ordre_RK _O_ = _ORDRE_>
110 std::enable_if_t<_O_ == Ordre_RK::DEUX_WILLIAMSON || _O_ == Ordre_RK::TROIS_WILLIAMSON || _O_ == Ordre_RK::QUATRE_WILLIAMSON, int>
111 faire_un_pas_de_temps_eqn_base_generique(Equation_base& eq);
112
113 template<Ordre_RK _O_ = _ORDRE_, int NB>
114 std::enable_if_t<_O_ == Ordre_RK::DEUX_CLASSIQUE, std::array<std::array<double, NB>, NB> >
115 inline const get_butcher_coeff() { return BUTCHER_2; }
116
117 template<Ordre_RK _O_ = _ORDRE_, int NB>
118 std::enable_if_t<_O_ == Ordre_RK::TROIS_CLASSIQUE, std::array<std::array<double, NB>, NB> >
119 inline const get_butcher_coeff() { return BUTCHER_3; }
120
121 template<Ordre_RK _O_ = _ORDRE_, int NB>
122 std::enable_if_t<_O_ == Ordre_RK::QUATRE_CLASSIQUE || _O_ == Ordre_RK::QUATRE_CLASSIQUE_3_8, std::array<std::array<double, NB>, NB> >
123 inline const get_butcher_coeff() { return _O_ == Ordre_RK::QUATRE_CLASSIQUE ? BUTCHER_4 : BUTCHER_4_3_8; }
124
125 template<Ordre_RK _O_ = _ORDRE_>
126 std::enable_if_t<_O_ == Ordre_RK::DEUX_CLASSIQUE || _O_ == Ordre_RK::TROIS_CLASSIQUE || _O_ == Ordre_RK::QUATRE_CLASSIQUE || _O_ == Ordre_RK::QUATRE_CLASSIQUE_3_8, int>
127 faire_un_pas_de_temps_eqn_base_generique(Equation_base& eq);
128
129 // DANGER : SHOULD NOT GO HERE
130 template<Ordre_RK _O_ = _ORDRE_> std::enable_if_t<_O_ == Ordre_RK::UN || _O_ == Ordre_RK::RATIO_DEUX, int>
131 faire_un_pas_de_temps_eqn_base_generique(Equation_base& eq) { throw; } // From VTABLE
132 DoubleTabs ki_;
133};
134
135// XXX : CAN BE REMOVED WHEN WE PASS TO C++17
136// see https://stackoverflow.com/questions/40690260/undefined-reference-error-for-static-constexpr-member
137template <Ordre_RK _ORDRE_ >
138constexpr std::array<ARR1, 1> TRUSTSchema_RK<_ORDRE_>::BUTCHER_2;
139
140template <Ordre_RK _ORDRE_ >
141constexpr std::array<ARR2, 2> TRUSTSchema_RK<_ORDRE_>::BUTCHER_3;
142
143template <Ordre_RK _ORDRE_ >
144constexpr std::array<ARR3, 3> TRUSTSchema_RK<_ORDRE_>::BUTCHER_4;
145
146template <Ordre_RK _ORDRE_ >
147constexpr std::array<ARR3, 3> TRUSTSchema_RK<_ORDRE_>::BUTCHER_4_3_8;
148
149template <Ordre_RK _ORDRE_ >
150constexpr std::array<ARR4, 4> TRUSTSchema_RK<_ORDRE_>::BUTCHER_TAB;
151
152template <Ordre_RK _ORDRE_ >
153constexpr ARR2 TRUSTSchema_RK<_ORDRE_>::A2;
154
155template <Ordre_RK _ORDRE_ >
156constexpr ARR2 TRUSTSchema_RK<_ORDRE_>::B2;
157
158template <Ordre_RK _ORDRE_ >
159constexpr ARR3 TRUSTSchema_RK<_ORDRE_>::A3;
160
161template <Ordre_RK _ORDRE_ >
162constexpr ARR3 TRUSTSchema_RK<_ORDRE_>::B3;
163
164template <Ordre_RK _ORDRE_ >
165constexpr ARR3 TRUSTSchema_RK<_ORDRE_>::A4;
166
167template <Ordre_RK _ORDRE_ >
168constexpr ARR3 TRUSTSchema_RK<_ORDRE_>::B4;
169
170#include <TRUSTSchema_RK.tpp>
171
172#endif /* TRUSTSchema_RK_included */
classe Equation_base Le role d'une equation est le calcul d'un ou plusieurs champs....
class Schema_Temps_base
double temps_courant() const
Renvoie le temps courant.
double pas_de_temps() const
Renvoie le pas de temps (delta_t) courant.
virtual int nb_valeurs_futures() const =0
virtual int nb_valeurs_temporelles() const =0
virtual double temps_defaut() const =0
virtual void completer()=0
void print_warning(const int nw)
friend class RK3_FT
static constexpr int NW