Nektar++
IMEXTimeIntegrationSchemes.h
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File: IMEXTimeIntegrationSchemes.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 basic IMEX 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_IMEX_TIME_INTEGRATION_SCHEME
42 #define NEKTAR_LIB_UTILITIES_TIME_INTEGRATION_IMEX_TIME_INTEGRATION_SCHEME
43 
44 #define LUE LIB_UTILITIES_EXPORT
45 
48 
51 
52 namespace Nektar
53 {
54 namespace LibUtilities
55 {
56 
57 ///////////////////////////////////////////////////////////////////////////////
58 // IMEX Order N
59 
61 {
62 public:
63  IMEXTimeIntegrationScheme(std::string variant, unsigned int order,
64  std::vector<NekDouble> freeParams)
65  : TimeIntegrationSchemeGLM(variant, order, freeParams)
66  {
67  if (variant == "dirk" || variant == "DIRK")
68  {
69  ASSERTL1(freeParams.size() == 2,
70  "IMEX DIRK Time integration scheme invalid number "
71  "of free parameters, expected two "
72  "<implicit stages, explicit stages>, received " +
73  std::to_string(freeParams.size()));
74 
75  int s = freeParams[0];
76  int sigma = freeParams[1];
77 
80  new TimeIntegrationAlgorithmGLM(this));
81 
82  if (order == 1 && s == 1 && sigma == 1)
83  {
84  // This phase is Forward Backward Euler which has two steps.
87  }
88  else
89  {
91  m_integration_phases[0], order, freeParams);
92  }
93  }
94  else if (variant == "Gear")
95  {
98  new TimeIntegrationAlgorithmGLM(this));
100  new TimeIntegrationAlgorithmGLM(this));
101 
103  m_integration_phases[0], 2, std::vector<NekDouble>{2, 2});
106  }
107  else if (variant == "")
108  {
109  // Currently up to 4th order is implemented.
110  ASSERTL1(1 <= order && order <= 4,
111  "IMEX Time integration scheme bad order (1-4): " +
112  std::to_string(order));
113 
115 
116  for (unsigned int n = 0; n < order; ++n)
117  {
119  new TimeIntegrationAlgorithmGLM(this));
120  }
121 
122  // Last phase
124  m_integration_phases[order - 1], order);
125 
126  // Initial phases
127  switch (order)
128  {
129  case 1:
130  // No intial phase.
131  break;
132 
133  case 2:
135  m_integration_phases[0], 1);
136  // IMEXdirkTimeIntegrationScheme::SetupSchemeData(
137  // m_integration_phases[0], 2, std::vector<NekDouble>
138  // {2, 3});
139  break;
140 
141  case 3:
143  m_integration_phases[0], 3,
144  std::vector<NekDouble>{3, 4});
146  m_integration_phases[1], 3,
147  std::vector<NekDouble>{3, 4});
148  break;
149 
150  case 4:
152  m_integration_phases[0], 3,
153  std::vector<NekDouble>{2, 3});
155  m_integration_phases[1], 3,
156  std::vector<NekDouble>{2, 3});
158  m_integration_phases[2], 3);
159  break;
160 
161  default:
162  ASSERTL1(false, "IMEX Time integration scheme bad order: " +
163  std::to_string(order));
164  }
165  }
166  else
167  {
168  ASSERTL1(false, "IMEX Time integration scheme bad variant: " +
169  variant + ". Must be blank, 'dirk' or 'Gear'");
170  }
171  }
172 
174  {
175  }
176 
178  std::string variant, unsigned int order,
179  std::vector<NekDouble> freeParams)
180  {
183  variant, order, freeParams);
184 
185  return p;
186  }
187 
188  static std::string className;
189 
190  LUE virtual std::string GetFullName() const
191  {
192  return m_integration_phases[m_integration_phases.size() - 1]->m_name;
193  }
194 
195  LUE virtual std::string GetName() const
196  {
197  return std::string("IMEX");
198  }
199 
201  {
202  return 1.0;
203  }
204 
206  int order)
207  {
208  const NekDouble ABcoefficients[5] = {0.,
209  1., // 1st Order
210  2. / 3., // 2nd Order
211  6. / 11., // 3rd Order
212  12. / 25.}; // 4th Order
213 
214  // Nsteps = 2 * order
215 
216  // clang-format off
217  const NekDouble UVcoefficients[5][8] =
218  { { 0., 0., 0., 0.,
219  0., 0., 0., 0. },
220  // 1st Order
221  { 1., 1., 0., 0.,
222  0., 0., 0., 0. },
223  // 2nd Order
224  { 4./ 3., -1./ 3., 4./3., -2./ 3.,
225  0., 0., 0., 0. },
226  // 3rd Order
227  { 18./11., -9./11., 2./11., 18./11.,
228  -18./11., 6./11., 0., 0. },
229  // 4th Order
230  { 48./25., -36./25., 16./25., -3./25.,
231  48./25., -72./25., 48./25., -12./25. } };
232  // clang-format on
233 
234  phase->m_schemeType = eIMEX;
235  phase->m_order = order;
236  phase->m_name =
237  std::string("IMEXOrder" + std::to_string(phase->m_order));
238 
239  phase->m_numsteps = 2 * phase->m_order;
240  phase->m_numstages = 1;
241 
242  phase->m_A = Array<OneD, Array<TwoD, NekDouble>>(2);
243  phase->m_B = Array<OneD, Array<TwoD, NekDouble>>(2);
244 
245  phase->m_A[0] =
246  Array<TwoD, NekDouble>(phase->m_numstages, phase->m_numstages, 0.0);
247  phase->m_B[0] =
248  Array<TwoD, NekDouble>(phase->m_numsteps, phase->m_numstages, 0.0);
249  phase->m_A[1] =
250  Array<TwoD, NekDouble>(phase->m_numstages, phase->m_numstages, 0.0);
251  phase->m_B[1] =
252  Array<TwoD, NekDouble>(phase->m_numsteps, phase->m_numstages, 0.0);
253  phase->m_U =
254  Array<TwoD, NekDouble>(phase->m_numstages, phase->m_numsteps, 0.0);
255  phase->m_V =
256  Array<TwoD, NekDouble>(phase->m_numsteps, phase->m_numsteps, 0.0);
257 
258  // Coefficients
259  phase->m_B[1][phase->m_order][0] = 1.0;
260 
261  phase->m_A[0][0][0] = ABcoefficients[phase->m_order];
262  phase->m_B[0][0][0] = ABcoefficients[phase->m_order];
263 
264  for (int n = 0; n < 2 * phase->m_order; ++n)
265  {
266  phase->m_U[0][n] = UVcoefficients[phase->m_order][n];
267  phase->m_V[0][n] = UVcoefficients[phase->m_order][n];
268  }
269 
270  // V evaluation value shuffling row n column n-1
271  for (int n = 1; n < 2 * phase->m_order; ++n)
272  {
273  if (n != phase->m_order)
274  phase->m_V[n][n - 1] = 1.0; // constant 1
275  }
276 
277  phase->m_numMultiStepValues = phase->m_order;
278  phase->m_numMultiStepDerivs = phase->m_order;
279 
280  phase->m_timeLevelOffset = Array<OneD, unsigned int>(phase->m_numsteps);
281 
282  // Values and derivatives needed.
283  for (int n = 0; n < phase->m_order; ++n)
284  {
285  phase->m_timeLevelOffset[n] = n;
286  phase->m_timeLevelOffset[phase->m_order + n] = n;
287  }
288 
289  phase->CheckAndVerify();
290  }
291 
292 }; // end class IMEXTimeIntegrationScheme
293 
294 ////////////////////////////////////////////////////////////////////////////////
295 // Backwards compatibility
297 {
298 public:
299  IMEXOrder1TimeIntegrationScheme(std::string variant, unsigned int order,
300  std::vector<NekDouble> freeParams)
301  : IMEXTimeIntegrationScheme("", 1, freeParams)
302  {
303  boost::ignore_unused(variant);
304  boost::ignore_unused(order);
305  }
306 
308  std::string variant, unsigned int order,
309  std::vector<NekDouble> freeParams)
310  {
311  boost::ignore_unused(variant);
312  boost::ignore_unused(order);
313 
316  "", 1, freeParams);
317  return p;
318  }
319 
320  static std::string className;
321 
322 }; // end class IMEXOrder1TimeIntegrationScheme
323 
325 {
326 public:
327  IMEXOrder2TimeIntegrationScheme(std::string variant, unsigned int order,
328  std::vector<NekDouble> freeParams)
329  : IMEXTimeIntegrationScheme("", 2, freeParams)
330  {
331  boost::ignore_unused(variant);
332  boost::ignore_unused(order);
333  }
334 
336  std::string variant, unsigned int order,
337  std::vector<NekDouble> freeParams)
338  {
339  boost::ignore_unused(variant);
340  boost::ignore_unused(order);
341 
344  "", 2, freeParams);
345  return p;
346  }
347 
348  static std::string className;
349 
350 }; // end class IMEXOrder2TimeIntegrationScheme
351 
353 {
354 public:
355  IMEXOrder3TimeIntegrationScheme(std::string variant, unsigned int order,
356  std::vector<NekDouble> freeParams)
357  : IMEXTimeIntegrationScheme("", 3, freeParams)
358  {
359  boost::ignore_unused(variant);
360  boost::ignore_unused(order);
361  }
362 
364  std::string variant, unsigned int order,
365  std::vector<NekDouble> freeParams)
366  {
367  boost::ignore_unused(variant);
368  boost::ignore_unused(order);
369 
372  "", 3, freeParams);
373  return p;
374  }
375 
376  static std::string className;
377 
378 }; // end class IMEXOrder3TimeIntegrationScheme
379 
381 {
382 public:
383  IMEXOrder4TimeIntegrationScheme(std::string variant, unsigned int order,
384  std::vector<NekDouble> freeParams)
385  : IMEXTimeIntegrationScheme("", 4, freeParams)
386  {
387  boost::ignore_unused(variant);
388  boost::ignore_unused(order);
389  }
390 
392  std::string variant, unsigned int order,
393  std::vector<NekDouble> freeParams)
394  {
395  boost::ignore_unused(variant);
396  boost::ignore_unused(order);
397 
400  "", 4, freeParams);
401  return p;
402  }
403 
404  static std::string className;
405 
406 }; // end class IMEXOrder4TimeIntegrationScheme
407 
408 } // end namespace LibUtilities
409 } // end namespace Nektar
410 
411 #endif
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:250
#define LUE
static LUE void SetupSchemeData(TimeIntegrationAlgorithmGLMSharedPtr &phase)
static TimeIntegrationSchemeSharedPtr create(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
IMEXOrder1TimeIntegrationScheme(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
static TimeIntegrationSchemeSharedPtr create(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
IMEXOrder2TimeIntegrationScheme(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
static TimeIntegrationSchemeSharedPtr create(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
IMEXOrder3TimeIntegrationScheme(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
static TimeIntegrationSchemeSharedPtr create(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
IMEXOrder4TimeIntegrationScheme(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
IMEXTimeIntegrationScheme(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
static TimeIntegrationSchemeSharedPtr create(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
static LUE void SetupSchemeData(TimeIntegrationAlgorithmGLMSharedPtr &phase, int order)
static LUE void SetupSchemeData(TimeIntegrationAlgorithmGLMSharedPtr &phase, unsigned int order, std::vector< NekDouble > freeParams)
static LUE void SetupSchemeData_1_1_1(TimeIntegrationAlgorithmGLMSharedPtr &phase)
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
@ eIMEX
Implicit Explicit General Linear Method.
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