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 
101  LUE virtual std::string GetName() const
102  {
103  return std::string("RungeKutta");
104  }
105 
107  {
108  if (GetOrder() == 4 || GetOrder() == 5)
109  {
110  return 2.784;
111  }
112  else
113  {
114  return 2.0;
115  }
116  }
117 
119  std::string variant, unsigned int order,
120  std::vector<NekDouble> freeParams)
121  {
122  boost::ignore_unused(freeParams);
123 
124  const unsigned int nStages[6] = {0, 1, 2, 3, 4, 6};
125 
126  // A Coefficients for the lower diagonal quadrant stored in a
127  // contiguous fashion. For the fourth order, six coefficients
128  // from the Butcher tableau would be stored as the following.
129  //
130  // 0 0 0 0
131  // Butcher a 0 0 0 Stored as a
132  // Tableau b c 0 0 b c
133  // d e f 0 d e f 0 ... 0
134 
135  // clang-format off
136  const NekDouble Acoefficients[2][6][15] =
137  { { { 0., 0., 0., 0., 0.,
138  0., 0., 0., 0., 0.,
139  0., 0., 0., 0., 0. },
140  // 1st Order
141  { 0., 0., 0., 0., 0.,
142  0., 0., 0., 0., 0.,
143  0., 0., 0., 0., 0. },
144  // 2nd Order - midpoint
145  { 1./2, // Last entry
146  0., 0., 0., 0.,
147  0., 0., 0., 0., 0.,
148  0., 0., 0., 0., 0. },
149  // 3rd Order - Ralston's
150  { 1./2.,
151  0., 3./4., // Last entry
152  0., 0.,
153  0., 0., 0., 0., 0.,
154  0., 0., 0., 0., 0. },
155  // 4th Order - Classic
156  { 1./2.,
157  0., 1./2.,
158  0., 0., 1., // Last entry
159  0., 0., 0., 0.,
160  0., 0., 0., 0., 0. },
161  // 5th Order - 6 stages
162  { 1./4.,
163  1./8., 1./8.,
164  0., 0., 1./2.,
165  3./16., -3./8., 3./8., 9./16.,
166  -3./7., 8./7., 6./7., -12./7., 8./7. } },
167  // Strong Stability Preserving
168  { { 0., 0., 0., 0., 0.,
169  0., 0., 0., 0., 0.,
170  0., 0., 0., 0., 0. },
171  // 1st Order
172  { 0., 0., 0., 0., 0.,
173  0., 0., 0., 0., 0.,
174  0., 0., 0., 0., 0. },
175  // 2nd Order - strong scaling - improved
176  { 1., // Last entry
177  0., 0., 0., 0.,
178  0., 0., 0., 0., 0.,
179  0., 0., 0., 0., 0. },
180  // 3rd Order - strong scaling
181  { 1.,
182  1./4., 1./4., // Last entry
183  0, 0.,
184  0., 0., 0., 0., 0.,
185  0., 0., 0., 0., 0. },
186  // 4th Order - Classic - not used
187  { 1./2.,
188  0., 1./2.,
189  0., 0., 1., // Last entry
190  0., 0., 0., 0.,
191  0., 0., 0., 0., 0. },
192  // 5th Order - 6 stages - not used
193  { 1./4.,
194  1./8., 1./8.,
195  0., 0., 1./2.,
196  3./16., -3./8., 3./8., 9./16.,
197  -3./7., 8./7., 6./7., -12./7., 8./7. } } };
198  // clang-format on
199 
200  // B Coefficients for the final summing.
201 
202  // clang-format off
203  const NekDouble Bcoefficients[2][6][5] =
204  { { { 0., 0., 0., 0., 0. },
205  // 1st Order
206  { 1., 0., 0., 0., 0. },
207  // 2nd Order - midpoint
208  { 0., 1., 0., 0., 0. },
209  // 3rd Order - Ralston's
210  { 2./9., 3./9., 4./9., 0., 0. },
211  // 4th Order - Classic
212  { 1./6., 2./6., 2./6., 1./6., 0. },
213  // 5th Order - 6 stages
214  { 7./90., 32./90., 12./90., 32./90., 7./90. } },
215  // Strong Stability Preserving
216  { { 0., 0., 0., 0., 0. },
217  // 1st Order
218  { 1., 0., 0., 0., 0. },
219  // 2nd Order - improved
220  { 1./2., 1./2., 0., 0., 0. },
221  // 3rd Order - strong scaling
222  { 1./6., 1./6., 4./6., 0., 0. },
223  // 4th Order - Classic
224  { 1./6., 2./6., 2./6., 1./6., 0. },
225  // 5th Order - 6 stages
226  { 7./90., 32./90., 12./90., 32./90., 7./90. } } };
227  // clang-format on
228 
229  unsigned int index = (variant == "SSP" || variant == "ImprovedEuler");
230 
231  phase->m_schemeType = eExplicit;
232  phase->m_variant = variant;
233  phase->m_order = order;
234  phase->m_name = std::string("RungeKutta") + phase->m_variant +
235  std::string("Order") + std::to_string(phase->m_order);
236 
237  phase->m_numsteps = 1;
238  phase->m_numstages = nStages[phase->m_order];
239 
240  phase->m_A = Array<OneD, Array<TwoD, NekDouble>>(1);
241  phase->m_B = Array<OneD, Array<TwoD, NekDouble>>(1);
242 
243  phase->m_A[0] =
244  Array<TwoD, NekDouble>(phase->m_numstages, phase->m_numstages, 0.0);
245  phase->m_B[0] =
246  Array<TwoD, NekDouble>(phase->m_numsteps, phase->m_numstages, 0.0);
247  phase->m_U =
248  Array<TwoD, NekDouble>(phase->m_numstages, phase->m_numsteps, 1.0);
249  phase->m_V =
250  Array<TwoD, NekDouble>(phase->m_numsteps, phase->m_numsteps, 1.0);
251 
252  // Coefficients
253 
254  // A Coefficients for each stages along the lower diagonal quadrant.
255  unsigned int cc = 0;
256 
257  for (int s = 1; s < phase->m_numstages; ++s)
258  {
259  for (int i = 0; i < s; ++i)
260  {
261  phase->m_A[0][s][i] =
262  Acoefficients[index][phase->m_order][cc++];
263  }
264  }
265 
266  // B Coefficients for the finial summing.
267  for (int n = 0; n < phase->m_order; ++n)
268  {
269  phase->m_B[0][0][n] = Bcoefficients[index][phase->m_order][n];
270  }
271 
272  phase->m_numMultiStepValues = 1;
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 }; // end class RungeKuttaTimeIntegrator
281 
282 ////////////////////////////////////////////////////////////////////////////////
283 // Backwards compatibility
285 {
286 public:
287  RungeKutta2TimeIntegrationScheme(std::string variant, unsigned int order,
288  std::vector<NekDouble> freeParams)
289  : RungeKuttaTimeIntegrationScheme("", 2, freeParams)
290  {
291  boost::ignore_unused(variant);
292  boost::ignore_unused(order);
293  }
294 
296  std::string variant, unsigned int order,
297  std::vector<NekDouble> freeParams)
298  {
299  boost::ignore_unused(variant);
300  boost::ignore_unused(order);
301 
304  "", 2, freeParams);
305  return p;
306  }
307 
308  static std::string className;
309 
310 }; // end class RungeKutta2TimeIntegrationScheme
311 
314 {
315 public:
317  unsigned int order,
318  std::vector<NekDouble> freeParams)
319  : RungeKuttaTimeIntegrationScheme("", 4, freeParams)
320  {
321  boost::ignore_unused(variant);
322  boost::ignore_unused(order);
323  }
324 
326  std::string variant, unsigned int order,
327  std::vector<NekDouble> freeParams)
328  {
329  boost::ignore_unused(variant);
330  boost::ignore_unused(order);
331 
334  "", 4, freeParams);
335  return p;
336  }
337 
338  static std::string className;
339 
340 }; // end class RungeKutta2TimeIntegrationScheme
341 
343 {
344 public:
345  RungeKutta5TimeIntegrationScheme(std::string variant, unsigned int order,
346  std::vector<NekDouble> freeParams)
347  : RungeKuttaTimeIntegrationScheme("", 5, freeParams)
348  {
349  boost::ignore_unused(variant);
350  boost::ignore_unused(order);
351  }
352 
354  std::string variant, unsigned int order,
355  std::vector<NekDouble> freeParams)
356  {
357  boost::ignore_unused(variant);
358  boost::ignore_unused(order);
359 
362  "", 5, freeParams);
363  return p;
364  }
365 
366  static std::string className;
367 
368 }; // end class RungeKutta2TimeIntegrationScheme
369 
372 {
373 public:
375  std::string variant, unsigned int order,
376  std::vector<NekDouble> freeParams)
377  : RungeKuttaTimeIntegrationScheme("SSP", 2, freeParams)
378  {
379  boost::ignore_unused(variant);
380  boost::ignore_unused(order);
381  }
382 
384  std::string variant, unsigned int order,
385  std::vector<NekDouble> freeParams)
386  {
387  boost::ignore_unused(variant);
388  boost::ignore_unused(order);
389 
392  "SSP", 2, freeParams);
393  return p;
394  }
395 
396  static std::string className;
397 
398 }; // end class RungeKutta2_ImprovedEulerTimeIntegrationScheme
399 
402 {
403 public:
405  unsigned int order,
406  std::vector<NekDouble> freeParams)
407  : RungeKuttaTimeIntegrationScheme("SSP", 2, freeParams)
408  {
409  boost::ignore_unused(variant);
410  boost::ignore_unused(order);
411  }
412 
414  std::string variant, unsigned int order,
415  std::vector<NekDouble> freeParams)
416  {
417  boost::ignore_unused(variant);
418  boost::ignore_unused(order);
419 
422  "SSP", 2, freeParams);
423  return p;
424  }
425 
426  static std::string className;
427 
428 }; // end class RungeKutta2_SSPTimeIntegrationScheme
429 
432 {
433 public:
435  unsigned int order,
436  std::vector<NekDouble> freeParams)
437  : RungeKuttaTimeIntegrationScheme("SSP", 3, freeParams)
438  {
439  boost::ignore_unused(variant);
440  boost::ignore_unused(order);
441  }
442 
444  std::string variant, unsigned int order,
445  std::vector<NekDouble> freeParams)
446  {
447  boost::ignore_unused(variant);
448  boost::ignore_unused(order);
449 
452  "SSP", 3, freeParams);
453  return p;
454  }
455 
456  static std::string className;
457 
458 }; // end class RungeKutta3_SSPTimeIntegrationScheme
459 
460 } // end namespace LibUtilities
461 } // end namespace Nektar
462 
463 #endif
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:250
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)
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)
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:1
double NekDouble