Nektar++
RungeKuttaTimeIntegrationSchemes.h
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: RungeKuttaTimeIntegrationSchemes.h
4//
5// For more information, please see: http://www.nektar.info
6//
7// The MIT License
8//
9// Copyright (c) 2018 Division of Applied Mathematics, Brown University (USA),
10// Department of Aeronautics, Imperial College London (UK), and Scientific
11// Computing and Imaging Institute, University of Utah (USA).
12//
13// License for the specific language governing rights and limitations under
14// Permission is hereby granted, free of charge, to any person obtaining a
15// copy of this software and associated documentation files (the "Software"),
16// to deal in the Software without restriction, including without limitation
17// the rights to use, copy, modify, merge, publish, distribute, sublicense,
18// and/or sell copies of the Software, and to permit persons to whom the
19// Software is furnished to do so, subject to the following conditions:
20//
21// The above copyright notice and this permission notice shall be included
22// in all copies or substantial portions of the Software.
23//
24// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30// DEALINGS IN THE SOFTWARE.
31//
32// Description: Combined header file for all Runge Kutta based time integration
33// schemes.
34//
35///////////////////////////////////////////////////////////////////////////////
36
37// Note : If adding a new integrator be sure to register the
38// integrator with the Time Integration Scheme Facatory in
39// SchemeInitializor.cpp.
40
41#ifndef NEKTAR_LIB_UTILITIES_TIME_INTEGRATION_RK_TIME_INTEGRATION_SCHEME
42#define NEKTAR_LIB_UTILITIES_TIME_INTEGRATION_RK_TIME_INTEGRATION_SCHEME
43
44#define LUE LIB_UTILITIES_EXPORT
45
46#include <boost/core/ignore_unused.hpp>
47
49
51{
52
53////////////////////////////////////////////////////////////////////////////////
54// Runge Kutta Order N where the number of stages == order
55
57{
58public:
59 RungeKuttaTimeIntegrationScheme(std::string variant, size_t order,
60 std::vector<NekDouble> freeParams)
61 : TimeIntegrationSchemeGLM(variant, order, freeParams)
62 {
63 ASSERTL1(variant == "" || variant == "SSP",
64 "Runge Kutta Time integration scheme unknown variant: " +
65 variant + ". Must be blank or 'SSP'");
66
67 // Std - Currently up to 5th order is implemented.
68 // SSP - Currently 1st through 3rd order is implemented.
69 ASSERTL1((variant == "" && 1 <= order && order <= 5) ||
70 (variant == "SSP" && 1 <= order && order <= 3),
71 "Runge Kutta Time integration scheme bad order, "
72 "Std (1-5) or SSP (1-3): " +
73 std::to_string(order));
74
78
80 m_integration_phases[0], variant, order, freeParams);
81 }
82
84 {
85 }
86
88 std::string variant, size_t order, std::vector<NekDouble> freeParams)
89 {
92 variant, order, freeParams);
93
94 return p;
95 }
96
97 static std::string className;
98
99 LUE static void SetupSchemeData(
100 TimeIntegrationAlgorithmGLMSharedPtr &phase, std::string variant,
101 size_t order, [[maybe_unused]] std::vector<NekDouble> freeParams)
102 {
103 constexpr size_t nStages[6] = {0, 1, 2, 3, 4, 6};
104
105 // A Coefficients for the lower diagonal quadrant stored in a
106 // contiguous fashion. For the fourth order, six coefficients
107 // from the Butcher tableau would be stored as the following.
108 //
109 // 0 0 0 0
110 // Butcher a 0 0 0 Stored as a
111 // Tableau b c 0 0 b c
112 // d e f 0 d e f 0 ... 0
113
114 // clang-format off
115 constexpr NekDouble Acoefficients[2][6][15] =
116 { { { 0., 0., 0., 0., 0.,
117 0., 0., 0., 0., 0.,
118 0., 0., 0., 0., 0. },
119 // 1st Order
120 { 0., 0., 0., 0., 0.,
121 0., 0., 0., 0., 0.,
122 0., 0., 0., 0., 0. },
123 // 2nd Order - midpoint
124 { 1./2, // Last entry
125 0., 0., 0., 0.,
126 0., 0., 0., 0., 0.,
127 0., 0., 0., 0., 0. },
128 // 3rd Order - Ralston's
129 { 1./2.,
130 0., 3./4., // Last entry
131 0., 0.,
132 0., 0., 0., 0., 0.,
133 0., 0., 0., 0., 0. },
134 // 4th Order - Classic
135 { 1./2.,
136 0., 1./2.,
137 0., 0., 1., // Last entry
138 0., 0., 0., 0.,
139 0., 0., 0., 0., 0. },
140 // 5th Order - 6 stages
141 // Rabiei, Faranak, and Fudziah Ismail. "Fifth order improved
142 // Runge-Kutta method for solving ordinary differential
143 // equations." In Proceedings of the 11th WSEAS international
144 // conference on Applied computer science, pp. 129-133. 2011.
145 { 1./4.,
146 1./8., 1./8.,
147 0., -1./2., 1.,
148 3./16., 0., 0., 9./16.,
149 -3./7., 2./7., 12./7., -12./7., 8./7. } },
150 // Strong Stability Preserving
151 { { 0., 0., 0., 0., 0.,
152 0., 0., 0., 0., 0.,
153 0., 0., 0., 0., 0. },
154 // 1st Order
155 { 0., 0., 0., 0., 0.,
156 0., 0., 0., 0., 0.,
157 0., 0., 0., 0., 0. },
158 // 2nd Order - strong scaling - improved
159 { 1., // Last entry
160 0., 0., 0., 0.,
161 0., 0., 0., 0., 0.,
162 0., 0., 0., 0., 0. },
163 // 3rd Order - strong scaling
164 { 1.,
165 1./4., 1./4., // Last entry
166 0, 0.,
167 0., 0., 0., 0., 0.,
168 0., 0., 0., 0., 0. },
169 // 4th Order - Classic - not used
170 { 1./2.,
171 0., 1./2.,
172 0., 0., 1., // Last entry
173 0., 0., 0., 0.,
174 0., 0., 0., 0., 0. },
175 // 5th Order - 6 stages - not used
176 // Rabiei, Faranak, and Fudziah Ismail. "Fifth order improved
177 // Runge-Kutta method for solving ordinary differential
178 // equations." In Proceedings of the 11th WSEAS international
179 // conference on Applied computer science, pp. 129-133. 2011.
180 { 1./4.,
181 1./8., 1./8.,
182 0., -1./2., 1.,
183 3./16., 0., 0., 9./16.,
184 -3./7., 2./7., 12./7., -12./7., 8./7. } } };
185 // clang-format on
186
187 // B Coefficients for the final summing.
188
189 // clang-format off
190 constexpr NekDouble Bcoefficients[2][6][6] =
191 { { { 0., 0., 0., 0., 0., 0. },
192 // 1st Order
193 { 1., 0., 0., 0., 0., 0. },
194 // 2nd Order - midpoint
195 { 0., 1., 0., 0., 0., 0. },
196 // 3rd Order - Ralston's
197 { 2./9., 3./9., 4./9., 0., 0., 0. },
198 // 4th Order - Classic
199 { 1./6., 2./6., 2./6., 1./6., 0., 0. },
200 // 5th Order - 6 stages
201 // Rabiei, Faranak, and Fudziah Ismail. "Fifth order improved
202 // Runge-Kutta method for solving ordinary differential
203 // equations." In Proceedings of the 11th WSEAS international
204 // conference on Applied computer science, pp. 129-133. 2011.
205 { 7./90., 0., 32./90., 12./90., 32./90., 7./90.} },
206 // Strong Stability Preserving
207 { { 0., 0., 0., 0., 0., 0. },
208 // 1st Order
209 { 1., 0., 0., 0., 0., 0. },
210 // 2nd Order - improved
211 { 1./2., 1./2., 0., 0., 0., 0. },
212 // 3rd Order - strong scaling
213 { 1./6., 1./6., 4./6., 0., 0., 0. },
214 // 4th Order - Classic - not used
215 { 1./6., 2./6., 2./6., 1./6., 0., 0. },
216 // 5th Order - 6 stages - not used
217 // Rabiei, Faranak, and Fudziah Ismail. "Fifth order improved
218 // Runge-Kutta method for solving ordinary differential
219 // equations." In Proceedings of the 11th WSEAS international
220 // conference on Applied computer science, pp. 129-133. 2011.
221 { 7./90., 0., 32./90., 12./90., 32./90., 7./90. } } };
222 // clang-format on
223
224 size_t index = (variant == "SSP" || variant == "ImprovedEuler");
225
226 phase->m_schemeType = eExplicit;
227 phase->m_variant = variant;
228 phase->m_order = order;
229 phase->m_name = std::string("RungeKutta") + phase->m_variant +
230 std::string("Order") + std::to_string(phase->m_order);
231
232 phase->m_numsteps = 1;
233 phase->m_numstages = nStages[phase->m_order];
234
235 phase->m_A = Array<OneD, Array<TwoD, NekDouble>>(1);
236 phase->m_B = Array<OneD, Array<TwoD, NekDouble>>(1);
237
238 phase->m_A[0] =
239 Array<TwoD, NekDouble>(phase->m_numstages, phase->m_numstages, 0.0);
240 phase->m_B[0] =
241 Array<TwoD, NekDouble>(phase->m_numsteps, phase->m_numstages, 0.0);
242 phase->m_U =
243 Array<TwoD, NekDouble>(phase->m_numstages, phase->m_numsteps, 1.0);
244 phase->m_V =
245 Array<TwoD, NekDouble>(phase->m_numsteps, phase->m_numsteps, 1.0);
246
247 // Coefficients
248
249 // A Coefficients for each stages along the lower diagonal quadrant.
250 size_t cc = 0;
251
252 for (size_t s = 1; s < phase->m_numstages; ++s)
253 {
254 for (size_t i = 0; i < s; ++i)
255 {
256 phase->m_A[0][s][i] =
257 Acoefficients[index][phase->m_order][cc++];
258 }
259 }
260
261 // B Coefficients for the finial summing.
262 for (size_t n = 0; n < phase->m_numstages; ++n)
263 {
264 phase->m_B[0][0][n] = Bcoefficients[index][phase->m_order][n];
265 }
266
267 phase->m_numMultiStepValues = 1;
268 phase->m_numMultiStepImplicitDerivs = 0;
269 phase->m_numMultiStepExplicitDerivs = 0;
270 phase->m_timeLevelOffset = Array<OneD, size_t>(phase->m_numsteps);
271 phase->m_timeLevelOffset[0] = 0;
272
273 phase->CheckAndVerify();
274 }
275
276protected:
277 LUE std::string v_GetName() const override
278 {
279 return std::string("RungeKutta");
280 }
281
283 {
284 if (GetOrder() == 1 || GetOrder() == 2)
285 {
286 return 2.0;
287 }
288 else if (GetOrder() == 3)
289 {
290 return 2.51274532661833;
291 }
292 else if (GetOrder() == 4)
293 {
294 // return 2.78529356340528;
295 return 2.784;
296 }
297 else if (GetOrder() == 5)
298 {
299 return 3.21704786664011;
300 }
301 else
302 {
303 return 2.0;
304 }
305 }
306
307}; // end class RungeKuttaTimeIntegrator
308
309////////////////////////////////////////////////////////////////////////////////
310// Backwards compatibility
312{
313public:
314 RungeKutta1TimeIntegrationScheme(std::string variant, size_t order,
315 std::vector<NekDouble> freeParams)
316 : RungeKuttaTimeIntegrationScheme("", 1, freeParams)
317 {
318 boost::ignore_unused(variant, order);
319 }
320
322 [[maybe_unused]] std::string variant, [[maybe_unused]] size_t order,
323 std::vector<NekDouble> freeParams)
324 {
327 "", 1, freeParams);
328 return p;
329 }
330
331 static std::string className;
332
333protected:
335
336}; // end class RungeKutta1TimeIntegrationScheme
337
339{
340public:
341 RungeKutta2TimeIntegrationScheme(std::string variant, size_t order,
342 std::vector<NekDouble> freeParams)
343 : RungeKuttaTimeIntegrationScheme("", 2, freeParams)
344 {
345 boost::ignore_unused(variant, order);
346 }
347
349 [[maybe_unused]] std::string variant, [[maybe_unused]] size_t order,
350 std::vector<NekDouble> freeParams)
351 {
354 "", 2, freeParams);
355 return p;
356 }
357
358 static std::string className;
359
360protected:
362
363}; // end class RungeKutta2TimeIntegrationScheme
364
366{
367public:
368 RungeKutta3TimeIntegrationScheme(std::string variant, size_t order,
369 std::vector<NekDouble> freeParams)
370 : RungeKuttaTimeIntegrationScheme("", 3, freeParams)
371 {
372 boost::ignore_unused(variant, order);
373 }
374
376 [[maybe_unused]] std::string variant, [[maybe_unused]] size_t order,
377 std::vector<NekDouble> freeParams)
378 {
381 "", 3, freeParams);
382 return p;
383 }
384
385 static std::string className;
386
387protected:
389
390}; // end class RungeKutta3TimeIntegrationScheme
391
394{
395public:
396 ClassicalRungeKutta4TimeIntegrationScheme(std::string variant, size_t order,
397 std::vector<NekDouble> freeParams)
398 : RungeKuttaTimeIntegrationScheme("", 4, freeParams)
399 {
400 boost::ignore_unused(variant, order);
401 }
402
404 [[maybe_unused]] std::string variant, [[maybe_unused]] size_t order,
405 std::vector<NekDouble> freeParams)
406 {
409 "", 4, freeParams);
410 return p;
411 }
412
413 static std::string className;
414
415protected:
417
418}; // end class ClassicalRungeKutta4TimeIntegrationScheme
419
422{
423public:
424 RungeKutta4TimeIntegrationScheme(std::string variant, size_t order,
425 std::vector<NekDouble> freeParams)
426 : ClassicalRungeKutta4TimeIntegrationScheme(variant, order, freeParams)
427 {
428 }
429
430 static std::string className;
431
432protected:
434
435}; // end class RungeKutta4TimeIntegrationScheme
436
438{
439public:
440 RungeKutta5TimeIntegrationScheme(std::string variant, size_t order,
441 std::vector<NekDouble> freeParams)
442 : RungeKuttaTimeIntegrationScheme("", 5, freeParams)
443 {
444 boost::ignore_unused(variant, order);
445 }
446
448 [[maybe_unused]] std::string variant, [[maybe_unused]] size_t order,
449 std::vector<NekDouble> freeParams)
450 {
453 "", 5, freeParams);
454 return p;
455 }
456
457 static std::string className;
458
459protected:
461
462}; // end class RungeKutta5TimeIntegrationScheme
463
466{
467public:
469 std::string variant, size_t order, std::vector<NekDouble> freeParams)
470 : RungeKuttaTimeIntegrationScheme("SSP", 2, freeParams)
471 {
472 boost::ignore_unused(variant, order);
473 }
474
476 [[maybe_unused]] std::string variant, [[maybe_unused]] size_t order,
477 std::vector<NekDouble> freeParams)
478 {
481 "SSP", 2, freeParams);
482 return p;
483 }
484
485 static std::string className;
486
487protected:
489
490}; // end class RungeKutta2_ImprovedEulerTimeIntegrationScheme
491
494{
495public:
496 RungeKutta2_SSPTimeIntegrationScheme(std::string variant, size_t order,
497 std::vector<NekDouble> freeParams)
498 : RungeKuttaTimeIntegrationScheme("SSP", 2, freeParams)
499 {
500 boost::ignore_unused(variant, order);
501 }
502
504 [[maybe_unused]] std::string variant, [[maybe_unused]] size_t order,
505 std::vector<NekDouble> freeParams)
506 {
509 "SSP", 2, freeParams);
510 return p;
511 }
512
513 static std::string className;
514
515protected:
517
518}; // end class RungeKutta2_SSPTimeIntegrationScheme
519
522{
523public:
524 RungeKutta3_SSPTimeIntegrationScheme(std::string variant, size_t order,
525 std::vector<NekDouble> freeParams)
526 : RungeKuttaTimeIntegrationScheme("SSP", 3, freeParams)
527 {
528 boost::ignore_unused(variant, order);
529 }
530
532 [[maybe_unused]] std::string variant, [[maybe_unused]] size_t order,
533 std::vector<NekDouble> freeParams)
534 {
537 "SSP", 3, freeParams);
538 return p;
539 }
540
541 static std::string className;
542
543protected:
545
546}; // end class RungeKutta3_SSPTimeIntegrationScheme
547
548} // namespace Nektar::LibUtilities
549
550#endif
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:242
ClassicalRungeKutta4TimeIntegrationScheme(std::string variant, size_t order, std::vector< NekDouble > freeParams)
static TimeIntegrationSchemeSharedPtr create(std::string variant, size_t order, std::vector< NekDouble > freeParams)
RungeKutta1TimeIntegrationScheme(std::string variant, size_t order, std::vector< NekDouble > freeParams)
static TimeIntegrationSchemeSharedPtr create(std::string variant, size_t order, std::vector< NekDouble > freeParams)
static TimeIntegrationSchemeSharedPtr create(std::string variant, size_t order, std::vector< NekDouble > freeParams)
RungeKutta2_ImprovedEulerTimeIntegrationScheme(std::string variant, size_t order, std::vector< NekDouble > freeParams)
static TimeIntegrationSchemeSharedPtr create(std::string variant, size_t order, std::vector< NekDouble > freeParams)
RungeKutta2_SSPTimeIntegrationScheme(std::string variant, size_t order, std::vector< NekDouble > freeParams)
static TimeIntegrationSchemeSharedPtr create(std::string variant, size_t order, std::vector< NekDouble > freeParams)
RungeKutta2TimeIntegrationScheme(std::string variant, size_t order, std::vector< NekDouble > freeParams)
static TimeIntegrationSchemeSharedPtr create(std::string variant, size_t order, std::vector< NekDouble > freeParams)
RungeKutta3_SSPTimeIntegrationScheme(std::string variant, size_t order, std::vector< NekDouble > freeParams)
RungeKutta3TimeIntegrationScheme(std::string variant, size_t order, std::vector< NekDouble > freeParams)
static TimeIntegrationSchemeSharedPtr create(std::string variant, size_t order, std::vector< NekDouble > freeParams)
RungeKutta4TimeIntegrationScheme(std::string variant, size_t order, std::vector< NekDouble > freeParams)
RungeKutta5TimeIntegrationScheme(std::string variant, size_t order, std::vector< NekDouble > freeParams)
static TimeIntegrationSchemeSharedPtr create(std::string variant, size_t order, std::vector< NekDouble > freeParams)
static LUE void SetupSchemeData(TimeIntegrationAlgorithmGLMSharedPtr &phase, std::string variant, size_t order, std::vector< NekDouble > freeParams)
static TimeIntegrationSchemeSharedPtr create(std::string variant, size_t order, std::vector< NekDouble > freeParams)
RungeKuttaTimeIntegrationScheme(std::string variant, size_t order, std::vector< NekDouble > freeParams)
Base class for GLM time integration schemes.
TimeIntegrationAlgorithmGLMVector m_integration_phases
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
std::shared_ptr< TimeIntegrationAlgorithmGLM > TimeIntegrationAlgorithmGLMSharedPtr
@ eExplicit
Formally explicit scheme.
std::vector< TimeIntegrationAlgorithmGLMSharedPtr > TimeIntegrationAlgorithmGLMVector
std::shared_ptr< TimeIntegrationScheme > TimeIntegrationSchemeSharedPtr
double NekDouble