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 
48 
49 namespace Nektar
50 {
51 namespace LibUtilities
52 {
53 
54 ////////////////////////////////////////////////////////////////////////////////
55 // Runge Kutta Order N where the number of stages == order
56 
58 {
59 public:
60  RungeKuttaTimeIntegrationScheme(std::string variant, unsigned int order,
61  std::vector<NekDouble> freeParams)
62  : TimeIntegrationSchemeGLM(variant, order, freeParams)
63  {
64  ASSERTL1(variant == "" || variant == "SSP",
65  "Runge Kutta Time integration scheme unknown variant: " +
66  variant + ". Must be blank or 'SSP'");
67 
68  // Std - Currently up to 5th order is implemented.
69  // SSP - Currently 1st through 3rd order is implemented.
70  ASSERTL1((variant == "" && 1 <= order && order <= 5) ||
71  (variant == "SSP" && 1 <= order && order <= 3),
72  "Runge Kutta Time integration scheme bad order, "
73  "Std (1-5) or SSP (1-3): " +
74  std::to_string(order));
75 
78  new TimeIntegrationAlgorithmGLM(this));
79 
81  m_integration_phases[0], variant, order, freeParams);
82  }
83 
85  {
86  }
87 
89  std::string variant, unsigned int order,
90  std::vector<NekDouble> freeParams)
91  {
94  variant, order, freeParams);
95 
96  return p;
97  }
98 
99  static std::string className;
100 
102  std::string variant, unsigned int order,
103  std::vector<NekDouble> freeParams)
104  {
105  boost::ignore_unused(freeParams);
106 
107  const unsigned int nStages[6] = {0, 1, 2, 3, 4, 6};
108 
109  // A Coefficients for the lower diagonal quadrant stored in a
110  // contiguous fashion. For the fourth order, six coefficients
111  // from the Butcher tableau would be stored as the following.
112  //
113  // 0 0 0 0
114  // Butcher a 0 0 0 Stored as a
115  // Tableau b c 0 0 b c
116  // d e f 0 d e f 0 ... 0
117 
118  // clang-format off
119  const NekDouble Acoefficients[2][6][15] =
120  { { { 0., 0., 0., 0., 0.,
121  0., 0., 0., 0., 0.,
122  0., 0., 0., 0., 0. },
123  // 1st Order
124  { 0., 0., 0., 0., 0.,
125  0., 0., 0., 0., 0.,
126  0., 0., 0., 0., 0. },
127  // 2nd Order - midpoint
128  { 1./2, // Last entry
129  0., 0., 0., 0.,
130  0., 0., 0., 0., 0.,
131  0., 0., 0., 0., 0. },
132  // 3rd Order - Ralston's
133  { 1./2.,
134  0., 3./4., // Last entry
135  0., 0.,
136  0., 0., 0., 0., 0.,
137  0., 0., 0., 0., 0. },
138  // 4th Order - Classic
139  { 1./2.,
140  0., 1./2.,
141  0., 0., 1., // Last entry
142  0., 0., 0., 0.,
143  0., 0., 0., 0., 0. },
144  // 5th Order - 6 stages
145  // Rabiei, Faranak, and Fudziah Ismail. "Fifth order improved
146  // Runge-Kutta method for solving ordinary differential
147  // equations." In Proceedings of the 11th WSEAS international
148  // conference on Applied computer science, pp. 129-133. 2011.
149  { 1./4.,
150  1./8., 1./8.,
151  0., -1./2., 1.,
152  3./16., 0., 0., 9./16.,
153  -3./7., 2./7., 12./7., -12./7., 8./7. } },
154  // Strong Stability Preserving
155  { { 0., 0., 0., 0., 0.,
156  0., 0., 0., 0., 0.,
157  0., 0., 0., 0., 0. },
158  // 1st Order
159  { 0., 0., 0., 0., 0.,
160  0., 0., 0., 0., 0.,
161  0., 0., 0., 0., 0. },
162  // 2nd Order - strong scaling - improved
163  { 1., // Last entry
164  0., 0., 0., 0.,
165  0., 0., 0., 0., 0.,
166  0., 0., 0., 0., 0. },
167  // 3rd Order - strong scaling
168  { 1.,
169  1./4., 1./4., // Last entry
170  0, 0.,
171  0., 0., 0., 0., 0.,
172  0., 0., 0., 0., 0. },
173  // 4th Order - Classic - not used
174  { 1./2.,
175  0., 1./2.,
176  0., 0., 1., // Last entry
177  0., 0., 0., 0.,
178  0., 0., 0., 0., 0. },
179  // 5th Order - 6 stages - not used
180  // Rabiei, Faranak, and Fudziah Ismail. "Fifth order improved
181  // Runge-Kutta method for solving ordinary differential
182  // equations." In Proceedings of the 11th WSEAS international
183  // conference on Applied computer science, pp. 129-133. 2011.
184  { 1./4.,
185  1./8., 1./8.,
186  0., -1./2., 1.,
187  3./16., 0., 0., 9./16.,
188  -3./7., 2./7., 12./7., -12./7., 8./7. } } };
189  // clang-format on
190 
191  // B Coefficients for the final summing.
192 
193  // clang-format off
194  const NekDouble Bcoefficients[2][6][6] =
195  { { { 0., 0., 0., 0., 0., 0. },
196  // 1st Order
197  { 1., 0., 0., 0., 0., 0. },
198  // 2nd Order - midpoint
199  { 0., 1., 0., 0., 0., 0. },
200  // 3rd Order - Ralston's
201  { 2./9., 3./9., 4./9., 0., 0., 0. },
202  // 4th Order - Classic
203  { 1./6., 2./6., 2./6., 1./6., 0., 0. },
204  // 5th Order - 6 stages
205  // Rabiei, Faranak, and Fudziah Ismail. "Fifth order improved
206  // Runge-Kutta method for solving ordinary differential
207  // equations." In Proceedings of the 11th WSEAS international
208  // conference on Applied computer science, pp. 129-133. 2011.
209  { 7./90., 0., 32./90., 12./90., 32./90., 7./90.} },
210  // Strong Stability Preserving
211  { { 0., 0., 0., 0., 0., 0. },
212  // 1st Order
213  { 1., 0., 0., 0., 0., 0. },
214  // 2nd Order - improved
215  { 1./2., 1./2., 0., 0., 0., 0. },
216  // 3rd Order - strong scaling
217  { 1./6., 1./6., 4./6., 0., 0., 0. },
218  // 4th Order - Classic - not used
219  { 1./6., 2./6., 2./6., 1./6., 0., 0. },
220  // 5th Order - 6 stages - not used
221  // Rabiei, Faranak, and Fudziah Ismail. "Fifth order improved
222  // Runge-Kutta method for solving ordinary differential
223  // equations." In Proceedings of the 11th WSEAS international
224  // conference on Applied computer science, pp. 129-133. 2011.
225  { 7./90., 0., 32./90., 12./90., 32./90., 7./90. } } };
226  // clang-format on
227 
228  unsigned int index = (variant == "SSP" || variant == "ImprovedEuler");
229 
230  phase->m_schemeType = eExplicit;
231  phase->m_variant = variant;
232  phase->m_order = order;
233  phase->m_name = std::string("RungeKutta") + phase->m_variant +
234  std::string("Order") + std::to_string(phase->m_order);
235 
236  phase->m_numsteps = 1;
237  phase->m_numstages = nStages[phase->m_order];
238 
239  phase->m_A = Array<OneD, Array<TwoD, NekDouble>>(1);
240  phase->m_B = Array<OneD, Array<TwoD, NekDouble>>(1);
241 
242  phase->m_A[0] =
243  Array<TwoD, NekDouble>(phase->m_numstages, phase->m_numstages, 0.0);
244  phase->m_B[0] =
245  Array<TwoD, NekDouble>(phase->m_numsteps, phase->m_numstages, 0.0);
246  phase->m_U =
247  Array<TwoD, NekDouble>(phase->m_numstages, phase->m_numsteps, 1.0);
248  phase->m_V =
249  Array<TwoD, NekDouble>(phase->m_numsteps, phase->m_numsteps, 1.0);
250 
251  // Coefficients
252 
253  // A Coefficients for each stages along the lower diagonal quadrant.
254  unsigned int cc = 0;
255 
256  for (int s = 1; s < phase->m_numstages; ++s)
257  {
258  for (int i = 0; i < s; ++i)
259  {
260  phase->m_A[0][s][i] =
261  Acoefficients[index][phase->m_order][cc++];
262  }
263  }
264 
265  // B Coefficients for the finial summing.
266  for (int n = 0; n < phase->m_numstages; ++n)
267  {
268  phase->m_B[0][0][n] = Bcoefficients[index][phase->m_order][n];
269  }
270 
271  phase->m_numMultiStepValues = 1;
272  phase->m_numMultiStepImplicitDerivs = 0;
273  phase->m_numMultiStepDerivs = 0;
274  phase->m_timeLevelOffset = Array<OneD, unsigned int>(phase->m_numsteps);
275  phase->m_timeLevelOffset[0] = 0;
276 
277  phase->CheckAndVerify();
278  }
279 
280 protected:
281  LUE virtual std::string v_GetName() const override
282  {
283  return std::string("RungeKutta");
284  }
285 
286  LUE virtual NekDouble v_GetTimeStability() const override
287  {
288  if (GetOrder() == 4 || GetOrder() == 5)
289  {
290  return 2.784;
291  }
292  else
293  {
294  return 2.0;
295  }
296  }
297 
298 }; // end class RungeKuttaTimeIntegrator
299 
300 ////////////////////////////////////////////////////////////////////////////////
301 // Backwards compatibility
303 {
304 public:
305  RungeKutta1TimeIntegrationScheme(std::string variant, unsigned int order,
306  std::vector<NekDouble> freeParams)
307  : RungeKuttaTimeIntegrationScheme("", 1, freeParams)
308  {
309  boost::ignore_unused(variant);
310  boost::ignore_unused(order);
311  }
312 
314  std::string variant, unsigned int order,
315  std::vector<NekDouble> freeParams)
316  {
317  boost::ignore_unused(variant);
318  boost::ignore_unused(order);
319 
322  "", 1, freeParams);
323  return p;
324  }
325 
326  static std::string className;
327 
328 }; // end class RungeKutta1TimeIntegrationScheme
329 
331 {
332 public:
333  RungeKutta2TimeIntegrationScheme(std::string variant, unsigned int order,
334  std::vector<NekDouble> freeParams)
335  : RungeKuttaTimeIntegrationScheme("", 2, freeParams)
336  {
337  boost::ignore_unused(variant);
338  boost::ignore_unused(order);
339  }
340 
342  std::string variant, unsigned int order,
343  std::vector<NekDouble> freeParams)
344  {
345  boost::ignore_unused(variant);
346  boost::ignore_unused(order);
347 
350  "", 2, freeParams);
351  return p;
352  }
353 
354  static std::string className;
355 
356 }; // end class RungeKutta2TimeIntegrationScheme
357 
359 {
360 public:
361  RungeKutta3TimeIntegrationScheme(std::string variant, unsigned int order,
362  std::vector<NekDouble> freeParams)
363  : RungeKuttaTimeIntegrationScheme("", 3, freeParams)
364  {
365  boost::ignore_unused(variant);
366  boost::ignore_unused(order);
367  }
368 
370  std::string variant, unsigned int order,
371  std::vector<NekDouble> freeParams)
372  {
373  boost::ignore_unused(variant);
374  boost::ignore_unused(order);
375 
378  "", 3, freeParams);
379  return p;
380  }
381 
382  static std::string className;
383 
384 }; // end class RungeKutta3TimeIntegrationScheme
385 
388 {
389 public:
391  unsigned int order,
392  std::vector<NekDouble> freeParams)
393  : RungeKuttaTimeIntegrationScheme("", 4, freeParams)
394  {
395  boost::ignore_unused(variant);
396  boost::ignore_unused(order);
397  }
398 
400  std::string variant, unsigned int order,
401  std::vector<NekDouble> freeParams)
402  {
403  boost::ignore_unused(variant);
404  boost::ignore_unused(order);
405 
408  "", 4, freeParams);
409  return p;
410  }
411 
412  static std::string className;
413 
414 }; // end class ClassicalRungeKutta4TimeIntegrationScheme
415 
418 {
419 public:
420  RungeKutta4TimeIntegrationScheme(std::string variant, unsigned int order,
421  std::vector<NekDouble> freeParams)
422  : ClassicalRungeKutta4TimeIntegrationScheme(variant, order, freeParams)
423  {
424  }
425 
426  static std::string className;
427 
428 }; // end class RungeKutta4TimeIntegrationScheme
429 
431 {
432 public:
433  RungeKutta5TimeIntegrationScheme(std::string variant, unsigned int order,
434  std::vector<NekDouble> freeParams)
435  : RungeKuttaTimeIntegrationScheme("", 5, freeParams)
436  {
437  boost::ignore_unused(variant);
438  boost::ignore_unused(order);
439  }
440 
442  std::string variant, unsigned int order,
443  std::vector<NekDouble> freeParams)
444  {
445  boost::ignore_unused(variant);
446  boost::ignore_unused(order);
447 
450  "", 5, freeParams);
451  return p;
452  }
453 
454  static std::string className;
455 
456 }; // end class RungeKutta5TimeIntegrationScheme
457 
460 {
461 public:
463  std::string variant, unsigned int order,
464  std::vector<NekDouble> freeParams)
465  : RungeKuttaTimeIntegrationScheme("SSP", 2, freeParams)
466  {
467  boost::ignore_unused(variant);
468  boost::ignore_unused(order);
469  }
470 
472  std::string variant, unsigned int order,
473  std::vector<NekDouble> freeParams)
474  {
475  boost::ignore_unused(variant);
476  boost::ignore_unused(order);
477 
480  "SSP", 2, freeParams);
481  return p;
482  }
483 
484  static std::string className;
485 
486 }; // end class RungeKutta2_ImprovedEulerTimeIntegrationScheme
487 
490 {
491 public:
493  unsigned int order,
494  std::vector<NekDouble> freeParams)
495  : RungeKuttaTimeIntegrationScheme("SSP", 2, freeParams)
496  {
497  boost::ignore_unused(variant);
498  boost::ignore_unused(order);
499  }
500 
502  std::string variant, unsigned int order,
503  std::vector<NekDouble> freeParams)
504  {
505  boost::ignore_unused(variant);
506  boost::ignore_unused(order);
507 
510  "SSP", 2, freeParams);
511  return p;
512  }
513 
514  static std::string className;
515 
516 }; // end class RungeKutta2_SSPTimeIntegrationScheme
517 
520 {
521 public:
523  unsigned int order,
524  std::vector<NekDouble> freeParams)
525  : RungeKuttaTimeIntegrationScheme("SSP", 3, freeParams)
526  {
527  boost::ignore_unused(variant);
528  boost::ignore_unused(order);
529  }
530 
532  std::string variant, unsigned int order,
533  std::vector<NekDouble> freeParams)
534  {
535  boost::ignore_unused(variant);
536  boost::ignore_unused(order);
537 
540  "SSP", 3, freeParams);
541  return p;
542  }
543 
544  static std::string className;
545 
546 }; // end class RungeKutta3_SSPTimeIntegrationScheme
547 
548 } // end namespace LibUtilities
549 } // end namespace Nektar
550 
551 #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, unsigned int order, std::vector< NekDouble > freeParams)
static TimeIntegrationSchemeSharedPtr create(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
static TimeIntegrationSchemeSharedPtr create(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
RungeKutta1TimeIntegrationScheme(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
static TimeIntegrationSchemeSharedPtr create(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
RungeKutta2_ImprovedEulerTimeIntegrationScheme(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
static TimeIntegrationSchemeSharedPtr create(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
RungeKutta2_SSPTimeIntegrationScheme(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
RungeKutta2TimeIntegrationScheme(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
static TimeIntegrationSchemeSharedPtr create(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
static TimeIntegrationSchemeSharedPtr create(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
RungeKutta3_SSPTimeIntegrationScheme(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
static TimeIntegrationSchemeSharedPtr create(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
RungeKutta3TimeIntegrationScheme(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
RungeKutta4TimeIntegrationScheme(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
static TimeIntegrationSchemeSharedPtr create(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
RungeKutta5TimeIntegrationScheme(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
static LUE void SetupSchemeData(TimeIntegrationAlgorithmGLMSharedPtr &phase, std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
RungeKuttaTimeIntegrationScheme(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
static TimeIntegrationSchemeSharedPtr create(std::string variant, unsigned int 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