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
47
48namespace Nektar
49{
50namespace LibUtilities
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
100 std::string variant, size_t order,
101 std::vector<NekDouble> freeParams)
102 {
103 boost::ignore_unused(freeParams);
104
105 constexpr size_t nStages[6] = {0, 1, 2, 3, 4, 6};
106
107 // A Coefficients for the lower diagonal quadrant stored in a
108 // contiguous fashion. For the fourth order, six coefficients
109 // from the Butcher tableau would be stored as the following.
110 //
111 // 0 0 0 0
112 // Butcher a 0 0 0 Stored as a
113 // Tableau b c 0 0 b c
114 // d e f 0 d e f 0 ... 0
115
116 // clang-format off
117 constexpr NekDouble Acoefficients[2][6][15] =
118 { { { 0., 0., 0., 0., 0.,
119 0., 0., 0., 0., 0.,
120 0., 0., 0., 0., 0. },
121 // 1st Order
122 { 0., 0., 0., 0., 0.,
123 0., 0., 0., 0., 0.,
124 0., 0., 0., 0., 0. },
125 // 2nd Order - midpoint
126 { 1./2, // Last entry
127 0., 0., 0., 0.,
128 0., 0., 0., 0., 0.,
129 0., 0., 0., 0., 0. },
130 // 3rd Order - Ralston's
131 { 1./2.,
132 0., 3./4., // Last entry
133 0., 0.,
134 0., 0., 0., 0., 0.,
135 0., 0., 0., 0., 0. },
136 // 4th Order - Classic
137 { 1./2.,
138 0., 1./2.,
139 0., 0., 1., // Last entry
140 0., 0., 0., 0.,
141 0., 0., 0., 0., 0. },
142 // 5th Order - 6 stages
143 // Rabiei, Faranak, and Fudziah Ismail. "Fifth order improved
144 // Runge-Kutta method for solving ordinary differential
145 // equations." In Proceedings of the 11th WSEAS international
146 // conference on Applied computer science, pp. 129-133. 2011.
147 { 1./4.,
148 1./8., 1./8.,
149 0., -1./2., 1.,
150 3./16., 0., 0., 9./16.,
151 -3./7., 2./7., 12./7., -12./7., 8./7. } },
152 // Strong Stability Preserving
153 { { 0., 0., 0., 0., 0.,
154 0., 0., 0., 0., 0.,
155 0., 0., 0., 0., 0. },
156 // 1st Order
157 { 0., 0., 0., 0., 0.,
158 0., 0., 0., 0., 0.,
159 0., 0., 0., 0., 0. },
160 // 2nd Order - strong scaling - improved
161 { 1., // Last entry
162 0., 0., 0., 0.,
163 0., 0., 0., 0., 0.,
164 0., 0., 0., 0., 0. },
165 // 3rd Order - strong scaling
166 { 1.,
167 1./4., 1./4., // Last entry
168 0, 0.,
169 0., 0., 0., 0., 0.,
170 0., 0., 0., 0., 0. },
171 // 4th Order - Classic - not used
172 { 1./2.,
173 0., 1./2.,
174 0., 0., 1., // Last entry
175 0., 0., 0., 0.,
176 0., 0., 0., 0., 0. },
177 // 5th Order - 6 stages - not used
178 // Rabiei, Faranak, and Fudziah Ismail. "Fifth order improved
179 // Runge-Kutta method for solving ordinary differential
180 // equations." In Proceedings of the 11th WSEAS international
181 // conference on Applied computer science, pp. 129-133. 2011.
182 { 1./4.,
183 1./8., 1./8.,
184 0., -1./2., 1.,
185 3./16., 0., 0., 9./16.,
186 -3./7., 2./7., 12./7., -12./7., 8./7. } } };
187 // clang-format on
188
189 // B Coefficients for the final summing.
190
191 // clang-format off
192 constexpr NekDouble Bcoefficients[2][6][6] =
193 { { { 0., 0., 0., 0., 0., 0. },
194 // 1st Order
195 { 1., 0., 0., 0., 0., 0. },
196 // 2nd Order - midpoint
197 { 0., 1., 0., 0., 0., 0. },
198 // 3rd Order - Ralston's
199 { 2./9., 3./9., 4./9., 0., 0., 0. },
200 // 4th Order - Classic
201 { 1./6., 2./6., 2./6., 1./6., 0., 0. },
202 // 5th Order - 6 stages
203 // Rabiei, Faranak, and Fudziah Ismail. "Fifth order improved
204 // Runge-Kutta method for solving ordinary differential
205 // equations." In Proceedings of the 11th WSEAS international
206 // conference on Applied computer science, pp. 129-133. 2011.
207 { 7./90., 0., 32./90., 12./90., 32./90., 7./90.} },
208 // Strong Stability Preserving
209 { { 0., 0., 0., 0., 0., 0. },
210 // 1st Order
211 { 1., 0., 0., 0., 0., 0. },
212 // 2nd Order - improved
213 { 1./2., 1./2., 0., 0., 0., 0. },
214 // 3rd Order - strong scaling
215 { 1./6., 1./6., 4./6., 0., 0., 0. },
216 // 4th Order - Classic - not used
217 { 1./6., 2./6., 2./6., 1./6., 0., 0. },
218 // 5th Order - 6 stages - not used
219 // Rabiei, Faranak, and Fudziah Ismail. "Fifth order improved
220 // Runge-Kutta method for solving ordinary differential
221 // equations." In Proceedings of the 11th WSEAS international
222 // conference on Applied computer science, pp. 129-133. 2011.
223 { 7./90., 0., 32./90., 12./90., 32./90., 7./90. } } };
224 // clang-format on
225
226 size_t index = (variant == "SSP" || variant == "ImprovedEuler");
227
228 phase->m_schemeType = eExplicit;
229 phase->m_variant = variant;
230 phase->m_order = order;
231 phase->m_name = std::string("RungeKutta") + phase->m_variant +
232 std::string("Order") + std::to_string(phase->m_order);
233
234 phase->m_numsteps = 1;
235 phase->m_numstages = nStages[phase->m_order];
236
237 phase->m_A = Array<OneD, Array<TwoD, NekDouble>>(1);
238 phase->m_B = Array<OneD, Array<TwoD, NekDouble>>(1);
239
240 phase->m_A[0] =
241 Array<TwoD, NekDouble>(phase->m_numstages, phase->m_numstages, 0.0);
242 phase->m_B[0] =
243 Array<TwoD, NekDouble>(phase->m_numsteps, phase->m_numstages, 0.0);
244 phase->m_U =
245 Array<TwoD, NekDouble>(phase->m_numstages, phase->m_numsteps, 1.0);
246 phase->m_V =
247 Array<TwoD, NekDouble>(phase->m_numsteps, phase->m_numsteps, 1.0);
248
249 // Coefficients
250
251 // A Coefficients for each stages along the lower diagonal quadrant.
252 size_t cc = 0;
253
254 for (size_t s = 1; s < phase->m_numstages; ++s)
255 {
256 for (size_t i = 0; i < s; ++i)
257 {
258 phase->m_A[0][s][i] =
259 Acoefficients[index][phase->m_order][cc++];
260 }
261 }
262
263 // B Coefficients for the finial summing.
264 for (size_t n = 0; n < phase->m_numstages; ++n)
265 {
266 phase->m_B[0][0][n] = Bcoefficients[index][phase->m_order][n];
267 }
268
269 phase->m_numMultiStepValues = 1;
270 phase->m_numMultiStepImplicitDerivs = 0;
271 phase->m_numMultiStepExplicitDerivs = 0;
272 phase->m_timeLevelOffset = Array<OneD, size_t>(phase->m_numsteps);
273 phase->m_timeLevelOffset[0] = 0;
274
275 phase->CheckAndVerify();
276 }
277
278protected:
279 LUE virtual std::string v_GetName() const override
280 {
281 return std::string("RungeKutta");
282 }
283
284 LUE virtual NekDouble v_GetTimeStability() const override
285 {
286 if (GetOrder() == 1 || GetOrder() == 2)
287 {
288 return 2.0;
289 }
290 else if (GetOrder() == 3)
291 {
292 return 2.51274532661833;
293 }
294 else if (GetOrder() == 4)
295 {
296 // return 2.78529356340528;
297 return 2.784;
298 }
299 else if (GetOrder() == 5)
300 {
301 return 3.21704786664011;
302 }
303 else
304 {
305 return 2.0;
306 }
307 }
308
309}; // end class RungeKuttaTimeIntegrator
310
311////////////////////////////////////////////////////////////////////////////////
312// Backwards compatibility
314{
315public:
316 RungeKutta1TimeIntegrationScheme(std::string variant, size_t order,
317 std::vector<NekDouble> freeParams)
318 : RungeKuttaTimeIntegrationScheme("", 1, freeParams)
319 {
320 boost::ignore_unused(variant);
321 boost::ignore_unused(order);
322 }
323
325 std::string variant, size_t order, std::vector<NekDouble> freeParams)
326 {
327 boost::ignore_unused(variant);
328 boost::ignore_unused(order);
329
332 "", 1, freeParams);
333 return p;
334 }
335
336 static std::string className;
337
338protected:
340
341}; // end class RungeKutta1TimeIntegrationScheme
342
344{
345public:
346 RungeKutta2TimeIntegrationScheme(std::string variant, size_t order,
347 std::vector<NekDouble> freeParams)
348 : RungeKuttaTimeIntegrationScheme("", 2, freeParams)
349 {
350 boost::ignore_unused(variant);
351 boost::ignore_unused(order);
352 }
353
355 std::string variant, size_t order, std::vector<NekDouble> freeParams)
356 {
357 boost::ignore_unused(variant);
358 boost::ignore_unused(order);
359
362 "", 2, freeParams);
363 return p;
364 }
365
366 static std::string className;
367
368protected:
370
371}; // end class RungeKutta2TimeIntegrationScheme
372
374{
375public:
376 RungeKutta3TimeIntegrationScheme(std::string variant, size_t order,
377 std::vector<NekDouble> freeParams)
378 : RungeKuttaTimeIntegrationScheme("", 3, freeParams)
379 {
380 boost::ignore_unused(variant);
381 boost::ignore_unused(order);
382 }
383
385 std::string variant, size_t order, std::vector<NekDouble> freeParams)
386 {
387 boost::ignore_unused(variant);
388 boost::ignore_unused(order);
389
392 "", 3, freeParams);
393 return p;
394 }
395
396 static std::string className;
397
398protected:
400
401}; // end class RungeKutta3TimeIntegrationScheme
402
405{
406public:
407 ClassicalRungeKutta4TimeIntegrationScheme(std::string variant, size_t order,
408 std::vector<NekDouble> freeParams)
409 : RungeKuttaTimeIntegrationScheme("", 4, freeParams)
410 {
411 boost::ignore_unused(variant);
412 boost::ignore_unused(order);
413 }
414
416 std::string variant, size_t order, std::vector<NekDouble> freeParams)
417 {
418 boost::ignore_unused(variant);
419 boost::ignore_unused(order);
420
423 "", 4, freeParams);
424 return p;
425 }
426
427 static std::string className;
428
429protected:
431
432}; // end class ClassicalRungeKutta4TimeIntegrationScheme
433
436{
437public:
438 RungeKutta4TimeIntegrationScheme(std::string variant, size_t order,
439 std::vector<NekDouble> freeParams)
440 : ClassicalRungeKutta4TimeIntegrationScheme(variant, order, freeParams)
441 {
442 }
443
444 static std::string className;
445
446protected:
448
449}; // end class RungeKutta4TimeIntegrationScheme
450
452{
453public:
454 RungeKutta5TimeIntegrationScheme(std::string variant, size_t order,
455 std::vector<NekDouble> freeParams)
456 : RungeKuttaTimeIntegrationScheme("", 5, freeParams)
457 {
458 boost::ignore_unused(variant);
459 boost::ignore_unused(order);
460 }
461
463 std::string variant, size_t order, std::vector<NekDouble> freeParams)
464 {
465 boost::ignore_unused(variant);
466 boost::ignore_unused(order);
467
470 "", 5, freeParams);
471 return p;
472 }
473
474 static std::string className;
475
476protected:
478
479}; // end class RungeKutta5TimeIntegrationScheme
480
483{
484public:
486 std::string variant, size_t order, std::vector<NekDouble> freeParams)
487 : RungeKuttaTimeIntegrationScheme("SSP", 2, freeParams)
488 {
489 boost::ignore_unused(variant);
490 boost::ignore_unused(order);
491 }
492
494 std::string variant, size_t order, std::vector<NekDouble> freeParams)
495 {
496 boost::ignore_unused(variant);
497 boost::ignore_unused(order);
498
501 "SSP", 2, freeParams);
502 return p;
503 }
504
505 static std::string className;
506
507protected:
509
510}; // end class RungeKutta2_ImprovedEulerTimeIntegrationScheme
511
514{
515public:
516 RungeKutta2_SSPTimeIntegrationScheme(std::string variant, size_t order,
517 std::vector<NekDouble> freeParams)
518 : RungeKuttaTimeIntegrationScheme("SSP", 2, freeParams)
519 {
520 boost::ignore_unused(variant);
521 boost::ignore_unused(order);
522 }
523
525 std::string variant, size_t order, std::vector<NekDouble> freeParams)
526 {
527 boost::ignore_unused(variant);
528 boost::ignore_unused(order);
529
532 "SSP", 2, freeParams);
533 return p;
534 }
535
536 static std::string className;
537
538protected:
540
541}; // end class RungeKutta2_SSPTimeIntegrationScheme
542
545{
546public:
547 RungeKutta3_SSPTimeIntegrationScheme(std::string variant, size_t order,
548 std::vector<NekDouble> freeParams)
549 : RungeKuttaTimeIntegrationScheme("SSP", 3, freeParams)
550 {
551 boost::ignore_unused(variant);
552 boost::ignore_unused(order);
553 }
554
556 std::string variant, size_t order, std::vector<NekDouble> freeParams)
557 {
558 boost::ignore_unused(variant);
559 boost::ignore_unused(order);
560
563 "SSP", 3, freeParams);
564 return p;
565 }
566
567 static std::string className;
568
569protected:
571
572}; // end class RungeKutta3_SSPTimeIntegrationScheme
573
574} // end namespace LibUtilities
575} // end namespace Nektar
576
577#endif
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:249
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
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
double NekDouble